# 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,200` and color mismatch `0 / 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 portbaddr` family is absent, not merely exchanged for an equally long `rbin -> raddr_q` or `raddr_q -> portbaddr` family; - 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.