diff options
| author | Schuyler Eldridge | 2021-03-18 12:28:09 -0400 |
|---|---|---|
| committer | GitHub | 2021-03-18 12:28:09 -0400 |
| commit | ac094a5e8f7fb8237b54d4d6b9e0b7b759b44ef7 (patch) | |
| tree | d0970ea7b8ad7bc0b78583fb8c53d5ada5be730c /src/main/resources | |
| parent | 492a71d6d4d3acef39f29345835637bca028a089 (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')
| -rw-r--r-- | src/main/resources/chisel3/top.cpp | 12 |
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 } - |
