From e855ef38f4b6958e74122bdac257c211d1a98445 Mon Sep 17 00:00:00 2001 From: Istvan Csomortani Date: Tue, 19 Apr 2016 11:28:33 +0300 Subject: [PATCH] axi_dacfifo: Initial commit AXI DAC fifo, which use the PL side DDR memory. The minimum data granularity is 1kbyte. --- library/Makefile | 2 + library/axi_dacfifo/Makefile | 48 +++ library/axi_dacfifo/axi_dacfifo.v | 310 +++++++++++++++ library/axi_dacfifo/axi_dacfifo_constr.xdc | 11 + library/axi_dacfifo/axi_dacfifo_dac.v | 279 ++++++++++++++ library/axi_dacfifo/axi_dacfifo_ip.tcl | 24 ++ library/axi_dacfifo/axi_dacfifo_rd.v | 240 ++++++++++++ library/axi_dacfifo/axi_dacfifo_wr.v | 424 +++++++++++++++++++++ 8 files changed, 1338 insertions(+) create mode 100644 library/axi_dacfifo/Makefile create mode 100644 library/axi_dacfifo/axi_dacfifo.v create mode 100644 library/axi_dacfifo/axi_dacfifo_constr.xdc create mode 100644 library/axi_dacfifo/axi_dacfifo_dac.v create mode 100644 library/axi_dacfifo/axi_dacfifo_ip.tcl create mode 100644 library/axi_dacfifo/axi_dacfifo_rd.v create mode 100644 library/axi_dacfifo/axi_dacfifo_wr.v diff --git a/library/Makefile b/library/Makefile index f6e88a083..983870d4f 100644 --- a/library/Makefile +++ b/library/Makefile @@ -29,6 +29,7 @@ clean: make -C axi_ad9739a clean make -C axi_adcfifo clean make -C axi_clkgen clean + make -C axi_dacfifo clean make -C axi_dmac clean make -C axi_generic_adc clean make -C axi_gpreg clean @@ -96,6 +97,7 @@ lib: -make -C axi_ad9739a -make -C axi_adcfifo -make -C axi_clkgen + -make -C axi_dacfifo -make -C axi_dmac -make -C axi_generic_adc -make -C axi_gpreg diff --git a/library/axi_dacfifo/Makefile b/library/axi_dacfifo/Makefile new file mode 100644 index 000000000..f84dfb477 --- /dev/null +++ b/library/axi_dacfifo/Makefile @@ -0,0 +1,48 @@ +#################################################################################### +#################################################################################### +## Copyright 2011(c) Analog Devices, Inc. +## Auto-generated, do not modify! +#################################################################################### +#################################################################################### + +M_DEPS := axi_dacfifo_ip.tcl +M_DEPS += ../scripts/adi_env.tcl +M_DEPS += ../scripts/adi_ip.tcl +M_DEPS += ../common/ad_mem_asym.v +M_DEPS += ../common/ad_axis_inf_rx.v +M_DEPS += axi_dacfifo_dac.v +M_DEPS += axi_dacfifo_wr.v +M_DEPS += axi_dacfifo_rd.v +M_DEPS += axi_dacfifo.v +M_DEPS += axi_dacfifo_constr.xdc + +M_VIVADO := vivado -mode batch -source + +M_FLIST := *.cache +M_FLIST += *.data +M_FLIST += *.xpr +M_FLIST += *.log +M_FLIST += component.xml +M_FLIST += *.jou +M_FLIST += xgui +M_FLIST += .Xil + + + +.PHONY: all clean clean-all +all: axi_dacfifo.xpr + + +clean:clean-all + + +clean-all: + rm -rf $(M_FLIST) + + +axi_dacfifo.xpr: $(M_DEPS) + rm -rf $(M_FLIST) + $(M_VIVADO) axi_dacfifo_ip.tcl >> axi_dacfifo_ip.log 2>&1 + +#################################################################################### +#################################################################################### diff --git a/library/axi_dacfifo/axi_dacfifo.v b/library/axi_dacfifo/axi_dacfifo.v new file mode 100644 index 000000000..c949dcb6c --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo.v @@ -0,0 +1,310 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2016(c) Analog Devices, Inc. +// +// 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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dacfifo ( + + // dma interface (AXI Stream) + + dma_clk, + dma_valid, + dma_data, + dma_ready, + dma_xfer_req, + dma_xfer_last, + + // dac interface + + dac_clk, + dac_reset, + dac_valid, + dac_data, + dac_dunf, + dac_dovf, + dac_xfer_out, + + // axi interface + + axi_clk, + axi_resetn, + axi_awvalid, + axi_awid, + axi_awburst, + axi_awlock, + axi_awcache, + axi_awprot, + axi_awqos, + axi_awuser, + axi_awlen, + axi_awsize, + axi_awaddr, + axi_awready, + axi_wvalid, + axi_wdata, + axi_wstrb, + axi_wlast, + axi_wuser, + axi_wready, + axi_bvalid, + axi_bid, + axi_bresp, + axi_buser, + axi_bready, + axi_arvalid, + axi_arid, + axi_arburst, + axi_arlock, + axi_arcache, + axi_arprot, + axi_arqos, + axi_aruser, + axi_arlen, + axi_arsize, + axi_araddr, + axi_arready, + axi_rvalid, + axi_rid, + axi_ruser, + axi_rresp, + axi_rlast, + axi_rdata, + axi_rready); + + // parameters + + parameter DAC_DATA_WIDTH = 128; + parameter DMA_DATA_WIDTH = 64; + parameter AXI_DATA_WIDTH = 512; + parameter AXI_RD_SIZE = 2; + parameter AXI_RD_LENGTH = 32; + parameter AXI_WR_SIZE = 2; + parameter AXI_WR_LENGTH = 32; + parameter AXI_ADDRESS = 32'h00000000; + parameter AXI_ADDRESS_LIMIT = 32'hffffffff; + parameter AXI_BYTE_WIDTH = AXI_DATA_WIDTH/8; + + // dma interface + + input dma_clk; + input dma_valid; + input [(DMA_DATA_WIDTH-1):0] dma_data; + output dma_ready; + input dma_xfer_req; + input dma_xfer_last; + + // dac interface + + input dac_clk; + input dac_reset; + input dac_valid; + output [(DAC_DATA_WIDTH-1):0] dac_data; + output dac_dunf; + output dac_dovf; + output dac_xfer_out; + + // axi interface + + input axi_clk; + input axi_resetn; + output axi_awvalid; + output [ 3:0] axi_awid; + output [ 1:0] axi_awburst; + output axi_awlock; + output [ 3:0] axi_awcache; + output [ 2:0] axi_awprot; + output [ 3:0] axi_awqos; + output [ 3:0] axi_awuser; + output [ 7:0] axi_awlen; + output [ 2:0] axi_awsize; + output [ 31:0] axi_awaddr; + input axi_awready; + output axi_wvalid; + output [(AXI_DATA_WIDTH-1):0] axi_wdata; + output [(AXI_BYTE_WIDTH-1):0] axi_wstrb; + output axi_wlast; + output [ 3:0] axi_wuser; + input axi_wready; + input axi_bvalid; + input [ 3:0] axi_bid; + input [ 1:0] axi_bresp; + input [ 3:0] axi_buser; + output axi_bready; + output axi_arvalid; + output [ 3:0] axi_arid; + output [ 1:0] axi_arburst; + output axi_arlock; + output [ 3:0] axi_arcache; + output [ 2:0] axi_arprot; + output [ 3:0] axi_arqos; + output [ 3:0] axi_aruser; + output [ 7:0] axi_arlen; + output [ 2:0] axi_arsize; + output [ 31:0] axi_araddr; + input axi_arready; + input axi_rvalid; + input [ 3:0] axi_rid; + input [ 3:0] axi_ruser; + input [ 1:0] axi_rresp; + input axi_rlast; + input [(AXI_DATA_WIDTH-1):0] axi_rdata; + output axi_rready; + + // internal registers + reg dma_dacrst_m1 = 1'b0; + reg dma_dacrst_m2 = 1'b0; + + // internal signals + + wire [(AXI_DATA_WIDTH-1):0] axi_wr_data_s; + wire axi_wr_ready_s; + wire axi_wr_valid_s; + wire [(AXI_DATA_WIDTH-1):0] axi_rd_data_s; + wire axi_rd_ready_s; + wire axi_rd_valid_s; + wire [31:0] axi_rd_lastaddr_s; + wire axi_xfer_req_s; + wire dma_rst_s; + + // DAC reset the DMA side too + + always @(posedge dma_clk) begin + dma_dacrst_m1 <= dac_reset; + dma_dacrst_m2 <= dma_dacrst_m1; + end + assign dma_rst_s = dma_dacrst_m2; + + // instantiations + + axi_dacfifo_wr #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .DMA_DATA_WIDTH (DMA_DATA_WIDTH), + .AXI_SIZE (AXI_WR_SIZE), + .AXI_LENGTH (AXI_WR_LENGTH), + .AXI_ADDRESS (AXI_ADDRESS), + .AXI_ADDRESS_LIMIT (AXI_ADDRESS_LIMIT) + ) i_wr ( + .dma_clk (dma_clk), + .dma_rst (dma_rst_s), + .dma_data (dma_data), + .dma_ready (dma_ready), + .dma_valid (dma_valid), + .dma_xfer_req (dma_xfer_req), + .dma_xfer_last (dma_xfer_last), + .axi_last_raddr (axi_rd_lastaddr_s), + .axi_xfer_out (axi_xfer_req_s), + .axi_clk (axi_clk), + .axi_resetn (axi_resetn), + .axi_awvalid (axi_awvalid), + .axi_awid (axi_awid), + .axi_awburst (axi_awburst), + .axi_awlock (axi_awlock), + .axi_awcache (axi_awcache), + .axi_awprot (axi_awprot), + .axi_awqos (axi_awqos), + .axi_awuser (axi_awuser), + .axi_awlen (axi_awlen), + .axi_awsize (axi_awsize), + .axi_awaddr (axi_awaddr), + .axi_awready (axi_awready), + .axi_wvalid (axi_wvalid), + .axi_wdata (axi_wdata), + .axi_wstrb (axi_wstrb), + .axi_wlast (axi_wlast), + .axi_wuser (axi_wuser), + .axi_wready (axi_wready), + .axi_bvalid (axi_bvalid), + .axi_bid (axi_bid), + .axi_bresp (axi_bresp), + .axi_buser (axi_buser), + .axi_bready (axi_bready), + .axi_werror (axi_werror)); + + axi_dacfifo_rd #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_SIZE (AXI_RD_SIZE), + .AXI_LENGTH (AXI_RD_LENGTH), + .AXI_ADDRESS (AXI_ADDRESS) + ) i_rd ( + .axi_rd_lastaddr (axi_rd_lastaddr_s), + .axi_xfer_req (axi_xfer_req_s), + .axi_clk (axi_clk), + .axi_resetn (axi_resetn), + .axi_arvalid (axi_arvalid), + .axi_arid (axi_arid), + .axi_arburst (axi_arburst), + .axi_arlock (axi_arlock), + .axi_arcache (axi_arcache), + .axi_arprot (axi_arprot), + .axi_arqos (axi_arqos), + .axi_aruser (axi_aruser), + .axi_arlen (axi_arlen), + .axi_arsize (axi_arsize), + .axi_araddr (axi_araddr), + .axi_arready (axi_arready), + .axi_rvalid (axi_rvalid), + .axi_rid (axi_rid), + .axi_ruser (axi_ruser), + .axi_rresp (axi_rresp), + .axi_rlast (axi_rlast), + .axi_rdata (axi_rdata), + .axi_rready (axi_rready), + .axi_rerror (axi_rerror), + .axi_dvalid (axi_rd_valid_s), + .axi_ddata (axi_rd_data_s), + .axi_dready (axi_rd_ready_s)); + + axi_dacfifo_dac #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .DAC_DATA_WIDTH (DAC_DATA_WIDTH) + ) i_dac ( + .axi_clk (axi_clk), + .axi_dvalid (axi_rd_valid_s), + .axi_ddata (axi_rd_data_s), + .axi_dready (axi_rd_ready_s), + .axi_xfer_req (axi_xfer_req_s), + .dac_clk (dac_clk), + .dac_valid (dac_valid), + .dac_data (dac_data), + .dac_xfer_out (dac_xfer_out), + .dac_dunf (dac_dunf), + .dac_dovf (dac_dovf)); + +endmodule + diff --git a/library/axi_dacfifo/axi_dacfifo_constr.xdc b/library/axi_dacfifo/axi_dacfifo_constr.xdc new file mode 100644 index 000000000..0343601bc --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo_constr.xdc @@ -0,0 +1,11 @@ + +set_property ASYNC_REG TRUE \ + [get_cells -hier *dac_dovf_m_reg*] \ + [get_cells -hier *dac_xfer_req_m_reg*] \ + [get_cells -hier *dac_dunf_m_reg*] + +set_false_path -from [get_cells *dac_* -hierarchical -filter {PRIMITIVE_SUBGROUP == flop}] \ + -to [get_cells *axi_*_m* -hierarchical -filter {PRIMITIVE_SUBGROUP == flop}] +set_false_path -from [get_cells *axi_* -hierarchical -filter {PRIMITIVE_SUBGROUP == flop}] \ + -to [get_cells *dac_*_m* -hierarchical -filter {PRIMITIVE_SUBGROUP == flop}] + diff --git a/library/axi_dacfifo/axi_dacfifo_dac.v b/library/axi_dacfifo/axi_dacfifo_dac.v new file mode 100644 index 000000000..37f725a01 --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo_dac.v @@ -0,0 +1,279 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2016(c) Analog Devices, Inc. +// +// 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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dacfifo_dac ( + + axi_clk, + axi_dvalid, + axi_ddata, + axi_dready, + axi_xfer_req, + + dac_clk, + dac_valid, + dac_data, + dac_xfer_out, + dac_dunf, + dac_dovf + +); + + // parameters + + parameter AXI_DATA_WIDTH = 512; + parameter DAC_DATA_WIDTH = 64; + + localparam MEM_RATIO = AXI_DATA_WIDTH/DAC_DATA_WIDTH; + localparam DAC_ADDRESS_WIDTH = 8; + localparam AXI_ADDRESS_WIDTH = (MEM_RATIO == 1) ? DAC_ADDRESS_WIDTH : + (MEM_RATIO == 2) ? (DAC_ADDRESS_WIDTH - 1) : + (MEM_RATIO == 4) ? (DAC_ADDRESS_WIDTH - 2) : + (DAC_ADDRESS_WIDTH - 3); + localparam BUF_THRESHOLD_LO = 8'd32; + localparam BUF_THRESHOLD_HI = 8'd240; + + // dma write + + input axi_clk; + input axi_dvalid; + input [(AXI_DATA_WIDTH-1):0] axi_ddata; + output axi_dready; + input axi_xfer_req; + + // dac read + + input dac_clk; + input dac_valid; + output [(DAC_DATA_WIDTH-1):0] dac_data; + output dac_xfer_out; + output dac_dunf; + output dac_dovf; + + // internal registers + + reg [(AXI_ADDRESS_WIDTH-1):0] axi_waddr = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] axi_waddr_g = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] axi_raddr = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] axi_raddr_m = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] axi_addr_diff = 'd0; + reg axi_dready = 'd0; + reg axi_almost_full = 1'b0; + reg axi_dwunf = 1'b0; + reg axi_almost_empty = 1'b0; + reg axi_dwovf = 1'b0; + + reg dac_rst = 'd0; + reg dac_rd = 'd0; + reg dac_rd_d = 'd0; + reg [(DAC_DATA_WIDTH-1):0] dac_rdata_d = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] dac_raddr = 'd0; + reg [(DAC_ADDRESS_WIDTH-1):0] dac_raddr_g = 'd0; + + reg [ 2:0] dac_dunf_m = 3'b0; + reg [ 2:0] dac_dovf_m = 3'b0; + reg [ 2:0] dac_xfer_req_m = 3'b0; + + // internal signals + + wire [DAC_ADDRESS_WIDTH:0] axi_addr_diff_s; + wire [(DAC_ADDRESS_WIDTH-1):0] axi_waddr_s; + wire dac_wready_s; + wire dac_rd_s; + wire [(DAC_DATA_WIDTH-1):0] dac_rdata_s; + + wire dac_valid_s; + + // binary to grey conversion + + function [7:0] b2g; + input [7:0] b; + reg [7:0] g; + begin + g[7] = b[7]; + g[6] = b[7] ^ b[6]; + g[5] = b[6] ^ b[5]; + g[4] = b[5] ^ b[4]; + g[3] = b[4] ^ b[3]; + g[2] = b[3] ^ b[2]; + g[1] = b[2] ^ b[1]; + g[0] = b[1] ^ b[0]; + b2g = g; + end + endfunction + + // grey to binary conversion + + function [7:0] g2b; + input [7:0] g; + reg [7:0] b; + begin + b[7] = g[7]; + b[6] = b[7] ^ g[6]; + b[5] = b[6] ^ g[5]; + b[4] = b[5] ^ g[4]; + b[3] = b[4] ^ g[3]; + b[2] = b[3] ^ g[2]; + b[1] = b[2] ^ g[1]; + b[0] = b[1] ^ g[0]; + g2b = b; + end + endfunction + + // write interface + + always @(posedge axi_clk) begin + if (axi_xfer_req == 1'b0) begin + axi_waddr <= 'd0; + axi_waddr_g <= 'd0; + end else begin + if (axi_dvalid == 1'b1) begin + axi_waddr <= axi_waddr + 1'b1; + end + axi_waddr_g <= b2g(axi_waddr_s); + end + end + + // underflow / overflow + + assign axi_addr_diff_s = {1'b1, axi_waddr_s} - axi_raddr; + assign axi_waddr_s = (MEM_RATIO == 1) ? axi_waddr : + (MEM_RATIO == 2) ? {axi_waddr, 1'd0} : + (MEM_RATIO == 4) ? {axi_waddr, 2'd0} : + {axi_waddr, 3'd0}; + + always @(posedge axi_clk) begin + if (axi_xfer_req == 1'b0) begin + axi_addr_diff <= 'd0; + axi_raddr <= 'd0; + axi_raddr_m <= 'd0; + axi_dready <= 'd0; + axi_almost_full <= 1'b0; + axi_dwunf <= 1'b0; + axi_almost_empty <= 1'b0; + axi_dwovf <= 1'b0; + end else begin + axi_raddr_m <= g2b(dac_raddr_g); + axi_raddr <= axi_raddr_m; + axi_addr_diff <= axi_addr_diff_s[DAC_ADDRESS_WIDTH-1:0]; + if (axi_addr_diff >= BUF_THRESHOLD_HI) begin + axi_dready <= 1'b0; + end else if (axi_addr_diff <= BUF_THRESHOLD_LO) begin + axi_dready <= 1'b1; + end + if (axi_addr_diff > BUF_THRESHOLD_HI) begin + axi_almost_full <= 1'b1; + end else begin + axi_almost_full <= 1'b0; + end + if (axi_addr_diff < BUF_THRESHOLD_LO) begin + axi_almost_empty <= 1'b1; + end else begin + axi_almost_empty <= 1'b0; + end + axi_dwunf <= (axi_addr_diff == 0) ? 1'b1 : 1'b0; + axi_dwovf <= (axi_addr_diff == {(DAC_ADDRESS_WIDTH){1'b1}}) ? 1'b1 : 1'b0; + end + end + + always @(posedge dac_clk) begin + dac_dunf_m <= {dac_dunf_m[1:0], axi_dwunf}; + dac_dovf_m <= {dac_dovf_m[1:0], axi_dwovf}; + dac_xfer_req_m <= {dac_xfer_req_m[1:0], axi_xfer_req}; + end + + assign dac_dovf = dac_dovf_m[2]; + assign dac_dunf = dac_dunf_m[2]; + assign dac_xfer_out = dac_xfer_req_m[2]; + + // read interface + + assign dac_rd_s = dac_xfer_out & dac_valid; + + always @(posedge dac_clk) begin + if (dac_xfer_out == 1'b0) begin + dac_rd <= 'd0; + dac_rd_d <= 'd0; + dac_rdata_d <= 'd0; + dac_raddr <= 'd0; + dac_raddr_g <= 'd0; + end else begin + dac_rd <= dac_rd_s; + dac_rd_d <= dac_rd; + dac_rdata_d <= dac_rdata_s; + if (dac_rd_s == 1'b1) begin + dac_raddr <= dac_raddr + 1'b1; + end + dac_raddr_g <= b2g(dac_raddr); + end + end + + // instantiations + + ad_mem_asym #( + .A_ADDRESS_WIDTH (AXI_ADDRESS_WIDTH), + .A_DATA_WIDTH (AXI_DATA_WIDTH), + .B_ADDRESS_WIDTH (DAC_ADDRESS_WIDTH), + .B_DATA_WIDTH (DAC_DATA_WIDTH)) + i_mem_asym ( + .clka (axi_clk), + .wea (axi_dvalid), + .addra (axi_waddr), + .dina (axi_ddata), + .clkb (dac_clk), + .addrb (dac_raddr), + .doutb (dac_rdata_s)); + + ad_axis_inf_rx #(.DATA_WIDTH(DAC_DATA_WIDTH)) i_axis_inf ( + .clk (dac_clk), + .rst (dac_rst), + .valid (dac_rd_d), + .last (1'd0), + .data (dac_rdata_d), + .inf_valid (dac_valid_s), + .inf_last (), + .inf_data (dac_data), + .inf_ready (dac_valid)); + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/library/axi_dacfifo/axi_dacfifo_ip.tcl b/library/axi_dacfifo/axi_dacfifo_ip.tcl new file mode 100644 index 000000000..905139739 --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo_ip.tcl @@ -0,0 +1,24 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_dacfifo + +adi_ip_files axi_dacfifo [list \ + "$ad_hdl_dir/library/common/ad_mem_asym.v" \ + "$ad_hdl_dir/library/common/ad_axis_inf_rx.v" \ + "axi_dacfifo_dac.v" \ + "axi_dacfifo_wr.v" \ + "axi_dacfifo_rd.v" \ + "axi_dacfifo.v" \ + "axi_dacfifo_constr.xdc" ] + +adi_ip_properties_lite axi_dacfifo +adi_ip_constraints axi_dacfifo [list \ + "axi_dacfifo_constr.xdc" ] + +ipx::infer_bus_interfaces {{xilinx.com:interface:aximm:1.0}} [ipx::current_core] + +ipx::save_core [ipx::current_core] + diff --git a/library/axi_dacfifo/axi_dacfifo_rd.v b/library/axi_dacfifo/axi_dacfifo_rd.v new file mode 100644 index 000000000..b3ec1388f --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo_rd.v @@ -0,0 +1,240 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2016(c) Analog Devices, Inc. +// +// 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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dacfifo_rd ( + + // xfer last for read/write synchronization + + axi_xfer_req, + axi_rd_lastaddr, + + // axi read address and read data channels + + axi_clk, + axi_resetn, + axi_arvalid, + axi_arid, + axi_arburst, + axi_arlock, + axi_arcache, + axi_arprot, + axi_arqos, + axi_aruser, + axi_arlen, + axi_arsize, + axi_araddr, + axi_arready, + axi_rvalid, + axi_rid, + axi_ruser, + axi_rresp, + axi_rlast, + axi_rdata, + axi_rready, + + // axi status + + axi_rerror, + + // fifo interface + + axi_dvalid, + axi_ddata, + axi_dready); + + // parameters + + parameter AXI_DATA_WIDTH = 512; + parameter AXI_SIZE = 2; + parameter AXI_LENGTH = 15; + parameter AXI_ADDRESS = 32'h00000000; + localparam AXI_BYTE_WIDTH = AXI_DATA_WIDTH/8; + localparam AXI_AWINCR = (AXI_LENGTH + 1) * AXI_BYTE_WIDTH; + + // xfer last for read/write synchronization + + input axi_xfer_req; + input [ 31:0] axi_rd_lastaddr; + + // axi interface + + input axi_clk; + input axi_resetn; + output axi_arvalid; + output [ 3:0] axi_arid; + output [ 1:0] axi_arburst; + output axi_arlock; + output [ 3:0] axi_arcache; + output [ 2:0] axi_arprot; + output [ 3:0] axi_arqos; + output [ 3:0] axi_aruser; + output [ 7:0] axi_arlen; + output [ 2:0] axi_arsize; + output [ 31:0] axi_araddr; + input axi_arready; + input axi_rvalid; + input [ 3:0] axi_rid; + input [ 3:0] axi_ruser; + input [ 1:0] axi_rresp; + input axi_rlast; + input [(AXI_DATA_WIDTH-1):0] axi_rdata; + output axi_rready; + + // axi status + + output axi_rerror; + + // fifo interface + + output axi_dvalid; + output [(AXI_DATA_WIDTH-1):0] axi_ddata; + input axi_dready; + + // internal registers + + reg [ 31:0] axi_rd_addr_h = 32'b0; + reg axi_rd = 1'b0; + reg axi_rd_active = 1'b0; + reg axi_arvalid = 1'b0; + reg [ 31:0] axi_araddr = 32'b0; + reg [(AXI_DATA_WIDTH-1):0] axi_ddata = 'b0; + reg axi_dvalid = 1'b0; + reg axi_rready = 1'b0; + reg axi_rerror = 1'b0; + reg [ 1:0] axi_xfer_req_m = 2'b0; + + // internal signals + + wire axi_ready_s; + wire axi_xfer_req_init; + wire axi_dvalid_s; + + assign axi_ready_s = (~axi_arvalid | axi_arready) & axi_dready; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_rd <= 1'b0; + axi_rd_active <= 1'b0; + axi_xfer_req_m <= 2'b0; + end else begin + if (axi_rd_active == 1'b1) begin + axi_rd <= 1'b0; + if ((axi_rvalid == 1'b1) && (axi_rlast == 1'b1)) begin + axi_rd_active <= 1'b0; + end + end else if ((axi_ready_s == 1'b1)) begin + axi_rd <= axi_xfer_req; + axi_rd_active <= axi_xfer_req; + end + axi_xfer_req_m <= {axi_xfer_req_m[0], axi_xfer_req}; + end + end + + assign axi_xfer_req_init = axi_xfer_req_m[0] & ~axi_xfer_req_m[1]; + + // address channel + + assign axi_arid = 4'b0000; + assign axi_arburst = 2'b01; + assign axi_arlock = 1'b0; + assign axi_arcache = 4'b0010; + assign axi_arprot = 3'b000; + assign axi_arqos = 4'b0000; + assign axi_aruser = 4'b0001; + assign axi_arlen = AXI_LENGTH; + assign axi_arsize = AXI_SIZE; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_arvalid <= 'd0; + axi_araddr <= 'd0; + end else begin + if (axi_arvalid == 1'b1) begin + if (axi_arready == 1'b1) begin + axi_arvalid <= 1'b0; + end + end else begin + if (axi_rd == 1'b1) begin + axi_arvalid <= 1'b1; + end + end + if ((axi_xfer_req_init == 1'b1)) begin + axi_araddr <= AXI_ADDRESS; + axi_rd_addr_h <= axi_rd_lastaddr; + end else if ((axi_xfer_req == 1'b1) && + (axi_arvalid == 1'b1) && + (axi_arready == 1'b1)) begin + axi_araddr <= ((axi_araddr + AXI_AWINCR) >= axi_rd_addr_h) ? AXI_ADDRESS : axi_araddr + AXI_AWINCR; + end + end + end + + // read data channel + + assign axi_dvalid_s = axi_rvalid & axi_rready; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_ddata <= 'd0; + axi_rready <= 1'b0; + axi_dvalid <= 1'b0; + end else begin + axi_ddata <= axi_rdata; + axi_dvalid <= axi_dvalid_s; + if (axi_xfer_req == 1) begin + axi_rready <= axi_rvalid; + end + end + end + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_rerror <= 'd0; + end else begin + axi_rerror <= axi_rvalid & axi_rresp[1]; + end + end + +endmodule + +// *************************************************************************** +// *************************************************************************** + diff --git a/library/axi_dacfifo/axi_dacfifo_wr.v b/library/axi_dacfifo/axi_dacfifo_wr.v new file mode 100644 index 000000000..7111200cf --- /dev/null +++ b/library/axi_dacfifo/axi_dacfifo_wr.v @@ -0,0 +1,424 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2016(c) Analog Devices, Inc. +// +// 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. +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_dacfifo_wr ( + + // dma fifo interface + + dma_clk, + dma_rst, + dma_data, + dma_ready, + dma_valid, + + // request and syncronizaiton + + dma_xfer_req, + dma_xfer_last, + + // syncronization for the read side + + axi_last_raddr, + axi_xfer_out, + + // axi write address, write data and write response channels + + axi_clk, + axi_resetn, + axi_awvalid, + axi_awid, + axi_awburst, + axi_awlock, + axi_awcache, + axi_awprot, + axi_awqos, + axi_awuser, + axi_awlen, + axi_awsize, + axi_awaddr, + axi_awready, + axi_wvalid, + axi_wdata, + axi_wstrb, + axi_wlast, + axi_wuser, + axi_wready, + axi_bvalid, + axi_bid, + axi_bresp, + axi_buser, + axi_bready, + + axi_werror); + + // parameters + + parameter AXI_DATA_WIDTH = 512; + parameter DMA_DATA_WIDTH = 64; + parameter AXI_SIZE = 2; + parameter AXI_LENGTH = 15; + parameter AXI_ADDRESS = 32'h00000000; + parameter AXI_ADDRESS_LIMIT = 32'h00000000; + + // for the syncronization buffer + + localparam MEM_RATIO = AXI_DATA_WIDTH/DMA_DATA_WIDTH; + localparam DMA_MADDRESS_WIDTH = 8; + localparam AXI_MADDRESS_WIDTH = (MEM_RATIO == 1) ? DMA_MADDRESS_WIDTH : + (MEM_RATIO == 2) ? (DMA_MADDRESS_WIDTH - 1) : + (MEM_RATIO == 4) ? (DMA_MADDRESS_WIDTH - 2) : + (DMA_MADDRESS_WIDTH - 3); + + // for the AXI interface + + localparam AXI_BYTE_WIDTH = AXI_DATA_WIDTH/8; + localparam AXI_AWINCR = (AXI_LENGTH + 1) * AXI_BYTE_WIDTH; + + // dma fifo interface + + input dma_clk; + input dma_rst; + input [(DMA_DATA_WIDTH-1):0] dma_data; + output dma_ready; + input dma_valid; + + input dma_xfer_req; + input dma_xfer_last; + + output [31:0] axi_last_raddr; + output axi_xfer_out; + + // axi interface + + input axi_clk; + input axi_resetn; + output axi_awvalid; + output [ 3:0] axi_awid; + output [ 1:0] axi_awburst; + output axi_awlock; + output [ 3:0] axi_awcache; + output [ 2:0] axi_awprot; + output [ 3:0] axi_awqos; + output [ 3:0] axi_awuser; + output [ 7:0] axi_awlen; + output [ 2:0] axi_awsize; + output [31:0] axi_awaddr; + input axi_awready; + output axi_wvalid; + output [(AXI_DATA_WIDTH-1):0] axi_wdata; + output [(AXI_BYTE_WIDTH-1):0] axi_wstrb; + output axi_wlast; + output [ 3:0] axi_wuser; + input axi_wready; + input axi_bvalid; + input [ 3:0] axi_bid; + input [ 1:0] axi_bresp; + input [ 3:0] axi_buser; + output axi_bready; + + output axi_werror; + + // internal register + + reg [(DMA_MADDRESS_WIDTH-1):0] dma_mem_waddr = 'd0; + reg [(DMA_MADDRESS_WIDTH-1):0] dma_mem_waddr_g = 'd0; + reg [(DMA_MADDRESS_WIDTH-1):0] dma_mem_addr_diff = 'd0; + reg [(AXI_MADDRESS_WIDTH-1):0] dma_mem_raddr_m1 = 'd0; + reg [(AXI_MADDRESS_WIDTH-1):0] dma_mem_raddr_m2 = 'd0; + reg [(AXI_MADDRESS_WIDTH-1):0] dma_mem_raddr = 'd0; + reg dma_ready = 'd0; + + reg [ 2:0] axi_xfer_req_m = 3'b0; + reg [ 2:0] axi_xfer_last_m = 3'b0; + reg [(DMA_MADDRESS_WIDTH-1):0] axi_mem_waddr_m1 = 'b0; + reg [(DMA_MADDRESS_WIDTH-1):0] axi_mem_waddr_m2 = 'b0; + reg [(DMA_MADDRESS_WIDTH-1):0] axi_mem_waddr = 'b0; + reg axi_mem_ready = 'b0; + reg axi_mem_ready_d = 'b0; + reg [(AXI_DATA_WIDTH-1):0] axi_mem_rdata_d = 'b0; + reg [(AXI_MADDRESS_WIDTH-1):0] axi_mem_raddr = 'd0; + reg [(AXI_MADDRESS_WIDTH-1):0] axi_mem_raddr_g = 'd0; + + reg axi_reset = 1'b0; + reg axi_xfer_out = 1'b0; + reg [31:0] axi_last_raddr = 'b0; + reg axi_awvalid = 1'b0; + reg [31:0] axi_awaddr = 32'b0; + reg axi_xfer_init = 1'b0; + reg axi_werror = 1'b0; + reg axi_mem_last = 1'b0; + reg axi_mem_last_d = 1'b0; + reg [ 3:0] axi_wvalid_cntr = 4'b0; + + // internal signal + + wire [(DMA_MADDRESS_WIDTH-1):0] dma_mem_addr_diff_s; + wire [(DMA_MADDRESS_WIDTH-1):0] dma_mem_raddr_s; + wire [(DMA_MADDRESS_WIDTH-1):0] axi_mem_waddr_s; + wire axi_req_s; + wire [(AXI_DATA_WIDTH-1):0] axi_mem_rdata_s; + wire axi_wready_s; + wire axi_mem_last_s; + + // binary to grey conversion + + function [7:0] b2g; + input [7:0] b; + reg [7:0] g; + begin + g[7] = b[7]; + g[6] = b[7] ^ b[6]; + g[5] = b[6] ^ b[5]; + g[4] = b[5] ^ b[4]; + g[3] = b[4] ^ b[3]; + g[2] = b[3] ^ b[2]; + g[1] = b[2] ^ b[1]; + g[0] = b[1] ^ b[0]; + b2g = g; + end + endfunction + + // grey to binary conversion + + function [7:0] g2b; + input [7:0] g; + reg [7:0] b; + begin + b[7] = g[7]; + b[6] = b[7] ^ g[6]; + b[5] = b[6] ^ g[5]; + b[4] = b[5] ^ g[4]; + b[3] = b[4] ^ g[3]; + b[2] = b[3] ^ g[2]; + b[1] = b[2] ^ g[1]; + b[0] = b[1] ^ g[0]; + g2b = b; + end + endfunction + + // write address generation for the asymetric memory + + always @(posedge dma_clk) begin + if (dma_rst == 1'b1) begin + dma_mem_waddr <= 8'h0; + dma_mem_waddr_g <= 8'h0; + end else begin + if ((dma_ready == 1'b1) && (dma_valid == 1'b1)) begin + dma_mem_waddr <= dma_mem_waddr + 1; + end + dma_mem_waddr_g <= b2g(dma_mem_waddr); + end + end + + assign dma_mem_addr_diff_s = {1'b1, dma_mem_waddr} - dma_mem_raddr_s; + assign dma_mem_raddr_s = (MEM_RATIO == 1) ? dma_mem_raddr : + (MEM_RATIO == 2) ? {dma_mem_raddr, 1'b0} : + (MEM_RATIO == 4) ? {dma_mem_raddr, 2'b0} : + {dma_mem_raddr, 3'b0}; + + always @(posedge dma_clk) begin + if (dma_rst == 1'b1) begin + dma_mem_addr_diff <= 'b0; + dma_mem_raddr_m1 <= 'b0; + dma_mem_raddr_m2 <= 'b0; + dma_mem_raddr <= 'b0; + end else begin + dma_mem_raddr_m1 <= g2b(axi_mem_raddr_g); + dma_mem_raddr_m2 <= dma_mem_raddr_m1; + dma_mem_raddr <= dma_mem_raddr_m2; + dma_mem_addr_diff <= dma_mem_addr_diff_s[DMA_MADDRESS_WIDTH-1:0]; + if (dma_mem_addr_diff >= 180) begin + dma_ready <= 1'b0; + end else begin + dma_ready <= 1'b1; + end + end + end + + // read address generation for the asymetric memory + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_xfer_req_m <= 3'b0; + axi_xfer_last_m <= 3'b0; + axi_mem_waddr_m1 <= 'b0; + axi_mem_waddr_m2 <= 'b0; + axi_mem_waddr <= 'b0; + axi_xfer_init <= 1'b0; + end else begin + axi_xfer_req_m <= {axi_xfer_req_m[1:0], dma_xfer_req}; + axi_xfer_last_m <= {axi_xfer_last_m[1:0], dma_xfer_last}; + axi_mem_waddr_m1 <= g2b(dma_mem_waddr_g); + axi_mem_waddr_m2 <= axi_mem_waddr_m1; + axi_mem_waddr <= axi_mem_waddr_m2; + axi_xfer_init = ~axi_xfer_req_m[2] & axi_xfer_req_m[1]; + end + end + + assign axi_wready_s = ~axi_wvalid | axi_wready; + assign axi_mem_ready_s = (axi_mem_raddr == axi_mem_waddr_s) ? 1'b0 : axi_wready_s; + assign axi_req_s = (axi_mem_raddr[1:0] == 2'h0) ? axi_mem_ready_s : 1'b0; + assign axi_mem_last_s = (axi_wvalid_cntr == AXI_LENGTH) ? axi_mem_ready_s : 1'b0; + assign axi_mem_waddr_s = (MEM_RATIO == 1) ? axi_mem_waddr : + (MEM_RATIO == 2) ? axi_mem_waddr[(DMA_MADDRESS_WIDTH-1):1] : + (MEM_RATIO == 4) ? axi_mem_waddr[(DMA_MADDRESS_WIDTH-1):2] : + axi_mem_waddr[(DMA_MADDRESS_WIDTH-1):3]; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_mem_ready <= 1'b0; + axi_mem_ready_d <= 1'b0; + axi_mem_rdata_d <= 'b0; + axi_mem_raddr <= 'b0; + axi_wvalid_cntr <= 4'b0; + end else begin + axi_mem_ready <= axi_mem_ready_s; + axi_mem_last <= axi_mem_last_s; + axi_mem_last_d <= axi_mem_last; + axi_mem_ready_d <= axi_mem_ready; + axi_mem_rdata_d <= axi_mem_rdata_s; + if (axi_mem_ready_s == 1'b1) begin + axi_mem_raddr <= axi_mem_raddr + 1; + axi_wvalid_cntr <= (axi_wvalid_cntr == AXI_LENGTH) ? 4'b0 : axi_wvalid_cntr + 1; + end + axi_mem_raddr_g <= b2g(axi_mem_raddr); + end + end + + // write address generation for AXI MEMORY MAP interface + + // address channel + + assign axi_awid = 4'b0000; + assign axi_awburst = 2'b01; + assign axi_awlock = 1'b0; + assign axi_awcache = 4'b0010; + assign axi_awprot = 3'b000; + assign axi_awqos = 4'b0000; + assign axi_awuser = 4'b0001; + assign axi_awlen = AXI_LENGTH; + assign axi_awsize = AXI_SIZE; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_awvalid <= 'd0; + axi_awaddr <= AXI_ADDRESS; + axi_last_raddr <= AXI_ADDRESS; + axi_xfer_out <= 1'b0; + end else begin + if (axi_awvalid == 1'b1) begin + if (axi_awready == 1'b1) begin + axi_awvalid <= 1'b0; + end + end else begin + if (axi_req_s == 1'b1) begin + axi_awvalid <= 1'b1; + end + end + if (axi_xfer_init == 1'b1) begin + axi_awaddr <= (axi_xfer_out == 1'b1) ? AXI_ADDRESS : axi_last_raddr; + axi_xfer_out <= 1'b0; + end else if ((axi_awvalid == 1'b1) && (axi_awready == 1'b1)) begin + axi_awaddr <= axi_awaddr + AXI_AWINCR; + end + if(axi_xfer_last_m[2] == 1) begin + axi_last_raddr <= axi_awaddr; + axi_xfer_out <= 1'b1; + end + end + end + + // write channel + + assign axi_wstrb = {AXI_BYTE_WIDTH{1'b1}}; + assign axi_wuser = 4'b0000; + + // response channel + + assign axi_bready = 1'b1; + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_werror <= 'd0; + end else begin + axi_werror <= axi_bvalid & axi_bresp[1]; + end + end + + // fifo needs a reset + + always @(posedge axi_clk) begin + if (axi_resetn == 1'b0) begin + axi_reset <= 1'b1; + end else begin + axi_reset <= 1'b0; + end + end + + // instantiations + + ad_mem_asym #( + .A_ADDRESS_WIDTH (DMA_MADDRESS_WIDTH), + .A_DATA_WIDTH (DMA_DATA_WIDTH), + .B_ADDRESS_WIDTH (AXI_MADDRESS_WIDTH), + .B_DATA_WIDTH (AXI_DATA_WIDTH)) + i_mem_asym ( + .clka (dma_clk), + .wea (dma_valid), + .addra (dma_mem_waddr), + .dina (dma_data), + .clkb (axi_clk), + .addrb (axi_mem_raddr), + .doutb (axi_mem_rdata_s)); + + ad_axis_inf_rx #(.DATA_WIDTH(AXI_DATA_WIDTH)) i_axis_inf ( + .clk (axi_clk), + .rst (axi_reset), + .valid (axi_mem_ready_d), + .last (axi_mem_last_d), + .data (axi_mem_rdata_d), + .inf_valid (axi_wvalid), + .inf_last (axi_wlast), + .inf_data (axi_wdata), + .inf_ready (axi_wready)); + +endmodule +