Every runnable example in this course uses two free simulators: Verilator 5.048 and Icarus Verilog 13. Neither implements all of SystemVerilog. Most gaps are loud: the tool refuses the code. A few are quiet: the code compiles and the answer is wrong. This page lists both kinds for the three parts where it matters most, so you know which results to trust.
You do not need this page yet. Come back to it when a lesson in Part 3, 4 or 5 says a listing is not run, or when your own experiment in Code Lab disagrees with a lesson.
Each row comes from a small test with a known answer, written for this page: a trace where the right verdict is worked out by hand, including at least one case that must fail. A row says runs only when the tool gave the right answer on that trace, not merely when it compiled.
Icarus 13 has no constraint support at all, so every row below is about Verilator 5.048.
Feature | Verilator 5.048 | What the course does |
|---|---|---|
| Runs: every solve was legal | Runs the real solver many times and checks every result |
| Runs: every block of N calls was a full permutation | Runs it |
| Runs: measured shares within about 1.5 points of the predicted weights | Shows measured shares beside the predicted ones |
| Differs a little: about 90% where renormalising the weights gives 93.1% | Shows both numbers |
| Differs: the weights were ignored and every name came out about equally often. Numeric values ( | Writes the numeric values, with the names in a comment |
Uniform choice over the legal solutions | Differs: | Teaches the standard's numbers and shows Verilator's measured numbers next to them |
| Differs, and not consistently: in one test the flag came out about 30% where the standard gives 50%; in another it was never set at all; on a starved enable bit it gave 26% where the standard gives 50%. Every solve stayed legal. A | Teaches the standard's numbers; the benches check legality and print the measured rates |
| Runs: a hard rule discards the soft one, and the later of two softs wins, as the standard says | Runs it |
| Differs: the weights applied, but a hard inline rule that contradicted the soft | Says so; the bench checks only the weights |
| Runs. Reading | Uses the variable form |
| Runs, but | Says so where hooks are taught |
A contradiction: | Runs, with an | Runs it |
| Runs | Runs them |
Object random stability: an object seeded at | Runs, as the standard says; an extra | Runs it |
| Runs: restoring the state repeated the next draw | Runs it |
| Runs on its own. Once the design names | Reseeds with |
A function call in a constraint ( | Differs, in the helpful direction: the argument was not solved first, so a later bound pushed back through the call. 400 of 400 calls solved where the standard's order makes most of them fail | Teaches the standard's order and shows Verilator's result |
| Differs: the | Teaches the standard's order and shows Verilator's result |
| Rejected: "Unsupported" | Shown as a fragment |
| Differs: other | Uses |
Dynamic array | Runs | Runs it |
| Runs | Runs it |
| Differs: the total was computed wide, so | Teaches the widened form, which is right on every tool, and shows Verilator's result |
| Differs: the solver stopped with an internal error, and later solves in the same run went wrong | Zeroes unused bytes, so the reduction runs over the whole array |
A size whose elements are infeasible ( | Better than the standard promises: 300 of 300 calls solved, using only the feasible sizes 1 to 7 | Teaches the standard's size-first risk and shows Verilator's result |
| Differs: every solve failed as unsatisfiable | Uses a fixed-size array plus a length field |
| Runs on a fixed-size array when another rule also names its elements (such as a range); with | Uses |
| Differs: about a third of the calls failed as unsatisfiable, though legal answers existed | Keeps the |
One | Runs, including constraints across the two objects | Runs it |
A null | Runs as the standard says when the handle's class has no constraints: skipped, and | Builds every rand handle in |
A null-handle guard in a constraint ( | Differs: the handle was dereferenced anyway and the run stopped with "Null pointer dereferenced", in both the | Copies the value into a plain field plus a "have previous" bit |
A constraint that reads another object's | Differs: after that, | Copies the configuration value into a plain field of the transaction |
Arrays of | Differs: each element's own constraints were ignored | Shown as a fragment, with a fixed-size field array as the runnable form |
Icarus 13 has no concurrent assertions. Verilator runs them only when asked: the course's checks pass --assert, and --coverage whenever a listing has a cover property.
Feature | Verilator 5.048 | What the course does |
|---|---|---|
| Runs: right verdicts, including the failing cases | Runs real assertions with a planted bug |
Multi-step sequences in an assertion: repetition and | Differs, depending on where the trace breaks: | Teaches the full forms; benches show the compact form's count beside a form that works: fixed delays, written-out repetition, a split into simple implications, or a few lines of modeling code |
Goto | Differs: that occurrence was not counted, so | Starts goto counts on a cycle before the first event |
| Differs: matched nothing, as an assert or a cover | Uses a flag set by modeling code for the first event |
| Runs: caught a planted abort | Runs it |
A named | Rejected: "Cycle delays not allowed as intra-assignment delays", with or without a default clocking block. A body that starts with the delay ( | Writes the sequence inline in the property, and says where a named sequence would go |
| Ignored with a | Uses |
| Runs | Runs them |
| Rejected: "Unsupported: $past expr2 and/or clock arguments" | Uses a small flop to hold the gated value |
| Runs | Runs them |
| Never fires: Verilator is 2-state, so X becomes 0 or 1 | Shows X behaviour on Icarus with immediate checks |
| Differs: when | Writes |
| Rejected: "Unexpected 'not' in sequence expression context" | Writes |
| Stops the run at the first failure: the default error limit is 1. The run-time option | Counts failures in the action block ( |
| Rejected: "Unsupported: property case expression" | Writes one implication per arm |
| Rejected: "Unsupported" | Writes |
| Runs: right verdicts on a known trace | Runs them |
Sequence | Runs: the cover counted the right match with | Runs it |
Ranged goto | Rejected: "Unsupported" | Uses a fixed |
| Rejected: "Unsupported" | Shown as a fragment |
| Rejected: the tool stopped with an internal error | Shown as fragments, with a counter as the runnable form |
| Runs (cover count correct) | Runs it |
| Rejected | Shown as fragments |
Local variables in a property | Differs: compiled, but the captured value was not held, so the verdict was wrong | Uses a small scoreboard instead; the Expert part has the details |
| Counts correctly with | Builds covers with |
Immediate | Runs | Runs them |
Feature | Tool behaviour | What the course does |
|---|---|---|
| Verilator 5.048 compiles them with a | Teaches the real syntax, and gets real numbers from a small bins model written in plain classes, which runs and prints a report shaped like a simulator's |
Code coverage (lines, toggles) | Verilator runs it with | Shows real line coverage where code and functional coverage are compared |
| Counted with | Used as the third coverage instrument |
get_inst_coverage() print on Verilator 5.048?0.0. Verilator parses covergroups but does not count them, and it says so only in a COVERIGN warning. The lessons get their numbers from the bins model instead.
Because some features compile and still give wrong answers: unique that is not unique, b[*3] that misses a failure, a local variable that does not hold its value. Only a test with a known answer, including a case that must fail, tells you the feature works.
Every row was measured on 2026-10-18 with a directed test whose right answer was worked out by hand, including at least one failing case: 16 randomization probes (thousands of solves each for the share rows, with three seeds) and 35 assertion and coverage probes, on Verilator 5.048 with --binary --timing --assert, and --coverage where a cover property is counted. Icarus 13 rejected every constraint and concurrent-assertion probe.
Two rows differ from the Expert part's earlier table: ##1 (!x) was still rejected with the parentheses, and a cover only counts when --coverage is on.