summaryrefslogtreecommitdiff
path: root/src/main/resources/chisel3
diff options
context:
space:
mode:
authorSchuyler Eldridge2021-03-18 12:28:09 -0400
committerGitHub2021-03-18 12:28:09 -0400
commitac094a5e8f7fb8237b54d4d6b9e0b7b759b44ef7 (patch)
treed0970ea7b8ad7bc0b78583fb8c53d5ada5be730c /src/main/resources/chisel3
parent492a71d6d4d3acef39f29345835637bca028a089 (diff)
Don't toggle top.cpp clock and reset on same cycle (#1820)
Change top.cpp to deassert reset one time unit before the clock asserts. This avoids a Verilator simultation issue in top.cpp where the eval() function is only called once per simultation loop. If the clock and reset are both changed and eval() is only called once, then any combinational update due to a change in reset is not visible to the sequential logic. This avoids issues where the downstream compilation utilities move synchronous reset logic outside of an always block that describes a synchronous reset flip flop. Reset now deasserts on time unit 10 and the clock ticks on time unit 11. h/t @albert-magyar Signed-off-by: Schuyler Eldridge <schuyler.eldridge@sifive.com>
Diffstat (limited to 'src/main/resources/chisel3')
-rw-r--r--src/main/resources/chisel3/top.cpp12
1 files changed, 9 insertions, 3 deletions
diff --git a/src/main/resources/chisel3/top.cpp b/src/main/resources/chisel3/top.cpp
index 4e9c1433..a3475e2f 100644
--- a/src/main/resources/chisel3/top.cpp
+++ b/src/main/resources/chisel3/top.cpp
@@ -47,8 +47,15 @@ int main(int argc, char** argv) {
cout << "Starting simulation!\n";
while (!Verilated::gotFinish() && main_time < timeout) {
- if (main_time > 10) {
- top->reset = 0; // Deassert reset
+ // Deassert reset on timestep 10. This needs to occur before the clock
+ // asserts on timestep 11 because there is a single call to top->eval() in
+ // this loop. Verilator evaluates sequential logic (always blocks) before
+ // combinational logic during top->eval(). Staggering the reset update is
+ // necessary to produce the same simulation behavior independent of whether
+ // or not the generated Verilog puts synchronous reset logic inside or
+ // outside its associated always block.
+ if (main_time == 10) {
+ top->reset = 0;
}
if ((main_time % 10) == 1) {
top->clock = 1; // Toggle clock
@@ -92,4 +99,3 @@ int main(int argc, char** argv) {
if (tfp) tfp->close();
#endif
}
-