From e083cd5c2e26547b897287c70af58167a11cf231 Mon Sep 17 00:00:00 2001 From: Phil Date: Tue, 28 Apr 2026 13:13:27 +0300 Subject: [PATCH] rtl: update accum to support real cases --- rtl/accum/src/accum.sv | 321 +++++++++++++++---------------- rtl/accum/src/accum_top.sv | 4 +- rtl/accum/tests/accum_full_tb.sv | 24 +-- 3 files changed, 173 insertions(+), 176 deletions(-) diff --git a/rtl/accum/src/accum.sv b/rtl/accum/src/accum.sv index 0522a7d..121acdc 100644 --- a/rtl/accum/src/accum.sv +++ b/rtl/accum/src/accum.sv @@ -5,8 +5,8 @@ module accumulator parameter DATA_WIDTH = 12, parameter ACCUM_WIDTH = 32, parameter N_MAX = 4096, - parameter WINDOW_SIZE = 4, //65 - parameter PACKET_SIZE = 8, //1024 + parameter WINDOW_SIZE = 4, + parameter PACKET_SIZE = 8, parameter READ_BATCH_SIZE =(PACKET_SIZE*8)/(ACCUM_WIDTH) ) ( @@ -25,30 +25,38 @@ module accumulator input finish ); - logic [31:0] smp_num_reg, cnt_smp_num; - logic [15:0] seq_num_reg, cnt_seq_num; - logic [15:0] cnt_addr, addra, addrb; - logic [1:0] delay_cnt; - logic enable; - logic [ACCUM_WIDTH-1:0] data; - logic valid_data; -logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; - logic wea, enb, start_reg; + logic [31:0] smp_num_reg, cnt_smp_num; + logic [15:0] seq_num_reg, cnt_seq_num; + logic [15:0] cnt_addr, addra, addrb; - logic readout_begin_reg; - logic [ACCUM_WIDTH-1:0] out_data_reg; - logic out_valid_reg; - logic read_batch, finish_reg, batch_req_reg, finish_buf; - logic [31:0] cnt_readout; + logic [ACCUM_WIDTH-1:0] data; + logic valid_data; + logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; + logic wea, enb; - typedef enum logic [2:0] { + logic readout_begin_reg; + logic [ACCUM_WIDTH-1:0] out_data_reg; + 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, - INITIALIZE, - DELAY, + INIT_MEM, + BEGIN_SEQ, + REQ_WORD_B, ACCUM, - READOUT - } state_t; - state_t state; + READOUT_START, + READOUT_AWAIT, + READOUT_DELAY, + READOUT_PUT, + READOUT_LAST, + FINISH + } wr_state_t; + (* MARK_DEBUG="true" *) wr_state_t wr_state; always @(posedge clk_in) begin if (rst) begin @@ -57,161 +65,148 @@ logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; seq_num_reg <= '0; cnt_seq_num <= '0; cnt_addr <= '0; - enable <= 0; wea <= 0; enb <= 0; - delay_cnt <= '0; - state <= IDLE; - read_batch <= 0; - cnt_readout <= '0; + wr_state <= IDLE; finish_reg <= 0; out_valid_reg <= 0; end else begin - batch_req_reg <= batch_req; finish_buf <= finish; - start_reg <= start; - case(state) + + // FSM + case(wr_state) + IDLE: begin + // wait for start signal + wea <= 0; + enb <= 0; + readout_begin_reg <= 0; + finish_reg <= 0; + out_valid_reg <= 0; + if (start) begin + smp_num_reg <= smp_num; + seq_num_reg <= seq_num; + wr_state <= INIT_MEM; + end + + end + INIT_MEM: begin + // first run to initialize memory with first batch of values + wea <= 0; + if (valid_data) begin + 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; + end + + end + BEGIN_SEQ: begin + // start new acc seq + 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; - enb <= 0; - read_batch <= 0; - cnt_readout <= '0; - readout_begin_reg <= 0; - finish_reg <= 0; - out_valid_reg <= 0; - if (start_reg) begin - enable <= 1; - end - if (enable) begin - smp_num_reg <= smp_num; - seq_num_reg <= seq_num; - state <= INITIALIZE; - end + addrb <= 0; + wr_state <= REQ_WORD_B; + end + end - end - INITIALIZE: begin - if (enable) begin - if ( cnt_seq_num == 0) begin - wea <= 0; - if (valid_data) begin - data_bram_in <= data; - addra <= cnt_addr; - wea <= 1; - if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - end else begin - cnt_addr <= cnt_addr+1; - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - end - end - if (cnt_smp_num >= smp_num_reg) begin - cnt_seq_num <= cnt_seq_num + 1; - cnt_smp_num <= '0; - cnt_addr <= '0; - wea <= 0; + REQ_WORD_B: begin + // pre-request data for port b + wea <= 0; + enb <= 1; + addrb <= cnt_addr; + wr_state <= ACCUM; + end - addrb <= 0; - enb <= 1; - state <= DELAY; - end - end - else begin - state <= DELAY; - addrb <= cnt_addr; - enb <= 1; - wea <= 0; - end - end else begin - state <= IDLE; - end - end - DELAY: begin - enb <= 0; - if (delay_cnt == 0) begin - delay_cnt <= 1; - end else if (delay_cnt == 1) begin - delay_cnt <= 0; - if (readout_begin_reg) begin - state <= READOUT; - end else begin - state <= ACCUM; - end - end - end ACCUM: begin - if (enable) begin - if (valid_data) begin - addra <= cnt_addr; - wea <= 1; - data_bram_in <= data + data_bram_out; - if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - end else begin - cnt_smp_num <= cnt_smp_num + WINDOW_SIZE; - cnt_addr <= cnt_addr + 1; - end - end - - if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin - if (cnt_seq_num == seq_num_reg - 1) begin - readout_begin_reg <= 1; - cnt_seq_num <= '0; - cnt_smp_num <= '0; - cnt_addr <= '0; - state <= DELAY; - addrb <= '0; - enb <= 0; - end else begin - cnt_seq_num <= cnt_seq_num + 1; - cnt_smp_num <= 0; - addrb <= 0; - cnt_addr <= 0; - state <= INITIALIZE; - end - end else if (valid_data) begin - state <= INITIALIZE; - end + // sum mem+input + enb <= 0; + if (valid_data) begin + addra <= cnt_addr; + 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 else begin - state <= IDLE; + cnt_addr <= cnt_addr + 1; + wr_state <= REQ_WORD_B; end - end - READOUT: begin - enable <= 0; - wea <= 0; - if (finish_buf) begin - read_batch <= 0; - enb <= 0; - out_valid_reg <= 0; - cnt_readout <= 0; - addrb <= 0; - state <= IDLE; - readout_begin_reg <= 0; - end else if ( batch_req_reg ) begin - read_batch <= 1; - enb <= 1; - // addrb <= 0; - cnt_readout <= 0; - out_valid_reg <= 0; - end else if ( read_batch) begin - out_valid_reg <= 1; -// out_data_reg <= data_bram_out; - cnt_readout <= cnt_readout + 1; - if (cnt_readout < READ_BATCH_SIZE) begin - addrb <= addrb + 1; - end - if (cnt_readout == READ_BATCH_SIZE) begin - read_batch <= 0; - enb <= 0; - out_valid_reg <= 0; - cnt_readout <= 0; - end - end - end - default: state <= IDLE; + end + end + READOUT_START: begin + readout_begin_reg <= 1'b1; + wr_state <= READOUT_AWAIT; + enb <= 0; + end + + READOUT_AWAIT: begin + // req await + delay for every-clock readout. + if (batch_req) begin + enb <= 1; + wr_state <= READOUT_DELAY; + end else if (finish_buf) begin + wr_state <= FINISH; + end else begin + enb <= 0; + out_valid_reg <= 0; + end + end + + READOUT_DELAY: begin + // wait for mem latency + addrb <= addrb + 1; + wr_state <= READOUT_PUT; + end + + READOUT_PUT: begin + // main data output + if ((addrb % READ_BATCH_SIZE) == 0) begin + wr_state <= READOUT_LAST; + enb <= 0; + end else addrb <= addrb + 1; + + out_valid_reg <= 1; + out_data_reg <= data_bram_out; + end + + READOUT_LAST: begin + // last word of packet + out_valid_reg <= 0; + out_data_reg <= data_bram_out; + wr_state <= READOUT_START; + end + + FINISH: begin + out_valid_reg <= 0; + enb <= 0; + wr_state <= IDLE; + end + + default: wr_state <= IDLE; endcase end end + adder #( .DATA_WIDTH(DATA_WIDTH), @@ -227,7 +222,7 @@ logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; .sum_valid(valid_data) ); - xpm_memory_sdpram #( + xpm_memory_sdpram #( .ADDR_WIDTH_A(16), // DECIMAL .ADDR_WIDTH_B(16), // DECIMAL .AUTO_SLEEP_TIME(0), // DECIMAL @@ -252,7 +247,7 @@ logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; .USE_MEM_INIT_MMI(0), // DECIMAL .WAKEUP_TIME("disable_sleep"), // String .WRITE_DATA_WIDTH_A(ACCUM_WIDTH), // DECIMAL - .WRITE_MODE_B("read_first"), // String no_change + .WRITE_MODE_B("no_change"), // String .WRITE_PROTECT(1) // DECIMAL ) xpm_memory_sdpram_inst ( @@ -270,7 +265,7 @@ logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; ); assign readout_begin = readout_begin_reg; - assign out_data = data_bram_out; + assign out_data = out_data_reg; assign out_valid = out_valid_reg; endmodule diff --git a/rtl/accum/src/accum_top.sv b/rtl/accum/src/accum_top.sv index bf1616b..3ae2f62 100644 --- a/rtl/accum/src/accum_top.sv +++ b/rtl/accum/src/accum_top.sv @@ -5,8 +5,8 @@ module accumulator_top parameter DATA_WIDTH = 12, parameter ACCUM_WIDTH = 32, parameter N_MAX = 4096, - parameter WINDOW_SIZE = 4, - parameter PACKET_SIZE = 8, + parameter WINDOW_SIZE = 65, + parameter PACKET_SIZE = 1024, parameter READ_BATCH_SIZE =(PACKET_SIZE*8)/(ACCUM_WIDTH) ) ( diff --git a/rtl/accum/tests/accum_full_tb.sv b/rtl/accum/tests/accum_full_tb.sv index 1b6d1d5..a7196c5 100644 --- a/rtl/accum/tests/accum_full_tb.sv +++ b/rtl/accum/tests/accum_full_tb.sv @@ -4,11 +4,11 @@ module tb_accumulator_top; localparam DATA_WIDTH = 12; localparam ACCUM_WIDTH = 32; - localparam N_MAX = 256; - localparam WINDOW_SIZE = 4; - localparam PACKET_SIZE = 128; + localparam N_MAX = 4096; + localparam WINDOW_SIZE = 65; + localparam PACKET_SIZE = 1024; localparam READ_BATCH_SIZE = (PACKET_SIZE*8)/ACCUM_WIDTH; - localparam MAX_WORDS = N_MAX / WINDOW_SIZE; + localparam MAX_WORDS = N_MAX; localparam MAX_SEQ_NUM = 64; logic clk_in; @@ -147,7 +147,7 @@ module tb_accumulator_top; input integer base_value, input string test_name ); - logic [DATA_WIDTH-1:0] sample_mem [0:MAX_SEQ_NUM-1][0:N_MAX-1]; + logic [DATA_WIDTH-1:0] sample_mem [0:MAX_SEQ_NUM-1][0:(N_MAX*WINDOW_SIZE)-1]; integer seq_idx; integer sample_idx; integer word_idx; @@ -213,7 +213,7 @@ module tb_accumulator_top; end timeout_cnt = 0; - while (packets_seen < exp_packet_count && timeout_cnt < 30000) begin + while (packets_seen < exp_packet_count && timeout_cnt < 50 * PACKET_SIZE) begin @(posedge eth_clk_in); timeout_cnt = timeout_cnt + 1; end @@ -318,12 +318,14 @@ module tb_accumulator_top; reset_dut(); - run_test(1, 2, 8, 1'b0, 1, "deterministic_small"); - run_test(2, 3, 8, 1'b1, 0, "random_seq3_smp8"); - run_test(3, 5, 16, 1'b1, 0, "random_seq5_smp16_multi_packet"); + run_test(1, 1, 1 * WINDOW_SIZE, 1'b0, 1, "deterministic_small"); +// $finish; + run_test(2, 2, 1 * WINDOW_SIZE, 1'b1, 0, "random_seq3_smp8"); + run_test(3, 1, 16 * WINDOW_SIZE, 1'b1, 0, "random_seq5_smp16_multi_packet"); // run_test(4, 1, 4, 1'b1, 0, "random_single_window"); - run_test(5, 7, 12, 1'b1, 0, "random_seq7_smp12"); - run_test(6, 4, 256, 1'b1, 0, "random_max_smpnum"); + run_test(5, 2, 12 * WINDOW_SIZE, 1'b1, 0, "random_seq7_smp12"); + run_test(6, 4, 256 * WINDOW_SIZE, 1'b1, 0, "random_max_smpnum"); + run_test(7, 2, 1500 * WINDOW_SIZE, 1'b1, 0, "random_max_smpnum2"); $display("\n========================================"); $display("ALL TESTS COMPLETED");