buid/sim: add vga framebuffer with SDL
This commit is contained in:
parent
55c9c653e0
commit
e890a566a9
|
@ -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)),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue