patch notes · #294 October

#29 · A failed build leaves no old bitstream, wrong pins are named, a quick save rebuilds

A wrong pin name stops at its own XDC line. With PACKAGE_PIN ZZ99 on the clock line, the pin check printed xdc ok: 33 ports, all mapped., then nextpnr stopped with its raw ERROR: Unable to constrain IO 'clk', device does not have a pin named 'ZZ99', no file, no line, no fix. Now the check reads the chip's own pin list (the prjxray database the bitstream is built from) and stops first: blink.xdc:5: ERROR [no-such-pin]: ZZ99 is not an I/O pin of the Basys3's chip ... Fix: .... A pin written in small letters (w5) and two ports on one pin ([pin-used-twice], both lines named) are caught the same way. If nextpnr still refuses a pin, its line gets the same code and XDC line.

A failed build leaves no old bitstream. After that failure the previous blink.bit was still in the folder, byte for byte the old design, with its .fasm, .frames and routed netlist. Anything that loads the file by name would load yesterday's design. The pin-and-route stage now removes its outputs before it starts, as synthesis already did; dewfpga flash after a failed build stops at the same error line.

A save in the same second rebuilds. macOS's make (3.81) compares whole seconds. A testbench edited within the second of the last compile was not newer to it: dewfpga sim ran the old simulation and printed its old PASS (measured: an edit 0.4 s after the build, 0 of 5 rebuilt). VS Code's save and build in one keystroke hits exactly this. The stage records a checksum of every source next to its file list; when the content differs the stage builds again. With the planted $error and the same timestamp, sim now compiles, prints the error and exits 2. Blink's simulation time did not change (0.14-0.20 s).

On a real Basys3 (6 October). The board test ran with a board for the first time: dewfpga flash programmed blink (openFPGALoader's Done line, no ERROR). With PACKAGE_PIN ZZ99, dewfpga flash stopped at blink.xdc:5: ERROR [no-such-pin], never started the programmer, and left no .bit.

Tests. 8 new checks (listed checks 329 → 337; with #28's six, 343), each with a mutation: removing the old-output cleanup, the pin list, the duplicate-pin check, nextpnr's coded lines or the checksum rebuild turns its check red. The same-second checks ran three times in a row and passed each time. Not verified: nextpnr's behaviour on the chip's 14 transceiver pads, which the pin list accepts.

Closing run (6 October, board unplugged). test/run.sh: passed 314, failed 0, known gaps 25 in 21 min 7 s, the board check skipped (SKIP flash on the board: no board; no FTDI device on the USB bus at that hour), the probe table byte-identical to the two runs before it. Two checks were red in the run before it, neither in the product: shellcheck read the Verilog $error in a new test function as a shell variable (the directive the sibling functions carry was missing), and the MCP check's SDK venv lived in $TMPDIR, which macOS empties of files untouched for three days (the venv was built on 3 October; on the 6th it had 420 directories and 0 .py files, so dewfpga mcp reported mcp-not-installed; python3.14 -m venv and pip install -r templates/mcp-requirements.txt rebuilt it and the check passed alone and in the full run). The mail suites: 9 suites, each exit 0 (activation SQL 142, SQL 187 with 154 privilege checks, mail flow 60, sender idempotency, lifecycle 112, usage 13, integration 8, pages 139, Chromium and WebKit 158; 0 failures). Site check: 112 pages, 2053 links, 0 failures.


previous: #28 dewfpga sim simulates what the build reads when iverilog refuses the design
next: #30 The install keeps only the chain that runs: about 0.25 GB on disk instead of 1.5
This entry in the full list
The commands this entry names: dewfpga sim · dewfpga flash · dewfpga mcp
Every SystemVerilog construct measured so far, next to what Vivado does: the probes, stage by stage