-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
101 lines (86 loc) · 2.58 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <iostream>
#include <string.h>
#include "Vtop.h"
#include "verilated.h"
#include "system.h"
#if VM_TRACE
# include <verilated_vcd_c.h> // Trace file format header
#endif
#define RAM_SIZE (1*GIGA)
#define INIT_STACK_OFFSET (4*MEGA)
#define INIT_STACK_POINTER (RAM_SIZE - INIT_STACK_OFFSET)
/** Current simulation time */
double sc_time_stamp() {
return System::sys->ticks;
}
int main(int argc, char* argv[]) {
Verilated::commandArgs(argc, argv);
const char* binaryfn = NULL;
if (argc > 0) binaryfn = argv[1];
Vtop top;
System sys(&top, RAM_SIZE, binaryfn, argc-1, argv+1, 500/*ps_per_clock*/);
if (!sys.full_system) {
// (argc, argv) sanity check
std::cerr << "===== Printing arguments of the program..." << std::endl;
for (int j = 0; j <= argc-1; j++) {
unsigned long guest_addr = top.stackptr + j * sizeof(uint64_t);
uint64_t val = *(uint64_t *)(sys.ram_virt + guest_addr);
if (0 == j) {
std::cerr << std::dec << "== argc: " << val << std::endl;
} else {
char *arg_ptr = sys.ram_virt + val;
char *arg_ptr1 = arg_ptr;
while (*arg_ptr++);
unsigned len = arg_ptr - arg_ptr1;
std::cerr << std::dec << "== argv[" << j-1 << "]: ";
do_ecall(1/*__NR_write*/, 2, val, len-1, 0, 0, 0, 0, (long long*)&arg_ptr/*dummy*/);
std::cerr << std::endl;
}
}
std::cerr << "==========================================" << std::endl;
}
#if VM_TRACE
// If verilator was invoked with --trace
VerilatedVcdC* tfp = NULL;
Verilated::traceEverOn(true);
VL_PRINTF("Enabling waves...\n");
tfp = new VerilatedVcdC;
assert(tfp);
// Trace 99 levels of hierarchy
top.trace (tfp, 99);
tfp->spTrace()->set_time_resolution("1 ps");
// Open the dump file
tfp->open ("../trace.vcd");
#define TFP_DUMP if (tfp) tfp->dump(sys.ticks);
#else
#define TFP_DUMP
#endif
#define TICK() do { \
top.clk = !top.clk; \
top.eval(); \
TFP_DUMP \
sys.tick(top.clk); \
top.eval(); \
TFP_DUMP \
sys.ticks += sys.ps_per_clock/2; \
} while(0)
top.reset = 1;
top.clk = 0;
TICK(); // 1
TICK(); // 0
TICK(); // 1
TICK(); // 0
TICK(); // 1
top.reset = 0;
const char* SHOWCONSOLE = getenv("SHOWCONSOLE");
if (SHOWCONSOLE?(atoi(SHOWCONSOLE)!=0):0) sys.console();
while (sys.ticks/sys.ps_per_clock < 2000*GIGA && !Verilated::gotFinish()) {
TICK();
}
top.final();
#if VM_TRACE
if (tfp) tfp->close();
delete tfp;
#endif
return 0;
}