patch notes · #317 October

#31 · A random-design generator checks the SystemVerilog DDCA teaches against its own simulation

The product did not change in this update. It adds a test tool, test/fuzz, separate from test/run.sh: gen.py <seed> <folder> writes a random design in the SystemVerilog the course book (DDCA, chapters 4, 5 and 7) and CS223 teach, on the Basys3's own ports, with its XDC and a testbench of 300 cycles of random switches and buttons that prints every output every cycle and expects nothing. Forty language features are switches (always_comb, case without default, casez, unique case, async reset, a start value in the declaration, always_latch, an enum state machine, parameters and #(.N(..)) overrides, generate for/if, packed and unpacked arrays, a memory, packed structs, typedefs, functions with break, a for loop in always_comb, named, positional and .* connections, a package in its own file, submodules in their own files, signed arithmetic, shifts, reductions, concatenation, $clog2, mixed widths, the seven-segment ports, three or four levels of modules, the same submodule twice); a seed draws them, --on/--off force them, so a failing design narrows to the feature that causes it. run.sh <first seed> <count> runs each design through dewfpga sim (the RTL in iverilog) and dewfpga bit, then simulates the netlist the build made (read_json, write_verilog, iverilog with yosys' Xilinx cell models, the same testbench, the way test/sv does) and compares the two traces bit by bit: a bit the RTL knows (0 or 1) must be the same in the netlist, an x in the RTL matches anything. Six outcomes per seed: ok, silent-wrong (the bitstream built, the netlist does not do what the simulation showed), refused-coded, refused-uncoded, crash, sim-refused (no independent reference: dewfpga sim failed or ran on the build's view). The last line is the metric, fuzz: ok 123 of 144; silent-wrong 10; refused-coded 6; refused-uncoded 0; crash 0; sim-refused 5, and a failed seed's folder stays.

What 194 designs found. Seeds 1-12, 100-243 and 500-537 (two batches stopped at the 90-minute mark; a seed costs about 8 s, of which dewfpga bit about 4.5 s): 168 ok, 14 silent-wrong, 6 refused with a code, 0 refused without one, 0 crashes, 6 sim-refused. The failures fall into six families, each with the update that owns it:

Numbers. From the closing run of this tree: Vivado-supported probes passing all four stages 86/111 → 86/111, all four stages 95/133 → 95/133, synthesis 108/133 → 108/133, known gaps 25 → 25, the probe table byte-identical to #30's closing run (the compiler did not change). test/run.sh: passed 314, failed 0, known gaps 25 in 20 min 52 s, the board check skipped (SKIP flash on the board: no board; no FTDI device on the USB bus at that hour), no check changed since #30 (the 320 of #30's run included its FULL=1 clean install, not run here). The listed count stays 347: test/fuzz is not in the suite and is not in CI.

Tests. The tool is the test; what it checks on the product is the comparison above. The four shrunk reproductions were run through run.sh's steps by hand: the unique casez and the always_latch ones MISMATCH, the enum state machine and an 8x8 multiplier EQUAL: 4 cycles. compare.py on the kept folders gives the lines quoted above. Mail suites: 9 suites, each exit 0 (activation SQL 142, SQL 187, mail flow 60, sender idempotency, lifecycle 112, usage, integration, pages 139, Chromium and WebKit 158; 0 failures). Site check: 112 pages, 2056 links, 0 failures.

Open.


previous: #30 The install keeps only the chain that runs: about 0.25 GB on disk instead of 1.5
next: #32 A latch whose gate and data change together, and a unique casez whose items overlap: the chain names both before the board differs from the simulation
This entry in the full list
The commands this entry names: dewfpga sim · dewfpga bit
Every SystemVerilog construct measured so far, next to what Vivado does: the probes, stage by stage