diff options
Diffstat (limited to 'fpga/usrp3/top/n3xx/sim/dram_fifo')
-rw-r--r-- | fpga/usrp3/top/n3xx/sim/dram_fifo/Makefile | 70 | ||||
-rw-r--r-- | fpga/usrp3/top/n3xx/sim/dram_fifo/axis_dram_fifo_single.sv | 493 | ||||
-rw-r--r-- | fpga/usrp3/top/n3xx/sim/dram_fifo/dram_fifo_tb.sv | 163 |
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 |