gc_bba_test: tell a spent id_phase from a real fault using the hardware

The ID tests guarded on g_ncra_reset_done, which is software state standing in
for hardware state.  The two come apart exactly when a build is delivered over
the wire: netboot replaces the DOL and restarts the app with the flag clear,
while the FPGA keeps running with id_phase already spent by the previous run.
The app then queries address 0, gets NCRA back -- correct behaviour -- and
reported a FAILURE for it.  That is why the ID tests would sometimes skip and
sometimes fail for the same expected condition.

Both tests now ask the hardware instead.  HIPR and NWAYS are hardwired
constants in the register file and do not depend on id_phase, so if both read
correctly the EXI path is demonstrably fine and a wrong answer at address 0 can
only be a spent id_phase -> SKIP, with "reflash FPGA" in the message.  If they
are wrong too, something real is broken and the test still FAILS.

The flag is kept only as a fast path for a reset issued during the same run,
with a comment saying it can be stale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-10 10:17:41 +02:00
parent 2b0cbdd809
commit 5ee1b9d07b
2 changed files with 52 additions and 8 deletions
+12 -2
View File
@@ -88,8 +88,18 @@ Reset/control, EXI integrity (speed sweep `ok=[1,1,1,1,1,1]`, per-speed dump
clean at all six indices, raw reg dump `0x17` in slot 0), Ethernet, and
SPRAM/DMA. The EXI front end runs at the real 27 MHz hardware rate.
(`Raw ID dump` reports SKIP once an earlier suite has issued the NCRA reset
that clears `id_phase` — reflash or reset the FPGA to restore it.)
(The ID tests report SKIP, not FAIL, once `id_phase` has been consumed —
reflash the FPGA to restore it. They decide that from the hardware, via
`iface_alive()`: HIPR and NWAYS are hardwired and independent of `id_phase`, so
if both read correctly the EXI path is fine and only a spent `id_phase` can
explain a wrong answer at address 0.
⚠️ The `g_ncra_reset_done` flag alone is NOT sufficient, and this bites every
time a build is delivered over the wire: netboot replaces the DOL and restarts
the app with the flag clear, while the FPGA keeps running with `id_phase`
already spent by the previous run. The app then queries address 0, gets NCRA
back — correct behaviour — and called it a FAILURE. Software state cannot stand
in for hardware state across a self-update.)
**Timing closes on EVERY seed (re-measured 2026-10-10).** `python -m
exi_bba.synth --seeds 8`: