aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/n3xx/sim/dram_fifo
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/n3xx/sim/dram_fifo')
-rw-r--r--fpga/usrp3/top/n3xx/sim/dram_fifo/Makefile70
-rw-r--r--fpga/usrp3/top/n3xx/sim/dram_fifo/axis_dram_fifo_single.sv493
-rw-r--r--fpga/usrp3/top/n3xx/sim/dram_fifo/dram_fifo_tb.sv163
3 files changed, 726 insertions, 0 deletions
diff --git a/fpga/usrp3/top/n3xx/sim/dram_fifo/Makefile b/fpga/usrp3/top/n3xx/sim/dram_fifo/Makefile
new file mode 100644
index 000000000..738cb12dc
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/sim/dram_fifo/Makefile
@@ -0,0 +1,70 @@
+#
+# Copyright 2015 Ettus Research LLC
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../..)
+# Include viv_sim_preample after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Design Specific
+#-------------------------------------------------
+# Define part using PART_ID (<device>/<package>/<speedgrade>)
+ARCH = zynq
+PART_ID = xc7z100/ffg900/-2
+
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+include $(BASE_DIR)/../lib/axi/Makefile.srcs
+include $(BASE_DIR)/../lib/control/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(FIFO_SRCS) \
+$(AXI_SRCS) \
+$(CONTROL_LIB_SRCS) \
+)
+
+#-------------------------------------------------
+# IP Specific
+#-------------------------------------------------
+# If simulation contains IP, define the IP_DIR and point
+# it to the base level IP directory
+IP_DIR = ../../ip
+
+# Include makefiles and sources for all IP components
+# *after* defining the IP_DIR
+include $(IP_DIR)/ddr3_32bit/Makefile.inc
+include $(IP_DIR)/axi_intercon_4x64_256_bd/Makefile.inc
+include $(IP_DIR)/fifo_short_2clk/Makefile.inc
+include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+
+DESIGN_SRCS += $(abspath \
+$(IP_DDR3_32BIT_SRCS) \
+$(IP_AXI_INTERCON_4X64_256_SRCS) \
+$(IP_AXI_INTERCON_4X64_256_BD_SRCS) \
+$(IP_FIFO_4K_2CLK_SRCS) \
+$(IP_FIFO_SHORT_2CLK_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = dram_fifo_tb
+
+SIM_SRCS = \
+$(abspath dram_fifo_tb.sv) \
+$(abspath axis_dram_fifo_single.sv) \
+$(IP_DDR3_32BIT_SIM_OUTS)
+
+#-------------------------------------------------
+# Bottom-of-Makefile
+#-------------------------------------------------
+# Include all simulator specific makefiles here
+# Each should define a unique target to simulate
+# e.g. xsim, vsim, etc and a common "clean" target
+include $(BASE_DIR)/../tools/make/viv_simulator.mak
diff --git a/fpga/usrp3/top/n3xx/sim/dram_fifo/axis_dram_fifo_single.sv b/fpga/usrp3/top/n3xx/sim/dram_fifo/axis_dram_fifo_single.sv
new file mode 100644
index 000000000..63bea218e
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/sim/dram_fifo/axis_dram_fifo_single.sv
@@ -0,0 +1,493 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+
+`timescale 1ns/1ps
+
+module axis_dram_fifo_single
+#(
+ parameter DIFF_CLK = 0,
+ parameter SR_BASE = 0
+) (
+ input bus_clk,
+ input bus_rst,
+ input sys_clk_p,
+ input sys_clk_n,
+ input sys_rst_n,
+ input dma_engine_clk,
+
+ input [63:0] i_tdata,
+ input i_tlast,
+ input i_tvalid,
+ output i_tready,
+
+ output [63:0] o_tdata,
+ output o_tlast,
+ output o_tvalid,
+ input o_tready,
+
+ input set_stb,
+ input [7:0] set_addr,
+ input [31:0] set_data,
+ output [31:0] rb_data,
+
+ input [63:0] forced_bit_err,
+
+ output init_calib_complete
+);
+
+ wire ddr3_axi_clk; // 1/4 DDR external clock rate (250MHz)
+ wire ddr3_axi_rst; // Synchronized to ddr_sys_clk
+ reg ddr3_axi_rst_reg_n; // Synchronized to ddr_sys_clk
+
+ // Misc declarations
+ axi4_rd_t #(.DWIDTH(64), .AWIDTH(32), .IDWIDTH(1)) dma_axi_rd(.clk(dma_engine_clk));
+ axi4_wr_t #(.DWIDTH(64), .AWIDTH(32), .IDWIDTH(1)) dma_axi_wr(.clk(dma_engine_clk));
+ axi4_rd_t #(.DWIDTH(256), .AWIDTH(32), .IDWIDTH(4)) mig_axi_rd(.clk(ddr3_axi_clk));
+ axi4_wr_t #(.DWIDTH(256), .AWIDTH(32), .IDWIDTH(4)) mig_axi_wr(.clk(ddr3_axi_clk));
+
+ wire [31:0] ddr3_dq; // Data pins. Input for Reads; Output for Writes.
+ wire [3:0] ddr3_dqs_n; // Data Strobes. Input for Reads; Output for Writes.
+ wire [3:0] ddr3_dqs_p;
+ wire [15:0] ddr3_addr; // Address
+ wire [2:0] ddr3_ba; // Bank Address
+ wire ddr3_ras_n; // Row Address Strobe.
+ wire ddr3_cas_n; // Column address select
+ wire ddr3_we_n; // Write Enable
+ wire ddr3_reset_n; // SDRAM reset pin.
+ wire [0:0] ddr3_ck_p; // Differential clock
+ wire [0:0] ddr3_ck_n;
+ wire [0:0] ddr3_cke; // Clock Enable
+ wire [0:0] ddr3_cs_n; // Chip Select
+ wire [3:0] ddr3_dm; // Data Mask [3] = UDM.U26; [2] = LDM.U26; ...
+ wire [0:0] ddr3_odt; // On-Die termination enable.
+
+ always @(posedge ddr3_axi_clk)
+ ddr3_axi_rst_reg_n <= ~ddr3_axi_rst;
+
+ axi_dma_fifo #(
+ .DEFAULT_BASE(30'h02000000),
+ .DEFAULT_MASK(30'hFF000000),
+ .DEFAULT_TIMEOUT(280),
+ .SR_BASE(SR_BASE),
+ .EXT_BIST(1),
+ .SIMULATION(1)
+ ) axi_dma_fifo_i0 (
+ //
+ // Clocks and reset
+ .bus_clk (bus_clk),
+ .bus_reset (bus_rst),
+ .dram_clk (dma_engine_clk),
+ .dram_reset (ddr3_axi_rst),
+ //
+ // AXI Write address channel
+ .m_axi_awid (dma_axi_wr.addr.id),
+ .m_axi_awaddr (dma_axi_wr.addr.addr),
+ .m_axi_awlen (dma_axi_wr.addr.len),
+ .m_axi_awsize (dma_axi_wr.addr.size),
+ .m_axi_awburst (dma_axi_wr.addr.burst),
+ .m_axi_awlock (dma_axi_wr.addr.lock),
+ .m_axi_awcache (dma_axi_wr.addr.cache),
+ .m_axi_awprot (dma_axi_wr.addr.prot),
+ .m_axi_awqos (dma_axi_wr.addr.qos),
+ .m_axi_awregion (dma_axi_wr.addr.region),
+ .m_axi_awuser (dma_axi_wr.addr.user),
+ .m_axi_awvalid (dma_axi_wr.addr.valid),
+ .m_axi_awready (dma_axi_wr.addr.ready),
+ //
+ // AXI Write data channel.
+ .m_axi_wdata (dma_axi_wr.data.data),
+ .m_axi_wstrb (dma_axi_wr.data.strb),
+ .m_axi_wlast (dma_axi_wr.data.last),
+ .m_axi_wuser (dma_axi_wr.data.user),
+ .m_axi_wvalid (dma_axi_wr.data.valid),
+ .m_axi_wready (dma_axi_wr.data.ready),
+ //
+ // AXI Write response channel signals
+ .m_axi_bid (dma_axi_wr.resp.id),
+ .m_axi_bresp (dma_axi_wr.resp.resp),
+ .m_axi_buser (dma_axi_wr.resp.user),
+ .m_axi_bvalid (dma_axi_wr.resp.valid),
+ .m_axi_bready (dma_axi_wr.resp.ready),
+ //
+ // AXI Read address channel
+ .m_axi_arid (dma_axi_rd.addr.id),
+ .m_axi_araddr (dma_axi_rd.addr.addr),
+ .m_axi_arlen (dma_axi_rd.addr.len),
+ .m_axi_arsize (dma_axi_rd.addr.size),
+ .m_axi_arburst (dma_axi_rd.addr.burst),
+ .m_axi_arlock (dma_axi_rd.addr.lock),
+ .m_axi_arcache (dma_axi_rd.addr.cache),
+ .m_axi_arprot (dma_axi_rd.addr.prot),
+ .m_axi_arqos (dma_axi_rd.addr.qos),
+ .m_axi_arregion (dma_axi_rd.addr.region),
+ .m_axi_aruser (dma_axi_rd.addr.user),
+ .m_axi_arvalid (dma_axi_rd.addr.valid),
+ .m_axi_arready (dma_axi_rd.addr.ready),
+ //
+ // AXI Read data channel
+ .m_axi_rid (dma_axi_rd.data.id),
+ .m_axi_rdata (dma_axi_rd.data.data),
+ .m_axi_rresp (dma_axi_rd.data.resp),
+ .m_axi_rlast (dma_axi_rd.data.last),
+ .m_axi_ruser (dma_axi_rd.data.user),
+ .m_axi_rvalid (dma_axi_rd.data.valid),
+ .m_axi_rready (dma_axi_rd.data.ready),
+ //
+ // CHDR friendly AXI stream input
+ .i_tdata (i_tdata),
+ .i_tlast (i_tlast),
+ .i_tvalid (i_tvalid),
+ .i_tready (i_tready),
+ //
+ // CHDR friendly AXI Stream output
+ .o_tdata (o_tdata),
+ .o_tlast (o_tlast),
+ .o_tvalid (o_tvalid),
+ .o_tready (o_tready),
+ //
+ // Settings
+ .set_stb (set_stb),
+ .set_addr (set_addr),
+ .set_data (set_data),
+ .rb_data (rb_data),
+
+ .debug()
+ );
+
+ //---------------------------------------------------
+ // We use an interconnect to connect to FIFOs.
+ //---------------------------------------------------
+ // Attach to third slave just to validate proper ID handling in interconnect
+
+ axi_intercon_4x64_256_bd_wrapper axi_intercon_i (
+ //
+ .S00_AXI_ACLK (dma_engine_clk), // input S01_AXI_ACLK
+ .S00_AXI_ARESETN (~ddr3_axi_rst), // input S01_AXI_ARESETN
+ .S00_AXI_AWID (0), // input [0 : 0] S01_AXI_AWID
+ .S00_AXI_AWADDR (0), // input [31 : 0] S01_AXI_AWADDR
+ .S00_AXI_AWLEN (0), // input [7 : 0] S01_AXI_AWLEN
+ .S00_AXI_AWSIZE (0), // input [2 : 0] S01_AXI_AWSIZE
+ .S00_AXI_AWBURST (0), // input [1 : 0] S01_AXI_AWBURST
+ .S00_AXI_AWLOCK (0), // input S01_AXI_AWLOCK
+ .S00_AXI_AWCACHE (0), // input [3 : 0] S01_AXI_AWCACHE
+ .S00_AXI_AWPROT (0), // input [2 : 0] S01_AXI_AWPROT
+ .S00_AXI_AWQOS (0), // input [3 : 0] S01_AXI_AWQOS
+ .S00_AXI_AWVALID (0), // input S01_AXI_AWVALID
+ .S00_AXI_AWREADY (), // output S01_AXI_AWREADY
+ .S00_AXI_WDATA (0), // input [63 : 0] S01_AXI_WDATA
+ .S00_AXI_WSTRB (0), // input [7 : 0] S01_AXI_WSTRB
+ .S00_AXI_WLAST (0), // input S01_AXI_WLAST
+ .S00_AXI_WVALID (0), // input S01_AXI_WVALID
+ .S00_AXI_WREADY (), // output S01_AXI_WREADY
+ .S00_AXI_BID (), // output [0 : 0] S01_AXI_BID
+ .S00_AXI_BRESP (), // output [1 : 0] S01_AXI_BRESP
+ .S00_AXI_BVALID (), // output S01_AXI_BVALID
+ .S00_AXI_BREADY (1), // input S01_AXI_BREADY
+ .S00_AXI_ARID (0), // input [0 : 0] S01_AXI_ARID
+ .S00_AXI_ARADDR (0), // input [31 : 0] S01_AXI_ARADDR
+ .S00_AXI_ARLEN (0), // input [7 : 0] S01_AXI_ARLEN
+ .S00_AXI_ARSIZE (0), // input [2 : 0] S01_AXI_ARSIZE
+ .S00_AXI_ARBURST (0), // input [1 : 0] S01_AXI_ARBURST
+ .S00_AXI_ARLOCK (0), // input S01_AXI_ARLOCK
+ .S00_AXI_ARCACHE (0), // input [3 : 0] S01_AXI_ARCACHE
+ .S00_AXI_ARPROT (0), // input [2 : 0] S01_AXI_ARPROT
+ .S00_AXI_ARQOS (0), // input [3 : 0] S01_AXI_ARQOS
+ .S00_AXI_ARVALID (0), // input S01_AXI_ARVALID
+ .S00_AXI_ARREADY (), // output S01_AXI_ARREADY
+ .S00_AXI_RID (), // output [0 : 0] S01_AXI_RID
+ .S00_AXI_RDATA (), // output [63 : 0] S01_AXI_RDATA
+ .S00_AXI_RRESP (), // output [1 : 0] S01_AXI_RRESP
+ .S00_AXI_RLAST (), // output S01_AXI_RLAST
+ .S00_AXI_RVALID (), // output S01_AXI_RVALID
+ .S00_AXI_RREADY (1), // input S01_AXI_RREADY
+ //
+ .S01_AXI_ACLK (dma_engine_clk), // input S01_AXI_ACLK
+ .S01_AXI_ARESETN (~ddr3_axi_rst), // input S01_AXI_ARESETN
+ .S01_AXI_AWID (0), // input [0 : 0] S01_AXI_AWID
+ .S01_AXI_AWADDR (0), // input [31 : 0] S01_AXI_AWADDR
+ .S01_AXI_AWLEN (0), // input [7 : 0] S01_AXI_AWLEN
+ .S01_AXI_AWSIZE (0), // input [2 : 0] S01_AXI_AWSIZE
+ .S01_AXI_AWBURST (0), // input [1 : 0] S01_AXI_AWBURST
+ .S01_AXI_AWLOCK (0), // input S01_AXI_AWLOCK
+ .S01_AXI_AWCACHE (0), // input [3 : 0] S01_AXI_AWCACHE
+ .S01_AXI_AWPROT (0), // input [2 : 0] S01_AXI_AWPROT
+ .S01_AXI_AWQOS (0), // input [3 : 0] S01_AXI_AWQOS
+ .S01_AXI_AWVALID (0), // input S01_AXI_AWVALID
+ .S01_AXI_AWREADY (), // output S01_AXI_AWREADY
+ .S01_AXI_WDATA (0), // input [63 : 0] S01_AXI_WDATA
+ .S01_AXI_WSTRB (0), // input [7 : 0] S01_AXI_WSTRB
+ .S01_AXI_WLAST (0), // input S01_AXI_WLAST
+ .S01_AXI_WVALID (0), // input S01_AXI_WVALID
+ .S01_AXI_WREADY (), // output S01_AXI_WREADY
+ .S01_AXI_BID (), // output [0 : 0] S01_AXI_BID
+ .S01_AXI_BRESP (), // output [1 : 0] S01_AXI_BRESP
+ .S01_AXI_BVALID (), // output S01_AXI_BVALID
+ .S01_AXI_BREADY (1), // input S01_AXI_BREADY
+ .S01_AXI_ARID (0), // input [0 : 0] S01_AXI_ARID
+ .S01_AXI_ARADDR (0), // input [31 : 0] S01_AXI_ARADDR
+ .S01_AXI_ARLEN (0), // input [7 : 0] S01_AXI_ARLEN
+ .S01_AXI_ARSIZE (0), // input [2 : 0] S01_AXI_ARSIZE
+ .S01_AXI_ARBURST (0), // input [1 : 0] S01_AXI_ARBURST
+ .S01_AXI_ARLOCK (0), // input S01_AXI_ARLOCK
+ .S01_AXI_ARCACHE (0), // input [3 : 0] S01_AXI_ARCACHE
+ .S01_AXI_ARPROT (0), // input [2 : 0] S01_AXI_ARPROT
+ .S01_AXI_ARQOS (0), // input [3 : 0] S01_AXI_ARQOS
+ .S01_AXI_ARVALID (0), // input S01_AXI_ARVALID
+ .S01_AXI_ARREADY (), // output S01_AXI_ARREADY
+ .S01_AXI_RID (), // output [0 : 0] S01_AXI_RID
+ .S01_AXI_RDATA (), // output [63 : 0] S01_AXI_RDATA
+ .S01_AXI_RRESP (), // output [1 : 0] S01_AXI_RRESP
+ .S01_AXI_RLAST (), // output S01_AXI_RLAST
+ .S01_AXI_RVALID (), // output S01_AXI_RVALID
+ .S01_AXI_RREADY (1), // input S01_AXI_RREADY
+ //
+ .S02_AXI_ACLK (dma_engine_clk), // input S01_AXI_ACLK
+ .S02_AXI_ARESETN (~ddr3_axi_rst), // input S01_AXI_ARESETN
+ .S02_AXI_AWID (0), // input [0 : 0] S01_AXI_AWID
+ .S02_AXI_AWADDR (0), // input [31 : 0] S01_AXI_AWADDR
+ .S02_AXI_AWLEN (0), // input [7 : 0] S01_AXI_AWLEN
+ .S02_AXI_AWSIZE (0), // input [2 : 0] S01_AXI_AWSIZE
+ .S02_AXI_AWBURST (0), // input [1 : 0] S01_AXI_AWBURST
+ .S02_AXI_AWLOCK (0), // input S01_AXI_AWLOCK
+ .S02_AXI_AWCACHE (0), // input [3 : 0] S01_AXI_AWCACHE
+ .S02_AXI_AWPROT (0), // input [2 : 0] S01_AXI_AWPROT
+ .S02_AXI_AWQOS (0), // input [3 : 0] S01_AXI_AWQOS
+ .S02_AXI_AWVALID (0), // input S01_AXI_AWVALID
+ .S02_AXI_AWREADY (), // output S01_AXI_AWREADY
+ .S02_AXI_WDATA (0), // input [63 : 0] S01_AXI_WDATA
+ .S02_AXI_WSTRB (0), // input [7 : 0] S01_AXI_WSTRB
+ .S02_AXI_WLAST (0), // input S01_AXI_WLAST
+ .S02_AXI_WVALID (0), // input S01_AXI_WVALID
+ .S02_AXI_WREADY (), // output S01_AXI_WREADY
+ .S02_AXI_BID (), // output [0 : 0] S01_AXI_BID
+ .S02_AXI_BRESP (), // output [1 : 0] S01_AXI_BRESP
+ .S02_AXI_BVALID (), // output S01_AXI_BVALID
+ .S02_AXI_BREADY (1), // input S01_AXI_BREADY
+ .S02_AXI_ARID (0), // input [0 : 0] S01_AXI_ARID
+ .S02_AXI_ARADDR (0), // input [31 : 0] S01_AXI_ARADDR
+ .S02_AXI_ARLEN (0), // input [7 : 0] S01_AXI_ARLEN
+ .S02_AXI_ARSIZE (0), // input [2 : 0] S01_AXI_ARSIZE
+ .S02_AXI_ARBURST (0), // input [1 : 0] S01_AXI_ARBURST
+ .S02_AXI_ARLOCK (0), // input S01_AXI_ARLOCK
+ .S02_AXI_ARCACHE (0), // input [3 : 0] S01_AXI_ARCACHE
+ .S02_AXI_ARPROT (0), // input [2 : 0] S01_AXI_ARPROT
+ .S02_AXI_ARQOS (0), // input [3 : 0] S01_AXI_ARQOS
+ .S02_AXI_ARVALID (0), // input S01_AXI_ARVALID
+ .S02_AXI_ARREADY (), // output S01_AXI_ARREADY
+ .S02_AXI_RID (), // output [0 : 0] S01_AXI_RID
+ .S02_AXI_RDATA (), // output [63 : 0] S01_AXI_RDATA
+ .S02_AXI_RRESP (), // output [1 : 0] S01_AXI_RRESP
+ .S02_AXI_RLAST (), // output S01_AXI_RLAST
+ .S02_AXI_RVALID (), // output S01_AXI_RVALID
+ .S02_AXI_RREADY (1), // input S01_AXI_RREADY
+ //
+ .S03_AXI_ACLK (dma_engine_clk), // input S00_AXI_ACLK
+ .S03_AXI_ARESETN (~ddr3_axi_rst), // input S00_AXI_ARESETN
+ .S03_AXI_AWID (dma_axi_wr.addr.id), // input [0 : 0] S00_AXI_AWID
+ .S03_AXI_AWADDR (dma_axi_wr.addr.addr), // input [31 : 0] S00_AXI_AWADDR
+ .S03_AXI_AWLEN (dma_axi_wr.addr.len), // input [7 : 0] S00_AXI_AWLEN
+ .S03_AXI_AWSIZE (dma_axi_wr.addr.size), // input [2 : 0] S00_AXI_AWSIZE
+ .S03_AXI_AWBURST (dma_axi_wr.addr.burst), // input [1 : 0] S00_AXI_AWBURST
+ .S03_AXI_AWLOCK (dma_axi_wr.addr.lock), // input S00_AXI_AWLOCK
+ .S03_AXI_AWCACHE (dma_axi_wr.addr.cache), // input [3 : 0] S00_AXI_AWCACHE
+ .S03_AXI_AWPROT (dma_axi_wr.addr.prot), // input [2 : 0] S00_AXI_AWPROT
+ .S03_AXI_AWQOS (dma_axi_wr.addr.qos), // input [3 : 0] S00_AXI_AWQOS
+ .S03_AXI_AWVALID (dma_axi_wr.addr.valid), // input S00_AXI_AWVALID
+ .S03_AXI_AWREADY (dma_axi_wr.addr.ready), // output S00_AXI_AWREADY
+ .S03_AXI_WDATA (dma_axi_wr.data.data ^ forced_bit_err), // input [63 : 0] S00_AXI_WDATA
+ .S03_AXI_WSTRB (dma_axi_wr.data.strb), // input [7 : 0] S00_AXI_WSTRB
+ .S03_AXI_WLAST (dma_axi_wr.data.last), // input S00_AXI_WLAST
+ .S03_AXI_WVALID (dma_axi_wr.data.valid), // input S00_AXI_WVALID
+ .S03_AXI_WREADY (dma_axi_wr.data.ready), // output S00_AXI_WREADY
+ .S03_AXI_BID (dma_axi_wr.resp.id), // output [0 : 0] S00_AXI_BID
+ .S03_AXI_BRESP (dma_axi_wr.resp.resp), // output [1 : 0] S00_AXI_BRESP
+ .S03_AXI_BVALID (dma_axi_wr.resp.valid), // output S00_AXI_BVALID
+ .S03_AXI_BREADY (dma_axi_wr.resp.ready), // input S00_AXI_BREADY
+ .S03_AXI_ARID (dma_axi_rd.addr.id), // input [0 : 0] S00_AXI_ARID
+ .S03_AXI_ARADDR (dma_axi_rd.addr.addr), // input [31 : 0] S00_AXI_ARADDR
+ .S03_AXI_ARLEN (dma_axi_rd.addr.len), // input [7 : 0] S00_AXI_ARLEN
+ .S03_AXI_ARSIZE (dma_axi_rd.addr.size), // input [2 : 0] S00_AXI_ARSIZE
+ .S03_AXI_ARBURST (dma_axi_rd.addr.burst), // input [1 : 0] S00_AXI_ARBURST
+ .S03_AXI_ARLOCK (dma_axi_rd.addr.lock), // input S00_AXI_ARLOCK
+ .S03_AXI_ARCACHE (dma_axi_rd.addr.cache), // input [3 : 0] S00_AXI_ARCACHE
+ .S03_AXI_ARPROT (dma_axi_rd.addr.prot), // input [2 : 0] S00_AXI_ARPROT
+ .S03_AXI_ARQOS (dma_axi_rd.addr.qos), // input [3 : 0] S00_AXI_ARQOS
+ .S03_AXI_ARVALID (dma_axi_rd.addr.valid), // input S00_AXI_ARVALID
+ .S03_AXI_ARREADY (dma_axi_rd.addr.ready), // output S00_AXI_ARREADY
+ .S03_AXI_RID (dma_axi_rd.data.id), // output [0 : 0] S00_AXI_RID
+ .S03_AXI_RDATA (dma_axi_rd.data.data), // output [63 : 0] S00_AXI_RDATA
+ .S03_AXI_RRESP (dma_axi_rd.data.resp), // output [1 : 0] S00_AXI_RRESP
+ .S03_AXI_RLAST (dma_axi_rd.data.last), // output S00_AXI_RLAST
+ .S03_AXI_RVALID (dma_axi_rd.data.valid), // output S00_AXI_RVALID
+ .S03_AXI_RREADY (dma_axi_rd.data.ready), // input S00_AXI_RREADY
+ //
+ .M00_AXI_ACLK (ddr3_axi_clk), // input M00_AXI_ACLK
+ .M00_AXI_ARESETN (~ddr3_axi_rst), // input M00_AXI_ARESETN
+ .M00_AXI_AWID (mig_axi_wr.addr.id), // output [3 : 0] M00_AXI_AWID
+ .M00_AXI_AWADDR (mig_axi_wr.addr.addr), // output [31 : 0] M00_AXI_AWADDR
+ .M00_AXI_AWLEN (mig_axi_wr.addr.len), // output [7 : 0] M00_AXI_AWLEN
+ .M00_AXI_AWSIZE (mig_axi_wr.addr.size), // output [2 : 0] M00_AXI_AWSIZE
+ .M00_AXI_AWBURST (mig_axi_wr.addr.burst), // output [1 : 0] M00_AXI_AWBURST
+ .M00_AXI_AWLOCK (mig_axi_wr.addr.lock), // output M00_AXI_AWLOCK
+ .M00_AXI_AWCACHE (mig_axi_wr.addr.cache), // output [3 : 0] M00_AXI_AWCACHE
+ .M00_AXI_AWPROT (mig_axi_wr.addr.prot), // output [2 : 0] M00_AXI_AWPROT
+ .M00_AXI_AWQOS (mig_axi_wr.addr.qos), // output [3 : 0] M00_AXI_AWQOS
+ .M00_AXI_AWVALID (mig_axi_wr.addr.valid), // output M00_AXI_AWVALID
+ .M00_AXI_AWREADY (mig_axi_wr.addr.ready), // input M00_AXI_AWREADY
+ .M00_AXI_WDATA (mig_axi_wr.data.data), // output [127 : 0] M00_AXI_WDATA
+ .M00_AXI_WSTRB (mig_axi_wr.data.strb), // output [15 : 0] M00_AXI_WSTRB
+ .M00_AXI_WLAST (mig_axi_wr.data.last), // output M00_AXI_WLAST
+ .M00_AXI_WVALID (mig_axi_wr.data.valid), // output M00_AXI_WVALID
+ .M00_AXI_WREADY (mig_axi_wr.data.ready), // input M00_AXI_WREADY
+ .M00_AXI_BID (mig_axi_wr.resp.id), // input [3 : 0] M00_AXI_BID
+ .M00_AXI_BRESP (mig_axi_wr.resp.resp), // input [1 : 0] M00_AXI_BRESP
+ .M00_AXI_BVALID (mig_axi_wr.resp.valid), // input M00_AXI_BVALID
+ .M00_AXI_BREADY (mig_axi_wr.resp.ready), // output M00_AXI_BREADY
+ .M00_AXI_ARID (mig_axi_rd.addr.id), // output [3 : 0] M00_AXI_ARID
+ .M00_AXI_ARADDR (mig_axi_rd.addr.addr), // output [31 : 0] M00_AXI_ARADDR
+ .M00_AXI_ARLEN (mig_axi_rd.addr.len), // output [7 : 0] M00_AXI_ARLEN
+ .M00_AXI_ARSIZE (mig_axi_rd.addr.size), // output [2 : 0] M00_AXI_ARSIZE
+ .M00_AXI_ARBURST (mig_axi_rd.addr.burst), // output [1 : 0] M00_AXI_ARBURST
+ .M00_AXI_ARLOCK (mig_axi_rd.addr.lock), // output M00_AXI_ARLOCK
+ .M00_AXI_ARCACHE (mig_axi_rd.addr.cache), // output [3 : 0] M00_AXI_ARCACHE
+ .M00_AXI_ARPROT (mig_axi_rd.addr.prot), // output [2 : 0] M00_AXI_ARPROT
+ .M00_AXI_ARQOS (mig_axi_rd.addr.qos), // output [3 : 0] M00_AXI_ARQOS
+ .M00_AXI_ARVALID (mig_axi_rd.addr.valid), // output M00_AXI_ARVALID
+ .M00_AXI_ARREADY (mig_axi_rd.addr.ready), // input M00_AXI_ARREADY
+ .M00_AXI_RID (mig_axi_rd.data.id), // input [3 : 0] M00_AXI_RID
+ .M00_AXI_RDATA (mig_axi_rd.data.data), // input [127 : 0] M00_AXI_RDATA
+ .M00_AXI_RRESP (mig_axi_rd.data.resp), // input [1 : 0] M00_AXI_RRESP
+ .M00_AXI_RLAST (mig_axi_rd.data.last), // input M00_AXI_RLAST
+ .M00_AXI_RVALID (mig_axi_rd.data.valid), // input M00_AXI_RVALID
+ .M00_AXI_RREADY (mig_axi_rd.data.ready) // output M00_AXI_RREADY
+ );
+
+ //---------------------------------------------------
+ // MIG
+ //---------------------------------------------------
+ ddr3_32bit ddr_mig_i (
+ // Memory interface ports
+ .ddr3_addr (ddr3_addr),
+ .ddr3_ba (ddr3_ba),
+ .ddr3_cas_n (ddr3_cas_n),
+ .ddr3_ck_n (ddr3_ck_n),
+ .ddr3_ck_p (ddr3_ck_p),
+ .ddr3_cke (ddr3_cke),
+ .ddr3_ras_n (ddr3_ras_n),
+ .ddr3_reset_n (ddr3_reset_n),
+ .ddr3_we_n (ddr3_we_n),
+ .ddr3_dq (ddr3_dq),
+ .ddr3_dqs_n (ddr3_dqs_n),
+ .ddr3_dqs_p (ddr3_dqs_p),
+ .init_calib_complete (init_calib_complete),
+
+ .ddr3_cs_n (ddr3_cs_n),
+ .ddr3_dm (ddr3_dm),
+ .ddr3_odt (ddr3_odt),
+ // Application interface ports
+ .ui_clk (ddr3_axi_clk), // 150MHz clock out
+ .ui_clk_sync_rst (ddr3_axi_rst), // Active high Reset signal synchronised to 150MHz
+ .aresetn (ddr3_axi_rst_reg_n),
+ .app_sr_req (1'b0),
+ .app_sr_active (),
+ .app_ref_req (1'b0),
+ .app_ref_ack (),
+ .app_zq_req (1'b0),
+ .app_zq_ack (),
+
+ // Slave Interface Write Address Ports
+ .s_axi_awid (mig_axi_wr.addr.id),
+ .s_axi_awaddr (mig_axi_wr.addr.addr),
+ .s_axi_awlen (mig_axi_wr.addr.len),
+ .s_axi_awsize (mig_axi_wr.addr.size),
+ .s_axi_awburst (mig_axi_wr.addr.burst),
+ .s_axi_awlock (mig_axi_wr.addr.lock),
+ .s_axi_awcache (mig_axi_wr.addr.cache),
+ .s_axi_awprot (mig_axi_wr.addr.prot),
+ .s_axi_awqos (mig_axi_wr.addr.qos),
+ .s_axi_awvalid (mig_axi_wr.addr.valid),
+ .s_axi_awready (mig_axi_wr.addr.ready),
+ // Slave Interface Write Data Ports
+ .s_axi_wdata (mig_axi_wr.data.data),
+ .s_axi_wstrb (mig_axi_wr.data.strb),
+ .s_axi_wlast (mig_axi_wr.data.last),
+ .s_axi_wvalid (mig_axi_wr.data.valid),
+ .s_axi_wready (mig_axi_wr.data.ready),
+ // Slave Interface Write Response Ports
+ .s_axi_bid (mig_axi_wr.resp.id),
+ .s_axi_bresp (mig_axi_wr.resp.resp),
+ .s_axi_bvalid (mig_axi_wr.resp.valid),
+ .s_axi_bready (mig_axi_wr.resp.ready),
+ // Slave Interface Read Address Ports
+ .s_axi_arid (mig_axi_rd.addr.id),
+ .s_axi_araddr (mig_axi_rd.addr.addr),
+ .s_axi_arlen (mig_axi_rd.addr.len),
+ .s_axi_arsize (mig_axi_rd.addr.size),
+ .s_axi_arburst (mig_axi_rd.addr.burst),
+ .s_axi_arlock (mig_axi_rd.addr.lock),
+ .s_axi_arcache (mig_axi_rd.addr.cache),
+ .s_axi_arprot (mig_axi_rd.addr.prot),
+ .s_axi_arqos (mig_axi_rd.addr.qos),
+ .s_axi_arvalid (mig_axi_rd.addr.valid),
+ .s_axi_arready (mig_axi_rd.addr.ready),
+ // Slave Interface Read Data Ports
+ .s_axi_rid (mig_axi_rd.data.id),
+ .s_axi_rdata (mig_axi_rd.data.data),
+ .s_axi_rresp (mig_axi_rd.data.resp),
+ .s_axi_rlast (mig_axi_rd.data.last),
+ .s_axi_rvalid (mig_axi_rd.data.valid),
+ .s_axi_rready (mig_axi_rd.data.ready),
+ // System Clock Ports
+ .sys_clk_p (sys_clk_p), // From external 100MHz source.
+ .sys_clk_n (sys_clk_n), // From external 100MHz source.
+ .clk_ref_i (bus_clk),
+ .sys_rst (sys_rst_n) // IJB. Poorly named active low. Should change RST_ACT_LOW.
+ );
+
+ //---------------------------------------------------
+ // DDR3 SDRAM Models
+ //---------------------------------------------------
+ ddr3_model #(
+ .DEBUG(0) //Disable verbose prints
+ ) sdram_i0 (
+ .rst_n (ddr3_reset_n),
+ .ck (ddr3_ck_p),
+ .ck_n (ddr3_ck_n),
+ .cke (ddr3_cke),
+ .cs_n (ddr3_cs_n),
+ .ras_n (ddr3_ras_n),
+ .cas_n (ddr3_cas_n),
+ .we_n (ddr3_we_n),
+ .dm_tdqs (ddr3_dm[1:0]),
+ .ba (ddr3_ba),
+ .addr (ddr3_addr),
+ .dq (ddr3_dq[15:0]),
+ .dqs (ddr3_dqs_p[1:0]),
+ .dqs_n (ddr3_dqs_n[1:0]),
+ .tdqs_n (), // Unused on x16
+ .odt (ddr3_odt)
+ );
+
+ ddr3_model #(
+ .DEBUG(0) //Disable verbose prints
+ ) sdram_i1 (
+ .rst_n (ddr3_reset_n),
+ .ck (ddr3_ck_p),
+ .ck_n (ddr3_ck_n),
+ .cke (ddr3_cke),
+ .cs_n (ddr3_cs_n),
+ .ras_n (ddr3_ras_n),
+ .cas_n (ddr3_cas_n),
+ .we_n (ddr3_we_n),
+ .dm_tdqs (ddr3_dm[3:2]),
+ .ba (ddr3_ba),
+ .addr (ddr3_addr),
+ .dq (ddr3_dq[31:16]),
+ .dqs (ddr3_dqs_p[3:2]),
+ .dqs_n (ddr3_dqs_n[3:2]),
+ .tdqs_n (), // Unused on x16
+ .odt (ddr3_odt)
+ );
+
+endmodule
diff --git a/fpga/usrp3/top/n3xx/sim/dram_fifo/dram_fifo_tb.sv b/fpga/usrp3/top/n3xx/sim/dram_fifo/dram_fifo_tb.sv
new file mode 100644
index 000000000..2979aefb7
--- /dev/null
+++ b/fpga/usrp3/top/n3xx/sim/dram_fifo/dram_fifo_tb.sv
@@ -0,0 +1,163 @@
+//
+// Copyright 2016 Ettus Research
+//
+
+
+`timescale 1ns/1ps
+`define SIM_TIMEOUT_US 120
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 7
+
+`include "sim_clks_rsts.vh"
+`include "sim_exec_report.vh"
+`include "sim_cvita_lib.svh"
+`include "sim_axi4_lib.svh"
+`include "sim_set_rb_lib.svh"
+
+module dram_fifo_tb();
+ `TEST_BENCH_INIT("dram_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_DIFF_CLK(sys_clk_p, sys_clk_n, 10, 50) //100MHz differential sys_clk to generate DDR3 clocking
+ `DEFINE_CLK(bus_clk, 1000/200, 50) //200MHz bus_clk
+ `DEFINE_CLK(dma_engine_clk, 1000.0/305.0, 50) //305MHz dma_engine_clk
+ `DEFINE_RESET(bus_rst, 0, 100) //100ns for GSR to deassert
+ `DEFINE_RESET_N(sys_rst_n, 0, 100) //100ns for GSR to deassert
+
+ settings_bus_master #(.SR_AWIDTH(8),.SR_DWIDTH(32)) tst_set (.clk(bus_clk));
+ cvita_master chdr_i (.clk(bus_clk));
+ cvita_slave chdr_o (.clk(bus_clk));
+
+ // Initialize DUT
+ wire calib_complete;
+
+ axis_dram_fifo_single dut_single (
+ .bus_clk(bus_clk),
+ .bus_rst(bus_rst),
+ .sys_clk_p(sys_clk_p),//use differential clock on N310
+ .sys_clk_n(sys_clk_n),
+ .sys_rst_n(sys_rst_n),
+ .dma_engine_clk(dma_engine_clk),
+
+ .i_tdata(chdr_i.axis.tdata),
+ .i_tlast(chdr_i.axis.tlast),
+ .i_tvalid(chdr_i.axis.tvalid),
+ .i_tready(chdr_i.axis.tready),
+
+ .o_tdata(chdr_o.axis.tdata),
+ .o_tlast(chdr_o.axis.tlast),
+ .o_tvalid(chdr_o.axis.tvalid),
+ .o_tready(chdr_o.axis.tready),
+
+ .set_stb(tst_set.settings_bus.set_stb),
+ .set_addr(tst_set.settings_bus.set_addr),
+ .set_data(tst_set.settings_bus.set_data),
+ .rb_data(),
+
+ .forced_bit_err(64'h0),
+ .init_calib_complete(calib_complete)
+ );
+
+ //Testbench variables
+ cvita_hdr_t header;
+ cvita_pkt_t pkt_out;
+ integer i;
+
+ //------------------------------------------
+ //Main thread for testbench execution
+ //------------------------------------------
+ initial begin : tb_main
+ string s;
+
+ `TEST_CASE_START("Wait for reset");
+ while (bus_rst) @(posedge bus_clk);
+ while (~sys_rst_n) @(posedge sys_clk_p);
+ `TEST_CASE_DONE((~bus_rst & sys_rst_n));
+
+ `TEST_CASE_START("Wait for initial calibration to complete");
+ while (calib_complete !== 1'b1) @(posedge bus_clk);
+ `TEST_CASE_DONE(calib_complete);
+
+ `TEST_CASE_START("Clear FIFO");
+ tst_set.write(1, {16'h0, 12'd280, 2'b00, 1'b0, 1'b1});
+ repeat (200) @(posedge bus_clk);
+ tst_set.write(1, {16'h0, 12'd280, 2'b00, 1'b0, 1'b0});
+ repeat (200) @(posedge bus_clk);
+ `TEST_CASE_DONE(1);
+
+ header = '{
+ pkt_type:DATA, has_time:0, eob:0, seqnum:12'h666,
+ length:0, src_sid:$random, dst_sid:$random, timestamp:64'h0};
+
+ `TEST_CASE_START("Fill up empty FIFO then drain (short packet)");
+ chdr_i.push_ramp_pkt(16, 64'd0, 64'h100, header);
+ chdr_o.pull_pkt(pkt_out);
+ $sformat(s, "Bad packet: Length mismatch. Expected: %0d, Actual: %0d",16,pkt_out.payload.size());
+ `ASSERT_ERROR(pkt_out.payload.size()==16, s);
+ $sformat(s, "Bad packet: Wrong SID. Expected: %08x, Actual: %08x",
+ {header.src_sid,header.dst_sid},{pkt_out.hdr.src_sid,pkt_out.hdr.dst_sid});
+ `ASSERT_ERROR({header.src_sid,header.dst_sid}=={pkt_out.hdr.src_sid,pkt_out.hdr.dst_sid}, s);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Fill up empty FIFO then drain (long packet)");
+ chdr_i.push_ramp_pkt(1024, 64'd0, 64'h100, header);
+ chdr_o.pull_pkt(pkt_out);
+ $sformat(s, "Bad packet: Length mismatch. Expected: %0d, Actual: %0d",1024,pkt_out.payload.size());
+ `ASSERT_ERROR(pkt_out.payload.size()==1024, s);
+ $sformat(s, "Bad packet: Wrong SID. Expected: %08x, Actual: %08x",
+ {header.src_sid,header.dst_sid},{pkt_out.hdr.src_sid,pkt_out.hdr.dst_sid});
+ `ASSERT_ERROR({header.src_sid,header.dst_sid}=={pkt_out.hdr.src_sid,pkt_out.hdr.dst_sid}, s);
+ `TEST_CASE_DONE(1);
+
+ header = '{
+ pkt_type:DATA, has_time:0, eob:0, seqnum:12'h666,
+ length:0, src_sid:$random, dst_sid:$random, timestamp:64'h0};
+
+ `TEST_CASE_START("Concurrent read and write (single packet)");
+ fork
+ begin
+ chdr_i.push_ramp_pkt(20, 64'd0, 64'h100, header);
+ end
+ begin
+ chdr_o.pull_pkt(pkt_out);
+ end
+ join
+ $sformat(s, "Bad packet: Length mismatch. Expected: %0d, Actual: %0d",20,pkt_out.payload.size());
+ `ASSERT_ERROR(pkt_out.payload.size()==20, s);
+ i = 0;
+ repeat (20) begin
+ $sformat(s, "Bad packet: Wrong payload. Index: %d, Expected: %08x, Actual: %08x",
+ i,(i * 64'h100),pkt_out.payload[i]);
+ `ASSERT_ERROR(pkt_out.payload[i]==(i * 64'h100), s);
+ end
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Concurrent read and write (multiple packets)");
+ fork
+ begin
+ repeat (10) begin
+ chdr_i.push_ramp_pkt(20, 64'd0, 64'h100, header);
+ repeat (30) @(posedge bus_clk);
+ end
+ end
+ begin
+ repeat (10) begin
+ chdr_o.pull_pkt(pkt_out);
+ $sformat(s, "Bad packet: Length mismatch. Expected: %0d, Actual: %0d",20,pkt_out.payload.size());
+ `ASSERT_ERROR(pkt_out.payload.size()==20, s);
+ i = 0;
+ repeat (20) begin
+ $sformat(s, "Bad packet: Wrong payload. Index: %d, Expected: %08x, Actual: %08x",
+ i,(i * 64'h100),pkt_out.payload[i]);
+ `ASSERT_ERROR(pkt_out.payload[i]==(i * 64'h100), s);
+ end
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_BENCH_DONE;
+
+ end
+
+endmodule