Closes the last currently-visible EMIF-handshake -> FSM setup family the
Ch443c fit exposed (-0.043/-0.022/-0.005 ns), the read-response analogue
of the AW/W buffers.
- gs_axi_r_regbuf: one-entry FULLY-registered AXI R buffer (the R twin of
gs_axi_w_regbuf). Buffers the complete {rdata,rresp,rlast}; u_rready =
!full only (NO combinational dependence on the texture FSM's d_rready);
captures on u_rvalid && u_rready; d_rvalid = full with the payload held
stable until d_rvalid && d_rready; resets only . Inserted between
read-arbiter s2 and gs_texture_cache (u_texf_rbuf). The arbiter is
unchanged -- it completes its R transaction into the buffer, which then
owns delivery to the fill FSM. Cuts EMIF rvalid/rdata -> fst.F_R.
- gs_texture_cache: drop the unobservable fill_data_q reset. F_DRAIN (its
only reader) is reachable only after F_R loads it, so the reset value is
never observed; removing it kills the separate lock_sync|dreg[1] ->
fill_data_q[80] setup path (-0.005 ns).
- New tb_gs_axi_r_regbuf: exactly-once/in-order, randomized responses +
stalls, full backpressure, the full && d_rready no-fall-through case,
{rdata,rresp,rlast} stability, reset-while-empty AND reset-while-full.
All green: r-buffer TB, texture_cache, texture_psmt8_clut, scanout_lb,
scanout_restart, scanout_diag, ps2_hps_bridge, rd_arb, and the complete
f52 replay BYTE-IDENTICAL (Z 0/307200, COLOR 0/245760). No Quartus/board/
push from here.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Read-only diagnostic to disambiguate the three causes folded into
LPDDR_STATUS[5]. bit5 (0x02C) semantics are UNCHANGED.
- gs_lpddr_scanout_lb: register a live (rd_errs!=0) flag in the emif
domain (the raw counter never crosses), and capture the FIRST raw
underflow of each video-source-enabled session as a bundled-data
snapshot (scan_y/nf_v/nf_s0 + base-vs-lookahead cause + line_valid +
vphase), held stable until !enable. The existing sticky underflow_v
latch, fetch FSM, pixel path and arbitration are untouched.
- ps2_hps_bridge: independently 2-FF sync the two split live flags;
latch the snapshot on the rising synced-valid edge (coherent bundled
data). New read-only regs 0x120 SCAN_DIAG_STATUS / 0x124
SCAN_DIAG_FIRST (window addr[37:5]==9); 0x118/0x11C reserved slots
untouched.
- top: drive 5 diag nets per scanout arm like scan_err_w; bit5 assign
unchanged.
- tb_gs_scanout_diag (new): provokes AXI RRESP error, cold-start row-0
starvation, first-failure capture + coherent bridge readback, and
clear-via-video-source-disable (17/17 checks).
- Tie off the new bridge inputs in the four .*-instantiating TBs.
Sim set all PASS: focused TB, tb_ps2_hps_bridge, scanout_lb
{binomial,hstretch,psm32_256}, and the complete f52 replay (FB
byte-identical: Z 0/307200, COLOR 0/245760; sum32=0xaad0b94d).
No fix / gray-code / persistence-filter / scanout checksum. No Quartus,
no board, no push.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
My REQ_DEPTH=1024 reduction was wrong: I sized it off a 478 peak from a SMALL
scene. The documented full-f52 replay peak is 6,115 (adjacent frame 3,610; even
2,048 clips) — ch439_timing_convergence_prefit.md. The raster cannot backpressure,
so an undersized FIFO SILENTLY DROPS Z-requests -> corrupt frame. The -0.074 fit
was on an invalid (drop-prone) config. Restore 8,192 as the correctness baseline.
The real timing fix is a registered/skid AR-handshake boundary (arbiter s2_arready
combinational -> texcache F_AR), NOT FIFO shrinking. Packaging that for Codex review.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The 8K request FIFO was 8x oversized (measured peak ~478; Codex's TB uses 1024).
Its read address routed to 8 spread M20K blocks -> 310MHz EMIF setup miss (-0.103,
MAX_FANOUT can't help: Quartus refuses to duplicate RAM-address regs, Warning 22471).
Shrinking to 1024 (2 blocks): 26.1 fit shows that path GONE, design clk +0.631->+5.693,
RAM 309/358 (86%) -> 277/358 (77%). New worst is a DIFFERENT, skew-dominated EMIF->
texcache-FSM path at -0.074 (TNS -2.032 -> -0.164).
SAFETY GATE before board load: confirm the full zsrt139f52 scene never bursts >1024
Z-requests in flight (peak I have is 478 from a smaller scene). Bump to 2048 if unsure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The fog blend's tex_color*F multiply landed on the texture->color critical path
(u_texcache RAM -> u_tex|tex_color -> mult_126 -> raster_pixel_color_q, 46ns,
-6.165ns setup). Fog is a proven no-op for the current board scene (96.5% F=255),
so pay zero for it here.
FOG_ENABLE (default 1, byte-identical fog) added to gs_stub; each fog mux gated
(FOG_ENABLE && ras_fge) so FOG_ENABLE=0 constant-folds the entire fog cone away
(multiply, FOGCOL adders, s2_fog_f/persp_fog_f5 interp). Threaded through
top_psmct32_raster_demo_bram; set FOG_ENABLE(1'b0) on the active GS_SH3_LPDDR_FB
board arm (elsif at :1086, the one the QSF profile compiles). Fog stays default-on
everywhere else.
Verified: FOG_ENABLE=1 fog TBs unchanged PASS; FOG_ENABLE=0 (new tb_gs_fog_disabled
+ board scene TB) emits raw color = pre-fog datapath; board elaborates clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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>
RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression
(272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps,
and all dump-derived textures/traces) is excluded via .gitignore and stays local.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>