Replace the single async-read polymem[0:28*256-1] with 3 polynomial-indexed banks (bank_a A_hat / bank_se s_hat||e_hat / bank_t t_hat), addressed by abs_slot - base_slot. Still async-read here -- a pure refactor that validates bank sizing and base-relative addressing with zero timing change before stage 2b converts them to registered sd_bram + read-ahead pipelines. 11/11 KAT PASS, byte-exact, 0 file-not-found.
48 lines
2.4 KiB
Markdown
48 lines
2.4 KiB
Markdown
# Phase 2: polymem -> BRAM banks
|
|
|
|
## Goal
|
|
Replace the single multi-port async-read `reg [11:0] polymem [0:28*256-1]` with
|
|
registered-read `sd_bram` banks that infer real BRAM (ASIC: compiled SRAM).
|
|
|
|
## Bank split (all sd_bram, W=12, 1R+1W registered)
|
|
- bank_a : A_hat[i][j], slots 0..K^2-1 -> D=4096 (KMAX^2*256), A=12
|
|
- bank_se: s_hat[i] then e_hat[i] -> D=2048 (2*KMAX*256), A=11
|
|
relative slot = abs_slot - slot_s_rt (s: 0..K-1, e: K..2K-1)
|
|
- bank_t : t_hat[i], slots slot_t_rt.. -> D=1024 (KMAX*256), A=10
|
|
relative slot = abs_slot - slot_t_rt
|
|
|
|
## Port budget (verified disjoint)
|
|
- poly_mul LOAD vs ACCUMULATE never overlap; ST_N/ST_M/ST_E are disjoint
|
|
top-states. => each bank needs only 1R+1W. sd_bram fits.
|
|
- bank_t ST_M-acc reads t_hat[idx] (j>0 source) and writes t_hat[idx] result
|
|
same cycle: 1R+1W, read-old/write-new. Prefetch keeps read AHEAD of write
|
|
(monotonic idx), so no same-pass RAW hazard.
|
|
|
|
## Read sites (all need 1-cycle read-ahead vs async today)
|
|
- ntt_in (ST_N load) <- bank_se[n_slot]
|
|
- e_c0,e_c1 (ST_E) <- bank_se (dk) or bank_t (ek); SERIALIZE the
|
|
two reads across the 3-byte/pair window
|
|
- pm_a_in (ST_M load) <- bank_a[m_aslot]
|
|
- pm_b_in (ST_M load) <- bank_se[m_j]
|
|
- m_acc_src (ST_M acc) <- bank_se[K+m_i] (j==0) or bank_t[m_i] (j>0)
|
|
- dbg_coeff_o (not on KAT path) <- route by slot range (compile-only)
|
|
|
|
## Write sites
|
|
- ST_A: bank_a[a_slot] <= snt_coeff
|
|
- ST_C: bank_se[c_slot-slot_s] <= cbd_modq
|
|
- ST_N: bank_se[n_slot] <= ntt_coeff (write-back, same slot)
|
|
- ST_M-acc: bank_t[m_i] <= m_accq
|
|
|
|
## Read-ahead strategy
|
|
Cores hold ready_o high through entire LOAD (no mid-stream backpressure) =>
|
|
fixed 1-cycle skew. Pattern: advance a read-address pointer 1 cycle ahead of
|
|
the consumer index; delay the consumer's valid by 1 cycle ("prime the pipe").
|
|
For ST_M-acc (irregular pm_vo cadence 0,1,1): 2-entry prefetch skid buffer,
|
|
read pointer runs monotonically ahead of write pointer.
|
|
|
|
## Checkpoints (KAT-gated: 11 cases, byte-exact, 0 file-not-found)
|
|
- 2a: split polymem -> 4 ASYNC-read banks (pure refactor, zero timing change).
|
|
Validates bank sizing + base-relative addressing + debug mux. COMMIT.
|
|
- 2b: convert banks to registered sd_bram + add read-ahead pipelines to every
|
|
consumer FSM (ST_N, ST_E, ST_M load, ST_M acc). COMMIT.
|