Pipeline matmul bank chaining

This commit is contained in:
2026-07-01 22:41:31 +08:00
parent ceff12eaf1
commit 2b6e29f761
2 changed files with 85 additions and 37 deletions

View File

@@ -708,6 +708,8 @@ module snix_axil_cdma_mux #(
wire [31:0] seq_src_addr_for_store = seq_mat_base + (seq_store_idx[0] ? MAT_B1_C_OFF : MAT_B0_C_OFF); wire [31:0] seq_src_addr_for_store = seq_mat_base + (seq_store_idx[0] ? MAT_B1_C_OFF : MAT_B0_C_OFF);
wire [31:0] seq_dst_addr_for_store = seq_dst_base + (seq_store_idx * seq_dst_stride); wire [31:0] seq_dst_addr_for_store = seq_dst_base + (seq_store_idx * seq_dst_stride);
wire [31:0] seq_start_value_for_bank = seq_compute_bank ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0; wire [31:0] seq_start_value_for_bank = seq_compute_bank ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0;
wire [31:0] seq_start_value_for_loaded_bank =
(seq_load_idx[0] == 1'b0) ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0;
assign seq_awid = '0; assign seq_awid = '0;
assign seq_awsize = 3'd2; assign seq_awsize = 3'd2;
@@ -925,9 +927,10 @@ module snix_axil_cdma_mux #(
SQ_LOAD1: begin SQ_LOAD1: begin
if (op_done) begin if (op_done) begin
op_read_addr <= seq_mat_base + MAT_STATUS_OFF; op_write_addr <= seq_mat_base + MAT_CTRL_OFF;
op_start_read <= 1'b1; op_write_data <= seq_start_value_for_loaded_bank;
seq_state <= SQ_WAIT_DONE; op_start_write <= 1'b1;
seq_state <= SQ_START_NEXT;
end end
end end
@@ -957,7 +960,7 @@ module snix_axil_cdma_mux #(
SQ_STORE: begin SQ_STORE: begin
if (op_done) begin if (op_done) begin
if ((seq_group_idx + 32'd1) >= seq_groups) begin if ((seq_store_idx + 32'd1) >= seq_groups) begin
seq_state <= SQ_DONE; seq_state <= SQ_DONE;
end else if (seq_has_more_load) begin end else if (seq_has_more_load) begin
op_src_addr <= seq_src_addr_for_load; op_src_addr <= seq_src_addr_for_load;
@@ -978,28 +981,28 @@ module snix_axil_cdma_mux #(
if (op_done) begin if (op_done) begin
seq_group_idx <= seq_group_idx + 32'd1; seq_group_idx <= seq_group_idx + 32'd1;
seq_compute_bank <= ~seq_compute_bank; seq_compute_bank <= ~seq_compute_bank;
op_write_addr <= seq_mat_base + MAT_CTRL_OFF; op_src_addr <= seq_src_addr_for_store;
op_write_data <= (~seq_compute_bank) ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0; op_dst_addr <= seq_dst_addr_for_store;
op_start_write <= 1'b1; op_bytes <= MAT_C_BYTES;
seq_state <= SQ_START_NEXT; op_start_copy <= 1'b1;
seq_state <= SQ_STORE;
end end
end end
SQ_START_NEXT: begin SQ_START_NEXT: begin
if (op_done) begin if (op_done) begin
op_src_addr <= seq_src_addr_for_store; op_read_addr <= seq_mat_base + MAT_STATUS_OFF;
op_dst_addr <= seq_dst_addr_for_store; op_start_read <= 1'b1;
op_bytes <= MAT_C_BYTES; seq_state <= SQ_WAIT_DONE;
op_start_copy <= 1'b1;
seq_state <= SQ_STORE;
end end
end end
SQ_LOAD_NEXT: begin SQ_LOAD_NEXT: begin
if (op_done) begin if (op_done) begin
op_read_addr <= seq_mat_base + MAT_STATUS_OFF; op_write_addr <= seq_mat_base + MAT_CTRL_OFF;
op_start_read <= 1'b1; op_write_data <= seq_start_value_for_loaded_bank;
seq_state <= SQ_WAIT_DONE; op_start_write <= 1'b1;
seq_state <= SQ_START_NEXT;
end end
end end

View File

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