§ Шаблон для верилятора

#include <SDL2/SDL.h>
#include <verilated.h>
// ----------------------------------------------------
SDL_Surface*        screen_surface;
SDL_Window*         sdl_window;
SDL_Renderer*       sdl_renderer;
SDL_PixelFormat*    sdl_pixel_format;
SDL_Texture*        sdl_screen_texture;
SDL_Event           evt;
Uint32*             screen_buffer;
SDL_Rect            dstRect;
// ----------------------------------------------------
int scale  = 2;
int width  = 640;
int height = 400;
int length = 16;
int _hs = 0, _vs = 0;
int x   = 0, y   = 0;
// ----------------------------------------------------
void pset(int, int, Uint32);
void vga(int, int, int);

int main(int argc, char** argv)
{
    int pticks = 0;

    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO)) {
        exit(1);
    }

    SDL_ClearError();
    sdl_window = SDL_CreateWindow(
        "T8080 VEMULATOR",
        SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        scale*width, scale*height,
        SDL_WINDOW_SHOWN);

    sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_PRESENTVSYNC);
    sdl_screen_texture  =
        SDL_CreateTexture(sdl_renderer,
        SDL_PIXELFORMAT_BGRA32,
        SDL_TEXTUREACCESS_STREAMING,
        width, height);

    SDL_SetTextureBlendMode(sdl_screen_texture, SDL_BLENDMODE_NONE);
    screen_buffer = (Uint32*) malloc(width*height*sizeof(Uint32));

    dstRect.x = 0;
    dstRect.y = 0;
    dstRect.w = scale * width;
    dstRect.h = scale * height;

    for (;;)
    {
        // Прием событий
        while (SDL_PollEvent(& evt))
        {
            switch (evt.type)
            {
                // Выход из приложения
                case SDL_QUIT:

                    free(screen_buffer);
                    SDL_DestroyTexture(sdl_screen_texture);
                    SDL_FreeFormat(sdl_pixel_format);
                    SDL_DestroyRenderer(sdl_renderer);
                    SDL_DestroyWindow(sdl_window);
                    SDL_Quit();
                    return 0;
            }
        }

        int nticks = SDL_GetTicks();

        // Обновление экрана
        if (nticks - pticks >= length) {

            pticks = nticks;
            SDL_UpdateTexture(sdl_screen_texture, NULL, screen_buffer, width * sizeof(Uint32));
            SDL_SetRenderDrawColor  (sdl_renderer, 0, 0, 0, 0);
            SDL_RenderClear         (sdl_renderer);
            SDL_RenderCopy          (sdl_renderer, sdl_screen_texture, NULL, & dstRect);
            SDL_RenderPresent       (sdl_renderer);
        }

        SDL_Delay(1);
    }
}

// Установка точки
void pset(int x, int y, Uint32 cl)
{
    if (x < 0 || y < 0 || x >= width || y >= height) {
        return;
    }

    screen_buffer[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

VLIB="/usr/share/verilator/include"
LIBS=$(VLIB)/verilated_threads.cpp $(VLIB)/verilated.cpp

all: ica app
app: syn
	g++ -o i8080 -I$(VLIB) i8080.cc -lSDL2 $(LIBS)
	./i8080
syn:
	#verilator --threads 1 -cc xxx.v > /dev/null
	#cd obj_dir && make -f Vxxx.mk > /dev/null
ica:
	iverilog -g2005-sv -DICARUS=1 -o tb.qqq tb.v
	vvp tb.qqq >> /dev/null
	rm tb.qqq
vcd:
	gtkwave tb.vcd
wav:
	gtkwave tb.gtkw