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.

  1. Icarus Verilog runs the testbench, as the reference.
  2. 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.
  3. 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.