diff --git a/rtl/accum/src/accum.sv b/rtl/accum/src/accum.sv index d77ad2c..b7ef552 100644 --- a/rtl/accum/src/accum.sv +++ b/rtl/accum/src/accum.sv @@ -112,11 +112,23 @@ module accumulator seq_num_reg <= '0; cnt_seq_num <= '0; cnt_addr <= '0; + addra <= '0; + addrb <= '0; + data_bram_in <= '0; wea <= 0; enb <= 0; wr_state <= IDLE; finish_reg <= 0; + finish_buf <= 0; + readout_begin_reg <= 0; + out_data_reg <= '0; out_valid_reg <= 0; + accum_pipe_valid <= 0; + accum_pipe_addr <= '0; + accum_pipe_data <= '0; + accum_pipe_bypass_valid <= 0; + accum_pipe_bypass_data <= '0; + accum_done <= 0; end else begin finish_buf <= finish; @@ -130,6 +142,13 @@ module accumulator readout_begin_reg <= 0; finish_reg <= 0; out_valid_reg <= 0; + accum_pipe_valid <= 0; + accum_pipe_bypass_valid <= 0; + accum_done <= 0; + cnt_smp_num <= '0; + cnt_seq_num <= '0; + cnt_addr <= '0; + addrb <= '0; if (start) begin smp_num_reg <= smp_num; seq_num_reg <= seq_num; @@ -137,76 +156,122 @@ module accumulator end end + INIT_MEM: begin - // first run to initialize memory with first batch of values + // First sequence wea <= 0; + enb <= 0; + out_valid_reg <= 0; + accum_pipe_valid <= 0; + accum_pipe_bypass_valid <= 0; + accum_done <= 0; + if (valid_data) begin + // mem_wea/mem_addra/mem_dina do the actual write in this clock data_bram_in <= data; addra <= cnt_addr; wea <= 1; - cnt_addr <= cnt_addr + 1; - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - end - if (cnt_smp_num >= smp_num_reg) begin - wr_state <= BEGIN_SEQ; + if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin + cnt_smp_num <= '0; + cnt_addr <= '0; + + if (seq_num_reg <= 16'd1) begin + cnt_seq_num <= '0; + addrb <= '0; + wr_state <= READOUT_START; + end else begin + // start further accumulation + cnt_seq_num <= 16'd1; + wr_state <= ACCUM; + end + end else begin + cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; + cnt_addr <= cnt_addr + 1; + end end end + BEGIN_SEQ: begin - // start new acc seq + // FIXME: unused wea <= 0; enb <= 0; - if (cnt_seq_num == seq_num_reg - 1) begin - cnt_seq_num <= '0; - cnt_smp_num <= '0; - cnt_addr <= '0; - wr_state <= READOUT_START; - addrb <= '0; - enb <= 0; - end else begin - // beginning of new data sequence - cnt_seq_num <= cnt_seq_num + 1; - cnt_smp_num <= '0; - cnt_addr <= '0; - wea <= 0; - addrb <= 0; - wr_state <= REQ_WORD_B; - end + wr_state <= ACCUM; end REQ_WORD_B: begin - // pre-request data for port b + // FIXME: depr wea <= 0; - enb <= 1; - addrb <= cnt_addr; + enb <= 0; wr_state <= ACCUM; end ACCUM: begin - // sum mem+input + // accum pipeline + wea <= 0; enb <= 0; - if (valid_data) begin - addra <= cnt_addr; + out_valid_reg <= 0; + + if (accum_pipe_valid) begin + // mem_wea/mem_addra/mem_dina do the actual write this clock + addra <= accum_pipe_addr; + data_bram_in <= accum_write_value; wea <= 1; - data_bram_in <= data + data_bram_out; - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin - wr_state <= BEGIN_SEQ; + end + + if (accum_done) begin + // Last input word was accepted on the previous clk + accum_pipe_valid <= 0; + accum_pipe_bypass_valid <= 0; + cnt_smp_num <= '0; + cnt_seq_num <= '0; + cnt_addr <= '0; + addrb <= '0; + enb <= 0; + wr_state <= READOUT_START; + end else if (valid_data) begin + // mem_enb/mem_addrb launch the actual read this clock + enb <= 1; + addrb <= cnt_addr; + + accum_pipe_valid <= 1; + accum_pipe_addr <= cnt_addr; + accum_pipe_data <= data; + + // case window_size=1 && smp_num is small + accum_pipe_bypass_valid <= accum_pipe_valid && (accum_pipe_addr == cnt_addr); + accum_pipe_bypass_data <= accum_write_value; + + if (accum_accept_last) begin + cnt_smp_num <= '0; + cnt_addr <= '0; + + if (cnt_seq_num == seq_num_reg - 1) begin + accum_done <= 1; + end else begin + cnt_seq_num <= cnt_seq_num + 1; + end end else begin + cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; cnt_addr <= cnt_addr + 1; - wr_state <= REQ_WORD_B; end + end else begin + accum_pipe_valid <= 0; + accum_pipe_bypass_valid <= 0; end end + READOUT_START: begin readout_begin_reg <= 1'b1; wr_state <= READOUT_AWAIT; enb <= 0; + wea <= 0; end READOUT_AWAIT: begin - // req await + delay for every-clock readout. + // req await + delay for every-clock readout + wea <= 0; if (batch_req) begin enb <= 1; wr_state <= READOUT_DELAY; @@ -220,12 +285,14 @@ module accumulator READOUT_DELAY: begin // wait for mem latency + wea <= 0; addrb <= addrb + 1; wr_state <= READOUT_PUT; end READOUT_PUT: begin // main data output + wea <= 0; if ((addrb % READ_BATCH_SIZE) == 0) begin wr_state <= READOUT_LAST; enb <= 0; @@ -237,6 +304,7 @@ module accumulator READOUT_LAST: begin // last word of packet + wea <= 0; out_valid_reg <= 0; out_data_reg <= data_bram_out; wr_state <= READOUT_START; @@ -245,6 +313,7 @@ module accumulator FINISH: begin out_valid_reg <= 0; enb <= 0; + wea <= 0; wr_state <= IDLE; end @@ -301,14 +370,14 @@ module accumulator .doutb(data_bram_out), - .addra(addra), - .addrb(addrb), + .addra(mem_addra), + .addrb(mem_addrb), .clka(clk_in), .clkb(clk_in), - .dina(data_bram_in), + .dina(mem_dina), .ena(1'b1), - .enb(enb), - .wea(wea) + .enb(mem_enb), + .wea(mem_wea) ); assign readout_begin = readout_begin_reg;