refactor(kg): registered read-ahead for ST_M load (bank_a + bank_se)
Second per-consumer step of stage 2b. m_ld becomes a read-ahead pointer; both poly_mul load reads (bank_a A_hat, bank_se s_hat) are registered into pm_a_rd/pm_b_rd and fed one cycle later (pm_valid delayed 1 cyc), same pattern as ST_N. 11/11 KAT PASS, byte-exact.
This commit is contained in:
@@ -483,11 +483,14 @@ module mlkem_top #(
|
||||
wire [11:0] pm_coeff;
|
||||
wire pm_vo;
|
||||
// pm_a: A_hat[i][j] in bank_a (abs slot m_aslot). pm_b: s_hat[j] in
|
||||
// bank_se (relative slot = m_sslot - slot_s_rt = m_j).
|
||||
// bank_se (relative slot = m_sslot - slot_s_rt = m_j). m_ld is a read-ahead
|
||||
// pointer; both bank reads are registered into pm_a_rd/pm_b_rd and fed to
|
||||
// poly_mul one cycle later (pm_valid delayed 1 cyc), like ST_N.
|
||||
wire [13:0] pm_a_full = m_aslot*256 + m_ld[7:0];
|
||||
wire [13:0] pm_b_full = m_j*256 + m_ld[7:0];
|
||||
wire [11:0] pm_a_in = bank_a [pm_a_full[PA_AW-1:0]];
|
||||
wire [11:0] pm_b_in = bank_se[pm_b_full[PSE_AW-1:0]];
|
||||
reg [11:0] pm_a_rd, pm_b_rd; // registered bank reads (sd_bram timing)
|
||||
wire [11:0] pm_a_in = pm_a_rd;
|
||||
wire [11:0] pm_b_in = pm_b_rd;
|
||||
|
||||
poly_mul_sync u_pmul (
|
||||
.clk(clk), .rst_n(rst_n),
|
||||
@@ -561,6 +564,8 @@ module mlkem_top #(
|
||||
m_loading <= 1'b0;
|
||||
m_pending <= 1'b0;
|
||||
pm_valid <= 1'b0;
|
||||
pm_a_rd <= 12'd0;
|
||||
pm_b_rd <= 12'd0;
|
||||
e_poly <= 3'd0;
|
||||
e_pair <= 8'd0;
|
||||
e_byte <= 2'd0;
|
||||
@@ -732,7 +737,9 @@ module mlkem_top #(
|
||||
end
|
||||
end
|
||||
|
||||
// Arm M stage when N finishes: start first (i=0,j=0) poly_mul load
|
||||
// Arm M stage when N finishes: prime first (i=0,j=0) poly_mul load.
|
||||
// m_ld read-ahead pointer; pm_a_rd/pm_b_rd registered, pm_valid
|
||||
// asserted one cycle after an address is presented (like ST_N).
|
||||
if (st == ST_N && st_next == ST_M) begin
|
||||
m_i <= 2'd0;
|
||||
m_j <= 2'd0;
|
||||
@@ -740,20 +747,26 @@ module mlkem_top #(
|
||||
m_oidx <= 8'd0;
|
||||
m_loading <= 1'b1;
|
||||
m_pending <= 1'b0;
|
||||
pm_valid <= 1'b1;
|
||||
pm_valid <= 1'b0;
|
||||
end
|
||||
|
||||
// ---- ST_M: t_hat[i] = e_hat[i] + sum_j A[i][j] o s_hat[j] ----
|
||||
if (st == ST_M) begin
|
||||
// LOAD: stream 256 (A,shat) pairs into poly_mul
|
||||
if (m_loading && pm_valid && pm_ready) begin
|
||||
if (m_ld == 9'd255) begin
|
||||
pm_valid <= 1'b0; // last pair presented
|
||||
// LOAD: present read-ahead addr to bank_a/bank_se; the pair
|
||||
// registered last cycle (pm_a_rd/pm_b_rd) is consumed by
|
||||
// poly_mul this cycle (pm_valid). poly_mul holds ready high
|
||||
// through LOAD, so a fixed 1-cycle skew suffices.
|
||||
if (m_loading) begin
|
||||
if (m_ld == 9'd256) begin
|
||||
pm_valid <= 1'b0; // 256th pair consumed this cycle
|
||||
m_loading <= 1'b0;
|
||||
m_ld <= 9'd0;
|
||||
m_oidx <= 8'd0;
|
||||
end else begin
|
||||
m_ld <= m_ld + 9'd1;
|
||||
pm_a_rd <= bank_a [pm_a_full[PA_AW-1:0]];
|
||||
pm_b_rd <= bank_se[pm_b_full[PSE_AW-1:0]];
|
||||
m_ld <= m_ld + 9'd1;
|
||||
pm_valid <= 1'b1; // pair presented last cycle is valid
|
||||
end
|
||||
end
|
||||
|
||||
@@ -776,12 +789,12 @@ module mlkem_top #(
|
||||
end
|
||||
end
|
||||
|
||||
// Start next (i,j) poly_mul load once core is IDLE again
|
||||
// Start next (i,j) poly_mul load once core is IDLE again (re-prime)
|
||||
if (m_pending && pm_ready && !pm_vo) begin
|
||||
pm_valid <= 1'b1;
|
||||
m_loading <= 1'b1;
|
||||
m_ld <= 9'd0;
|
||||
m_oidx <= 8'd0;
|
||||
pm_valid <= 1'b0;
|
||||
m_pending <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user