Pipeline matmul bank chaining
This commit is contained in:
@@ -119,8 +119,9 @@ module matmul_axi_slave (
|
||||
// ==========================================
|
||||
reg req_0, req_1;
|
||||
reg busy;
|
||||
reg done;
|
||||
reg [1:0] done_count;
|
||||
reg error;
|
||||
wire done = (done_count != 2'd0);
|
||||
|
||||
reg [31:0] b0_a [0:15];
|
||||
reg [31:0] b0_b [0:15];
|
||||
@@ -350,6 +351,8 @@ module matmul_axi_slave (
|
||||
|
||||
// 【修改点 1】单独引出一个写脉冲信号给 CRC 清零用
|
||||
wire crc_clear_pulse = (w_state == W_DATA) && s_axi_wvalid && s_axi_wready && (w_offset == ADDR_CRC);
|
||||
wire done_clear_pulse = (w_state == W_DATA) && s_axi_wvalid && s_axi_wready &&
|
||||
(w_offset == ADDR_STATUS) && s_axi_wdata[1];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
@@ -359,7 +362,7 @@ module matmul_axi_slave (
|
||||
s_axi_bvalid <= 1'b0;
|
||||
req_0 <= 1'b0;
|
||||
req_1 <= 1'b0;
|
||||
done <= 1'b0;
|
||||
done_count <= 2'd0;
|
||||
error <= 1'b0;
|
||||
end else begin
|
||||
if (ep_wr_valid && ep_wr_ready) begin
|
||||
@@ -383,10 +386,6 @@ module matmul_axi_slave (
|
||||
if (req_0 && state == C_RUN && cur_bank == 1'b0) req_0 <= 1'b0;
|
||||
if (req_1 && state == C_RUN && cur_bank == 1'b1) req_1 <= 1'b0;
|
||||
|
||||
if (calc_done_pulse) begin
|
||||
done <= 1'b1;
|
||||
end
|
||||
|
||||
case (w_state)
|
||||
W_IDLE: begin
|
||||
s_axi_awready <= 1'b1;
|
||||
@@ -406,7 +405,6 @@ module matmul_axi_slave (
|
||||
if (s_axi_wdata[1]) req_1 <= 1'b1;
|
||||
end
|
||||
else if (w_offset == ADDR_STATUS) begin
|
||||
if (s_axi_wdata[1]) done <= 1'b0;
|
||||
if (s_axi_wdata[2]) error <= 1'b0;
|
||||
end
|
||||
// 【修改点 2】删除 else if (w_offset == ADDR_CRC) { crc_reg <= ... } 防止多重驱动
|
||||
@@ -440,6 +438,12 @@ module matmul_axi_slave (
|
||||
end
|
||||
default: w_state <= W_IDLE;
|
||||
endcase
|
||||
|
||||
case ({calc_done_pulse, done_clear_pulse})
|
||||
2'b10: if (done_count != 2'd3) done_count <= done_count + 2'd1;
|
||||
2'b01: if (done_count != 2'd0) done_count <= done_count - 2'd1;
|
||||
default: done_count <= done_count;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
@@ -580,8 +584,33 @@ module matmul_axi_slave (
|
||||
// Pipeline delay shift registers for accumulation (4 stages = 3 multiplier pipe + 1)
|
||||
reg [3:0] acc_idx_d1, acc_idx_d2, acc_idx_d3, acc_idx_d4;
|
||||
reg acc_bank_d1, acc_bank_d2, acc_bank_d3, acc_bank_d4;
|
||||
reg acc_valid_d1, acc_valid_d2, acc_valid_d3, acc_valid_d4;
|
||||
reg [4:0] pipe_cnt;
|
||||
|
||||
task start_calc_bank;
|
||||
input bank;
|
||||
begin
|
||||
cur_bank <= bank;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
pipe_cnt <= 5'd1;
|
||||
acc_idx_d1 <= 4'd0;
|
||||
acc_bank_d1 <= bank;
|
||||
acc_valid_d1 <= 1'b1;
|
||||
if (bank == 1'b0) begin
|
||||
m_in_a[0] <= b0_a[4'd0]; m_in_b[0] <= b0_b[4'd0];
|
||||
m_in_a[1] <= b0_a[4'd1]; m_in_b[1] <= b0_b[4'd4];
|
||||
m_in_a[2] <= b0_a[4'd2]; m_in_b[2] <= b0_b[4'd8];
|
||||
m_in_a[3] <= b0_a[4'd3]; m_in_b[3] <= b0_b[4'd12];
|
||||
end else begin
|
||||
m_in_a[0] <= b1_a[4'd0]; m_in_b[0] <= b1_b[4'd0];
|
||||
m_in_a[1] <= b1_a[4'd1]; m_in_b[1] <= b1_b[4'd4];
|
||||
m_in_a[2] <= b1_a[4'd2]; m_in_b[2] <= b1_b[4'd8];
|
||||
m_in_a[3] <= b1_a[4'd3]; m_in_b[3] <= b1_b[4'd12];
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!resetn) begin
|
||||
state <= C_IDLE;
|
||||
@@ -597,6 +626,10 @@ module matmul_axi_slave (
|
||||
acc_bank_d2 <= 1'b0;
|
||||
acc_bank_d3 <= 1'b0;
|
||||
acc_bank_d4 <= 1'b0;
|
||||
acc_valid_d1 <= 1'b0;
|
||||
acc_valid_d2 <= 1'b0;
|
||||
acc_valid_d3 <= 1'b0;
|
||||
acc_valid_d4 <= 1'b0;
|
||||
end else begin
|
||||
calc_done_pulse <= 1'b0;
|
||||
|
||||
@@ -604,24 +637,24 @@ module matmul_axi_slave (
|
||||
acc_idx_d4 <= acc_idx_d3;
|
||||
acc_idx_d3 <= acc_idx_d2;
|
||||
acc_idx_d2 <= acc_idx_d1;
|
||||
acc_idx_d1 <= pipe_cnt[3:0];
|
||||
acc_idx_d1 <= 4'd0;
|
||||
acc_bank_d4 <= acc_bank_d3;
|
||||
acc_bank_d3 <= acc_bank_d2;
|
||||
acc_bank_d2 <= acc_bank_d1;
|
||||
acc_bank_d1 <= cur_bank;
|
||||
acc_bank_d1 <= 1'b0;
|
||||
acc_valid_d4 <= acc_valid_d3;
|
||||
acc_valid_d3 <= acc_valid_d2;
|
||||
acc_valid_d2 <= acc_valid_d1;
|
||||
acc_valid_d1 <= 1'b0;
|
||||
|
||||
case (state)
|
||||
C_IDLE: begin
|
||||
pipe_cnt <= 5'd0;
|
||||
if (req_0) begin
|
||||
cur_bank <= 1'b0;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
start_calc_bank(1'b0);
|
||||
end else if (req_1) begin
|
||||
cur_bank <= 1'b1;
|
||||
busy <= 1'b1;
|
||||
state <= C_RUN;
|
||||
start_calc_bank(1'b1);
|
||||
end else begin
|
||||
pipe_cnt <= 5'd0;
|
||||
busy <= 1'b0;
|
||||
end
|
||||
end
|
||||
@@ -629,6 +662,9 @@ module matmul_axi_slave (
|
||||
C_RUN: begin
|
||||
// Issue 4 new operands every cycle (pipe_cnt 0-15, 16 rounds)
|
||||
if (pipe_cnt < 5'd16) begin
|
||||
acc_idx_d1 <= pipe_cnt[3:0];
|
||||
acc_bank_d1 <= cur_bank;
|
||||
acc_valid_d1 <= 1'b1;
|
||||
if (cur_bank == 1'b0) begin
|
||||
m_in_a[0] <= b0_a[{pipe_cnt[3:2], 2'd0}]; m_in_b[0] <= b0_b[{2'd0, pipe_cnt[1:0]}];
|
||||
m_in_a[1] <= b0_a[{pipe_cnt[3:2], 2'd1}]; m_in_b[1] <= b0_b[{2'd1, pipe_cnt[1:0]}];
|
||||
@@ -642,8 +678,8 @@ module matmul_axi_slave (
|
||||
end
|
||||
end
|
||||
|
||||
// Accumulate results from 4 cycles ago (pipe_cnt 4-19)
|
||||
if (pipe_cnt >= 5'd4 && pipe_cnt < 5'd20) begin
|
||||
// Accumulate results from 4 cycles ago.
|
||||
if (acc_valid_d4) begin
|
||||
if (acc_bank_d4 == 1'b0)
|
||||
b0_c[acc_idx_d4] <= ({2'b0, mult_p[0]} + {2'b0, mult_p[1]}) +
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
@@ -652,10 +688,19 @@ module matmul_axi_slave (
|
||||
({2'b0, mult_p[2]} + {2'b0, mult_p[3]});
|
||||
end
|
||||
|
||||
if (pipe_cnt == 5'd20) begin
|
||||
if (acc_valid_d4 && acc_idx_d4 == 4'd15) begin
|
||||
calc_done_pulse <= 1'b1;
|
||||
busy <= 1'b0;
|
||||
state <= C_IDLE;
|
||||
end
|
||||
|
||||
if (pipe_cnt < 5'd16) begin
|
||||
pipe_cnt <= pipe_cnt + 5'd1;
|
||||
end else if (cur_bank == 1'b0 && req_1) begin
|
||||
start_calc_bank(1'b1);
|
||||
end else if (cur_bank == 1'b1 && req_0) begin
|
||||
start_calc_bank(1'b0);
|
||||
end else if (acc_valid_d4 && acc_idx_d4 == 4'd15) begin
|
||||
busy <= 1'b0;
|
||||
state <= C_IDLE;
|
||||
end else begin
|
||||
pipe_cnt <= pipe_cnt + 5'd1;
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user