HDL simulator observations: thirty original examples

Dataset Last tested 24 October 2026

The thirty fixtures produced twenty matching and ten differing observation payloads across the two pinned simulator configurations. Eight differences involved unknown values or initialization, and two involved built-in seeded random streams. Every one of the sixty tool/fixture combinations repeated its own observation payload on a second execution; this is a reproducibility result for these examples, not a simulator compliance ranking.

Compare observations without discarding the original output

Each fixture prints lines beginning with OBS. The compact table compares those deliberate observations, while the data retains compiler output, runtime output, warnings and return codes. Simulator finish banners are not counted as design-behavior differences. A matching payload means the selected printed observations matched; it does not establish equivalence for behavior the fixture never observed.

Example sourceIcarus observationVerilator observationPayload
F01: Explicit unknown assignmentOBS value=10x1 unknown=1OBS value=1001 unknown=0Different
F02: Uninitialized registerOBS value=xxxxxxxx unknown=1OBS value=00000000 unknown=0Different
F03: Mixed signed comparisonOBS mixed_less=0 cast_less=1OBS mixed_less=0 cast_less=1Same
F04: Assignment-width truncationOBS narrow=1 wide=17OBS narrow=1 wide=17Same
F05: Clocked nonblocking updateOBS a=1 b=0OBS a=1 b=0Same
F06: Signed extensionOBS a=-8 b=-8 bits=fff8OBS a=-8 b=-8 bits=fff8Same
F07: Unsigned extensionOBS a=248 b=248 bits=00f8OBS a=248 b=248 bits=00f8Same
F08: Logical and arithmetic shiftsOBS logical=3c arithmetic=fcOBS logical=3c arithmetic=fcSame
F09: Unsized literal widthsOBS decimal_bits=32 hex_bits=32 value=1OBS decimal_bits=32 hex_bits=32 value=1Same
F10: Expression assignment contextOBS narrow=0 wide=16OBS narrow=0 wide=16Same
F11: Concatenation unsigned comparisonOBS signed_less=1 concat_less=0OBS signed_less=1 concat_less=0Same
F12: Explicit signed castOBS unsigned=255 signed=-1OBS unsigned=255 signed=-1Same
F13: Unknown condition in ifOBS sel=x branch=2OBS sel=0 branch=2Different
F14: Unknown conditional bit mergeOBS value=10xxOBS value=1001Different
F15: Case equality against unknownOBS ordinary=x case_x=1 unknown=1OBS ordinary=1 case_x=0 unknown=0Different
F16: Reduction with unknown bitOBS and=x or=1 xor=xOBS and=0 or=1 xor=1Different
F17: Controlling bitwise zeroOBS x_and_0=0 x_or_1=1OBS x_and_0=0 x_or_1=1Same
F18: Unknown XOR operandOBS x_xor_0=xOBS x_xor_0=0Different
F19: Two-state bit assignmentOBS bit=0 logic=xOBS bit=0 logic=0Different
F20: Explicit register initializationOBS value=5aOBS value=5aSame
F21: Declaration initializationOBS value=a5OBS value=a5Same
F22: Blocking statements in one processOBS a=2 b=2OBS a=2 b=2Same
F23: Nonblocking swap after edgeOBS a=2 b=1OBS a=2 b=1Same
F24: Last nonblocking assignment in processOBS a=2OBS a=2Same
F25: Three-stage pipelineOBS a=1 b=0 c=0; OBS a=2 b=1 c=0; OBS a=3 b=2 c=1OBS a=1 b=0 c=0; OBS a=2 b=1 c=0; OBS a=3 b=2 c=1Same
F26: Opposite-edge stimulusOBS d=1 q=1OBS d=1 q=1Same
F27: Asynchronous reset then clockOBS reset_q=0; OBS clock_q=1OBS reset_q=0; OBS clock_q=1Same
F28: Explicit modulo arithmetic sequenceOBS state=3d20bdba; OBS state=e9dab1d1; OBS state=9ccc40fcOBS state=3d20bdba; OBS state=e9dab1d1; OBS state=9ccc40fcSame
F29: Seeded random sequenceOBS random=8011ec00 seed=0011ea9e; OBS random=61e0e9c3 seed=e1e0e687; OBS random=b3547666 seed=3354751cOBS random=979a27f1 seed=a79f332a; OBS random=7d04cbad seed=83d6c4a7; OBS random=9c22637a seed=0e23cf8bDifferent
F30: Seeded urandom processOBS urandom=0011ec00; OBS urandom=e1e0e9c3; OBS urandom=33547666OBS urandom=a79f332a; OBS urandom=979a27f1; OBS urandom=b38d6fdbDifferent

The JSON, CSV and method retain commands, hashes and literal outputs. Original observations are CC BY 4.0; the original fixture code is MIT licensed.

Read unknown-value results with the selected configuration

F01 assigns an explicit unknown bit. Icarus prints OBS value=10x1 unknown=1; the selected Verilator configuration prints OBS value=1001 unknown=0. F02 likewise distinguishes an uninitialized register represented as unknown bits from the selected zero initialization policy. These outcomes must be read with the declared state model and command-line choices, not as evidence that a hardware signal starts at zero.

Verilator documents its treatment of unknown values and the options controlling unknown assignment and initialization1. The fixture records those settings so a recipient can reproduce the observation or deliberately run a different configuration. Changing an option creates a new experiment; it should not silently replace the published row.

F19 provides a useful contrast: the explicit two-state bit variable is printed as zero by both tools, while the accompanying logic value differs. That row keeps the declaration choice visible. It prevents the broad conclusion that every value in one source file has the same unknown-value behavior.

Keep widths, scheduling and seeds explicit

The width cases record their signedness, sizing and output rather than inferring behavior from a literal’s appearance. Icarus documents its expression-width choices and the strict-width option used here2. Use the exact source and options when interpreting a result involving an unsized expression, truncation or sign extension.

The ordering cases are intentionally small and deterministic under their recorded stimulus. They are not a licence to depend on the execution order of competing processes in a larger testbench. Preserve the observation point as well as the assignment: a value printed before an update and one sampled after it answer different questions.

F29 and F30 use fixed seeds with built-in random functions. Their streams repeat within each tool but differ between tools. Store the selected test and seed together with the simulator configuration; a shared numeric seed alone did not produce a shared stream in these observations. The row keeps literal values so that a repeat can be checked without reducing the output to a generic pass label.

Read warnings before reusing a fixture

A zero return code does not mean that no diagnostic was emitted. The dataset preserves warning text even when execution continued. Verilator’s warning documentation provides the named diagnostic context3; the recorded command states how warnings affected this run. Review the message and the source together before adopting the example’s configuration in another project.

For a project-specific investigation, reduce the disputed behavior to an original minimal fixture, name the expected observation and preserve both tool configurations. The handoff guide shows how a byte-level manifest can detect changed inputs. It complements the measured observations without converting agreement between two runs into a general correctness claim.

Use the observation viewer to search the same thirty examples.

Not covered on this page

Sources

  1. Verilator command-line options. ↩

  2. Icarus Verilog expression-width documentation. ↩

  3. Verilator errors and warnings. ↩

Code on this page is original and MIT licensed.

How we test: methodology. Found a mistake? Corrections.