buid/sim: add vga framebuffer with SDL

This commit is contained in:
Florent Kermarrec 2016-05-04 20:17:02 +02:00
parent 55c9c653e0
commit e890a566a9
3 changed files with 121 additions and 6 deletions

View File

@ -30,6 +30,14 @@ _io = [
Subsignal("sink_ready", SimPins(1)), Subsignal("sink_ready", SimPins(1)),
Subsignal("sink_data", SimPins(8)), Subsignal("sink_data", SimPins(8)),
), ),
("vga", 0,
Subsignal("de", SimPins(1)),
Subsignal("hsync", SimPins(1)),
Subsignal("vsync", SimPins(1)),
Subsignal("r", SimPins(8)),
Subsignal("g", SimPins(8)),
Subsignal("b", SimPins(8)),
),
] ]

View File

@ -17,6 +17,8 @@
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.h> #include <linux/if_tun.h>
#include <SDL/SDL.h>
/* ios */ /* ios */
#ifdef SERIAL_SOURCE_VALID #ifdef SERIAL_SOURCE_VALID
@ -27,6 +29,10 @@
#define WITH_ETH #define WITH_ETH
#endif #endif
#ifdef VGA_DE
#define WITH_VGA
#endif
#define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
@ -38,6 +44,9 @@ double sc_time_stamp()
return main_time; return main_time;
} }
Vdut* dut;
VerilatedVcdC* tfp;
/* Sim struct */ /* Sim struct */
struct sim { struct sim {
bool run; bool run;
@ -180,8 +189,78 @@ int eth_read(struct sim *s, unsigned char *buf)
} }
#endif #endif
Vdut* dut; /* VGA functions */
VerilatedVcdC* tfp; #ifdef WITH_VGA
SDL_Surface *screen;
SDL_Event event;
void vga_set_pixel(SDL_Surface *screen, int x, int y, char r, char g, char b)
{
unsigned int *pixmem32;
unsigned int color;
color = SDL_MapRGB(screen->format, r, g, b);
pixmem32 = (unsigned int*) screen->pixels + y*640 + x;
*pixmem32 = color;
}
int vga_init(struct sim *s) {
if(SDL_Init(SDL_INIT_VIDEO) < 0) return 1;
if(!(screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE))) {
SDL_Quit();
return 1;
}
return 0;
}
int x;
int y;
int hsync_needs_de = 1;
int vsync_needs_de = 1;
void vga_service(struct sim *s) {
if(VGA_HSYNC == 1 && hsync_needs_de == 0) {
x = 0;
y++;
hsync_needs_de = 1;
}
if(VGA_VSYNC == 1 && vsync_needs_de == 0) {
y = 0;
vsync_needs_de = 1;
if(SDL_MUSTLOCK(screen))
SDL_UnlockSurface(screen);
SDL_Flip(screen);
if(SDL_MUSTLOCK(screen))
SDL_LockSurface(screen);
}
if(VGA_DE == 1) {
hsync_needs_de = 0;
vsync_needs_de = 0;
vga_set_pixel(screen, x, y, VGA_R, VGA_G, VGA_B);
x++;
}
if(s->tick%1000 == 0) {
while(SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
s->run = false;
break;
case SDL_KEYDOWN:
s->run = false;
break;
}
}
}
}
int vga_close(struct sim *s) {
SDL_Quit();
}
#endif
#ifndef WITH_SERIAL_PTY #ifndef WITH_SERIAL_PTY
int console_service(struct sim *s) int console_service(struct sim *s)
@ -366,6 +445,10 @@ int main(int argc, char **argv, char **env)
eth_open(&s); eth_open(&s);
#endif #endif
#ifdef WITH_VGA
if(vga_init(&s)) return 1;
#endif
s.run = true; s.run = true;
while(s.run) { while(s.run) {
sim_tick(&s); sim_tick(&s);
@ -376,6 +459,9 @@ int main(int argc, char **argv, char **env)
#endif #endif
#ifdef WITH_ETH #ifdef WITH_ETH
ethernet_service(&s); ethernet_service(&s);
#endif
#ifdef WITH_VGA
vga_service(&s);
#endif #endif
} }
} }
@ -387,13 +473,15 @@ int main(int argc, char **argv, char **env)
tfp->close(); tfp->close();
#ifdef WITH_SERIAL_PTY #ifdef WITH_SERIAL_PTY
console_close(&s); console_close(&s);
#endif #endif
#ifdef WITH_ETH #ifdef WITH_ETH
eth_close(&s); eth_close(&s);
#endif #endif
#ifdef WITH_VGA
vga_close(&s);
#endif
exit(0); exit(0);
} }

View File

@ -1,4 +1,4 @@
# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr> # This file is Copyright (c) 2015-2016 Florent Kermarrec <florent@enjoy-digital.fr>
# License: BSD # License: BSD
import os import os
@ -71,6 +71,25 @@ def _build_tb(platform, vns, serial, template):
except: except:
pass pass
try:
ios += """
#define VGA_DE dut->{vga_de}
#define VGA_HSYNC dut->{vga_hsync}
#define VGA_VSYNC dut->{vga_vsync}
#define VGA_R dut->{vga_r}
#define VGA_G dut->{vga_g}
#define VGA_B dut->{vga_b}
""".format(
vga_de=io_name("vga", "de"),
vga_hsync=io_name("vga", "hsync"),
vga_vsync=io_name("vga", "vsync"),
vga_r=io_name("vga", "r"),
vga_g=io_name("vga", "g"),
vga_b=io_name("vga", "b"),
)
except:
pass
content = "" content = ""
f = open(template, "r") f = open(template, "r")
done = False done = False
@ -91,7 +110,7 @@ def _build_sim(platform, vns, build_name, include_paths, serial, verbose):
build_script_contents = """# Autogenerated by LiteX build_script_contents = """# Autogenerated by LiteX
rm -rf obj_dir/ rm -rf obj_dir/
verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include} verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread -lSDL" -trace {include}
make -j -C obj_dir/ -f Vdut.mk Vdut make -j -C obj_dir/ -f Vdut.mk Vdut
""".format( """.format(
@ -126,7 +145,7 @@ def _run_sim(build_name):
class SimVerilatorToolchain: class SimVerilatorToolchain:
def build(self, platform, fragment, build_dir="build", build_name="top", def build(self, platform, fragment, build_dir="build", build_name="top",
toolchain_path=None, serial="console", run=True, verbose=False): toolchain_path=None, serial="console", run=True, verbose=True):
tools.mkdir_noerror(build_dir) tools.mkdir_noerror(build_dir)
os.chdir(build_dir) os.chdir(build_dir)