Two simulators
Why an RTL++ test passes only when Icarus Verilog and a netlist simulator agree on every sample, what a disagreement means, and how unknown values are found.
A simulator can be wrong, and so can a design that only works in one simulator. So every test runs twice.
- Icarus Verilog runs the testbench, as the reference.
- The netlist simulator replays each design instance under the testbench, up to 4, from its Yosys netlist with the same parameters and the same input changes, while Icarus runs.
- Outputs are compared just before each clock edge, where no assignment can race the sample.
A test passes only when Icarus passes it and the replay matches on every sample. When the replay cannot run, the test reads Passed in Icarus only, with the reason, and is never counted as a pass.
When they disagree
The test reads Simulators disagree and names the first signal, the time and both values, with the likely cause:
- Unknown values
- One of them has unknown bits. Give that state a reset or an initial value.
- A race
- The values match one sample apart, the signature of processes racing. Use non-blocking assignments in clocked logic.
- Neither
- Both values are known and no race was found, so it may be an engine bug.
Unknown values
Every run is also searched for unknown values that matter: an output that becomes x, and a branch condition that is x when it is decided. Each finding has the time it first appears, and a design that ran before its reset says how many clock cycles it ran unknown.