diff --git a/rtl/ip/cdma/snix_axil_cdma_mux.sv b/rtl/ip/cdma/snix_axil_cdma_mux.sv index 8b4d767..6d6f35b 100644 --- a/rtl/ip/cdma/snix_axil_cdma_mux.sv +++ b/rtl/ip/cdma/snix_axil_cdma_mux.sv @@ -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_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_loaded_bank = + (seq_load_idx[0] == 1'b0) ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0; assign seq_awid = '0; assign seq_awsize = 3'd2; @@ -925,9 +927,10 @@ module snix_axil_cdma_mux #( SQ_LOAD1: begin if (op_done) begin - op_read_addr <= seq_mat_base + MAT_STATUS_OFF; - op_start_read <= 1'b1; - seq_state <= SQ_WAIT_DONE; + op_write_addr <= seq_mat_base + MAT_CTRL_OFF; + op_write_data <= seq_start_value_for_loaded_bank; + op_start_write <= 1'b1; + seq_state <= SQ_START_NEXT; end end @@ -957,7 +960,7 @@ module snix_axil_cdma_mux #( SQ_STORE: 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; end else if (seq_has_more_load) begin op_src_addr <= seq_src_addr_for_load; @@ -978,28 +981,28 @@ module snix_axil_cdma_mux #( if (op_done) begin seq_group_idx <= seq_group_idx + 32'd1; seq_compute_bank <= ~seq_compute_bank; - op_write_addr <= seq_mat_base + MAT_CTRL_OFF; - op_write_data <= (~seq_compute_bank) ? MAT_CTRL_START_B1 : MAT_CTRL_START_B0; - op_start_write <= 1'b1; - seq_state <= SQ_START_NEXT; + op_src_addr <= seq_src_addr_for_store; + op_dst_addr <= seq_dst_addr_for_store; + op_bytes <= MAT_C_BYTES; + op_start_copy <= 1'b1; + seq_state <= SQ_STORE; end end SQ_START_NEXT: begin if (op_done) begin - op_src_addr <= seq_src_addr_for_store; - op_dst_addr <= seq_dst_addr_for_store; - op_bytes <= MAT_C_BYTES; - op_start_copy <= 1'b1; - seq_state <= SQ_STORE; + op_read_addr <= seq_mat_base + MAT_STATUS_OFF; + op_start_read <= 1'b1; + seq_state <= SQ_WAIT_DONE; end end SQ_LOAD_NEXT: begin if (op_done) begin - op_read_addr <= seq_mat_base + MAT_STATUS_OFF; - op_start_read <= 1'b1; - seq_state <= SQ_WAIT_DONE; + op_write_addr <= seq_mat_base + MAT_CTRL_OFF; + op_write_data <= seq_start_value_for_loaded_bank; + op_start_write <= 1'b1; + seq_state <= SQ_START_NEXT; end end diff --git a/rtl/ip/matmul/matmul_axi_slave.v b/rtl/ip/matmul/matmul_axi_slave.v index 557c7f5..86df2c5 100644 --- a/rtl/ip/matmul/matmul_axi_slave.v +++ b/rtl/ip/matmul/matmul_axi_slave.v @@ -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