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>
This commit is contained in:
2026-07-23 10:03:01 -04:00
parent 846eee06b6
commit 6319d7ca85
6 changed files with 256 additions and 5 deletions
+16 -3
View File
@@ -1991,6 +1991,9 @@ module de25_nano_psmct32_raster_demo_top (
wire [29:0] texf_ar_araddr; wire [1:0] texf_ar_arburst; wire [6:0] texf_ar_arid;
wire [7:0] texf_ar_arlen; wire [2:0] texf_ar_arsize; wire texf_ar_arvalid, texf_ar_arready;
wire [255:0] texf_r_rdata; wire [1:0] texf_r_rresp; wire texf_r_rlast, texf_r_rvalid, texf_r_rready;
// Ch443d — read-arbiter s2 R output feeds a one-entry registered R buffer (texf_ri_* =
// buffer upstream, from the arbiter); the buffer drives texf_r_* into the texture fill FSM.
wire [255:0] texf_ri_rdata; wire [1:0] texf_ri_rresp; wire texf_ri_rlast, texf_ri_rvalid, texf_ri_rready;
EMIF_Qsys u_emif_lpddr4b (
.iopll_refclk_clk (CLOCK2_50),
@@ -2719,8 +2722,8 @@ module de25_nano_psmct32_raster_demo_top (
.s2_araddr(texf_ar_araddr), .s2_arburst(texf_ar_arburst), .s2_arid(texf_ar_arid),
.s2_arlen(texf_ar_arlen), .s2_arsize(texf_ar_arsize), .s2_arvalid(texf_ar_arvalid),
.s2_arready(texf_ar_arready),
.s2_rdata(texf_r_rdata), .s2_rresp(texf_r_rresp), .s2_rlast(texf_r_rlast),
.s2_rvalid(texf_r_rvalid), .s2_rready(texf_r_rready),
.s2_rdata(texf_ri_rdata), .s2_rresp(texf_ri_rresp), .s2_rlast(texf_ri_rlast),
.s2_rvalid(texf_ri_rvalid), .s2_rready(texf_ri_rready),
.s3_araddr(reload_ar_araddr), .s3_arburst(reload_ar_arburst), .s3_arid(reload_ar_arid),
.s3_arlen(reload_ar_arlen), .s3_arsize(reload_ar_arsize), .s3_arvalid(reload_ar_arvalid),
.s3_arready(reload_ar_arready),
@@ -2740,6 +2743,16 @@ module de25_nano_psmct32_raster_demo_top (
// (one-shot before raster, armed by the bridge); sample side on design_clk, tapping
// u_demo's texel-fetch request and returning the texel at the existing 1-cycle latency.
`ifdef GS_LPDDR_TEX
// Ch443d — one-entry fully-registered R buffer between read-arbiter s2 and the
// texture fill FSM. Cuts the combinational EMIF RVALID/RDATA -> gs_texture_cache
// F_R next-state (`fst`) path (the -0.043/-0.022 ns EMIF setup family). The arbiter
// completes its R transaction into this buffer (s2_rready = !full); the buffer owns
// delivery to the fill FSM. B/AR/W untouched.
gs_axi_r_regbuf #(.RDATA_W(256), .RRESP_W(2)) u_texf_rbuf (
.clk(emif_clk), .rst_n(emif_reset_n),
.u_rdata(texf_ri_rdata), .u_rresp(texf_ri_rresp), .u_rlast(texf_ri_rlast), .u_rvalid(texf_ri_rvalid), .u_rready(texf_ri_rready),
.d_rdata(texf_r_rdata), .d_rresp(texf_r_rresp), .d_rlast(texf_r_rlast), .d_rvalid(texf_r_rvalid), .d_rready(texf_r_rready)
);
gs_texture_cache #(
.LPDDR_TEX_BASE(TEX_LPDDR_BASE), .TEX_VRAM_BASE(TEXC_VRAM_BASE), .TEX_BYTES(TEXC_BYTES), .N_BEATS(TEXC_NBEATS)
) u_texcache (
@@ -2758,7 +2771,7 @@ module de25_nano_psmct32_raster_demo_top (
// no texture cache — tie read-port-2 inert (arvalid=0, rready=1 drains).
assign texf_ar_araddr=30'd0; assign texf_ar_arburst=2'b01; assign texf_ar_arid=7'd4;
assign texf_ar_arlen=8'd0; assign texf_ar_arsize=3'b101; assign texf_ar_arvalid=1'b0;
assign texf_r_rready=1'b1;
assign texf_ri_rready=1'b1; // Ch443d — drain the arbiter s2 R directly (no R buffer / texcache in this profile)
assign tex_fill_done_w=1'b0; assign tex_fill_beats_w=32'd0;
assign tex_fill_bytes_w=32'd0; assign tex_rd_errs_w=32'd0; assign tex_fill_crc_w=32'd0;
`ifndef GS_TILE_SPILL