Pipeline matmul bank chaining
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user