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>
This commit is contained in:
2026-07-20 19:56:46 -04:00
parent ec82764bef
commit ba74bbd5aa
476 changed files with 696247 additions and 130119 deletions
+51 -20
View File
@@ -77,6 +77,20 @@ module gs_lpddr_rd_arb (
output logic s3_rvalid,
input logic s3_rready,
// ---- Port 4: destination-color read for SH3 alpha ROP ----
input logic [29:0] s4_araddr,
input logic [1:0] s4_arburst,
input logic [6:0] s4_arid,
input logic [7:0] s4_arlen,
input logic [2:0] s4_arsize,
input logic s4_arvalid,
output logic s4_arready,
output logic [255:0] s4_rdata,
output logic [1:0] s4_rresp,
output logic s4_rlast,
output logic s4_rvalid,
input logic s4_rready,
// ---- Master out: EMIF read channel ----
output logic [29:0] m_araddr,
output logic [1:0] m_arburst,
@@ -91,7 +105,7 @@ module gs_lpddr_rd_arb (
input logic m_rvalid,
output logic m_rready
);
// grant: 0=idle, 1=s0 scanout, 2=s1 probe, 3=s2 texfill, 4=s3 tile-reload.
// grant: 0=idle, 1=s0 scanout, 2=s1 probe, 3=s2 texfill, 4=s3 reload/Z, 5=s4 alpha destination.
// EXPLICIT priority (Ch323, Codex): scanout > tile_reload > probe > texture_fill — i.e.
// s0 > s3 > s1 > s2. Render-display (scanout) highest; the render-prep tile reload above
// the debug read-probe so a debug read can never starve a render's Z/color reload.
@@ -105,26 +119,37 @@ module gs_lpddr_rd_arb (
// transaction committed yet — safe to drop); after AR acceptance the grant is held until
// m_rvalid && m_rlast && selected_rready, regardless of how long the read takes.
reg ar_done; // AR handshake captured for the active grant -> never abort past here
// Register the terminal R handshake before releasing the grant. Besides
// making the ownership boundary explicit, this removes the selected
// requester's rready mux from the encoded grant register's D cone. The
// old direct clear path was the secondary 310 MHz setup family after the
// wide request-FIFO RAM-enable fanout.
reg response_done_q;
reg [21:0] watchdog; // pre-AR only (waiting for m_arready); ~6.7 ms @ 310 MHz dead-bus backstop
wire wd_expired = watchdog[21];
wire sel_rready = (grant==3'd1)?s0_rready:(grant==3'd2)?s1_rready:
(grant==3'd3)?s2_rready:(grant==3'd4)?s3_rready:1'b1;
(grant==3'd3)?s2_rready:(grant==3'd4)?s3_rready:(grant==3'd5)?s4_rready:1'b1;
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
grant <= 3'd0; ar_done <= 1'b0; watchdog <= '0;
grant <= 3'd0; ar_done <= 1'b0; response_done_q <= 1'b0; watchdog <= '0;
end else if (grant == 3'd0) begin
ar_done <= 1'b0; watchdog <= '0;
ar_done <= 1'b0; response_done_q <= 1'b0; watchdog <= '0;
if (s0_arvalid) grant <= 3'd1; // scanout (highest)
else if (s3_arvalid) grant <= 3'd4; // tile reload (render-prep)
else if (s4_arvalid) grant <= 3'd5; // alpha destination RMW
else if (s1_arvalid) grant <= 3'd2; // read probe (debug)
else if (s2_arvalid) grant <= 3'd3; // texture fill (lowest)
end else if (response_done_q) begin
// The selected requester accepted RLAST on the preceding cycle.
// Hold ownership through that handshake, then release here.
grant <= 3'd0; ar_done <= 1'b0; response_done_q <= 1'b0; watchdog <= '0;
end else begin
if (m_arvalid && m_arready) ar_done <= 1'b1; // AR accepted -> COMMITTED
if (m_rvalid && m_rlast && sel_rready) begin
grant <= 3'd0; ar_done <= 1'b0; watchdog <= '0; // response delivered -> release
response_done_q <= 1'b1; watchdog <= '0; // response delivered; release next cycle
end else if (!ar_done) begin // still waiting for AR (nothing owed)
if (wd_expired) begin grant <= 3'd0; ar_done <= 1'b0; watchdog <= '0; end
if (wd_expired) begin grant <= 3'd0; ar_done <= 1'b0; response_done_q <= 1'b0; watchdog <= '0; end
else watchdog <= watchdog + 22'd1;
end
// ar_done && response not yet complete: HOLD the grant, never abort.
@@ -132,24 +157,30 @@ module gs_lpddr_rd_arb (
end
// AR mux
assign m_araddr = (grant==3'd4)?s3_araddr :(grant==3'd3)?s2_araddr :(grant==3'd2)?s1_araddr :s0_araddr;
assign m_arburst = (grant==3'd4)?s3_arburst:(grant==3'd3)?s2_arburst:(grant==3'd2)?s1_arburst:s0_arburst;
assign m_arid = (grant==3'd4)?s3_arid :(grant==3'd3)?s2_arid :(grant==3'd2)?s1_arid :s0_arid;
assign m_arlen = (grant==3'd4)?s3_arlen :(grant==3'd3)?s2_arlen :(grant==3'd2)?s1_arlen :s0_arlen;
assign m_arsize = (grant==3'd4)?s3_arsize :(grant==3'd3)?s2_arsize :(grant==3'd2)?s1_arsize :s0_arsize;
assign m_arvalid = (grant==3'd1)?s0_arvalid:(grant==3'd2)?s1_arvalid:(grant==3'd3)?s2_arvalid:(grant==3'd4)?s3_arvalid:1'b0;
assign s0_arready = (grant==3'd1)?m_arready:1'b0;
assign s1_arready = (grant==3'd2)?m_arready:1'b0;
assign s2_arready = (grant==3'd3)?m_arready:1'b0;
assign s3_arready = (grant==3'd4)?m_arready:1'b0;
assign m_araddr = (grant==3'd5)?s4_araddr :(grant==3'd4)?s3_araddr :(grant==3'd3)?s2_araddr :(grant==3'd2)?s1_araddr :s0_araddr;
assign m_arburst = (grant==3'd5)?s4_arburst:(grant==3'd4)?s3_arburst:(grant==3'd3)?s2_arburst:(grant==3'd2)?s1_arburst:s0_arburst;
assign m_arid = (grant==3'd5)?s4_arid :(grant==3'd4)?s3_arid :(grant==3'd3)?s2_arid :(grant==3'd2)?s1_arid :s0_arid;
assign m_arlen = (grant==3'd5)?s4_arlen :(grant==3'd4)?s3_arlen :(grant==3'd3)?s2_arlen :(grant==3'd2)?s1_arlen :s0_arlen;
assign m_arsize = (grant==3'd5)?s4_arsize :(grant==3'd4)?s3_arsize :(grant==3'd3)?s2_arsize :(grant==3'd2)?s1_arsize :s0_arsize;
// Once an address is accepted, do not expose another address from the
// selected requester while its response (or registered release) is active.
// This also makes the deliberate one-cycle release bubble AXI-safe.
wire ar_open = !ar_done && !response_done_q;
assign m_arvalid = ar_open && ((grant==3'd1)?s0_arvalid:(grant==3'd2)?s1_arvalid:(grant==3'd3)?s2_arvalid:(grant==3'd4)?s3_arvalid:(grant==3'd5)?s4_arvalid:1'b0);
assign s0_arready = (ar_open && grant==3'd1)?m_arready:1'b0;
assign s1_arready = (ar_open && grant==3'd2)?m_arready:1'b0;
assign s2_arready = (ar_open && grant==3'd3)?m_arready:1'b0;
assign s3_arready = (ar_open && grant==3'd4)?m_arready:1'b0;
assign s4_arready = (ar_open && grant==3'd5)?m_arready:1'b0;
// R demux (idle: rready=1 drains any stale/late response)
assign s0_rdata=m_rdata; assign s1_rdata=m_rdata; assign s2_rdata=m_rdata; assign s3_rdata=m_rdata;
assign s0_rresp=m_rresp; assign s1_rresp=m_rresp; assign s2_rresp=m_rresp; assign s3_rresp=m_rresp;
assign s0_rlast=m_rlast; assign s1_rlast=m_rlast; assign s2_rlast=m_rlast; assign s3_rlast=m_rlast;
assign s0_rdata=m_rdata; assign s1_rdata=m_rdata; assign s2_rdata=m_rdata; assign s3_rdata=m_rdata; assign s4_rdata=m_rdata;
assign s0_rresp=m_rresp; assign s1_rresp=m_rresp; assign s2_rresp=m_rresp; assign s3_rresp=m_rresp; assign s4_rresp=m_rresp;
assign s0_rlast=m_rlast; assign s1_rlast=m_rlast; assign s2_rlast=m_rlast; assign s3_rlast=m_rlast; assign s4_rlast=m_rlast;
assign s0_rvalid = (grant==3'd1)?m_rvalid:1'b0;
assign s1_rvalid = (grant==3'd2)?m_rvalid:1'b0;
assign s2_rvalid = (grant==3'd3)?m_rvalid:1'b0;
assign s3_rvalid = (grant==3'd4)?m_rvalid:1'b0;
assign m_rready = (grant==3'd1)?s0_rready:(grant==3'd2)?s1_rready:(grant==3'd3)?s2_rready:(grant==3'd4)?s3_rready:1'b1;
assign s4_rvalid = (grant==3'd5)?m_rvalid:1'b0;
assign m_rready = (grant==3'd1)?s0_rready:(grant==3'd2)?s1_rready:(grant==3'd3)?s2_rready:(grant==3'd4)?s3_rready:(grant==3'd5)?s4_rready:1'b1;
endmodule