From f73819f4d4c22ea7f6233991451cc82e8c079dec Mon Sep 17 00:00:00 2001 From: Rejeesh Kutty Date: Tue, 13 May 2014 16:19:53 -0400 Subject: [PATCH] zc706: pl ddr3 initial checkin --- library/axi_fifo2s/axi_fifo2s.v | 266 ++++++++++ library/axi_fifo2s/axi_fifo2s_ip.tcl | 21 + library/axi_fifo2s/axi_fifo2s_rd.v | 317 ++++++++++++ library/axi_fifo2s/axi_fifo2s_wr.v | 469 ++++++++++++++++++ projects/common/zc706/zc706_system_plddr3.tcl | 7 + 5 files changed, 1080 insertions(+) create mode 100755 library/axi_fifo2s/axi_fifo2s.v create mode 100644 library/axi_fifo2s/axi_fifo2s_ip.tcl create mode 100755 library/axi_fifo2s/axi_fifo2s_rd.v create mode 100755 library/axi_fifo2s/axi_fifo2s_wr.v create mode 100644 projects/common/zc706/zc706_system_plddr3.tcl diff --git a/library/axi_fifo2s/axi_fifo2s.v b/library/axi_fifo2s/axi_fifo2s.v new file mode 100755 index 000000000..1dec6ce66 --- /dev/null +++ b/library/axi_fifo2s/axi_fifo2s.v @@ -0,0 +1,266 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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_fifo2s ( + + // fifo interface + + m_rst, + m_clk, + m_wr, + m_wdata, + m_wovf, + + axi_mwr, + axi_mwdata, + axi_mwovf, + axi_mwpfull, + + // 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, + + // transfer request + + axi_xfer_req); + + // parameters + + parameter DATA_WIDTH = 32; + parameter AXI_SIZE = 2; + parameter AXI_LENGTH = 16; + parameter AXI_ADDRESS = 32'h00000000; + + // fifo interface + + input m_rst; + input m_clk; + input m_wr; + input [DATA_WIDTH-1:0] m_wdata; + output m_wovf; + + output axi_mwr; + output [DATA_WIDTH-1:0] axi_mwdata; + input axi_mwovf; + input axi_mwpfull; + + // 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 [DATA_WIDTH-1:0] axi_wdata; + output [(DATA_WIDTH/8)-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 [DATA_WIDTH-1:0] axi_rdata; + output axi_rready; + + // transfer request + + input axi_xfer_req; + + // internal signals + + wire axi_rd_req_s; + wire [ 31:0] axi_rd_addr_s; + wire axi_rd_status_s; + + // instantiations + + axi_fifo2s_wr #( + .DATA_WIDTH (DATA_WIDTH), + .AXI_SIZE (AXI_SIZE), + .AXI_LENGTH (AXI_LENGTH), + .AXI_ADDRESS (AXI_ADDRESS)) + i_wr ( + .axi_xfer_req (axi_xfer_req), + .axi_rd_req (axi_rd_req_s), + .axi_rd_addr (axi_rd_addr_s), + .axi_rd_status (axi_rd_status_s), + .m_rst (m_rst), + .m_clk (m_clk), + .m_wr (m_wr), + .m_wdata (m_wdata), + .m_wovf (m_wovf), + .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_fifo2s_rd #( + .DATA_WIDTH (DATA_WIDTH), + .AXI_SIZE (AXI_SIZE), + .AXI_LENGTH (AXI_LENGTH)) + i_rd ( + .axi_xfer_req (axi_xfer_req), + .axi_rd_req (axi_rd_req_s), + .axi_rd_addr (axi_rd_addr_s), + .axi_rd_status (axi_rd_status_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_mwr (axi_mwr), + .axi_mwdata (axi_mwdata), + .axi_mwovf (axi_mwovf), + .axi_mwpfull (axi_mwpfull)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_fifo2s/axi_fifo2s_ip.tcl b/library/axi_fifo2s/axi_fifo2s_ip.tcl new file mode 100644 index 000000000..ac36b3889 --- /dev/null +++ b/library/axi_fifo2s/axi_fifo2s_ip.tcl @@ -0,0 +1,21 @@ +# ip + +source ../scripts/adi_env.tcl +source $ad_hdl_dir/library/scripts/adi_ip.tcl + +adi_ip_create axi_fifo2s +adi_ip_files axi_fifo2s [list \ + "$ad_hdl_dir/library/common/ad_mem.v" \ + "$ad_hdl_dir/library/common/ad_axis_inf_rx.v" \ + "axi_fifo2s_wr.v" \ + "axi_fifo2s_rd.v" \ + "axi_fifo2s.v" ] + +adi_ip_properties_lite axi_fifo2s + +ipx::remove_bus_interface {m} [ipx::current_core] +ipx::remove_bus_interface {m_signal_clock} [ipx::current_core] +ipx::remove_memory_map {m} [ipx::current_core] + +ipx::save_core [ipx::current_core] + diff --git a/library/axi_fifo2s/axi_fifo2s_rd.v b/library/axi_fifo2s/axi_fifo2s_rd.v new file mode 100755 index 000000000..a7e410064 --- /dev/null +++ b/library/axi_fifo2s/axi_fifo2s_rd.v @@ -0,0 +1,317 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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_fifo2s_rd ( + + // request and synchronization + + axi_xfer_req, + axi_rd_req, + axi_rd_addr, + axi_rd_status, + + // axi interface + + 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, + + // fifo interface + + axi_mwr, + axi_mwdata, + axi_mwovf, + axi_mwpfull); + + // parameters + + parameter DATA_WIDTH = 32; + parameter AXI_SIZE = 2; + parameter AXI_LENGTH = 16; + localparam BUF_THRESHOLD_LO = 6'd3; + localparam BUF_THRESHOLD_HI = 6'd60; + + // request and synchronization + + input axi_xfer_req; + input axi_rd_req; + input [ 31:0] axi_rd_addr; + output axi_rd_status; + + // 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 [DATA_WIDTH-1:0] axi_rdata; + output axi_rready; + + // fifo interface + + output axi_mwr; + output [DATA_WIDTH-1:0] axi_mwdata; + input axi_mwovf; + input axi_mwpfull; + + // internal registers + + reg [ 5:0] axi_waddr = 'd0; + reg [ 5:0] axi_raddr = 'd0; + reg axi_rd = 'd0; + reg axi_rd_d = 'd0; + reg [ 31:0] axi_rdata_d = 'd0; + reg [ 5:0] axi_addr_diff = 'd0; + reg axi_almost_full = 'd0; + reg axi_unf = 'd0; + reg axi_almost_empty = 'd0; + reg axi_ovf = 'd0; + reg axi_arerror = 'd0; + reg axi_arvalid = 'd0; + reg [ 31:0] axi_araddr = 'd0; + reg axi_mwr = 'd0; + reg [DATA_WIDTH-1:0] axi_mwdata = 'd0; + reg axi_rready = 'd0; + reg axi_rerror = 'd0; + reg axi_reset = 'd0; + reg axi_rd_status = 'd0; + + // internal signals + + wire axi_wr_s; + wire [ 31:0] axi_wdata_s; + wire axi_arready_s; + wire axi_fifo_ready_s; + wire axi_rd_s; + wire [ 6:0] axi_addr_diff_s; + wire [ 31:0] axi_rdata_s; + + // queue requests + + assign axi_wr_s = axi_rd_req; + assign axi_wdata_s = axi_rd_addr; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_waddr <= 'd0; + end else begin + if (axi_wr_s == 1'b1) begin + axi_waddr <= axi_waddr + 1'b1; + end + end + end + + // read queue + + assign axi_arready_s = ~axi_arvalid | axi_arready; + assign axi_fifo_ready_s = ~axi_xfer_req | ~axi_mwpfull; + assign axi_rd_s = (axi_waddr == axi_raddr) ? 1'b0 : (axi_arready_s & axi_fifo_ready_s); + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_raddr <= 'd0; + axi_rd <= 'd0; + axi_rd_d <= 'd0; + axi_rdata_d <= 'd0; + end else begin + if (axi_rd_s == 1'b1) begin + axi_raddr <= axi_raddr + 1'b1; + end + axi_rd <= axi_rd_s; + axi_rd_d <= axi_rd; + axi_rdata_d <= axi_rdata_s; + end + end + + // overflow (no underflow possible) + + assign axi_addr_diff_s = {1'b1, axi_waddr} - axi_raddr; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_addr_diff <= 'd0; + axi_almost_full <= 'd0; + axi_unf <= 'd0; + axi_almost_empty <= 'd0; + axi_ovf <= 'd0; + end else begin + axi_addr_diff <= axi_addr_diff_s[5:0]; + if (axi_addr_diff > BUF_THRESHOLD_HI) begin + axi_almost_full <= 1'b1; + axi_unf <= axi_almost_empty; + end else begin + axi_almost_full <= 1'b0; + axi_unf <= 1'b0; + end + if (axi_addr_diff < BUF_THRESHOLD_LO) begin + axi_almost_empty <= 1'b1; + axi_ovf <= axi_almost_full; + end else begin + axi_almost_empty <= 1'b0; + axi_ovf <= 1'b0; + end + end + end + + // 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 - 1; + assign axi_arsize = AXI_SIZE; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_arerror <= 'd0; + axi_arvalid <= 'd0; + axi_araddr <= 'd0; + end else begin + axi_arerror <= axi_rd_d & axi_arvalid; + if (axi_arvalid == 1'b1) begin + if (axi_arready == 1'b1) begin + axi_arvalid <= 1'b0; + end + end else begin + if (axi_rd_d == 1'b1) begin + axi_arvalid <= 1'b1; + end + end + if ((axi_rd_d == 1'b1) && (axi_arvalid == 1'b0)) begin + axi_araddr <= axi_rdata_d; + end + end + end + + // read data channel + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_mwr <= 'd0; + axi_mwdata <= 'd0; + axi_rready <= 'd0; + end else begin + axi_mwr <= axi_rvalid & axi_rready; + axi_mwdata <= axi_rdata; + axi_rready <= axi_fifo_ready_s; + end + end + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_rerror <= 'd0; + end else begin + axi_rerror <= axi_rvalid & axi_rready & axi_rresp[1]; + end + end + + // fifo needs a reset + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_reset <= 1'b1; + end else begin + axi_reset <= 1'b0; + end + end + + // combined status + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_rd_status <= 'd0; + end else begin + axi_rd_status <= axi_mwovf | axi_ovf | axi_unf | axi_arerror | axi_rerror; + end + end + + // buffer + + ad_mem #(.DATA_WIDTH(32), .ADDR_WIDTH(6)) i_mem ( + .clka (axi_clk), + .wea (axi_wr_s), + .addra (axi_waddr), + .dina (axi_wdata_s), + .clkb (axi_clk), + .addrb (axi_raddr), + .doutb (axi_rdata_s)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_fifo2s/axi_fifo2s_wr.v b/library/axi_fifo2s/axi_fifo2s_wr.v new file mode 100755 index 000000000..504fa0138 --- /dev/null +++ b/library/axi_fifo2s/axi_fifo2s_wr.v @@ -0,0 +1,469 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2011(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_fifo2s_wr ( + + // request and synchronization + + axi_xfer_req, + axi_rd_req, + axi_rd_addr, + axi_rd_status, + + // fifo interface + + m_rst, + m_clk, + m_wr, + m_wdata, + m_wovf, + + // 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); + + // parameters + + parameter DATA_WIDTH = 32; + parameter AXI_SIZE = 2; + parameter AXI_LENGTH = 16; + parameter AXI_ADDRESS = 32'h00000000; + localparam AXI_AWINCR = (AXI_LENGTH * DATA_WIDTH)/8; + localparam BUF_THRESHOLD_LO = 6'd3; + localparam BUF_THRESHOLD_HI = 6'd60; + + // request and synchronization + + input axi_xfer_req; + output axi_rd_req; + output [ 31:0] axi_rd_addr; + input axi_rd_status; + + // fifo interface + + input m_rst; + input m_clk; + input m_wr; + input [DATA_WIDTH-1:0] m_wdata; + output m_wovf; + + // 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 [DATA_WIDTH-1:0] axi_wdata; + output [(DATA_WIDTH/8)-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; + + // internal registers + + reg [ 5:0] m_waddr = 'd0; + reg [ 5:0] m_waddr_g = 'd0; + reg m_rel_enable = 'd0; + reg m_rel_toggle = 'd0; + reg [ 5:0] m_rel_waddr = 'd0; + reg [ 2:0] m_status_m = 'd0; + reg m_wovf = 'd0; + reg [ 2:0] axi_rel_toggle_m = 'd0; + reg [ 5:0] axi_rel_waddr = 'd0; + reg [ 5:0] axi_waddr_m1 = 'd0; + reg [ 5:0] axi_waddr_m2 = 'd0; + reg [ 5:0] axi_waddr = 'd0; + reg [ 5:0] axi_addr_diff = 'd0; + reg axi_almost_full = 'd0; + reg axi_unf = 'd0; + reg axi_almost_empty = 'd0; + reg axi_ovf = 'd0; + reg [ 2:0] axi_xfer_enable_m = 'd0; + reg axi_xfer_enable = 'd0; + reg [ 5:0] axi_raddr = 'd0; + reg axi_rd = 'd0; + reg axi_rlast = 'd0; + reg axi_rd_d = 'd0; + reg axi_rlast_d = 'd0; + reg [DATA_WIDTH-1:0] axi_rdata_d = 'd0; + reg axi_rd_req = 'd0; + reg [ 31:0] axi_rd_addr = 'd0; + reg axi_awerror = 'd0; + reg axi_awvalid = 'd0; + reg [ 31:0] axi_awaddr = 'd0; + reg axi_werror = 'd0; + reg axi_reset = 'd0; + reg [ 4:0] axi_status_cnt = 'd0; + reg axi_status = 'd0; + + // internal signals + + wire axi_rel_toggle_s; + wire [ 6:0] axi_addr_diff_s; + wire axi_wready_s; + wire axi_rd_s; + wire axi_req_s; + wire axi_rlast_s; + wire axi_status_s; + wire [DATA_WIDTH-1:0] axi_rdata_s; + + // binary to grey conversion + + function [5:0] b2g; + input [5:0] b; + reg [5:0] g; + begin + g[5] = 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 [5:0] g2b; + input [5:0] g; + reg [5:0] b; + begin + b[5] = 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 + + // fifo interface + + always @(posedge m_clk) begin + if (m_rst == 1'b1) begin + m_waddr <= 'd0; + m_waddr_g <= 'd0; + m_rel_enable <= 'd0; + m_rel_toggle <= 'd0; + m_rel_waddr <= 'd0; + m_status_m <= 'd0; + m_wovf <= 'd0; + end else begin + if (m_wr == 1'b1) begin + m_waddr <= m_waddr + 1'b1; + end + m_waddr_g <= b2g(m_waddr); + if (m_waddr[1:0] == 2'h3) begin + m_rel_enable <= m_wr; + end else begin + m_rel_enable <= 1'd0; + end + if (m_rel_enable == 1'b1) begin + m_rel_toggle <= ~m_rel_toggle; + m_rel_waddr <= m_waddr; + end + m_status_m <= {m_status_m[1:0], axi_status}; + m_wovf <= m_status_m[2]; + end + end + + // fifo signals on axi side + + assign axi_rel_toggle_s = axi_rel_toggle_m[2] ^ axi_rel_toggle_m[1]; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_rel_toggle_m <= 'd0; + axi_rel_waddr <= 'd0; + axi_waddr_m1 <= 'd0; + axi_waddr_m2 <= 'd0; + axi_waddr <= 'd0; + end else begin + axi_rel_toggle_m <= {axi_rel_toggle_m[1:0], m_rel_toggle}; + if (axi_rel_toggle_s == 1'b1) begin + axi_rel_waddr <= m_rel_waddr; + end + axi_waddr_m1 <= m_waddr_g; + axi_waddr_m2 <= axi_waddr_m1; + axi_waddr <= g2b(axi_waddr_m2); + end + end + + // overflow (no underflow possible) + + assign axi_addr_diff_s = {1'b1, axi_waddr} - axi_raddr; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_addr_diff <= 'd0; + axi_almost_full <= 'd0; + axi_unf <= 'd0; + axi_almost_empty <= 'd0; + axi_ovf <= 'd0; + end else begin + axi_addr_diff <= axi_addr_diff_s[5:0]; + if (axi_addr_diff > BUF_THRESHOLD_HI) begin + axi_almost_full <= 1'b1; + axi_unf <= axi_almost_empty; + end else begin + axi_almost_full <= 1'b0; + axi_unf <= 1'b0; + end + if (axi_addr_diff < BUF_THRESHOLD_LO) begin + axi_almost_empty <= 1'b1; + axi_ovf <= axi_almost_full; + end else begin + axi_almost_empty <= 1'b0; + axi_ovf <= 1'b0; + end + end + end + + // transfer request is required to keep things in sync + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_xfer_enable_m <= 'd0; + axi_xfer_enable <= 'd0; + end else begin + axi_xfer_enable_m <= {axi_xfer_enable_m[1:0], axi_xfer_req}; + if (axi_rel_toggle_s == 1'b1) begin + axi_xfer_enable <= axi_xfer_enable_m[2]; + end + end + end + + // read is initiated if xfer enabled + + assign axi_wready_s = ~axi_wvalid | axi_wready; + assign axi_rd_s = (axi_rel_waddr == axi_raddr) ? 1'b0 : (axi_wready_s & axi_xfer_enable); + assign axi_req_s = (axi_raddr[1:0] == 2'h0) ? axi_rd_s : 1'b0; + assign axi_rlast_s = (axi_raddr[1:0] == 2'h3) ? axi_rd_s : 1'b0; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_raddr <= 'd0; + axi_rd <= 'd0; + axi_rlast <= 'd0; + axi_rd_d <= 'd0; + axi_rlast_d <= 'd0; + axi_rdata_d <= 'd0; + end else begin + if (axi_xfer_enable == 1'b0) begin + axi_raddr <= axi_rel_waddr; + end else if (axi_rd_s == 1'b1) begin + axi_raddr <= axi_raddr + 1'b1; + end + axi_rd <= axi_rd_s; + axi_rlast <= axi_rlast_s; + axi_rd_d <= axi_rd; + axi_rlast_d <= axi_rlast; + axi_rdata_d <= axi_rdata_s; + end + end + + // send read request for every burst about to be completed + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_rd_req <= 'd0; + axi_rd_addr <= 'd0; + end else begin + axi_rd_req <= axi_rlast_s; + if (axi_xfer_enable == 1'b0) begin + axi_rd_addr <= AXI_ADDRESS; + end else if (axi_rd_req == 1'b1) begin + axi_rd_addr <= axi_rd_addr + AXI_AWINCR; + end + end + end + + // 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 - 1; + assign axi_awsize = AXI_SIZE; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_awerror <= 'd0; + axi_awvalid <= 'd0; + axi_awaddr <= 'd0; + end else begin + axi_awerror <= axi_req_s & axi_awvalid; + 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_enable == 1'b0) begin + axi_awaddr <= AXI_ADDRESS; + end else if ((axi_awvalid == 1'b1) && (axi_awready == 1'b1)) begin + axi_awaddr <= axi_awaddr + AXI_AWINCR; + end + end + end + + // write channel + + assign axi_wstrb = {(DATA_WIDTH/8){1'b1}}; + assign axi_wuser = 4'b0000; + + // response channel + + assign axi_bready = 1'b1; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_werror <= 'd0; + end else begin + axi_werror <= axi_bvalid & axi_bready & axi_bresp[1]; + end + end + + // fifo needs a reset + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_reset <= 1'b1; + end else begin + axi_reset <= 1'b0; + end + end + + // combined status + + assign axi_status_s = axi_ovf | axi_unf | axi_awerror | axi_werror | axi_rd_status; + + always @(posedge axi_clk or negedge axi_resetn) begin + if (axi_resetn == 1'b0) begin + axi_status_cnt <= 'd0; + axi_status <= 'd0; + end else begin + if (axi_status_s == 1'b1) begin + axi_status_cnt <= 5'h1f; + end else if (axi_status_cnt[4] == 1'b1) begin + axi_status_cnt <= axi_status_cnt + 1'b1; + end + axi_status <= axi_status_cnt[4]; + end + end + + // interface handler + + ad_axis_inf_rx #(.DATA_WIDTH(DATA_WIDTH)) i_axis_inf ( + .clk (axi_clk), + .rst (axi_reset), + .valid (axi_rd_d), + .last (axi_rlast_d), + .data (axi_rdata_d), + .inf_valid (axi_wvalid), + .inf_last (axi_wlast), + .inf_data (axi_wdata), + .inf_ready (axi_wready)); + + // buffer + + ad_mem #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(6)) i_mem ( + .clka (m_clk), + .wea (m_wr), + .addra (m_waddr), + .dina (m_wdata), + .clkb (axi_clk), + .addrb (axi_raddr), + .doutb (axi_rdata_s)); + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/projects/common/zc706/zc706_system_plddr3.tcl b/projects/common/zc706/zc706_system_plddr3.tcl new file mode 100644 index 000000000..29c9ff5be --- /dev/null +++ b/projects/common/zc706/zc706_system_plddr3.tcl @@ -0,0 +1,7 @@ + +# pl ddr3 (use only when dma is not capable of keeping up) + +set axi_plddr3 [create_bd_cell -type ip -vlnv xilinx.com:ip:mig_7series:2.0 axi_plddr3] +set_property -dict [list CONFIG.XML_INPUT_FILE {kc705_system_mig.prj}] $axi_plddr3 + +