// SPDX-License-Identifier: MIT // // SystemVerilog interface wrapper around alexforencich/verilog-axi axi_dma.v. // // AXI memory, AXI-Stream data, DMA descriptor, and DMA status channels are all // exposed through compact interfaces. The original Forencich core remains // untouched and is connected through local flat wires. `default_nettype none // DMA Specific wrappers & converters module axi_dma_wrapper #( parameter int unsigned AXI_DATA_WIDTH = 32, parameter int unsigned AXI_ADDR_WIDTH = 16, parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, parameter int unsigned AXI_ID_WIDTH = 8, parameter int unsigned AXI_USER_WIDTH = 1, parameter int unsigned AXI_MAX_BURST_LEN = 16, parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, parameter int unsigned AXIS_LAST_ENABLE = 1, parameter int unsigned AXIS_ID_ENABLE = 1, parameter int unsigned AXIS_ID_WIDTH = 8, parameter int unsigned AXIS_DEST_ENABLE = 0, parameter int unsigned AXIS_DEST_WIDTH = 8, parameter int unsigned AXIS_USER_ENABLE = 1, parameter int unsigned AXIS_USER_WIDTH = 1, parameter int unsigned LEN_WIDTH = 20, parameter int unsigned TAG_WIDTH = 8, parameter int unsigned ENABLE_SG = 0, parameter int unsigned ENABLE_UNALIGNED = 0 )( input logic clk, input logic rst, axis_if.slave s_axis_read_desc, axis_if.master m_axis_read_desc_status, axis_if.master m_axis_read_data, axis_if.slave s_axis_write_desc, axis_if.master m_axis_write_desc_status, axis_if.slave s_axis_write_data, axi4_if.master m_axi, /* * Configuration. */ input logic read_enable, input logic write_enable, input logic write_abort ); // -------------------------------------------------------------------------- // Flat wires connected to original alexforencich axi_dma.v // -------------------------------------------------------------------------- logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_read_desc_addr; logic [LEN_WIDTH-1:0] dma_s_axis_read_desc_len; logic [TAG_WIDTH-1:0] dma_s_axis_read_desc_tag; logic [AXIS_ID_WIDTH-1:0] dma_s_axis_read_desc_id; logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_read_desc_dest; logic [AXIS_USER_WIDTH-1:0] dma_s_axis_read_desc_user; logic dma_s_axis_read_desc_valid; logic dma_s_axis_read_desc_ready; logic [TAG_WIDTH-1:0] dma_m_axis_read_desc_status_tag; logic [3:0] dma_m_axis_read_desc_status_error; logic dma_m_axis_read_desc_status_valid; logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_write_desc_addr; logic [LEN_WIDTH-1:0] dma_s_axis_write_desc_len; logic [TAG_WIDTH-1:0] dma_s_axis_write_desc_tag; logic dma_s_axis_write_desc_valid; logic dma_s_axis_write_desc_ready; logic [LEN_WIDTH-1:0] dma_m_axis_write_desc_status_len; logic [TAG_WIDTH-1:0] dma_m_axis_write_desc_status_tag; logic [AXIS_ID_WIDTH-1:0] dma_m_axis_write_desc_status_id; logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_write_desc_status_dest; logic [AXIS_USER_WIDTH-1:0] dma_m_axis_write_desc_status_user; logic [3:0] dma_m_axis_write_desc_status_error; logic dma_m_axis_write_desc_status_valid; logic [AXIS_DATA_WIDTH-1:0] dma_m_axis_read_data_tdata; logic [AXIS_KEEP_WIDTH-1:0] dma_m_axis_read_data_tkeep; logic dma_m_axis_read_data_tvalid; logic dma_m_axis_read_data_tready; logic dma_m_axis_read_data_tlast; logic [AXIS_ID_WIDTH-1:0] dma_m_axis_read_data_tid; logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_read_data_tdest; logic [AXIS_USER_WIDTH-1:0] dma_m_axis_read_data_tuser; logic [AXIS_DATA_WIDTH-1:0] dma_s_axis_write_data_tdata; logic [AXIS_KEEP_WIDTH-1:0] dma_s_axis_write_data_tkeep; logic [AXIS_KEEP_WIDTH-1:0] unused_s_axis_write_data_tstrb; logic dma_s_axis_write_data_tvalid; logic dma_s_axis_write_data_tready; logic dma_s_axis_write_data_tlast; logic [AXIS_ID_WIDTH-1:0] dma_s_axis_write_data_tid; logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_write_data_tdest; logic [AXIS_USER_WIDTH-1:0] dma_s_axis_write_data_tuser; logic [AXI_ID_WIDTH-1:0] dma_m_axi_awid; logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_awaddr; logic [7:0] dma_m_axi_awlen; logic [2:0] dma_m_axi_awsize; logic [1:0] dma_m_axi_awburst; logic dma_m_axi_awlock; logic [3:0] dma_m_axi_awcache; logic [2:0] dma_m_axi_awprot; logic dma_m_axi_awvalid; logic dma_m_axi_awready; logic [AXI_DATA_WIDTH-1:0] dma_m_axi_wdata; logic [AXI_STRB_WIDTH-1:0] dma_m_axi_wstrb; logic dma_m_axi_wlast; logic dma_m_axi_wvalid; logic dma_m_axi_wready; logic [AXI_ID_WIDTH-1:0] dma_m_axi_bid; logic [1:0] dma_m_axi_bresp; logic dma_m_axi_bvalid; logic dma_m_axi_bready; logic [AXI_ID_WIDTH-1:0] dma_m_axi_arid; logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_araddr; logic [7:0] dma_m_axi_arlen; logic [2:0] dma_m_axi_arsize; logic [1:0] dma_m_axi_arburst; logic dma_m_axi_arlock; logic [3:0] dma_m_axi_arcache; logic [2:0] dma_m_axi_arprot; logic dma_m_axi_arvalid; logic dma_m_axi_arready; logic [AXI_ID_WIDTH-1:0] dma_m_axi_rid; logic [AXI_DATA_WIDTH-1:0] dma_m_axi_rdata; logic [1:0] dma_m_axi_rresp; logic dma_m_axi_rlast; logic dma_m_axi_rvalid; logic dma_m_axi_rready; logic [AXI_USER_WIDTH-1:0] unused_m_axi_buser; logic [AXI_USER_WIDTH-1:0] unused_m_axi_ruser; // Original DMA: flat ports only. axi_dma #( .AXI_DATA_WIDTH (AXI_DATA_WIDTH), .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), .AXI_STRB_WIDTH (AXI_STRB_WIDTH), .AXI_ID_WIDTH (AXI_ID_WIDTH), .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), .AXIS_ID_ENABLE (AXIS_ID_ENABLE), .AXIS_ID_WIDTH (AXIS_ID_WIDTH), .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), .AXIS_USER_ENABLE (AXIS_USER_ENABLE), .AXIS_USER_WIDTH (AXIS_USER_WIDTH), .LEN_WIDTH (LEN_WIDTH), .TAG_WIDTH (TAG_WIDTH), .ENABLE_SG (ENABLE_SG), .ENABLE_UNALIGNED (ENABLE_UNALIGNED) ) i_axi_dma ( .clk (clk), .rst (rst), .s_axis_read_desc_addr (dma_s_axis_read_desc_addr), .s_axis_read_desc_len (dma_s_axis_read_desc_len), .s_axis_read_desc_tag (dma_s_axis_read_desc_tag), .s_axis_read_desc_id (dma_s_axis_read_desc_id), .s_axis_read_desc_dest (dma_s_axis_read_desc_dest), .s_axis_read_desc_user (dma_s_axis_read_desc_user), .s_axis_read_desc_valid (dma_s_axis_read_desc_valid), .s_axis_read_desc_ready (dma_s_axis_read_desc_ready), .m_axis_read_desc_status_tag (dma_m_axis_read_desc_status_tag), .m_axis_read_desc_status_error (dma_m_axis_read_desc_status_error), .m_axis_read_desc_status_valid (dma_m_axis_read_desc_status_valid), .m_axis_read_data_tdata (dma_m_axis_read_data_tdata), .m_axis_read_data_tkeep (dma_m_axis_read_data_tkeep), .m_axis_read_data_tvalid (dma_m_axis_read_data_tvalid), .m_axis_read_data_tready (dma_m_axis_read_data_tready), .m_axis_read_data_tlast (dma_m_axis_read_data_tlast), .m_axis_read_data_tid (dma_m_axis_read_data_tid), .m_axis_read_data_tdest (dma_m_axis_read_data_tdest), .m_axis_read_data_tuser (dma_m_axis_read_data_tuser), .s_axis_write_desc_addr (dma_s_axis_write_desc_addr), .s_axis_write_desc_len (dma_s_axis_write_desc_len), .s_axis_write_desc_tag (dma_s_axis_write_desc_tag), .s_axis_write_desc_valid (dma_s_axis_write_desc_valid), .s_axis_write_desc_ready (dma_s_axis_write_desc_ready), .m_axis_write_desc_status_len (dma_m_axis_write_desc_status_len), .m_axis_write_desc_status_tag (dma_m_axis_write_desc_status_tag), .m_axis_write_desc_status_id (dma_m_axis_write_desc_status_id), .m_axis_write_desc_status_dest (dma_m_axis_write_desc_status_dest), .m_axis_write_desc_status_user (dma_m_axis_write_desc_status_user), .m_axis_write_desc_status_error (dma_m_axis_write_desc_status_error), .m_axis_write_desc_status_valid (dma_m_axis_write_desc_status_valid), .s_axis_write_data_tdata (dma_s_axis_write_data_tdata), .s_axis_write_data_tkeep (dma_s_axis_write_data_tkeep), .s_axis_write_data_tvalid (dma_s_axis_write_data_tvalid), .s_axis_write_data_tready (dma_s_axis_write_data_tready), .s_axis_write_data_tlast (dma_s_axis_write_data_tlast), .s_axis_write_data_tid (dma_s_axis_write_data_tid), .s_axis_write_data_tdest (dma_s_axis_write_data_tdest), .s_axis_write_data_tuser (dma_s_axis_write_data_tuser), .m_axi_awid (dma_m_axi_awid), .m_axi_awaddr (dma_m_axi_awaddr), .m_axi_awlen (dma_m_axi_awlen), .m_axi_awsize (dma_m_axi_awsize), .m_axi_awburst (dma_m_axi_awburst), .m_axi_awlock (dma_m_axi_awlock), .m_axi_awcache (dma_m_axi_awcache), .m_axi_awprot (dma_m_axi_awprot), .m_axi_awvalid (dma_m_axi_awvalid), .m_axi_awready (dma_m_axi_awready), .m_axi_wdata (dma_m_axi_wdata), .m_axi_wstrb (dma_m_axi_wstrb), .m_axi_wlast (dma_m_axi_wlast), .m_axi_wvalid (dma_m_axi_wvalid), .m_axi_wready (dma_m_axi_wready), .m_axi_bid (dma_m_axi_bid), .m_axi_bresp (dma_m_axi_bresp), .m_axi_bvalid (dma_m_axi_bvalid), .m_axi_bready (dma_m_axi_bready), .m_axi_arid (dma_m_axi_arid), .m_axi_araddr (dma_m_axi_araddr), .m_axi_arlen (dma_m_axi_arlen), .m_axi_arsize (dma_m_axi_arsize), .m_axi_arburst (dma_m_axi_arburst), .m_axi_arlock (dma_m_axi_arlock), .m_axi_arcache (dma_m_axi_arcache), .m_axi_arprot (dma_m_axi_arprot), .m_axi_arvalid (dma_m_axi_arvalid), .m_axi_arready (dma_m_axi_arready), .m_axi_rid (dma_m_axi_rid), .m_axi_rdata (dma_m_axi_rdata), .m_axi_rresp (dma_m_axi_rresp), .m_axi_rlast (dma_m_axi_rlast), .m_axi_rvalid (dma_m_axi_rvalid), .m_axi_rready (dma_m_axi_rready), .read_enable (read_enable), .write_enable (write_enable), .write_abort (write_abort) ); // local read descriptor interface -> DMA flat input axis_if_to_flat #( .DATA_W (AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) i_read_desc_cmd_i2f ( .s_axis (s_axis_read_desc), .m_axis_tdata ({dma_s_axis_read_desc_addr, dma_s_axis_read_desc_len, dma_s_axis_read_desc_tag}), .m_axis_tkeep (), .m_axis_tstrb (), .m_axis_tlast (), .m_axis_tid (dma_s_axis_read_desc_id), .m_axis_tdest (dma_s_axis_read_desc_dest), .m_axis_tuser (dma_s_axis_read_desc_user), .m_axis_tvalid (dma_s_axis_read_desc_valid), .m_axis_tready (dma_s_axis_read_desc_ready) ); // DMA read descriptor status flat output -> local status interface axis_flat_to_if #( .DATA_W (TAG_WIDTH + 4), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) i_read_desc_status_f2i( .s_axis_tdata ({dma_m_axis_read_desc_status_tag, dma_m_axis_read_desc_status_error}), .s_axis_tkeep (), .s_axis_tstrb (), .s_axis_tlast (), .s_axis_tid (), .s_axis_tdest (), .s_axis_tuser (), .s_axis_tvalid (dma_m_axis_read_desc_status_valid), .s_axis_tready (), .m_axis (m_axis_read_desc_status) ); // local write descriptor interface -> DMA flat input axis_if_to_flat #( .DATA_W (AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) i_write_desc_cmd_i2f ( .s_axis (s_axis_write_desc), .m_axis_tdata ({dma_s_axis_write_desc_addr, dma_s_axis_write_desc_len, dma_s_axis_write_desc_tag}), .m_axis_tkeep (), .m_axis_tstrb (), .m_axis_tlast (), .m_axis_tid (), .m_axis_tdest (), .m_axis_tuser (), .m_axis_tvalid (dma_s_axis_write_desc_valid), .m_axis_tready (dma_s_axis_write_desc_ready) ); // DMA write descriptor status flat output -> local status interface axis_flat_to_if #( .DATA_W (TAG_WIDTH + LEN_WIDTH + 4), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) i_write_desc_status_f2i( .s_axis_tdata ({dma_m_axis_write_desc_status_len, dma_m_axis_write_desc_status_tag, dma_m_axis_write_desc_status_error}), .s_axis_tkeep (), .s_axis_tstrb (), .s_axis_tlast (), .s_axis_tid (dma_m_axis_write_desc_status_id), .s_axis_tdest (dma_m_axis_write_desc_status_dest), .s_axis_tuser (dma_m_axis_write_desc_status_user), .s_axis_tvalid (dma_m_axis_write_desc_status_valid), .s_axis_tready (), .m_axis (m_axis_write_desc_status) ); // DMA read data flat output -> local axis_if.master axis_flat_to_if #( .DATA_W (AXIS_DATA_WIDTH), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) u_m_axis_read_data_flat_to_if ( .s_axis_tdata (dma_m_axis_read_data_tdata), .s_axis_tkeep (dma_m_axis_read_data_tkeep), .s_axis_tstrb (dma_m_axis_read_data_tkeep), // axi_dma has no tstrb; mirror tkeep .s_axis_tlast (dma_m_axis_read_data_tlast), .s_axis_tid (dma_m_axis_read_data_tid), .s_axis_tdest (dma_m_axis_read_data_tdest), .s_axis_tuser (dma_m_axis_read_data_tuser), .s_axis_tvalid (dma_m_axis_read_data_tvalid), .s_axis_tready (dma_m_axis_read_data_tready), .m_axis (m_axis_read_data) ); // local axis_if.slave -> DMA write data flat input axis_if_to_flat #( .DATA_W (AXIS_DATA_WIDTH), .KEEP_W (AXIS_KEEP_WIDTH), .ID_W (AXIS_ID_WIDTH), .DEST_W (AXIS_DEST_WIDTH), .USER_W (AXIS_USER_WIDTH) ) u_s_axis_write_data_if_to_flat ( .s_axis (s_axis_write_data), .m_axis_tdata (dma_s_axis_write_data_tdata), .m_axis_tkeep (dma_s_axis_write_data_tkeep), .m_axis_tstrb (unused_s_axis_write_data_tstrb), .m_axis_tlast (dma_s_axis_write_data_tlast), .m_axis_tid (dma_s_axis_write_data_tid), .m_axis_tdest (dma_s_axis_write_data_tdest), .m_axis_tuser (dma_s_axis_write_data_tuser), .m_axis_tvalid(dma_s_axis_write_data_tvalid), .m_axis_tready(dma_s_axis_write_data_tready) ); // DMA AXI master flat output -> local axi4_if.master axi4_flat_to_if #( .ADDR_W (AXI_ADDR_WIDTH), .DATA_W (AXI_DATA_WIDTH), .ID_W (AXI_ID_WIDTH), .USER_W (AXI_USER_WIDTH) ) u_m_axi_flat_to_if ( .s_axi_awid (dma_m_axi_awid), .s_axi_awaddr (dma_m_axi_awaddr), .s_axi_awlen (dma_m_axi_awlen), .s_axi_awsize (dma_m_axi_awsize), .s_axi_awburst (dma_m_axi_awburst), .s_axi_awlock (dma_m_axi_awlock), .s_axi_awcache (dma_m_axi_awcache), .s_axi_awprot (dma_m_axi_awprot), .s_axi_awqos (4'd0), .s_axi_awregion (4'd0), .s_axi_awuser ({AXI_USER_WIDTH{1'b0}}), .s_axi_awvalid (dma_m_axi_awvalid), .s_axi_awready (dma_m_axi_awready), .s_axi_wdata (dma_m_axi_wdata), .s_axi_wstrb (dma_m_axi_wstrb), .s_axi_wlast (dma_m_axi_wlast), .s_axi_wuser ({AXI_USER_WIDTH{1'b0}}), .s_axi_wvalid (dma_m_axi_wvalid), .s_axi_wready (dma_m_axi_wready), .s_axi_bid (dma_m_axi_bid), .s_axi_bresp (dma_m_axi_bresp), .s_axi_buser (unused_m_axi_buser), .s_axi_bvalid (dma_m_axi_bvalid), .s_axi_bready (dma_m_axi_bready), .s_axi_arid (dma_m_axi_arid), .s_axi_araddr (dma_m_axi_araddr), .s_axi_arlen (dma_m_axi_arlen), .s_axi_arsize (dma_m_axi_arsize), .s_axi_arburst (dma_m_axi_arburst), .s_axi_arlock (dma_m_axi_arlock), .s_axi_arcache (dma_m_axi_arcache), .s_axi_arprot (dma_m_axi_arprot), .s_axi_arqos (4'd0), .s_axi_arregion (4'd0), .s_axi_aruser ({AXI_USER_WIDTH{1'b0}}), .s_axi_arvalid (dma_m_axi_arvalid), .s_axi_arready (dma_m_axi_arready), .s_axi_rid (dma_m_axi_rid), .s_axi_rdata (dma_m_axi_rdata), .s_axi_rresp (dma_m_axi_rresp), .s_axi_rlast (dma_m_axi_rlast), .s_axi_ruser (unused_m_axi_ruser), .s_axi_rvalid (dma_m_axi_rvalid), .s_axi_rready (dma_m_axi_rready), .m_axi (m_axi) ); endmodule : axi_dma_wrapper `default_nettype wire