rtl: update accum design

This commit is contained in:
Phil
2026-04-28 11:55:46 +03:00
parent a8a3aff498
commit 9b189f931f

View File

@ -5,8 +5,8 @@ module accumulator
parameter DATA_WIDTH = 12, parameter DATA_WIDTH = 12,
parameter ACCUM_WIDTH = 32, parameter ACCUM_WIDTH = 32,
parameter N_MAX = 4096, parameter N_MAX = 4096,
parameter WINDOW_SIZE = 4, parameter WINDOW_SIZE = 4, //65
parameter PACKET_SIZE = 8, parameter PACKET_SIZE = 8, //1024
parameter READ_BATCH_SIZE =(PACKET_SIZE*8)/(ACCUM_WIDTH) parameter READ_BATCH_SIZE =(PACKET_SIZE*8)/(ACCUM_WIDTH)
) )
( (
@ -17,46 +17,38 @@ module accumulator
input start, input start,
input [31:0] smp_num, input [31:0] smp_num,
input [15:0] seq_num, input [15:0] seq_num,
output [ACCUM_WIDTH-1:0] out_data, output [ACCUM_WIDTH-1:0] out_data,
output out_valid, output out_valid,
output readout_begin, output readout_begin,
input batch_req, input batch_req,
input finish 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 [ACCUM_WIDTH-1:0] data; logic [31:0] smp_num_reg, cnt_smp_num;
logic valid_data; logic [15:0] seq_num_reg, cnt_seq_num;
logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out; logic [15:0] cnt_addr, addra, addrb;
logic wea, enb; logic [1:0] delay_cnt;
logic enable;
logic readout_begin_reg; logic [ACCUM_WIDTH-1:0] data;
logic [ACCUM_WIDTH-1:0] out_data_reg; logic valid_data;
logic out_valid_reg; logic [ACCUM_WIDTH-1:0] data_bram_in, data_bram_out;
logic finish_reg, finish_buf; logic wea, enb, start_reg;
// registers for port b data request logic readout_begin_reg;
reg req_data_b; logic [ACCUM_WIDTH-1:0] out_data_reg;
reg [15:0] req_addr_b; logic out_valid_reg;
logic read_batch, finish_reg, batch_req_reg, finish_buf;
typedef enum logic [3:0] { logic [31:0] cnt_readout;
typedef enum logic [2:0] {
IDLE, IDLE,
INIT_MEM, INITIALIZE,
BEGIN_SEQ, DELAY,
REQ_WORD_B,
ACCUM, ACCUM,
READOUT_START, READOUT
READOUT_AWAIT, } state_t;
READOUT_DELAY, state_t state;
READOUT_PUT,
READOUT_LAST,
FINISH
} wr_state_t;
(* MARK_DEBUG="true" *) wr_state_t wr_state;
always @(posedge clk_in) begin always @(posedge clk_in) begin
if (rst) begin if (rst) begin
@ -65,150 +57,162 @@ module accumulator
seq_num_reg <= '0; seq_num_reg <= '0;
cnt_seq_num <= '0; cnt_seq_num <= '0;
cnt_addr <= '0; cnt_addr <= '0;
enable <= 0;
wea <= 0; wea <= 0;
enb <= 0; enb <= 0;
wr_state <= IDLE; delay_cnt <= '0;
state <= IDLE;
read_batch <= 0;
cnt_readout <= '0;
finish_reg <= 0; finish_reg <= 0;
out_valid_reg <= 0; out_valid_reg <= 0;
end else begin end else begin
batch_req_reg <= batch_req;
finish_buf <= finish; finish_buf <= finish;
start_reg <= start;
// FSM case(state)
case(wr_state)
IDLE: begin 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; wea <= 0;
addrb <= 0;
wr_state <= REQ_WORD_B;
end
end
REQ_WORD_B: begin
// pre-request data for port b
wea <= 0;
enb <= 1;
addrb <= cnt_addr;
wr_state <= ACCUM;
end
ACCUM: 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
wr_state <= BEGIN_SEQ;
end else begin
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;
addrb <= 0;
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; enb <= 0;
read_batch <= 0;
cnt_readout <= '0;
readout_begin_reg <= 0;
finish_reg <= 0;
out_valid_reg <= 0; out_valid_reg <= 0;
end if (start_reg) begin
end enable <= 1;
end
if (enable) begin
smp_num_reg <= smp_num;
seq_num_reg <= seq_num;
state <= INITIALIZE;
end
READOUT_DELAY: begin end
// wait for mem latency INITIALIZE: begin
addrb <= addrb + 1; if (enable) begin
wr_state <= READOUT_PUT; if ( cnt_seq_num == 0) begin
end 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;
READOUT_PUT: begin addrb <= 0;
// main data output enb <= 1;
if (addrb == READ_BATCH_SIZE) begin state <= DELAY;
wr_state <= READOUT_LAST; 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; enb <= 0;
end if (delay_cnt == 0) begin
addrb <= addrb + 1; delay_cnt <= 1;
out_valid_reg <= 1; end else if (delay_cnt == 1) begin
out_data_reg <= data_bram_out; delay_cnt <= 0;
end 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
READOUT_LAST: begin if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin
// last word of packet if (cnt_seq_num == seq_num_reg - 1) begin
out_valid_reg <= 0; readout_begin_reg <= 1;
out_data_reg <= data_bram_out; cnt_seq_num <= '0;
wr_state <= FINISH; cnt_smp_num <= '0;
end cnt_addr <= '0;
state <= DELAY;
FINISH: begin addrb <= '0;
out_valid_reg <= 0; enb <= 0;
enb <= 0; end else begin
wr_state <= IDLE; cnt_seq_num <= cnt_seq_num + 1;
end cnt_smp_num <= 0;
addrb <= 0;
default: wr_state <= IDLE; 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
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;
endcase endcase
end end
end end
adder
adder
#( #(
.DATA_WIDTH(DATA_WIDTH), .DATA_WIDTH(DATA_WIDTH),
.WINDOW_SIZE(WINDOW_SIZE), .WINDOW_SIZE(WINDOW_SIZE),
@ -222,8 +226,8 @@ module accumulator
.sum_data(data), .sum_data(data),
.sum_valid(valid_data) .sum_valid(valid_data)
); );
xpm_memory_sdpram #( xpm_memory_sdpram #(
.ADDR_WIDTH_A(16), // DECIMAL .ADDR_WIDTH_A(16), // DECIMAL
.ADDR_WIDTH_B(16), // DECIMAL .ADDR_WIDTH_B(16), // DECIMAL
.AUTO_SLEEP_TIME(0), // DECIMAL .AUTO_SLEEP_TIME(0), // DECIMAL
@ -248,25 +252,25 @@ module accumulator
.USE_MEM_INIT_MMI(0), // DECIMAL .USE_MEM_INIT_MMI(0), // DECIMAL
.WAKEUP_TIME("disable_sleep"), // String .WAKEUP_TIME("disable_sleep"), // String
.WRITE_DATA_WIDTH_A(ACCUM_WIDTH), // DECIMAL .WRITE_DATA_WIDTH_A(ACCUM_WIDTH), // DECIMAL
.WRITE_MODE_B("no_change"), // String .WRITE_MODE_B("read_first"), // String no_change
.WRITE_PROTECT(1) // DECIMAL .WRITE_PROTECT(1) // DECIMAL
) )
xpm_memory_sdpram_inst ( xpm_memory_sdpram_inst (
.doutb(data_bram_out), .doutb(data_bram_out),
.addra(addra), .addra(addra),
.addrb(addrb), .addrb(addrb),
.clka(clk_in), .clka(clk_in),
.clkb(clk_in), .clkb(clk_in),
.dina(data_bram_in), .dina(data_bram_in),
.ena(1'b1), .ena(1'b1),
.enb(enb), .enb(enb),
.wea(wea) .wea(wea)
); );
assign readout_begin = readout_begin_reg; assign readout_begin = readout_begin_reg;
assign out_data = out_data_reg; assign out_data = data_bram_out;
assign out_valid = out_valid_reg; assign out_valid = out_valid_reg;
endmodule endmodule