rtl: rework memory controls in accum
This commit is contained in:
@ -39,10 +39,6 @@ module accumulator
|
|||||||
logic out_valid_reg;
|
logic out_valid_reg;
|
||||||
logic finish_reg, finish_buf;
|
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] {
|
typedef enum logic [3:0] {
|
||||||
IDLE,
|
IDLE,
|
||||||
INIT_MEM,
|
INIT_MEM,
|
||||||
@ -58,6 +54,57 @@ module accumulator
|
|||||||
} wr_state_t;
|
} wr_state_t;
|
||||||
(* MARK_DEBUG="true" *) wr_state_t wr_state;
|
(* 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
|
always @(posedge clk_in) begin
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
smp_num_reg <= '0;
|
smp_num_reg <= '0;
|
||||||
|
|||||||
Reference in New Issue
Block a user