diff --git a/rtl/ip/cdma/cdma_matmul_bridge.sv b/rtl/ip/cdma/cdma_matmul_bridge.sv new file mode 100644 index 0000000..b5f03bf --- /dev/null +++ b/rtl/ip/cdma/cdma_matmul_bridge.sv @@ -0,0 +1,347 @@ +// ============================================================================ +// cdma_matmul_bridge.sv +// Matmul-specific sequencer between the generic CDMA endpoint requester and +// the matmul local endpoint/control interface. +// +// AXI-Lite register map, relative to this bridge window: +// 0x00 CTRL bit0 start +// 0x04 STATUS bit0 busy, bit1 done (W1C) +// 0x08 SRC_BASE physical ExtRAM input base +// 0x0C DST_BASE physical ExtRAM result base +// 0x10 GROUPS +// 0x14 MAT_BASE reserved for software compatibility +// 0x18 SRC_STRIDE bytes, default 128 +// 0x1C DST_STRIDE bytes, default 192 +// ============================================================================ +`timescale 1ns / 1ps + +module cdma_matmul_bridge #( + parameter int ADDR_WIDTH = 32, + parameter int AXIL_ADDR_WIDTH = 32, + parameter int AXIL_DATA_WIDTH = 32 +) ( + input logic clk, + input logic rst_n, + + input logic [AXIL_ADDR_WIDTH-1:0] s_axil_awaddr, + input logic s_axil_awvalid, + output logic s_axil_awready, + input logic [AXIL_DATA_WIDTH-1:0] s_axil_wdata, + input logic [AXIL_DATA_WIDTH/8-1:0] s_axil_wstrb, + input logic s_axil_wvalid, + output logic s_axil_wready, + output logic [1:0] s_axil_bresp, + output logic s_axil_bvalid, + input logic s_axil_bready, + input logic [AXIL_ADDR_WIDTH-1:0] s_axil_araddr, + input logic s_axil_arvalid, + output logic s_axil_arready, + output logic [AXIL_DATA_WIDTH-1:0] s_axil_rdata, + output logic [1:0] s_axil_rresp, + output logic s_axil_rvalid, + input logic s_axil_rready, + + output logic cdma_req_valid, + input logic cdma_req_ready, + output logic [1:0] cdma_req_mode, + output logic [ADDR_WIDTH-1:0] cdma_req_src, + output logic [ADDR_WIDTH-1:0] cdma_req_dst, + output logic [31:0] cdma_req_bytes, + output logic [3:0] cdma_req_ep_id, + output logic [3:0] cdma_req_ep_bank, + output logic [7:0] cdma_req_ep_word_off, + input logic cdma_req_done, + + output logic mat_start_valid, + output logic mat_start_bank, + output logic mat_done_clear, + output logic mat_crc_clear, + input logic mat_done, + + output logic seq_done_irq +); + + localparam logic [1:0] MODE_MEM2EP = 2'd1; + localparam logic [1:0] MODE_EP2MEM = 2'd2; + + localparam logic [7:0] REG_CTRL = 8'h00; + localparam logic [7:0] REG_STATUS = 8'h04; + localparam logic [7:0] REG_SRC_BASE = 8'h08; + localparam logic [7:0] REG_DST_BASE = 8'h0C; + localparam logic [7:0] REG_GROUPS = 8'h10; + localparam logic [7:0] REG_MAT_BASE = 8'h14; + localparam logic [7:0] REG_SRC_STRIDE = 8'h18; + localparam logic [7:0] REG_DST_STRIDE = 8'h1C; + + localparam logic [31:0] MAT_AB_BYTES = 32'd128; + localparam logic [31:0] MAT_C_BYTES = 32'd192; + + typedef enum logic [3:0] { + SQ_IDLE, + SQ_CLEAR, + SQ_LOAD_START, + SQ_LOAD_REQ, + SQ_LOAD_WAIT, + SQ_WAIT_DONE, + SQ_STORE_START, + SQ_STORE_REQ, + SQ_STORE_WAIT, + SQ_DONE + } seq_state_t; + + seq_state_t seq_state; + + logic [31:0] seq_src_base; + logic [31:0] seq_dst_base; + logic [31:0] seq_groups; + logic [31:0] seq_mat_base; + logic [31:0] seq_src_stride; + logic [31:0] seq_dst_stride; + logic seq_busy; + logic seq_done_flag; + logic [31:0] seq_load_idx; + logic [31:0] seq_store_idx; + logic seq_compute_bank; + + wire [7:0] wr_off = s_axil_awaddr[7:0]; + wire [7:0] rd_off = s_axil_araddr[7:0]; + wire start_req = do_write && (wr_off == REG_CTRL) && s_axil_wstrb[0] && s_axil_wdata[0]; + wire done_clear_req = do_write && (wr_off == REG_STATUS) && s_axil_wstrb[0] && s_axil_wdata[1]; + wire [31:0] src_addr_for_load = seq_src_base + (seq_load_idx * seq_src_stride); + wire [31:0] dst_addr_for_store = seq_dst_base + (seq_store_idx * seq_dst_stride); + wire loaded_bank = seq_load_idx[0]; + + function automatic logic [31:0] apply_wstrb( + input logic [31:0] old_val, + input logic [31:0] new_val, + input logic [3:0] wstrb + ); + begin + apply_wstrb[7:0] = wstrb[0] ? new_val[7:0] : old_val[7:0]; + apply_wstrb[15:8] = wstrb[1] ? new_val[15:8] : old_val[15:8]; + apply_wstrb[23:16] = wstrb[2] ? new_val[23:16] : old_val[23:16]; + apply_wstrb[31:24] = wstrb[3] ? new_val[31:24] : old_val[31:24]; + end + endfunction + + assign s_axil_bresp = 2'b00; + assign s_axil_rresp = 2'b00; + assign seq_done_irq = seq_done_flag; + + always_ff @(posedge clk) begin + if (!rst_n) begin + s_axil_awready <= 1'b0; + s_axil_wready <= 1'b0; + end else begin + if (s_axil_awvalid && s_axil_wvalid && !s_axil_awready && (!s_axil_bvalid || s_axil_bready)) begin + s_axil_awready <= 1'b1; + s_axil_wready <= 1'b1; + end else begin + s_axil_awready <= 1'b0; + s_axil_wready <= 1'b0; + end + end + end + + wire do_write = s_axil_awready && s_axil_awvalid && s_axil_wready && s_axil_wvalid; + + always_ff @(posedge clk) begin + if (!rst_n) begin + s_axil_bvalid <= 1'b0; + end else if (do_write) begin + s_axil_bvalid <= 1'b1; + end else if (s_axil_bready && s_axil_bvalid) begin + s_axil_bvalid <= 1'b0; + end + end + + always_ff @(posedge clk) begin + if (!rst_n) begin + s_axil_arready <= 1'b0; + end else begin + if (s_axil_arvalid && !s_axil_arready && (!s_axil_rvalid || s_axil_rready)) begin + s_axil_arready <= 1'b1; + end else begin + s_axil_arready <= 1'b0; + end + end + end + + wire do_read = s_axil_arready && s_axil_arvalid; + + always_ff @(posedge clk) begin + if (!rst_n) begin + s_axil_rvalid <= 1'b0; + s_axil_rdata <= '0; + end else if (do_read) begin + s_axil_rvalid <= 1'b1; + case (rd_off) + REG_CTRL: s_axil_rdata <= {31'd0, start_req}; + REG_STATUS: s_axil_rdata <= {30'd0, seq_done_flag, seq_busy}; + REG_SRC_BASE: s_axil_rdata <= seq_src_base; + REG_DST_BASE: s_axil_rdata <= seq_dst_base; + REG_GROUPS: s_axil_rdata <= seq_groups; + REG_MAT_BASE: s_axil_rdata <= seq_mat_base; + REG_SRC_STRIDE: s_axil_rdata <= seq_src_stride; + REG_DST_STRIDE: s_axil_rdata <= seq_dst_stride; + default: s_axil_rdata <= 32'd0; + endcase + end else if (s_axil_rready && s_axil_rvalid) begin + s_axil_rvalid <= 1'b0; + end + end + + always_ff @(posedge clk) begin + if (!rst_n) begin + seq_src_base <= 32'h0; + seq_dst_base <= 32'h0; + seq_groups <= 32'h0; + seq_mat_base <= 32'h1f50_0000; + seq_src_stride <= 32'd128; + seq_dst_stride <= 32'd192; + end else if (do_write) begin + case (wr_off) + REG_SRC_BASE: if (!seq_busy) seq_src_base <= apply_wstrb(seq_src_base, s_axil_wdata, s_axil_wstrb); + REG_DST_BASE: if (!seq_busy) seq_dst_base <= apply_wstrb(seq_dst_base, s_axil_wdata, s_axil_wstrb); + REG_GROUPS: if (!seq_busy) seq_groups <= apply_wstrb(seq_groups, s_axil_wdata, s_axil_wstrb); + REG_MAT_BASE: if (!seq_busy) seq_mat_base <= apply_wstrb(seq_mat_base, s_axil_wdata, s_axil_wstrb); + REG_SRC_STRIDE: if (!seq_busy) seq_src_stride <= apply_wstrb(seq_src_stride, s_axil_wdata, s_axil_wstrb); + REG_DST_STRIDE: if (!seq_busy) seq_dst_stride <= apply_wstrb(seq_dst_stride, s_axil_wdata, s_axil_wstrb); + default: begin + end + endcase + end + end + + always_ff @(posedge clk) begin + if (!rst_n) begin + seq_state <= SQ_IDLE; + seq_busy <= 1'b0; + seq_done_flag <= 1'b0; + seq_load_idx <= 32'd0; + seq_store_idx <= 32'd0; + seq_compute_bank <= 1'b0; + cdma_req_valid <= 1'b0; + cdma_req_mode <= MODE_MEM2EP; + cdma_req_src <= '0; + cdma_req_dst <= '0; + cdma_req_bytes <= '0; + cdma_req_ep_id <= 4'd0; + cdma_req_ep_bank <= 4'd0; + cdma_req_ep_word_off <= 8'd0; + mat_start_valid <= 1'b0; + mat_start_bank <= 1'b0; + mat_done_clear <= 1'b0; + mat_crc_clear <= 1'b0; + end else begin + mat_start_valid <= 1'b0; + mat_done_clear <= 1'b0; + mat_crc_clear <= 1'b0; + + if (done_clear_req) + seq_done_flag <= 1'b0; + + case (seq_state) + SQ_IDLE: begin + seq_busy <= 1'b0; + cdma_req_valid <= 1'b0; + if (start_req && (seq_groups != 32'd0)) begin + seq_busy <= 1'b1; + seq_done_flag <= 1'b0; + seq_load_idx <= 32'd0; + seq_store_idx <= 32'd0; + seq_compute_bank <= 1'b0; + mat_crc_clear <= 1'b1; + mat_done_clear <= 1'b1; + seq_state <= SQ_CLEAR; + end + end + + SQ_CLEAR: begin + seq_state <= SQ_LOAD_START; + end + + SQ_LOAD_START: begin + cdma_req_mode <= MODE_MEM2EP; + cdma_req_src <= src_addr_for_load; + cdma_req_dst <= '0; + cdma_req_bytes <= MAT_AB_BYTES; + cdma_req_ep_id <= 4'd0; + cdma_req_ep_bank <= {3'b000, loaded_bank}; + cdma_req_ep_word_off <= 8'd0; + cdma_req_valid <= 1'b1; + seq_state <= SQ_LOAD_REQ; + end + + SQ_LOAD_REQ: begin + if (cdma_req_valid && cdma_req_ready) begin + cdma_req_valid <= 1'b0; + seq_state <= SQ_LOAD_WAIT; + end + end + + SQ_LOAD_WAIT: begin + if (cdma_req_done) begin + mat_start_valid <= 1'b1; + mat_start_bank <= cdma_req_ep_bank[0]; + seq_load_idx <= seq_load_idx + 32'd1; + if ((seq_load_idx + 32'd1) < seq_groups && (seq_load_idx == 32'd0)) begin + seq_state <= SQ_LOAD_START; + end else begin + seq_state <= SQ_WAIT_DONE; + end + end + end + + SQ_WAIT_DONE: begin + if (mat_done) begin + mat_done_clear <= 1'b1; + seq_state <= SQ_STORE_START; + end + end + + SQ_STORE_START: begin + cdma_req_mode <= MODE_EP2MEM; + cdma_req_src <= '0; + cdma_req_dst <= dst_addr_for_store; + cdma_req_bytes <= MAT_C_BYTES; + cdma_req_ep_id <= 4'd0; + cdma_req_ep_bank <= {3'b000, seq_compute_bank}; + cdma_req_ep_word_off <= 8'd0; + cdma_req_valid <= 1'b1; + seq_state <= SQ_STORE_REQ; + end + + SQ_STORE_REQ: begin + if (cdma_req_valid && cdma_req_ready) begin + cdma_req_valid <= 1'b0; + seq_state <= SQ_STORE_WAIT; + end + end + + SQ_STORE_WAIT: begin + if (cdma_req_done) begin + seq_store_idx <= seq_store_idx + 32'd1; + seq_compute_bank <= ~seq_compute_bank; + if ((seq_store_idx + 32'd1) >= seq_groups) begin + seq_state <= SQ_DONE; + end else if (seq_load_idx < seq_groups) begin + seq_state <= SQ_LOAD_START; + end else begin + seq_state <= SQ_WAIT_DONE; + end + end + end + + SQ_DONE: begin + seq_busy <= 1'b0; + seq_done_flag <= 1'b1; + seq_state <= SQ_IDLE; + end + + default: seq_state <= SQ_IDLE; + endcase + end + end + +endmodule diff --git a/rtl/ip/cdma/snix_axil_cdma_mux.sv b/rtl/ip/cdma/snix_axil_cdma_mux.sv index 3a4f870..b1cfc96 100644 --- a/rtl/ip/cdma/snix_axil_cdma_mux.sv +++ b/rtl/ip/cdma/snix_axil_cdma_mux.sv @@ -112,13 +112,18 @@ module snix_axil_cdma_mux #( input logic ep_rd_ready, // ========================================== - // Matmul direct control sideband + // Generic external endpoint requester // ========================================== - output logic mat_start_valid, - output logic mat_start_bank, - output logic mat_done_clear, - output logic mat_crc_clear, - input logic mat_done, + input logic ext_req_valid, + output logic ext_req_ready, + input logic [1:0] ext_req_mode, + input logic [ADDR_WIDTH-1:0] ext_req_src, + input logic [ADDR_WIDTH-1:0] ext_req_dst, + input logic [31:0] ext_req_bytes, + input logic [3:0] ext_req_ep_id, + input logic [3:0] ext_req_ep_bank, + input logic [7:0] ext_req_ep_word_off, + output logic ext_req_done, // Global Interrupt (OR'd from all channels) output logic dma_finish @@ -132,26 +137,6 @@ module snix_axil_cdma_mux #( localparam logic [1:0] MODE_MEM2EP = 2'd1; localparam logic [1:0] MODE_EP2MEM = 2'd2; - localparam logic [7:0] SEQ_REG_CTRL = 8'h00; - localparam logic [7:0] SEQ_REG_STATUS = 8'h04; - localparam logic [7:0] SEQ_REG_SRC_BASE = 8'h08; - localparam logic [7:0] SEQ_REG_DST_BASE = 8'h0C; - localparam logic [7:0] SEQ_REG_GROUPS = 8'h10; - localparam logic [7:0] SEQ_REG_MAT_BASE = 8'h14; - localparam logic [7:0] SEQ_REG_SRC_STRIDE = 8'h18; - localparam logic [7:0] SEQ_REG_DST_STRIDE = 8'h1C; - - localparam logic [11:0] MAT_CTRL_OFF = 12'h000; - localparam logic [11:0] MAT_STATUS_OFF = 12'h004; - localparam logic [11:0] MAT_CRC_OFF = 12'h010; - localparam logic [11:0] MAT_B0_AB_OFF = 12'h100; - localparam logic [11:0] MAT_B0_C_OFF = 12'h180; - localparam logic [11:0] MAT_B1_AB_OFF = 12'h300; - localparam logic [11:0] MAT_B1_C_OFF = 12'h380; - - localparam logic [31:0] MAT_AB_BYTES = 32'd128; - localparam logic [31:0] MAT_C_BYTES = 32'd192; - // Function to safely apply WSTRB to 32-bit registers function automatic logic [31:0] apply_wstrb( input logic [31:0] old_val, @@ -182,17 +167,6 @@ module snix_axil_cdma_mux #( logic [PORTS-1:0] arb_set_done; // From Arbiter to CSR - logic [31:0] seq_src_base; - logic [31:0] seq_dst_base; - logic [31:0] seq_groups; - logic [31:0] seq_mat_base; - logic [31:0] seq_src_stride; - logic [31:0] seq_dst_stride; - logic seq_busy; - logic seq_done_flag; - wire seq_start_req; - wire seq_done_clear_req; - // ========================================== // Address Decoding (0x40 offset per channel) // ========================================== @@ -200,14 +174,6 @@ module snix_axil_cdma_mux #( wire [5:0] wr_reg = s_axil_awaddr[5:0]; wire [CH_BITS-1:0] rd_ch = s_axil_araddr[6 +: CH_BITS]; wire [5:0] rd_reg = s_axil_araddr[5:0]; - wire wr_seq_reg = (s_axil_awaddr[11:8] == 4'h2); - wire rd_seq_reg = (s_axil_araddr[11:8] == 4'h2); - wire [7:0] wr_seq_off = s_axil_awaddr[7:0]; - wire [7:0] rd_seq_off = s_axil_araddr[7:0]; - assign seq_start_req = do_write && wr_seq_reg && (wr_seq_off == SEQ_REG_CTRL) && - s_axil_wstrb[0] && s_axil_wdata[0]; - assign seq_done_clear_req = do_write && wr_seq_reg && (wr_seq_off == SEQ_REG_STATUS) && - s_axil_wstrb[0] && s_axil_wdata[1]; // ========================================== // AXI-Lite Slave Logic (Robust Backpressure) @@ -267,19 +233,7 @@ module snix_axil_cdma_mux #( end else begin if (do_read) begin s_axil_rvalid <= 1'b1; - if (rd_seq_reg) begin - case (rd_seq_off) - SEQ_REG_CTRL: s_axil_rdata <= {31'd0, seq_start_req}; - SEQ_REG_STATUS: s_axil_rdata <= {30'd0, seq_done_flag, seq_busy}; - SEQ_REG_SRC_BASE: s_axil_rdata <= seq_src_base; - SEQ_REG_DST_BASE: s_axil_rdata <= seq_dst_base; - SEQ_REG_GROUPS: s_axil_rdata <= seq_groups; - SEQ_REG_MAT_BASE: s_axil_rdata <= seq_mat_base; - SEQ_REG_SRC_STRIDE: s_axil_rdata <= seq_src_stride; - SEQ_REG_DST_STRIDE: s_axil_rdata <= seq_dst_stride; - default: s_axil_rdata <= 32'd0; - endcase - end else if (rd_ch < PORTS) begin + if (rd_ch < PORTS) begin case (rd_reg) 6'h00: s_axil_rdata <= ch_src_addr[rd_ch]; 6'h04: s_axil_rdata <= ch_dst_addr[rd_ch]; @@ -303,18 +257,12 @@ module snix_axil_cdma_mux #( // ========================================== // Register File Write Logic // ========================================== - assign dma_finish = (|ch_done) | seq_done_flag; + assign dma_finish = |ch_done; always_ff @(posedge clk) begin if (!rst_n) begin ch_req <= '0; ch_done <= '0; - seq_src_base <= 32'h0; - seq_dst_base <= 32'h0; - seq_groups <= 32'h0; - seq_mat_base <= 32'h1f50_0000; - seq_src_stride <= 32'd128; - seq_dst_stride <= 32'd192; for (int i=0; i= seq_groups) begin - seq_state <= SQ_DONE; - end else if (seq_load_idx < seq_groups) begin - seq_state <= SQ_LOAD; - end else begin - seq_state <= SQ_WAIT_DONE; - end - end - end - - SQ_DONE: begin - seq_busy <= 1'b0; - seq_done_flag <= 1'b1; - seq_state <= SQ_IDLE; - end - - default: seq_state <= SQ_IDLE; - endcase + if (ext_req_valid && ext_req_ready) begin + ext_active <= 1'b1; + ext_start_pulse <= 1'b1; + ext_mode_r <= ext_req_mode; + ext_src_r <= ext_req_src; + ext_dst_r <= ext_req_dst; + ext_bytes_r <= ext_req_bytes; + ext_ep_id_r <= ext_req_ep_id; + ext_ep_bank_r <= ext_req_ep_bank; + ext_ep_word_off_r <= ext_req_ep_word_off; + end else if (ext_active && ep_done) begin + ext_active <= 1'b0; + ext_req_done <= 1'b1; + end end end diff --git a/rtl/soc_top.v b/rtl/soc_top.v index bc40ed6..48688a1 100644 --- a/rtl/soc_top.v +++ b/rtl/soc_top.v @@ -393,12 +393,15 @@ wire dma_s_wlast ; wire dma_s_wvalid ; wire dma_s_wready ; wire [4 :0] dma_s_bid ; -wire [1 :0] dma_s_bresp ; -wire dma_s_bvalid ; -wire dma_s_bready ; -wire dma_finish ; - -// reserved +wire [1 :0] dma_s_bresp ; +wire dma_s_bvalid ; +wire dma_s_bready ; +wire dma_finish ; +wire cdma_dma_finish; +wire cdma_matmul_seq_irq; +assign dma_finish = cdma_dma_finish | cdma_matmul_seq_irq; + +// reserved wire [4 :0] axiOut_1_arid ; wire [31:0] axiOut_1_araddr ; wire [7 :0] axiOut_1_arlen ; @@ -1576,11 +1579,115 @@ wire [2:0] cdma_s_arprot; wire cdma_s_arvalid; wire cdma_s_arready; wire [31:0] cdma_s_rdata; -wire [1:0] cdma_s_rresp; -wire cdma_s_rvalid; -wire cdma_s_rready; - -axi_axil_adapter #( +wire [1:0] cdma_s_rresp; +wire cdma_s_rvalid; +wire cdma_s_rready; + +wire [31:0] cdma_mux_awaddr; +wire cdma_mux_awvalid; +wire cdma_mux_awready; +wire [31:0] cdma_mux_wdata; +wire [3:0] cdma_mux_wstrb; +wire cdma_mux_wvalid; +wire cdma_mux_wready; +wire [1:0] cdma_mux_bresp; +wire cdma_mux_bvalid; +wire cdma_mux_bready; +wire [31:0] cdma_mux_araddr; +wire cdma_mux_arvalid; +wire cdma_mux_arready; +wire [31:0] cdma_mux_rdata; +wire [1:0] cdma_mux_rresp; +wire cdma_mux_rvalid; +wire cdma_mux_rready; + +wire [31:0] cdma_bridge_awaddr; +wire cdma_bridge_awvalid; +wire cdma_bridge_awready; +wire [31:0] cdma_bridge_wdata; +wire [3:0] cdma_bridge_wstrb; +wire cdma_bridge_wvalid; +wire cdma_bridge_wready; +wire [1:0] cdma_bridge_bresp; +wire cdma_bridge_bvalid; +wire cdma_bridge_bready; +wire [31:0] cdma_bridge_araddr; +wire cdma_bridge_arvalid; +wire cdma_bridge_arready; +wire [31:0] cdma_bridge_rdata; +wire [1:0] cdma_bridge_rresp; +wire cdma_bridge_rvalid; +wire cdma_bridge_rready; + +wire bridge_cdma_req_valid; +wire bridge_cdma_req_ready; +wire [1:0] bridge_cdma_req_mode; +wire [31:0] bridge_cdma_req_src; +wire [31:0] bridge_cdma_req_dst; +wire [31:0] bridge_cdma_req_bytes; +wire [3:0] bridge_cdma_req_ep_id; +wire [3:0] bridge_cdma_req_ep_bank; +wire [7:0] bridge_cdma_req_ep_word_off; +wire bridge_cdma_req_done; + +wire cdma_axil_wr_bridge = (cdma_s_awaddr[11:8] == 4'h2); +wire cdma_axil_rd_bridge = (cdma_s_araddr[11:8] == 4'h2); +reg cdma_axil_wr_active; +reg cdma_axil_wr_bridge_hold; +reg cdma_axil_b_bridge; +reg cdma_axil_r_bridge; +wire cdma_axil_wr_sel = cdma_axil_wr_active ? cdma_axil_wr_bridge_hold : cdma_axil_wr_bridge; + +assign cdma_mux_awaddr = cdma_s_awaddr; +assign cdma_mux_awvalid = cdma_s_awvalid && !cdma_axil_wr_sel; +assign cdma_mux_wdata = cdma_s_wdata; +assign cdma_mux_wstrb = cdma_s_wstrb; +assign cdma_mux_wvalid = cdma_s_wvalid && !cdma_axil_wr_sel; +assign cdma_mux_bready = cdma_s_bready && !cdma_axil_b_bridge; +assign cdma_mux_araddr = cdma_s_araddr; +assign cdma_mux_arvalid = cdma_s_arvalid && !cdma_axil_rd_bridge; +assign cdma_mux_rready = cdma_s_rready && !cdma_axil_r_bridge; + +assign cdma_bridge_awaddr = cdma_s_awaddr; +assign cdma_bridge_awvalid = cdma_s_awvalid && cdma_axil_wr_sel; +assign cdma_bridge_wdata = cdma_s_wdata; +assign cdma_bridge_wstrb = cdma_s_wstrb; +assign cdma_bridge_wvalid = cdma_s_wvalid && cdma_axil_wr_sel; +assign cdma_bridge_bready = cdma_s_bready && cdma_axil_b_bridge; +assign cdma_bridge_araddr = cdma_s_araddr; +assign cdma_bridge_arvalid = cdma_s_arvalid && cdma_axil_rd_bridge; +assign cdma_bridge_rready = cdma_s_rready && cdma_axil_r_bridge; + +assign cdma_s_awready = cdma_axil_wr_sel ? cdma_bridge_awready : cdma_mux_awready; +assign cdma_s_wready = cdma_axil_wr_sel ? cdma_bridge_wready : cdma_mux_wready; +assign cdma_s_bresp = cdma_axil_b_bridge ? cdma_bridge_bresp : cdma_mux_bresp; +assign cdma_s_bvalid = cdma_axil_b_bridge ? cdma_bridge_bvalid : cdma_mux_bvalid; +assign cdma_s_arready = cdma_axil_rd_bridge ? cdma_bridge_arready : cdma_mux_arready; +assign cdma_s_rdata = cdma_axil_r_bridge ? cdma_bridge_rdata : cdma_mux_rdata; +assign cdma_s_rresp = cdma_axil_r_bridge ? cdma_bridge_rresp : cdma_mux_rresp; +assign cdma_s_rvalid = cdma_axil_r_bridge ? cdma_bridge_rvalid : cdma_mux_rvalid; + +always @(posedge sys_clk) begin + if (!sys_resetn) begin + cdma_axil_wr_active <= 1'b0; + cdma_axil_wr_bridge_hold <= 1'b0; + cdma_axil_b_bridge <= 1'b0; + cdma_axil_r_bridge <= 1'b0; + end else begin + if (cdma_s_awvalid && !cdma_axil_wr_active) begin + cdma_axil_wr_active <= 1'b1; + cdma_axil_wr_bridge_hold <= cdma_axil_wr_bridge; + end + if (cdma_s_awvalid && cdma_s_awready && cdma_s_wvalid && cdma_s_wready) begin + cdma_axil_b_bridge <= cdma_axil_wr_sel; + cdma_axil_wr_active <= 1'b0; + end + if (cdma_s_arvalid && cdma_s_arready) + cdma_axil_r_bridge <= cdma_axil_rd_bridge; + end +end + +axi_axil_adapter #( .ADDR_WIDTH(32), .AXI_DATA_WIDTH(32), .AXI_ID_WIDTH(5), @@ -1645,11 +1752,56 @@ u_axi_axil_adapter( .m_axil_rdata(cdma_s_rdata), .m_axil_rresp(cdma_s_rresp), .m_axil_rvalid(cdma_s_rvalid), - .m_axil_rready(cdma_s_rready) -); - -// 8 通道 DMA -snix_axil_cdma_mux #( + .m_axil_rready(cdma_s_rready) +); + +cdma_matmul_bridge #( + .ADDR_WIDTH (32), + .AXIL_ADDR_WIDTH (32), + .AXIL_DATA_WIDTH (32) +) u_cdma_matmul_bridge ( + .clk (sys_clk), + .rst_n (sys_resetn), + + .s_axil_awaddr (cdma_bridge_awaddr), + .s_axil_awvalid (cdma_bridge_awvalid), + .s_axil_awready (cdma_bridge_awready), + .s_axil_wdata (cdma_bridge_wdata), + .s_axil_wstrb (cdma_bridge_wstrb), + .s_axil_wvalid (cdma_bridge_wvalid), + .s_axil_wready (cdma_bridge_wready), + .s_axil_bresp (cdma_bridge_bresp), + .s_axil_bvalid (cdma_bridge_bvalid), + .s_axil_bready (cdma_bridge_bready), + .s_axil_araddr (cdma_bridge_araddr), + .s_axil_arvalid (cdma_bridge_arvalid), + .s_axil_arready (cdma_bridge_arready), + .s_axil_rdata (cdma_bridge_rdata), + .s_axil_rresp (cdma_bridge_rresp), + .s_axil_rvalid (cdma_bridge_rvalid), + .s_axil_rready (cdma_bridge_rready), + + .cdma_req_valid (bridge_cdma_req_valid), + .cdma_req_ready (bridge_cdma_req_ready), + .cdma_req_mode (bridge_cdma_req_mode), + .cdma_req_src (bridge_cdma_req_src), + .cdma_req_dst (bridge_cdma_req_dst), + .cdma_req_bytes (bridge_cdma_req_bytes), + .cdma_req_ep_id (bridge_cdma_req_ep_id), + .cdma_req_ep_bank (bridge_cdma_req_ep_bank), + .cdma_req_ep_word_off(bridge_cdma_req_ep_word_off), + .cdma_req_done (bridge_cdma_req_done), + + .mat_start_valid (matmul_direct_start_valid), + .mat_start_bank (matmul_direct_start_bank), + .mat_done_clear (matmul_direct_done_clear), + .mat_crc_clear (matmul_direct_crc_clear), + .mat_done (matmul_direct_done), + .seq_done_irq (cdma_matmul_seq_irq) +); + +// 8 通道 DMA +snix_axil_cdma_mux #( .ADDR_WIDTH (32), .DATA_WIDTH (32), // 适配你的 32-bit 总线 .AXIL_ADDR_WIDTH (32), @@ -1663,23 +1815,23 @@ snix_axil_cdma_mux #( .rst_n (sys_resetn), // 低电平复位 // AXI-Lite 从机接口 (接 CPU 发来的配置请求) - .s_axil_awaddr (cdma_s_awaddr), - .s_axil_awvalid (cdma_s_awvalid), - .s_axil_awready (cdma_s_awready), - .s_axil_wdata (cdma_s_wdata), - .s_axil_wstrb (cdma_s_wstrb), - .s_axil_wvalid (cdma_s_wvalid), - .s_axil_wready (cdma_s_wready), - .s_axil_bresp (cdma_s_bresp), - .s_axil_bvalid (cdma_s_bvalid), - .s_axil_bready (cdma_s_bready), - .s_axil_araddr (cdma_s_araddr), - .s_axil_arvalid (cdma_s_arvalid), - .s_axil_arready (cdma_s_arready), - .s_axil_rdata (cdma_s_rdata), - .s_axil_rresp (cdma_s_rresp), - .s_axil_rvalid (cdma_s_rvalid), - .s_axil_rready (cdma_s_rready), + .s_axil_awaddr (cdma_mux_awaddr), + .s_axil_awvalid (cdma_mux_awvalid), + .s_axil_awready (cdma_mux_awready), + .s_axil_wdata (cdma_mux_wdata), + .s_axil_wstrb (cdma_mux_wstrb), + .s_axil_wvalid (cdma_mux_wvalid), + .s_axil_wready (cdma_mux_wready), + .s_axil_bresp (cdma_mux_bresp), + .s_axil_bvalid (cdma_mux_bvalid), + .s_axil_bready (cdma_mux_bready), + .s_axil_araddr (cdma_mux_araddr), + .s_axil_arvalid (cdma_mux_arvalid), + .s_axil_arready (cdma_mux_arready), + .s_axil_rdata (cdma_mux_rdata), + .s_axil_rresp (cdma_mux_rresp), + .s_axil_rvalid (cdma_mux_rvalid), + .s_axil_rready (cdma_mux_rready), // AXI4 主机接口 (接 Crossbar 去搬运数据) .mm2mm_awid (dma_m_awid), @@ -1739,14 +1891,19 @@ snix_axil_cdma_mux #( .ep_rd_data (matmul_ep_rd_data), .ep_rd_ready (matmul_ep_rd_ready), - .mat_start_valid (matmul_direct_start_valid), - .mat_start_bank (matmul_direct_start_bank), - .mat_done_clear (matmul_direct_done_clear), - .mat_crc_clear (matmul_direct_crc_clear), - .mat_done (matmul_direct_done), + .ext_req_valid (bridge_cdma_req_valid), + .ext_req_ready (bridge_cdma_req_ready), + .ext_req_mode (bridge_cdma_req_mode), + .ext_req_src (bridge_cdma_req_src), + .ext_req_dst (bridge_cdma_req_dst), + .ext_req_bytes (bridge_cdma_req_bytes), + .ext_req_ep_id (bridge_cdma_req_ep_id), + .ext_req_ep_bank (bridge_cdma_req_ep_bank), + .ext_req_ep_word_off(bridge_cdma_req_ep_word_off), + .ext_req_done (bridge_cdma_req_done), // 全局中断输出 - .dma_finish (dma_finish) + .dma_finish (cdma_dma_finish) ); endmodule