-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathsim_main.cpp
More file actions
153 lines (119 loc) · 4.55 KB
/
Copy pathsim_main.cpp
File metadata and controls
153 lines (119 loc) · 4.55 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// Labarc FPGA Simulator
// This file is derived from:
// verilator-3.922/examples/hello_world_c/sim_main.cpp
// This program is based in part on the work of the FLTK project (http://www.fltk.org).
// This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.1.
// Icaro Dantas de Araujo Lima and Elmar Melcher at UFCG, 2019
// Include graphic user interface
#include "gui.h"
// Include common Verilator routines
#include <verilated.h>
// Include Verilator model header, generated from Verilating "top.v"
#include "Vtop.h"
Vtop* top; // Verilated model
vluint64_t main_time = 0; // Current Verilator simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
// One main_time unit corresponds to 0.1 seconds in real time
double sc_time_stamp () { // Called by $time in Verilog
return main_time; // converts to double, to match what SystemC does
}
// ****** The main action is in this callback ******
// It controls Verilog simulation time, retrieves Verilog output and displays it.
void callback(void*) {
main_time++; // Verilator simulation time passes...
top->clk_2 = !top->clk_2; // Toggle clock
top->eval(); // Evaluate Verilated SystemVerilog model
fpga->redraw();
Fl::repeat_timeout(fpga->clk->value()/2, callback); // retrigger timeout for next clock change
}
int SWI::handle(int event) {
if (event == FL_PUSH) {
state = !state;
if (state) {
top->SWI |= 1UL << id;
} else {
top->SWI &= ~(1UL << id);
}
top->eval(); // Evaluate Verilated SystemVerilog model
fpga->redraw();
}
return 1;
}
void LEDs::draw() {
for(int i = 0; i < NLEDS; i++) {
((top->LED >> i & 1) ? led_on : led_off)->draw(x_origin + (NLEDS-1 - i) * offset, y_origin);
}
}
void SegmentsDisplay::draw() {
base->draw(x(), y());
draw_segments(top->SEG);
}
void rec_set_lcd() {} // only needed for remote
void display::draw() {
this->window()->make_current(); // needed because draw() will be called from callback
if(fpga->riscv_check->value()) {
fl_rectf(x(), y(), w(), h(), FL_WHITE); // clean LCD and register window
lcd_labels();
stringstream ss;
ss << hex << setfill('0') << uppercase;
// LCD data
// first line
ss << setw(2) << (int)top->lcd_pc;
ss << " " << setw(8) << (int)top->lcd_instruction;
ss << " " << setw(2) << (int)top->lcd_WriteData;
ss << (top->lcd_MemWrite ? '*' : '_');
ss << (top->lcd_Branch ? '*' : '_');
fl_draw(ss.str().c_str(), x() + XMARGIN, y() + DISPLAY_FONT_SIZE+LCD_FONT_SIZE);
// second line
ss.str(""); // reset stringstream
ss << setw(2) << (int)top->lcd_SrcA;
ss << " " << setw(2) << (int)top->lcd_SrcB;
ss << " " << setw(2) << (int)top->lcd_ALUResult;
ss << " " << setw(2) << (int)top->lcd_Result;
ss << " " << setw(2) << (int)top->lcd_ReadData;
ss << (top->lcd_MemtoReg ? '*' : '_');
ss << (top->lcd_RegWrite ? '*' : '_');
fl_draw(ss.str().c_str(), this->x() + XMARGIN, y() + DISPLAY_FONT_SIZE+2*LCD_FONT_SIZE);
register_labels();
int yy = y() + 3*DISPLAY_FONT_SIZE + 2*LCD_FONT_SIZE;
// register values
ss << nouppercase;
for(int i = 0; i < NREGS; i++) { // for all registradores
if(i % NREGS_PER_LINE == 0) { // start of line
ss.str(""); // reset stringstream
ss << " ";
}
ss << " : " << setw(2) << (int)top->lcd_registrador[i];
if(i % NREGS_PER_LINE == NREGS_PER_LINE-1) { // end of line
fl_draw(ss.str().c_str(), this->x() + XMARGIN, yy += 1.5*DISPLAY_FONT_SIZE);
}
}
}
}
void hexval::draw() {
this->window()->make_current(); // needed because draw() will be called from callback
if(fpga->lcd_check->value()) {
fl_rectf(x(), y(), w(), h(), FL_WHITE); // clean LCD window
lcd_lines((long)top->lcd_a, (long)top->lcd_b);
}
}
int main(int argc, char** argv, char** env) {
init_gui(argc,argv, (char *)"Labarc FPGA Simulator");
Verilated::commandArgs(argc, argv); // Remember args
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
top = new Vtop;
top->SWI = 0; // Initial settings of inputs
top->clk_2 = 0;
Fl::run(); // run the graphical interface which calls callback()
// Final Verilog model cleanup
top->final();
// Destroy Verilog model
delete top;
delete_gui();
// Fin
exit(0);
}