aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/top/x300/sim
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/top/x300/sim')
-rw-r--r--fpga/usrp3/top/x300/sim/aurora_loopback/Makefile77
-rw-r--r--fpga/usrp3/top/x300/sim/aurora_loopback/aurora_loopback_tb.sv310
-rw-r--r--fpga/usrp3/top/x300/sim/dram_fifo/Makefile72
-rw-r--r--fpga/usrp3/top/x300/sim/dram_fifo/axis_dram_fifo_single.sv589
-rw-r--r--fpga/usrp3/top/x300/sim/dram_fifo/dram_fifo_tb.sv184
-rw-r--r--fpga/usrp3/top/x300/sim/dram_fifo_bist/Makefile72
-rw-r--r--fpga/usrp3/top/x300/sim/dram_fifo_bist/dram_fifo_bist_tb.sv349
-rw-r--r--fpga/usrp3/top/x300/sim/x300_pcie_int/Makefile66
-rw-r--r--fpga/usrp3/top/x300/sim/x300_pcie_int/x300_pcie_int_tb.sv596
9 files changed, 2315 insertions, 0 deletions
diff --git a/fpga/usrp3/top/x300/sim/aurora_loopback/Makefile b/fpga/usrp3/top/x300/sim/aurora_loopback/Makefile
new file mode 100644
index 000000000..eb135ef4e
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/aurora_loopback/Makefile
@@ -0,0 +1,77 @@
+#
+# 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 = kintex7
+PART_ID = xc7k410t/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
+include $(BASE_DIR)/../lib/rfnoc/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(FIFO_SRCS) \
+$(AXI_SRCS) \
+$(CONTROL_LIB_SRCS) \
+$(RFNOC_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)/aurora_64b66b_pcs_pma/Makefile.inc
+include $(IP_DIR)/fifo_short_2clk/Makefile.inc
+include $(IP_DIR)/axi64_4k_2clk_fifo/Makefile.inc
+
+DESIGN_SRCS += $(abspath \
+$(IP_AURORA_64B66B_PCS_PMA_SRCS) \
+$(IP_AXI64_4K_2CLK_FIFO_SRCS) \
+$(IP_FIFO_SHORT_2CLK_SRCS) \
+$(AURORA_PHY_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+include $(BASE_DIR)/../sim/general/Makefile.srcs
+include $(BASE_DIR)/../sim/control/Makefile.srcs
+include $(BASE_DIR)/../sim/axi/Makefile.srcs
+
+# Define only one toplevel module
+SIM_TOP = aurora_loopback_tb
+# Simulation runtime in microseconds
+SIM_RUNTIME_US = 70
+
+SIM_SRCS = \
+$(abspath aurora_loopback_tb.sv) \
+$(SIM_GENERAL_SRCS) \
+$(SIM_CONTROL_SRCS) \
+$(SIM_AXI_SRCS)
+
+#-------------------------------------------------
+# 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/x300/sim/aurora_loopback/aurora_loopback_tb.sv b/fpga/usrp3/top/x300/sim/aurora_loopback/aurora_loopback_tb.sv
new file mode 100644
index 000000000..75c07dd09
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/aurora_loopback/aurora_loopback_tb.sv
@@ -0,0 +1,310 @@
+//
+// Copyright 2016 Ettus Research LLC
+//
+
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 13
+
+`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 aurora_loopback_tb();
+ `TEST_BENCH_INIT("aurora_loopback_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_CLK(XG_CLK_P, 1000/156.25, 50) //156.25MHz GT transceiver clock
+ `DEFINE_RESET(GSR, 0, 100) //100ns for GSR to deassert
+
+ wire XG_CLK_N = ~XG_CLK_P;
+ wire SFP_LN0_P, SFP_LN0_N, SFP_LN1_P, SFP_LN1_N;
+
+ localparam PACKET_MODE = 1;
+
+ // Aurora Loopback Topology:
+ //
+ // TB Simulus ====> |------------| |----------------|
+ // | Aurora MAC | <===> | Aurora PCS/PMA | <====>||
+ // TB Checker <==== |------------| |----------------| || Loopback through
+ // ||
+ // ====> |------------| |----------------| || perfect serial channel
+ // Loopback | | Aurora MAC | <===> | Aurora PCS/PMA | <====>||
+ // <==== |------------| |----------------|
+
+ // Initialize DUT
+ wire aurora_refclk, aurora_init_clk;
+ wire m_user_clk, s_user_clk;
+ wire m_user_rst, s_user_rst;
+ wire m_channel_up, s_channel_up;
+ wire m_hard_err, s_hard_err;
+ wire m_soft_err, s_soft_err;
+
+ aurora_phy_clk_gen aurora_clk_gen_i (
+ .areset(GSR),
+ .refclk_p(XG_CLK_P),
+ .refclk_n(XG_CLK_N),
+ .refclk(aurora_refclk),
+ .clk156(),
+ .init_clk(aurora_init_clk)
+ );
+
+ wire [63:0] m_i_tdata, m_o_tdata;
+ wire m_i_tvalid, m_i_tready, m_o_tvalid;
+ wire [63:0] s_i_tdata, s_o_tdata;
+ wire s_i_tvalid, s_i_tready, s_o_tvalid;
+ wire [63:0] loop_tdata;
+ wire loop_tlast, loop_tvalid, loop_tready;
+ wire [31:0] m_overruns, s_overruns;
+ wire [31:0] m_soft_errors, s_soft_errors;
+ reg m_bist_gen, m_bist_check, s_bist_loopback;
+ reg [5:0] m_bist_rate;
+ wire m_bist_locked;
+ wire [47:0] m_bist_samps, m_bist_errors;
+
+
+ cvita_master m_tx_chdr (.clk(m_user_clk));
+ cvita_slave m_rx_chdr (.clk(s_user_clk));
+
+ aurora_phy_x1 #(.SIMULATION(1)) aurora_phy_master_i (
+ // Resets
+ .areset(GSR),
+ // Clocks
+ .refclk(aurora_refclk),
+ .user_clk(m_user_clk),
+ .init_clk(aurora_init_clk),
+ .user_rst(m_user_rst),
+ // GTX Serial I/O
+ .tx_p(SFP_LN0_P), .tx_n(SFP_LN0_N),
+ .rx_p(SFP_LN1_P), .rx_n(SFP_LN1_N),
+ // AXI4-Stream TX Interface
+ .s_axis_tdata(m_i_tdata), .s_axis_tvalid(m_i_tvalid), .s_axis_tready(m_i_tready),
+ // AXI4-Stream RX Interface
+ .m_axis_tdata(m_o_tdata), .m_axis_tvalid(m_o_tvalid),
+ // AXI4-Lite Config Interface
+ .s_axi_awaddr(32'h0), .s_axi_araddr(32'h0), .s_axi_awvalid(1'b0), .s_axi_awready(),
+ .s_axi_wdata(32'h0), .s_axi_wvalid(1'b0), .s_axi_wstrb(1'b0), .s_axi_wready(),
+ .s_axi_bvalid(), .s_axi_bresp(), .s_axi_bready(1'b1),
+ .s_axi_arready(), .s_axi_arvalid(1'b0),
+ .s_axi_rdata(), .s_axi_rvalid(), .s_axi_rresp(), .s_axi_rready(1'b1),
+ // Status and Error Reporting Interface
+ .channel_up(m_channel_up), .hard_err(m_hard_err), .soft_err(m_soft_err)
+ );
+
+ aurora_axis_mac #(.PACKET_MODE(PACKET_MODE), .BIST_ENABLED(1)) aurora_mac_master_i (
+ // Clocks and resets
+ .phy_clk(m_user_clk), .phy_rst(m_user_rst),
+ .sys_clk(m_user_clk), .sys_rst(m_user_rst),
+ .clear(1'b0),
+ // PHY Interface
+ .phy_s_axis_tdata(m_o_tdata), .phy_s_axis_tvalid(m_o_tvalid),
+ .phy_m_axis_tdata(m_i_tdata), .phy_m_axis_tvalid(m_i_tvalid), .phy_m_axis_tready(m_i_tready),
+ // User Interface
+ .s_axis_tdata(m_tx_chdr.axis.tdata), .s_axis_tlast(m_tx_chdr.axis.tlast),
+ .s_axis_tvalid(m_tx_chdr.axis.tvalid), .s_axis_tready(m_tx_chdr.axis.tready),
+ .m_axis_tdata(m_rx_chdr.axis.tdata), .m_axis_tlast(m_rx_chdr.axis.tlast),
+ .m_axis_tvalid(m_rx_chdr.axis.tvalid), .m_axis_tready(m_rx_chdr.axis.tready),
+ // Misc PHY
+ .channel_up(m_channel_up), .hard_err(m_hard_err), .soft_err(m_soft_err),
+ .overruns(m_overruns), .soft_errors(m_soft_errors),
+ //BIST
+ .bist_gen_en(m_bist_gen), .bist_checker_en(m_bist_check), .bist_loopback_en(1'b0), .bist_gen_rate(m_bist_rate),
+ .bist_checker_locked(m_bist_locked), .bist_checker_samps(m_bist_samps), .bist_checker_errors(m_bist_errors)
+ );
+
+ aurora_phy_x1 #(.SIMULATION(1)) aurora_phy_slave_i (
+ // Resets
+ .areset(GSR),
+ // Clocks
+ .refclk(aurora_refclk),
+ .user_clk(s_user_clk),
+ .init_clk(aurora_init_clk),
+ .user_rst(s_user_rst),
+ // GTX Serial I/O
+ .tx_p(SFP_LN1_P), .tx_n(SFP_LN1_N),
+ .rx_p(SFP_LN0_P), .rx_n(SFP_LN0_N),
+ // AXI4-Stream TX Interface
+ .s_axis_tdata(s_i_tdata), .s_axis_tvalid(s_i_tvalid), .s_axis_tready(s_i_tready),
+ // AXI4-Stream RX Interface
+ .m_axis_tdata(s_o_tdata), .m_axis_tvalid(s_o_tvalid),
+ // AXI4-Lite Config Interface
+ // AXI4-Lite Config Interface
+ .s_axi_awaddr(32'h0), .s_axi_araddr(32'h0), .s_axi_awvalid(1'b0), .s_axi_awready(),
+ .s_axi_wdata(32'h0), .s_axi_wvalid(1'b0), .s_axi_wstrb(1'b0), .s_axi_wready(),
+ .s_axi_bvalid(), .s_axi_bresp(), .s_axi_bready(1'b1),
+ .s_axi_arready(), .s_axi_arvalid(1'b0),
+ .s_axi_rdata(), .s_axi_rvalid(), .s_axi_rresp(), .s_axi_rready(1'b1),
+ // Status and Error Reporting Interface
+ .channel_up(s_channel_up), .hard_err(s_hard_err), .soft_err(s_soft_err)
+ );
+
+ aurora_axis_mac #(.PACKET_MODE(PACKET_MODE), .BIST_ENABLED(1)) aurora_mac_slave_i (
+ // Clocks and resets
+ .phy_clk(s_user_clk), .phy_rst(s_user_rst),
+ .sys_clk(s_user_clk), .sys_rst(s_user_rst),
+ .clear(1'b0),
+ // PHY Interface
+ .phy_s_axis_tdata(s_o_tdata), .phy_s_axis_tvalid(s_o_tvalid),
+ .phy_m_axis_tdata(s_i_tdata), .phy_m_axis_tvalid(s_i_tvalid), .phy_m_axis_tready(s_i_tready),
+ // User Interface
+ .s_axis_tdata(loop_tdata), .s_axis_tlast(loop_tlast),
+ .s_axis_tvalid(~s_bist_loopback & loop_tvalid), .s_axis_tready(loop_tready),
+ .m_axis_tdata(loop_tdata), .m_axis_tlast(loop_tlast),
+ .m_axis_tvalid(loop_tvalid), .m_axis_tready(~s_bist_loopback & loop_tready),
+ // Misc PHY
+ .channel_up(s_channel_up), .hard_err(s_hard_err), .soft_err(s_soft_err),
+ .overruns(s_overruns), .soft_errors(s_soft_errors),
+ //BIST
+ .bist_gen_en(1'b0), .bist_checker_en(1'b0), .bist_loopback_en(s_bist_loopback), .bist_gen_rate(6'd0),
+ .bist_checker_locked(), .bist_checker_samps(), .bist_checker_errors()
+ );
+
+ //Testbench variables
+ cvita_hdr_t header, header_out;
+ cvita_stats_t stats;
+ logic [63:0] crc_cache;
+
+ //------------------------------------------
+ //Main thread for testbench execution
+ //------------------------------------------
+ initial begin : tb_main
+ string s;
+ `TEST_CASE_START("Wait for reset");
+ while (GSR) @(posedge XG_CLK_P);
+ `TEST_CASE_DONE((~GSR));
+
+ m_bist_gen <= 1'b0;
+ m_bist_rate <= 6'd0;
+ m_bist_check <= 1'b0;
+ s_bist_loopback <= 1'b0;
+
+ m_tx_chdr.push_bubble();
+
+ `TEST_CASE_START("Wait for master channel to come up");
+ while (m_channel_up !== 1'b1) @(posedge m_user_clk);
+ `TEST_CASE_DONE(1'b1);
+
+ `TEST_CASE_START("Wait for slave channel to come up");
+ while (s_channel_up !== 1'b1) @(posedge s_user_clk);
+ `TEST_CASE_DONE(1'b1);
+
+ `TEST_CASE_START("Run PRBS BIST");
+ s_bist_loopback <= PACKET_MODE;
+ @(posedge m_user_clk);
+ m_bist_rate <= 6'd60;
+ m_bist_gen <= 1'b1;
+ m_bist_check <= 1'b1;
+ @(posedge m_user_clk);
+ while (m_bist_locked !== 1'b1) @(posedge m_user_clk);
+ repeat (512) @(posedge m_user_clk);
+ `ASSERT_ERROR(m_bist_samps>256, "BIST: Num samples incorrect");
+ `ASSERT_ERROR(m_bist_errors===36'd0, "BIST: Errors!");
+ @(posedge m_user_clk);
+ m_bist_gen <= 1'b0;
+ repeat (256) @(posedge m_user_clk);
+ m_bist_check <= 1'b0;
+ `TEST_CASE_DONE(1'b1);
+
+ 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)");
+ m_rx_chdr.axis.tready = 0;
+ m_tx_chdr.push_ramp_pkt(16, 64'd0, 64'h100, header);
+ m_rx_chdr.axis.tready = 1;
+ m_rx_chdr.wait_for_pkt_get_info(header_out, stats);
+ `ASSERT_ERROR(stats.count==16, "Bad packet: Length mismatch");
+ $sformat(s, "Bad packet: Wrong SID. Expected: %08x, Actual: %08x",
+ {header.src_sid,header.dst_sid},{header_out.src_sid,header_out.dst_sid});
+ `ASSERT_ERROR({header.src_sid,header.dst_sid}=={header_out.src_sid,header_out.dst_sid}, s);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Fill up empty FIFO then drain (long packet)");
+ m_rx_chdr.axis.tready = 0;
+ m_tx_chdr.push_ramp_pkt(256, 64'd0, 64'h100, header);
+ m_rx_chdr.axis.tready = 1;
+ m_rx_chdr.wait_for_pkt_get_info(header_out, stats);
+ `ASSERT_ERROR(stats.count==256, "Bad packet: Length mismatch");
+ $sformat(s, "Bad packet: Wrong SID. Expected: %08x, Actual: %08x",
+ {header.src_sid,header.dst_sid},{header_out.src_sid,header_out.dst_sid});
+ `ASSERT_ERROR({header.src_sid,header.dst_sid}=={header_out.src_sid,header_out.dst_sid}, s);
+ `TEST_CASE_DONE(1);
+
+ header = '{
+ pkt_type:DATA, has_time:1, 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)");
+ repeat (10) @(posedge m_user_clk); //Wait for clear to go low
+ m_rx_chdr.axis.tready = 1;
+ fork
+ begin
+ m_tx_chdr.push_ramp_pkt(200, 64'd0, 64'h100, header);
+ end
+ begin
+ m_rx_chdr.wait_for_pkt_get_info(header_out, stats);
+ end
+ join
+ crc_cache = stats.crc; //Cache CRC for future test cases
+ `ASSERT_ERROR(stats.count==200, "Bad packet: Length mismatch");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Concurrent read and write (multiple packets)");
+ m_rx_chdr.axis.tready = 1;
+ fork
+ begin
+ repeat (20) begin
+ m_tx_chdr.push_ramp_pkt(20, 64'd0, 64'h100, header);
+ m_tx_chdr.push_bubble();
+ end
+ end
+ begin
+ repeat (20) begin
+ m_rx_chdr.wait_for_pkt_get_info(header_out, stats);
+ `ASSERT_ERROR(stats.count==20, "Bad packet: Length mismatch");
+ `ASSERT_ERROR(crc_cache==stats.crc, "Bad packet: Wrong CRC");
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Validate no drops (master)");
+ `TEST_CASE_DONE((m_overruns === 32'd0));
+
+ `TEST_CASE_START("Validate no drops (slave)");
+ `TEST_CASE_DONE((s_overruns === 32'd0));
+
+ s_bist_loopback <= 1'b1;
+
+ `TEST_CASE_START("Run PRBS BIST (Loopback Mode)");
+ @(posedge m_user_clk);
+ m_bist_gen <= 1'b1;
+ m_bist_rate <= 6'd60;
+ m_bist_check <= 1'b1;
+ @(posedge m_user_clk);
+ while (m_bist_locked !== 1'b1) @(posedge m_user_clk);
+ repeat (512) @(posedge m_user_clk);
+ `ASSERT_ERROR(m_bist_samps>256, "BIST: Num samples incorrect");
+ `ASSERT_ERROR(m_bist_errors===36'd0, "BIST: Errors!");
+ @(posedge m_user_clk);
+ m_bist_gen <= 1'b0;
+ repeat (256) @(posedge m_user_clk);
+ m_bist_check <= 1'b0;
+ `TEST_CASE_DONE(1'b1);
+
+ s_bist_loopback <= 1'b0;
+
+ `TEST_CASE_START("Validate no drops (master)");
+ `TEST_CASE_DONE((m_overruns === 32'd0));
+
+ `TEST_CASE_START("Validate no drops (slave)");
+ `TEST_CASE_DONE((s_overruns === 32'd0));
+
+ `TEST_BENCH_DONE;
+ end
+
+endmodule
diff --git a/fpga/usrp3/top/x300/sim/dram_fifo/Makefile b/fpga/usrp3/top/x300/sim/dram_fifo/Makefile
new file mode 100644
index 000000000..8cc56331c
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/dram_fifo/Makefile
@@ -0,0 +1,72 @@
+#
+# 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 = kintex7
+PART_ID = xc7k410t/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_2x64_128_bd/Makefile.inc
+include $(IP_DIR)/fifo_short_2clk/Makefile.inc
+include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+include $(IP_DIR)/axi4_dualport_sram/Makefile.inc
+
+DESIGN_SRCS += $(abspath \
+$(IP_DDR3_32BIT_SRCS) \
+$(IP_AXI_INTERCON_2X64_128_SRCS) \
+$(IP_AXI_INTERCON_2X64_128_BD_SRCS) \
+$(IP_FIFO_4K_2CLK_SRCS) \
+$(IP_FIFO_SHORT_2CLK_SRCS) \
+$(IP_AXI4_BRAM_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/x300/sim/dram_fifo/axis_dram_fifo_single.sv b/fpga/usrp3/top/x300/sim/dram_fifo/axis_dram_fifo_single.sv
new file mode 100644
index 000000000..d4aae6dd0
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/dram_fifo/axis_dram_fifo_single.sv
@@ -0,0 +1,589 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+
+`timescale 1ns/1ps
+
+module axis_dram_fifo_single
+#(
+ parameter USE_SRAM_MEMORY = 0,
+ parameter USE_BD_INTERCON = 0,
+ parameter SR_BASE = 0
+) (
+ input bus_clk,
+ input bus_rst,
+ input sys_clk,
+ input sys_rst,
+
+ 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
+);
+
+ // Misc declarations
+ axi4_rd_t #(.DWIDTH(64), .AWIDTH(32), .IDWIDTH(1)) dma_axi_rd(.clk(sys_clk));
+ axi4_wr_t #(.DWIDTH(64), .AWIDTH(32), .IDWIDTH(1)) dma_axi_wr(.clk(sys_clk));
+ axi4_rd_t #(.DWIDTH(256), .AWIDTH(32), .IDWIDTH(1)) mig_axi_rd(.clk(sys_clk));
+ axi4_wr_t #(.DWIDTH(256), .AWIDTH(32), .IDWIDTH(1)) mig_axi_wr(.clk(sys_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 [14: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.
+
+ 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
+ wire ddr3_axi_clk_x2;
+
+ always @(posedge ddr3_axi_clk)
+ ddr3_axi_rst_reg_n <= ~ddr3_axi_rst;
+
+ axi_dma_fifo #(
+ .DEFAULT_BASE(30'h00010000),
+ .DEFAULT_MASK(30'hFFFF0000),
+ .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 (ddr3_axi_clk_x2),
+ .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()
+ );
+
+ generate if (USE_SRAM_MEMORY) begin
+ assign init_calib_complete = 1;
+ assign ddr3_axi_clk = bus_clk;
+ assign ddr3_axi_clk_x2 = bus_clk;
+ assign ddr3_axi_rst = bus_rst;
+
+ axi4_dualport_sram axi4_dualport_sram_i1 (
+ .s_aclk (ddr3_axi_clk_x2), // input s_aclk
+ .s_aresetn (~ddr3_axi_rst), // input s_aresetn
+ .s_axi_awid (dma_axi_wr.addr.id), // input [0 : 0] s_axi_awid
+ .s_axi_awaddr (dma_axi_wr.addr.addr), // input [31 : 0] s_axi_awaddr
+ .s_axi_awlen (dma_axi_wr.addr.len), // input [7 : 0] s_axi_awlen
+ .s_axi_awsize (dma_axi_wr.addr.size), // input [2 : 0] s_axi_awsize
+ .s_axi_awburst (dma_axi_wr.addr.burst), // input [1 : 0] s_axi_awburst
+ .s_axi_awvalid (dma_axi_wr.addr.valid), // input s_axi_awvalid
+ .s_axi_awready (dma_axi_wr.addr.ready), // output s_axi_awready
+ .s_axi_wdata (dma_axi_wr.data.data ^ forced_bit_err), // input [63 : 0] s_axi_wdata
+ .s_axi_wstrb (dma_axi_wr.data.strb), // input [7 : 0] s_axi_wstrb
+ .s_axi_wlast (dma_axi_wr.data.last), // input s_axi_wlast
+ .s_axi_wvalid (dma_axi_wr.data.valid), // input s_axi_wvalid
+ .s_axi_wready (dma_axi_wr.data.ready), // output s_axi_wready
+ .s_axi_bid (dma_axi_wr.resp.id), // output [0 : 0] s_axi_bid
+ .s_axi_bresp (dma_axi_wr.resp.resp), // output [1 : 0] s_axi_bresp
+ .s_axi_bvalid (dma_axi_wr.resp.valid), // output s_axi_bvalid
+ .s_axi_bready (dma_axi_wr.resp.ready), // input s_axi_bready
+ .s_axi_arid (dma_axi_rd.addr.id), // input [0 : 0] s_axi_arid
+ .s_axi_araddr (dma_axi_rd.addr.addr), // input [31 : 0] s_axi_araddr
+ .s_axi_arlen (dma_axi_rd.addr.len), // input [7 : 0] s_axi_arlen
+ .s_axi_arsize (dma_axi_rd.addr.size), // input [2 : 0] s_axi_arsize
+ .s_axi_arburst (dma_axi_rd.addr.burst), // input [1 : 0] s_axi_arburst
+ .s_axi_arvalid (dma_axi_rd.addr.valid), // input s_axi_arvalid
+ .s_axi_arready (dma_axi_rd.addr.ready), // output s_axi_arready
+ .s_axi_rid (dma_axi_rd.data.id), // output [0 : 0] s_axi_rid
+ .s_axi_rdata (dma_axi_rd.data.data), // output [63 : 0] s_axi_rdata
+ .s_axi_rresp (dma_axi_rd.data.resp), // output [1 : 0] s_axi_rresp
+ .s_axi_rlast (dma_axi_rd.data.last), // output s_axi_rlast
+ .s_axi_rvalid (dma_axi_rd.data.valid), // output s_axi_rvalid
+ .s_axi_rready (dma_axi_rd.data.ready) // input s_axi_rready
+ );
+
+ end else begin //generate if (USE_SRAM_MEMORY) begin
+ //---------------------------------------------------
+ // We use an interconnect to connect to FIFOs.
+ //---------------------------------------------------
+ if (USE_BD_INTERCON) begin
+ // Vivado Block Diagram interconnect.
+ axi_intercon_2x64_128_bd_wrapper axi_intercon_2x64_128_i (
+ .S00_AXI_ACLK (ddr3_axi_clk_x2), // input S00_AXI_ACLK
+ .S00_AXI_ARESETN (~ddr3_axi_rst), // input S00_AXI_ARESETN
+ .S00_AXI_AWID (dma_axi_wr.addr.id), // input [0 : 0] S00_AXI_AWID
+ .S00_AXI_AWADDR (dma_axi_wr.addr.addr), // input [31 : 0] S00_AXI_AWADDR
+ .S00_AXI_AWLEN (dma_axi_wr.addr.len), // input [7 : 0] S00_AXI_AWLEN
+ .S00_AXI_AWSIZE (dma_axi_wr.addr.size), // input [2 : 0] S00_AXI_AWSIZE
+ .S00_AXI_AWBURST (dma_axi_wr.addr.burst), // input [1 : 0] S00_AXI_AWBURST
+ .S00_AXI_AWLOCK (dma_axi_wr.addr.lock), // input S00_AXI_AWLOCK
+ .S00_AXI_AWCACHE (dma_axi_wr.addr.cache), // input [3 : 0] S00_AXI_AWCACHE
+ .S00_AXI_AWPROT (dma_axi_wr.addr.prot), // input [2 : 0] S00_AXI_AWPROT
+ .S00_AXI_AWQOS (dma_axi_wr.addr.qos), // input [3 : 0] S00_AXI_AWQOS
+ .S00_AXI_AWVALID (dma_axi_wr.addr.valid), // input S00_AXI_AWVALID
+ .S00_AXI_AWREADY (dma_axi_wr.addr.ready), // output S00_AXI_AWREADY
+ .S00_AXI_WDATA (dma_axi_wr.data.data ^ forced_bit_err), // input [63 : 0] S00_AXI_WDATA
+ .S00_AXI_WSTRB (dma_axi_wr.data.strb), // input [7 : 0] S00_AXI_WSTRB
+ .S00_AXI_WLAST (dma_axi_wr.data.last), // input S00_AXI_WLAST
+ .S00_AXI_WVALID (dma_axi_wr.data.valid), // input S00_AXI_WVALID
+ .S00_AXI_WREADY (dma_axi_wr.data.ready), // output S00_AXI_WREADY
+ .S00_AXI_BID (dma_axi_wr.resp.id), // output [0 : 0] S00_AXI_BID
+ .S00_AXI_BRESP (dma_axi_wr.resp.resp), // output [1 : 0] S00_AXI_BRESP
+ .S00_AXI_BVALID (dma_axi_wr.resp.valid), // output S00_AXI_BVALID
+ .S00_AXI_BREADY (dma_axi_wr.resp.ready), // input S00_AXI_BREADY
+ .S00_AXI_ARID (dma_axi_rd.addr.id), // input [0 : 0] S00_AXI_ARID
+ .S00_AXI_ARADDR (dma_axi_rd.addr.addr), // input [31 : 0] S00_AXI_ARADDR
+ .S00_AXI_ARLEN (dma_axi_rd.addr.len), // input [7 : 0] S00_AXI_ARLEN
+ .S00_AXI_ARSIZE (dma_axi_rd.addr.size), // input [2 : 0] S00_AXI_ARSIZE
+ .S00_AXI_ARBURST (dma_axi_rd.addr.burst), // input [1 : 0] S00_AXI_ARBURST
+ .S00_AXI_ARLOCK (dma_axi_rd.addr.lock), // input S00_AXI_ARLOCK
+ .S00_AXI_ARCACHE (dma_axi_rd.addr.cache), // input [3 : 0] S00_AXI_ARCACHE
+ .S00_AXI_ARPROT (dma_axi_rd.addr.prot), // input [2 : 0] S00_AXI_ARPROT
+ .S00_AXI_ARQOS (dma_axi_rd.addr.qos), // input [3 : 0] S00_AXI_ARQOS
+ .S00_AXI_ARVALID (dma_axi_rd.addr.valid), // input S00_AXI_ARVALID
+ .S00_AXI_ARREADY (dma_axi_rd.addr.ready), // output S00_AXI_ARREADY
+ .S00_AXI_RID (dma_axi_rd.data.id), // output [0 : 0] S00_AXI_RID
+ .S00_AXI_RDATA (dma_axi_rd.data.data), // output [63 : 0] S00_AXI_RDATA
+ .S00_AXI_RRESP (dma_axi_rd.data.resp), // output [1 : 0] S00_AXI_RRESP
+ .S00_AXI_RLAST (dma_axi_rd.data.last), // output S00_AXI_RLAST
+ .S00_AXI_RVALID (dma_axi_rd.data.valid), // output S00_AXI_RVALID
+ .S00_AXI_RREADY (dma_axi_rd.data.ready), // input S00_AXI_RREADY
+ //
+ //.S01_AXI_ARESET_OUT_N (), // output S01_AXI_ARESET_OUT_N
+ .S01_AXI_ACLK (ddr3_axi_clk_x2), // 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 (0), // 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 (0), // input S01_AXI_RREADY
+ //
+ //.M00_AXI_ARESET_OUT_N (), // output M00_AXI_ARESET_OUT_N
+ .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
+ );
+ end else begin
+ //Original IP interconnect
+ axi_intercon_2x64_128 axi_intercon_2x64_128_i (
+ .INTERCONNECT_ACLK(ddr3_axi_clk_x2), // input INTERCONNECT_ACLK
+ .INTERCONNECT_ARESETN(~ddr3_axi_rst), // input INTERCONNECT_ARESETN
+ //
+ .S00_AXI_ARESET_OUT_N (), // output S00_AXI_ARESET_OUT_N
+ .S00_AXI_ACLK (ddr3_axi_clk_x2), // input S00_AXI_ACLK
+ .S00_AXI_AWID (dma_axi_wr.addr.id), // input [0 : 0] S00_AXI_AWID
+ .S00_AXI_AWADDR (dma_axi_wr.addr.addr), // input [31 : 0] S00_AXI_AWADDR
+ .S00_AXI_AWLEN (dma_axi_wr.addr.len), // input [7 : 0] S00_AXI_AWLEN
+ .S00_AXI_AWSIZE (dma_axi_wr.addr.size), // input [2 : 0] S00_AXI_AWSIZE
+ .S00_AXI_AWBURST (dma_axi_wr.addr.burst), // input [1 : 0] S00_AXI_AWBURST
+ .S00_AXI_AWLOCK (dma_axi_wr.addr.lock), // input S00_AXI_AWLOCK
+ .S00_AXI_AWCACHE (dma_axi_wr.addr.cache), // input [3 : 0] S00_AXI_AWCACHE
+ .S00_AXI_AWPROT (dma_axi_wr.addr.prot), // input [2 : 0] S00_AXI_AWPROT
+ .S00_AXI_AWQOS (dma_axi_wr.addr.qos), // input [3 : 0] S00_AXI_AWQOS
+ .S00_AXI_AWVALID (dma_axi_wr.addr.valid), // input S00_AXI_AWVALID
+ .S00_AXI_AWREADY (dma_axi_wr.addr.ready), // output S00_AXI_AWREADY
+ .S00_AXI_WDATA (dma_axi_wr.data.data ^ forced_bit_err), // input [63 : 0] S00_AXI_WDATA
+ .S00_AXI_WSTRB (dma_axi_wr.data.strb), // input [7 : 0] S00_AXI_WSTRB
+ .S00_AXI_WLAST (dma_axi_wr.data.last), // input S00_AXI_WLAST
+ .S00_AXI_WVALID (dma_axi_wr.data.valid), // input S00_AXI_WVALID
+ .S00_AXI_WREADY (dma_axi_wr.data.ready), // output S00_AXI_WREADY
+ .S00_AXI_BID (dma_axi_wr.resp.id), // output [0 : 0] S00_AXI_BID
+ .S00_AXI_BRESP (dma_axi_wr.resp.resp), // output [1 : 0] S00_AXI_BRESP
+ .S00_AXI_BVALID (dma_axi_wr.resp.valid), // output S00_AXI_BVALID
+ .S00_AXI_BREADY (dma_axi_wr.resp.ready), // input S00_AXI_BREADY
+ .S00_AXI_ARID (dma_axi_rd.addr.id), // input [0 : 0] S00_AXI_ARID
+ .S00_AXI_ARADDR (dma_axi_rd.addr.addr), // input [31 : 0] S00_AXI_ARADDR
+ .S00_AXI_ARLEN (dma_axi_rd.addr.len), // input [7 : 0] S00_AXI_ARLEN
+ .S00_AXI_ARSIZE (dma_axi_rd.addr.size), // input [2 : 0] S00_AXI_ARSIZE
+ .S00_AXI_ARBURST (dma_axi_rd.addr.burst), // input [1 : 0] S00_AXI_ARBURST
+ .S00_AXI_ARLOCK (dma_axi_rd.addr.lock), // input S00_AXI_ARLOCK
+ .S00_AXI_ARCACHE (dma_axi_rd.addr.cache), // input [3 : 0] S00_AXI_ARCACHE
+ .S00_AXI_ARPROT (dma_axi_rd.addr.prot), // input [2 : 0] S00_AXI_ARPROT
+ .S00_AXI_ARQOS (dma_axi_rd.addr.qos), // input [3 : 0] S00_AXI_ARQOS
+ .S00_AXI_ARVALID (dma_axi_rd.addr.valid), // input S00_AXI_ARVALID
+ .S00_AXI_ARREADY (dma_axi_rd.addr.ready), // output S00_AXI_ARREADY
+ .S00_AXI_RID (dma_axi_rd.data.id), // output [0 : 0] S00_AXI_RID
+ .S00_AXI_RDATA (dma_axi_rd.data.data), // output [63 : 0] S00_AXI_RDATA
+ .S00_AXI_RRESP (dma_axi_rd.data.resp), // output [1 : 0] S00_AXI_RRESP
+ .S00_AXI_RLAST (dma_axi_rd.data.last), // output S00_AXI_RLAST
+ .S00_AXI_RVALID (dma_axi_rd.data.valid), // output S00_AXI_RVALID
+ .S00_AXI_RREADY (dma_axi_rd.data.ready), // input S00_AXI_RREADY
+ //
+ .S01_AXI_ARESET_OUT_N (), // output S01_AXI_ARESET_OUT_N
+ .S01_AXI_ACLK (ddr3_axi_clk_x2), // input S01_AXI_ACLK
+ .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 (0), // 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 (0), // input S01_AXI_RREADY
+ //
+ .M00_AXI_ARESET_OUT_N (), // output M00_AXI_ARESET_OUT_N
+ .M00_AXI_ACLK (ddr3_axi_clk), // input M00_AXI_ACLK
+ .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
+ );
+ end
+
+ //---------------------------------------------------
+ // MIG
+ //---------------------------------------------------
+ wire ddr3_idelay_refclk;
+
+ 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_addn_clk_0 (ddr3_axi_clk_x2), // 300MHz clock out
+ .ui_addn_clk_1 (ddr3_idelay_refclk),
+ .ui_addn_clk_2 (),
+ .ui_addn_clk_3 (),
+ .ui_addn_clk_4 (),
+ .clk_ref_i (ddr3_idelay_refclk),
+ .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 (),
+ .device_temp_i (12'd0),
+ // 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_i (sys_clk), // From external 100MHz source.
+ .sys_rst (sys_rst)
+ );
+
+ //---------------------------------------------------
+ // 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)
+ );
+ end endgenerate
+
+endmodule
diff --git a/fpga/usrp3/top/x300/sim/dram_fifo/dram_fifo_tb.sv b/fpga/usrp3/top/x300/sim/dram_fifo/dram_fifo_tb.sv
new file mode 100644
index 000000000..0be9dc9dd
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/dram_fifo/dram_fifo_tb.sv
@@ -0,0 +1,184 @@
+//
+// 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"
+
+//`define USE_SRAM_FIFO //Use an AXI-Stream SRAM FIFO (for testing)
+`define USE_SRAM_MIG 0 //Use the DMA engine from the DRAM FIFO but SRAM as the base memory
+`define USE_BD_INTERCON 1 //Use the Block Design Axi Interconnect
+
+module dram_fifo_tb();
+ `TEST_BENCH_INIT("dram_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_CLK(sys_clk, 10, 50) //100MHz sys_clk to generate DDR3 clocking
+ `DEFINE_CLK(bus_clk, 1000/166.6667, 50) //166MHz bus_clk
+ `DEFINE_RESET(bus_rst, 0, 100) //100ns for GSR to deassert
+ `DEFINE_RESET(sys_rst, 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;
+`ifdef USE_SRAM_FIFO
+
+ axi_fifo #(.WIDTH(65), .SIZE(18)) dut_single (
+ .clk(bus_clk),
+ .reset(bus_rst),
+ .clear(1'b0),
+
+ .i_tdata({chdr_i.axis.tlast, chdr_i.axis.tdata}),
+ .i_tvalid(chdr_i.axis.tvalid),
+ .i_tready(chdr_i.axis.tready),
+
+ .o_tdata({chdr_o.axis.tlast, chdr_o.axis.tdata}),
+ .o_tvalid(chdr_o.axis.tvalid),
+ .o_tready(chdr_o.axis.tready),
+
+ .space(),
+ .occupied()
+ );
+ assign calib_complete = 1;
+
+`else
+
+ axis_dram_fifo_single #(
+ .USE_SRAM_MEMORY(`USE_SRAM_MIG),
+ .USE_BD_INTERCON(`USE_BD_INTERCON)
+ ) dut_single
+ (
+ .bus_clk(bus_clk),
+ .bus_rst(bus_rst),
+ .sys_clk(sys_clk),
+ .sys_rst(sys_rst),
+
+ .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)
+ );
+`endif
+
+ //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) @(posedge sys_clk);
+ `TEST_CASE_DONE((~bus_rst & ~sys_rst));
+
+ `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);
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_BENCH_DONE;
+
+ end
+
+endmodule
diff --git a/fpga/usrp3/top/x300/sim/dram_fifo_bist/Makefile b/fpga/usrp3/top/x300/sim/dram_fifo_bist/Makefile
new file mode 100644
index 000000000..8e75817b1
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/dram_fifo_bist/Makefile
@@ -0,0 +1,72 @@
+#
+# 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 = kintex7
+PART_ID = xc7k410t/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_2x64_128_bd/Makefile.inc
+include $(IP_DIR)/fifo_short_2clk/Makefile.inc
+include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+include $(IP_DIR)/axi4_dualport_sram/Makefile.inc
+
+DESIGN_SRCS += $(abspath \
+$(IP_DDR3_32BIT_SRCS) \
+$(IP_AXI_INTERCON_2X64_128_SRCS) \
+$(IP_AXI_INTERCON_2X64_128_BD_SRCS) \
+$(IP_FIFO_4K_2CLK_SRCS) \
+$(IP_FIFO_SHORT_2CLK_SRCS) \
+$(IP_AXI4_BRAM_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = dram_fifo_bist_tb
+
+SIM_SRCS = \
+$(abspath dram_fifo_bist_tb.sv) \
+$(abspath ../dram_fifo/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/x300/sim/dram_fifo_bist/dram_fifo_bist_tb.sv b/fpga/usrp3/top/x300/sim/dram_fifo_bist/dram_fifo_bist_tb.sv
new file mode 100644
index 000000000..33fb93332
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/dram_fifo_bist/dram_fifo_bist_tb.sv
@@ -0,0 +1,349 @@
+//
+// Copyright 2015 Ettus Research LLC
+//
+
+
+`timescale 1ns/1ps
+`define SIM_RUNTIME_US 3000
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 25
+
+`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"
+
+//`define USE_SRAM_FIFO //Use an AXI-Stream SRAM FIFO (for testing)
+`define USE_SRAM_MIG 1 //Use the DMA engine from the DRAM FIFO but SRAM as the base memory
+`define USE_BD_INTERCON 1 //Use the Block Design Axi Interconnect
+
+
+module dram_fifo_bist_tb();
+ `TEST_BENCH_INIT("dram_fifo_bist_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_CLK(sys_clk, 10, 50) //100MHz sys_clk to generate DDR3 clocking
+ `DEFINE_CLK(bus_clk, 1000/166.6667, 50) //166MHz bus_clk
+ `DEFINE_RESET(bus_rst, 0, 100) //100ns for GSR to deassert
+ `DEFINE_RESET(sys_rst, 0, 100) //100ns for GSR to deassert
+
+ // Initialize DUT
+ wire calib_complete;
+ wire running, done;
+ wire [1:0] error;
+ wire [31:0] rb_data;
+ reg [63:0] forced_bit_err;
+
+ settings_bus_master #(.SR_AWIDTH(8),.SR_DWIDTH(32)) tst_set (.clk(bus_clk));
+ cvita_master cvita_fifo_in (.clk(bus_clk));
+ cvita_slave cvita_fifo_out (.clk(bus_clk));
+
+ // AXI DRAM FIFO Topology (Inline production BIST for DRAM FIFO):
+ //
+ // User Data ====> |---------| |---------------| |-----------| ====> User Data Out
+ // | AXI MUX | ====> | AXI DRAM FIFO | ====> | AXI DEMUX |
+ // BIST Data ====> |---------| |---------------| |-----------| ====> BIST Data Out
+ // ||
+ // |--------------|
+ // | MIG (D/S)RAM |
+ // |--------------|
+
+ localparam SR_FIFO_BASE = 0;
+ localparam SR_BIST_BASE = SR_FIFO_BASE + 4;
+
+ axis_dram_fifo_single #(
+ .USE_SRAM_MEMORY(`USE_SRAM_MIG),
+ .USE_BD_INTERCON(`USE_BD_INTERCON),
+ .SR_BASE(SR_FIFO_BASE)
+ ) dut_single (
+ .bus_clk(bus_clk),
+ .bus_rst(bus_rst),
+ .sys_clk(sys_clk),
+ .sys_rst(sys_rst),
+
+ .i_tdata(cvita_fifo_in.axis.tdata),
+ .i_tlast(cvita_fifo_in.axis.tlast),
+ .i_tvalid(cvita_fifo_in.axis.tvalid),
+ .i_tready(cvita_fifo_in.axis.tready),
+
+ .o_tdata(cvita_fifo_out.axis.tdata),
+ .o_tlast(cvita_fifo_out.axis.tlast),
+ .o_tvalid(cvita_fifo_out.axis.tvalid),
+ .o_tready(cvita_fifo_out.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(rb_data),
+
+ .forced_bit_err(forced_bit_err),
+ .init_calib_complete(calib_complete)
+ );
+
+ assign {error, done, running} = rb_data[3:0];
+
+ //Testbench variables
+ cvita_hdr_t header;
+ cvita_pkt_t pkt_out;
+ integer i;
+ integer single_run_time;
+ integer xfer_cnt, cyc_cnt;
+
+ //------------------------------------------
+ //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) @(posedge sys_clk);
+ `TEST_CASE_DONE(~bus_rst & ~sys_rst);
+
+ forced_bit_err <= 64'h0;
+ repeat (200) @(posedge sys_clk);
+
+ `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(SR_FIFO_BASE + 1, {16'h0, 12'd280, 2'b00, 1'b0, 1'b1});
+ repeat (200) @(posedge bus_clk);
+ tst_set.write(SR_FIFO_BASE + 1, {16'h0, 12'd280, 2'b00, 1'b0, 1'b0});
+ repeat (200) @(posedge bus_clk);
+ `TEST_CASE_DONE(1);
+
+ //Select BIST status as the readback output
+ tst_set.write(SR_FIFO_BASE + 0, 3'd1);
+
+ 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 (long packet)");
+ cvita_fifo_in.push_ramp_pkt(100, 64'd0, 64'h100, header);
+ cvita_fifo_out.pull_pkt(pkt_out);
+ $sformat(s, "Bad packet: Length mismatch. Expected: %0d, Actual: %0d",100,pkt_out.payload.size());
+ `ASSERT_ERROR(pkt_out.payload.size()==100, 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);
+ i = 0;
+ repeat (100) 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("Setup BIST: 10 x 40byte packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h01234567);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b0, 13'd40, 18'd10});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd3, 2'd0, 1'b0, 1'b1});
+ while (~done) @(posedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Run BIST ... again (should fail)");
+ forced_bit_err <= 64'h8000000000000000;
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b1});
+ while (~done) @(posedge bus_clk);
+ `ASSERT_ERROR(error==2'b01, "BIST passed when it should have failed!");
+ forced_bit_err <= 64'h0;
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Run BIST ... and again (should pass)");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 0, {2'd2, 2'd0, 1'b0, 1'b1});
+ while (~done) @(posedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Setup BIST: 8000 x 40byte ramping packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h01234567);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b1, 13'd40, 18'd8000});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd3, 2'd0, 1'b0, 1'b1});
+ while (~done) @(posedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Setup BIST: 256 x 1000byte packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h0ABCDEF0);
+ tst_set.write(SR_BIST_BASE + 2, {8'd4, 16'd256});
+ tst_set.write(SR_BIST_BASE + 1, {1'b0, 13'd1000, 18'd256});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd1, 2'd0, 1'b0, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("User Data: Concurrent read and write");
+ cvita_fifo_out.axis.tready = 1;
+ fork
+ begin
+ cvita_fifo_in.push_ramp_pkt(20, 64'd0, 64'h100, header);
+ end
+ begin
+ cvita_fifo_out.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);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Setup BIST: 256 x 600byte ramping packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h01234567);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b1, 13'd600, 18'd256});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b1});
+ while (~done) @(posedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Setup BIST: 30 x 8000byte packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h0ABCDEF0);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b0, 13'd8000, 18'd30});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd1, 2'd0, 1'b0, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Setup BIST: 100 x 8000byte ramping packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'h0ABCDEF0);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b1, 13'd8000, 18'd100});
+ `TEST_CASE_DONE(~done & ~running);
+
+ `TEST_CASE_START("Run BIST");
+ tst_set.write(SR_BIST_BASE + 0, {2'd1, 2'd0, 1'b0, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Validate Throughput");
+ tst_set.write(SR_FIFO_BASE + 0, 3'd2);
+ xfer_cnt = rb_data;
+ tst_set.write(SR_FIFO_BASE + 0, 3'd3);
+ cyc_cnt = rb_data;
+ `ASSERT_ERROR(xfer_cnt>0, "Transfer count was not >0");
+ `ASSERT_ERROR(cyc_cnt>0, "Cycle count was not >0");
+ $display("Measured Throughput = %0d%% of bus_clk throughput", ((xfer_cnt*100)/cyc_cnt));
+ `ASSERT_ERROR(((xfer_cnt*100)/cyc_cnt)>80, "Throughput was less than 80%%");
+ tst_set.write(SR_FIFO_BASE + 0, 3'd1); //Restore
+ `TEST_CASE_DONE(done & ~running);
+
+ `TEST_CASE_START("Setup BIST: 10 x 256byte packets");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 3, 32'hFFFFFFFF);
+ tst_set.write(SR_BIST_BASE + 2, {8'd0, 16'd0});
+ tst_set.write(SR_BIST_BASE + 1, {1'b0, 13'd256, 18'd30});
+ `TEST_CASE_DONE(~done & ~running);
+
+ fork
+ begin
+ integer curr_time = $time;
+ `TEST_CASE_START("Run BIST Continuous (Early interrupt)");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 0, {2'd2, 2'd0, 1'b1, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ single_run_time = $time - curr_time;
+ `TEST_CASE_DONE(done & ~running);
+ end
+ begin
+ //Wait then clear
+ #2000;
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ end
+ join
+
+ fork
+ begin
+ `TEST_CASE_START("Run BIST Continuous (Force error)");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 0, {2'd2, 2'd0, 1'b1, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b01, "BIST passed when it should have failed!");
+ @(posedge bus_clk);
+ `TEST_CASE_DONE(done & ~running);
+ end
+ begin
+ //Wait then force error
+ #10000;
+ forced_bit_err <= 64'h1;
+ end
+ join
+ //Recover from failure
+ forced_bit_err <= 64'h0;
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ repeat (2000) @(posedge bus_clk);
+
+ fork
+ begin
+ integer curr_time = $time;
+ `TEST_CASE_START("Run BIST Continuous");
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ tst_set.write(SR_BIST_BASE + 0, {2'd2, 2'd0, 1'b1, 1'b1});
+ while (~done) @(negedge bus_clk);
+ `ASSERT_ERROR(error==2'b00, "BIST failed!");
+ @(posedge bus_clk);
+ `ASSERT_ERROR((($time - curr_time) > 2 * single_run_time), "Continuous test most likely stopped early!");
+ `TEST_CASE_DONE(done & ~running);
+ end
+ begin
+ //Wait then clear
+ #100000;
+ tst_set.write(SR_BIST_BASE + 0, {2'd0, 2'd0, 1'b0, 1'b0});
+ end
+ join
+
+ `TEST_CASE_START("Validate Throughput");
+ tst_set.write(SR_FIFO_BASE + 0, 3'd2);
+ xfer_cnt = rb_data;
+ tst_set.write(SR_FIFO_BASE + 0, 3'd3);
+ cyc_cnt = rb_data;
+ `ASSERT_ERROR(xfer_cnt>0, "Transfer count was not >0");
+ `ASSERT_ERROR(cyc_cnt>0, "Cycle count was not >0");
+ $display("Measured Throughput = %0d%% of bus_clk throughput", ((xfer_cnt*100)/cyc_cnt));
+ `ASSERT_ERROR(((xfer_cnt*100)/cyc_cnt)>80, "Throughput was less than 80%%");
+ tst_set.write(SR_FIFO_BASE + 0, 3'd1); //Restore
+ `TEST_CASE_DONE(done & ~running);
+ `TEST_BENCH_DONE;
+
+ end
+endmodule
diff --git a/fpga/usrp3/top/x300/sim/x300_pcie_int/Makefile b/fpga/usrp3/top/x300/sim/x300_pcie_int/Makefile
new file mode 100644
index 000000000..02aaef59c
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/x300_pcie_int/Makefile
@@ -0,0 +1,66 @@
+#
+# 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 = kintex7
+PART_ID = xc7k410t/ffg900/-2
+
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/control/Makefile.srcs
+include $(BASE_DIR)/../lib/packet_proc/Makefile.srcs
+include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+include $(BASE_DIR)/../lib/io_port2/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(FIFO_SRCS) \
+$(CONTROL_LIB_SRCS) \
+$(PACKET_PROC_SRCS) \
+$(IOPORT2_SRCS) \
+../../x300_pcie_int.v \
+)
+
+#-------------------------------------------------
+# 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)/fifo_short_2clk/Makefile.inc
+include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+
+DESIGN_SRCS += $(abspath \
+$(IP_FIFO_4K_2CLK_SRCS) \
+$(IP_FIFO_SHORT_2CLK_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = x300_pcie_int_tb
+
+SIM_SRCS = \
+$(abspath x300_pcie_int_tb.sv)
+
+#-------------------------------------------------
+# 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/x300/sim/x300_pcie_int/x300_pcie_int_tb.sv b/fpga/usrp3/top/x300/sim/x300_pcie_int/x300_pcie_int_tb.sv
new file mode 100644
index 000000000..0093e4315
--- /dev/null
+++ b/fpga/usrp3/top/x300/sim/x300_pcie_int/x300_pcie_int_tb.sv
@@ -0,0 +1,596 @@
+//
+// Copyright 2013 Ettus Research LLC
+//
+
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 23
+
+`define SIM_TIMEOUT_US 1000 // 1ms
+
+`include "sim_clks_rsts.vh"
+`include "sim_exec_report.vh"
+
+module x300_pcie_int_tb();
+ `DEFINE_CLK(clk, 8.000, 50)
+ `DEFINE_RESET(reset, 0, 10)
+
+ `TEST_BENCH_INIT("x300_pcie_int_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ reg temp_pass = 0;
+ reg pkt_swap = 0;
+ reg [15:0] it = 0;
+ reg [15:0] tx_ch, rx_ch = 0;
+
+ reg [31:0] dma_sample_cnt = 0;
+ reg [31:0] dma_packet_cnt = 0;
+ reg [31:0] dma_out_sample_cnt[0:5];
+ reg [63:0] dma_out_last_sample[0:5];
+
+ reg pcie_usr_reg_wr, pcie_usr_reg_rd;
+ reg [1:0] pcie_usr_reg_len;
+ reg [19:0] pcie_usr_reg_addr;
+ reg [31:0] pcie_usr_reg_data_in, pcie_usr_data;
+ wire pcie_usr_reg_rc, pcie_usr_reg_rdy;
+ wire [31:0] pcie_usr_reg_data_out;
+
+ wire chinch_reg_wr, chinch_reg_rd;
+ wire [1:0] chinch_reg_len;
+ wire [19:0] chinch_reg_addr;
+ wire [31:0] chinch_reg_data_out;
+ reg chinch_reg_rc, chinch_reg_rdy;
+ reg [31:0] chinch_reg_data_in;
+
+ reg [2:0] i_chan, o_chan;
+ reg [383:0] i_tdata_par;
+ reg [5:0] i_tvalid_par = 6'b000000, o_tready_par = 6'b111111;
+ wire [383:0] o_tdata_par;
+ wire [5:0] o_tvalid_par, i_tready_par;
+
+ reg i_tvalid, i_tready, o_tvalid, o_tready;
+ reg [63:0] i_tdata, o_tdata;
+
+ localparam READ = 2'b01;
+ localparam WRITE = 2'b10;
+
+ task usr_regport_request;
+ input [1:0] operation;
+ input [19:0] address;
+ input [31:0] data;
+ begin
+ pcie_usr_reg_data_in <= data;
+ pcie_usr_reg_addr <= address;
+ pcie_usr_reg_wr <= operation[1];
+ pcie_usr_reg_rd <= operation[0];
+ pcie_usr_reg_len <= 2'b10;
+
+ @(posedge clk);
+ while (~pcie_usr_reg_rdy) @(posedge clk);
+
+ pcie_usr_reg_wr <= 1'b0;
+ pcie_usr_reg_rd <= 1'b0;
+ @(posedge clk);
+ end
+ endtask // usr_regport_request
+
+ task usr_regport_response;
+ begin
+ @(posedge clk);
+ while (~pcie_usr_reg_rc) @(posedge clk);
+ pcie_usr_data <= pcie_usr_reg_data_out;
+ @(posedge clk);
+ end
+ endtask // usr_regport_response
+
+ task chinch_regport_request;
+ input [1:0] operation;
+ input [19:0] address;
+ input [31:0] data;
+ begin
+ @(posedge clk);
+ while (~(chinch_reg_rdy &&
+ chinch_reg_addr == address &&
+ {chinch_reg_wr,chinch_reg_rd} == operation &&
+ chinch_reg_len == 2'b10 &&
+ (operation == WRITE || chinch_reg_data_out == data)
+ )) @(posedge clk);
+
+ @(posedge clk);
+ end
+ endtask // chinch_regport_request
+
+ task chinch_regport_response;
+ input [31:0] data;
+ begin
+ @(posedge clk);
+ chinch_reg_data_in <= data;
+ chinch_reg_rc <= 1'b1;
+ @(posedge clk);
+ chinch_reg_rc <= 1'b0;
+ end
+ endtask // chinch_regport_response
+
+ task send_packet;
+ input [63:0] sid;
+ input [31:0] len;
+ input [31:0] quant;
+ begin
+ if(quant < 2) begin
+ i_tdata <= { sid[63:32],len[15:0], sid[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ @(posedge clk);
+ end else begin
+ i_tdata <= { sid[63:32],len[15:0], sid[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tdata <= 64'h0000_0001_0000_0000;
+ repeat(quant - 2) begin
+ i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
+ @(posedge clk);
+ end
+ i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
+ @(posedge clk);
+ i_tvalid <= 1'b0;
+ @(posedge clk);
+ end // else: !if(len < 3)
+ end
+ endtask // send_packet
+
+ task reset_dma_counts;
+ begin
+ dma_sample_cnt <= 32'd0;
+ dma_packet_cnt <= 32'd0;
+ dma_out_sample_cnt[0] <= 32'd0;
+ dma_out_sample_cnt[1] <= 32'd0;
+ dma_out_sample_cnt[2] <= 32'd0;
+ dma_out_sample_cnt[3] <= 32'd0;
+ dma_out_sample_cnt[4] <= 32'd0;
+ dma_out_sample_cnt[5] <= 32'd0;
+ dma_out_last_sample[0] <= 64'd0;
+ dma_out_last_sample[1] <= 64'd0;
+ dma_out_last_sample[2] <= 64'd0;
+ dma_out_last_sample[3] <= 64'd0;
+ dma_out_last_sample[4] <= 64'd0;
+ dma_out_last_sample[5] <= 64'd0;
+ @(posedge clk);
+ end
+ endtask // reset_dma_counts
+
+ task select_channels;
+ input [2:0] tx_ch;
+ input [2:0] rx_ch;
+ begin
+ i_chan <= tx_ch;
+ o_chan <= rx_ch;
+ @(posedge clk);
+ end
+ endtask // select_channels
+
+ task wait_for_pkt_loopback;
+ begin
+ while (i_tvalid & i_tready) @(posedge clk); //Wait for outbound pkt to pad and send
+ while (~o_tvalid) @(posedge clk); //Wait for inbound pkt to arrive
+ while (o_tvalid & o_tready) @(posedge clk); //Wait for inbound pkt to finish
+ end
+ endtask // wait_for_pkt_loopback
+
+ wire [63:0] dma_loop_tdata ;
+ wire [ 2:0] dma_loop_tuser ;
+ wire dma_loop_tvalid, dma_loop_tlast, dma_loop_tready;
+
+ wire [63:0] iop2_msg_tdata ;
+ wire iop2_msg_tvalid, iop2_msg_tlast, iop2_msg_tready;
+
+
+ initial begin : tb_main
+ while (reset) @(posedge clk);
+
+ chinch_reg_rdy <= 1'b1;
+ chinch_reg_rc <= 1'b0;
+
+ `TEST_CASE_START("Verify signature register");
+ usr_regport_request(READ, 20'h40000, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE((pcie_usr_data == "X300"))
+
+ `TEST_CASE_START("Verify counter frequency register");
+ usr_regport_request(READ, 20'h4000C, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE((pcie_usr_data == 166666667));
+
+ `TEST_CASE_START("Verify scratch registers");
+ usr_regport_request(WRITE, 20'h40010, 32'hDEAD);
+ usr_regport_request(WRITE, 20'h40014, 32'hBEEF);
+ usr_regport_request(READ, 20'h40014, 32'h0);
+ usr_regport_response();
+ temp_pass <= (pcie_usr_data == 32'hBEEF);
+ usr_regport_request(READ, 20'h40010, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE((pcie_usr_data == 32'hDEAD) & temp_pass);
+
+ `TEST_CASE_START("Client register port write 1");
+ usr_regport_request(WRITE, 20'h60000, 32'h12345678);
+ chinch_regport_request(WRITE, 20'h60000, 32'h12345678);
+
+ usr_regport_request(WRITE, 20'h7FFFC, 32'h1357);
+ chinch_regport_request(WRITE, 20'h7FFFC, 32'h1357);
+
+ usr_regport_request(WRITE, 20'h70000, 32'h2468);
+ chinch_regport_request(WRITE, 20'h70000, 32'h2468);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Client register port read 1");
+ usr_regport_request(READ, 20'h60000, 32'h0);
+ chinch_regport_request(READ, 20'h60000, 32'h0);
+ chinch_regport_response(32'hACE0BA51);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32'hACE0BA51),"");
+
+ usr_regport_request(READ, 20'h7FFFC, 32'h0);
+ chinch_regport_request(READ, 20'h7FFFC, 32'h0);
+ chinch_regport_response(32'hACE0BA52);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32'hACE0BA52),"");
+
+ usr_regport_request(READ, 20'h70000, 32'h0);
+ chinch_regport_request(READ, 20'h70000, 32'h0);
+ chinch_regport_response(32'hACE0BA53);
+ usr_regport_response();
+ `TEST_CASE_DONE((pcie_usr_data == 32'hACE0BA53));
+
+ `TEST_CASE_START("Configure RX DMA routing table");
+ usr_regport_request(WRITE, 20'h40500, 32'h0000_0000);
+ usr_regport_request(WRITE, 20'h40500, 32'h0001_0001);
+ usr_regport_request(WRITE, 20'h40500, 32'h0002_0002);
+ usr_regport_request(WRITE, 20'h40500, 32'h0003_0003);
+ usr_regport_request(WRITE, 20'h40500, 32'h00D3_0000);
+ usr_regport_request(WRITE, 20'h40500, 32'h00D2_0001);
+ usr_regport_request(WRITE, 20'h40500, 32'h00D1_0002);
+ usr_regport_request(WRITE, 20'h40500, 32'h00D0_0003);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Frame size register read");
+ usr_regport_request(READ, 20'h40204, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32), "Frame size register read (Default) [TX0].");
+ usr_regport_request(READ, 20'h40214, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32), "Frame size register read (Default) [TX1].");
+ usr_regport_request(READ, 20'h40404, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32), "Frame size register read (Default) [RX0].");
+ usr_regport_request(READ, 20'h40414, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 32), "Frame size register read (Default) [RX1].");
+ `TEST_CASE_DONE(1);
+
+ o_tready <= 1'b1;
+
+ `TEST_CASE_START("Loopback packet");
+ reset_dma_counts();
+ usr_regport_request(WRITE, 20'h40200, 32'h0000_0012);
+ usr_regport_request(WRITE, 20'h40400, 32'h0000_0012);
+ select_channels(0,0);
+ send_packet(16'h00D2, 80, 32);
+ wait_for_pkt_loopback();
+ `TEST_CASE_DONE((dma_sample_cnt==10 && dma_packet_cnt==1 && dma_out_sample_cnt[0]==32));
+
+ reset_dma_counts();
+ select_channels(1,0);
+ send_packet(16'h00D3, 80, 32);
+ wait_for_pkt_loopback();
+ `TEST_CASE_DONE(dma_sample_cnt==10 && dma_packet_cnt==1 && dma_out_sample_cnt[0]==32);
+
+ `TEST_CASE_START("Frame size register write.");
+ usr_regport_request(WRITE, 20'h40224, 32'd16);
+ usr_regport_request(WRITE, 20'h40234, 32'd16);
+ usr_regport_request(WRITE, 20'h40424, 32'd16);
+ usr_regport_request(WRITE, 20'h40434, 32'd16);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Frame size register read");
+ usr_regport_request(READ, 20'h40224, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 16), "Frame size register read [TX2].");
+ usr_regport_request(READ, 20'h40234, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 16), "Frame size register read [TX3].");
+ usr_regport_request(READ, 20'h40424, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 16), "Frame size register read [RX2].");
+ usr_regport_request(READ, 20'h40434, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 16), "Frame size register read [RX3].");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Loopback packet");
+ reset_dma_counts();
+ select_channels(2,2);
+ send_packet(16'h0002, 32, 16);
+ wait_for_pkt_loopback();
+ `TEST_CASE_DONE(dma_sample_cnt==4 && dma_packet_cnt==1 && dma_out_sample_cnt[2]==16);
+
+ reset_dma_counts();
+ select_channels(3,3);
+ send_packet(16'h0003, 32, 16);
+ wait_for_pkt_loopback();
+ `TEST_CASE_DONE((dma_sample_cnt==4 && dma_packet_cnt==1 && dma_out_sample_cnt[3]==16));
+
+ `TEST_CASE_START("Loopback multiple packets");
+ reset_dma_counts();
+ select_channels(3,2);
+ send_packet(16'h0002, 128, 16);
+ send_packet(16'h0002, 128, 16);
+ send_packet(16'h0002, 128, 16);
+ send_packet(16'h0002, 128, 16);
+ wait_for_pkt_loopback();
+ repeat(64) @(posedge clk);
+ `TEST_CASE_DONE(dma_sample_cnt==64 && dma_packet_cnt==4 && dma_out_sample_cnt[2]==64 && o_tdata==64'h0000009e00000020);
+
+ `TEST_CASE_START("Loopback multiple packets (RX Swapped)");
+ reset_dma_counts();
+ select_channels(3,2);
+
+ usr_regport_request(WRITE, 20'h40230, 32'h10);
+ usr_regport_request(WRITE, 20'h40420, 32'h00);
+ repeat(16) @(posedge clk);
+
+ send_packet(16'h0002, 128, 16);
+ send_packet(16'h0002, 128, 16);
+ wait_for_pkt_loopback();
+ repeat(64) @(posedge clk);
+ `TEST_CASE_DONE(dma_sample_cnt==32 && dma_packet_cnt==2 && dma_out_sample_cnt[2]==32 && o_tdata==64'h000000200000009e);
+
+ /* @TODO: Need to implement data swapping in TB
+ `TEST_CASE_START();
+ reset_dma_counts();
+ select_channels(3,2);
+
+ usr_regport_request(WRITE, 20'h40230, 32'h00);
+ usr_regport_request(WRITE, 20'h40420, 32'h10);
+ repeat(16) @(posedge clk);
+
+ send_packet(16'h0002, 128, 16);
+ send_packet(16'h0002, 128, 16);
+ wait_for_pkt_loopback();
+ repeat(64) @(posedge clk);
+ `TEST_CASE_DONE(dma_sample_cnt==32 && dma_packet_cnt==2 && dma_out_sample_cnt[2]==32 && o_tdata[7:0]==32,
+ "Loopback multiple packets (TX Swapped).");
+ */
+
+ `TEST_CASE_START("Good DMA status.");
+ reset_dma_counts();
+ select_channels(3,2);
+ usr_regport_request(READ, 20'h40230, 32'h0);
+ usr_regport_response();
+ temp_pass <= (pcie_usr_data == 32'h0);
+ usr_regport_request(READ, 20'h40420, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE(temp_pass && (pcie_usr_data == 32'h0));
+
+ `TEST_CASE_START("Bad DMA status.");
+ send_packet(16'h0002, 160, 20);
+ repeat(64) @(posedge clk);
+ usr_regport_request(READ, 20'h40230, 32'h0);
+ usr_regport_response();
+ temp_pass <= (pcie_usr_data == 32'h1);
+ usr_regport_request(READ, 20'h40420, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE(temp_pass || (pcie_usr_data == 32'h1));
+
+ `TEST_CASE_START("DMA Status reset.");
+ usr_regport_request(WRITE, 20'h40230, 32'h1);
+ usr_regport_request(READ, 20'h40230, 32'h0);
+ usr_regport_response();
+ temp_pass <= (pcie_usr_data == 32'h0);
+ usr_regport_request(WRITE, 20'h40420, 32'h1);
+ usr_regport_request(READ, 20'h40420, 32'h0);
+ usr_regport_response();
+ `TEST_CASE_DONE(temp_pass && (pcie_usr_data == 32'h0));
+
+ `TEST_CASE_START("Packet count register reset");
+ select_channels(2,1);
+ reset_dma_counts();
+ usr_regport_request(WRITE, 20'h4022C, 32'h0);
+ usr_regport_request(READ, 20'h4022C, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 0), "TX Packet count register reset.");
+ usr_regport_request(WRITE, 20'h4041C, 32'h0);
+ usr_regport_request(READ, 20'h4041C, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 0), "RX Packet count register reset.");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("TX Packet count register read");
+ send_packet(16'h0001, 80, 16);
+ send_packet(16'h0001, 24, 16);
+ send_packet(16'h0001, 48, 16);
+ repeat(64) @(posedge clk);
+ usr_regport_request(READ, 20'h4022C, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 3), "TX Packet count register read.");
+ usr_regport_request(READ, 20'h4041C, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 3), "RX Packet count register read.");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("TX Sample count register reset");
+ select_channels(1,2);
+ reset_dma_counts();
+ usr_regport_request(WRITE, 20'h40218, 32'h0);
+ usr_regport_request(READ, 20'h40218, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 0), "TX Sample count register reset.");
+ usr_regport_request(WRITE, 20'h40428, 32'h0);
+ usr_regport_request(READ, 20'h40428, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 0), "RX Sample count register reset.");
+ `TEST_CASE_DONE(1'b1);
+
+ `TEST_CASE_START("TX Sample count register read");
+ send_packet(16'h0002, 28, 16);
+ wait_for_pkt_loopback();
+ usr_regport_request(READ, 20'h40218, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 4), "TX Sample count register read.");
+ usr_regport_request(READ, 20'h40428, 32'h0);
+ usr_regport_response();
+ `ASSERT_ERROR((pcie_usr_data == 4), "RX Sample count register read.");
+ `TEST_CASE_DONE(1'b1);
+
+ `TEST_CASE_START("Setup for NxN DMA test");
+ for (it = 0; it < 16'd6; it = it + 16'd1) begin
+ usr_regport_request(WRITE, 20'h40204 + (it * 16), 32'h4);
+ usr_regport_request(WRITE, 20'h40404 + (it * 16), 32'h4);
+ usr_regport_request(WRITE, 20'h40500, {it, it});
+ end
+ `TEST_CASE_DONE(1'b1);
+
+ `TEST_CASE_START("Setup for NxN DMA test");
+ for (tx_ch = 0; tx_ch < 6; tx_ch = tx_ch + 16'd2) begin
+ for (rx_ch = 1; rx_ch < 6; rx_ch = rx_ch + 16'd1) begin
+ select_channels(tx_ch,rx_ch);
+ reset_dma_counts();
+ @(posedge clk);
+ send_packet(rx_ch, 16, 4);
+ wait_for_pkt_loopback();
+ if (dma_sample_cnt==2 && dma_packet_cnt==1 && dma_out_sample_cnt[rx_ch]==4) begin
+ $display("[TEST%d]: NxN DMA Test [TX=%d, RX=%d]...Passed",tc_run_count,tx_ch[3:0],rx_ch[3:0]);
+ end else begin
+ $display("[TEST%d]: NxN DMA Test [TX=%d, RX=%d]...FAILED!!!",tc_run_count,tx_ch[3:0],rx_ch[3:0]);
+ end
+ @(posedge clk);
+ end
+ end
+ `TEST_CASE_DONE(1'b1);
+ end // initial begin
+
+
+ x300_pcie_int #(
+ .DMA_STREAM_WIDTH (64),
+ .NUM_TX_STREAMS (6 ),
+ .NUM_RX_STREAMS (6 ),
+ .REGPORT_ADDR_WIDTH(20),
+ .REGPORT_DATA_WIDTH(32),
+ .IOP2_MSG_WIDTH (64)
+ ) x300_pcie_int (
+ .ioport2_clk (clk ),
+ .bus_clk (clk ),
+ .bus_rst (reset ),
+
+ //DMA TX FIFOs (IoPort2 Clock Domain)
+ .dmatx_tdata_iop2 (i_tdata_par ),
+ .dmatx_tvalid_iop2 (i_tvalid_par ),
+ .dmatx_tready_iop2 (i_tready_par ),
+
+ //DMA TX FIFOs (IoPort2 Clock Domain)
+ .dmarx_tdata_iop2 (o_tdata_par ),
+ .dmarx_tvalid_iop2 (o_tvalid_par ),
+ .dmarx_tready_iop2 (o_tready_par ),
+
+ //PCIe User Regport
+ .pcie_usr_reg_wr (pcie_usr_reg_wr ),
+ .pcie_usr_reg_rd (pcie_usr_reg_rd ),
+ .pcie_usr_reg_addr (pcie_usr_reg_addr ),
+ .pcie_usr_reg_data_in (pcie_usr_reg_data_in ),
+ .pcie_usr_reg_len (pcie_usr_reg_len ),
+ .pcie_usr_reg_data_out(pcie_usr_reg_data_out),
+ .pcie_usr_reg_rc (pcie_usr_reg_rc ),
+ .pcie_usr_reg_rdy (pcie_usr_reg_rdy ),
+
+ //Chinch Regport
+ .chinch_reg_wr (chinch_reg_wr ),
+ .chinch_reg_rd (chinch_reg_rd ),
+ .chinch_reg_addr (chinch_reg_addr ),
+ .chinch_reg_data_out (chinch_reg_data_out ),
+ .chinch_reg_len (chinch_reg_len ),
+ .chinch_reg_data_in (chinch_reg_data_in ),
+ .chinch_reg_rc (chinch_reg_rc ),
+ .chinch_reg_rdy (chinch_reg_rdy ),
+
+ //DMA TX FIFO (Bus Clock Domain)
+ .dmatx_tdata (dma_loop_tdata ),
+ .dmatx_tuser (dma_loop_tuser ),
+ .dmatx_tlast (dma_loop_tlast ),
+ .dmatx_tvalid (dma_loop_tvalid ),
+ .dmatx_tready (dma_loop_tready ),
+
+ //DMA RX FIFO (Bus Clock Domain)
+ .dmarx_tdata (dma_loop_tdata ),
+ .dmarx_tuser (dma_loop_tuser ),
+ .dmarx_tlast (dma_loop_tlast ),
+ .dmarx_tvalid (dma_loop_tvalid ),
+ .dmarx_tready (dma_loop_tready ),
+
+ //Message FIFO Out (Bus Clock Domain)
+ .rego_tdata (iop2_msg_tdata ),
+ .rego_tvalid (iop2_msg_tvalid ),
+ .rego_tlast (iop2_msg_tlast ),
+ .rego_tready (iop2_msg_tready ),
+
+ //Message FIFO In (Bus Clock Domain)
+ .regi_tdata (iop2_msg_tdata ),
+ .regi_tvalid (iop2_msg_tvalid ),
+ .regi_tlast (iop2_msg_tlast ),
+ .regi_tready (iop2_msg_tready ),
+
+ .debug ( )
+ );
+
+ always @(posedge clk) begin
+ if (dma_loop_tvalid & dma_loop_tready) begin
+ dma_sample_cnt <= dma_sample_cnt + 32'd1;
+ if (dma_loop_tlast) dma_packet_cnt <= dma_packet_cnt + 32'd1;
+ end
+ end
+
+ always @(posedge clk) begin
+ case (i_chan)
+ 3'd5:
+ {i_tdata_par[383:320], i_tvalid_par[5], i_tready} <= {i_tdata, i_tvalid, i_tready_par[5]};
+ 3'd4:
+ {i_tdata_par[319:256], i_tvalid_par[4], i_tready} <= {i_tdata, i_tvalid, i_tready_par[4]};
+ 3'd3:
+ {i_tdata_par[255:192], i_tvalid_par[3], i_tready} <= {i_tdata, i_tvalid, i_tready_par[3]};
+ 3'd2:
+ {i_tdata_par[191:128], i_tvalid_par[2], i_tready} <= {i_tdata, i_tvalid, i_tready_par[2]};
+ 3'd1:
+ {i_tdata_par[127:64], i_tvalid_par[1], i_tready} <= {i_tdata, i_tvalid, i_tready_par[1]};
+ default:
+ {i_tdata_par[63:0], i_tvalid_par[0], i_tready} <= {i_tdata, i_tvalid, i_tready_par[0]};
+ endcase
+ end
+
+ always @(posedge clk) begin
+ case (o_chan)
+ 3'd5:
+ {o_tdata, o_tvalid, o_tready_par[5]} <= {o_tdata_par[383:320], o_tvalid_par[5], o_tready};
+ 3'd4:
+ {o_tdata, o_tvalid, o_tready_par[4]} <= {o_tdata_par[319:256], o_tvalid_par[4], o_tready};
+ 3'd3:
+ {o_tdata, o_tvalid, o_tready_par[3]} <= {o_tdata_par[255:192], o_tvalid_par[3], o_tready};
+ 3'd2:
+ {o_tdata, o_tvalid, o_tready_par[2]} <= {o_tdata_par[191:128], o_tvalid_par[2], o_tready};
+ 3'd1:
+ {o_tdata, o_tvalid, o_tready_par[1]} <= {o_tdata_par[127:64], o_tvalid_par[1], o_tready};
+ default:
+ {o_tdata, o_tvalid, o_tready_par[0]} <= {o_tdata_par[63:0], o_tvalid_par[0], o_tready};
+ endcase
+ end
+
+ genvar i;
+ generate
+ for (i=0; i<6; i=i+1) begin: dma_counter_generator
+ always @(posedge clk) begin
+ if (o_tvalid_par[i] & o_tready_par[i]) begin
+ dma_out_sample_cnt[i] <= dma_out_sample_cnt[i] + 32'd1;
+ dma_out_last_sample[i] <= o_tdata_par[(64*i)+63:64*i];
+ end
+ end
+ end
+ endgenerate
+
+endmodule