Per-vertex GS fog end-to-end (gs_stub emit incl. persp_emit5, gs_prim_list_feeder XYZ2->XYZF2 on PRIM.FGE, gs_make_sh3_scheduler_fixture.py F/FGE packing), new fog TBs, fidelity attribution tooling. Functional baseline before removing the dead bilinear lerp8 clamps (Codex: 161-node comb loop -> -0.042ns setup fail). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3.4 KiB
Ch420 — request FIFO dedicated read-address stage (prefit)
Trigger
Ch419 removed both intended timing families and reduced setup from
-0.388 ns / -7.218 ns to -0.115 ns / -1.150 ns. Its completed fit exposed
one uniform remaining family: request FIFO rbin[6] directly driving the wide
banked RAM's portbaddr[6] network.
This is not a new functional cone and not a reason to reroll placement. The
paths have zero logic levels, fan-out 713, and spend 2.892 ns of 3.192 ns
in one interconnect route.
Structural cut
Registered-read mode in gs_async_fifo now has a dedicated RAM-facing
raddr_q stage, marked dont_merge, preserve so it cannot collapse back into
the binary CDC pointer.
raddr_q captures rbin_nxt while the synchronous RAM reads the prior
raddr_q. Before each edge, raddr_q equals the current head address, so the
returned entry and accepted-pop latency are unchanged for isolated and
back-to-back reads. The added boundary only separates pointer/empty logic from
the physical address fan-out and gives the fitter a placeable/duplicable RAM-
local launch register.
The stage intentionally has no reset or clock enable. The FIFO remains empty for multiple read clocks while the write pointer crosses its two synchronizer flops, so the address has settled to zero before any legal pop. Avoiding reset and enable prevents recreating the prior high-fanout RAM-control failures.
Prefit verification
- async FIFO randomized CDC test: 3,284 writes and reads exact, no duplicate or drop;
- Z/color emit: 1,500 fragments across three epochs exact, including directed
ZTST=ALWAYS; - concurrent scanout/reload/probe: 16,384 pixels exact;
- full 283-epoch production-control replay: PASS;
- 1,177,489 fragments fed, 984,845 passed Z, zero drops/errors;
- final Z mismatch
0 / 307,200and color mismatch0 / 235,963; - framebuffer SHA-256 remains exactly
a88f1f6c926dd0db2b72ae2873c399e7dc5666f8003190184c34d360b13a5f44; - relevant
git diff --check: PASS.
Owner fit gate
Ready for one owner-controlled Quartus 26.1 GUI compile. Acceptance requires:
- the direct
rbin -> request RAM portbaddrfamily is absent, not merely exchanged for an equally longrbin -> raddr_qorraddr_q -> portbaddrfamily; - setup, hold, recovery, removal, and minimum pulse all close;
- request FIFO RAM inference and the 336 / 358 RAM-block budget remain intact.
Do not deploy the RBF until this report is clean. After timing acceptance, run the already-staged Ch419 283-epoch board scene and require exact equality with the production framebuffer hash above.
Owner fit result — 2026-07-18 11:59
The fitter preserved raddr_q, and the direct rbin -> portbaddr family is
absent from the violated paths. Setup did not close:
- WNS
-0.273 ns, TNS-1.613 ns; - hold
0.000 ns; all other timing checks clean; - 38,227 ALMs and 336 / 358 RAM blocks.
The ten reported violations are the next request boundary, not either half of the new address stage. They launch at the request RAM output and terminate at the two packet-type validity registers:
u_zc_emit|u_req|mem...portbdataout
-> req_stage_frag_valid / req_stage_marker_valid
The worst path is 3.443 ns, with the RAM output uTco accounting for
1.396 ns and three downstream decode/routing levels accounting for the rest.
Ch421 removes packet contents from stage-occupancy control and captures the
complete packet across one explicit boundary.