pluto_hdl_adi/library/axi_dmac/axi_dmac_transfer.v

408 lines
12 KiB
Verilog

// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
// developed independently, and may be accompanied by separate and unique license
// terms.
//
// The user should read each of these license terms, and understand the
// freedoms and responsabilities that he or she has by using this source/core.
//
// This core is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE.
//
// Redistribution and use of source or resulting binaries, with or without modification
// of this file, are permitted under one of the following two license terms:
//
// 1. The GNU General Public License version 2 as published by the
// Free Software Foundation, which can be found in the top level directory
// of this repository (LICENSE_GPL2), and also online at:
// <https://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
//
// OR
//
// 2. An ADI specific BSD license, which can be found in the top level directory
// of this repository (LICENSE_ADIBSD), and also on-line at:
// https://github.com/analogdevicesinc/hdl/blob/master/LICENSE_ADIBSD
// This will allow to generate bit files and not release the source code,
// as long as it attaches to an ADI device.
//
// ***************************************************************************
// ***************************************************************************
module axi_dmac_transfer #(
parameter DMA_DATA_WIDTH_SRC = 64,
parameter DMA_DATA_WIDTH_DEST = 64,
parameter DMA_LENGTH_WIDTH = 24,
parameter BYTES_PER_BEAT_WIDTH_DEST = $clog2(DMA_DATA_WIDTH_DEST/8),
parameter BYTES_PER_BEAT_WIDTH_SRC = $clog2(DMA_DATA_WIDTH_SRC/8),
parameter DMA_TYPE_DEST = 0,
parameter DMA_TYPE_SRC = 2,
parameter DMA_AXI_ADDR_WIDTH = 32,
parameter DMA_2D_TRANSFER = 1,
parameter ASYNC_CLK_REQ_SRC = 1,
parameter ASYNC_CLK_SRC_DEST = 1,
parameter ASYNC_CLK_DEST_REQ = 1,
parameter AXI_SLICE_DEST = 0,
parameter AXI_SLICE_SRC = 0,
parameter MAX_BYTES_PER_BURST = 128,
parameter FIFO_SIZE = 8,
parameter ID_WIDTH = $clog2(FIFO_SIZE*2),
parameter AXI_LENGTH_WIDTH_SRC = 8,
parameter AXI_LENGTH_WIDTH_DEST = 8
) (
input ctrl_clk,
input ctrl_resetn,
input ctrl_enable,
input ctrl_pause,
input req_valid,
output req_ready,
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address,
input [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] req_src_address,
input [DMA_LENGTH_WIDTH-1:0] req_x_length,
input [DMA_LENGTH_WIDTH-1:0] req_y_length,
input [DMA_LENGTH_WIDTH-1:0] req_dest_stride,
input [DMA_LENGTH_WIDTH-1:0] req_src_stride,
input req_sync_transfer_start,
input req_last,
output req_eot,
// Master AXI interface
input m_dest_axi_aclk,
input m_dest_axi_aresetn,
input m_src_axi_aclk,
input m_src_axi_aresetn,
// Write address
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_awaddr,
output [AXI_LENGTH_WIDTH_DEST-1:0] m_axi_awlen,
output [2:0] m_axi_awsize,
output [1:0] m_axi_awburst,
output [2:0] m_axi_awprot,
output [3:0] m_axi_awcache,
output m_axi_awvalid,
input m_axi_awready,
// Write data
output [DMA_DATA_WIDTH_DEST-1:0] m_axi_wdata,
output [(DMA_DATA_WIDTH_DEST/8)-1:0] m_axi_wstrb,
input m_axi_wready,
output m_axi_wvalid,
output m_axi_wlast,
// Write response
input m_axi_bvalid,
input [1:0] m_axi_bresp,
output m_axi_bready,
// Read address
input m_axi_arready,
output m_axi_arvalid,
output [DMA_AXI_ADDR_WIDTH-1:0] m_axi_araddr,
output [AXI_LENGTH_WIDTH_SRC-1:0] m_axi_arlen,
output [2:0] m_axi_arsize,
output [1:0] m_axi_arburst,
output [2:0] m_axi_arprot,
output [3:0] m_axi_arcache,
// Read data and response
input [DMA_DATA_WIDTH_SRC-1:0] m_axi_rdata,
output m_axi_rready,
input m_axi_rvalid,
input [1:0] m_axi_rresp,
// Slave streaming AXI interface
input s_axis_aclk,
output s_axis_ready,
input s_axis_valid,
input [DMA_DATA_WIDTH_SRC-1:0] s_axis_data,
input [0:0] s_axis_user,
input s_axis_last,
output s_axis_xfer_req,
// Master streaming AXI interface
input m_axis_aclk,
input m_axis_ready,
output m_axis_valid,
output [DMA_DATA_WIDTH_DEST-1:0] m_axis_data,
output m_axis_last,
output m_axis_xfer_req,
// Input FIFO interface
input fifo_wr_clk,
input fifo_wr_en,
input [DMA_DATA_WIDTH_SRC-1:0] fifo_wr_din,
output fifo_wr_overflow,
input fifo_wr_sync,
output fifo_wr_xfer_req,
// Input FIFO interface
input fifo_rd_clk,
input fifo_rd_en,
output fifo_rd_valid,
output [DMA_DATA_WIDTH_DEST-1:0] fifo_rd_dout,
output fifo_rd_underflow,
output fifo_rd_xfer_req,
output [ID_WIDTH-1:0] dbg_dest_request_id,
output [ID_WIDTH-1:0] dbg_dest_address_id,
output [ID_WIDTH-1:0] dbg_dest_data_id,
output [ID_WIDTH-1:0] dbg_dest_response_id,
output [ID_WIDTH-1:0] dbg_src_request_id,
output [ID_WIDTH-1:0] dbg_src_address_id,
output [ID_WIDTH-1:0] dbg_src_data_id,
output [ID_WIDTH-1:0] dbg_src_response_id,
output [11:0] dbg_status
);
wire dma_req_valid;
wire dma_req_ready;
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST] dma_req_dest_address;
wire [DMA_AXI_ADDR_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC] dma_req_src_address;
wire [DMA_LENGTH_WIDTH-1:0] dma_req_length;
wire dma_req_eot;
wire dma_req_sync_transfer_start;
wire dma_req_last;
wire req_clk = ctrl_clk;
wire req_resetn;
wire req_enable;
wire dest_clk;
wire dest_ext_resetn;
wire dest_resetn;
wire dest_enable;
wire dest_enabled;
wire src_clk;
wire src_ext_resetn;
wire src_resetn;
wire src_enable;
wire src_enabled;
wire req_valid_gated;
wire req_ready_gated;
axi_dmac_reset_manager #(
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
.ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ)
) i_reset_manager (
.clk (ctrl_clk),
.resetn (ctrl_resetn),
.ctrl_enable (ctrl_enable),
.ctrl_pause (ctrl_pause),
.req_resetn (req_resetn),
.req_enable (req_enable),
.req_enabled (req_enable),
.dest_clk (dest_clk),
.dest_ext_resetn (dest_ext_resetn),
.dest_resetn (dest_resetn),
.dest_enable (dest_enable),
.dest_enabled (dest_enabled),
.src_clk (src_clk),
.src_ext_resetn (src_ext_resetn),
.src_resetn (src_resetn),
.src_enable (src_enable),
.src_enabled (src_enabled),
.dbg_status (dbg_status)
);
/*
* Things become a lot easier if we gate incoming requests in a central place
* before they are propagated downstream. Otherwise we'd need to take special
* care to not accidentally accept requests while the DMA is going through a
* shutdown and reset phase.
*/
assign req_valid_gated = req_enable & req_valid;
assign req_ready = req_enable & req_ready_gated;
generate if (DMA_2D_TRANSFER == 1) begin
dmac_2d_transfer #(
.DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH),
.BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST),
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC)
) i_2d_transfer (
.req_aclk (req_clk),
.req_aresetn (req_resetn),
.req_eot (req_eot),
.req_valid (req_valid_gated),
.req_ready (req_ready_gated),
.req_dest_address (req_dest_address),
.req_src_address (req_src_address),
.req_x_length (req_x_length),
.req_y_length (req_y_length),
.req_dest_stride (req_dest_stride),
.req_src_stride (req_src_stride),
.req_sync_transfer_start (req_sync_transfer_start),
.out_req_valid (dma_req_valid),
.out_req_ready (dma_req_ready),
.out_req_dest_address (dma_req_dest_address),
.out_req_src_address (dma_req_src_address),
.out_req_length (dma_req_length),
.out_req_sync_transfer_start (dma_req_sync_transfer_start),
.out_eot (dma_req_eot)
);
assign dma_req_last = 1'b0;
end else begin
/* Request */
assign dma_req_valid = req_valid_gated;
assign req_ready_gated = dma_req_ready;
assign dma_req_dest_address = req_dest_address;
assign dma_req_src_address = req_src_address;
assign dma_req_length = req_x_length;
assign dma_req_sync_transfer_start = req_sync_transfer_start;
assign dma_req_last = req_last;
/* Response */
assign req_eot = dma_req_eot;
end endgenerate
dmac_request_arb #(
.DMA_DATA_WIDTH_SRC (DMA_DATA_WIDTH_SRC),
.DMA_DATA_WIDTH_DEST (DMA_DATA_WIDTH_DEST),
.DMA_LENGTH_WIDTH (DMA_LENGTH_WIDTH),
.BYTES_PER_BEAT_WIDTH_DEST (BYTES_PER_BEAT_WIDTH_DEST),
.BYTES_PER_BEAT_WIDTH_SRC (BYTES_PER_BEAT_WIDTH_SRC),
.DMA_TYPE_DEST (DMA_TYPE_DEST),
.DMA_TYPE_SRC (DMA_TYPE_SRC),
.DMA_AXI_ADDR_WIDTH (DMA_AXI_ADDR_WIDTH),
.ASYNC_CLK_REQ_SRC (ASYNC_CLK_REQ_SRC),
.ASYNC_CLK_SRC_DEST (ASYNC_CLK_SRC_DEST),
.ASYNC_CLK_DEST_REQ (ASYNC_CLK_DEST_REQ),
.AXI_SLICE_DEST (AXI_SLICE_DEST),
.AXI_SLICE_SRC (AXI_SLICE_SRC),
.MAX_BYTES_PER_BURST (MAX_BYTES_PER_BURST),
.FIFO_SIZE (FIFO_SIZE),
.ID_WIDTH (ID_WIDTH),
.AXI_LENGTH_WIDTH_DEST (AXI_LENGTH_WIDTH_DEST),
.AXI_LENGTH_WIDTH_SRC (AXI_LENGTH_WIDTH_SRC)
) i_request_arb (
.req_clk (req_clk),
.req_resetn (req_resetn),
.req_valid (dma_req_valid),
.req_ready (dma_req_ready),
.req_dest_address (dma_req_dest_address),
.req_src_address (dma_req_src_address),
.req_length (dma_req_length),
.req_xlast (dma_req_last),
.req_sync_transfer_start (dma_req_sync_transfer_start),
.eot (dma_req_eot),
.req_enable (req_enable),
.dest_clk (dest_clk),
.dest_ext_resetn (dest_ext_resetn),
.dest_resetn (dest_resetn),
.dest_enable (dest_enable),
.dest_enabled (dest_enabled),
.src_clk (src_clk),
.src_ext_resetn (src_ext_resetn),
.src_resetn (src_resetn),
.src_enable (src_enable),
.src_enabled (src_enabled),
.m_dest_axi_aclk (m_dest_axi_aclk),
.m_dest_axi_aresetn (m_dest_axi_aresetn),
.m_src_axi_aclk (m_src_axi_aclk),
.m_src_axi_aresetn (m_src_axi_aresetn),
.m_axi_awvalid (m_axi_awvalid),
.m_axi_awready (m_axi_awready),
.m_axi_awaddr (m_axi_awaddr),
.m_axi_awlen (m_axi_awlen),
.m_axi_awsize (m_axi_awsize),
.m_axi_awburst (m_axi_awburst),
.m_axi_awprot (m_axi_awprot),
.m_axi_awcache (m_axi_awcache),
.m_axi_wvalid (m_axi_wvalid),
.m_axi_wready (m_axi_wready),
.m_axi_wdata (m_axi_wdata),
.m_axi_wstrb (m_axi_wstrb),
.m_axi_wlast (m_axi_wlast),
.m_axi_bvalid (m_axi_bvalid),
.m_axi_bready (m_axi_bready),
.m_axi_bresp (m_axi_bresp),
.m_axi_arvalid (m_axi_arvalid),
.m_axi_arready (m_axi_arready),
.m_axi_araddr (m_axi_araddr),
.m_axi_arlen (m_axi_arlen),
.m_axi_arsize (m_axi_arsize),
.m_axi_arburst (m_axi_arburst),
.m_axi_arprot (m_axi_arprot),
.m_axi_arcache (m_axi_arcache),
.m_axi_rready (m_axi_rready),
.m_axi_rvalid (m_axi_rvalid),
.m_axi_rdata (m_axi_rdata),
.m_axi_rresp (m_axi_rresp),
.s_axis_aclk (s_axis_aclk),
.s_axis_ready (s_axis_ready),
.s_axis_valid (s_axis_valid),
.s_axis_data (s_axis_data),
.s_axis_user (s_axis_user),
.s_axis_last (s_axis_last),
.s_axis_xfer_req (s_axis_xfer_req),
.m_axis_aclk (m_axis_aclk),
.m_axis_ready (m_axis_ready),
.m_axis_valid (m_axis_valid),
.m_axis_data (m_axis_data),
.m_axis_last (m_axis_last),
.m_axis_xfer_req (m_axis_xfer_req),
.fifo_wr_clk (fifo_wr_clk),
.fifo_wr_en (fifo_wr_en),
.fifo_wr_din (fifo_wr_din),
.fifo_wr_overflow (fifo_wr_overflow),
.fifo_wr_sync (fifo_wr_sync),
.fifo_wr_xfer_req (fifo_wr_xfer_req),
.fifo_rd_clk (fifo_rd_clk),
.fifo_rd_en (fifo_rd_en),
.fifo_rd_valid (fifo_rd_valid),
.fifo_rd_dout (fifo_rd_dout),
.fifo_rd_underflow (fifo_rd_underflow),
.fifo_rd_xfer_req (fifo_rd_xfer_req),
.dbg_dest_request_id (dbg_dest_request_id),
.dbg_dest_address_id (dbg_dest_address_id),
.dbg_dest_data_id (dbg_dest_data_id),
.dbg_dest_response_id (dbg_dest_response_id),
.dbg_src_request_id (dbg_src_request_id),
.dbg_src_address_id (dbg_src_address_id),
.dbg_src_data_id (dbg_src_data_id),
.dbg_src_response_id (dbg_src_response_id)
);
endmodule