Ch440 review fixes: 93-bit per-bank test coverage + soften M20K claims [READY FOR REVIEW]
Per Codex review of 471c1af:
1. tb_gs_async_fifo QUAD_WIDTH4 variant now runs at the PRODUCTION 93-bit width
(exercising the odd 23/23/23/24 remainder split) and drives a DISTINCT NONZERO
pattern into every width bank (seq XOR per-bank constants, bank2 inverted), with
the scoreboard checking the FULL reconstructed word. A swapped/broken/zeroed
upper bank now changes the word and trips the scoreboard. Depth-half crossing
(DEPTH=8) + wrap/full coverage retained. mk() is generate-guarded so the 32-bit
variants never elaborate the 93-bit selects.
2. Softened gs_async_fifo comments: 'same total M20K' -> EXPECTED-similar, pending
synthesis (fact -> expectation).
No simulations or Quartus run. Awaiting review before any sim.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,8 +31,9 @@ module gs_async_fifo #(
|
||||
parameter bit QUADRANT_READ = 1'b0,
|
||||
// Ch440: two depth banks x FOUR width banks (eight physical RAMs). Like
|
||||
// QUADRANT_READ but splits the payload into four width banks instead of two,
|
||||
// halving each preserved read-address register's M20K load AGAIN at the same
|
||||
// total M20K, while KEEPING QUADRANT_READ's 2:1 depth output selector (no
|
||||
// halving each preserved read-address register's M20K load AGAIN (total M20K
|
||||
// is EXPECTED to stay ~the same, pending synthesis), while KEEPING
|
||||
// QUADRANT_READ's 2:1 depth output selector (no
|
||||
// new/deeper output mux). Depth, one-cycle read latency, ordering, capacity,
|
||||
// and interface behaviour are identical to QUADRANT_READ.
|
||||
parameter bit QUAD_WIDTH4_READ = 1'b0
|
||||
@@ -174,7 +175,8 @@ module gs_async_fifo #(
|
||||
if (QUAD_WIDTH4_READ) begin : g_quad_width4_storage
|
||||
// Ch440: 2 depth banks x 4 width banks = eight RAMs. Each read-address
|
||||
// register drives only a HALF_DEPTH x ~(WIDTH/4) RAM -> roughly half the
|
||||
// M20K load of QUADRANT_READ's hi/lo banks, at the SAME total M20K. The
|
||||
// M20K load of QUADRANT_READ's hi/lo banks, at an EXPECTED-similar total
|
||||
// M20K (pending synthesis confirmation). The
|
||||
// depth-half selection stays a 2:1 OUTPUT mux, byte-for-byte the selector
|
||||
// QUADRANT_READ already uses -- no new/deeper output mux is introduced.
|
||||
localparam int W4B0 = WIDTH/4;
|
||||
|
||||
@@ -14,7 +14,10 @@ module tb_gs_async_fifo #(
|
||||
parameter bit TEST_QUAD_WIDTH4 = 1'b0, // Ch440: 2 depth x 4 width banks
|
||||
parameter bit TEST_REGISTERED = TEST_BANKED || TEST_QUADRANT || TEST_QUAD_WIDTH4
|
||||
);
|
||||
localparam int WIDTH = 32;
|
||||
// Ch440: the 4-width-bank variant runs at the PRODUCTION 93-bit width so the
|
||||
// odd 23/23/23/24 remainder split and every width bank are exercised; the
|
||||
// other variants keep the legacy 32-bit width.
|
||||
localparam int WIDTH = TEST_QUAD_WIDTH4 ? 93 : 32;
|
||||
localparam int DEPTH = 8;
|
||||
|
||||
// Production request-FIFO corner: 40 MHz raster producer into the
|
||||
@@ -54,8 +57,32 @@ module tb_gs_async_fifo #(
|
||||
else registered_pending <= TEST_REGISTERED && dut_rd;
|
||||
end
|
||||
|
||||
logic [WIDTH-1:0] wr_seq, rd_seq; // next value to write / next value expected to read
|
||||
assign wdata = wr_seq;
|
||||
logic [WIDTH-1:0] wr_seq, rd_seq; // sequence counter to write / next expected to read
|
||||
logic [WIDTH-1:0] wr_pat, rd_pat; // payload for wr_seq / expected reconstruction for rd_seq
|
||||
|
||||
// Ch440: payload generator. For the 4-width-bank variant, spread a DISTINCT
|
||||
// NONZERO pattern into each of the four 23/23/23/24 banks (sequence counter
|
||||
// XORed with per-bank constants, one bank inverted) so that a swapped, broken,
|
||||
// or zeroed upper bank changes the reconstructed word and is caught by the
|
||||
// full-word scoreboard. Other variants keep the plain incrementing payload.
|
||||
// Generate-guarded so the 32-bit variants never elaborate the 93-bit selects.
|
||||
generate
|
||||
if (TEST_QUAD_WIDTH4) begin : g_payload
|
||||
function automatic logic [WIDTH-1:0] mk(input logic [WIDTH-1:0] s);
|
||||
mk = '0;
|
||||
mk[22:0] = s[22:0] ^ 23'h2AAAAA; // bank0
|
||||
mk[45:23] = s[22:0] ^ 23'h555555; // bank1 (distinct const)
|
||||
mk[68:46] = ~s[22:0] ^ 23'h0F0F0F; // bank2 (inverted)
|
||||
mk[92:69] = {s[7:0], s[15:8], 8'hA5} ^ 24'hC33C5A; // bank3 (24-bit remainder)
|
||||
endfunction
|
||||
assign wr_pat = mk(wr_seq);
|
||||
assign rd_pat = mk(rd_seq);
|
||||
end else begin : g_payload
|
||||
assign wr_pat = wr_seq;
|
||||
assign rd_pat = rd_seq;
|
||||
end
|
||||
endgenerate
|
||||
assign wdata = wr_pat;
|
||||
|
||||
int errors; initial errors=0;
|
||||
int sb_err; // scoreboard-only error counter (reset + written solely by the reader always_ff)
|
||||
@@ -70,8 +97,8 @@ module tb_gs_async_fifo #(
|
||||
always_ff @(posedge rclk or negedge rrst_n) begin
|
||||
if (!rrst_n) begin rd_seq <= '0; sb_err <= 0; end
|
||||
else if (TEST_REGISTERED ? registered_pending : dut_rd) begin
|
||||
if (rdata !== rd_seq) begin
|
||||
if (sb_err < 20) $error("[afifo] out-of-order/dup/drop: got %0d expected %0d", rdata, rd_seq);
|
||||
if (rdata !== rd_pat) begin
|
||||
if (sb_err < 20) $error("[afifo] out-of-order/dup/drop/bank: got %h expected %h (seq %0d)", rdata, rd_pat, rd_seq);
|
||||
sb_err <= sb_err + 1;
|
||||
end
|
||||
rd_seq <= rd_seq + 1;
|
||||
|
||||
Reference in New Issue
Block a user