FASE #1 hardware freeze for FPGA-Neural V2, N4/P8, single external SDRAM (Alliance Memory AS4C4M16SA-6TIN) serving weights, activations, and results through one physical sdram_controller.v instance. Removes the PSRAM dependency (hardware/v1/rtl/psram_controller.v + memory_interface.v) from the V2 physical path entirely -- V1 itself remains fully unmodified, the golden reference. New RTL: sdram_unified_backend.v (2-way W/AR arbitration over one SDRAM controller, real per-byte DQM write masking added to sdram_controller.v for correct single-byte result writes with no read-modify-write), nms_neural_multiprocessor_sdram_unified.v (the frozen top-level). Two real bugs found and fixed via full-system testing before being accepted (ERR-0023): a deadlock and an off-by-one data-shift bug in the new arbitration logic. Real results: N=4 and N=2 D-Stress bit-exact (256/256 neurons), 40 real AUTO REFRESH events interleaved with zero corruption, real Yosys+nextpnr-ecp5 synthesis/P&R for LFE5U-45F-8CABGA381 (149/245 TRELLIS_IO, a real 45-pin reduction from the prior dual-memory design). Timing is MARGINAL (1/8 P&R seeds >=80MHz), reported honestly rather than masked by the best seed. Real, sourced ball-level pinout for the SDRAM bus + clk/rst (39/149 signals, P&R-verified) using the official Lattice ECP5U-45 pinout CSV found on disk during this step's own pre-commit review -- corrects an earlier draft that wrongly assumed no real pinout data was available. Chip readiness: NO. Real, disclosed blockers remain (no physical host interface exists yet -- the RTL's own reg_* ports are a 110-pin raw test-harness bus; clock source/PLL decision; power/configuration component selection) -- see hardware/v2/docs/{HARDWARE_FREEZE, CHIP_READINESS,OPEN_ITEMS}.md for the complete, itemized status. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013xXuuRUWZScuo1DeYJxs3v
69 lines
2.9 KiB
Verilog
69 lines
2.9 KiB
Verilog
`timescale 1ns/1ps
|
|
|
|
// ============================================================
|
|
// NMS STEP16 Phase 5 -- SDRAM weight-fetch backend. Wraps the real,
|
|
// isolated-and-validated sdram_controller.v (Phase 1-4, EXP-0040/0041,
|
|
// ERR-0016..0019) with BURST_LEN=4 (P_IN*DATA_WIDTH/16 = 4 words/tile,
|
|
// the exact natural match identified in Phase 1) and presents the
|
|
// same mem_req/mem_wr/mem_addr/mem_wdata/mem_rdata/mem_ready
|
|
// convention as psram_controller_dual32.v, so it drops into
|
|
// nms_neural_multiprocessor_sdram.v's wide weight-fetch port exactly
|
|
// where psram_controller_dual32.v sits in the dual32 baseline --
|
|
// same external contract, different physical memory underneath, for
|
|
// a direct, apples-to-apples STEP16 comparison.
|
|
//
|
|
// Address conversion: `mem_addr` is a BYTE address (this project's
|
|
// own established convention, matching weight_prefetch_engine_wide.v
|
|
// and psram_controller_dual32.v's own external contract). The real
|
|
// AS4C4M16SA-6TIN is x16 (2 bytes/word), so the SDRAM controller's
|
|
// own word address is `mem_addr >> 1` -- exactly analogous to
|
|
// STEP15's own real ">>2" byte-to-32-bit-word fix (EXP-0037 bug #1),
|
|
// here ">>1" for a 16-bit-word device.
|
|
//
|
|
// Weight fetch never writes (same convention as psram_controller_
|
|
// dual32.v's own top-level instantiation, which ties mem_wr=0):
|
|
// `mem_wr` is exposed here for interface symmetry but the underlying
|
|
// sdram_controller is only ever driven with wr=0 by this wrapper's
|
|
// own real usage in nms_neural_multiprocessor_sdram.v.
|
|
// ============================================================
|
|
module sdram_weight_backend #(
|
|
parameter ADDR_WIDTH = 23, // byte address width (project convention)
|
|
parameter CLK_FREQ_MHZ = 80
|
|
)(
|
|
input wire clk,
|
|
input wire rst,
|
|
|
|
input wire mem_req,
|
|
input wire mem_wr,
|
|
input wire [ADDR_WIDTH-1:0] mem_addr,
|
|
input wire [63:0] mem_wdata,
|
|
output wire [63:0] mem_rdata,
|
|
output wire mem_ready,
|
|
|
|
output wire sdram_cke,
|
|
output wire sdram_cs_n,
|
|
output wire sdram_ras_n,
|
|
output wire sdram_cas_n,
|
|
output wire sdram_we_n,
|
|
output wire [1:0] sdram_ba,
|
|
output wire [11:0] sdram_a,
|
|
inout wire [15:0] sdram_dq,
|
|
output wire [1:0] sdram_dqm
|
|
);
|
|
|
|
wire busy;
|
|
wire [21:0] sdram_word_addr = mem_addr[ADDR_WIDTH-1:1]; // byte -> 16-bit-word address
|
|
|
|
sdram_controller #(
|
|
.CLK_FREQ_MHZ(CLK_FREQ_MHZ), .BURST_LEN(4), .ADDR_WIDTH(22)
|
|
) u_sdram_ctrl (
|
|
.clk(clk), .rst(rst),
|
|
.req(mem_req), .wr(mem_wr), .addr(sdram_word_addr),
|
|
.wdata(mem_wdata), .wmask(8'h00), .rdata(mem_rdata), .ready(mem_ready), .busy(busy),
|
|
.sdram_cke(sdram_cke), .sdram_cs_n(sdram_cs_n), .sdram_ras_n(sdram_ras_n),
|
|
.sdram_cas_n(sdram_cas_n), .sdram_we_n(sdram_we_n),
|
|
.sdram_ba(sdram_ba), .sdram_a(sdram_a), .sdram_dq(sdram_dq), .sdram_dqm(sdram_dqm)
|
|
);
|
|
|
|
endmodule
|