diff --git a/rtl/ip/matmul/matmul_axi_slave.v b/rtl/ip/matmul/matmul_axi_slave.v index c69a3a5..e3044ab 100644 --- a/rtl/ip/matmul/matmul_axi_slave.v +++ b/rtl/ip/matmul/matmul_axi_slave.v @@ -62,7 +62,11 @@ reg [65:0] c_data [0:15]; reg [31:0] awaddr_hold; reg [4:0] awid_hold; +reg [7:0] awlen_hold; +reg [7:0] wbeat_cnt; reg aw_hold_valid; +reg rburst_active; +reg [7:0] rburst_rem; reg [31:0] wdata_hold; reg [3:0] wstrb_hold; reg w_hold_valid; @@ -71,8 +75,6 @@ reg busy; reg done; reg error; reg [3:0] calc_index; -reg [65:0] partial; // pipeline register for 2-stage multiplier -reg pipe_valid; // partial has valid data wire write_fire; wire start_fire; @@ -201,6 +203,8 @@ always @(posedge clk) begin w_hold_valid <= 1'b0; s_axi_bid <= 5'b0; s_axi_bvalid <= 1'b0; + wbeat_cnt <= 8'd0; + rburst_active <= 1'b0; s_axi_rid <= 5'b0; s_axi_rdata <= 32'b0; s_axi_rvalid <= 1'b0; @@ -218,6 +222,7 @@ always @(posedge clk) begin if (s_axi_awvalid && s_axi_awready) begin awaddr_hold <= s_axi_awaddr; awid_hold <= s_axi_awid; + awlen_hold <= s_axi_awlen; aw_hold_valid <= 1'b1; end @@ -232,10 +237,15 @@ always @(posedge clk) begin end if (write_fire) begin - s_axi_bid <= awid_hold; - s_axi_bvalid <= 1'b1; - aw_hold_valid <= 1'b0; - w_hold_valid <= 1'b0; + wbeat_cnt <= wbeat_cnt + 8'd1; + w_hold_valid <= 1'b0; + + if (s_axi_wlast) begin + s_axi_bid <= awid_hold; + s_axi_bvalid <= 1'b1; + aw_hold_valid <= 1'b0; + wbeat_cnt <= 8'd0; + end if (write_offset == ADDR_SRC_BASE) begin src_base <= apply_wstrb(src_base, wdata_hold, wstrb_hold); @@ -253,14 +263,18 @@ always @(posedge clk) begin if (wdata_hold[1]) done <= 1'b0; if (wdata_hold[2]) error <= 1'b0; end else if ((write_offset != ADDR_CTRL) && (write_offset < ADDR_C_BASE)) begin - $display("[MATMUL_SLAVE] ERROR: write to unmapped offset=%03x wdata=%08x", write_offset, wdata_hold); error <= 1'b1; end + + awaddr_hold[31:0] <= awaddr_hold[31:0] + 32'd4; end if (s_axi_arvalid && s_axi_arready) begin - s_axi_rid <= s_axi_arid; - s_axi_rvalid <= 1'b1; + s_axi_rid <= s_axi_arid; + s_axi_rvalid <= 1'b1; + s_axi_rlast <= (s_axi_arlen == 8'd0); + rburst_rem <= s_axi_arlen; + rburst_active <= (s_axi_arlen > 8'd0); if (read_offset == ADDR_CTRL) begin s_axi_rdata <= 32'b0; @@ -282,7 +296,17 @@ always @(posedge clk) begin s_axi_rdata <= 32'b0; end end else if (s_axi_rvalid && s_axi_rready) begin - s_axi_rvalid <= 1'b0; + if (rburst_active && rburst_rem > 8'd0) begin + s_axi_rdata <= c_read_word((s_axi_araddr[11:0] - ADDR_C_BASE + 12'd4*(s_axi_arlen - rburst_rem + 8'd1)) >> 2); + rburst_rem <= rburst_rem - 8'd1; + s_axi_rlast <= (rburst_rem == 8'd1); + if (rburst_rem == 8'd1) begin + s_axi_rvalid <= 1'b0; + rburst_active <= 1'b0; + end + end else begin + s_axi_rvalid <= 1'b0; + end end if (start_fire) begin @@ -290,25 +314,14 @@ always @(posedge clk) begin done <= 1'b0; error <= 1'b0; calc_index <= 4'd0; - pipe_valid <= 1'b0; end else if (busy) begin - if (!pipe_valid) begin - // Stage 1: compute element, store in partial - partial <= calc_c_element(calc_index); - pipe_valid <= 1'b1; + c_data[calc_index] <= calc_c_element(calc_index); + if (calc_index == 4'd15) begin + busy <= 1'b0; + done <= 1'b1; + calc_index <= 4'd0; end else begin - // Stage 2: store partial into c_data, advance - c_data[calc_index] <= partial; - pipe_valid <= 1'b0; - if (calc_index == 4'd15) begin - busy <= 1'b0; - done <= 1'b1; - calc_index <= 4'd0; - partial <= 66'b0; - pipe_valid <= 1'b0; - end else begin - calc_index <= calc_index + 4'd1; - end + calc_index <= calc_index + 4'd1; end end end