Commit Graph

9 Commits

Author SHA1 Message Date
thejayman77 6319d7ca85 Ch443d: registered AXI R buffer (texcache fill) + drop fill_data_q reset
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>
2026-07-23 10:03:01 -04:00
thejayman77 846eee06b6 Ch443c: per-frame scanout diagnostic + frame-restart latency fix
The Ch443 board A+B diagnostic captured a WARM-UP miss, not a displayed-
frame miss: the line-buffer reader is enabled by video_src_emif
immediately, but the HDMI mux only switches to it at the next vsync, and
the diagnostic (cleared only on !enable) froze that pre-display capture.
scan_y=32/nf=32 was the expected pre-display warm-up, and line_valid is
sticky so it only meant SOME row had loaded, not that row 32 was valid.

Two fixes (all accepted Ch443 timing repairs kept: AW buffer, F_SETTLE +
drain multicycle, tile max-skew, monolithic tex_mem):

1. Per-frame diagnostic: clear diag_valid_q on fs_edge_v as well as
   !enable (mirrors underflow_v). Discards the warm-up capture and
   records the first miss, if any, AFTER the real frame boundary.

2. Frame-restart latency: in L_R, after the single-beat response is
   accepted, if fs_pending || fs_edge_e, abandon the remainder of the
   obsolete row -- no beat commit, no next old-row AR, no publish/
   increment -- and return to L_IDLE, which restarts at V_SOURCE_START.
   Protocol-safe (the accepted AXI transaction is complete); removes up
   to a full row of restart latency during vertical blanking, so the
   restarted prefetch leads the first displayed row.

New tb_gs_scanout_restart proves: mid-fetch frame-start accepts the
in-flight response, issues NO further old-row AR, restarts at row 32,
loads rows 32/33 before active consumption, and no post-restart
underflow. Regressions green: scanout_lb {,_binomial,_hstretch,
_psm32_256,_fb}, scanout_diag (per-frame), ps2_hps_bridge, and the
complete f52 replay BYTE-IDENTICAL (Z 0/307200, COLOR 0/245760).

Also commits the previously-untracked Ch443 board A+B evidence
(docs/hardware/ch443_board_validation/: verdict, 3-session raw, board
FB, RBF sha). No Quartus/board/push from here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 18:10:55 -04:00
thejayman77 27dfd0b0cf Ch443: combined timing repair for both Ch442 setup families
Ch442's fit exposed two failing setup families (plus a stale max-skew).
Attack both structurally; no reseeding.

Family 1 - AWREADY -> Z-FSM (-0.410): gen_p2c_ff[23] (EMIF AWREADY)
reached u_zc_emit|u_z's S_SFLUSH_AW/S_FILL_R next-state combinationally.
Ch441 registered only the W channel; add the AW twin:
- new gs_axi_aw_regbuf (one-entry fully-registered AW buffer), inserted
  in zc_emit between u_z's AW output and the arbiter s2 AW port. The FSM
  now sees registered occupancy, never EMIF's combinational AWREADY.

Family 2 - texcache drain_idx_q -> tex_mem (-0.370, x7): a single index
fanned across the whole 65536x32, 128-M20K macro. Split by WIDTH into
four 65536x8 banks, each with its own (* preserve, dont_merge *) write-
address launch register; write the four byte lanes together in F_WRITE;
reconstruct the sample word by concatenating four registered read bytes.
Selector structure and 1-cycle read latency unchanged; total M20Ks
unchanged (4x32 == 128); fill_crc still sums the full 32-bit word.

Max-skew: relax ONLY the Ch357 tile-write CDC set_max_skew 2.0 -> 2.5
(quasi-static bundle, >=2 dclk stability window); retain set_net_delay
2.0 (the real arrival bound). SDC comment updated.

Tests: new tb_gs_axi_aw_regbuf (AW scoreboard: exactly-once/order/no-
combinational-AWREADY-bypass/stable-while-stalled); tb_gs_texture_cache
strengthened to distinct-per-byte-bank data + per-bank + full-word
checks. All pass: aw/w regbuf, texture_cache, texture_psmt8_clut,
scanout_diag, ps2_hps_bridge, and the complete f52 replay BYTE-IDENTICAL
(Z 0/307200, COLOR 0/245760).

No Quartus, board, or push from here. Ready for one owner GUI fit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 11:19:09 -04:00
thejayman77 6720caee12 Ch442: A+B scanout diagnostic (split LPDDR_STATUS[5] + first-failure snapshot)
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>
2026-07-21 22:40:07 -04:00
thejayman77 dd7ca4fb8e Ch441: one-entry fully-registered W buffer, Z-RMW master -> wr_arb s2 [READY FOR REVIEW]
Cuts the lone remaining EMIF setup fail (-0.016 ns, -0.259 skew): the combinational
EMIF gen_p2c_ff -> wr_arb s2_wready -> gs_lpddr_z_rmw next-state (st, endpoint
labelled S_FILL_R via the shared encoded state register).

New gs_axi_w_regbuf: fully-registered one-entry W buffer (Option B per Codex).
- u_wready = !full ONLY (registered occupancy) -> EMIF WREADY never reaches the Z
  FSM combinationally. NOT a fall-through skid (no !full-OR-d_wready term).
- Buffers WDATA/WSTRB/WLAST; downstream held stable until accepted; exactly-once.
- AW/B untouched; arbiter bready_q unchanged (still arms on real EMIF W handshake).
- z_rmw may enter B-wait once the beat is buffered -- safe: EMIF cannot return B
  until the buffered beat reaches it. Single-beat writes -> the 1-beat/2-cycle
  buffer rate is far above the Z write rate (no new FIFO pressure).

Wired in zc_emit between u_z W output (zi_*) and the z_w* ports. New file in sim
Makefile RTL_SRCS + synth QSF (both). Focused tb_gs_axi_w_regbuf: exactly-once/order/
payload scoreboard + no-combinational-bypass check (u_wready===!full incl. full &&
d_wready) + downstream-stable check; standalone target + in make run. Texture-cache
+0.016 paths NOT touched. No simulations or Quartus run.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 14:12:11 -04:00
thejayman77 471c1af9cd Ch440: gs_async_fifo QUAD_WIDTH4_READ (2 depth x 4 width) for Z-req FIFO [READY FOR REVIEW]
Candidate 2 from the accepted structural proposal. Adds a QUAD_WIDTH4_READ
generate branch to gs_async_fifo: like QUADRANT_READ (2 depth x 2 width) but
splits the payload into FOUR width banks, so each preserved read-address launch
register drives ~half the M20K load (targets the 310MHz raddr_hi1_q->mem_hi1
setup family, WNS -0.103). Keeps QUADRANT_READ's proven 2:1 depth OUTPUT selector
unchanged (no new/deeper mux, per the doc's warning). Depth (8192), one-cycle
read latency, ordering, CDC, capacity, and interface are identical.

zc_emit u_req switched QUADRANT_READ->QUAD_WIDTH4_READ. New default-off param
leaves the other two gs_async_fifo instances byte-identical. TB gains a
TEST_QUAD_WIDTH4 variant + standalone Makefile target tb_gs_async_fifo_quad_width4.

NO simulations or Quartus run (per authorization). Awaiting review before any sim.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 10:19:09 -04:00
thejayman77 a72aaded22 Add FOG_ENABLE param, prune fog cone on the board profile (fix -6.165ns setup)
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>
2026-07-20 21:31:14 -04:00
thejayman77 ba74bbd5aa Snapshot: fog implementation + fidelity tooling baseline (pre bilinear-clamp fix)
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>
2026-07-20 19:56:46 -04:00
thejayman77 ec82764bef Initial commit: retroDE_ps2 — first-of-its-kind PS2 GS FPGA core (DE25-Nano / Agilex 5)
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>
2026-06-29 20:10:50 -04:00