§ Шаблон для верилятора
Стандартный код.Скачать шаблон в формате ZIP
#include <SDL2/SDL.h> #include <verilated.h> #include "obj_dir/Vvideo.h" // КОНСТАНТЫ ------------------------------------------------------------------- #define WIDTH 640 #define HEIGHT 480 // КЛАССЫ ---------------------------------------------------------------------- SDL_Surface* surface; SDL_Window* window; SDL_Renderer* renderer; SDL_Texture* texture; SDL_Event evt; SDL_Rect dstRect; Uint32* screen; // МОДУЛИ ---------------------------------------------------------------------- Vvideo* video; // ПЕРЕМЕННЫЕ ------------------------------------------------------------------ int length = 20, x = 0, y = 0, _hs = 1, _vs = 0; // ПРОТОТИПЫ ------------------------------------------------------------------- void pset(int x, int y, Uint32 cl); void vga(int hs, int vs, int cl); // ----------------------------------------------------------------------------- void tick() { video->clock = 0; video->eval(); video->clock = 1; video->eval(); vga(video->hs, video->vs, video->r*16*65536 + video->g*16*256 + video->b*16); } // ----------------------------------------------------------------------------- int main(int argc, char** argv) { SDL_ClearError(); Verilated::commandArgs(argc, argv); // Создание модулей video = new Vvideo; // Инициализация int pticks = 0, nticks; int wincen = SDL_WINDOWPOS_CENTERED; int pixfmt = SDL_PIXELFORMAT_BGRA32; int pixstm = SDL_TEXTUREACCESS_STREAMING; int presyn = SDL_RENDERER_PRESENTVSYNC; int wshown = SDL_WINDOW_SHOWN; dstRect.x = 0; dstRect.y = 0; dstRect.w = 2*WIDTH; dstRect.h = 2*HEIGHT; if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) { exit(1); } // Открыть окно SDL window = SDL_CreateWindow("Vemulator",wincen,wincen,dstRect.w,dstRect.h,wshown); renderer = SDL_CreateRenderer(window,-1,presyn); screen = (Uint32*) malloc(WIDTH*HEIGHT*sizeof(Uint32)); texture = SDL_CreateTexture(renderer,pixfmt,pixstm,WIDTH,HEIGHT); SDL_SetTextureBlendMode(texture,SDL_BLENDMODE_NONE); for (;;) { int count = 0; // Прием событий while (SDL_PollEvent(& evt)) { switch (evt.type) { // Событие выхода case SDL_QUIT: free(screen); SDL_DestroyTexture (texture); SDL_DestroyRenderer (renderer); SDL_DestroyWindow (window); SDL_Quit(); return 0; } } // Выполнение фрейма длиной <frame_length>: ms. do { for (int i = 0; i < 8192; i++) tick(); nticks = SDL_GetTicks(); } while ((nticks - pticks) <= length); pticks = nticks; SDL_UpdateTexture (texture, NULL, screen, WIDTH*sizeof(Uint32)); SDL_SetRenderDrawColor (renderer, 0, 0, 0, 0); SDL_RenderClear (renderer); SDL_RenderCopy (renderer, texture, NULL, & dstRect); SDL_RenderPresent (renderer); SDL_Delay(1); } } // Установка точки void pset(int x, int y, Uint32 cl) { if (x < 0 || y < 0 || x >= WIDTH || y >= HEIGHT) { return; } screen[WIDTH*y + x] = cl; } // Отслеживание сигнала RGB по HS/VS void vga(int hs, int vs, int cl) { if (hs) x++; if (_hs == 1 && hs == 0) { x = 0; y++; } if (_vs == 0 && vs == 1) { y = 0; } _hs = hs; _vs = vs; pset(x-(48+2), y-33, cl); }
§ makefile
Подключение видеоадаптера video 640 на 480 для тестирования.VLIB="/usr/share/verilator/include" COMM=$(VLIB)/verilated_threads.cpp $(VLIB)/verilated.cpp MODS=obj_dir/Vvideo__ALL.a all: app ./main app: syn g++ -o main -I$(VLIB) main.cc -lSDL2 $(COMM) $(MODS) syn: video.v verilator --threads 1 -cc video.v > /dev/null cd obj_dir && make -f Vvideo.mk > /dev/null clean: rm -r obj_dir tb
§ video.v
Тестовый модуль./* verilator lint_off WIDTH */ module video ( input wire clock, output reg [3:0] r, output reg [3:0] g, output reg [3:0] b, output wire hs, output wire vs ); // Тайминги для горизонтальной и вертикальной развертки // --------------------------------------------------------------------- parameter // Visible Front Sync Back Whole hzv = 640, hzf = 16, hzs = 96, hzb = 48, hzw = 800, vtv = 480, vtf = 10, vts = 2, vtb = 33, vtw = 525; // --------------------------------------------------------------------- assign hs = x < (hzb + hzv + hzf); assign vs = y < (vtb + vtv + vtf); // --------------------------------------------------------------------- wire xmax = (x == hzw - 1); wire ymax = (y == vtw - 1); reg [10:0] x = 0; reg [10:0] y = 0; // --------------------------------------------------------------------- always @(posedge clock) begin // Кадровая развертка x <= xmax ? 0 : x + 1; y <= xmax ? (ymax ? 0 : y + 1) : y; {r, g, b} <= 12'h000; // Вывод окна видеоадаптера if (x >= hzb && x < hzb+hzv && y >= vtb && y < vtb+vtv) begin {r, g, b} <= 12'h008; end end endmodule
07 июл 2025, 07:17
© 2011-2025 Все коты отлично зарезервированы