From 02416a96210207e0f8bb02caa23413e80c425385 Mon Sep 17 00:00:00 2001 From: Phil Date: Fri, 26 Jun 2026 18:07:02 +0300 Subject: [PATCH] rtl: rework memory controls in accum --- rtl/accum/src/accum.sv | 55 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/rtl/accum/src/accum.sv b/rtl/accum/src/accum.sv index 121acdc..d77ad2c 100644 --- a/rtl/accum/src/accum.sv +++ b/rtl/accum/src/accum.sv @@ -39,10 +39,6 @@ module accumulator logic out_valid_reg; logic finish_reg, finish_buf; - // registers for port b data request - reg req_data_b; - reg [15:0] req_addr_b; - typedef enum logic [3:0] { IDLE, INIT_MEM, @@ -58,6 +54,57 @@ module accumulator } wr_state_t; (* MARK_DEBUG="true" *) wr_state_t wr_state; + // One word per clock accumulation pipeline + // On every sum_valid in ACCUM we launch a BRAM read for cnt_addr + // On the next clock the saved sum_data is added to doutb and written back + logic accum_pipe_valid; + logic [15:0] accum_pipe_addr; + logic [ACCUM_WIDTH-1:0] accum_pipe_data; + + // case smp_num // WINDOW_SIZE == 1 + // Then the next sequence can read the same address it is written + logic accum_pipe_bypass_valid; + logic [ACCUM_WIDTH-1:0] accum_pipe_bypass_data; + logic accum_done; + + logic accum_accept_last; + logic accum_accept_last_all; + logic [ACCUM_WIDTH-1:0] accum_write_base; + logic [ACCUM_WIDTH-1:0] accum_write_value; + + assign accum_accept_last = (cnt_smp_num + WINDOW_SIZE >= smp_num_reg); + assign accum_accept_last_all = accum_accept_last && (cnt_seq_num == seq_num_reg - 1); + assign accum_write_base = accum_pipe_bypass_valid ? accum_pipe_bypass_data : data_bram_out; + assign accum_write_value = accum_pipe_data + accum_write_base; + + // Memory controls to XPM + // In accumulation/init states they are driven directly from the current + // state and pipeline registers. That avoids an extra register stage + logic mem_wea; + logic mem_enb; + logic [15:0] mem_addra; + logic [15:0] mem_addrb; + logic [ACCUM_WIDTH-1:0] mem_dina; + + assign mem_wea = (wr_state == INIT_MEM) ? valid_data : + (wr_state == ACCUM) ? accum_pipe_valid : + 1'b0; + + assign mem_addra = (wr_state == INIT_MEM) ? cnt_addr : + (wr_state == ACCUM) ? accum_pipe_addr : + addra; + + assign mem_dina = (wr_state == INIT_MEM) ? data : + (wr_state == ACCUM) ? accum_write_value : + data_bram_in; + + assign mem_enb = (wr_state == ACCUM) ? valid_data : enb; + assign mem_addrb = (wr_state == ACCUM) ? cnt_addr : addrb; + + // registers for port b data request + reg req_data_b; + reg [15:0] req_addr_b; + always @(posedge clk_in) begin if (rst) begin smp_num_reg <= '0;