diff options
Diffstat (limited to 'fpga/usrp3/lib/vivado_ipi/axi_dmac/request_arb.v')
| -rw-r--r-- | fpga/usrp3/lib/vivado_ipi/axi_dmac/request_arb.v | 1115 |
1 files changed, 1115 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/vivado_ipi/axi_dmac/request_arb.v b/fpga/usrp3/lib/vivado_ipi/axi_dmac/request_arb.v new file mode 100644 index 000000000..706d2cedc --- /dev/null +++ b/fpga/usrp3/lib/vivado_ipi/axi_dmac/request_arb.v @@ -0,0 +1,1115 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2013(c) Analog Devices, Inc. +// Author: Lars-Peter Clausen <lars@metafoo.de> +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// - Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// - Neither the name of Analog Devices, Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// - The use of this software may or may not infringe the patent rights +// of one or more patent holders. This license does not release you +// from the requirement that you obtain separate licenses from these +// patent holders to use this software. +// - Use of the software either in source or binary form, must be run +// on or directly connected to an Analog Devices Inc. component. +// +// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. +// +// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY +// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// *************************************************************************** +// *************************************************************************** + +module dmac_request_arb ( + input req_aclk, + input req_aresetn, + + input req_valid, + output req_ready, + input [31:BYTES_PER_BEAT_WIDTH_DEST] req_dest_address, + input [31:BYTES_PER_BEAT_WIDTH_SRC] req_src_address, + input [DMA_LENGTH_WIDTH-1:0] req_length, + input req_xlast, + input req_sync_transfer_start, + + output reg eot, + + input enable, + input pause, + + // 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 [31:0] m_axi_awaddr, + output [ 7: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 [31:0] m_axi_araddr, + output [ 7: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, + 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 [7:0] dbg_status +); + +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 = DMA_TYPE_MM_AXI; +parameter DMA_TYPE_SRC = DMA_TYPE_FIFO; + +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 = 4; + +parameter ID_WIDTH = $clog2(FIFO_SIZE*2); + +localparam DMA_TYPE_MM_AXI = 0; +localparam DMA_TYPE_STREAM_AXI = 1; +localparam DMA_TYPE_FIFO = 2; + +localparam DMA_ADDRESS_WIDTH_DEST = 32 - BYTES_PER_BEAT_WIDTH_DEST; +localparam DMA_ADDRESS_WIDTH_SRC = 32 - BYTES_PER_BEAT_WIDTH_SRC; + +localparam DMA_DATA_WIDTH = DMA_DATA_WIDTH_SRC < DMA_DATA_WIDTH_DEST ? + DMA_DATA_WIDTH_DEST : DMA_DATA_WIDTH_SRC; + + + +// Bytes per burst is the same for both dest and src, but bytes per beat may +// differ, so beats per burst may also differ + +parameter BYTES_PER_BURST_WIDTH = $clog2(MAX_BYTES_PER_BURST); +localparam BEATS_PER_BURST_WIDTH_SRC = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_SRC; +localparam BEATS_PER_BURST_WIDTH_DEST = BYTES_PER_BURST_WIDTH - BYTES_PER_BEAT_WIDTH_DEST; + +localparam BURSTS_PER_TRANSFER_WIDTH = DMA_LENGTH_WIDTH - BYTES_PER_BURST_WIDTH; + +reg [0:2**ID_WIDTH-1] eot_mem; +wire request_eot; + +wire [ID_WIDTH-1:0] request_id; +wire [ID_WIDTH-1:0] response_id; + +wire enabled_src; +wire enabled_dest; +wire sync_id; +wire sync_id_ret_dest; +wire sync_id_ret_src; + +wire dest_enable; +wire dest_enabled; +wire dest_pause; +wire dest_sync_id; +wire dest_sync_id_ret; +wire src_enable; +wire src_enabled; +wire src_pause; +wire src_sync_id; +wire src_sync_id_ret; + +wire req_dest_valid; +wire req_dest_ready; +wire req_dest_empty; +wire req_src_valid; +wire req_src_ready; +wire req_src_empty; + +wire dest_clk; +wire dest_resetn; +wire dest_req_valid; +wire dest_req_ready; +wire [DMA_ADDRESS_WIDTH_DEST-1:0] dest_req_address; +wire [BEATS_PER_BURST_WIDTH_DEST-1:0] dest_req_last_burst_length; +wire [BYTES_PER_BEAT_WIDTH_DEST-1:0] dest_req_last_beat_bytes; +wire dest_req_xlast; + +wire dest_response_valid; +wire dest_response_ready; +wire dest_response_empty; +wire [1:0] dest_response_resp; +wire dest_response_resp_eot; + +wire [ID_WIDTH-1:0] dest_request_id; +wire [ID_WIDTH-1:0] dest_response_id; + +wire dest_valid; +wire dest_ready; +wire [DMA_DATA_WIDTH_DEST-1:0] dest_data; +wire dest_fifo_repacked_valid; +wire dest_fifo_repacked_ready; +wire [DMA_DATA_WIDTH_DEST-1:0] dest_fifo_repacked_data; +wire dest_fifo_valid; +wire dest_fifo_ready; +wire [DMA_DATA_WIDTH-1:0] dest_fifo_data; + +wire src_clk; +wire src_resetn; +wire src_req_valid; +wire src_req_ready; +wire [DMA_ADDRESS_WIDTH_SRC-1:0] src_req_address; +wire [BEATS_PER_BURST_WIDTH_SRC-1:0] src_req_last_burst_length; +wire src_req_sync_transfer_start; + +wire src_response_valid; +wire src_response_ready; +wire src_response_empty; +wire [1:0] src_response_resp; + +wire [ID_WIDTH-1:0] src_request_id; +wire [ID_WIDTH-1:0] src_response_id; + +wire src_valid; +wire src_ready; +wire [DMA_DATA_WIDTH_SRC-1:0] src_data; +wire src_fifo_valid; +wire src_fifo_ready; +wire [DMA_DATA_WIDTH_SRC-1:0] src_fifo_data; +wire src_fifo_repacked_valid; +wire src_fifo_repacked_ready; +wire [DMA_DATA_WIDTH-1:0] src_fifo_repacked_data; +wire src_fifo_empty; + +wire fifo_empty; + +wire response_dest_valid; +wire response_dest_ready = 1'b1; +wire [1:0] response_dest_resp; +wire response_dest_resp_eot; + +/* Unused for now +wire response_src_valid; +wire response_src_ready = 1'b1; +wire [1:0] response_src_resp; +*/ + +assign dbg_dest_request_id = dest_request_id; +assign dbg_dest_response_id = dest_response_id; +assign dbg_src_request_id = src_request_id; +assign dbg_src_response_id = src_response_id; + +assign sync_id = ~enabled_dest && ~enabled_src && request_id != response_id; + +reg enabled; +reg do_enable; + +// Enable src and dest if we are in sync +always @(posedge req_aclk) +begin + if (req_aresetn == 1'b0) begin + do_enable <= 1'b0; + end else begin + if (enable) begin + // First make sure we are fully disabled + if (~sync_id_ret_dest && ~sync_id_ret_src && + response_id == request_id && ~enabled_dest && ~enabled_src && + req_dest_empty && req_src_empty && fifo_empty) + do_enable <= 1'b1; + end else begin + do_enable <= 1'b0; + end + end +end + +// Flag enabled once both src and dest are enabled +always @(posedge req_aclk) +begin + if (req_aresetn == 1'b0) begin + enabled <= 1'b0; + end else begin + if (do_enable == 1'b0) + enabled <= 1'b0; + else if (enabled_dest && enabled_src) + enabled <= 1'b1; + end +end + +assign dbg_status = {do_enable, enabled, enabled_dest, enabled_src, fifo_empty, + sync_id, sync_id_ret_dest, sync_id_ret_src}; + +always @(posedge req_aclk) +begin + eot_mem[request_id] <= request_eot; +end + +always @(posedge req_aclk) +begin + if (req_aresetn == 1'b0) begin + eot <= 1'b0; + end else begin + eot <= response_dest_valid & response_dest_ready & response_dest_resp_eot; + end +end + +generate if (ASYNC_CLK_REQ_SRC) begin + +wire src_async_resetn_source; + +if (DMA_TYPE_SRC == DMA_TYPE_MM_AXI) begin +assign src_async_resetn_source = m_src_axi_aresetn; +end else begin +assign src_async_resetn_source = req_aresetn; +end + +reg [2:0] src_reset_shift = 3'b111; +assign src_resetn = ~src_reset_shift[2]; + +always @(negedge src_async_resetn_source or posedge src_clk) begin + if (src_async_resetn_source == 1'b0) + src_reset_shift <= 3'b111; + else + src_reset_shift <= {src_reset_shift[1:0], 1'b0}; +end + +end else begin +assign src_resetn = req_aresetn; +end endgenerate + +generate if (ASYNC_CLK_DEST_REQ) begin +wire dest_async_resetn_source; + +if (DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin +assign dest_async_resetn_source = m_dest_axi_aresetn; +end else begin +assign dest_async_resetn_source = req_aresetn; +end + +reg [2:0] dest_reset_shift = 3'b111; +assign dest_resetn = ~dest_reset_shift[2]; + +always @(negedge dest_async_resetn_source or posedge dest_clk) begin + if (dest_async_resetn_source == 1'b0) + dest_reset_shift <= 3'b111; + else + dest_reset_shift <= {dest_reset_shift[1:0], 1'b0}; +end + +end else begin +assign dest_resetn = req_aresetn; +end endgenerate + +generate if (DMA_TYPE_DEST == DMA_TYPE_MM_AXI) begin + +assign dest_clk = m_dest_axi_aclk; + +wire [ID_WIDTH-1:0] dest_data_id; +wire [ID_WIDTH-1:0] dest_address_id; +wire dest_address_eot = eot_mem[dest_address_id]; +wire dest_data_eot = eot_mem[dest_data_id]; +wire dest_response_eot = eot_mem[dest_response_id]; + +assign dbg_dest_address_id = dest_address_id; +assign dbg_dest_data_id = dest_data_id; + +dmac_dest_mm_axi #( + .ID_WIDTH(ID_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_DEST) +) i_dest_dma_mm ( + .m_axi_aclk(m_dest_axi_aclk), + .m_axi_aresetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + .pause(dest_pause), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + .req_address(dest_req_address), + .req_last_burst_length(dest_req_last_burst_length), + .req_last_beat_bytes(dest_req_last_beat_bytes), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + + .request_id(dest_request_id), + .response_id(dest_response_id), + .sync_id(dest_sync_id), + .sync_id_ret(dest_sync_id_ret), + + .data_id(dest_data_id), + .address_id(dest_address_id), + + .address_eot(dest_address_eot), + .data_eot(dest_data_eot), + .response_eot(dest_response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + + .m_axi_awready(m_axi_awready), + .m_axi_awvalid(m_axi_awvalid), + .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_wready(m_axi_wready), + .m_axi_wvalid(m_axi_wvalid), + .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_bresp(m_axi_bresp), + .m_axi_bready(m_axi_bready) +); + +end else begin + +assign m_axi_awvalid = 1'b0; +assign m_axi_awaddr = 'h00; +assign m_axi_awlen = 'h00; +assign m_axi_awsize = 'h00; +assign m_axi_awburst = 'h00; +assign m_axi_awprot = 'h00; +assign m_axi_awcache = 'h00; + +assign m_axi_wvalid = 1'b0; +assign m_axi_wdata = 'h00; +assign m_axi_wstrb = 'h00; +assign m_axi_wlast = 1'b0; + +assign m_axi_bready = 1'b0; + +end + +if (DMA_TYPE_DEST == DMA_TYPE_STREAM_AXI) begin + +assign dest_clk = m_axis_aclk; + +wire [ID_WIDTH-1:0] data_id; + +wire data_eot = eot_mem[data_id]; +wire response_eot = eot_mem[dest_response_id]; + +assign dbg_dest_address_id = 'h00; +assign dbg_dest_data_id = data_id; + +dmac_dest_axi_stream #( + .ID_WIDTH(ID_WIDTH), + .S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST) +) i_dest_dma_stream ( + .s_axis_aclk(m_axis_aclk), + .s_axis_aresetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + .req_last_burst_length(dest_req_last_burst_length), + .req_xlast(dest_req_xlast), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + + .request_id(dest_request_id), + .response_id(dest_response_id), + .data_id(data_id), + .sync_id(dest_sync_id), + .sync_id_ret(dest_sync_id_ret), + .xfer_req(m_axis_xfer_req), + + .data_eot(data_eot), + .response_eot(response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + + .m_axis_valid(m_axis_valid), + .m_axis_ready(m_axis_ready), + .m_axis_data(m_axis_data), + .m_axis_last(m_axis_last) +); + +end else begin + +assign m_axis_valid = 1'b0; +assign m_axis_last = 1'b0; +assign m_axis_xfer_req = 1'b0; +assign m_axis_data = 'h00; + +end + +if (DMA_TYPE_DEST == DMA_TYPE_FIFO) begin + +assign dest_clk = fifo_rd_clk; + +wire [ID_WIDTH-1:0] data_id; + +wire data_eot = eot_mem[data_id]; +wire response_eot = eot_mem[dest_response_id]; + +assign dbg_dest_address_id = 'h00; +assign dbg_dest_data_id = data_id; + +dmac_dest_fifo_inf #( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_DEST) +) i_dest_dma_fifo ( + .clk(fifo_rd_clk), + .resetn(dest_resetn), + + .enable(dest_enable), + .enabled(dest_enabled), + + .req_valid(dest_req_valid), + .req_ready(dest_req_ready), + .req_last_burst_length(dest_req_last_burst_length), + + .response_valid(dest_response_valid), + .response_ready(dest_response_ready), + .response_resp(dest_response_resp), + .response_resp_eot(dest_response_resp_eot), + + .request_id(dest_request_id), + .response_id(dest_response_id), + .data_id(data_id), + .sync_id(dest_sync_id), + .sync_id_ret(dest_sync_id_ret), + + .data_eot(data_eot), + .response_eot(response_eot), + + .fifo_valid(dest_valid), + .fifo_ready(dest_ready), + .fifo_data(dest_data), + + .en(fifo_rd_en), + .valid(fifo_rd_valid), + .dout(fifo_rd_dout), + .underflow(fifo_rd_underflow), + .xfer_req(fifo_rd_xfer_req) +); + +end else begin + +assign fifo_rd_valid = 1'b0; +assign fifo_rd_dout = 'h0; +assign fifo_rd_underflow = 1'b0; +assign fifo_rd_xfer_req = 1'b0; + +end endgenerate + +generate if (DMA_TYPE_SRC == DMA_TYPE_MM_AXI) begin + +assign src_clk = m_src_axi_aclk; + +wire [ID_WIDTH-1:0] src_data_id; +wire [ID_WIDTH-1:0] src_address_id; +wire src_address_eot = eot_mem[src_address_id]; +wire src_data_eot = eot_mem[src_data_id]; + +assign dbg_src_address_id = src_address_id; +assign dbg_src_data_id = src_data_id; + +dmac_src_mm_axi #( + .ID_WIDTH(ID_WIDTH), + .DMA_DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC), + .BYTES_PER_BEAT_WIDTH(BYTES_PER_BEAT_WIDTH_SRC) +) i_src_dma_mm ( + .m_axi_aclk(m_src_axi_aclk), + .m_axi_aresetn(src_resetn), + + .pause(src_pause), + .enable(src_enable), + .enabled(src_enabled), + .sync_id(src_sync_id), + .sync_id_ret(src_sync_id_ret), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_address(src_req_address), + .req_last_burst_length(src_req_last_burst_length), + + .response_valid(src_response_valid), + .response_ready(src_response_ready), + .response_resp(src_response_resp), + + .request_id(src_request_id), + .response_id(src_response_id), + .address_id(src_address_id), + .data_id(src_data_id), + + .address_eot(src_address_eot), + .data_eot(src_data_eot), + + .fifo_valid(src_valid), + .fifo_ready(src_ready), + .fifo_data(src_data), + + .m_axi_arready(m_axi_arready), + .m_axi_arvalid(m_axi_arvalid), + .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) +); + +end else begin + +assign m_axi_arvalid = 1'b0; +assign m_axi_araddr = 'h00; +assign m_axi_arlen = 'h00; +assign m_axi_arsize = 'h00; +assign m_axi_arburst = 'h00; +assign m_axi_arcache = 'h00; +assign m_axi_arprot = 'h00; +assign m_axi_rready = 1'b0; + +end + +if (DMA_TYPE_SRC == DMA_TYPE_STREAM_AXI) begin + +assign src_clk = s_axis_aclk; + +wire src_eot = eot_mem[src_response_id]; + +assign dbg_src_address_id = 'h00; +assign dbg_src_data_id = 'h00; + +/* TODO */ +assign src_response_valid = 1'b0; +assign src_response_resp = 2'b0; + +dmac_src_axi_stream #( + .ID_WIDTH(ID_WIDTH), + .S_AXIS_DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC) +) i_src_dma_stream ( + .s_axis_aclk(s_axis_aclk), + .s_axis_aresetn(src_resetn), + + .enable(src_enable), + .enabled(src_enabled), + .sync_id(src_sync_id), + .sync_id_ret(src_sync_id_ret), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_last_burst_length(src_req_last_burst_length), + .req_sync_transfer_start(src_req_sync_transfer_start), + + .request_id(src_request_id), + .response_id(src_response_id), + + .eot(src_eot), + + .fifo_valid(src_valid), + .fifo_ready(src_ready), + .fifo_data(src_data), + + .s_axis_valid(s_axis_valid), + .s_axis_ready(s_axis_ready), + .s_axis_data(s_axis_data), + .s_axis_user(s_axis_user), + .s_axis_xfer_req(s_axis_xfer_req) +); + +end else begin + +assign s_axis_ready = 1'b0; +assign s_axis_xfer_req = 1'b0; + +end + +if (DMA_TYPE_SRC == DMA_TYPE_FIFO) begin + +assign src_clk = fifo_wr_clk; + +wire src_eot = eot_mem[src_response_id]; + +assign dbg_src_address_id = 'h00; +assign dbg_src_data_id = 'h00; + +/* TODO */ +assign src_response_valid = 1'b0; +assign src_response_resp = 2'b0; + +dmac_src_fifo_inf #( + .ID_WIDTH(ID_WIDTH), + .DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH_SRC) +) i_src_dma_fifo ( + .clk(fifo_wr_clk), + .resetn(src_resetn), + + .enable(src_enable), + .enabled(src_enabled), + .sync_id(src_sync_id), + .sync_id_ret(src_sync_id_ret), + + .req_valid(src_req_valid), + .req_ready(src_req_ready), + .req_last_burst_length(src_req_last_burst_length), + .req_sync_transfer_start(src_req_sync_transfer_start), + + .request_id(src_request_id), + .response_id(src_response_id), + + .eot(src_eot), + + .fifo_valid(src_valid), + .fifo_ready(src_ready), + .fifo_data(src_data), + + .en(fifo_wr_en), + .din(fifo_wr_din), + .overflow(fifo_wr_overflow), + .sync(fifo_wr_sync), + .xfer_req(fifo_wr_xfer_req) +); + +end else begin + +assign fifo_wr_overflow = 1'b0; +assign fifo_wr_xfer_req = 1'b0; + +end endgenerate + +sync_bits #( + .NUM_OF_BITS(ID_WIDTH), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_sync_src_request_id ( + .out_clk(src_clk), + .out_resetn(src_resetn), + .in(request_id), + .out(src_request_id) +); + +sync_bits #( + .NUM_OF_BITS(ID_WIDTH), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) +) i_sync_dest_request_id ( + .out_clk(dest_clk), + .out_resetn(dest_resetn), + .in(src_response_id), + .out(dest_request_id) +); + +sync_bits #( + .NUM_OF_BITS(ID_WIDTH), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_sync_req_response_id ( + .out_clk(req_aclk), + .out_resetn(req_aresetn), + .in(dest_response_id), + .out(response_id) +); + +axi_register_slice #( + .DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .FORWARD_REGISTERED(AXI_SLICE_SRC), + .BACKWARD_REGISTERED(AXI_SLICE_SRC) +) i_src_slice ( + .clk(src_clk), + .resetn(src_resetn), + .s_axi_valid(src_valid), + .s_axi_ready(src_ready), + .s_axi_data(src_data), + .m_axi_valid(src_fifo_valid), + .m_axi_ready(src_fifo_ready), + .m_axi_data(src_fifo_data) +); + +util_axis_resize #( + .SLAVE_DATA_WIDTH(DMA_DATA_WIDTH_SRC), + .MASTER_DATA_WIDTH(DMA_DATA_WIDTH) +) i_src_repack ( + .clk(src_clk), + .resetn(src_resetn & src_enable), + .s_valid(src_fifo_valid), + .s_ready(src_fifo_ready), + .s_data(src_fifo_data), + .m_valid(src_fifo_repacked_valid), + .m_ready(src_fifo_repacked_ready), + .m_data(src_fifo_repacked_data) +); + +util_axis_fifo #( + .DATA_WIDTH(DMA_DATA_WIDTH), + .ADDRESS_WIDTH($clog2(MAX_BYTES_PER_BURST / (DMA_DATA_WIDTH / 8) * FIFO_SIZE)), + .ASYNC_CLK(ASYNC_CLK_SRC_DEST) +) i_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_fifo_repacked_valid), + .s_axis_ready(src_fifo_repacked_ready), + .s_axis_data(src_fifo_repacked_data), + .s_axis_empty(src_fifo_empty), + .s_axis_room(), + + .m_axis_aclk(dest_clk), + .m_axis_aresetn(dest_resetn), + .m_axis_valid(dest_fifo_valid), + .m_axis_ready(dest_fifo_ready), + .m_axis_data(dest_fifo_data), + .m_axis_level() +); + +util_axis_resize #( + .SLAVE_DATA_WIDTH(DMA_DATA_WIDTH), + .MASTER_DATA_WIDTH(DMA_DATA_WIDTH_DEST) +) i_dest_repack ( + .clk(dest_clk), + .resetn(dest_resetn & dest_enable), + .s_valid(dest_fifo_valid), + .s_ready(dest_fifo_ready), + .s_data(dest_fifo_data), + .m_valid(dest_fifo_repacked_valid), + .m_ready(dest_fifo_repacked_ready), + .m_data(dest_fifo_repacked_data) +); + +wire _dest_valid; +wire _dest_ready; +wire [DMA_DATA_WIDTH_DEST-1:0] _dest_data; + +axi_register_slice #( + .DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .FORWARD_REGISTERED(AXI_SLICE_DEST) +) i_dest_slice2 ( + .clk(dest_clk), + .resetn(dest_resetn), + .s_axi_valid(dest_fifo_repacked_valid), + .s_axi_ready(dest_fifo_repacked_ready), + .s_axi_data(dest_fifo_repacked_data), + .m_axi_valid(_dest_valid), + .m_axi_ready(_dest_ready), + .m_axi_data(_dest_data) +); + +axi_register_slice #( + .DATA_WIDTH(DMA_DATA_WIDTH_DEST), + .FORWARD_REGISTERED(AXI_SLICE_DEST), + .BACKWARD_REGISTERED(AXI_SLICE_DEST) +) i_dest_slice ( + .clk(dest_clk), + .resetn(dest_resetn), + .s_axi_valid(_dest_valid), + .s_axi_ready(_dest_ready), + .s_axi_data(_dest_data), + .m_axi_valid(dest_valid), + .m_axi_ready(dest_ready), + .m_axi_data(dest_data) +); + + +// We do not accept any requests until all components are enabled +reg _req_valid = 1'b0; +wire _req_ready; + +always @(posedge req_aclk) +begin + if (req_aresetn == 1'b0) begin + _req_valid <= 1'b0; + end else begin + if (_req_valid == 1'b1 && _req_ready == 1'b1) begin + _req_valid <= 1'b0; + end else if (req_valid == 1'b1 && enabled == 1'b1) begin + _req_valid <= 1'b1; + end + end +end + +assign req_ready = _req_ready & _req_valid & enable; + +splitter #( + .NUM_M(3) +) i_req_splitter ( + .clk(req_aclk), + .resetn(req_aresetn), + .s_valid(_req_valid), + .s_ready(_req_ready), + .m_valid({ + req_gen_valid, + req_dest_valid, + req_src_valid + }), + .m_ready({ + req_gen_ready, + req_dest_ready, + req_src_ready + }) +); + +util_axis_fifo #( + .DATA_WIDTH(DMA_ADDRESS_WIDTH_DEST + BEATS_PER_BURST_WIDTH_DEST + BYTES_PER_BEAT_WIDTH_DEST + 1), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_dest_req_fifo ( + .s_axis_aclk(req_aclk), + .s_axis_aresetn(req_aresetn), + .s_axis_valid(req_dest_valid), + .s_axis_ready(req_dest_ready), + .s_axis_empty(req_dest_empty), + .s_axis_data({ + req_dest_address, + req_length[BYTES_PER_BURST_WIDTH-1:BYTES_PER_BEAT_WIDTH_DEST], + req_length[BYTES_PER_BEAT_WIDTH_DEST-1:0], + req_xlast + }), + .s_axis_room(), + + .m_axis_aclk(dest_clk), + .m_axis_aresetn(dest_resetn), + .m_axis_valid(dest_req_valid), + .m_axis_ready(dest_req_ready), + .m_axis_data({ + dest_req_address, + dest_req_last_burst_length, + dest_req_last_beat_bytes, + dest_req_xlast + }), + .m_axis_level() +); + +util_axis_fifo #( + .DATA_WIDTH(DMA_ADDRESS_WIDTH_SRC + BEATS_PER_BURST_WIDTH_SRC + 1), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_src_req_fifo ( + .s_axis_aclk(req_aclk), + .s_axis_aresetn(req_aresetn), + .s_axis_valid(req_src_valid), + .s_axis_ready(req_src_ready), + .s_axis_empty(req_src_empty), + .s_axis_data({ + req_src_address, + req_length[BYTES_PER_BURST_WIDTH-1:BYTES_PER_BEAT_WIDTH_SRC], + req_sync_transfer_start + }), + .s_axis_room(), + + .m_axis_aclk(src_clk), + .m_axis_aresetn(src_resetn), + .m_axis_valid(src_req_valid), + .m_axis_ready(src_req_ready), + .m_axis_data({ + src_req_address, + src_req_last_burst_length, + src_req_sync_transfer_start + }), + .m_axis_level() +); + +util_axis_fifo #( + .DATA_WIDTH(1), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_dest_response_fifo ( + .s_axis_aclk(dest_clk), + .s_axis_aresetn(dest_resetn), + .s_axis_valid(dest_response_valid), + .s_axis_ready(dest_response_ready), + .s_axis_empty(dest_response_empty), + .s_axis_data(dest_response_resp_eot), + .s_axis_room(), + + .m_axis_aclk(req_aclk), + .m_axis_aresetn(req_aresetn), + .m_axis_valid(response_dest_valid), + .m_axis_ready(response_dest_ready), + .m_axis_data(response_dest_resp_eot), + .m_axis_level() +); + +/* Unused for now +util_axis_fifo #( + .DATA_WIDTH(2), + .ADDRESS_WIDTH(0), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_src_response_fifo ( + .s_axis_aclk(src_clk), + .s_axis_aresetn(src_resetn), + .s_axis_valid(src_response_valid), + .s_axis_ready(src_response_ready), + .s_axis_empty(src_response_empty), + .s_axis_data(src_response_resp), + .m_axis_aclk(req_aclk), + .m_axis_aresetn(req_aresetn), + .m_axis_valid(response_src_valid), + .m_axis_ready(response_src_ready), + .m_axis_data(response_src_resp) +);*/ +assign src_response_empty = 1'b1; +assign src_response_ready = 1'b1; + +dmac_request_generator #( + .ID_WIDTH(ID_WIDTH), + .BURSTS_PER_TRANSFER_WIDTH(BURSTS_PER_TRANSFER_WIDTH) +) i_req_gen ( + .req_aclk(req_aclk), + .req_aresetn(req_aresetn), + + .request_id(request_id), + .response_id(response_id), + + .req_valid(req_gen_valid), + .req_ready(req_gen_ready), + .req_burst_count(req_length[DMA_LENGTH_WIDTH-1:BYTES_PER_BURST_WIDTH]), + + .enable(do_enable), + .pause(pause), + + .eot(request_eot) +); + +sync_bits #( + .NUM_OF_BITS(3), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_sync_control_dest ( + .out_clk(dest_clk), + .out_resetn(dest_resetn), + .in({do_enable, pause, sync_id}), + .out({dest_enable, dest_pause, dest_sync_id}) +); + +sync_bits #( + .NUM_OF_BITS(2), + .ASYNC_CLK(ASYNC_CLK_DEST_REQ) +) i_sync_status_dest ( + .out_clk(req_aclk), + .out_resetn(req_aresetn), + .in({dest_enabled | ~dest_response_empty, dest_sync_id_ret}), + .out({enabled_dest, sync_id_ret_dest}) +); + +sync_bits #( + .NUM_OF_BITS(3), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_sync_control_src ( + .out_clk(src_clk), + .out_resetn(src_resetn), + .in({do_enable, pause, sync_id}), + .out({src_enable, src_pause, src_sync_id}) +); + +sync_bits #( + .NUM_OF_BITS(3), + .ASYNC_CLK(ASYNC_CLK_REQ_SRC) +) i_sync_status_src ( + .out_clk(req_aclk), + .out_resetn(req_aresetn), + .in({src_enabled | ~src_response_empty, src_sync_id_ret, src_fifo_empty}), + .out({enabled_src, sync_id_ret_src, fifo_empty}) +); + +endmodule |
