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 ACCUM_WIDTH = 32,
parameter N_MAX = 4096,
parameter WINDOW_SIZE = 4,
parameter PACKET_SIZE = 8,
parameter WINDOW_SIZE = 4, //65
parameter PACKET_SIZE = 8, //1024
parameter READ_BATCH_SIZE =(PACKET_SIZE*8)/(ACCUM_WIDTH)
)
(
@ -28,35 +28,27 @@ 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;
logic wea, enb, start_reg;
logic readout_begin_reg;
logic [ACCUM_WIDTH-1:0] out_data_reg;
logic out_valid_reg;
logic finish_reg, finish_buf;
logic read_batch, finish_reg, batch_req_reg, finish_buf;
logic [31:0] cnt_readout;
// registers for port b data request
reg req_data_b;
reg [15:0] req_addr_b;
typedef enum logic [3:0] {
typedef enum logic [2:0] {
IDLE,
INIT_MEM,
BEGIN_SEQ,
REQ_WORD_B,
INITIALIZE,
DELAY,
ACCUM,
READOUT_START,
READOUT_AWAIT,
READOUT_DELAY,
READOUT_PUT,
READOUT_LAST,
FINISH
} wr_state_t;
(* MARK_DEBUG="true" *) wr_state_t wr_state;
READOUT
} state_t;
state_t state;
always @(posedge clk_in) begin
if (rst) begin
@ -65,149 +57,161 @@ module accumulator
seq_num_reg <= '0;
cnt_seq_num <= '0;
cnt_addr <= '0;
enable <= 0;
wea <= 0;
enb <= 0;
wr_state <= IDLE;
delay_cnt <= '0;
state <= IDLE;
read_batch <= 0;
cnt_readout <= '0;
finish_reg <= 0;
out_valid_reg <= 0;
end else begin
batch_req_reg <= batch_req;
finish_buf <= finish;
// FSM
case(wr_state)
start_reg <= start;
case(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) begin
if (start_reg) begin
enable <= 1;
end
if (enable) begin
smp_num_reg <= smp_num;
seq_num_reg <= seq_num;
wr_state <= INIT_MEM;
state <= INITIALIZE;
end
end
INIT_MEM: begin
// first run to initialize memory with first batch of values
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
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;
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;
state <= DELAY;
end
ACCUM: begin
// sum mem+input
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;
cnt_smp_num <= cnt_smp_num + WINDOW_SIZE;
if (cnt_smp_num + WINDOW_SIZE >= smp_num_reg) begin
wr_state <= BEGIN_SEQ;
cnt_smp_num <= cnt_smp_num + WINDOW_SIZE;
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;
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;
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;
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) begin
wr_state <= READOUT_LAST;
enb <= 0;
end
addrb <= addrb + 1;
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;
// out_data_reg <= data_bram_out;
cnt_readout <= cnt_readout + 1;
if (cnt_readout < READ_BATCH_SIZE) begin
addrb <= addrb + 1;
end
READOUT_LAST: begin
// last word of packet
out_valid_reg <= 0;
out_data_reg <= data_bram_out;
wr_state <= FINISH;
end
FINISH: begin
out_valid_reg <= 0;
if (cnt_readout == READ_BATCH_SIZE) begin
read_batch <= 0;
enb <= 0;
wr_state <= IDLE;
out_valid_reg <= 0;
cnt_readout <= 0;
end
default: wr_state <= IDLE;
end
end
default: state <= IDLE;
endcase
end
end
adder
#(
.DATA_WIDTH(DATA_WIDTH),
@ -248,7 +252,7 @@ module accumulator
.USE_MEM_INIT_MMI(0), // DECIMAL
.WAKEUP_TIME("disable_sleep"), // String
.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
)
xpm_memory_sdpram_inst (
@ -266,7 +270,7 @@ module accumulator
);
assign readout_begin = readout_begin_reg;
assign out_data = out_data_reg;
assign out_data = data_bram_out;
assign out_valid = out_valid_reg;
endmodule