Skip to content

Commit 9773e17

Browse files
committed
feat: add verilator sim wrapper files
1 parent c4d8c1e commit 9773e17

File tree

2 files changed

+203
-0
lines changed

2 files changed

+203
-0
lines changed

rtl/tc_l2/src/main/csrc/emu.h

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#include <unistd.h>
2+
#include <getopt.h>
3+
4+
#include <verilated_vcd_c.h>
5+
#include <verilated.h>
6+
#include <VysyxSoCFull.h>
7+
8+
extern "C"
9+
{
10+
void flash_init(const char *img);
11+
}
12+
13+
class Emulator
14+
{
15+
public:
16+
Emulator(int argc, char *argv[])
17+
{
18+
parseArgs(argc, argv);
19+
20+
if (args.image == nullptr)
21+
{
22+
printf("Image file unspecified. Use -i to provide the image of flash");
23+
exit(1);
24+
}
25+
printf("Initializing flash with \"%s\" ...\n", args.image);
26+
flash_init(args.image);
27+
28+
printf("Initializing and resetting DUT ...\n");
29+
dut_ptr = new VysyxSoCFull;
30+
dut_ptr->reset = 1;
31+
for (int i = 0; i < 10; i++)
32+
{
33+
dut_ptr->clock = 0;
34+
dut_ptr->eval();
35+
dut_ptr->clock = 1;
36+
dut_ptr->eval();
37+
}
38+
dut_ptr->clock = 0;
39+
dut_ptr->reset = 0;
40+
dut_ptr->eval();
41+
42+
if (args.dump_wave)
43+
{
44+
Verilated::traceEverOn(true);
45+
printf("`dump-wave` enabled, waves will be written to \"vlt_dump.vcd\".\n");
46+
fp = new VerilatedVcdC;
47+
dut_ptr->trace(fp, 1);
48+
fp->open("vlt_dump.vcd");
49+
fp->dump(0);
50+
}
51+
}
52+
~Emulator()
53+
{
54+
if (args.dump_wave)
55+
{
56+
fp->close();
57+
delete fp;
58+
}
59+
}
60+
61+
void step()
62+
{
63+
dut_ptr->clock = 1;
64+
dut_ptr->eval();
65+
cycle++;
66+
if (args.dump_wave && args.dump_begin <= cycle && cycle <= args.dump_end)
67+
fp->dump((vluint64_t)cycle);
68+
dut_ptr->clock = 0;
69+
dut_ptr->eval();
70+
}
71+
72+
unsigned long long get_cycle()
73+
{
74+
return cycle;
75+
}
76+
77+
private:
78+
void parseArgs(int argc, char *argv[])
79+
{
80+
81+
int long_index;
82+
const struct option long_options[] = {
83+
{"dump-wave", 0, NULL, 0},
84+
{"log-begin", 1, NULL, 'b'},
85+
{"log-end", 1, NULL, 'e'},
86+
{"image", 1, NULL, 'i'},
87+
{"help", 0, NULL, 'h'},
88+
{0, 0, NULL, 0}};
89+
90+
int o;
91+
while ((o = getopt_long(argc, const_cast<char *const *>(argv),
92+
"-hi:b:e:", long_options, &long_index)) != -1)
93+
{
94+
switch (o)
95+
{
96+
case 0:
97+
switch (long_index)
98+
{
99+
case 0:
100+
args.dump_wave = true;
101+
continue;
102+
}
103+
// fall through
104+
default:
105+
print_help(argv[0]);
106+
exit(0);
107+
case 'i':
108+
args.image = optarg;
109+
break;
110+
case 'b':
111+
args.dump_begin = atoll(optarg);
112+
break;
113+
case 'e':
114+
args.dump_end = atoll(optarg);
115+
break;
116+
}
117+
}
118+
119+
Verilated::commandArgs(argc, argv);
120+
}
121+
122+
static inline void print_help(const char *file)
123+
{
124+
printf("Usage: %s [OPTION...]\n", file);
125+
printf("\n");
126+
printf(" -i, --image=FILE run with this image file\n");
127+
printf(" --dump-wave dump waveform when log is enabled\n");
128+
printf(" -b, --log-begin=NUM display log from NUM th cycle\n");
129+
printf(" -e, --log-end=NUM stop display log at NUM th cycle\n");
130+
printf(" -h, --help print program help info\n");
131+
printf("\n");
132+
}
133+
134+
unsigned long long cycle = 0;
135+
136+
struct Args
137+
{
138+
bool dump_wave = false;
139+
unsigned long dump_begin = 0;
140+
unsigned long dump_end = -1;
141+
const char *image = nullptr;
142+
} args;
143+
144+
VysyxSoCFull *dut_ptr = nullptr;
145+
VerilatedVcdC *fp = nullptr;
146+
};

rtl/tc_l2/src/main/csrc/main.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <cstdio>
2+
#include <csignal>
3+
#include <chrono>
4+
namespace chrono = std::chrono;
5+
6+
#include "verilated.h" //Defines common routines
7+
#include "VysyxSoCFull.h"
8+
9+
#include <emu.h>
10+
11+
static int signal_received = 0;
12+
13+
void sig_handler(int signo)
14+
{
15+
if (signal_received != 0)
16+
{
17+
puts("SIGINT received, forcely shutting down.\n");
18+
exit(0);
19+
}
20+
puts("SIGINT received, gracefully shutting down... Type Ctrl+C again to stop forcely.\n");
21+
signal_received = signo;
22+
}
23+
24+
static Emulator *emu = nullptr;
25+
chrono::system_clock::time_point sim_start_time;
26+
void release()
27+
{
28+
if (emu != nullptr)
29+
{
30+
auto elapsed = chrono::duration_cast<chrono::seconds>(chrono::system_clock::now() - sim_start_time);
31+
printf("Simulated %llu cycles in %lds\n",
32+
emu->get_cycle(),
33+
elapsed.count());
34+
delete emu;
35+
}
36+
}
37+
38+
int main(int argc, char *argv[])
39+
{
40+
printf("Emu compiled at %s, %s\n", __DATE__, __TIME__);
41+
42+
if (signal(SIGINT, sig_handler) == SIG_ERR)
43+
{
44+
printf("can't catch SIGINT\n");
45+
}
46+
atexit(release);
47+
48+
emu = new Emulator(argc, argv);
49+
printf("Start simulating ...\n");
50+
sim_start_time = chrono::system_clock::now();
51+
while (!Verilated::gotFinish() && signal_received == 0)
52+
{
53+
emu->step();
54+
}
55+
56+
return 0;
57+
}

0 commit comments

Comments
 (0)