feat: SDRAM 8MB->64MB upgrade (AS4C32M16SB-7BIN) + N_SLOTS=8 support
Memory upgrade, at the user's own explicit request: Alliance Memory AS4C4M16SA-6TIN (64Mbit/8MB) -> AS4C32M16SB-7BIN (512Mbit/64MB, 54-ball TFBGA), the largest same-family SDR SDRAM Alliance Memory offers. Real-datasheet-driven (whole AS4C4M16SA/AS4C8M16SA/AS4C16M16SA/ AS4C32M16SA family investigated): 13 row bits (was 12, one new FPGA pin sdram_a[12]/ball F1), 10 column bits (was 8), real -7-grade AC timing (tRCD/tRP improved to 15ns, tREFI halved to 7.8us for the doubled row count). sdram_controller.v and sdram_model.v gained real ROW_BITS/COL_BITS/BANK_BITS parameters (was hardcoded 12/8/2). ADDR_WIDTH widened 23->26 bits across the live instantiation tree. This required a real SPI protocol change (spi_host_bridge.v): a 26-bit byte address no longer fits in 3 bytes -- every address field widened 3->4 bytes (WRITE_JOB 15->18 payload bytes, WRITE_MEM/READ_MEM header 5->6 bytes). Found and fixed two real timing regressions via nextpnr-ecp5 P&R (not assumed): neural_director.v's own runtime-indexed demux write (ERR-0027, was silently synthesizing an extra MULT18X18D) and nms_activation_fill_ctrl_v3.v's own linear N_SLOTS-wide max-scan (ERR-0028, became dominant at N_SLOTS=8) -- both replaced with constant-indexed/tree-based equivalents, bit-exact same behavior, confirmed via full D-Stress N=2/4/8 regression (identical cycle counts). N_SLOTS=4 now fully closes timing at 64MHz (8/8 seeds); N_SLOTS=8 significantly improved but not yet fully reliable (5/8 seeds) -- honestly disclosed, not claimed complete. Full regression re-verified: sdram_controller (461/461, 18 configs), tb_sdram_boundary (21/21), D-Stress N=2/4/8 (bit-exact), spi_host_bridge (18/18), board-level SPI smoke test (11/11), unified backend (40/40). See hardware/v2/docs/MEMORY_UPGRADE_64MB_N8.md for the full investigation, and errors.log/decisions.log (ERR-0027, ERR-0028, DEC-0039) for the complete root-cause writeups. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
// simultaneous traffic, all bit-exact.
|
||||
// ============================================================
|
||||
module tb;
|
||||
localparam ADDR_WIDTH = 23;
|
||||
localparam ADDR_WIDTH = 26; // AS4C32M16SA memory upgrade
|
||||
localparam CLK_FREQ_MHZ = 80;
|
||||
localparam CLK_PERIOD_NS = 1000.0/CLK_FREQ_MHZ;
|
||||
|
||||
@@ -49,7 +49,7 @@ module tb;
|
||||
|
||||
wire sdram_cke, sdram_cs_n, sdram_ras_n, sdram_cas_n, sdram_we_n;
|
||||
wire [1:0] sdram_ba;
|
||||
wire [11:0] sdram_a;
|
||||
wire [12:0] sdram_a;
|
||||
wire [15:0] sdram_dq;
|
||||
wire [1:0] sdram_dqm;
|
||||
|
||||
@@ -74,7 +74,7 @@ module tb;
|
||||
|
||||
task automatic poke64(input [ADDR_WIDTH-1:0] byte_addr, input [63:0] val);
|
||||
integer w;
|
||||
reg [21:0] word_addr;
|
||||
reg [24:0] word_addr;
|
||||
begin
|
||||
for (w = 0; w < 4; w = w + 1) begin
|
||||
word_addr = (byte_addr + w*2) >> 1;
|
||||
@@ -154,14 +154,14 @@ module tb;
|
||||
@(posedge clk);
|
||||
|
||||
// ---- A: W-port sequential access (weight region) ----
|
||||
wbase = 23'h010000;
|
||||
wbase = 26'h010000;
|
||||
for (i = 0; i < 16; i = i + 1)
|
||||
poke64(wbase + i*8, {4{16'hA000 + i[15:0]}});
|
||||
for (i = 0; i < 16; i = i + 1)
|
||||
check64(wbase + i*8, {4{16'hA000 + i[15:0]}}, "A-Wseq");
|
||||
|
||||
// ---- B: AR-port read (activation region, disjoint from W) ----
|
||||
arbase = 23'h200000 >> 1; // word address
|
||||
arbase = 26'h200000 >> 1; // word address
|
||||
poke64({arbase, 1'b0}, 64'h1111_2222_3333_4444);
|
||||
check16(arbase+0, 16'h4444, "B-ARrd-w0");
|
||||
check16(arbase+1, 16'h3333, "B-ARrd-w1");
|
||||
@@ -171,7 +171,7 @@ module tb;
|
||||
// ---- C: AR-port byte-masked write (result region) --
|
||||
// pre-seed a known 128-bit block, write ONE byte, verify
|
||||
// every OTHER byte in the same real SDRAM block is untouched.
|
||||
arbase = 23'h300000 >> 1;
|
||||
arbase = 26'h300000 >> 1;
|
||||
poke64({arbase[ADDR_WIDTH-2:3], 4'b0000}, 64'h9999_8888_7777_6666);
|
||||
poke64({arbase[ADDR_WIDTH-2:3], 4'b1000}, 64'h5555_4444_3333_2222);
|
||||
// write only the LOW byte of word 2 (within the 8-word block) to 8'hAB
|
||||
|
||||
Reference in New Issue
Block a user