Open RobertBaruch opened 3 years ago
This is a well known issue. There is a workaround for it that's supposed to be firing here, but doesn't. I'll look into it.
Wait, no, this is a different, much less well known issue. I've actually never seen this before, but it makes sense:
[T]he bug is the race between the always at time zero getting to the @ and the initial setting the values. A [#0] in the initial block before changing a or b should do the trick.
I don't really want to see
initial #0
in Verilog for synthesis.
Why not? I believe that most, possibly all, synthesizers ignore it, to solve exactly this kind of issue. Alternatively, we could guard its use with `ifdef SYNTHESIS
.
Oh, I didn't know that synthesizers would ignore it -- I thought they'd yell and scream about non-synthesizable statements. In that case it's fine to put it in there!
You mean something like this?
`ifndef SYNTHESIS
initial #0 begin ... end
`endif
BTW, I found that in the generated Verilog, this will not pass the test:
(* src = "simbug.py:12" *)
reg _b = 1'h0;
initial #0 begin _b = 1'h0; end
But this does:
(* src = "simbug.py:12" *)
reg _b;
initial #0 begin _b = 1'h0; end
As does this:
(* src = "simbug.py:12" *)
reg _b;
initial begin _b = 1'h0; end
Are the last two equivalent?
Another interesting data point. If I compile simbug.py to rtlil, then use yosys to convert that to verilog via:
yosys> read_ilang simbug.il
yosys> proc
yosys> write_verilog simbug.v
Then the test passes. Presumably because there are no always @*
in the output? I dunno.
Hi, I ran into this a year ago and I thought it was a bug in Icarus Verilog (my bad), so I reported it here.
There are two possible workarounds that, while none of them is a clean solution, may help someone until this is solved:
-g2005
in iverilog (the drawback is that you'll lose support for System Verilog)
Minimal test case. simbug.zip
Summary: The Verilog that nMigen outputs can contain time-0 race conditions which cause problems for simulation.
Details:
I'm running through the Zero to Asic course using nMigen. The digital design part assumes you're writing Verilog, runs the code through Icarus Verilog, and then simulates/tests using cocotb. Everything is fine, except I managed to stumble into a Verilog simulation subtlety. Best explained by the Icarus Verilog FAQ:
The Verilog generated by nMigen is something like this:
This results in the time-0 race described above. While not synthesizable, manually altering the Verilog resolves the problem:
You'd think that you could use a reset signal to reset registers to known states, but that doesn't fix the problem.
I emphasize that this is a simulation issue, not a synthesis issue. I'm honestly not sure what the solution here is. I don't really want to see
initial #0
in Verilog for synthesis.