rtl: update accum to support real cases

This commit is contained in:
Phil
2026-04-28 13:13:27 +03:00
parent 264c9ecb8e
commit e083cd5c2e
3 changed files with 173 additions and 176 deletions

View File

@ -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)
)
(
@ -28,27 +28,35 @@ module accumulator
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 wea, enb;
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 finish_reg, finish_buf;
typedef enum logic [2:0] {
// 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;
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
if (start) begin
smp_num_reg <= smp_num;
seq_num_reg <= seq_num;
state <= INITIALIZE;
wr_state <= INIT_MEM;
end
end
INITIALIZE: begin
if (enable) begin
if ( cnt_seq_num == 0) begin
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;
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
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;
addrb <= 0;
enb <= 1;
state <= DELAY;
wr_state <= REQ_WORD_B;
end
end
else begin
state <= DELAY;
addrb <= cnt_addr;
enb <= 1;
REQ_WORD_B: begin
// pre-request data for port b
wea <= 0;
enb <= 1;
addrb <= cnt_addr;
wr_state <= ACCUM;
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
// 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
cnt_smp_num <= cnt_smp_num + WINDOW_SIZE;
wr_state <= BEGIN_SEQ;
end else begin
cnt_smp_num <= cnt_smp_num + WINDOW_SIZE;
cnt_addr <= cnt_addr + 1;
wr_state <= REQ_WORD_B;
end
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
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
end else begin
state <= IDLE;
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
READOUT_DELAY: begin
// wait for mem latency
addrb <= addrb + 1;
wr_state <= READOUT_PUT;
end
if (cnt_readout == READ_BATCH_SIZE) begin
read_batch <= 0;
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;
cnt_readout <= 0;
out_data_reg <= data_bram_out;
wr_state <= READOUT_START;
end
FINISH: begin
out_valid_reg <= 0;
enb <= 0;
wr_state <= IDLE;
end
end
default: state <= IDLE;
default: wr_state <= IDLE;
endcase
end
end
adder
#(
.DATA_WIDTH(DATA_WIDTH),
@ -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

View File

@ -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)
)
(

View File

@ -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");