-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsim_main.cpp
More file actions
146 lines (121 loc) · 5.45 KB
/
sim_main.cpp
File metadata and controls
146 lines (121 loc) · 5.45 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
#include <verilated.h>
#include <verilated_vcd_c.h>
#include "Vsha256_processor_tb.h"
#include <iostream>
#include <iomanip>
int main(int argc, char** argv) {
// Initialize Verilator
Verilated::commandArgs(argc, argv);
// Enable debug output from Verilog $display statements
Verilated::debug(0);
// Ensure stdout is line-buffered for real-time output
std::cout.setf(std::ios::unitbuf);
std::cerr.setf(std::ios::unitbuf);
// Create instance of our module
Vsha256_processor_tb* tb = new Vsha256_processor_tb;
// Initialize VCD tracing
Verilated::traceEverOn(true);
VerilatedVcdC* tfp = new VerilatedVcdC;
tb->trace(tfp, 99);
tfp->open("sha256_processor_waveform.vcd");
// Simulation variables
vluint64_t sim_time = 0;
const vluint64_t max_sim_time = 100000000; // 100ms max simulation time
std::cout << "=== SHA256 Processor Simulation ===" << std::endl;
std::cout << "Starting Verilator simulation..." << std::endl;
// Initialize clock to 0 and ensure initial evaluation
tb->ext_clk = 0;
tb->eval();
tfp->dump(sim_time++);
// Debug variables
bool prev_test_complete = false;
vluint64_t last_debug_time = 0;
int clock_edges = 0;
bool simulation_started = false;
std::cout << "Initial evaluation complete, starting clock..." << std::endl;
// Run simulation
while (sim_time < max_sim_time && !Verilated::gotFinish()) {
// Generate a proper clock: toggle every 5 time units (100MHz, 10ns period)
bool new_clk = ((sim_time / 5) % 2) == 1;
if (new_clk != tb->ext_clk) {
tb->ext_clk = new_clk;
clock_edges++;
// Print first few clock edges for debugging
if (clock_edges <= 10) {
std::cout << "Clock edge " << clock_edges << " at time " << sim_time
<< " (clk=" << (int)tb->ext_clk << ")" << std::endl;
}
}
// Evaluate the design
tb->eval();
std::cout.flush();
// Dump trace data
tfp->dump(sim_time);
// Check if simulation has actually started (testbench is running)
if (!simulation_started && clock_edges > 5) {
simulation_started = true;
std::cout << "Testbench should be running now..." << std::endl;
}
// Debug output every 1M time units or when important events happen
if (((sim_time % 1000000) == 0 && sim_time > last_debug_time) ||
(clock_edges > 0 && clock_edges <= 20 && (clock_edges % 5) == 0)) {
std::cout << "Debug @ " << sim_time/1000.0 << "K: ";
std::cout << "clk=" << (int)tb->ext_clk;
std::cout << ", test_complete=" << (int)tb->test_complete;
std::cout << ", test_passed=" << (int)tb->test_passed;
std::cout << ", clock_edges=" << clock_edges;
std::cout << std::endl;
if (sim_time % 1000000 == 0) {
last_debug_time = sim_time;
}
}
// Check if test completed (only on positive clock edge to avoid glitches)
if (tb->ext_clk && tb->test_complete && !prev_test_complete) {
std::cout << "\n=== Test Completed ===" << std::endl;
if (tb->test_passed) {
std::cout << "✓ SHA-256 Test PASSED!" << std::endl;
} else {
std::cout << "✗ SHA-256 Test FAILED!" << std::endl;
}
// Run a few more cycles to capture the completion in VCD
for (int i = 0; i < 100; i++) {
sim_time++;
bool extra_clk = ((sim_time / 5) % 2) == 1;
tb->ext_clk = extra_clk;
tb->eval();
tfp->dump(sim_time);
}
break;
}
prev_test_complete = tb->test_complete;
// Progress indicator (less frequent to avoid spam)
if ((sim_time % 10000000) == 0 && sim_time > 0) {
std::cout << "Simulation progress: " << sim_time/1000000.0 << "M time units, "
<< clock_edges << " clock edges" << std::endl;
}
// Early exit check if we've been running for a while but test hasn't started
if (sim_time > 1000000 && !simulation_started) {
std::cout << "WARNING: Simulation has been running for 1M time units but testbench may not be active!" << std::endl;
std::cout << "Clock edges: " << clock_edges << std::endl;
}
// Advance time
sim_time++;
}
// Check if simulation completed normally
if (Verilated::gotFinish()) {
std::cout << "Simulation completed via $finish!" << std::endl;
} else if (sim_time >= max_sim_time) {
std::cout << "Simulation timed out!" << std::endl;
std::cout << "Consider increasing max_sim_time or checking for infinite loops." << std::endl;
std::cout << "Total clock edges generated: " << clock_edges << std::endl;
}
// Clean up
tfp->close();
delete tb;
delete tfp;
std::cout << "Total simulation time: " << sim_time << " time units" << std::endl;
std::cout << "Total clock edges: " << clock_edges << std::endl;
std::cout << "Waveform saved to sha256_processor_waveform.vcd" << std::endl;
std::cout << "Use 'gtkwave sha256_processor_waveform.vcd' to view waveforms" << std::endl;
return 0;
}