aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/sim
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/sim')
-rw-r--r--fpga/usrp3/lib/sim/Makefile.srcs26
-rw-r--r--fpga/usrp3/lib/sim/arm_deframer/Makefile47
-rw-r--r--fpga/usrp3/lib/sim/arm_deframer/arm_deframer_tb.sv112
-rw-r--r--fpga/usrp3/lib/sim/axi/axis_shift_register/Makefile49
-rw-r--r--fpga/usrp3/lib/sim/axi/axis_shift_register/axis_shift_register_tb.sv325
-rw-r--r--fpga/usrp3/lib/sim/axi/axis_width_conv/Makefile35
-rw-r--r--fpga/usrp3/lib/sim/axi/axis_width_conv/axis_width_conv_tb.sv322
-rw-r--r--fpga/usrp3/lib/sim/axi_packet_gate/Makefile46
-rw-r--r--fpga/usrp3/lib/sim/axi_packet_gate/axi_packet_gate_tb.sv347
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/gtk.conf.gtkw64
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/simulation_script.v82
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/gtk.conf.gtkw64
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/simulation_script.v83
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain/ddc_chain_tb.v94
-rwxr-xr-xfpga/usrp3/lib/sim/dsp/ddc_chain/run_isim18
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/.gitignore4
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/DDC.sav101
-rwxr-xr-xfpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/run_isim17
-rwxr-xr-xfpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/simcmds.tcl9
-rw-r--r--fpga/usrp3/lib/sim/dsp/ddc_chain_x300/ddc_chain_x300_tb.v64
-rw-r--r--fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/.gitignore4
-rwxr-xr-xfpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/run_isim17
-rwxr-xr-xfpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/simcmds.tcl9
-rw-r--r--fpga/usrp3/lib/sim/dsp/hb47_int/hb47_int_tb.v136
-rw-r--r--fpga/usrp3/lib/sim/dsp/mult_add_clip/Makefile45
-rw-r--r--fpga/usrp3/lib/sim/dsp/mult_add_clip/mult_add_clip_tb.sv137
-rw-r--r--fpga/usrp3/lib/sim/dsp/rx_frontend/rx_frontend_tb.v50
-rw-r--r--fpga/usrp3/lib/sim/dsp/variable_delay_line/Makefile47
-rw-r--r--fpga/usrp3/lib/sim/dsp/variable_delay_line/variable_delay_line_tb.sv117
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_dram_fifo/default.wcfg412
-rwxr-xr-xfpga/usrp3/lib/sim/fifo/axi_dram_fifo/run_isim16
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/default.wcfg412
-rwxr-xr-xfpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/run_isim17
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/simulation_script.v118
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/Default.wcfg388
-rwxr-xr-xfpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/run_isim19
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/simulation_script.v96
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_fifo/Makefile34
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_fifo/axi_fifo_tb.sv134
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_fifo_2clk/axi_fifo_2clk_tb.sv121
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_fifo_2clk_sim.v230
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_fifo_32_64/axi_fifo_32_64_tb.v121
-rw-r--r--fpga/usrp3/lib/sim/fifo/axi_packet_gate/axi_packet_gate_tb.v112
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/Makefile53
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/cap_pattern_verifier_tb.sv199
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v780
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_tb.v350
-rwxr-xr-xfpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.build21
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.v115
-rwxr-xr-xfpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.build21
-rw-r--r--fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.v103
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v92
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v110
-rw-r--r--fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v243
-rw-r--r--fpga/usrp3/lib/sim/packet_proc/chdr_chunker/chdr_chunker_tb.v190
-rw-r--r--fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/Makefile33
-rw-r--r--fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/chdr_dechunker_tb.sv200
-rw-r--r--fpga/usrp3/lib/sim/packet_proc/ip_hdr_checksum/ip_hdr_checksum_tb.v43
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/axi_pipe/axi_pipe_tb.v74
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/axi_rate_change/Makefile37
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/axi_rate_change/axi_rate_change_tb.sv323
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/axi_rate_change/wave.do115
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/axi_wrapper/axi_wrapper_tb.v144
-rwxr-xr-xfpga/usrp3/lib/sim/rfnoc/axi_wrapper/build_axi_wrapper_tb1
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/chdr_deframer/chdr_deframer_tb.v87
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/chdr_framer/chdr_framer_tb.v80
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/display_samples.grc413
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/gen_samples.grc381
-rwxr-xr-xfpga/usrp3/lib/sim/rfnoc/moving_sum/build_moving_sum_tb1
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/moving_sum/moving_sum_tb.v43
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/mult/mult_tb.v75
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/mult_add/mult_add_tb.v90
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/null_source/null_source_tb.v80
-rwxr-xr-xfpga/usrp3/lib/sim/rfnoc/window/build_window_tb1
-rw-r--r--fpga/usrp3/lib/sim/rfnoc/window/window_tb.v341
-rw-r--r--fpga/usrp3/lib/sim/simple_gemac/ll8_to_axi64/ll8_to_axi64_tb.v100
-rw-r--r--fpga/usrp3/lib/sim/simple_gemac/simple_gemac_tb.v208
-rwxr-xr-xfpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper.build1
-rw-r--r--fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper_tb.v213
-rw-r--r--fpga/usrp3/lib/sim/wishbone/simple_uart/simple_uart_tb.v132
80 files changed, 10194 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/sim/Makefile.srcs b/fpga/usrp3/lib/sim/Makefile.srcs
new file mode 100644
index 000000000..b76175cd9
--- /dev/null
+++ b/fpga/usrp3/lib/sim/Makefile.srcs
@@ -0,0 +1,26 @@
+#
+# Copyright 2016 Ettus Research
+#
+
+# Minimal set of sources in lib directory needed for simulation
+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/timing/Makefile.srcs
+include $(BASE_DIR)/../lib/packet_proc/Makefile.srcs
+include $(BASE_DIR)/../lib/dsp/Makefile.srcs
+include $(BASE_DIR)/../lib/rfnoc/Makefile.srcs
+
+# Use sim version of axi_fifo_2clk
+FIFO_SRCS := $(filter-out %/axi_fifo_2clk.v,$(FIFO_SRCS))
+FIFO_SRCS += $(abspath $(BASE_DIR)/../lib/sim/fifo/axi_fifo_2clk_sim.v)
+
+SIM_DESIGN_SRCS = $(abspath \
+$(FIFO_SRCS) \
+$(AXI_SRCS) \
+$(CONTROL_LIB_SRCS) \
+$(TIMING_SRCS) \
+$(PACKET_PROC_SRCS) \
+$(DSP_SRCS) \
+$(RFNOC_SRCS) \
+)
diff --git a/fpga/usrp3/lib/sim/arm_deframer/Makefile b/fpga/usrp3/lib/sim/arm_deframer/Makefile
new file mode 100644
index 000000000..eb7231d5e
--- /dev/null
+++ b/fpga/usrp3/lib/sim/arm_deframer/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright 2015 Ettus Research LLC
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# IP Specific
+#-------------------------------------------------
+# If simulation contains IP, define the IP_DIR and point
+# it to the base level IP directory
+LIB_IP_DIR = $(BASE_DIR)/../lib/ip
+
+# Include makefiles and sources for all IP components
+# *after* defining the IP_DIR
+
+DESIGN_SRCS += $(abspath \
+../../packet_proc/arm_deframer.v \
+../../fifo/axi_mux4.v \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = arm_deframer_tb
+
+SIM_SRCS = $(abspath \
+$(SIM_PROTORFNOC_SRCS) \
+arm_deframer_tb.sv \
+)
+
+MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/arm_deframer/arm_deframer_tb.sv b/fpga/usrp3/lib/sim/arm_deframer/arm_deframer_tb.sv
new file mode 100644
index 000000000..4e252b5b4
--- /dev/null
+++ b/fpga/usrp3/lib/sim/arm_deframer/arm_deframer_tb.sv
@@ -0,0 +1,112 @@
+/////////////////////////////////////////////////////////////////////
+//
+// Copyright 2016-2017 Ettus Research
+//
+// Arm Deframer Testbench
+//
+// Arm Deframer adds a 6 bit padding to the ethernet frame
+//
+//////////////////////////////////////////////////////////////////////
+
+`timescale 1ns/1ps
+`define SIM_RUNTIME_US 0.0001
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 3
+`include "sim_axis_lib.svh"
+`include "sim_exec_report.vh"
+`include "sim_rfnoc_lib.svh"
+`include "sim_set_rb_lib.svh"
+
+// NOTE: The tesbench is not self-checking
+module arm_deframer_tb();
+ `TEST_BENCH_INIT("arm_deframer_tb",`NUM_TEST_CASES,`NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e6/166.67e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(rst, 0, 100);
+
+ axis_master #(.DWIDTH(68)) m_axis (.clk(clk));
+ axis_slave #(.DWIDTH(68)) s_axis (.clk(clk));
+
+ reg clear;
+ wire [63:0] c2e_tdata_int;
+ wire [3:0] c2e_tuser_int;
+ wire c2e_tlast_int;
+ wire c2e_tvalid_int;
+ wire c2e_tready_int;
+
+ arm_deframer inst_arm_deframer (
+ .clk (clk),
+ .reset (rst),
+ .clear (clear),
+ .s_axis_tdata (m_axis.axis.tdata[63:0]),
+ .s_axis_tuser (m_axis.axis.tdata[67:64]),
+ .s_axis_tlast (m_axis.axis.tlast),
+ .s_axis_tvalid (m_axis.axis.tvalid),
+ .s_axis_tready (m_axis.axis.tready),
+ .m_axis_tdata (c2e_tdata_int),
+ .m_axis_tuser (c2e_tuser_int),
+ .m_axis_tlast (c2e_tlast_int),
+ .m_axis_tvalid (c2e_tvalid_int),
+ .m_axis_tready (c2e_tready_int)
+ );
+
+ axi_mux4 #(.PRIO(0), .WIDTH(68)) eth_mux
+ (.clk(clk), .reset(reset), .clear(clear),
+ .i0_tdata({c2e_tuser_int,c2e_tdata_int}), .i0_tlast(c2e_tlast_int), .i0_tvalid(c2e_tvalid_int), .i0_tready(c2e_tready_int),
+ .i1_tdata(), .i1_tlast(), .i1_tvalid(), .i1_tready(),
+ .i2_tdata(), .i2_tlast(), .i2_tvalid(), .i2_tready(),
+ .i3_tdata(), .i3_tlast(), .i3_tvalid(1'b0), .i3_tready(),
+ .o_tdata(s_axis.axis.tdata), .o_tlast(s_axis.axis.tlast), .o_tvalid(s_axis.axis.tvalid), .o_tready(1'b1/*s_axis.axis.tready*/));
+
+ reg [63:0] out_tdata;
+ reg [3:0] tuser;
+ reg tlast;
+
+ initial begin
+ forever begin
+ s_axis.pull_word({tuser,out_tdata}, tlast);
+ $display("tuser = %d, out_tdata = %x, last = %d", tuser, out_tdata, tlast);
+ end
+ end
+
+ initial begin : tb_main
+ `TEST_CASE_START("Wait for reset");
+ m_axis.reset;
+ while (rst) @(posedge clk);
+ `TEST_CASE_DONE(~rst);
+
+ `TEST_CASE_START("Send frame");
+ repeat (10) @(posedge clk);
+ for (int j = 0; j < 2; j ++) begin
+ @(posedge clk);
+ $display("----------New Frame---------------");
+ for (int i = 0; i < 9; i ++) begin
+ m_axis.push_word({4'h0,64'h1111111111111111 * i}, 1'b0);
+ //m_axis.push_bubble();
+ end
+ m_axis.push_word({4'h1,64'h9999999999999999}, 1'b1);
+ //m_axis.push_bubble();
+ end
+ @(posedge clk);
+ @(posedge clk);
+ `TEST_CASE_DONE(1);
+ repeat (10) @(posedge clk);
+
+ `TEST_CASE_START("Send frame with bubble");
+ repeat (10) @(posedge clk);
+ for (int j = 0; j < 2; j ++) begin
+ @(posedge clk);
+ $display("----------New Frame---------------");
+ for (int i = 0; i < 9; i ++) begin
+ m_axis.push_word({4'h0,64'h1111111111111111 * i}, 1'b0);
+ m_axis.push_bubble();
+ end
+ m_axis.push_word({4'h1,64'h9999999999999999}, 1'b1);
+ m_axis.push_bubble();
+ end
+ @(posedge clk);
+ @(posedge clk);
+ `TEST_CASE_DONE(1);
+ `TEST_BENCH_DONE;
+ end
+endmodule
diff --git a/fpga/usrp3/lib/sim/axi/axis_shift_register/Makefile b/fpga/usrp3/lib/sim/axi/axis_shift_register/Makefile
new file mode 100644
index 000000000..8a65a6024
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi/axis_shift_register/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright 2018 Ettus Research, A National Instruments Company
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Design Specific
+#-------------------------------------------------
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/axi/Makefile.srcs
+include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+include $(BASE_DIR)/../lib/control/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(AXI_SRCS) \
+$(FIFO_SRCS) \
+$(CONTROL_LIB_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = axis_shift_register_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+axis_shift_register_tb.sv \
+)
+
+# MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/axi/axis_shift_register/axis_shift_register_tb.sv b/fpga/usrp3/lib/sim/axi/axis_shift_register/axis_shift_register_tb.sv
new file mode 100644
index 000000000..1ce868069
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi/axis_shift_register/axis_shift_register_tb.sv
@@ -0,0 +1,325 @@
+//
+// Copyright 2018 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 8
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_axis_lib.svh"
+
+module axis_shift_register_tb();
+ `TEST_BENCH_INIT("axis_shift_register_tb", `NUM_TEST_CASES, `NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/100.0e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ localparam WIDTH = 32;
+ localparam integer NUM_INST = 4;
+
+ logic [WIDTH:0] i_tdata[0:NUM_INST-1];
+ logic i_tlast[0:NUM_INST-1], i_tvalid[0:NUM_INST-1];
+ wire i_tready[0:NUM_INST-1];
+ wire [WIDTH:0] o_tdata[0:NUM_INST-1];
+ wire o_tlast[0:NUM_INST-1], o_tvalid[0:NUM_INST-1];
+ logic o_tready[0:NUM_INST-1];
+ wire [15:0] stage_stb[0:NUM_INST-1], stage_eop[0:NUM_INST-1];
+ wire [WIDTH-1:0] sb_dout, sb_din;
+ wire sb_keep;
+ reg [WIDTH-1:0] sb_shreg[0:2];
+ always @(posedge clk) begin
+ if (stage_stb[2][0])
+ sb_shreg[0] <= sb_dout;
+ if (stage_stb[2][1])
+ sb_shreg[1] <= sb_shreg[0];
+ if (stage_stb[2][2])
+ sb_shreg[2] <= sb_shreg[1];
+ end
+ assign sb_din = sb_shreg[2];
+
+ axis_shift_register #(
+ .WIDTH(WIDTH), .NSPC(1), .LATENCY(2),
+ .SIDEBAND_DATAPATH(0), .GAPLESS(0),
+ .PIPELINE("NONE")
+ ) inst_0 (
+ .clk(clk), .reset(reset),
+ .s_axis_tdata(i_tdata[0]), .s_axis_tkeep(i_tdata[0][WIDTH]), .s_axis_tlast(i_tlast[0]),
+ .s_axis_tvalid(i_tvalid[0]), .s_axis_tready(i_tready[0]),
+ .m_axis_tdata(o_tdata[0]), .m_axis_tkeep(o_tdata[0][WIDTH]), .m_axis_tlast(o_tlast[0]),
+ .m_axis_tvalid(o_tvalid[0]), .m_axis_tready(o_tready[0]),
+ .stage_stb(stage_stb[0]), .stage_eop(stage_eop[0]),
+ .m_sideband_data(), .m_sideband_keep(), .s_sideband_data()
+ );
+
+ axis_shift_register #(
+ .WIDTH(WIDTH), .NSPC(1), .LATENCY(9),
+ .SIDEBAND_DATAPATH(0), .GAPLESS(0),
+ .PIPELINE("BOTH")
+ ) inst_1 (
+ .clk(clk), .reset(reset),
+ .s_axis_tdata(i_tdata[1]), .s_axis_tkeep(i_tdata[1][WIDTH]), .s_axis_tlast(i_tlast[1]),
+ .s_axis_tvalid(i_tvalid[1]), .s_axis_tready(i_tready[1]),
+ .m_axis_tdata(o_tdata[1]), .m_axis_tkeep(o_tdata[1][WIDTH]), .m_axis_tlast(o_tlast[1]),
+ .m_axis_tvalid(o_tvalid[1]), .m_axis_tready(o_tready[1]),
+ .stage_stb(stage_stb[1]), .stage_eop(stage_eop[1]),
+ .m_sideband_data(), .m_sideband_keep(), .s_sideband_data()
+ );
+
+ axis_shift_register #(
+ .WIDTH(WIDTH/2), .NSPC(2), .LATENCY(3),
+ .SIDEBAND_DATAPATH(1), .GAPLESS(0),
+ .PIPELINE("NONE")
+ ) inst_2 (
+ .clk(clk), .reset(reset),
+ .s_axis_tdata(i_tdata[2]), .s_axis_tkeep(i_tdata[2][WIDTH]), .s_axis_tlast(i_tlast[2]),
+ .s_axis_tvalid(i_tvalid[2]), .s_axis_tready(i_tready[2]),
+ .m_axis_tdata(o_tdata[2]), .m_axis_tkeep(o_tdata[2][WIDTH]), .m_axis_tlast(o_tlast[2]),
+ .m_axis_tvalid(o_tvalid[2]), .m_axis_tready(o_tready[2]),
+ .stage_stb(stage_stb[2]), .stage_eop(stage_eop[2]),
+ .m_sideband_data(sb_dout), .m_sideband_keep(sb_keep), .s_sideband_data(sb_din)
+ );
+
+ axis_shift_register #(
+ .WIDTH(WIDTH/8), .NSPC(8), .LATENCY(14),
+ .SIDEBAND_DATAPATH(0), .GAPLESS(1),
+ .PIPELINE("NONE")
+ ) inst_3 (
+ .clk(clk), .reset(reset),
+ .s_axis_tdata(i_tdata[3]), .s_axis_tkeep(i_tdata[3][WIDTH]), .s_axis_tlast(i_tlast[3]),
+ .s_axis_tvalid(i_tvalid[3]), .s_axis_tready(i_tready[3]),
+ .m_axis_tdata(o_tdata[3]), .m_axis_tkeep(o_tdata[3][WIDTH]), .m_axis_tlast(o_tlast[3]),
+ .m_axis_tvalid(o_tvalid[3]), .m_axis_tready(o_tready[3]),
+ .stage_stb(stage_stb[3]), .stage_eop(stage_eop[3]),
+ .m_sideband_data(), .m_sideband_keep(), .s_sideband_data()
+ );
+
+ logic [15:0] prev_stage_stb[0:NUM_INST-1];
+ initial begin : tb_main
+ string s;
+
+ `TEST_CASE_START("Wait for Reset");
+ for (int k = 0; k < NUM_INST; k=k+1) begin
+ o_tready[k] = 1'b1;
+ i_tvalid[k] = 1'b0;
+ prev_stage_stb[k] = 0;
+ end
+ while (reset) @(posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ `TEST_CASE_START("Check module with LATENCY=2, PIPELINE=NONE");
+ `ASSERT_ERROR(o_tvalid[0] == 1'b0, "Output incorrectly active when idle");
+ `ASSERT_ERROR(i_tready[0] == 1'b1, "Input was not ready when idle");
+ `ASSERT_ERROR(stage_stb[0][1:0] === 0, "Incorrect stage_stb when idle");
+ for (int j = 0; j < 2; j=j+1) begin
+ i_tdata[0] = j;
+ i_tlast[0] = j % 2;
+ i_tvalid[0] = 1'b1;
+ @(posedge clk);
+ i_tvalid[0] = 1'b0;
+ prev_stage_stb[0][1:0] = {prev_stage_stb[0][0], 1'b1};
+ `ASSERT_ERROR(stage_stb[0][1:0] == prev_stage_stb[0][1:0], "Incorrect stage_stb");
+ `ASSERT_ERROR(i_tready[0] == 1'b1, "Input was not ready during fill-up");
+ `ASSERT_ERROR(o_tvalid[0] == 1'b0, "Output incorrectly active during fill-up");
+ end
+ for (int j = 0; j < 2; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[0] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[0] == j % 2, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[0] == j, "Incorrect tdata");
+ end
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=9, PIPELINE=BOTH");
+ prev_stage_stb[1] = 0;
+ `ASSERT_ERROR(o_tvalid[1] == 1'b0, "Output incorrectly active when idle");
+ `ASSERT_ERROR(i_tready[1] == 1'b1, "Input was not ready when idle");
+ `ASSERT_ERROR(stage_stb[1][1:0] === 0, "Incorrect stage_stb when idle");
+ for (int j = 0; j < 9; j=j+1) begin
+ i_tdata[1] = -j;
+ i_tlast[1] = 1'b1;
+ i_tvalid[1] = 1'b1;
+ @(posedge clk);
+ i_tvalid[1] = 1'b0;
+ prev_stage_stb[1][8:0] = {prev_stage_stb[1][7:0], 1'b1};
+ `ASSERT_ERROR(stage_eop[1][8:0] == prev_stage_stb[1][8:0], "Incorrect stage_eop");
+ `ASSERT_ERROR(stage_stb[1][8:0] == prev_stage_stb[1][8:0], "Incorrect stage_stb");
+ `ASSERT_ERROR(i_tready[1] == 1'b1, "Input was not ready during fill-up");
+ `ASSERT_ERROR(o_tvalid[1] == 1'b0, "Output incorrectly active during fill-up");
+ end
+ for (int j = 0; j < 9; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[1] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[1] == 1'b1, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[1] == -j, "Incorrect tdata");
+ end
+ @(posedge clk);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=9, PIPELINE=BOTH (backpressure)");
+ prev_stage_stb[1] = 0;
+ o_tready[1] = 1'b0;
+ `ASSERT_ERROR(o_tvalid[1] == 1'b0, "Output incorrectly active when idle");
+ `ASSERT_ERROR(i_tready[1] == 1'b1, "Input was not ready when idle");
+ `ASSERT_ERROR(stage_stb[1][1:0] === 0, "Incorrect stage_stb when idle");
+ for (int j = 0; j < 9; j=j+1) begin
+ i_tdata[1] = -j;
+ i_tlast[1] = 1'b1;
+ i_tvalid[1] = 1'b1;
+ @(posedge clk);
+ i_tvalid[1] = 1'b0;
+ prev_stage_stb[1][8:0] = {prev_stage_stb[1][7:0], 1'b1};
+ `ASSERT_ERROR(stage_stb[1][8:0] == prev_stage_stb[1][8:0], "Incorrect stage_stb");
+ `ASSERT_ERROR(stage_eop[1][8:0] == prev_stage_stb[1][8:0], "Incorrect stage_eop");
+ `ASSERT_ERROR(i_tready[1] == 1'b1, "Input was not ready during fill-up");
+ `ASSERT_ERROR(o_tvalid[1] == 1'b0, "Output incorrectly active during fill-up");
+ end
+ o_tready[1] = 1'b1;
+ for (int j = 0; j < 9; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[1] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[1] == 1'b1, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[1] == -j, "Incorrect tdata");
+ end
+ @(posedge clk);
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=9, PIPELINE=BOTH (steady-state)");
+ prev_stage_stb[1] = 0;
+ fork
+ begin
+ for (int j = 0; j < 50; j=j+1) begin
+ i_tdata[1] = j;
+ i_tlast[1] = j % 2;
+ i_tvalid[1] = 1'b1;
+ @(posedge clk);
+ i_tvalid[1] = 1'b0;
+ prev_stage_stb[1][8:0] = {prev_stage_stb[1][7:0], 1'b1};
+ `ASSERT_ERROR(stage_stb[1][8:0] == prev_stage_stb[1][8:0], "Incorrect stage_stb");
+ end
+ end
+ begin
+ o_tready[1] = 1'b1;
+ repeat(9) @(posedge clk);
+ for (int j = 0; j < 50; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[1] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[1] == j % 2, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[1] == j, "Incorrect tdata");
+ end
+ @(posedge clk);
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=9, PIPELINE=BOTH (gaps)");
+ prev_stage_stb[1] = 0;
+ fork
+ begin
+ for (int j = 0; j < 50; j=j+1) begin
+ i_tdata[1] = j;
+ i_tlast[1] = j % 2;
+ i_tvalid[1] = 1'b1;
+ @(posedge clk);
+ while (~i_tready[1]) @(posedge clk);
+ i_tvalid[1] = 1'b0;
+ end
+ end
+ begin
+ o_tready[1] = 1'b1;
+ repeat(9) @(posedge clk);
+ for (int j = 0; j < 20; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[1] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[1] == j % 2, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[1] == j, "Incorrect tdata");
+ end
+ o_tready[1] = 1'b0;
+ repeat(4) @(posedge clk);
+ o_tready[1] = 1'b1;
+ for (int j = 20; j < 50; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[1] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[1] == j % 2, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[1] == j, "Incorrect tdata");
+ end
+ @(posedge clk);
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=3, SIDEBAND=1 (gaps)");
+ prev_stage_stb[2] = 0;
+ fork
+ begin
+ for (int j = 0; j < 50; j=j+1) begin
+ i_tdata[2] = j;
+ i_tlast[2] = j % 4 == 0;
+ i_tvalid[2] = 1'b1;
+ @(posedge clk);
+ while (~i_tready[2]) @(posedge clk);
+ i_tvalid[2] = 1'b0;
+ end
+ end
+ begin
+ o_tready[2] = 1'b1;
+ repeat(3) @(posedge clk);
+ for (int j = 0; j < 20; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[2] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[2] == j % 4 == 0, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[2] == j, "Incorrect tdata");
+ end
+ o_tready[2] = 1'b0;
+ repeat(4) @(posedge clk);
+ o_tready[2] = 1'b1;
+ for (int j = 20; j < 50; j=j+1) begin
+ @(posedge clk);
+ `ASSERT_ERROR(o_tvalid[2] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[2] == j % 4 == 0, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[2] == j, "Incorrect tdata");
+ end
+ @(posedge clk);
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check module with LATENCY=14, GAPLESS=1");
+ prev_stage_stb[3] = 0;
+ o_tready[3] = 1'b0;
+ fork
+ begin
+ for (int j = 0; j < 50; j=j+1) begin
+ i_tdata[3] = j;
+ i_tlast[3] = j % 4 == 0;
+ i_tvalid[3] = 1'b1;
+ @(posedge clk);
+ prev_stage_stb[3][13:0] = {prev_stage_stb[3][12:0], 1'b1};
+ `ASSERT_ERROR(stage_stb[3][13:0] == prev_stage_stb[3][13:0], "Incorrect stage_stb");
+ while (~i_tready[3]) @(posedge clk);
+ i_tvalid[3] = 1'b0;
+ if (j > 16) repeat($urandom_range(0, 15)) @(posedge clk);
+ `ASSERT_ERROR(stage_stb[3][13:0] == prev_stage_stb[3][13:0] || stage_stb[3][13:0] == 14'd0, "Incorrect stage_stb");
+ end
+ end
+ begin
+ for (int j = 0; j < 50 - 14; j=j+1) begin
+ while (~o_tvalid[3]) @(posedge clk);
+ @(negedge clk);
+ `ASSERT_ERROR(o_tvalid[3] == 1'b1, "Output was not active");
+ `ASSERT_ERROR(o_tlast[3] == j % 4 == 0, "Incorrect tlast");
+ `ASSERT_ERROR(o_tdata[3] == j, "Incorrect tdata");
+ o_tready[3] = 1'b1;
+ @(negedge clk);
+ o_tready[3] = 1'b0;
+ @(posedge clk);
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+ `TEST_BENCH_DONE;
+ end
+endmodule
diff --git a/fpga/usrp3/lib/sim/axi/axis_width_conv/Makefile b/fpga/usrp3/lib/sim/axi/axis_width_conv/Makefile
new file mode 100644
index 000000000..2e7d0ba0c
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi/axis_width_conv/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright 2018 Ettus Research, A National Instruments Company
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = axis_width_conv_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+axis_width_conv_tb.sv \
+)
+
+# MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/axi/axis_width_conv/axis_width_conv_tb.sv b/fpga/usrp3/lib/sim/axi/axis_width_conv/axis_width_conv_tb.sv
new file mode 100644
index 000000000..0b1f4414c
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi/axis_width_conv/axis_width_conv_tb.sv
@@ -0,0 +1,322 @@
+//
+// Copyright 2018 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 13
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_axis_lib.svh"
+
+module axis_width_conv_tb();
+ `TEST_BENCH_INIT("axis_width_conv_tb", `NUM_TEST_CASES, `NS_PER_TICK);
+
+ `DEFINE_CLK(clk50, 20.000, 50);
+ `DEFINE_CLK(clk200, 5.000, 50);
+ `DEFINE_LATE_START_CLK(clk166, 6.000, 50, 0.37, 0.01)
+ `DEFINE_RESET(areset, 0, 100);
+
+ localparam WORD_W = 8;
+ localparam integer NINST = 6;
+ localparam integer IN_WORDS[0:NINST-1] = {1, 4, 4, 8, 8, 17};
+ localparam integer OUT_WORDS[0:NINST-1] = {4, 1, 3, 2, 8, 19};
+ localparam integer MAX_IN_WORDS = 20;
+ localparam integer MAX_OUT_WORDS = 20;
+ localparam integer MAX_SPP = 100;
+
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[0])) m0 (.clk(clk50));
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[1])) m1 (.clk(clk50));
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[2])) m2 (.clk(clk50));
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[3])) m3 (.clk(clk50));
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[4])) m4 (.clk(clk50));
+ axis_master #(.DWIDTH((WORD_W+1)*IN_WORDS[5])) m5 (.clk(clk50));
+
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[0])) s0 (.clk(clk50));
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[1])) s1 (.clk(clk50));
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[2])) s2 (.clk(clk200));
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[3])) s3 (.clk(clk166));
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[4])) s4 (.clk(clk166));
+ axis_slave #(.DWIDTH((WORD_W+1)*OUT_WORDS[5])) s5 (.clk(clk50));
+
+ // An integer 1-to-4 upsizer
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[0]), .OUT_WORDS(OUT_WORDS[0]),
+ .SYNC_CLKS(1), .PIPELINE("INOUT")
+ ) dut0 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m0.axis.tdata[(IN_WORDS[0]*WORD_W)-1:0]),
+ .s_axis_tkeep (m0.axis.tdata[IN_WORDS[0]*WORD_W+:IN_WORDS[0]]),
+ .s_axis_tlast (m0.axis.tlast),
+ .s_axis_tvalid(m0.axis.tvalid),
+ .s_axis_tready(m0.axis.tready),
+ .m_axis_aclk (clk50),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s0.axis.tdata[(OUT_WORDS[0]*WORD_W)-1:0]),
+ .m_axis_tkeep (s0.axis.tdata[OUT_WORDS[0]*WORD_W+:OUT_WORDS[0]]),
+ .m_axis_tlast (s0.axis.tlast),
+ .m_axis_tvalid(s0.axis.tvalid),
+ .m_axis_tready(s0.axis.tready)
+ );
+
+ // An integer 4-to-1 downsizer
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[1]), .OUT_WORDS(OUT_WORDS[1]),
+ .SYNC_CLKS(1), .PIPELINE("IN")
+ ) dut1 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m1.axis.tdata[(IN_WORDS[1]*WORD_W)-1:0]),
+ .s_axis_tkeep (m1.axis.tdata[IN_WORDS[1]*WORD_W+:IN_WORDS[1]]),
+ .s_axis_tlast (m1.axis.tlast),
+ .s_axis_tvalid(m1.axis.tvalid),
+ .s_axis_tready(m1.axis.tready),
+ .m_axis_aclk (clk50),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s1.axis.tdata[(OUT_WORDS[1]*WORD_W)-1:0]),
+ .m_axis_tkeep (s1.axis.tdata[OUT_WORDS[1]*WORD_W+:OUT_WORDS[1]]),
+ .m_axis_tlast (s1.axis.tlast),
+ .m_axis_tvalid(s1.axis.tvalid),
+ .m_axis_tready(s1.axis.tready)
+ );
+
+ // A rational integer 4-to-3 downsizer
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[2]), .OUT_WORDS(OUT_WORDS[2]),
+ .SYNC_CLKS(0), .PIPELINE("OUT")
+ ) dut2 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m2.axis.tdata[(IN_WORDS[2]*WORD_W)-1:0]),
+ .s_axis_tkeep (m2.axis.tdata[IN_WORDS[2]*WORD_W+:IN_WORDS[2]]),
+ .s_axis_tlast (m2.axis.tlast),
+ .s_axis_tvalid(m2.axis.tvalid),
+ .s_axis_tready(m2.axis.tready),
+ .m_axis_aclk (clk200),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s2.axis.tdata[(OUT_WORDS[2]*WORD_W)-1:0]),
+ .m_axis_tkeep (s2.axis.tdata[OUT_WORDS[2]*WORD_W+:OUT_WORDS[2]]),
+ .m_axis_tlast (s2.axis.tlast),
+ .m_axis_tvalid(s2.axis.tvalid),
+ .m_axis_tready(s2.axis.tready)
+ );
+
+ // An integer 4-to-1 downsizer but with 2 words per cycle
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[3]), .OUT_WORDS(OUT_WORDS[3]),
+ .SYNC_CLKS(0), .PIPELINE("NONE")
+ ) dut3 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m3.axis.tdata[(IN_WORDS[3]*WORD_W)-1:0]),
+ .s_axis_tkeep (m3.axis.tdata[IN_WORDS[3]*WORD_W+:IN_WORDS[3]]),
+ .s_axis_tlast (m3.axis.tlast),
+ .s_axis_tvalid(m3.axis.tvalid),
+ .s_axis_tready(m3.axis.tready),
+ .m_axis_aclk (clk166),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s3.axis.tdata[(OUT_WORDS[3]*WORD_W)-1:0]),
+ .m_axis_tkeep (s3.axis.tdata[OUT_WORDS[3]*WORD_W+:OUT_WORDS[3]]),
+ .m_axis_tlast (s3.axis.tlast),
+ .m_axis_tvalid(s3.axis.tvalid),
+ .m_axis_tready(s3.axis.tready)
+ );
+
+ // A passthrough module (no up/down sizing) but with 8 words per cycle
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[4]), .OUT_WORDS(OUT_WORDS[4]),
+ .SYNC_CLKS(0), .PIPELINE("INOUT")
+ ) dut4 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m4.axis.tdata[(IN_WORDS[4]*WORD_W)-1:0]),
+ .s_axis_tkeep (m4.axis.tdata[IN_WORDS[4]*WORD_W+:IN_WORDS[4]]),
+ .s_axis_tlast (m4.axis.tlast),
+ .s_axis_tvalid(m4.axis.tvalid),
+ .s_axis_tready(m4.axis.tready),
+ .m_axis_aclk (clk166),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s4.axis.tdata[(OUT_WORDS[4]*WORD_W)-1:0]),
+ .m_axis_tkeep (s4.axis.tdata[OUT_WORDS[4]*WORD_W+:OUT_WORDS[4]]),
+ .m_axis_tlast (s4.axis.tlast),
+ .m_axis_tvalid(s4.axis.tvalid),
+ .m_axis_tready(s4.axis.tready)
+ );
+
+ // A rational integer 17-to-19 upsizer
+ axis_width_conv #(
+ .WORD_W(WORD_W), .IN_WORDS(IN_WORDS[5]), .OUT_WORDS(OUT_WORDS[5]),
+ .SYNC_CLKS(1), .PIPELINE("INOUT")
+ ) dut5 (
+ .s_axis_aclk (clk50),
+ .s_axis_rst (areset),
+ .s_axis_tdata (m5.axis.tdata[(IN_WORDS[5]*WORD_W)-1:0]),
+ .s_axis_tkeep (m5.axis.tdata[IN_WORDS[5]*WORD_W+:IN_WORDS[5]]),
+ .s_axis_tlast (m5.axis.tlast),
+ .s_axis_tvalid(m5.axis.tvalid),
+ .s_axis_tready(m5.axis.tready),
+ .m_axis_aclk (clk50),
+ .m_axis_rst (areset),
+ .m_axis_tdata (s5.axis.tdata[(OUT_WORDS[5]*WORD_W)-1:0]),
+ .m_axis_tkeep (s5.axis.tdata[OUT_WORDS[5]*WORD_W+:OUT_WORDS[5]]),
+ .m_axis_tlast (s5.axis.tlast),
+ .m_axis_tvalid(s5.axis.tvalid),
+ .m_axis_tready(s5.axis.tready)
+ );
+
+ // Push a test ramp packet into the specific instance of the module
+ // - words: The size of the packet in words
+ // - inst: The instance number of the module to send to
+ // - gaps: If 1 then insert bubble cycles randomly in the stream
+ task push_test_pkt(input integer words, input integer inst, input logic gaps);
+ begin
+ logic [(MAX_IN_WORDS*WORD_W)-1:0] data = 0;
+ logic [MAX_IN_WORDS-1:0] keep = 0;
+ logic last = 0;
+ integer nspc = IN_WORDS[inst];
+ integer lines = words/nspc;
+ integer residue = words % nspc;
+ if (residue != 0) begin
+ lines = lines + 1;
+ end
+ for (int l = 0; l < lines; l=l+1) begin
+ last = (l == lines-1);
+ for (int p = 0; p < nspc; p=p+1) begin
+ data[p*WORD_W+:WORD_W] = (l*nspc)+p;
+ end
+ keep = (last && (residue != 0)) ? (1<<residue)-1 : (1<<nspc)-1;
+ if (inst == 0)
+ m0.push_word({keep[IN_WORDS[0]-1:0], data[(IN_WORDS[0]*WORD_W)-1:0]}, last);
+ else if (inst == 1)
+ m1.push_word({keep[IN_WORDS[1]-1:0], data[(IN_WORDS[1]*WORD_W)-1:0]}, last);
+ else if (inst == 2)
+ m2.push_word({keep[IN_WORDS[2]-1:0], data[(IN_WORDS[2]*WORD_W)-1:0]}, last);
+ else if (inst == 3)
+ m3.push_word({keep[IN_WORDS[3]-1:0], data[(IN_WORDS[3]*WORD_W)-1:0]}, last);
+ else if (inst == 4)
+ m4.push_word({keep[IN_WORDS[4]-1:0], data[(IN_WORDS[4]*WORD_W)-1:0]}, last);
+ else
+ m5.push_word({keep[IN_WORDS[5]-1:0], data[(IN_WORDS[5]*WORD_W)-1:0]}, last);
+
+ // Keep tvalid deasserted randomly introduce gaps
+ if (gaps) begin
+ integer r = $urandom_range(0, 100);
+ if (r < 20) repeat(r) @(posedge clk50);
+ end
+// $display("PUSH(%02d)[%03d]: D{%0x}, K{%0b}, L{%0b}", inst, l, data, keep, last);
+ end
+ end
+ endtask
+
+ // Pull a test ramp packet from the specific instance of the module
+ // - words: The size of the packet in words
+ // - inst: The instance number of the module to send to
+ // - gaps: If 1 then insert bubble cycles randomly in the stream
+ // - ok: If 1 then all sanity checks have passed
+ task pull_test_pkt(input integer words, input integer inst, input logic gaps, output logic ok);
+ begin
+ logic [(MAX_OUT_WORDS*WORD_W)-1:0] pull_data = 0;
+ logic [MAX_OUT_WORDS-1:0] pull_keep = 0;
+ logic pull_last = 0;
+
+ logic [(MAX_OUT_WORDS*WORD_W)-1:0] data = 0;
+ logic [MAX_OUT_WORDS-1:0] keep = 0;
+ logic last = 0;
+ logic [(MAX_OUT_WORDS*WORD_W)-1:0] mask = 0;
+ integer nspc = OUT_WORDS[inst];
+ integer lines = words/nspc;
+ integer residue = words % nspc;
+ if (residue != 0) begin
+ lines = lines + 1;
+ end
+ for (int l = 0; l < lines; l=l+1) begin
+ last = (l == lines-1);
+ for (int p = 0; p < nspc; p=p+1) begin
+ data[p*WORD_W+:WORD_W] = (l*nspc)+p;
+ end
+ keep = (last && (residue != 0)) ? (1<<residue)-1 : (1<<nspc)-1;
+ mask = (last && (residue != 0)) ? (1<<(residue*WORD_W))-1 : (1<<(nspc*WORD_W))-1;
+ if (inst == 0)
+ s0.pull_word({pull_keep[OUT_WORDS[0]-1:0], pull_data[(OUT_WORDS[0]*WORD_W)-1:0]}, pull_last);
+ else if (inst == 1)
+ s1.pull_word({pull_keep[OUT_WORDS[1]-1:0], pull_data[(OUT_WORDS[1]*WORD_W)-1:0]}, pull_last);
+ else if (inst == 2)
+ s2.pull_word({pull_keep[OUT_WORDS[2]-1:0], pull_data[(OUT_WORDS[2]*WORD_W)-1:0]}, pull_last);
+ else if (inst == 3)
+ s3.pull_word({pull_keep[OUT_WORDS[3]-1:0], pull_data[(OUT_WORDS[3]*WORD_W)-1:0]}, pull_last);
+ else if (inst == 4)
+ s4.pull_word({pull_keep[OUT_WORDS[4]-1:0], pull_data[(OUT_WORDS[4]*WORD_W)-1:0]}, pull_last);
+ else
+ s5.pull_word({pull_keep[OUT_WORDS[5]-1:0], pull_data[(OUT_WORDS[5]*WORD_W)-1:0]}, pull_last);
+
+ // Keep tready deasserted randomly introduce gaps
+ if (gaps) begin
+ integer r = $urandom_range(0, 100);
+ if (r < 20) repeat(r) @(posedge clk50);
+ end
+ // Check data, keep and last
+ ok = ((data&mask) == (pull_data&mask)) && (keep == (pull_keep&((1<<nspc)-1))) && (last == pull_last);
+// $display("PULL(%02d)[%03d]: D{%0x =? %0x}, K{%0b =? %0b}, L{%0b =? %0b} ... %s",
+// inst, l, (data&mask), (pull_data&mask), keep, (pull_keep&((1<<nspc)-1)), last, pull_last, (ok?"OK":"FAIL"));
+ end
+ end
+ endtask
+
+ initial begin : tb_main
+ string s;
+
+ `TEST_CASE_START("Wait for Reset");
+ m0.reset();
+ m1.reset();
+ m2.reset();
+ m3.reset();
+ m4.reset();
+ m5.reset();
+ s0.reset();
+ s1.reset();
+ s2.reset();
+ s3.reset();
+ s4.reset();
+ s5.reset();
+ while (areset) @(posedge clk50);
+ `TEST_CASE_DONE(~areset);
+
+ // Iterate through two modes:
+ // - g == 0: Gapless send and receive. Transfer as fast as possible
+ // - g == 1: Sender and receiver AXI streams will have random bubbles
+ for (int g = 0; g < 2; g=g+1) begin
+ // Iterate through the various instances of the module
+ for (int i = 0; i < NINST; i=i+1) begin
+ $sformat(s, "Testing Instance %0d (%0s gaps)", i, (g==0?"without":"with"));
+ `TEST_CASE_START(s);
+ fork
+ begin
+ // Send packets of increasing size (up to MAX_SPP) to test all
+ // configurations of tkeep and tlast.
+ for (int n = 1; n <= MAX_SPP; n=n+1) begin
+ push_test_pkt(n, i, g);
+ end
+ end
+ begin
+ logic ok;
+ // Receive packets of increasing size and validate tlast, tkeep and tdata
+ for (int n = 1; n <= MAX_SPP; n=n+1) begin
+ pull_test_pkt(n, i, g, ok);
+ $sformat(s, "Packet Validation Failed! (Size=%0d)", n);
+ `ASSERT_ERROR(ok, s);
+ end
+ end
+ join
+ // Gaps to separate the tests in the wfm viewer
+ repeat (100) @(posedge clk50);
+ `TEST_CASE_DONE(1'b1);
+ end
+ end
+
+ `TEST_BENCH_DONE;
+ end
+endmodule
diff --git a/fpga/usrp3/lib/sim/axi_packet_gate/Makefile b/fpga/usrp3/lib/sim/axi_packet_gate/Makefile
new file mode 100644
index 000000000..625a02877
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi_packet_gate/Makefile
@@ -0,0 +1,46 @@
+#
+# Copyright 2016 Ettus Research
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Design Specific
+#-------------------------------------------------
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/control/Makefile.srcs
+include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(CONTROL_LIB_SRCS) \
+$(FIFO_SRCS) \
+$(LIB_DIR)/fifo/axi_packet_gate.v \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = axi_packet_gate_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+axi_packet_gate_tb.sv \
+)
+
+# MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/axi_packet_gate/axi_packet_gate_tb.sv b/fpga/usrp3/lib/sim/axi_packet_gate/axi_packet_gate_tb.sv
new file mode 100644
index 000000000..0463a1e28
--- /dev/null
+++ b/fpga/usrp3/lib/sim/axi_packet_gate/axi_packet_gate_tb.sv
@@ -0,0 +1,347 @@
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 7
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_axis_lib.svh"
+
+module axi_packet_gate_tb();
+ `TEST_BENCH_INIT("axi_packet_gate_tb", `NUM_TEST_CASES, `NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/166.67e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ localparam MAX_PKT_SIZE = 64;
+
+ // +1 for terror
+ axis_master #(.DWIDTH(32+1)) m_axis (.clk(clk));
+ axis_slave #(.DWIDTH(32)) s_axis (.clk(clk));
+
+ axi_packet_gate #(
+ .WIDTH(32),
+ .SIZE($clog2(MAX_PKT_SIZE)),
+ .USE_AS_BUFF(1)
+ ) dut (
+ .clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata(m_axis.axis.tdata[31:0]),
+ .i_tvalid(m_axis.axis.tvalid),
+ .i_tlast(m_axis.axis.tlast),
+ .i_terror(m_axis.axis.tdata[32]), // Use MSB as terror
+ .i_tready(m_axis.axis.tready),
+ .o_tdata(s_axis.axis.tdata),
+ .o_tvalid(s_axis.axis.tvalid),
+ .o_tlast(s_axis.axis.tlast),
+ .o_tready(s_axis.axis.tready)
+ );
+
+ /********************************************************
+ ** Verification
+ ********************************************************/
+ task random_wait(int unsigned min_cycles, int unsigned max_cycles);
+ begin
+ int unsigned num_cycles;
+ do begin
+ num_cycles = $random() & (2**($clog2(max_cycles))-1);
+ end while ((num_cycles < min_cycles) || (num_cycles > max_cycles));
+
+ if (num_cycles != 0) begin
+ for (int unsigned i = 0; i < num_cycles; i++) begin
+ @(posedge clk);
+ end
+ @(negedge clk); // Realign with negedge
+ end
+ end
+ endtask
+
+ initial begin : tb_main
+ string s;
+ logic error, last;
+ int cnt, check;
+
+ /********************************************************
+ ** Test 1 -- Reset
+ ********************************************************/
+ `TEST_CASE_START("Wait for Reset");
+ m_axis.reset();
+ s_axis.reset();
+ while (reset) @(posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ /********************************************************
+ ** Test 2 -- Fill / Empty FIFO
+ ********************************************************/
+ `TEST_CASE_START("Fill and empty FIFO");
+ error = 0;
+ last = 0;
+ cnt = 0;
+ $display("Write %0d words to FIFO", MAX_PKT_SIZE);
+ for (int i = 0; i < MAX_PKT_SIZE; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE-1);
+ cnt++;
+ end
+ $display("Done writing to FIFO");
+ if (m_axis.axis.tready) begin
+ $display("FIFO not full, fill remaining space");
+ // Continue filling until FIFO is full
+ while (m_axis.axis.tready) begin
+ m_axis.push_word({error,cnt}, 0);
+ cnt++;
+ end
+ $display("Done filling remaining space");
+ $display("Expected FIFO size: %0d, Actual: %0d",MAX_PKT_SIZE,cnt);
+ end
+ // On the first packet, output is held off until a full packet is received
+ repeat(MAX_PKT_SIZE) @(posedge clk);
+ $display("Empty FIFO and check output");
+ for (int i = 0; i < cnt; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == i, s);
+ if (i == cnt-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ /********************************************************
+ ** Test 3 -- Check gating
+ ********************************************************/
+ `TEST_CASE_START("Check gating");
+ error = 0;
+ last = 0;
+ cnt = 0;
+
+ $display("Write %0d words to FIFO and check out valid", MAX_PKT_SIZE);
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ m_axis.push_word({error,cnt}, 0);
+ cnt++;
+ end
+ // On the first packet, output is held off until a full packet is received
+ repeat(10) @(posedge clk);
+ `ASSERT_FATAL(~s_axis.axis.tvalid, "Saw output before a full packet input");
+ for (int i = MAX_PKT_SIZE/2; i < MAX_PKT_SIZE; i++) begin
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE-1);
+ cnt++;
+ end
+ repeat(10) @(posedge clk);
+ `ASSERT_FATAL(s_axis.axis.tvalid, "Did not see output even after full packet input");
+ $display("Empty FIFO and check output");
+ for (int i = 0; i < cnt; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == i, s);
+ if (i == cnt-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ /********************************************************
+ ** Test 4 -- Ensure no bleed
+ ********************************************************/
+ `TEST_CASE_START("Ensure no bleed");
+ error = 0;
+ last = 0;
+ cnt = 0;
+
+ $display("Write %0d words to FIFO (full packet)", MAX_PKT_SIZE/2);
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ m_axis.push_word({error,cnt}, i == (MAX_PKT_SIZE/2)-1);
+ cnt++;
+ end
+ $display("Write %0d words to FIFO (partial packet)", MAX_PKT_SIZE/4);
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ m_axis.push_word({error,cnt}, 0);
+ cnt++;
+ end
+ // On the first packet, output is held off until a full packet is received
+ repeat(10) @(posedge clk);
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == i, s);
+ if (i == (MAX_PKT_SIZE/2)-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ repeat(10) @(posedge clk);
+ `ASSERT_FATAL(~s_axis.axis.tvalid, "Partial packet bled through with full packet");
+ for (int i = MAX_PKT_SIZE/4; i < MAX_PKT_SIZE/2; i++) begin
+ m_axis.push_word({error,cnt}, i == (MAX_PKT_SIZE/2)-1);
+ cnt++;
+ end
+ repeat(10) @(posedge clk);
+ `ASSERT_FATAL(s_axis.axis.tvalid, "Did not see output even after full packet input");
+ $display("Empty FIFO and check output");
+ for (int i = MAX_PKT_SIZE/2; i < cnt; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == i, s);
+ if (i == cnt-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ /********************************************************
+ ** Test 5 -- Back to back small packets
+ ********************************************************/
+ `TEST_CASE_START("Back to back small packets");
+ error = 0;
+ last = 0;
+ cnt = 0;
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/2-1);
+ cnt++;
+ end
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/2-1);
+ cnt++;
+ end
+ fork
+ begin
+ for (int k = 0; k < 8; k++) begin
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/2-1);
+ cnt++;
+ end
+ end
+ end
+ begin
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ for (int k = 0; k < 10; k++) begin
+ for (int i = 0; i < MAX_PKT_SIZE/2; i++) begin
+ `ASSERT_FATAL(s_axis.axis.tvalid, "tvalid not asserted!");
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == (i+k*MAX_PKT_SIZE/2), s);
+ if (i == MAX_PKT_SIZE/2-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ #2000; // Delay to make the tests visually distinct in waveform viewer
+
+ /********************************************************
+ ** Test 6 -- Drop error packet
+ ** - Send packet, drop a packet, send another packet
+ ********************************************************/
+ `TEST_CASE_START("Drop error packet");
+ cnt = 0;
+ $display("Write packet with %0d words to FIFO", MAX_PKT_SIZE/4);
+ error = 0;
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/4-1);
+ cnt++;
+ end
+ $display("Write error packet with %0d words to FIFO", MAX_PKT_SIZE/4);
+ error = 1;
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/4-1);
+ cnt++;
+ end
+ $display("Write packet with %0d words to FIFO", MAX_PKT_SIZE/4);
+ error = 0;
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ $sformat(s, "FIFO prematurely full at %0d (tready not asserted!)", i);
+ `ASSERT_FATAL(m_axis.axis.tready, s);
+ m_axis.push_word({error,cnt}, i == MAX_PKT_SIZE/4-1);
+ cnt++;
+ end
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == i, s);
+ if (i == MAX_PKT_SIZE/4-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ for (int i = 0; i < MAX_PKT_SIZE/4; i++) begin
+ $sformat(s, "FIFO prematurely empty at %0d (tvalid not asserted!)", i);
+ `ASSERT_FATAL(s_axis.axis.tvalid, s);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", i, check);
+ `ASSERT_FATAL(check == (i+MAX_PKT_SIZE/2), s);
+ if (i == MAX_PKT_SIZE/4-1) begin
+ `ASSERT_FATAL(last, "tlast not asserted on final word!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ #2000;
+
+ /********************************************************
+ ** Test 7 -- Random read / writes
+ ********************************************************/
+ `TEST_CASE_START("Random read / writes");
+ error = 0;
+ last = 0;
+ cnt = 0;
+ fork
+ begin
+ for (int k = 1; k <= 5000*MAX_PKT_SIZE; k++) begin
+ m_axis.push_word({error,k}, (k % 16) == 0);
+ random_wait(0,16);
+ end
+ end
+ begin
+ for (int k = 1; k <= 5000*MAX_PKT_SIZE; k++) begin
+ random_wait(0,16);
+ s_axis.pull_word(check, last);
+ $sformat(s, "FIFO output incorrect! Expected: %0d, Actual: %0d", k, check);
+ `ASSERT_FATAL(check == k, s);
+ if ((k % 16) == 0) begin
+ `ASSERT_FATAL(last, "tlast not asserted!");
+ end else begin
+ `ASSERT_FATAL(~last, "tlast asserted prematurely!");
+ end
+ end
+ end
+ join
+ `TEST_CASE_DONE(1);
+
+ `TEST_BENCH_DONE;
+
+ end
+endmodule
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/gtk.conf.gtkw b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/gtk.conf.gtkw
new file mode 100644
index 000000000..27c2c836e
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/gtk.conf.gtkw
@@ -0,0 +1,64 @@
+[*]
+[*] GTKWave Analyzer v3.3.40 (w)1999-2012 BSI
+[*] Wed Jul 15 02:18:40 2015
+[*]
+[dumpfile] "/disk2/ianb/ettus/fpgadev-b200/fpgadev/usrp3/lib/dsp/sim/sim_ddc_chain/dc_in_cordic_run/waves.vcd"
+[dumpfile_mtime] "Wed Jul 15 02:13:19 2015"
+[dumpfile_size] 238141440
+[savefile] "/disk2/ianb/ettus/fpgadev-b200/fpgadev/usrp3/lib/dsp/sim/sim_ddc_chain/dc_in_cordic_run/gtk.conf.gtkw"
+[timestart] 0
+[size] 2488 1221
+[pos] -1 -1
+*-24.083374 129800000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] ddc_chain_tb.
+[treeopen] ddc_chain_tb.dut_i0.
+[sst_width] 331
+[signals_width] 280
+[sst_expanded] 1
+[sst_vpaned_height] 370
+@28
+ddc_chain_tb.dut_i0.clk
+ddc_chain_tb.dut_i0.rst
+ddc_chain_tb.dut_i0.set_stb
+@22
+#{ddc_chain_tb.dut_i0.set_addr[7:0]} ddc_chain_tb.dut_i0.set_addr[7] ddc_chain_tb.dut_i0.set_addr[6] ddc_chain_tb.dut_i0.set_addr[5] ddc_chain_tb.dut_i0.set_addr[4] ddc_chain_tb.dut_i0.set_addr[3] ddc_chain_tb.dut_i0.set_addr[2] ddc_chain_tb.dut_i0.set_addr[1] ddc_chain_tb.dut_i0.set_addr[0]
+#{ddc_chain_tb.dut_i0.set_data[31:0]} ddc_chain_tb.dut_i0.set_data[31] ddc_chain_tb.dut_i0.set_data[30] ddc_chain_tb.dut_i0.set_data[29] ddc_chain_tb.dut_i0.set_data[28] ddc_chain_tb.dut_i0.set_data[27] ddc_chain_tb.dut_i0.set_data[26] ddc_chain_tb.dut_i0.set_data[25] ddc_chain_tb.dut_i0.set_data[24] ddc_chain_tb.dut_i0.set_data[23] ddc_chain_tb.dut_i0.set_data[22] ddc_chain_tb.dut_i0.set_data[21] ddc_chain_tb.dut_i0.set_data[20] ddc_chain_tb.dut_i0.set_data[19] ddc_chain_tb.dut_i0.set_data[18] ddc_chain_tb.dut_i0.set_data[17] ddc_chain_tb.dut_i0.set_data[16] ddc_chain_tb.dut_i0.set_data[15] ddc_chain_tb.dut_i0.set_data[14] ddc_chain_tb.dut_i0.set_data[13] ddc_chain_tb.dut_i0.set_data[12] ddc_chain_tb.dut_i0.set_data[11] ddc_chain_tb.dut_i0.set_data[10] ddc_chain_tb.dut_i0.set_data[9] ddc_chain_tb.dut_i0.set_data[8] ddc_chain_tb.dut_i0.set_data[7] ddc_chain_tb.dut_i0.set_data[6] ddc_chain_tb.dut_i0.set_data[5] ddc_chain_tb.dut_i0.set_data[4] ddc_chain_tb.dut_i0.set_data[3] ddc_chain_tb.dut_i0.set_data[2] ddc_chain_tb.dut_i0.set_data[1] ddc_chain_tb.dut_i0.set_data[0]
+@10420
+#{ddc_chain_tb.dut_i0.rx_fe_i[23:0]} ddc_chain_tb.dut_i0.rx_fe_i[23] ddc_chain_tb.dut_i0.rx_fe_i[22] ddc_chain_tb.dut_i0.rx_fe_i[21] ddc_chain_tb.dut_i0.rx_fe_i[20] ddc_chain_tb.dut_i0.rx_fe_i[19] ddc_chain_tb.dut_i0.rx_fe_i[18] ddc_chain_tb.dut_i0.rx_fe_i[17] ddc_chain_tb.dut_i0.rx_fe_i[16] ddc_chain_tb.dut_i0.rx_fe_i[15] ddc_chain_tb.dut_i0.rx_fe_i[14] ddc_chain_tb.dut_i0.rx_fe_i[13] ddc_chain_tb.dut_i0.rx_fe_i[12] ddc_chain_tb.dut_i0.rx_fe_i[11] ddc_chain_tb.dut_i0.rx_fe_i[10] ddc_chain_tb.dut_i0.rx_fe_i[9] ddc_chain_tb.dut_i0.rx_fe_i[8] ddc_chain_tb.dut_i0.rx_fe_i[7] ddc_chain_tb.dut_i0.rx_fe_i[6] ddc_chain_tb.dut_i0.rx_fe_i[5] ddc_chain_tb.dut_i0.rx_fe_i[4] ddc_chain_tb.dut_i0.rx_fe_i[3] ddc_chain_tb.dut_i0.rx_fe_i[2] ddc_chain_tb.dut_i0.rx_fe_i[1] ddc_chain_tb.dut_i0.rx_fe_i[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.rx_fe_q[23:0]} ddc_chain_tb.dut_i0.rx_fe_q[23] ddc_chain_tb.dut_i0.rx_fe_q[22] ddc_chain_tb.dut_i0.rx_fe_q[21] ddc_chain_tb.dut_i0.rx_fe_q[20] ddc_chain_tb.dut_i0.rx_fe_q[19] ddc_chain_tb.dut_i0.rx_fe_q[18] ddc_chain_tb.dut_i0.rx_fe_q[17] ddc_chain_tb.dut_i0.rx_fe_q[16] ddc_chain_tb.dut_i0.rx_fe_q[15] ddc_chain_tb.dut_i0.rx_fe_q[14] ddc_chain_tb.dut_i0.rx_fe_q[13] ddc_chain_tb.dut_i0.rx_fe_q[12] ddc_chain_tb.dut_i0.rx_fe_q[11] ddc_chain_tb.dut_i0.rx_fe_q[10] ddc_chain_tb.dut_i0.rx_fe_q[9] ddc_chain_tb.dut_i0.rx_fe_q[8] ddc_chain_tb.dut_i0.rx_fe_q[7] ddc_chain_tb.dut_i0.rx_fe_q[6] ddc_chain_tb.dut_i0.rx_fe_q[5] ddc_chain_tb.dut_i0.rx_fe_q[4] ddc_chain_tb.dut_i0.rx_fe_q[3] ddc_chain_tb.dut_i0.rx_fe_q[2] ddc_chain_tb.dut_i0.rx_fe_q[1] ddc_chain_tb.dut_i0.rx_fe_q[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.i_cordic_clip[23:0]} ddc_chain_tb.dut_i0.i_cordic_clip[23] ddc_chain_tb.dut_i0.i_cordic_clip[22] ddc_chain_tb.dut_i0.i_cordic_clip[21] ddc_chain_tb.dut_i0.i_cordic_clip[20] ddc_chain_tb.dut_i0.i_cordic_clip[19] ddc_chain_tb.dut_i0.i_cordic_clip[18] ddc_chain_tb.dut_i0.i_cordic_clip[17] ddc_chain_tb.dut_i0.i_cordic_clip[16] ddc_chain_tb.dut_i0.i_cordic_clip[15] ddc_chain_tb.dut_i0.i_cordic_clip[14] ddc_chain_tb.dut_i0.i_cordic_clip[13] ddc_chain_tb.dut_i0.i_cordic_clip[12] ddc_chain_tb.dut_i0.i_cordic_clip[11] ddc_chain_tb.dut_i0.i_cordic_clip[10] ddc_chain_tb.dut_i0.i_cordic_clip[9] ddc_chain_tb.dut_i0.i_cordic_clip[8] ddc_chain_tb.dut_i0.i_cordic_clip[7] ddc_chain_tb.dut_i0.i_cordic_clip[6] ddc_chain_tb.dut_i0.i_cordic_clip[5] ddc_chain_tb.dut_i0.i_cordic_clip[4] ddc_chain_tb.dut_i0.i_cordic_clip[3] ddc_chain_tb.dut_i0.i_cordic_clip[2] ddc_chain_tb.dut_i0.i_cordic_clip[1] ddc_chain_tb.dut_i0.i_cordic_clip[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.q_cordic_clip[23:0]} ddc_chain_tb.dut_i0.q_cordic_clip[23] ddc_chain_tb.dut_i0.q_cordic_clip[22] ddc_chain_tb.dut_i0.q_cordic_clip[21] ddc_chain_tb.dut_i0.q_cordic_clip[20] ddc_chain_tb.dut_i0.q_cordic_clip[19] ddc_chain_tb.dut_i0.q_cordic_clip[18] ddc_chain_tb.dut_i0.q_cordic_clip[17] ddc_chain_tb.dut_i0.q_cordic_clip[16] ddc_chain_tb.dut_i0.q_cordic_clip[15] ddc_chain_tb.dut_i0.q_cordic_clip[14] ddc_chain_tb.dut_i0.q_cordic_clip[13] ddc_chain_tb.dut_i0.q_cordic_clip[12] ddc_chain_tb.dut_i0.q_cordic_clip[11] ddc_chain_tb.dut_i0.q_cordic_clip[10] ddc_chain_tb.dut_i0.q_cordic_clip[9] ddc_chain_tb.dut_i0.q_cordic_clip[8] ddc_chain_tb.dut_i0.q_cordic_clip[7] ddc_chain_tb.dut_i0.q_cordic_clip[6] ddc_chain_tb.dut_i0.q_cordic_clip[5] ddc_chain_tb.dut_i0.q_cordic_clip[4] ddc_chain_tb.dut_i0.q_cordic_clip[3] ddc_chain_tb.dut_i0.q_cordic_clip[2] ddc_chain_tb.dut_i0.q_cordic_clip[1] ddc_chain_tb.dut_i0.q_cordic_clip[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.i_cic[23:0]} ddc_chain_tb.dut_i0.i_cic[23] ddc_chain_tb.dut_i0.i_cic[22] ddc_chain_tb.dut_i0.i_cic[21] ddc_chain_tb.dut_i0.i_cic[20] ddc_chain_tb.dut_i0.i_cic[19] ddc_chain_tb.dut_i0.i_cic[18] ddc_chain_tb.dut_i0.i_cic[17] ddc_chain_tb.dut_i0.i_cic[16] ddc_chain_tb.dut_i0.i_cic[15] ddc_chain_tb.dut_i0.i_cic[14] ddc_chain_tb.dut_i0.i_cic[13] ddc_chain_tb.dut_i0.i_cic[12] ddc_chain_tb.dut_i0.i_cic[11] ddc_chain_tb.dut_i0.i_cic[10] ddc_chain_tb.dut_i0.i_cic[9] ddc_chain_tb.dut_i0.i_cic[8] ddc_chain_tb.dut_i0.i_cic[7] ddc_chain_tb.dut_i0.i_cic[6] ddc_chain_tb.dut_i0.i_cic[5] ddc_chain_tb.dut_i0.i_cic[4] ddc_chain_tb.dut_i0.i_cic[3] ddc_chain_tb.dut_i0.i_cic[2] ddc_chain_tb.dut_i0.i_cic[1] ddc_chain_tb.dut_i0.i_cic[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.q_cic[23:0]} ddc_chain_tb.dut_i0.q_cic[23] ddc_chain_tb.dut_i0.q_cic[22] ddc_chain_tb.dut_i0.q_cic[21] ddc_chain_tb.dut_i0.q_cic[20] ddc_chain_tb.dut_i0.q_cic[19] ddc_chain_tb.dut_i0.q_cic[18] ddc_chain_tb.dut_i0.q_cic[17] ddc_chain_tb.dut_i0.q_cic[16] ddc_chain_tb.dut_i0.q_cic[15] ddc_chain_tb.dut_i0.q_cic[14] ddc_chain_tb.dut_i0.q_cic[13] ddc_chain_tb.dut_i0.q_cic[12] ddc_chain_tb.dut_i0.q_cic[11] ddc_chain_tb.dut_i0.q_cic[10] ddc_chain_tb.dut_i0.q_cic[9] ddc_chain_tb.dut_i0.q_cic[8] ddc_chain_tb.dut_i0.q_cic[7] ddc_chain_tb.dut_i0.q_cic[6] ddc_chain_tb.dut_i0.q_cic[5] ddc_chain_tb.dut_i0.q_cic[4] ddc_chain_tb.dut_i0.q_cic[3] ddc_chain_tb.dut_i0.q_cic[2] ddc_chain_tb.dut_i0.q_cic[1] ddc_chain_tb.dut_i0.q_cic[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.i_hb1[46:0]} ddc_chain_tb.dut_i0.\new_hb.i_hb1[46] ddc_chain_tb.dut_i0.\new_hb.i_hb1[45] ddc_chain_tb.dut_i0.\new_hb.i_hb1[44] ddc_chain_tb.dut_i0.\new_hb.i_hb1[43] ddc_chain_tb.dut_i0.\new_hb.i_hb1[42] ddc_chain_tb.dut_i0.\new_hb.i_hb1[41] ddc_chain_tb.dut_i0.\new_hb.i_hb1[40] ddc_chain_tb.dut_i0.\new_hb.i_hb1[39] ddc_chain_tb.dut_i0.\new_hb.i_hb1[38] ddc_chain_tb.dut_i0.\new_hb.i_hb1[37] ddc_chain_tb.dut_i0.\new_hb.i_hb1[36] ddc_chain_tb.dut_i0.\new_hb.i_hb1[35] ddc_chain_tb.dut_i0.\new_hb.i_hb1[34] ddc_chain_tb.dut_i0.\new_hb.i_hb1[33] ddc_chain_tb.dut_i0.\new_hb.i_hb1[32] ddc_chain_tb.dut_i0.\new_hb.i_hb1[31] ddc_chain_tb.dut_i0.\new_hb.i_hb1[30] ddc_chain_tb.dut_i0.\new_hb.i_hb1[29] ddc_chain_tb.dut_i0.\new_hb.i_hb1[28] ddc_chain_tb.dut_i0.\new_hb.i_hb1[27] ddc_chain_tb.dut_i0.\new_hb.i_hb1[26] ddc_chain_tb.dut_i0.\new_hb.i_hb1[25] ddc_chain_tb.dut_i0.\new_hb.i_hb1[24] ddc_chain_tb.dut_i0.\new_hb.i_hb1[23] ddc_chain_tb.dut_i0.\new_hb.i_hb1[22] ddc_chain_tb.dut_i0.\new_hb.i_hb1[21] ddc_chain_tb.dut_i0.\new_hb.i_hb1[20] ddc_chain_tb.dut_i0.\new_hb.i_hb1[19] ddc_chain_tb.dut_i0.\new_hb.i_hb1[18] ddc_chain_tb.dut_i0.\new_hb.i_hb1[17] ddc_chain_tb.dut_i0.\new_hb.i_hb1[16] ddc_chain_tb.dut_i0.\new_hb.i_hb1[15] ddc_chain_tb.dut_i0.\new_hb.i_hb1[14] ddc_chain_tb.dut_i0.\new_hb.i_hb1[13] ddc_chain_tb.dut_i0.\new_hb.i_hb1[12] ddc_chain_tb.dut_i0.\new_hb.i_hb1[11] ddc_chain_tb.dut_i0.\new_hb.i_hb1[10] ddc_chain_tb.dut_i0.\new_hb.i_hb1[9] ddc_chain_tb.dut_i0.\new_hb.i_hb1[8] ddc_chain_tb.dut_i0.\new_hb.i_hb1[7] ddc_chain_tb.dut_i0.\new_hb.i_hb1[6] ddc_chain_tb.dut_i0.\new_hb.i_hb1[5] ddc_chain_tb.dut_i0.\new_hb.i_hb1[4] ddc_chain_tb.dut_i0.\new_hb.i_hb1[3] ddc_chain_tb.dut_i0.\new_hb.i_hb1[2] ddc_chain_tb.dut_i0.\new_hb.i_hb1[1] ddc_chain_tb.dut_i0.\new_hb.i_hb1[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.q_hb1[46:0]} ddc_chain_tb.dut_i0.\new_hb.q_hb1[46] ddc_chain_tb.dut_i0.\new_hb.q_hb1[45] ddc_chain_tb.dut_i0.\new_hb.q_hb1[44] ddc_chain_tb.dut_i0.\new_hb.q_hb1[43] ddc_chain_tb.dut_i0.\new_hb.q_hb1[42] ddc_chain_tb.dut_i0.\new_hb.q_hb1[41] ddc_chain_tb.dut_i0.\new_hb.q_hb1[40] ddc_chain_tb.dut_i0.\new_hb.q_hb1[39] ddc_chain_tb.dut_i0.\new_hb.q_hb1[38] ddc_chain_tb.dut_i0.\new_hb.q_hb1[37] ddc_chain_tb.dut_i0.\new_hb.q_hb1[36] ddc_chain_tb.dut_i0.\new_hb.q_hb1[35] ddc_chain_tb.dut_i0.\new_hb.q_hb1[34] ddc_chain_tb.dut_i0.\new_hb.q_hb1[33] ddc_chain_tb.dut_i0.\new_hb.q_hb1[32] ddc_chain_tb.dut_i0.\new_hb.q_hb1[31] ddc_chain_tb.dut_i0.\new_hb.q_hb1[30] ddc_chain_tb.dut_i0.\new_hb.q_hb1[29] ddc_chain_tb.dut_i0.\new_hb.q_hb1[28] ddc_chain_tb.dut_i0.\new_hb.q_hb1[27] ddc_chain_tb.dut_i0.\new_hb.q_hb1[26] ddc_chain_tb.dut_i0.\new_hb.q_hb1[25] ddc_chain_tb.dut_i0.\new_hb.q_hb1[24] ddc_chain_tb.dut_i0.\new_hb.q_hb1[23] ddc_chain_tb.dut_i0.\new_hb.q_hb1[22] ddc_chain_tb.dut_i0.\new_hb.q_hb1[21] ddc_chain_tb.dut_i0.\new_hb.q_hb1[20] ddc_chain_tb.dut_i0.\new_hb.q_hb1[19] ddc_chain_tb.dut_i0.\new_hb.q_hb1[18] ddc_chain_tb.dut_i0.\new_hb.q_hb1[17] ddc_chain_tb.dut_i0.\new_hb.q_hb1[16] ddc_chain_tb.dut_i0.\new_hb.q_hb1[15] ddc_chain_tb.dut_i0.\new_hb.q_hb1[14] ddc_chain_tb.dut_i0.\new_hb.q_hb1[13] ddc_chain_tb.dut_i0.\new_hb.q_hb1[12] ddc_chain_tb.dut_i0.\new_hb.q_hb1[11] ddc_chain_tb.dut_i0.\new_hb.q_hb1[10] ddc_chain_tb.dut_i0.\new_hb.q_hb1[9] ddc_chain_tb.dut_i0.\new_hb.q_hb1[8] ddc_chain_tb.dut_i0.\new_hb.q_hb1[7] ddc_chain_tb.dut_i0.\new_hb.q_hb1[6] ddc_chain_tb.dut_i0.\new_hb.q_hb1[5] ddc_chain_tb.dut_i0.\new_hb.q_hb1[4] ddc_chain_tb.dut_i0.\new_hb.q_hb1[3] ddc_chain_tb.dut_i0.\new_hb.q_hb1[2] ddc_chain_tb.dut_i0.\new_hb.q_hb1[1] ddc_chain_tb.dut_i0.\new_hb.q_hb1[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.i_hb2[46:0]} ddc_chain_tb.dut_i0.\new_hb.i_hb2[46] ddc_chain_tb.dut_i0.\new_hb.i_hb2[45] ddc_chain_tb.dut_i0.\new_hb.i_hb2[44] ddc_chain_tb.dut_i0.\new_hb.i_hb2[43] ddc_chain_tb.dut_i0.\new_hb.i_hb2[42] ddc_chain_tb.dut_i0.\new_hb.i_hb2[41] ddc_chain_tb.dut_i0.\new_hb.i_hb2[40] ddc_chain_tb.dut_i0.\new_hb.i_hb2[39] ddc_chain_tb.dut_i0.\new_hb.i_hb2[38] ddc_chain_tb.dut_i0.\new_hb.i_hb2[37] ddc_chain_tb.dut_i0.\new_hb.i_hb2[36] ddc_chain_tb.dut_i0.\new_hb.i_hb2[35] ddc_chain_tb.dut_i0.\new_hb.i_hb2[34] ddc_chain_tb.dut_i0.\new_hb.i_hb2[33] ddc_chain_tb.dut_i0.\new_hb.i_hb2[32] ddc_chain_tb.dut_i0.\new_hb.i_hb2[31] ddc_chain_tb.dut_i0.\new_hb.i_hb2[30] ddc_chain_tb.dut_i0.\new_hb.i_hb2[29] ddc_chain_tb.dut_i0.\new_hb.i_hb2[28] ddc_chain_tb.dut_i0.\new_hb.i_hb2[27] ddc_chain_tb.dut_i0.\new_hb.i_hb2[26] ddc_chain_tb.dut_i0.\new_hb.i_hb2[25] ddc_chain_tb.dut_i0.\new_hb.i_hb2[24] ddc_chain_tb.dut_i0.\new_hb.i_hb2[23] ddc_chain_tb.dut_i0.\new_hb.i_hb2[22] ddc_chain_tb.dut_i0.\new_hb.i_hb2[21] ddc_chain_tb.dut_i0.\new_hb.i_hb2[20] ddc_chain_tb.dut_i0.\new_hb.i_hb2[19] ddc_chain_tb.dut_i0.\new_hb.i_hb2[18] ddc_chain_tb.dut_i0.\new_hb.i_hb2[17] ddc_chain_tb.dut_i0.\new_hb.i_hb2[16] ddc_chain_tb.dut_i0.\new_hb.i_hb2[15] ddc_chain_tb.dut_i0.\new_hb.i_hb2[14] ddc_chain_tb.dut_i0.\new_hb.i_hb2[13] ddc_chain_tb.dut_i0.\new_hb.i_hb2[12] ddc_chain_tb.dut_i0.\new_hb.i_hb2[11] ddc_chain_tb.dut_i0.\new_hb.i_hb2[10] ddc_chain_tb.dut_i0.\new_hb.i_hb2[9] ddc_chain_tb.dut_i0.\new_hb.i_hb2[8] ddc_chain_tb.dut_i0.\new_hb.i_hb2[7] ddc_chain_tb.dut_i0.\new_hb.i_hb2[6] ddc_chain_tb.dut_i0.\new_hb.i_hb2[5] ddc_chain_tb.dut_i0.\new_hb.i_hb2[4] ddc_chain_tb.dut_i0.\new_hb.i_hb2[3] ddc_chain_tb.dut_i0.\new_hb.i_hb2[2] ddc_chain_tb.dut_i0.\new_hb.i_hb2[1] ddc_chain_tb.dut_i0.\new_hb.i_hb2[0]
+#{ddc_chain_tb.dut_i0.\new_hb.q_hb2[46:0]} ddc_chain_tb.dut_i0.\new_hb.q_hb2[46] ddc_chain_tb.dut_i0.\new_hb.q_hb2[45] ddc_chain_tb.dut_i0.\new_hb.q_hb2[44] ddc_chain_tb.dut_i0.\new_hb.q_hb2[43] ddc_chain_tb.dut_i0.\new_hb.q_hb2[42] ddc_chain_tb.dut_i0.\new_hb.q_hb2[41] ddc_chain_tb.dut_i0.\new_hb.q_hb2[40] ddc_chain_tb.dut_i0.\new_hb.q_hb2[39] ddc_chain_tb.dut_i0.\new_hb.q_hb2[38] ddc_chain_tb.dut_i0.\new_hb.q_hb2[37] ddc_chain_tb.dut_i0.\new_hb.q_hb2[36] ddc_chain_tb.dut_i0.\new_hb.q_hb2[35] ddc_chain_tb.dut_i0.\new_hb.q_hb2[34] ddc_chain_tb.dut_i0.\new_hb.q_hb2[33] ddc_chain_tb.dut_i0.\new_hb.q_hb2[32] ddc_chain_tb.dut_i0.\new_hb.q_hb2[31] ddc_chain_tb.dut_i0.\new_hb.q_hb2[30] ddc_chain_tb.dut_i0.\new_hb.q_hb2[29] ddc_chain_tb.dut_i0.\new_hb.q_hb2[28] ddc_chain_tb.dut_i0.\new_hb.q_hb2[27] ddc_chain_tb.dut_i0.\new_hb.q_hb2[26] ddc_chain_tb.dut_i0.\new_hb.q_hb2[25] ddc_chain_tb.dut_i0.\new_hb.q_hb2[24] ddc_chain_tb.dut_i0.\new_hb.q_hb2[23] ddc_chain_tb.dut_i0.\new_hb.q_hb2[22] ddc_chain_tb.dut_i0.\new_hb.q_hb2[21] ddc_chain_tb.dut_i0.\new_hb.q_hb2[20] ddc_chain_tb.dut_i0.\new_hb.q_hb2[19] ddc_chain_tb.dut_i0.\new_hb.q_hb2[18] ddc_chain_tb.dut_i0.\new_hb.q_hb2[17] ddc_chain_tb.dut_i0.\new_hb.q_hb2[16] ddc_chain_tb.dut_i0.\new_hb.q_hb2[15] ddc_chain_tb.dut_i0.\new_hb.q_hb2[14] ddc_chain_tb.dut_i0.\new_hb.q_hb2[13] ddc_chain_tb.dut_i0.\new_hb.q_hb2[12] ddc_chain_tb.dut_i0.\new_hb.q_hb2[11] ddc_chain_tb.dut_i0.\new_hb.q_hb2[10] ddc_chain_tb.dut_i0.\new_hb.q_hb2[9] ddc_chain_tb.dut_i0.\new_hb.q_hb2[8] ddc_chain_tb.dut_i0.\new_hb.q_hb2[7] ddc_chain_tb.dut_i0.\new_hb.q_hb2[6] ddc_chain_tb.dut_i0.\new_hb.q_hb2[5] ddc_chain_tb.dut_i0.\new_hb.q_hb2[4] ddc_chain_tb.dut_i0.\new_hb.q_hb2[3] ddc_chain_tb.dut_i0.\new_hb.q_hb2[2] ddc_chain_tb.dut_i0.\new_hb.q_hb2[1] ddc_chain_tb.dut_i0.\new_hb.q_hb2[0]
+@20000
+-
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/simulation_script.v b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/simulation_script.v
new file mode 100644
index 000000000..bc11b8b01
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_2/simulation_script.v
@@ -0,0 +1,82 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// 10MHz master_clock_rate
+always #50 clk <= ~clk;
+
+ initial
+ begin
+ reset <= 1'b0;
+ i_in <= 0;
+ q_in <= 0;
+ run <= 0;
+ set_stb <= 0;
+ set_addr <= 0;
+ set_data <= 0;
+
+
+ @(posedge clk);
+ // Into Reset...
+ reset <= 1'b1;
+ repeat(10) @(posedge clk);
+ // .. and back out of reset.
+ reset <= 1'b0;
+ repeat(10) @(posedge clk);
+ // Now program DSP configuration via settings regs.
+ write_setting_bus(SR_DSP_RX_FREQ,42949672); // 100kHz @ 10MHz MCR
+ // (1 << 15) * std::pow(2, ceil_log2(rate_pow))*2./(1.648*rate_pow)
+ write_setting_bus(SR_DSP_RX_SCALE_IQ, 39767); // Should include CORDIC and CIC gain compensation.
+ write_setting_bus(SR_DSP_RX_DECIM, 1<<9|1); // Decim = 2
+ write_setting_bus(SR_DSP_RX_MUX, 0);
+ write_setting_bus(SR_DSP_RX_COEFFS,0);
+ repeat(10) @(posedge clk);
+
+ // Set complex data inputs to DC unit circle position.
+ i_in <= 12'h7ff;
+ q_in <= 12'h0;
+ run <= 1'b1;
+ repeat(100) @(posedge clk);
+ // Set complex data inputs to simulate ADC saturation of front end
+ i_in <= 12'h7ff;
+ q_in <= 12'h100;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h200;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h300;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h400;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h500;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h600;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h700;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h7FF;
+ // Now test small signal performance
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h001;
+ q_in <= 12'h000;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h000;
+ q_in <= 12'h001;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'hfff;
+ q_in <= 12'h000;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h000;
+ q_in <= 12'hfff;
+
+ repeat(100000) @(posedge clk);
+ $finish();
+
+ end // initial begin
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/gtk.conf.gtkw b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/gtk.conf.gtkw
new file mode 100644
index 000000000..27c2c836e
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/gtk.conf.gtkw
@@ -0,0 +1,64 @@
+[*]
+[*] GTKWave Analyzer v3.3.40 (w)1999-2012 BSI
+[*] Wed Jul 15 02:18:40 2015
+[*]
+[dumpfile] "/disk2/ianb/ettus/fpgadev-b200/fpgadev/usrp3/lib/dsp/sim/sim_ddc_chain/dc_in_cordic_run/waves.vcd"
+[dumpfile_mtime] "Wed Jul 15 02:13:19 2015"
+[dumpfile_size] 238141440
+[savefile] "/disk2/ianb/ettus/fpgadev-b200/fpgadev/usrp3/lib/dsp/sim/sim_ddc_chain/dc_in_cordic_run/gtk.conf.gtkw"
+[timestart] 0
+[size] 2488 1221
+[pos] -1 -1
+*-24.083374 129800000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] ddc_chain_tb.
+[treeopen] ddc_chain_tb.dut_i0.
+[sst_width] 331
+[signals_width] 280
+[sst_expanded] 1
+[sst_vpaned_height] 370
+@28
+ddc_chain_tb.dut_i0.clk
+ddc_chain_tb.dut_i0.rst
+ddc_chain_tb.dut_i0.set_stb
+@22
+#{ddc_chain_tb.dut_i0.set_addr[7:0]} ddc_chain_tb.dut_i0.set_addr[7] ddc_chain_tb.dut_i0.set_addr[6] ddc_chain_tb.dut_i0.set_addr[5] ddc_chain_tb.dut_i0.set_addr[4] ddc_chain_tb.dut_i0.set_addr[3] ddc_chain_tb.dut_i0.set_addr[2] ddc_chain_tb.dut_i0.set_addr[1] ddc_chain_tb.dut_i0.set_addr[0]
+#{ddc_chain_tb.dut_i0.set_data[31:0]} ddc_chain_tb.dut_i0.set_data[31] ddc_chain_tb.dut_i0.set_data[30] ddc_chain_tb.dut_i0.set_data[29] ddc_chain_tb.dut_i0.set_data[28] ddc_chain_tb.dut_i0.set_data[27] ddc_chain_tb.dut_i0.set_data[26] ddc_chain_tb.dut_i0.set_data[25] ddc_chain_tb.dut_i0.set_data[24] ddc_chain_tb.dut_i0.set_data[23] ddc_chain_tb.dut_i0.set_data[22] ddc_chain_tb.dut_i0.set_data[21] ddc_chain_tb.dut_i0.set_data[20] ddc_chain_tb.dut_i0.set_data[19] ddc_chain_tb.dut_i0.set_data[18] ddc_chain_tb.dut_i0.set_data[17] ddc_chain_tb.dut_i0.set_data[16] ddc_chain_tb.dut_i0.set_data[15] ddc_chain_tb.dut_i0.set_data[14] ddc_chain_tb.dut_i0.set_data[13] ddc_chain_tb.dut_i0.set_data[12] ddc_chain_tb.dut_i0.set_data[11] ddc_chain_tb.dut_i0.set_data[10] ddc_chain_tb.dut_i0.set_data[9] ddc_chain_tb.dut_i0.set_data[8] ddc_chain_tb.dut_i0.set_data[7] ddc_chain_tb.dut_i0.set_data[6] ddc_chain_tb.dut_i0.set_data[5] ddc_chain_tb.dut_i0.set_data[4] ddc_chain_tb.dut_i0.set_data[3] ddc_chain_tb.dut_i0.set_data[2] ddc_chain_tb.dut_i0.set_data[1] ddc_chain_tb.dut_i0.set_data[0]
+@10420
+#{ddc_chain_tb.dut_i0.rx_fe_i[23:0]} ddc_chain_tb.dut_i0.rx_fe_i[23] ddc_chain_tb.dut_i0.rx_fe_i[22] ddc_chain_tb.dut_i0.rx_fe_i[21] ddc_chain_tb.dut_i0.rx_fe_i[20] ddc_chain_tb.dut_i0.rx_fe_i[19] ddc_chain_tb.dut_i0.rx_fe_i[18] ddc_chain_tb.dut_i0.rx_fe_i[17] ddc_chain_tb.dut_i0.rx_fe_i[16] ddc_chain_tb.dut_i0.rx_fe_i[15] ddc_chain_tb.dut_i0.rx_fe_i[14] ddc_chain_tb.dut_i0.rx_fe_i[13] ddc_chain_tb.dut_i0.rx_fe_i[12] ddc_chain_tb.dut_i0.rx_fe_i[11] ddc_chain_tb.dut_i0.rx_fe_i[10] ddc_chain_tb.dut_i0.rx_fe_i[9] ddc_chain_tb.dut_i0.rx_fe_i[8] ddc_chain_tb.dut_i0.rx_fe_i[7] ddc_chain_tb.dut_i0.rx_fe_i[6] ddc_chain_tb.dut_i0.rx_fe_i[5] ddc_chain_tb.dut_i0.rx_fe_i[4] ddc_chain_tb.dut_i0.rx_fe_i[3] ddc_chain_tb.dut_i0.rx_fe_i[2] ddc_chain_tb.dut_i0.rx_fe_i[1] ddc_chain_tb.dut_i0.rx_fe_i[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.rx_fe_q[23:0]} ddc_chain_tb.dut_i0.rx_fe_q[23] ddc_chain_tb.dut_i0.rx_fe_q[22] ddc_chain_tb.dut_i0.rx_fe_q[21] ddc_chain_tb.dut_i0.rx_fe_q[20] ddc_chain_tb.dut_i0.rx_fe_q[19] ddc_chain_tb.dut_i0.rx_fe_q[18] ddc_chain_tb.dut_i0.rx_fe_q[17] ddc_chain_tb.dut_i0.rx_fe_q[16] ddc_chain_tb.dut_i0.rx_fe_q[15] ddc_chain_tb.dut_i0.rx_fe_q[14] ddc_chain_tb.dut_i0.rx_fe_q[13] ddc_chain_tb.dut_i0.rx_fe_q[12] ddc_chain_tb.dut_i0.rx_fe_q[11] ddc_chain_tb.dut_i0.rx_fe_q[10] ddc_chain_tb.dut_i0.rx_fe_q[9] ddc_chain_tb.dut_i0.rx_fe_q[8] ddc_chain_tb.dut_i0.rx_fe_q[7] ddc_chain_tb.dut_i0.rx_fe_q[6] ddc_chain_tb.dut_i0.rx_fe_q[5] ddc_chain_tb.dut_i0.rx_fe_q[4] ddc_chain_tb.dut_i0.rx_fe_q[3] ddc_chain_tb.dut_i0.rx_fe_q[2] ddc_chain_tb.dut_i0.rx_fe_q[1] ddc_chain_tb.dut_i0.rx_fe_q[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.i_cordic_clip[23:0]} ddc_chain_tb.dut_i0.i_cordic_clip[23] ddc_chain_tb.dut_i0.i_cordic_clip[22] ddc_chain_tb.dut_i0.i_cordic_clip[21] ddc_chain_tb.dut_i0.i_cordic_clip[20] ddc_chain_tb.dut_i0.i_cordic_clip[19] ddc_chain_tb.dut_i0.i_cordic_clip[18] ddc_chain_tb.dut_i0.i_cordic_clip[17] ddc_chain_tb.dut_i0.i_cordic_clip[16] ddc_chain_tb.dut_i0.i_cordic_clip[15] ddc_chain_tb.dut_i0.i_cordic_clip[14] ddc_chain_tb.dut_i0.i_cordic_clip[13] ddc_chain_tb.dut_i0.i_cordic_clip[12] ddc_chain_tb.dut_i0.i_cordic_clip[11] ddc_chain_tb.dut_i0.i_cordic_clip[10] ddc_chain_tb.dut_i0.i_cordic_clip[9] ddc_chain_tb.dut_i0.i_cordic_clip[8] ddc_chain_tb.dut_i0.i_cordic_clip[7] ddc_chain_tb.dut_i0.i_cordic_clip[6] ddc_chain_tb.dut_i0.i_cordic_clip[5] ddc_chain_tb.dut_i0.i_cordic_clip[4] ddc_chain_tb.dut_i0.i_cordic_clip[3] ddc_chain_tb.dut_i0.i_cordic_clip[2] ddc_chain_tb.dut_i0.i_cordic_clip[1] ddc_chain_tb.dut_i0.i_cordic_clip[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.q_cordic_clip[23:0]} ddc_chain_tb.dut_i0.q_cordic_clip[23] ddc_chain_tb.dut_i0.q_cordic_clip[22] ddc_chain_tb.dut_i0.q_cordic_clip[21] ddc_chain_tb.dut_i0.q_cordic_clip[20] ddc_chain_tb.dut_i0.q_cordic_clip[19] ddc_chain_tb.dut_i0.q_cordic_clip[18] ddc_chain_tb.dut_i0.q_cordic_clip[17] ddc_chain_tb.dut_i0.q_cordic_clip[16] ddc_chain_tb.dut_i0.q_cordic_clip[15] ddc_chain_tb.dut_i0.q_cordic_clip[14] ddc_chain_tb.dut_i0.q_cordic_clip[13] ddc_chain_tb.dut_i0.q_cordic_clip[12] ddc_chain_tb.dut_i0.q_cordic_clip[11] ddc_chain_tb.dut_i0.q_cordic_clip[10] ddc_chain_tb.dut_i0.q_cordic_clip[9] ddc_chain_tb.dut_i0.q_cordic_clip[8] ddc_chain_tb.dut_i0.q_cordic_clip[7] ddc_chain_tb.dut_i0.q_cordic_clip[6] ddc_chain_tb.dut_i0.q_cordic_clip[5] ddc_chain_tb.dut_i0.q_cordic_clip[4] ddc_chain_tb.dut_i0.q_cordic_clip[3] ddc_chain_tb.dut_i0.q_cordic_clip[2] ddc_chain_tb.dut_i0.q_cordic_clip[1] ddc_chain_tb.dut_i0.q_cordic_clip[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.i_cic[23:0]} ddc_chain_tb.dut_i0.i_cic[23] ddc_chain_tb.dut_i0.i_cic[22] ddc_chain_tb.dut_i0.i_cic[21] ddc_chain_tb.dut_i0.i_cic[20] ddc_chain_tb.dut_i0.i_cic[19] ddc_chain_tb.dut_i0.i_cic[18] ddc_chain_tb.dut_i0.i_cic[17] ddc_chain_tb.dut_i0.i_cic[16] ddc_chain_tb.dut_i0.i_cic[15] ddc_chain_tb.dut_i0.i_cic[14] ddc_chain_tb.dut_i0.i_cic[13] ddc_chain_tb.dut_i0.i_cic[12] ddc_chain_tb.dut_i0.i_cic[11] ddc_chain_tb.dut_i0.i_cic[10] ddc_chain_tb.dut_i0.i_cic[9] ddc_chain_tb.dut_i0.i_cic[8] ddc_chain_tb.dut_i0.i_cic[7] ddc_chain_tb.dut_i0.i_cic[6] ddc_chain_tb.dut_i0.i_cic[5] ddc_chain_tb.dut_i0.i_cic[4] ddc_chain_tb.dut_i0.i_cic[3] ddc_chain_tb.dut_i0.i_cic[2] ddc_chain_tb.dut_i0.i_cic[1] ddc_chain_tb.dut_i0.i_cic[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.q_cic[23:0]} ddc_chain_tb.dut_i0.q_cic[23] ddc_chain_tb.dut_i0.q_cic[22] ddc_chain_tb.dut_i0.q_cic[21] ddc_chain_tb.dut_i0.q_cic[20] ddc_chain_tb.dut_i0.q_cic[19] ddc_chain_tb.dut_i0.q_cic[18] ddc_chain_tb.dut_i0.q_cic[17] ddc_chain_tb.dut_i0.q_cic[16] ddc_chain_tb.dut_i0.q_cic[15] ddc_chain_tb.dut_i0.q_cic[14] ddc_chain_tb.dut_i0.q_cic[13] ddc_chain_tb.dut_i0.q_cic[12] ddc_chain_tb.dut_i0.q_cic[11] ddc_chain_tb.dut_i0.q_cic[10] ddc_chain_tb.dut_i0.q_cic[9] ddc_chain_tb.dut_i0.q_cic[8] ddc_chain_tb.dut_i0.q_cic[7] ddc_chain_tb.dut_i0.q_cic[6] ddc_chain_tb.dut_i0.q_cic[5] ddc_chain_tb.dut_i0.q_cic[4] ddc_chain_tb.dut_i0.q_cic[3] ddc_chain_tb.dut_i0.q_cic[2] ddc_chain_tb.dut_i0.q_cic[1] ddc_chain_tb.dut_i0.q_cic[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.i_hb1[46:0]} ddc_chain_tb.dut_i0.\new_hb.i_hb1[46] ddc_chain_tb.dut_i0.\new_hb.i_hb1[45] ddc_chain_tb.dut_i0.\new_hb.i_hb1[44] ddc_chain_tb.dut_i0.\new_hb.i_hb1[43] ddc_chain_tb.dut_i0.\new_hb.i_hb1[42] ddc_chain_tb.dut_i0.\new_hb.i_hb1[41] ddc_chain_tb.dut_i0.\new_hb.i_hb1[40] ddc_chain_tb.dut_i0.\new_hb.i_hb1[39] ddc_chain_tb.dut_i0.\new_hb.i_hb1[38] ddc_chain_tb.dut_i0.\new_hb.i_hb1[37] ddc_chain_tb.dut_i0.\new_hb.i_hb1[36] ddc_chain_tb.dut_i0.\new_hb.i_hb1[35] ddc_chain_tb.dut_i0.\new_hb.i_hb1[34] ddc_chain_tb.dut_i0.\new_hb.i_hb1[33] ddc_chain_tb.dut_i0.\new_hb.i_hb1[32] ddc_chain_tb.dut_i0.\new_hb.i_hb1[31] ddc_chain_tb.dut_i0.\new_hb.i_hb1[30] ddc_chain_tb.dut_i0.\new_hb.i_hb1[29] ddc_chain_tb.dut_i0.\new_hb.i_hb1[28] ddc_chain_tb.dut_i0.\new_hb.i_hb1[27] ddc_chain_tb.dut_i0.\new_hb.i_hb1[26] ddc_chain_tb.dut_i0.\new_hb.i_hb1[25] ddc_chain_tb.dut_i0.\new_hb.i_hb1[24] ddc_chain_tb.dut_i0.\new_hb.i_hb1[23] ddc_chain_tb.dut_i0.\new_hb.i_hb1[22] ddc_chain_tb.dut_i0.\new_hb.i_hb1[21] ddc_chain_tb.dut_i0.\new_hb.i_hb1[20] ddc_chain_tb.dut_i0.\new_hb.i_hb1[19] ddc_chain_tb.dut_i0.\new_hb.i_hb1[18] ddc_chain_tb.dut_i0.\new_hb.i_hb1[17] ddc_chain_tb.dut_i0.\new_hb.i_hb1[16] ddc_chain_tb.dut_i0.\new_hb.i_hb1[15] ddc_chain_tb.dut_i0.\new_hb.i_hb1[14] ddc_chain_tb.dut_i0.\new_hb.i_hb1[13] ddc_chain_tb.dut_i0.\new_hb.i_hb1[12] ddc_chain_tb.dut_i0.\new_hb.i_hb1[11] ddc_chain_tb.dut_i0.\new_hb.i_hb1[10] ddc_chain_tb.dut_i0.\new_hb.i_hb1[9] ddc_chain_tb.dut_i0.\new_hb.i_hb1[8] ddc_chain_tb.dut_i0.\new_hb.i_hb1[7] ddc_chain_tb.dut_i0.\new_hb.i_hb1[6] ddc_chain_tb.dut_i0.\new_hb.i_hb1[5] ddc_chain_tb.dut_i0.\new_hb.i_hb1[4] ddc_chain_tb.dut_i0.\new_hb.i_hb1[3] ddc_chain_tb.dut_i0.\new_hb.i_hb1[2] ddc_chain_tb.dut_i0.\new_hb.i_hb1[1] ddc_chain_tb.dut_i0.\new_hb.i_hb1[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.q_hb1[46:0]} ddc_chain_tb.dut_i0.\new_hb.q_hb1[46] ddc_chain_tb.dut_i0.\new_hb.q_hb1[45] ddc_chain_tb.dut_i0.\new_hb.q_hb1[44] ddc_chain_tb.dut_i0.\new_hb.q_hb1[43] ddc_chain_tb.dut_i0.\new_hb.q_hb1[42] ddc_chain_tb.dut_i0.\new_hb.q_hb1[41] ddc_chain_tb.dut_i0.\new_hb.q_hb1[40] ddc_chain_tb.dut_i0.\new_hb.q_hb1[39] ddc_chain_tb.dut_i0.\new_hb.q_hb1[38] ddc_chain_tb.dut_i0.\new_hb.q_hb1[37] ddc_chain_tb.dut_i0.\new_hb.q_hb1[36] ddc_chain_tb.dut_i0.\new_hb.q_hb1[35] ddc_chain_tb.dut_i0.\new_hb.q_hb1[34] ddc_chain_tb.dut_i0.\new_hb.q_hb1[33] ddc_chain_tb.dut_i0.\new_hb.q_hb1[32] ddc_chain_tb.dut_i0.\new_hb.q_hb1[31] ddc_chain_tb.dut_i0.\new_hb.q_hb1[30] ddc_chain_tb.dut_i0.\new_hb.q_hb1[29] ddc_chain_tb.dut_i0.\new_hb.q_hb1[28] ddc_chain_tb.dut_i0.\new_hb.q_hb1[27] ddc_chain_tb.dut_i0.\new_hb.q_hb1[26] ddc_chain_tb.dut_i0.\new_hb.q_hb1[25] ddc_chain_tb.dut_i0.\new_hb.q_hb1[24] ddc_chain_tb.dut_i0.\new_hb.q_hb1[23] ddc_chain_tb.dut_i0.\new_hb.q_hb1[22] ddc_chain_tb.dut_i0.\new_hb.q_hb1[21] ddc_chain_tb.dut_i0.\new_hb.q_hb1[20] ddc_chain_tb.dut_i0.\new_hb.q_hb1[19] ddc_chain_tb.dut_i0.\new_hb.q_hb1[18] ddc_chain_tb.dut_i0.\new_hb.q_hb1[17] ddc_chain_tb.dut_i0.\new_hb.q_hb1[16] ddc_chain_tb.dut_i0.\new_hb.q_hb1[15] ddc_chain_tb.dut_i0.\new_hb.q_hb1[14] ddc_chain_tb.dut_i0.\new_hb.q_hb1[13] ddc_chain_tb.dut_i0.\new_hb.q_hb1[12] ddc_chain_tb.dut_i0.\new_hb.q_hb1[11] ddc_chain_tb.dut_i0.\new_hb.q_hb1[10] ddc_chain_tb.dut_i0.\new_hb.q_hb1[9] ddc_chain_tb.dut_i0.\new_hb.q_hb1[8] ddc_chain_tb.dut_i0.\new_hb.q_hb1[7] ddc_chain_tb.dut_i0.\new_hb.q_hb1[6] ddc_chain_tb.dut_i0.\new_hb.q_hb1[5] ddc_chain_tb.dut_i0.\new_hb.q_hb1[4] ddc_chain_tb.dut_i0.\new_hb.q_hb1[3] ddc_chain_tb.dut_i0.\new_hb.q_hb1[2] ddc_chain_tb.dut_i0.\new_hb.q_hb1[1] ddc_chain_tb.dut_i0.\new_hb.q_hb1[0]
+@20000
+-
+@10420
+#{ddc_chain_tb.dut_i0.\new_hb.i_hb2[46:0]} ddc_chain_tb.dut_i0.\new_hb.i_hb2[46] ddc_chain_tb.dut_i0.\new_hb.i_hb2[45] ddc_chain_tb.dut_i0.\new_hb.i_hb2[44] ddc_chain_tb.dut_i0.\new_hb.i_hb2[43] ddc_chain_tb.dut_i0.\new_hb.i_hb2[42] ddc_chain_tb.dut_i0.\new_hb.i_hb2[41] ddc_chain_tb.dut_i0.\new_hb.i_hb2[40] ddc_chain_tb.dut_i0.\new_hb.i_hb2[39] ddc_chain_tb.dut_i0.\new_hb.i_hb2[38] ddc_chain_tb.dut_i0.\new_hb.i_hb2[37] ddc_chain_tb.dut_i0.\new_hb.i_hb2[36] ddc_chain_tb.dut_i0.\new_hb.i_hb2[35] ddc_chain_tb.dut_i0.\new_hb.i_hb2[34] ddc_chain_tb.dut_i0.\new_hb.i_hb2[33] ddc_chain_tb.dut_i0.\new_hb.i_hb2[32] ddc_chain_tb.dut_i0.\new_hb.i_hb2[31] ddc_chain_tb.dut_i0.\new_hb.i_hb2[30] ddc_chain_tb.dut_i0.\new_hb.i_hb2[29] ddc_chain_tb.dut_i0.\new_hb.i_hb2[28] ddc_chain_tb.dut_i0.\new_hb.i_hb2[27] ddc_chain_tb.dut_i0.\new_hb.i_hb2[26] ddc_chain_tb.dut_i0.\new_hb.i_hb2[25] ddc_chain_tb.dut_i0.\new_hb.i_hb2[24] ddc_chain_tb.dut_i0.\new_hb.i_hb2[23] ddc_chain_tb.dut_i0.\new_hb.i_hb2[22] ddc_chain_tb.dut_i0.\new_hb.i_hb2[21] ddc_chain_tb.dut_i0.\new_hb.i_hb2[20] ddc_chain_tb.dut_i0.\new_hb.i_hb2[19] ddc_chain_tb.dut_i0.\new_hb.i_hb2[18] ddc_chain_tb.dut_i0.\new_hb.i_hb2[17] ddc_chain_tb.dut_i0.\new_hb.i_hb2[16] ddc_chain_tb.dut_i0.\new_hb.i_hb2[15] ddc_chain_tb.dut_i0.\new_hb.i_hb2[14] ddc_chain_tb.dut_i0.\new_hb.i_hb2[13] ddc_chain_tb.dut_i0.\new_hb.i_hb2[12] ddc_chain_tb.dut_i0.\new_hb.i_hb2[11] ddc_chain_tb.dut_i0.\new_hb.i_hb2[10] ddc_chain_tb.dut_i0.\new_hb.i_hb2[9] ddc_chain_tb.dut_i0.\new_hb.i_hb2[8] ddc_chain_tb.dut_i0.\new_hb.i_hb2[7] ddc_chain_tb.dut_i0.\new_hb.i_hb2[6] ddc_chain_tb.dut_i0.\new_hb.i_hb2[5] ddc_chain_tb.dut_i0.\new_hb.i_hb2[4] ddc_chain_tb.dut_i0.\new_hb.i_hb2[3] ddc_chain_tb.dut_i0.\new_hb.i_hb2[2] ddc_chain_tb.dut_i0.\new_hb.i_hb2[1] ddc_chain_tb.dut_i0.\new_hb.i_hb2[0]
+#{ddc_chain_tb.dut_i0.\new_hb.q_hb2[46:0]} ddc_chain_tb.dut_i0.\new_hb.q_hb2[46] ddc_chain_tb.dut_i0.\new_hb.q_hb2[45] ddc_chain_tb.dut_i0.\new_hb.q_hb2[44] ddc_chain_tb.dut_i0.\new_hb.q_hb2[43] ddc_chain_tb.dut_i0.\new_hb.q_hb2[42] ddc_chain_tb.dut_i0.\new_hb.q_hb2[41] ddc_chain_tb.dut_i0.\new_hb.q_hb2[40] ddc_chain_tb.dut_i0.\new_hb.q_hb2[39] ddc_chain_tb.dut_i0.\new_hb.q_hb2[38] ddc_chain_tb.dut_i0.\new_hb.q_hb2[37] ddc_chain_tb.dut_i0.\new_hb.q_hb2[36] ddc_chain_tb.dut_i0.\new_hb.q_hb2[35] ddc_chain_tb.dut_i0.\new_hb.q_hb2[34] ddc_chain_tb.dut_i0.\new_hb.q_hb2[33] ddc_chain_tb.dut_i0.\new_hb.q_hb2[32] ddc_chain_tb.dut_i0.\new_hb.q_hb2[31] ddc_chain_tb.dut_i0.\new_hb.q_hb2[30] ddc_chain_tb.dut_i0.\new_hb.q_hb2[29] ddc_chain_tb.dut_i0.\new_hb.q_hb2[28] ddc_chain_tb.dut_i0.\new_hb.q_hb2[27] ddc_chain_tb.dut_i0.\new_hb.q_hb2[26] ddc_chain_tb.dut_i0.\new_hb.q_hb2[25] ddc_chain_tb.dut_i0.\new_hb.q_hb2[24] ddc_chain_tb.dut_i0.\new_hb.q_hb2[23] ddc_chain_tb.dut_i0.\new_hb.q_hb2[22] ddc_chain_tb.dut_i0.\new_hb.q_hb2[21] ddc_chain_tb.dut_i0.\new_hb.q_hb2[20] ddc_chain_tb.dut_i0.\new_hb.q_hb2[19] ddc_chain_tb.dut_i0.\new_hb.q_hb2[18] ddc_chain_tb.dut_i0.\new_hb.q_hb2[17] ddc_chain_tb.dut_i0.\new_hb.q_hb2[16] ddc_chain_tb.dut_i0.\new_hb.q_hb2[15] ddc_chain_tb.dut_i0.\new_hb.q_hb2[14] ddc_chain_tb.dut_i0.\new_hb.q_hb2[13] ddc_chain_tb.dut_i0.\new_hb.q_hb2[12] ddc_chain_tb.dut_i0.\new_hb.q_hb2[11] ddc_chain_tb.dut_i0.\new_hb.q_hb2[10] ddc_chain_tb.dut_i0.\new_hb.q_hb2[9] ddc_chain_tb.dut_i0.\new_hb.q_hb2[8] ddc_chain_tb.dut_i0.\new_hb.q_hb2[7] ddc_chain_tb.dut_i0.\new_hb.q_hb2[6] ddc_chain_tb.dut_i0.\new_hb.q_hb2[5] ddc_chain_tb.dut_i0.\new_hb.q_hb2[4] ddc_chain_tb.dut_i0.\new_hb.q_hb2[3] ddc_chain_tb.dut_i0.\new_hb.q_hb2[2] ddc_chain_tb.dut_i0.\new_hb.q_hb2[1] ddc_chain_tb.dut_i0.\new_hb.q_hb2[0]
+@20000
+-
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/simulation_script.v b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/simulation_script.v
new file mode 100644
index 000000000..19836cc98
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/dc_in_cordic_decim_6/simulation_script.v
@@ -0,0 +1,83 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// 10MHz master_clock_rate
+always #50 clk <= ~clk;
+
+ initial
+ begin
+ reset <= 1'b0;
+ i_in <= 0;
+ q_in <= 0;
+ run <= 0;
+ set_stb <= 0;
+ set_addr <= 0;
+ set_data <= 0;
+
+
+ @(posedge clk);
+ // Into Reset...
+ reset <= 1'b1;
+ repeat(10) @(posedge clk);
+ // .. and back out of reset.
+ reset <= 1'b0;
+ repeat(10) @(posedge clk);
+ // Now program DSP configuration via settings regs.
+ write_setting_bus(SR_DSP_RX_FREQ,42949672); // 100kHz @ 10MHz MCR
+ write_setting_bus(SR_DSP_RX_SCALE_IQ, 62842); // Should include CORDIC and CIC gain compensation.
+ // write_setting_bus(SR_DSP_RX_SCALE_IQ, ((1<<16) * 1.647 * 0.5 * 1.22)); // Should include CORDIC and CIC gain compensation.
+ write_setting_bus(SR_DSP_RX_DECIM, 1<<9|3); // Decim = 6
+ write_setting_bus(SR_DSP_RX_MUX, 0);
+ write_setting_bus(SR_DSP_RX_COEFFS,0);
+ repeat(10) @(posedge clk);
+
+ // Set complex data inputs to DC unit circle position.
+ i_in <= 12'h7ff;
+ q_in <= 12'h0;
+ run <= 1'b1;
+ repeat(100) @(posedge clk);
+ // Set complex data inputs to simulate ADC saturation of front end
+ i_in <= 12'h7ff;
+ q_in <= 12'h100;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h200;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h300;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h400;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h500;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h600;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h700;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h7ff;
+ q_in <= 12'h7FF;
+ // Now test small signal performance
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h001;
+ q_in <= 12'h000;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h000;
+ q_in <= 12'h001;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'hfff;
+ q_in <= 12'h000;
+ repeat(1000) @(posedge clk);
+ i_in <= 12'h000;
+ q_in <= 12'hfff;
+
+
+ repeat(100000) @(posedge clk);
+ $finish();
+
+ end // initial begin
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/ddc_chain_tb.v b/fpga/usrp3/lib/sim/dsp/ddc_chain/ddc_chain_tb.v
new file mode 100644
index 000000000..fe8bbb000
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/ddc_chain_tb.v
@@ -0,0 +1,94 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module ddc_chain_tb();
+
+ initial $dumpfile("waves.vcd");
+ initial $dumpvars(2,ddc_chain_tb.dut_i0);
+
+
+ // Need these declarations to use the task libarary.
+`ifndef CHDR_IN_NUMBER
+ `define CHDR_IN_NUMBER 1
+`endif
+`ifndef CHDR_OUT_NUMBER
+ `define CHDR_OUT_NUMBER 1
+`endif
+
+ reg [63:0] data_in[`CHDR_IN_NUMBER-1:0];
+ reg last_in[`CHDR_IN_NUMBER-1:0];
+ reg valid_in[`CHDR_IN_NUMBER-1:0];
+ wire ready_in[`CHDR_IN_NUMBER-1:0];
+ wire [63:0] data_out[`CHDR_OUT_NUMBER-1:0];
+ wire last_out[`CHDR_OUT_NUMBER-1:0];
+ wire valid_out[`CHDR_OUT_NUMBER-1:0];
+ reg ready_out[`CHDR_OUT_NUMBER-1:0];
+ //
+
+`include "../../../../../sim/radio_setting_regs.v"
+`include "../../../../../sim/task_library.v"
+
+ localparam DSPNO = 0;
+ localparam WIDTH = 24;
+ localparam NEW_HB_DECIM = 1;
+ localparam DEVICE = "SPARTAN6";
+
+ reg clk = 0;
+ reg reset;
+
+ reg set_stb;
+ reg [7:0] set_addr;
+ reg [31:0] set_data;
+
+ wire [WIDTH-1:0] rx_fe_i, rx_fe_q;
+ wire [31:0] sample;
+ reg run;
+ wire strobe;
+
+ reg [11:0] i_in, q_in;
+
+ assign rx_fe_i = {i_in,12'h0};
+ assign rx_fe_q = {q_in,12'h0};
+
+ //
+ // DUT
+ //
+ ddc_chain
+ #(
+ .BASE(SR_RX_DSP),
+ .DSPNO(DSPNO),
+ .WIDTH(WIDTH),
+ .NEW_HB_DECIM(NEW_HB_DECIM),
+ .DEVICE("SPARTAN6")
+ )
+ dut_i0 (
+ .clk(clk),
+ .rst(reset),
+ .clr(1'b0),
+ .set_stb(set_stb),
+ .set_addr(set_addr),
+ .set_data(set_data),
+
+ // From RX frontend
+ .rx_fe_i(rx_fe_i),
+ .rx_fe_q(rx_fe_q),
+
+ // To RX control
+ .sample(sample),
+ .run(run),
+ .strobe(strobe),
+ .debug()
+ );
+
+
+
+ //
+ // Include testbench
+ //
+`include "simulation_script.v"
+
+endmodule //
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain/run_isim b/fpga/usrp3/lib/sim/dsp/ddc_chain/run_isim
new file mode 100755
index 000000000..d43ccf230
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain/run_isim
@@ -0,0 +1,18 @@
+rm -rf fuse* *.exe isim
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../.. \
+ --sourcelibdir ../../../../control \
+ --sourcelibdir ../../../../../top/b200/coregen_dsp \
+ --sourcelibdir ../../../../../top/b200/coregen \
+ --sourcelibdir ${XILINX}/verilog/src/unimacro \
+ ddc_chain_tb.v
+
+
+
+fuse work.ddc_chain_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o testbench.exe
+
+# run the simulation script
+./testbench.exe #-gui #-tclbatch simcmds.tcl
+
+
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/.gitignore b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/.gitignore
new file mode 100644
index 000000000..7826d75e2
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/.gitignore
@@ -0,0 +1,4 @@
+fuse*
+isim*
+*.exe
+*.wcfg
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/DDC.sav b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/DDC.sav
new file mode 100644
index 000000000..96ec87c67
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/DDC.sav
@@ -0,0 +1,101 @@
+[*]
+[*] GTKWave Analyzer v3.3.35 (w)1999-2012 BSI
+[*] Thu Dec 5 01:04:45 2013
+[*]
+[dumpfile] "/home/matt/fpgadev/usrp3/sim/ddc_chain_x300/dctest/ddc_chain_x300_tb.vcd"
+[dumpfile_mtime] "Wed Dec 4 23:01:47 2013"
+[dumpfile_size] 12968759
+[savefile] "/home/matt/fpgadev/usrp3/sim/ddc_chain_x300/dctest/DDC.sav"
+[timestart] 0
+[size] 1600 843
+[pos] -1 -1
+*-22.573410 5990000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
+[treeopen] ddc_chain_x300_tb.
+[treeopen] ddc_chain_x300_tb.ddc_chain.
+[treeopen] ddc_chain_x300_tb.ddc_chain.clip_i.
+[sst_width] 231
+[signals_width] 313
+[sst_expanded] 1
+[sst_vpaned_height] 229
+@420
+#{ddc_chain_x300_tb.ddc_chain.i_cic[23:0]} ddc_chain_x300_tb.ddc_chain.i_cic[23] ddc_chain_x300_tb.ddc_chain.i_cic[22] ddc_chain_x300_tb.ddc_chain.i_cic[21] ddc_chain_x300_tb.ddc_chain.i_cic[20] ddc_chain_x300_tb.ddc_chain.i_cic[19] ddc_chain_x300_tb.ddc_chain.i_cic[18] ddc_chain_x300_tb.ddc_chain.i_cic[17] ddc_chain_x300_tb.ddc_chain.i_cic[16] ddc_chain_x300_tb.ddc_chain.i_cic[15] ddc_chain_x300_tb.ddc_chain.i_cic[14] ddc_chain_x300_tb.ddc_chain.i_cic[13] ddc_chain_x300_tb.ddc_chain.i_cic[12] ddc_chain_x300_tb.ddc_chain.i_cic[11] ddc_chain_x300_tb.ddc_chain.i_cic[10] ddc_chain_x300_tb.ddc_chain.i_cic[9] ddc_chain_x300_tb.ddc_chain.i_cic[8] ddc_chain_x300_tb.ddc_chain.i_cic[7] ddc_chain_x300_tb.ddc_chain.i_cic[6] ddc_chain_x300_tb.ddc_chain.i_cic[5] ddc_chain_x300_tb.ddc_chain.i_cic[4] ddc_chain_x300_tb.ddc_chain.i_cic[3] ddc_chain_x300_tb.ddc_chain.i_cic[2] ddc_chain_x300_tb.ddc_chain.i_cic[1] ddc_chain_x300_tb.ddc_chain.i_cic[0]
+@28
+ddc_chain_x300_tb.ddc_chain.strobe_cic
+@420
+#{ddc_chain_x300_tb.ddc_chain.i_hb1[46:0]} ddc_chain_x300_tb.ddc_chain.i_hb1[46] ddc_chain_x300_tb.ddc_chain.i_hb1[45] ddc_chain_x300_tb.ddc_chain.i_hb1[44] ddc_chain_x300_tb.ddc_chain.i_hb1[43] ddc_chain_x300_tb.ddc_chain.i_hb1[42] ddc_chain_x300_tb.ddc_chain.i_hb1[41] ddc_chain_x300_tb.ddc_chain.i_hb1[40] ddc_chain_x300_tb.ddc_chain.i_hb1[39] ddc_chain_x300_tb.ddc_chain.i_hb1[38] ddc_chain_x300_tb.ddc_chain.i_hb1[37] ddc_chain_x300_tb.ddc_chain.i_hb1[36] ddc_chain_x300_tb.ddc_chain.i_hb1[35] ddc_chain_x300_tb.ddc_chain.i_hb1[34] ddc_chain_x300_tb.ddc_chain.i_hb1[33] ddc_chain_x300_tb.ddc_chain.i_hb1[32] ddc_chain_x300_tb.ddc_chain.i_hb1[31] ddc_chain_x300_tb.ddc_chain.i_hb1[30] ddc_chain_x300_tb.ddc_chain.i_hb1[29] ddc_chain_x300_tb.ddc_chain.i_hb1[28] ddc_chain_x300_tb.ddc_chain.i_hb1[27] ddc_chain_x300_tb.ddc_chain.i_hb1[26] ddc_chain_x300_tb.ddc_chain.i_hb1[25] ddc_chain_x300_tb.ddc_chain.i_hb1[24] ddc_chain_x300_tb.ddc_chain.i_hb1[23] ddc_chain_x300_tb.ddc_chain.i_hb1[22] ddc_chain_x300_tb.ddc_chain.i_hb1[21] ddc_chain_x300_tb.ddc_chain.i_hb1[20] ddc_chain_x300_tb.ddc_chain.i_hb1[19] ddc_chain_x300_tb.ddc_chain.i_hb1[18] ddc_chain_x300_tb.ddc_chain.i_hb1[17] ddc_chain_x300_tb.ddc_chain.i_hb1[16] ddc_chain_x300_tb.ddc_chain.i_hb1[15] ddc_chain_x300_tb.ddc_chain.i_hb1[14] ddc_chain_x300_tb.ddc_chain.i_hb1[13] ddc_chain_x300_tb.ddc_chain.i_hb1[12] ddc_chain_x300_tb.ddc_chain.i_hb1[11] ddc_chain_x300_tb.ddc_chain.i_hb1[10] ddc_chain_x300_tb.ddc_chain.i_hb1[9] ddc_chain_x300_tb.ddc_chain.i_hb1[8] ddc_chain_x300_tb.ddc_chain.i_hb1[7] ddc_chain_x300_tb.ddc_chain.i_hb1[6] ddc_chain_x300_tb.ddc_chain.i_hb1[5] ddc_chain_x300_tb.ddc_chain.i_hb1[4] ddc_chain_x300_tb.ddc_chain.i_hb1[3] ddc_chain_x300_tb.ddc_chain.i_hb1[2] ddc_chain_x300_tb.ddc_chain.i_hb1[1] ddc_chain_x300_tb.ddc_chain.i_hb1[0]
+@28
+ddc_chain_x300_tb.ddc_chain.strobe_hb1
+@420
+#{ddc_chain_x300_tb.ddc_chain.i_hb2[46:0]} ddc_chain_x300_tb.ddc_chain.i_hb2[46] ddc_chain_x300_tb.ddc_chain.i_hb2[45] ddc_chain_x300_tb.ddc_chain.i_hb2[44] ddc_chain_x300_tb.ddc_chain.i_hb2[43] ddc_chain_x300_tb.ddc_chain.i_hb2[42] ddc_chain_x300_tb.ddc_chain.i_hb2[41] ddc_chain_x300_tb.ddc_chain.i_hb2[40] ddc_chain_x300_tb.ddc_chain.i_hb2[39] ddc_chain_x300_tb.ddc_chain.i_hb2[38] ddc_chain_x300_tb.ddc_chain.i_hb2[37] ddc_chain_x300_tb.ddc_chain.i_hb2[36] ddc_chain_x300_tb.ddc_chain.i_hb2[35] ddc_chain_x300_tb.ddc_chain.i_hb2[34] ddc_chain_x300_tb.ddc_chain.i_hb2[33] ddc_chain_x300_tb.ddc_chain.i_hb2[32] ddc_chain_x300_tb.ddc_chain.i_hb2[31] ddc_chain_x300_tb.ddc_chain.i_hb2[30] ddc_chain_x300_tb.ddc_chain.i_hb2[29] ddc_chain_x300_tb.ddc_chain.i_hb2[28] ddc_chain_x300_tb.ddc_chain.i_hb2[27] ddc_chain_x300_tb.ddc_chain.i_hb2[26] ddc_chain_x300_tb.ddc_chain.i_hb2[25] ddc_chain_x300_tb.ddc_chain.i_hb2[24] ddc_chain_x300_tb.ddc_chain.i_hb2[23] ddc_chain_x300_tb.ddc_chain.i_hb2[22] ddc_chain_x300_tb.ddc_chain.i_hb2[21] ddc_chain_x300_tb.ddc_chain.i_hb2[20] ddc_chain_x300_tb.ddc_chain.i_hb2[19] ddc_chain_x300_tb.ddc_chain.i_hb2[18] ddc_chain_x300_tb.ddc_chain.i_hb2[17] ddc_chain_x300_tb.ddc_chain.i_hb2[16] ddc_chain_x300_tb.ddc_chain.i_hb2[15] ddc_chain_x300_tb.ddc_chain.i_hb2[14] ddc_chain_x300_tb.ddc_chain.i_hb2[13] ddc_chain_x300_tb.ddc_chain.i_hb2[12] ddc_chain_x300_tb.ddc_chain.i_hb2[11] ddc_chain_x300_tb.ddc_chain.i_hb2[10] ddc_chain_x300_tb.ddc_chain.i_hb2[9] ddc_chain_x300_tb.ddc_chain.i_hb2[8] ddc_chain_x300_tb.ddc_chain.i_hb2[7] ddc_chain_x300_tb.ddc_chain.i_hb2[6] ddc_chain_x300_tb.ddc_chain.i_hb2[5] ddc_chain_x300_tb.ddc_chain.i_hb2[4] ddc_chain_x300_tb.ddc_chain.i_hb2[3] ddc_chain_x300_tb.ddc_chain.i_hb2[2] ddc_chain_x300_tb.ddc_chain.i_hb2[1] ddc_chain_x300_tb.ddc_chain.i_hb2[0]
+@28
+ddc_chain_x300_tb.ddc_chain.strobe_hb2
+@420
+#{ddc_chain_x300_tb.ddc_chain.i_hb3[47:0]} ddc_chain_x300_tb.ddc_chain.i_hb3[47] ddc_chain_x300_tb.ddc_chain.i_hb3[46] ddc_chain_x300_tb.ddc_chain.i_hb3[45] ddc_chain_x300_tb.ddc_chain.i_hb3[44] ddc_chain_x300_tb.ddc_chain.i_hb3[43] ddc_chain_x300_tb.ddc_chain.i_hb3[42] ddc_chain_x300_tb.ddc_chain.i_hb3[41] ddc_chain_x300_tb.ddc_chain.i_hb3[40] ddc_chain_x300_tb.ddc_chain.i_hb3[39] ddc_chain_x300_tb.ddc_chain.i_hb3[38] ddc_chain_x300_tb.ddc_chain.i_hb3[37] ddc_chain_x300_tb.ddc_chain.i_hb3[36] ddc_chain_x300_tb.ddc_chain.i_hb3[35] ddc_chain_x300_tb.ddc_chain.i_hb3[34] ddc_chain_x300_tb.ddc_chain.i_hb3[33] ddc_chain_x300_tb.ddc_chain.i_hb3[32] ddc_chain_x300_tb.ddc_chain.i_hb3[31] ddc_chain_x300_tb.ddc_chain.i_hb3[30] ddc_chain_x300_tb.ddc_chain.i_hb3[29] ddc_chain_x300_tb.ddc_chain.i_hb3[28] ddc_chain_x300_tb.ddc_chain.i_hb3[27] ddc_chain_x300_tb.ddc_chain.i_hb3[26] ddc_chain_x300_tb.ddc_chain.i_hb3[25] ddc_chain_x300_tb.ddc_chain.i_hb3[24] ddc_chain_x300_tb.ddc_chain.i_hb3[23] ddc_chain_x300_tb.ddc_chain.i_hb3[22] ddc_chain_x300_tb.ddc_chain.i_hb3[21] ddc_chain_x300_tb.ddc_chain.i_hb3[20] ddc_chain_x300_tb.ddc_chain.i_hb3[19] ddc_chain_x300_tb.ddc_chain.i_hb3[18] ddc_chain_x300_tb.ddc_chain.i_hb3[17] ddc_chain_x300_tb.ddc_chain.i_hb3[16] ddc_chain_x300_tb.ddc_chain.i_hb3[15] ddc_chain_x300_tb.ddc_chain.i_hb3[14] ddc_chain_x300_tb.ddc_chain.i_hb3[13] ddc_chain_x300_tb.ddc_chain.i_hb3[12] ddc_chain_x300_tb.ddc_chain.i_hb3[11] ddc_chain_x300_tb.ddc_chain.i_hb3[10] ddc_chain_x300_tb.ddc_chain.i_hb3[9] ddc_chain_x300_tb.ddc_chain.i_hb3[8] ddc_chain_x300_tb.ddc_chain.i_hb3[7] ddc_chain_x300_tb.ddc_chain.i_hb3[6] ddc_chain_x300_tb.ddc_chain.i_hb3[5] ddc_chain_x300_tb.ddc_chain.i_hb3[4] ddc_chain_x300_tb.ddc_chain.i_hb3[3] ddc_chain_x300_tb.ddc_chain.i_hb3[2] ddc_chain_x300_tb.ddc_chain.i_hb3[1] ddc_chain_x300_tb.ddc_chain.i_hb3[0]
+@28
+ddc_chain_x300_tb.ddc_chain.strobe_hb3
+@420
+ddc_chain_x300_tb.ddc_chain.i_unscaled[23:0]
+#{ddc_chain_x300_tb.ddc_chain.i_scaled[42:0]} ddc_chain_x300_tb.ddc_chain.i_scaled[42] ddc_chain_x300_tb.ddc_chain.i_scaled[41] ddc_chain_x300_tb.ddc_chain.i_scaled[40] ddc_chain_x300_tb.ddc_chain.i_scaled[39] ddc_chain_x300_tb.ddc_chain.i_scaled[38] ddc_chain_x300_tb.ddc_chain.i_scaled[37] ddc_chain_x300_tb.ddc_chain.i_scaled[36] ddc_chain_x300_tb.ddc_chain.i_scaled[35] ddc_chain_x300_tb.ddc_chain.i_scaled[34] ddc_chain_x300_tb.ddc_chain.i_scaled[33] ddc_chain_x300_tb.ddc_chain.i_scaled[32] ddc_chain_x300_tb.ddc_chain.i_scaled[31] ddc_chain_x300_tb.ddc_chain.i_scaled[30] ddc_chain_x300_tb.ddc_chain.i_scaled[29] ddc_chain_x300_tb.ddc_chain.i_scaled[28] ddc_chain_x300_tb.ddc_chain.i_scaled[27] ddc_chain_x300_tb.ddc_chain.i_scaled[26] ddc_chain_x300_tb.ddc_chain.i_scaled[25] ddc_chain_x300_tb.ddc_chain.i_scaled[24] ddc_chain_x300_tb.ddc_chain.i_scaled[23] ddc_chain_x300_tb.ddc_chain.i_scaled[22] ddc_chain_x300_tb.ddc_chain.i_scaled[21] ddc_chain_x300_tb.ddc_chain.i_scaled[20] ddc_chain_x300_tb.ddc_chain.i_scaled[19] ddc_chain_x300_tb.ddc_chain.i_scaled[18] ddc_chain_x300_tb.ddc_chain.i_scaled[17] ddc_chain_x300_tb.ddc_chain.i_scaled[16] ddc_chain_x300_tb.ddc_chain.i_scaled[15] ddc_chain_x300_tb.ddc_chain.i_scaled[14] ddc_chain_x300_tb.ddc_chain.i_scaled[13] ddc_chain_x300_tb.ddc_chain.i_scaled[12] ddc_chain_x300_tb.ddc_chain.i_scaled[11] ddc_chain_x300_tb.ddc_chain.i_scaled[10] ddc_chain_x300_tb.ddc_chain.i_scaled[9] ddc_chain_x300_tb.ddc_chain.i_scaled[8] ddc_chain_x300_tb.ddc_chain.i_scaled[7] ddc_chain_x300_tb.ddc_chain.i_scaled[6] ddc_chain_x300_tb.ddc_chain.i_scaled[5] ddc_chain_x300_tb.ddc_chain.i_scaled[4] ddc_chain_x300_tb.ddc_chain.i_scaled[3] ddc_chain_x300_tb.ddc_chain.i_scaled[2] ddc_chain_x300_tb.ddc_chain.i_scaled[1] ddc_chain_x300_tb.ddc_chain.i_scaled[0]
+@200
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_cic[23:0]} ddc_chain_x300_tb.ddc_chain.i_cic[23] ddc_chain_x300_tb.ddc_chain.i_cic[22] ddc_chain_x300_tb.ddc_chain.i_cic[21] ddc_chain_x300_tb.ddc_chain.i_cic[20] ddc_chain_x300_tb.ddc_chain.i_cic[19] ddc_chain_x300_tb.ddc_chain.i_cic[18] ddc_chain_x300_tb.ddc_chain.i_cic[17] ddc_chain_x300_tb.ddc_chain.i_cic[16] ddc_chain_x300_tb.ddc_chain.i_cic[15] ddc_chain_x300_tb.ddc_chain.i_cic[14] ddc_chain_x300_tb.ddc_chain.i_cic[13] ddc_chain_x300_tb.ddc_chain.i_cic[12] ddc_chain_x300_tb.ddc_chain.i_cic[11] ddc_chain_x300_tb.ddc_chain.i_cic[10] ddc_chain_x300_tb.ddc_chain.i_cic[9] ddc_chain_x300_tb.ddc_chain.i_cic[8] ddc_chain_x300_tb.ddc_chain.i_cic[7] ddc_chain_x300_tb.ddc_chain.i_cic[6] ddc_chain_x300_tb.ddc_chain.i_cic[5] ddc_chain_x300_tb.ddc_chain.i_cic[4] ddc_chain_x300_tb.ddc_chain.i_cic[3] ddc_chain_x300_tb.ddc_chain.i_cic[2] ddc_chain_x300_tb.ddc_chain.i_cic[1] ddc_chain_x300_tb.ddc_chain.i_cic[0]
+@20000
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_hb1[46:0]} ddc_chain_x300_tb.ddc_chain.i_hb1[46] ddc_chain_x300_tb.ddc_chain.i_hb1[45] ddc_chain_x300_tb.ddc_chain.i_hb1[44] ddc_chain_x300_tb.ddc_chain.i_hb1[43] ddc_chain_x300_tb.ddc_chain.i_hb1[42] ddc_chain_x300_tb.ddc_chain.i_hb1[41] ddc_chain_x300_tb.ddc_chain.i_hb1[40] ddc_chain_x300_tb.ddc_chain.i_hb1[39] ddc_chain_x300_tb.ddc_chain.i_hb1[38] ddc_chain_x300_tb.ddc_chain.i_hb1[37] ddc_chain_x300_tb.ddc_chain.i_hb1[36] ddc_chain_x300_tb.ddc_chain.i_hb1[35] ddc_chain_x300_tb.ddc_chain.i_hb1[34] ddc_chain_x300_tb.ddc_chain.i_hb1[33] ddc_chain_x300_tb.ddc_chain.i_hb1[32] ddc_chain_x300_tb.ddc_chain.i_hb1[31] ddc_chain_x300_tb.ddc_chain.i_hb1[30] ddc_chain_x300_tb.ddc_chain.i_hb1[29] ddc_chain_x300_tb.ddc_chain.i_hb1[28] ddc_chain_x300_tb.ddc_chain.i_hb1[27] ddc_chain_x300_tb.ddc_chain.i_hb1[26] ddc_chain_x300_tb.ddc_chain.i_hb1[25] ddc_chain_x300_tb.ddc_chain.i_hb1[24] ddc_chain_x300_tb.ddc_chain.i_hb1[23] ddc_chain_x300_tb.ddc_chain.i_hb1[22] ddc_chain_x300_tb.ddc_chain.i_hb1[21] ddc_chain_x300_tb.ddc_chain.i_hb1[20] ddc_chain_x300_tb.ddc_chain.i_hb1[19] ddc_chain_x300_tb.ddc_chain.i_hb1[18] ddc_chain_x300_tb.ddc_chain.i_hb1[17] ddc_chain_x300_tb.ddc_chain.i_hb1[16] ddc_chain_x300_tb.ddc_chain.i_hb1[15] ddc_chain_x300_tb.ddc_chain.i_hb1[14] ddc_chain_x300_tb.ddc_chain.i_hb1[13] ddc_chain_x300_tb.ddc_chain.i_hb1[12] ddc_chain_x300_tb.ddc_chain.i_hb1[11] ddc_chain_x300_tb.ddc_chain.i_hb1[10] ddc_chain_x300_tb.ddc_chain.i_hb1[9] ddc_chain_x300_tb.ddc_chain.i_hb1[8] ddc_chain_x300_tb.ddc_chain.i_hb1[7] ddc_chain_x300_tb.ddc_chain.i_hb1[6] ddc_chain_x300_tb.ddc_chain.i_hb1[5] ddc_chain_x300_tb.ddc_chain.i_hb1[4] ddc_chain_x300_tb.ddc_chain.i_hb1[3] ddc_chain_x300_tb.ddc_chain.i_hb1[2] ddc_chain_x300_tb.ddc_chain.i_hb1[1] ddc_chain_x300_tb.ddc_chain.i_hb1[0]
+@20000
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_hb2[46:0]} ddc_chain_x300_tb.ddc_chain.i_hb2[46] ddc_chain_x300_tb.ddc_chain.i_hb2[45] ddc_chain_x300_tb.ddc_chain.i_hb2[44] ddc_chain_x300_tb.ddc_chain.i_hb2[43] ddc_chain_x300_tb.ddc_chain.i_hb2[42] ddc_chain_x300_tb.ddc_chain.i_hb2[41] ddc_chain_x300_tb.ddc_chain.i_hb2[40] ddc_chain_x300_tb.ddc_chain.i_hb2[39] ddc_chain_x300_tb.ddc_chain.i_hb2[38] ddc_chain_x300_tb.ddc_chain.i_hb2[37] ddc_chain_x300_tb.ddc_chain.i_hb2[36] ddc_chain_x300_tb.ddc_chain.i_hb2[35] ddc_chain_x300_tb.ddc_chain.i_hb2[34] ddc_chain_x300_tb.ddc_chain.i_hb2[33] ddc_chain_x300_tb.ddc_chain.i_hb2[32] ddc_chain_x300_tb.ddc_chain.i_hb2[31] ddc_chain_x300_tb.ddc_chain.i_hb2[30] ddc_chain_x300_tb.ddc_chain.i_hb2[29] ddc_chain_x300_tb.ddc_chain.i_hb2[28] ddc_chain_x300_tb.ddc_chain.i_hb2[27] ddc_chain_x300_tb.ddc_chain.i_hb2[26] ddc_chain_x300_tb.ddc_chain.i_hb2[25] ddc_chain_x300_tb.ddc_chain.i_hb2[24] ddc_chain_x300_tb.ddc_chain.i_hb2[23] ddc_chain_x300_tb.ddc_chain.i_hb2[22] ddc_chain_x300_tb.ddc_chain.i_hb2[21] ddc_chain_x300_tb.ddc_chain.i_hb2[20] ddc_chain_x300_tb.ddc_chain.i_hb2[19] ddc_chain_x300_tb.ddc_chain.i_hb2[18] ddc_chain_x300_tb.ddc_chain.i_hb2[17] ddc_chain_x300_tb.ddc_chain.i_hb2[16] ddc_chain_x300_tb.ddc_chain.i_hb2[15] ddc_chain_x300_tb.ddc_chain.i_hb2[14] ddc_chain_x300_tb.ddc_chain.i_hb2[13] ddc_chain_x300_tb.ddc_chain.i_hb2[12] ddc_chain_x300_tb.ddc_chain.i_hb2[11] ddc_chain_x300_tb.ddc_chain.i_hb2[10] ddc_chain_x300_tb.ddc_chain.i_hb2[9] ddc_chain_x300_tb.ddc_chain.i_hb2[8] ddc_chain_x300_tb.ddc_chain.i_hb2[7] ddc_chain_x300_tb.ddc_chain.i_hb2[6] ddc_chain_x300_tb.ddc_chain.i_hb2[5] ddc_chain_x300_tb.ddc_chain.i_hb2[4] ddc_chain_x300_tb.ddc_chain.i_hb2[3] ddc_chain_x300_tb.ddc_chain.i_hb2[2] ddc_chain_x300_tb.ddc_chain.i_hb2[1] ddc_chain_x300_tb.ddc_chain.i_hb2[0]
+@20000
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_hb3[47:0]} ddc_chain_x300_tb.ddc_chain.i_hb3[47] ddc_chain_x300_tb.ddc_chain.i_hb3[46] ddc_chain_x300_tb.ddc_chain.i_hb3[45] ddc_chain_x300_tb.ddc_chain.i_hb3[44] ddc_chain_x300_tb.ddc_chain.i_hb3[43] ddc_chain_x300_tb.ddc_chain.i_hb3[42] ddc_chain_x300_tb.ddc_chain.i_hb3[41] ddc_chain_x300_tb.ddc_chain.i_hb3[40] ddc_chain_x300_tb.ddc_chain.i_hb3[39] ddc_chain_x300_tb.ddc_chain.i_hb3[38] ddc_chain_x300_tb.ddc_chain.i_hb3[37] ddc_chain_x300_tb.ddc_chain.i_hb3[36] ddc_chain_x300_tb.ddc_chain.i_hb3[35] ddc_chain_x300_tb.ddc_chain.i_hb3[34] ddc_chain_x300_tb.ddc_chain.i_hb3[33] ddc_chain_x300_tb.ddc_chain.i_hb3[32] ddc_chain_x300_tb.ddc_chain.i_hb3[31] ddc_chain_x300_tb.ddc_chain.i_hb3[30] ddc_chain_x300_tb.ddc_chain.i_hb3[29] ddc_chain_x300_tb.ddc_chain.i_hb3[28] ddc_chain_x300_tb.ddc_chain.i_hb3[27] ddc_chain_x300_tb.ddc_chain.i_hb3[26] ddc_chain_x300_tb.ddc_chain.i_hb3[25] ddc_chain_x300_tb.ddc_chain.i_hb3[24] ddc_chain_x300_tb.ddc_chain.i_hb3[23] ddc_chain_x300_tb.ddc_chain.i_hb3[22] ddc_chain_x300_tb.ddc_chain.i_hb3[21] ddc_chain_x300_tb.ddc_chain.i_hb3[20] ddc_chain_x300_tb.ddc_chain.i_hb3[19] ddc_chain_x300_tb.ddc_chain.i_hb3[18] ddc_chain_x300_tb.ddc_chain.i_hb3[17] ddc_chain_x300_tb.ddc_chain.i_hb3[16] ddc_chain_x300_tb.ddc_chain.i_hb3[15] ddc_chain_x300_tb.ddc_chain.i_hb3[14] ddc_chain_x300_tb.ddc_chain.i_hb3[13] ddc_chain_x300_tb.ddc_chain.i_hb3[12] ddc_chain_x300_tb.ddc_chain.i_hb3[11] ddc_chain_x300_tb.ddc_chain.i_hb3[10] ddc_chain_x300_tb.ddc_chain.i_hb3[9] ddc_chain_x300_tb.ddc_chain.i_hb3[8] ddc_chain_x300_tb.ddc_chain.i_hb3[7] ddc_chain_x300_tb.ddc_chain.i_hb3[6] ddc_chain_x300_tb.ddc_chain.i_hb3[5] ddc_chain_x300_tb.ddc_chain.i_hb3[4] ddc_chain_x300_tb.ddc_chain.i_hb3[3] ddc_chain_x300_tb.ddc_chain.i_hb3[2] ddc_chain_x300_tb.ddc_chain.i_hb3[1] ddc_chain_x300_tb.ddc_chain.i_hb3[0]
+@20000
+-
+@8420
+ddc_chain_x300_tb.ddc_chain.i_unscaled[23:0]
+@20000
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_scaled[42:0]} ddc_chain_x300_tb.ddc_chain.i_scaled[42] ddc_chain_x300_tb.ddc_chain.i_scaled[41] ddc_chain_x300_tb.ddc_chain.i_scaled[40] ddc_chain_x300_tb.ddc_chain.i_scaled[39] ddc_chain_x300_tb.ddc_chain.i_scaled[38] ddc_chain_x300_tb.ddc_chain.i_scaled[37] ddc_chain_x300_tb.ddc_chain.i_scaled[36] ddc_chain_x300_tb.ddc_chain.i_scaled[35] ddc_chain_x300_tb.ddc_chain.i_scaled[34] ddc_chain_x300_tb.ddc_chain.i_scaled[33] ddc_chain_x300_tb.ddc_chain.i_scaled[32] ddc_chain_x300_tb.ddc_chain.i_scaled[31] ddc_chain_x300_tb.ddc_chain.i_scaled[30] ddc_chain_x300_tb.ddc_chain.i_scaled[29] ddc_chain_x300_tb.ddc_chain.i_scaled[28] ddc_chain_x300_tb.ddc_chain.i_scaled[27] ddc_chain_x300_tb.ddc_chain.i_scaled[26] ddc_chain_x300_tb.ddc_chain.i_scaled[25] ddc_chain_x300_tb.ddc_chain.i_scaled[24] ddc_chain_x300_tb.ddc_chain.i_scaled[23] ddc_chain_x300_tb.ddc_chain.i_scaled[22] ddc_chain_x300_tb.ddc_chain.i_scaled[21] ddc_chain_x300_tb.ddc_chain.i_scaled[20] ddc_chain_x300_tb.ddc_chain.i_scaled[19] ddc_chain_x300_tb.ddc_chain.i_scaled[18] ddc_chain_x300_tb.ddc_chain.i_scaled[17] ddc_chain_x300_tb.ddc_chain.i_scaled[16] ddc_chain_x300_tb.ddc_chain.i_scaled[15] ddc_chain_x300_tb.ddc_chain.i_scaled[14] ddc_chain_x300_tb.ddc_chain.i_scaled[13] ddc_chain_x300_tb.ddc_chain.i_scaled[12] ddc_chain_x300_tb.ddc_chain.i_scaled[11] ddc_chain_x300_tb.ddc_chain.i_scaled[10] ddc_chain_x300_tb.ddc_chain.i_scaled[9] ddc_chain_x300_tb.ddc_chain.i_scaled[8] ddc_chain_x300_tb.ddc_chain.i_scaled[7] ddc_chain_x300_tb.ddc_chain.i_scaled[6] ddc_chain_x300_tb.ddc_chain.i_scaled[5] ddc_chain_x300_tb.ddc_chain.i_scaled[4] ddc_chain_x300_tb.ddc_chain.i_scaled[3] ddc_chain_x300_tb.ddc_chain.i_scaled[2] ddc_chain_x300_tb.ddc_chain.i_scaled[1] ddc_chain_x300_tb.ddc_chain.i_scaled[0]
+@20000
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_clip[23:0]} ddc_chain_x300_tb.ddc_chain.i_clip[23] ddc_chain_x300_tb.ddc_chain.i_clip[22] ddc_chain_x300_tb.ddc_chain.i_clip[21] ddc_chain_x300_tb.ddc_chain.i_clip[20] ddc_chain_x300_tb.ddc_chain.i_clip[19] ddc_chain_x300_tb.ddc_chain.i_clip[18] ddc_chain_x300_tb.ddc_chain.i_clip[17] ddc_chain_x300_tb.ddc_chain.i_clip[16] ddc_chain_x300_tb.ddc_chain.i_clip[15] ddc_chain_x300_tb.ddc_chain.i_clip[14] ddc_chain_x300_tb.ddc_chain.i_clip[13] ddc_chain_x300_tb.ddc_chain.i_clip[12] ddc_chain_x300_tb.ddc_chain.i_clip[11] ddc_chain_x300_tb.ddc_chain.i_clip[10] ddc_chain_x300_tb.ddc_chain.i_clip[9] ddc_chain_x300_tb.ddc_chain.i_clip[8] ddc_chain_x300_tb.ddc_chain.i_clip[7] ddc_chain_x300_tb.ddc_chain.i_clip[6] ddc_chain_x300_tb.ddc_chain.i_clip[5] ddc_chain_x300_tb.ddc_chain.i_clip[4] ddc_chain_x300_tb.ddc_chain.i_clip[3] ddc_chain_x300_tb.ddc_chain.i_clip[2] ddc_chain_x300_tb.ddc_chain.i_clip[1] ddc_chain_x300_tb.ddc_chain.i_clip[0]
+@20000
+-
+@28
+ddc_chain_x300_tb.ddc_chain.strobe_unscaled
+ddc_chain_x300_tb.ddc_chain.strobe_scaled
+ddc_chain_x300_tb.ddc_chain.strobe_clip
+ddc_chain_x300_tb.ddc_chain.strobe
+ddc_chain_x300_tb.ddc_chain.clip_i.clip.overflow
+@8420
+#{ddc_chain_x300_tb.ddc_chain.round_i.out[15:0]} ddc_chain_x300_tb.ddc_chain.round_i.out[15] ddc_chain_x300_tb.ddc_chain.round_i.out[14] ddc_chain_x300_tb.ddc_chain.round_i.out[13] ddc_chain_x300_tb.ddc_chain.round_i.out[12] ddc_chain_x300_tb.ddc_chain.round_i.out[11] ddc_chain_x300_tb.ddc_chain.round_i.out[10] ddc_chain_x300_tb.ddc_chain.round_i.out[9] ddc_chain_x300_tb.ddc_chain.round_i.out[8] ddc_chain_x300_tb.ddc_chain.round_i.out[7] ddc_chain_x300_tb.ddc_chain.round_i.out[6] ddc_chain_x300_tb.ddc_chain.round_i.out[5] ddc_chain_x300_tb.ddc_chain.round_i.out[4] ddc_chain_x300_tb.ddc_chain.round_i.out[3] ddc_chain_x300_tb.ddc_chain.round_i.out[2] ddc_chain_x300_tb.ddc_chain.round_i.out[1] ddc_chain_x300_tb.ddc_chain.round_i.out[0]
+@20000
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_cordic[24:0]} ddc_chain_x300_tb.ddc_chain.i_cordic[24] ddc_chain_x300_tb.ddc_chain.i_cordic[23] ddc_chain_x300_tb.ddc_chain.i_cordic[22] ddc_chain_x300_tb.ddc_chain.i_cordic[21] ddc_chain_x300_tb.ddc_chain.i_cordic[20] ddc_chain_x300_tb.ddc_chain.i_cordic[19] ddc_chain_x300_tb.ddc_chain.i_cordic[18] ddc_chain_x300_tb.ddc_chain.i_cordic[17] ddc_chain_x300_tb.ddc_chain.i_cordic[16] ddc_chain_x300_tb.ddc_chain.i_cordic[15] ddc_chain_x300_tb.ddc_chain.i_cordic[14] ddc_chain_x300_tb.ddc_chain.i_cordic[13] ddc_chain_x300_tb.ddc_chain.i_cordic[12] ddc_chain_x300_tb.ddc_chain.i_cordic[11] ddc_chain_x300_tb.ddc_chain.i_cordic[10] ddc_chain_x300_tb.ddc_chain.i_cordic[9] ddc_chain_x300_tb.ddc_chain.i_cordic[8] ddc_chain_x300_tb.ddc_chain.i_cordic[7] ddc_chain_x300_tb.ddc_chain.i_cordic[6] ddc_chain_x300_tb.ddc_chain.i_cordic[5] ddc_chain_x300_tb.ddc_chain.i_cordic[4] ddc_chain_x300_tb.ddc_chain.i_cordic[3] ddc_chain_x300_tb.ddc_chain.i_cordic[2] ddc_chain_x300_tb.ddc_chain.i_cordic[1] ddc_chain_x300_tb.ddc_chain.i_cordic[0]
+@20000
+-
+-
+@8420
+#{ddc_chain_x300_tb.ddc_chain.i_cordic_clip[23:0]} ddc_chain_x300_tb.ddc_chain.i_cordic_clip[23] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[22] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[21] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[20] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[19] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[18] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[17] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[16] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[15] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[14] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[13] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[12] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[11] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[10] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[9] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[8] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[7] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[6] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[5] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[4] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[3] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[2] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[1] ddc_chain_x300_tb.ddc_chain.i_cordic_clip[0]
+@20000
+-
+@20001
+-
+[pattern_trace] 1
+[pattern_trace] 0
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/run_isim b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/run_isim
new file mode 100755
index 000000000..6a3e532c6
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/run_isim
@@ -0,0 +1,17 @@
+rm -rf fuse* *.exe isim
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../../lib/dsp \
+ --sourcelibdir ../../../lib/control \
+ --sourcelibdir ../../../top/x300/coregen_dsp \
+ --sourcelibdir ${XILINX}/verilog/src/unimacro \
+ ../../../lib/dsp/ddc_chain_x300_tb.v
+
+
+
+fuse work.ddc_chain_x300_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o ddc_chain_x300_tb.exe
+
+# run the simulation scrip
+./ddc_chain_x300_tb.exe -tclbatch simcmds.tcl # -gui
+
+
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/simcmds.tcl b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/simcmds.tcl
new file mode 100755
index 000000000..3dcfd3eaf
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/dctest/simcmds.tcl
@@ -0,0 +1,9 @@
+# file: simcmds.tcl
+
+# create the simulation script
+#vcd dumpfile isim.vcd
+#vcd dumpvars -m /bus_clk_gen_tb -l 0
+#wave add /
+run 1 s
+quit
+
diff --git a/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/ddc_chain_x300_tb.v b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/ddc_chain_x300_tb.v
new file mode 100644
index 000000000..901844d66
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/ddc_chain_x300/ddc_chain_x300_tb.v
@@ -0,0 +1,64 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module ddc_chain_x300_tb();
+
+`ifdef ISIM
+`else //iverilog implied.
+// xlnx_glbl glbl (.GSR(),.GTS());
+`endif
+
+ localparam SR_TX_DSP = 8;
+
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("ddc_chain_x300_tb.vcd");
+ initial $dumpvars(0,ddc_chain_x300_tb);
+ reg run = 0;
+ wire strobe;
+
+ initial
+ begin
+ #1000 reset = 0;
+ @(posedge clk);
+ set_addr <= 0; set_data <= 32'd8434349; set_stb <= 1; @(posedge clk); // CORDIC
+ set_addr <= 1; set_data <= 18'd19800; set_stb <= 1; @(posedge clk); // Scale factor
+ set_addr <= 2; set_data <= 10'h003; set_stb <= 1; @(posedge clk); // Decim control
+ set_addr <= 3; set_data <= 0; set_stb <= 1; @(posedge clk); // Swap iq
+ set_addr <= 4; set_data <= 0; set_stb <= 1; @(posedge clk); // filter taps
+ set_stb <= 0;
+
+ repeat(10)
+ @(posedge clk);
+ run <= 1'b1;
+ #30000;
+ $finish;
+ end
+
+ reg [7:0] set_addr;
+ reg [31:0] set_data;
+ reg set_stb = 1'b0;
+
+ wire [15:0] i_out, q_out;
+ wire [23:0] rx_fe_i, rx_fe_q;
+
+ assign rx_fe_i = 24'd8388607;
+ assign rx_fe_q = 24'd8388607;
+ //assign rx_fe_q = 0;
+
+ ddc_chain_x300 #(.BASE(0), .DSPNO(0), .WIDTH(24)) ddc_chain
+ (.clk(clk), .rst(reset), .clr(1'b0),
+ .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data),
+ .rx_fe_i(rx_fe_i),.rx_fe_q(rx_fe_q),
+ .sample({i_out,q_out}), .run(run), .strobe(strobe),
+ .debug() );
+
+endmodule // new_tx_tb
diff --git a/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/.gitignore b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/.gitignore
new file mode 100644
index 000000000..7826d75e2
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/.gitignore
@@ -0,0 +1,4 @@
+fuse*
+isim*
+*.exe
+*.wcfg
diff --git a/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/run_isim b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/run_isim
new file mode 100755
index 000000000..0672e32a6
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/run_isim
@@ -0,0 +1,17 @@
+rm -rf fuse* *.exe isim
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../../lib/dsp \
+ --sourcelibdir ../../../lib/control \
+ --sourcelibdir ../../../top/x300/coregen_dsp \
+ --sourcelibdir ${XILINX}/verilog/src/unimacro \
+ ../../../lib/dsp/duc_chain_x300_tb.v
+
+
+
+fuse work.duc_chain_x300_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o duc_chain_x300_tb.exe
+
+# run the simulation scrip
+./duc_chain_x300_tb.exe -tclbatch simcmds.tcl # -gui
+
+
diff --git a/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/simcmds.tcl b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/simcmds.tcl
new file mode 100755
index 000000000..3dcfd3eaf
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/duc_chain_x300/dctest/simcmds.tcl
@@ -0,0 +1,9 @@
+# file: simcmds.tcl
+
+# create the simulation script
+#vcd dumpfile isim.vcd
+#vcd dumpvars -m /bus_clk_gen_tb -l 0
+#wave add /
+run 1 s
+quit
+
diff --git a/fpga/usrp3/lib/sim/dsp/hb47_int/hb47_int_tb.v b/fpga/usrp3/lib/sim/dsp/hb47_int/hb47_int_tb.v
new file mode 100644
index 000000000..b64b5b7dc
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/hb47_int/hb47_int_tb.v
@@ -0,0 +1,136 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module hb47_int_tb();
+
+ wire GSR, GTS;
+ glbl glbl( );
+
+ reg clk = 0;
+ reg rst;
+ reg bypass;
+ reg run;
+
+ wire stb_in;
+ reg stb_out;
+ reg [7:0] cpo;
+
+ reg [17:0] data_in;
+
+ wire [17:0] data_out_dsp48a;
+ wire [17:0] data_out_dsp48e;
+
+ reg [15:0] freq = 500;
+
+ integer x = 0, y =0;
+
+
+
+ always #100 clk = ~clk;
+
+ // SPARTAN6 / DSP48A
+ hb47_int
+ #(.WIDTH(18),
+ .DEVICE("SPARTAN6"))
+ hb47_int_i0
+ (
+ .clk(clk),
+ .rst(rst),
+ .bypass(bypass),
+ .stb_in(stb_in),
+ .data_in(data_in),
+ .output_rate(cpo),
+ .stb_out(stb_out),
+ .data_out(data_out_dsp48a)
+ );
+
+ // SERIES7 / DSP48E
+ hb47_int
+ #(.WIDTH(18),
+ .DEVICE("7SERIES"))
+ hb47_int_i1
+ (
+ .clk(clk),
+ .rst(rst),
+ .bypass(bypass),
+ .stb_in(stb_in),
+ .data_in(data_in),
+ .output_rate(cpo),
+ .stb_out(stb_out),
+ .data_out(data_out_dsp48e)
+ );
+
+ always @(negedge clk)
+ if (data_out_dsp48a !== data_out_dsp48e)
+ $display("Output missmatch at %t",$time);
+
+
+
+ cic_strober #(.WIDTH(2))
+ hb1_strober(.clock(clk),.reset(rst),.enable(run),.rate(2'd2),
+ .strobe_fast(stb_out),.strobe_slow(stb_in) );
+
+ initial
+ begin
+ rst <= 1;
+ bypass <= 0;
+ run <= 0;
+ data_in <= 0;
+ stb_out <= 1;
+ cpo <= 1;
+
+ repeat(10) @(posedge clk);
+ rst <= 0;
+ run <= 1;
+
+ for (x=0; x<100000; x=x+1) begin
+ for (y=0; y<10000; y=y+1)
+ begin
+ while (stb_in == 1'b0) @(posedge clk);
+ triangle_wave(freq,data_in);
+ @(posedge clk);
+
+ end
+ freq = freq * 2;
+ end
+
+ $finish;
+ end // initial begin
+
+
+
+
+ reg signed [18:0] phase_acc = 0;
+ reg direction = 0;
+
+
+ task triangle_wave;
+ input [15:0] inc;
+ output [17:0] data_out;
+
+ begin
+ if (direction) begin
+ phase_acc = phase_acc - inc;
+ if (phase_acc < -19'sh20000) begin
+ direction = 0;
+ phase_acc = phase_acc + inc;
+ end
+ end else begin
+ phase_acc = phase_acc + inc;
+ if (phase_acc > 19'sh1ffff) begin
+ direction = 1;
+ phase_acc = phase_acc - inc;
+ end
+ end
+ data_out = phase_acc[17:0];
+ end
+
+ endtask // triangle_wave
+
+
+
+endmodule // hb47_int_tb
diff --git a/fpga/usrp3/lib/sim/dsp/mult_add_clip/Makefile b/fpga/usrp3/lib/sim/dsp/mult_add_clip/Makefile
new file mode 100644
index 000000000..f0cdb3704
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/mult_add_clip/Makefile
@@ -0,0 +1,45 @@
+#
+# Copyright 2018 Ettus Research, A National Instruments Company
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Design Specific
+#-------------------------------------------------
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/dsp/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(DSP_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = mult_add_clip_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+mult_add_clip_tb.sv \
+)
+
+# MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/dsp/mult_add_clip/mult_add_clip_tb.sv b/fpga/usrp3/lib/sim/dsp/mult_add_clip/mult_add_clip_tb.sv
new file mode 100644
index 000000000..47cd1a369
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/mult_add_clip/mult_add_clip_tb.sv
@@ -0,0 +1,137 @@
+//
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Checks a few cases of A*B+C against precomputed values
+// Configurations checked include widths and binary points for
+// rx_frontend_gen3 and tx_frontend_gen3. All latencies for those
+// configurations are checked.
+
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 2
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+
+module mult_add_clip_tb();
+ `TEST_BENCH_INIT("mult_add_clip_tb", `NUM_TEST_CASES, `NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/200e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ // {RX config, TX config}
+ localparam integer AW[0:1] = {18,16};
+ localparam integer A_PT[0:1] = {17,15};
+ localparam integer BW[0:1] = {18,18};
+ localparam integer B_PT[0:1] = {17,17};
+ localparam integer CW[0:1] = {24,16};
+ localparam integer C_PT[0:1] = {23,15};
+ localparam integer OW = 24;
+ localparam integer O_PT = 23;
+ localparam integer NUM_LATENCY = 4;
+ localparam integer NUM_CASES = 2;
+
+ localparam [23:0] A_VECTOR[0:7] = {24'h000000,
+ 24'h800000,
+ 24'h7fffff,
+ 24'h111111,
+ 24'h333333,
+ 24'h111111,
+ 24'h333333,
+ 24'h333333};
+ localparam [17:0] B_VECTOR[0:7] = {18'h00000,
+ 18'h1ffff,
+ 18'h1ffff,
+ 18'h10000,
+ 18'h3ffff,
+ 18'h3ffff,
+ 18'h10000,
+ 18'h10000};
+ localparam [23:0] C_VECTOR[0:7] = {24'h000000,
+ 24'h880000,
+ 24'h70ffff,
+ 24'h000000,
+ 24'h000000,
+ 24'h101010,
+ 24'h101010,
+ 24'hfffff1};
+ localparam [OW-1:0] O_VECTOR_RX[0:7] = {24'h000000,
+ 24'h800000,
+ 24'h7fffff,
+ 24'h088880,
+ 24'hffffe6,
+ 24'h101007,
+ 24'h29a990,
+ 24'h199971};
+ localparam [OW-1:0] O_VECTOR_TX[0:7] = {24'h000000,
+ 24'h800000,
+ 24'h7fffff,
+ 24'h088880,
+ 24'hffffe6,
+ 24'h100ff7,
+ 24'h29a980,
+ 24'h199880};
+
+ logic [23:0] a;
+ logic [17:0] b;
+ logic [23:0] c;
+ wire [OW-1:0] o[0:NUM_LATENCY*NUM_CASES-1];
+
+ task check_result(integer samp, integer inst);
+ begin
+ string s;
+ if ((samp >= inst) && (samp-inst < 8)) begin
+ $sformat(s, "Incorrect data for RX. Samp = %0d, Latency = %0d, Data = %06x, Expected = %06x", samp, inst, o[inst], O_VECTOR_RX[samp-inst]);
+ `ASSERT_ERROR(o[inst] == O_VECTOR_RX[samp-inst], s);
+ $sformat(s, "Incorrect data for TX. Samp = %0d, Latency = %0d, Data = %06x, Expected = %06x", samp, inst, o[inst+NUM_LATENCY], O_VECTOR_TX[samp-inst]);
+ `ASSERT_ERROR(o[inst+NUM_LATENCY] == O_VECTOR_TX[samp-inst], s);
+ end
+ end
+ endtask
+
+ genvar k, l;
+ generate for (k = 0; k < NUM_CASES; k = k + 1) begin: inst
+ for (l = 0; l < NUM_LATENCY; l = l + 1) begin: latency
+ mult_add_clip #(
+ .WIDTH_A(AW[k]),
+ .BIN_PT_A(A_PT[k]),
+ .WIDTH_B(BW[k]),
+ .BIN_PT_B(B_PT[k]),
+ .WIDTH_C(CW[k]),
+ .BIN_PT_C(C_PT[k]),
+ .WIDTH_O(OW),
+ .BIN_PT_O(O_PT),
+ .LATENCY(l+1)
+ ) dut (
+ .clk(clk), .reset(reset), .CE(1'b1),
+ .A(a[23 -: AW[k]]),
+ .B(b[17 -: BW[k]]),
+ .C(c[23 -: CW[k]]),
+ .O(o[k*NUM_LATENCY+l])
+ );
+ end
+ end endgenerate
+
+ initial begin : tb_main
+ `TEST_CASE_START("Wait for Reset");
+ while (reset) @ (posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ `TEST_CASE_START("Check products");
+ for (int i = 0; i < (8 + NUM_LATENCY); i = i + 1) begin
+ @(negedge clk);
+ for (int j = 0; j < NUM_LATENCY; j = j + 1) begin
+ check_result(i-1, j); // i-1 because inst = latency - 1
+ end
+ a = A_VECTOR[i % 8];
+ b = B_VECTOR[i % 8];
+ c = C_VECTOR[i % 8];
+ end
+ `TEST_CASE_DONE(1);
+ `TEST_BENCH_DONE;
+ end
+
+endmodule // mult_add_clip_tb
diff --git a/fpga/usrp3/lib/sim/dsp/rx_frontend/rx_frontend_tb.v b/fpga/usrp3/lib/sim/dsp/rx_frontend/rx_frontend_tb.v
new file mode 100644
index 000000000..60a866033
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/rx_frontend/rx_frontend_tb.v
@@ -0,0 +1,50 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ns
+module rx_frontend_tb();
+
+ reg clk, rst;
+
+ initial rst = 1;
+ initial #1000 rst = 0;
+ initial clk = 0;
+ always #5 clk = ~clk;
+
+ initial $dumpfile("rx_frontend_tb.vcd");
+ initial $dumpvars(0,rx_frontend_tb);
+
+ reg [15:0] adc_in;
+ wire [23:0] adc_out;
+
+ always @(posedge clk)
+ begin
+ if(adc_in[15])
+ $write("-%d,",-adc_in);
+ else
+ $write("%d,",adc_in);
+ if(adc_out[23])
+ $write("-%d\n",-adc_out);
+ else
+ $write("%d\n",adc_out);
+ end
+
+ rx_frontend #(.BASE(0), .IQCOMP_EN(1)) rx_frontend
+ (.clk(clk),.rst(rst),
+ .set_stb(0),.set_addr(0),.set_data(0),
+ .adc_a(adc_in), .adc_ovf_a(0),
+ .adc_b(0), .adc_ovf_b(0),
+ .i_out(adc_out),.q_out(),
+ .run(), .debug());
+
+ always @(posedge clk)
+ if(rst)
+ adc_in <= 0;
+ else
+ adc_in <= adc_in + 4;
+ //adc_in <= (($random % 473) + 23)/4;
+
+endmodule // rx_frontend_tb
diff --git a/fpga/usrp3/lib/sim/dsp/variable_delay_line/Makefile b/fpga/usrp3/lib/sim/dsp/variable_delay_line/Makefile
new file mode 100644
index 000000000..90733cb5d
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/variable_delay_line/Makefile
@@ -0,0 +1,47 @@
+#
+# Copyright 2018 Ettus Research, A National Instruments Company
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Design Specific
+#-------------------------------------------------
+# Include makefiles and sources for the DUT and its dependencies
+include $(BASE_DIR)/../lib/dsp/Makefile.srcs
+include $(BASE_DIR)/../lib/control/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(DSP_SRCS) \
+$(CONTROL_LIB_SRCS) \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = variable_delay_line_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+variable_delay_line_tb.sv \
+)
+
+# MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/dsp/variable_delay_line/variable_delay_line_tb.sv b/fpga/usrp3/lib/sim/dsp/variable_delay_line/variable_delay_line_tb.sv
new file mode 100644
index 000000000..1691f5b8c
--- /dev/null
+++ b/fpga/usrp3/lib/sim/dsp/variable_delay_line/variable_delay_line_tb.sv
@@ -0,0 +1,117 @@
+//
+// Copyright 2018 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 4
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_axis_lib.svh"
+
+module variable_delay_line_tb();
+ `TEST_BENCH_INIT("variable_delay_line_tb", `NUM_TEST_CASES, `NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/166.67e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ localparam WIDTH = 32;
+ localparam [WIDTH-1:0] DEFAULT = 32'hDEADBEEF;
+ localparam integer NUM_INST = 24;
+ localparam integer DELAYS[0:NUM_INST-1] = {3, 14, 15, 16, 17, 30, 31, 32, 33, 127, 256, 511,
+ 3, 14, 15, 16, 17, 30, 31, 32, 33, 127, 256, 511};
+
+ logic in_stb [0:NUM_INST-1];
+ logic [WIDTH-1:0] in_samp [0:NUM_INST-1];
+ wire [WIDTH-1:0] out_samp [0:NUM_INST-1];
+ logic [31:0] out_delay[0:NUM_INST-1];
+
+ task push_samp(logic [WIDTH-1:0] word, integer inst);
+ begin
+ //$display("D[%0d]: push(0x%08x)", inst, word);
+ in_samp[inst] = word;
+ in_stb[inst] = 1'b1;
+ @(posedge clk);
+ in_stb[inst] = 1'b0;
+ end
+ endtask
+
+ task change_delay(logic [31:0] delay, integer inst);
+ begin
+ out_delay[inst] = delay;
+ @(posedge clk); // First stage
+ if (inst/(NUM_INST/2) == 1) @(posedge clk); // Pipeline stage
+ @(negedge clk);
+ //$display("D[%0d]: cd(%0d) = 0x%08x", inst, delay, out_samp[inst]);
+ end
+ endtask
+
+ genvar d;
+ generate for (d = 0; d < NUM_INST; d=d+1) begin: inst
+ variable_delay_line #(
+ .WIDTH(WIDTH), .DEPTH(DELAYS[d]),
+ .DYNAMIC_DELAY(1), .DEFAULT_DATA(DEFAULT), .OUT_REG(d / (NUM_INST/2))
+ ) dut (
+ .clk(clk), .clk_en(1'b1), .reset(reset),
+ .data_in(in_samp[d]), .stb_in(in_stb[d]),
+ .delay(out_delay[d]), .data_out(out_samp[d])
+ );
+ end endgenerate
+
+ initial begin : tb_main
+ string s;
+
+ `TEST_CASE_START("Wait for Reset");
+ for (int k = 0; k < NUM_INST; k=k+1) begin
+ in_stb[k] = 1'b0;
+ out_delay[k] = 0;
+ end
+ while (reset) @(posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ `TEST_CASE_START("Check startup state of delay line");
+ for (int k = 0; k < NUM_INST; k=k+1) begin
+ $display("Validating delay line with DEPTH=%0d, OUT_REG=%0d...", DELAYS[k], k/(NUM_INST/2));
+ for (int j = 0; j < DELAYS[k]; j=j+1) begin
+ change_delay(j, k);
+ `ASSERT_ERROR(out_samp[k] == DEFAULT, "Transient delay value incorrect");
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check partially filled delay line");
+ for (int k = 0; k < NUM_INST; k=k+1) begin
+ $display("Validating delay line with DEPTH=%0d, OUT_REG=%0d...", DELAYS[k], k/(NUM_INST/2));
+ for (int i = 0; i < DELAYS[k]; i=i+1) begin
+ push_samp(i, k);
+ for (int j = 0; j < DELAYS[k]; j=j+1) begin
+ change_delay(j, k);
+ $sformat(s, "Incorrect data. Samp = %0d, Delay = %0d, Data = %08x", i, j, out_samp[k]);
+ `ASSERT_ERROR(out_samp[k] == (j>i ? DEFAULT : i - j), s);
+ end
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Check steady state delay line");
+ for (int k = 0; k < NUM_INST; k=k+1) begin
+ $display("Validating delay line with DEPTH=%0d, OUT_REG=%0d...", DELAYS[k], k/(NUM_INST/2));
+ for (int i = 0; i < DELAYS[k]; i=i+1) begin
+ push_samp(i + DELAYS[k], k);
+ for (int j = 0; j < DELAYS[k]; j=j+1) begin
+ change_delay(j, k);
+ $sformat(s, "Incorrect data. Samp = %0d, Delay = %0d, Data = %08x", i, j, out_samp[k]);
+ `ASSERT_ERROR(out_samp[k] == DELAYS[k] + i - j, s);
+ end
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+
+ `TEST_BENCH_DONE;
+
+ end
+endmodule
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/default.wcfg b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/default.wcfg
new file mode 100644
index 000000000..796071597
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/default.wcfg
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wave_config>
+ <wave_state>
+ </wave_state>
+ <db_ref_list>
+ <db_ref path="./isim.wdb" id="1" type="auto">
+ <top_modules>
+ <top_module name="axi_dram_fifo_tb" />
+ <top_module name="glbl" />
+ </top_modules>
+ </db_ref>
+ </db_ref_list>
+ <WVObjectSize size="38" />
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/clk" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">clk</obj_property>
+ <obj_property name="ObjectShortName">clk</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">reset</obj_property>
+ <obj_property name="ObjectShortName">reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/clear" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">clear</obj_property>
+ <obj_property name="ObjectShortName">clear</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/count_rx" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">count_rx[31:0]</obj_property>
+ <obj_property name="ObjectShortName">count_rx[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/count_tx" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">count_tx[31:0]</obj_property>
+ <obj_property name="ObjectShortName">count_tx[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tlast</obj_property>
+ <obj_property name="ObjectShortName">i_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">input_state[2:0]</obj_property>
+ <obj_property name="ObjectShortName">input_state[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_ctrl_ready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">write_ctrl_ready</obj_property>
+ <obj_property name="ObjectShortName">write_ctrl_ready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_ctrl_valid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">write_ctrl_valid</obj_property>
+ <obj_property name="ObjectShortName">write_ctrl_valid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/occupied_input" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">occupied_input[5:0]</obj_property>
+ <obj_property name="ObjectShortName">occupied_input[5:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group92" type="group">
+ <obj_property name="label">INPUT TIMEOUT</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_count[7:0]</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_count[7:0]</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_reset</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_triggered" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_triggered</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_triggered</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group60" type="group">
+ <obj_property name="label">AXI_WADDR</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/write_addr_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_addr_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">write_addr_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awaddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awaddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awaddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awsize" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awsize[2:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awsize[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awburst" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awburst[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awburst[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/write_data_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_data_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">write_data_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group61" type="group">
+ <obj_property name="label">AXI_WDATA</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wstrb" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wstrb[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wstrb[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wlast</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group62" type="group">
+ <obj_property name="label">AXI_WRESP</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bresp" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bresp[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bresp[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bready</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#00ff00</obj_property>
+ <obj_property name="label">/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/space" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">space[10:0]</obj_property>
+ <obj_property name="ObjectShortName">space[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/occupied" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">occupied[10:0]</obj_property>
+ <obj_property name="ObjectShortName">occupied[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#00ffff</obj_property>
+ </wvobject>
+ <wvobject fp_name="group63" type="group">
+ <obj_property name="label">AXI_RADDR</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_addr_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_addr_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">read_addr_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_araddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arsize" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arsize[2:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arsize[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arburst" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arburst[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arburst[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group64" type="group">
+ <obj_property name="label">AXI_RDATA</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_data_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_data_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">read_data_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rresp" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rresp[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rresp[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rlast</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_ctrl_valid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">read_ctrl_valid</obj_property>
+ <obj_property name="ObjectShortName">read_ctrl_valid</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_ctrl_ready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">read_ctrl_ready</obj_property>
+ <obj_property name="ObjectShortName">read_ctrl_ready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_data_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_data_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">read_data_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">output_state[2:0]</obj_property>
+ <obj_property name="ObjectShortName">output_state[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/space_output" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">space_output[5:0]</obj_property>
+ <obj_property name="ObjectShortName">space_output[5:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group80" type="group">
+ <obj_property name="label">DRAM FIFO OUT</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_output" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_output[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_output[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_output" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_output</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_output</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_output" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_output</obj_property>
+ <obj_property name="ObjectShortName">o_tready_output</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/update_write" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">update_write</obj_property>
+ <obj_property name="ObjectShortName">update_write</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ff00ff</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">write_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/update_read" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">update_read</obj_property>
+ <obj_property name="ObjectShortName">update_read</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ff00ff</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">read_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group68" type="group">
+ <obj_property name="label">Output TImeout</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_count[7:0]</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_count[7:0]</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_reset</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_triggered" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_triggered</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_triggered</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group76" type="group">
+ <obj_property name="label">Extract TLAST</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_i0" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_i0[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_i0[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_i0" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_i0</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_i0</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_i0" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_i0</obj_property>
+ <obj_property name="ObjectShortName">o_tready_i0</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_i1" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_i1[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_i1[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_i1</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tready_i1</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tlast_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tlast_i1</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast</obj_property>
+ <obj_property name="ObjectShortName">o_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+</wave_config>
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/run_isim b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/run_isim
new file mode 100755
index 000000000..5d32efcdd
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/run_isim
@@ -0,0 +1,16 @@
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+#vlogcomp --define SIM_SCRIPT=true --define ISIM=true -work work ../../../packet_proc/source_flow_control_tb.v
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../axi \
+ --sourcelibdir ../../fifo \
+ --sourcelibdir ../../../top/b250/coregen \
+ ../../axi/axi_dram_fifo_tb.v
+
+
+
+fuse work.axi_dram_fifo_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o axi_dram_fifo_tb.exe
+
+# run the simulation scrip
+./axi_dram_fifo_tb.exe -gui #-tclbatch simcmds.tcl
+#./source_flow_control_tb.exe
+
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/default.wcfg b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/default.wcfg
new file mode 100644
index 000000000..796071597
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/default.wcfg
@@ -0,0 +1,412 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wave_config>
+ <wave_state>
+ </wave_state>
+ <db_ref_list>
+ <db_ref path="./isim.wdb" id="1" type="auto">
+ <top_modules>
+ <top_module name="axi_dram_fifo_tb" />
+ <top_module name="glbl" />
+ </top_modules>
+ </db_ref>
+ </db_ref_list>
+ <WVObjectSize size="38" />
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/clk" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">clk</obj_property>
+ <obj_property name="ObjectShortName">clk</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">reset</obj_property>
+ <obj_property name="ObjectShortName">reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/clear" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">clear</obj_property>
+ <obj_property name="ObjectShortName">clear</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/count_rx" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">count_rx[31:0]</obj_property>
+ <obj_property name="ObjectShortName">count_rx[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/count_tx" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">count_tx[31:0]</obj_property>
+ <obj_property name="ObjectShortName">count_tx[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tlast</obj_property>
+ <obj_property name="ObjectShortName">i_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">input_state[2:0]</obj_property>
+ <obj_property name="ObjectShortName">input_state[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_ctrl_ready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">write_ctrl_ready</obj_property>
+ <obj_property name="ObjectShortName">write_ctrl_ready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_ctrl_valid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">write_ctrl_valid</obj_property>
+ <obj_property name="ObjectShortName">write_ctrl_valid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/occupied_input" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">occupied_input[5:0]</obj_property>
+ <obj_property name="ObjectShortName">occupied_input[5:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group92" type="group">
+ <obj_property name="label">INPUT TIMEOUT</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_count[7:0]</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_count[7:0]</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_reset</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/input_timeout_triggered" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">input_timeout_triggered</obj_property>
+ <obj_property name="ObjectShortName">input_timeout_triggered</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group60" type="group">
+ <obj_property name="label">AXI_WADDR</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/write_addr_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_addr_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">write_addr_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awaddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awaddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awaddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awsize" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awsize[2:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awsize[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awburst" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awburst[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awburst[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_awready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_awready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_awready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/write_data_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_data_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">write_data_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group61" type="group">
+ <obj_property name="label">AXI_WDATA</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wstrb" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wstrb[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wstrb[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wlast</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_wready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_wready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_wready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group62" type="group">
+ <obj_property name="label">AXI_WRESP</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bresp" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bresp[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bresp[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_bready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_bready</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#00ff00</obj_property>
+ <obj_property name="label">/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_bready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/space" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">space[10:0]</obj_property>
+ <obj_property name="ObjectShortName">space[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/occupied" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">occupied[10:0]</obj_property>
+ <obj_property name="ObjectShortName">occupied[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#00ffff</obj_property>
+ </wvobject>
+ <wvobject fp_name="group63" type="group">
+ <obj_property name="label">AXI_RADDR</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_addr_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_addr_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">read_addr_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_araddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arsize" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arsize[2:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arsize[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arburst" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arburst[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arburst[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group64" type="group">
+ <obj_property name="label">AXI_RDATA</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_data_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_data_state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">read_data_state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rid" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rid[0:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rid[0:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rresp" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rresp[1:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rresp[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rlast</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_ctrl_valid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">read_ctrl_valid</obj_property>
+ <obj_property name="ObjectShortName">read_ctrl_valid</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ffff00</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_ctrl_ready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">read_ctrl_ready</obj_property>
+ <obj_property name="ObjectShortName">read_ctrl_ready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_dma_master_i/read_data_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_data_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">read_data_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">output_state[2:0]</obj_property>
+ <obj_property name="ObjectShortName">output_state[2:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/space_output" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">space_output[5:0]</obj_property>
+ <obj_property name="ObjectShortName">space_output[5:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group80" type="group">
+ <obj_property name="label">DRAM FIFO OUT</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_output" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_output[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_output[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_output" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_output</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_output</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_output" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_output</obj_property>
+ <obj_property name="ObjectShortName">o_tready_output</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/update_write" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">update_write</obj_property>
+ <obj_property name="ObjectShortName">update_write</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ff00ff</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/write_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">write_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">write_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/update_read" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">update_read</obj_property>
+ <obj_property name="ObjectShortName">update_read</obj_property>
+ <obj_property name="UseCustomSignalColor">true</obj_property>
+ <obj_property name="CustomSignalColor">#ff00ff</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/read_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">read_count[3:0]</obj_property>
+ <obj_property name="ObjectShortName">read_count[3:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group68" type="group">
+ <obj_property name="label">Output TImeout</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_count" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_count[7:0]</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_count[7:0]</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_reset</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/output_timeout_triggered" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">output_timeout_triggered</obj_property>
+ <obj_property name="ObjectShortName">output_timeout_triggered</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group76" type="group">
+ <obj_property name="label">Extract TLAST</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_i0" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_i0[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_i0[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_i0" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_i0</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_i0</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_i0" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_i0</obj_property>
+ <obj_property name="ObjectShortName">o_tready_i0</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata_i1" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata_i1[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata_i1[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid_i1</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tready_i1</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tlast_i1" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast_i1</obj_property>
+ <obj_property name="ObjectShortName">o_tlast_i1</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast</obj_property>
+ <obj_property name="ObjectShortName">o_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+</wave_config>
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/run_isim b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/run_isim
new file mode 100755
index 000000000..03eead1f7
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/run_isim
@@ -0,0 +1,17 @@
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+#vlogcomp --define SIM_SCRIPT=true --define ISIM=true -work work ../../../packet_proc/source_flow_control_tb.v
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../../lib/axi \
+ --sourcelibdir ../../../lib/fifo \
+ --sourcelibdir ../../../lib/control \
+ --sourcelibdir ../../../top/x300/coregen \
+ ../../../lib/axi/axi_dram_fifo_tb.v
+
+
+
+fuse work.axi_dram_fifo_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o axi_dram_fifo_tb.exe
+
+# run the simulation scrip
+./axi_dram_fifo_tb.exe # -gui #-tclbatch simcmds.tcl
+
+
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/simulation_script.v b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/simulation_script.v
new file mode 100644
index 000000000..974b4e096
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_1/simulation_script.v
@@ -0,0 +1,118 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+reg [31:0] count_rx, count_tx;
+reg status;
+reg fail;
+
+
+//
+// Use task library
+//
+`define USE_TASKS
+
+ initial
+ begin
+ clk <= 1'b0;
+ reset <= 1'b0;
+ clear <= 1'b0;
+ i_tdata_r <= 0;
+ i_tlast_r <= 0;
+ i_tvalid_r <= 0;
+ o_tready_r <= 0;
+ end
+
+ always
+ #5 clk <= ~clk;
+
+ initial
+ begin
+ count_tx = 2;
+ count_rx = 2;
+ status = 0;
+
+
+ @(negedge clk);
+ reset <= 1'b1;
+ repeat(10) @(negedge clk);
+ reset <= 1'b0;
+ repeat(10) @(negedge clk);
+
+ // Send 40 packets.
+ repeat(40) begin
+ send_raw_packet(count_tx);
+ repeat(2) @(posedge clk);
+ count_tx = count_tx + 1;
+ @(posedge clk);
+ end
+ repeat(100) @(posedge clk);
+
+
+ // Recieve 40 packets
+ repeat(40) begin
+ receive_raw_packet(count_rx,fail);
+ status = status || fail;
+ repeat(2) @(posedge clk);
+ count_rx = count_rx + 1;
+ @(posedge clk);
+ end
+ repeat(100) @(posedge clk);
+
+ count_tx = 2;
+ count_rx = 2;
+
+ // Send 40 packets.
+ repeat(40) begin
+ send_raw_packet(count_tx);
+ repeat(2) @(posedge clk);
+ count_tx = count_tx + 1;
+ @(posedge clk);
+ end
+ repeat(100) @(posedge clk);
+ // Now fork so send and receive run concurrently
+ fork
+ begin
+ // Send 40 packets.
+ repeat(40) begin
+ send_raw_packet(count_tx);
+ repeat(2) @(posedge clk);
+ count_tx = count_tx + 1;
+ @(posedge clk);
+ end
+ end
+ begin
+ // Recieve 80 packets
+ repeat(80) begin
+ receive_raw_packet(count_rx,status);
+ status = status || fail;
+ repeat(2) @(posedge clk);
+ count_rx = count_rx + 1;
+ @(posedge clk);
+ if (status !== 0) begin
+ repeat(100) @(posedge clk);
+ $display("FAILED.");
+ $finish;
+ end
+ end
+ end
+ join
+ // Now single threaded agian.
+ repeat(100) @(posedge clk);
+
+ $display;
+ // Should not be able to get to here with FAIL status but check anyhow
+ if (status != 0)
+ $display("FAILED.");
+ else
+ $display("PASSED.");
+
+ @(posedge clk);
+ $finish;
+
+ end
+
+ //initial
+ // o_tready = 1;
+
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/Default.wcfg b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/Default.wcfg
new file mode 100644
index 000000000..3e6d96fb4
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/Default.wcfg
@@ -0,0 +1,388 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wave_config>
+ <wave_state>
+ </wave_state>
+ <db_ref_list>
+ <db_ref path="./isim.wdb" id="1" type="auto">
+ <top_modules>
+ <top_module name="axi_dram_fifo_tb" />
+ <top_module name="glbl" />
+ </top_modules>
+ </db_ref>
+ </db_ref_list>
+ <WVObjectSize size="14" />
+ <wave_markers>
+ <marker time="31415100000" label="" />
+ <marker time="30385518000" label="" />
+ <marker time="23065100000" label="" />
+ <marker time="18355382000" label="" />
+ </wave_markers>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/clk" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">clk</obj_property>
+ <obj_property name="ObjectShortName">clk</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/reset" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">reset</obj_property>
+ <obj_property name="ObjectShortName">reset</obj_property>
+ </wvobject>
+ <wvobject fp_name="group31" type="group">
+ <obj_property name="label">chdr_test_pattern</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/start" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">start</obj_property>
+ <obj_property name="ObjectShortName">start</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/i_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tlast</obj_property>
+ <obj_property name="ObjectShortName">i_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/o_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast</obj_property>
+ <obj_property name="ObjectShortName">o_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_chdr_test_pattern_i/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group11" type="group">
+ <obj_property name="label">embed_tlast</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/i_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tlast</obj_property>
+ <obj_property name="ObjectShortName">i_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_embed_tlast_i/state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group18" type="group">
+ <obj_property name="label">fast_fifo_i0</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/state" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">state[1:0]</obj_property>
+ <obj_property name="ObjectShortName">state[1:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="DisplayName">FullPathName</obj_property>
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i0/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ <obj_property name="label">o_tready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group25" type="group">
+ <obj_property name="label">fifo_i1</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i1/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group79" type="group">
+ <obj_property name="label">AXI write bus</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_awaddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_awaddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">axi_awaddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_awlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_awlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">axi_awlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_awvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_awvalid</obj_property>
+ <obj_property name="ObjectShortName">axi_awvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_awready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_awready</obj_property>
+ <obj_property name="ObjectShortName">axi_awready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_wdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_wdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">axi_wdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_wvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_wvalid</obj_property>
+ <obj_property name="ObjectShortName">axi_wvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_wready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_wready</obj_property>
+ <obj_property name="ObjectShortName">axi_wready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_bvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_bvalid</obj_property>
+ <obj_property name="ObjectShortName">axi_bvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_bready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">axi_bready</obj_property>
+ <obj_property name="ObjectShortName">axi_bready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/space" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">space[10:0]</obj_property>
+ <obj_property name="ObjectShortName">space[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/occupied" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">occupied[10:0]</obj_property>
+ <obj_property name="ObjectShortName">occupied[10:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="group71" type="group">
+ <obj_property name="label">AXI read bus</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_araddr" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_araddr[31:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arlen" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arlen[7:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_arready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_arready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_arready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rvalid</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/m_axi_rready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">m_axi_rready</obj_property>
+ <obj_property name="ObjectShortName">m_axi_rready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group43" type="group">
+ <obj_property name="label">fifo_i2</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fifo_i2/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group50" type="group">
+ <obj_property name="label">fast_fifo_i1</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/fast_fifo_i1/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group58" type="group">
+ <obj_property name="label">axi_fast_extract</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/i_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">i_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/i_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tvalid</obj_property>
+ <obj_property name="ObjectShortName">i_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/i_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">i_tready</obj_property>
+ <obj_property name="ObjectShortName">i_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/o_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast</obj_property>
+ <obj_property name="ObjectShortName">o_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/axi_fast_extract_tlast_i0/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ </wvobject>
+ <wvobject fp_name="group63" type="group">
+ <obj_property name="label">dram_fifo_output</obj_property>
+ <obj_property name="DisplayName">label</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tdata" type="array" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="ObjectShortName">o_tdata[63:0]</obj_property>
+ <obj_property name="Radix">HEXRADIX</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tlast" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tlast</obj_property>
+ <obj_property name="ObjectShortName">o_tlast</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tvalid" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tvalid</obj_property>
+ <obj_property name="ObjectShortName">o_tvalid</obj_property>
+ </wvobject>
+ <wvobject fp_name="/axi_dram_fifo_tb/axi_dram_fifo_i1/o_tready" type="logic" db_ref_id="1">
+ <obj_property name="ElementShortName">o_tready</obj_property>
+ <obj_property name="ObjectShortName">o_tready</obj_property>
+ </wvobject>
+ </wvobject>
+</wave_config>
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/run_isim b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/run_isim
new file mode 100755
index 000000000..46141fcae
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/run_isim
@@ -0,0 +1,19 @@
+/bin/rm -r isim
+
+vlogcomp -work work ${XILINX}/verilog/src/glbl.v
+
+vlogcomp -work work --sourcelibext .v \
+ --sourcelibdir ../../../lib/axi \
+ --sourcelibdir ../../../lib/fifo \
+ --sourcelibdir ../../../lib/control \
+ --sourcelibdir ../../../top/x300/coregen \
+ ../../../lib/axi/axi_dram_fifo_tb.v
+
+
+
+fuse work.axi_dram_fifo_tb work.glbl -L unisims_ver -L xilinxcorelib_ver -o axi_dram_fifo_tb.exe
+
+# run the simulation scrip
+./axi_dram_fifo_tb.exe -gui #-tclbatch simcmds.tcl
+
+
diff --git a/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/simulation_script.v b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/simulation_script.v
new file mode 100644
index 000000000..66de106d7
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_dram_fifo/sim_sram_2/simulation_script.v
@@ -0,0 +1,96 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+wire fail;
+wire done;
+reg start;
+reg [15:0] control;
+
+
+
+axi_chdr_test_pattern axi_chdr_test_pattern_i
+ (
+ .clk(clk),
+ .reset(reset),
+
+ //
+ // 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),
+ //
+ // Test flags
+ //
+ .start(start),
+ .fail(fail),
+ .done(done),
+ .control(control)
+ );
+
+
+ always
+ #5 clk <= ~clk;
+
+ initial
+ begin
+ clk <= 1'b0;
+ reset <= 1'b0;
+ clear <= 1'b0;
+ start <= 1'b0;
+ control <= 16'h0101;
+
+
+ @(negedge clk);
+ reset <= 1'b1;
+ repeat(10) @(negedge clk);
+ reset <= 1'b0;
+ repeat(10) @(negedge clk);
+ // Now activate BIST
+ start <= 1'b1;
+
+ // Wait until simulation is done.
+ while(!done)
+ @(negedge clk);
+
+ $display;
+
+ if (fail)
+ $display("FAILED.");
+ else
+ $display("Done 1st pass.");
+
+ @(posedge clk);
+ start <= 1'b0;
+ repeat(10) @(negedge clk);
+ // Now activate BIST
+ start <= 1'b1;
+
+ // Wait until simulation is done.
+ while(!done)
+ @(negedge clk);
+
+ $display;
+
+ if (fail)
+ $display("FAILED.");
+ else
+ $display("PASSED.");
+
+ $finish;
+
+ end
+
+ //initial
+ // o_tready = 1;
+
diff --git a/fpga/usrp3/lib/sim/fifo/axi_fifo/Makefile b/fpga/usrp3/lib/sim/fifo/axi_fifo/Makefile
new file mode 100644
index 000000000..3cd861176
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_fifo/Makefile
@@ -0,0 +1,34 @@
+#
+# Copyright 2016 Ettus Research
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = axi_fifo_tb
+
+SIM_SRCS = $(abspath \
+axi_fifo_tb.sv \
+$(LIB_DIR)/fifo/axi_fifo.v \
+$(LIB_DIR)/fifo/axi_fifo_flop.v \
+$(LIB_DIR)/fifo/axi_fifo_flop2.v \
+$(LIB_DIR)/fifo/axi_fifo_short.v \
+$(LIB_DIR)/fifo/axi_fifo_bram.v \
+)
+
+#-------------------------------------------------
+# 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/lib/sim/fifo/axi_fifo/axi_fifo_tb.sv b/fpga/usrp3/lib/sim/fifo/axi_fifo/axi_fifo_tb.sv
new file mode 100644
index 000000000..c2832cade
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_fifo/axi_fifo_tb.sv
@@ -0,0 +1,134 @@
+//
+// Copyright 2016 Ettus Research
+//
+
+`timescale 1ns/1ps
+`define SIM_TIMEOUT_US 1000
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 4
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_cvita_lib.svh"
+`include "sim_axis_lib.svh"
+`include "sim_set_rb_lib.svh"
+
+module axi_fifo_tb();
+ /*********************************************
+ ** Setup Testbench
+ *********************************************/
+ `TEST_BENCH_INIT("axi_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/166.67e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ // 4 variants: axi_fifo_flop, axi_fifo_flop2, axi_fifo_short, axi_fifo_bram
+ localparam NUM_FIFOS = 4;
+ localparam integer FIFO_SIZES[NUM_FIFOS-1:0] = '{0,1,5,8};
+ localparam NUM_ITERATIONS = 10000;
+
+ /*********************************************
+ ** DUTs
+ ** - Instances of all variations of AXI FIFO
+ *********************************************/
+ reg [NUM_FIFOS-1:0] clear;
+ axis_master #(.DWIDTH(32), .NUM_STREAMS(NUM_FIFOS)) m_axis(.clk(clk));
+ axis_slave #(.DWIDTH(32), .NUM_STREAMS(NUM_FIFOS)) s_axis(.clk(clk));
+
+ genvar n;
+ generate
+ for (n = 0; n < NUM_FIFOS; n = n + 1) begin
+ axi_fifo #(
+ .SIZE(FIFO_SIZES[n]),
+ .WIDTH(32))
+ axi_fifo (
+ .clk(clk), .reset(reset), .clear(clear[n]),
+ .i_tdata(m_axis.axis.tdata[32*n +: 32]), .i_tvalid(m_axis.axis.tvalid[n]), .i_tready(m_axis.axis.tready[n]),
+ .o_tdata(s_axis.axis.tdata[32*n +: 32]), .o_tvalid(s_axis.axis.tvalid[n]), .o_tready(s_axis.axis.tready[n]),
+ .space(), .occupied());
+ end
+ endgenerate
+
+ /*********************************************
+ ** Testbench
+ *********************************************/
+ int write_word = 0;
+ int read_word = 0;
+ logic last;
+ string s;
+
+ initial begin
+ clear = 'd0;
+
+ /********************************************************
+ ** Test 1 -- Reset
+ ********************************************************/
+ `TEST_CASE_START("Wait for Reset");
+ m_axis.reset();
+ s_axis.reset();
+ while (reset) @(posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ /********************************************************
+ ** Test 2 -- Check filling FIFOs
+ ********************************************************/
+ `TEST_CASE_START("Check filling FIFOs");
+ for (int i = 0; i < NUM_FIFOS; i++) begin
+ $display("Testing FIFO %0d, SIZE %0d",i,2**FIFO_SIZES[i]);
+ for (int k = 0; k < 2**FIFO_SIZES[i]; k++) begin
+ $sformat(s,"FIFO size should be %0d entries, but detected %0d!",2**FIFO_SIZES[i],k);
+ `ASSERT_FATAL(m_axis.axis.tready[i],s);
+ m_axis.push_word(k,0,i);
+ end
+ $sformat(s,"FIFO depth appears to be greater than %0d entries! Might be due to output registering.",2**FIFO_SIZES[i]);
+ `ASSERT_WARN(~m_axis.axis.tready[i],s);
+ end
+ `TEST_CASE_DONE(1);
+
+ /********************************************************
+ ** Test 3 -- Check emptying FIFOs
+ ********************************************************/
+ `TEST_CASE_START("Check emptying FIFOs");
+ for (int i = 0; i < NUM_FIFOS; i++) begin
+ $display("Testing FIFO %0d, SIZE %0d",i,2**FIFO_SIZES[i]);
+ for (int k = 0; k < 2**FIFO_SIZES[i]; k = k + 1) begin
+ $sformat(s,"FIFO prematurely empty! Occured after %0d reads!",k);
+ `ASSERT_FATAL(s_axis.axis.tvalid[i],s);
+ s_axis.pull_word(read_word,last,i);
+ $sformat(s,"Read invalid FIFO word! Expected: %0d, Actual: %0d",k,read_word);
+ `ASSERT_FATAL(read_word == k,s);
+ end
+ `ASSERT_FATAL(~s_axis.axis.tvalid[i],"FIFO not empty after reading all entries!");
+ end
+ `TEST_CASE_DONE(1);
+
+ /********************************************************
+ ** Test 4 -- Randomized Write / Read Timing
+ ********************************************************/
+ `TEST_CASE_START("Randomized Write / Read");
+ for (int i = 0; i < NUM_FIFOS; i++) begin
+ $display("Testing FIFO %0d, SIZE %0d",i,2**FIFO_SIZES[i]);
+ fork
+ begin
+ write_word = 0;
+ for (int k = 0; k < NUM_ITERATIONS; k++) begin
+ while ($signed($random()) > 0) @(posedge clk);
+ m_axis.push_word(write_word,0,i);
+ write_word++;
+ end
+ end
+ begin
+ for (int k = 0; k < NUM_ITERATIONS; k++) begin
+ while ($signed($random()) > 0) @(posedge clk);
+ s_axis.pull_word(read_word,last,i);
+ $sformat(s,"Read invalid FIFO word! Expected: %0d, Actual: %0d",read_word,k);
+ `ASSERT_FATAL(read_word == k,s);
+ end
+ end
+ join
+ end
+ `TEST_CASE_DONE(1);
+ `TEST_BENCH_DONE;
+ end
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk/axi_fifo_2clk_tb.sv b/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk/axi_fifo_2clk_tb.sv
new file mode 100644
index 000000000..c2c69b963
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk/axi_fifo_2clk_tb.sv
@@ -0,0 +1,121 @@
+//
+// Copyright 2016 Ettus Research
+//
+
+module axi_fifo_2clk_tb();
+
+ localparam WIDTH = 32;
+ localparam SIZE = 5;
+
+ reg s_axis_clk;
+ reg s_axis_rst;
+ reg [WIDTH-1:0] s_axis_tdata;
+ reg s_axis_tvalid;
+ reg s_axis_tlast;
+ wire s_axis_tready;
+ reg m_axis_clk;
+ reg m_axis_rst;
+ wire [WIDTH-1:0] m_axis_tdata;
+ wire m_axis_tvalid;
+ wire m_axis_tlast;
+ reg m_axis_tready;
+ wire [SIZE:0] s_axis_occupied;
+ wire s_axis_full;
+ wire s_axis_empty;
+ wire [SIZE:0] m_axis_occupied;
+ wire m_axis_full;
+ wire m_axis_empty;
+
+ axi_fifo_2clk #(.SIZE(SIZE),.WIDTH(WIDTH)) axi_fifo_2clk (
+ .s_axis_clk(s_axis_clk),
+ .s_axis_rst(s_axis_rst),
+ .s_axis_tdata(s_axis_tdata),
+ .s_axis_tvalid(s_axis_tvalid),
+ .s_axis_tlast(s_axis_tlast),
+ .s_axis_tready(s_axis_tready),
+ .m_axis_clk(m_axis_clk),
+ .m_axis_rst(m_axis_rst),
+ .m_axis_tdata(m_axis_tdata),
+ .m_axis_tvalid(m_axis_tvalid),
+ .m_axis_tlast(m_axis_tlast),
+ .m_axis_tready(m_axis_tready),
+ .s_axis_occupied(s_axis_occupied),
+ .s_axis_full(s_axis_full),
+ .s_axis_empty(s_axis_empty),
+ .m_axis_occupied(m_axis_occupied),
+ .m_axis_full(m_axis_full),
+ .m_axis_empty(m_axis_empty));
+
+ `define S_AXIS_CLK_PERIOD 7
+ initial begin
+ s_axis_clk = 1'b0;
+ forever begin
+ #(`S_AXIS_CLK_PERIOD/2) s_axis_clk = ~s_axis_clk;
+ end
+ end
+
+ `define S_AXIS_RESET_PERIOD 70
+ initial begin
+ s_axis_rst = 1'b1;
+ #(`S_AXIS_RESET_PERIOD) s_axis_rst = 1'b0;
+ end
+
+ `define M_AXIS_CLK_PERIOD 10
+ initial begin
+ m_axis_clk = 1'b0;
+ forever begin
+ #(`M_AXIS_CLK_PERIOD/2) m_axis_clk = ~m_axis_clk;
+ end
+ end
+
+ `define M_AXIS_RESET_PERIOD 100
+ initial begin
+ m_axis_rst = 1'b1;
+ #(`M_AXIS_RESET_PERIOD) m_axis_rst = 1'b0;
+ end
+
+ initial begin
+ @(posedge m_axis_clk);
+ @(posedge s_axis_clk);
+ s_axis_tdata = 'd0;
+ s_axis_tlast = 1'b0;
+ s_axis_tvalid = 1'b0;
+ m_axis_tready = 1'b0;
+ assert(~s_axis_full && ~m_axis_full) else $error("FIFO is full during reset!");
+ assert(s_axis_empty == 1'b1 && m_axis_empty == 1'b1) else $error("FIFO is not empty during reset!");
+ assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("FIFO is occupied during reset!");
+ while (s_axis_rst) @(negedge s_axis_rst);
+ while (m_axis_rst) @(negedge m_axis_rst);
+ @(posedge m_axis_clk);
+ @(posedge s_axis_clk);
+ assert(~s_axis_full && ~m_axis_full) else $error("FIFO is full after reset!");
+ assert(s_axis_empty == 1'b1 && m_axis_empty == 1'b1) else $error("FIFO is not empty after reset!");
+ assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("FIFO is occupied after reset!");
+ // Fill FIFO
+ while (~s_axis_tready) @(posedge s_axis_clk);
+ for (int i = 0; i < 1 << DEPTH_LOG2; i++) begin
+ s_axis_tdata = i+1'b1;
+ s_axis_tvalid = 1'b1;
+ @(posedge s_axis_clk);
+ end
+ repeat (6) @(posedge s_axis_clk);
+ assert(s_axis_full && m_axis_full) else $error("Incorrect FIFO full flag!");
+ assert(~s_axis_empty && ~m_axis_empty) else $error("Incorrect FIFO empty flag!");
+ assert(s_axis_occupied == (1 << DEPTH_LOG2) && m_axis_occupied == (1 << DEPTH_LOG2)) else $error("Incorrect FIFO occupied count!");
+ // Empty FIFO
+ s_axis_tdata = 'd0;
+ s_axis_tvalid = 1'b0;
+ @(posedge m_axis_clk);
+ while (~m_axis_tvalid) @(posedge m_axis_clk);
+ for (int i = 0; i < 1 << DEPTH_LOG2; i++) begin
+ m_axis_tready = 1'b1;
+ @(posedge m_axis_clk);
+ assert(m_axis_tdata == i+1'b1) else $error("Incorrect FIFO data! (read)");
+ end
+ repeat (6) @(posedge m_axis_clk);
+ assert(~s_axis_full && ~m_axis_full) else $error("Incorrect FIFO full flag!");
+ assert(s_axis_empty && m_axis_empty) else $error("Incorrect FIFO empty flag!");
+ assert(s_axis_occupied == 0 && m_axis_occupied == 0) else $error("Incorrect FIFO occupied count!");
+ end
+
+endmodule \ No newline at end of file
diff --git a/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk_sim.v b/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk_sim.v
new file mode 100644
index 000000000..cf31ae2d9
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_fifo_2clk_sim.v
@@ -0,0 +1,230 @@
+//
+// Copyright 2016 Ettus Research
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+module axi_fifo_2clk #(
+ parameter SYNC_STAGES = 2,
+ parameter SIZE = 10,
+ parameter WIDTH = 32,
+ parameter PIPELINE = "<UNUSED>")
+(
+ input reset,
+ input i_aclk,
+ input [WIDTH-1:0] i_tdata,
+ input i_tvalid,
+ output reg i_tready = 1'b0,
+ input o_aclk,
+ output [WIDTH-1:0] o_tdata,
+ output reg o_tvalid = 1'b0,
+ input o_tready
+);
+
+ localparam FIFOSIZE = (SIZE < 5) ? 5 : SIZE;
+
+ // Synchronizers
+ wire o_rst_sync, i_rst_sync;
+ synchronizer #(
+ .INITIAL_VAL(1'b1),
+ .WIDTH(1),
+ .STAGES(SYNC_STAGES))
+ synchronizer_i_rst (
+ .clk(i_aclk), .rst(1'b0),
+ .in(reset), .out(i_rst_sync));
+ synchronizer #(
+ .INITIAL_VAL(1'b1),
+ .WIDTH(1),
+ .STAGES(SYNC_STAGES))
+ synchronizer_o_rst (
+ .clk(o_aclk), .rst(1'b0),
+ .in(reset), .out(o_rst_sync));
+
+ // Gray counter encode / decode + synchronizers
+ reg [FIFOSIZE-1:0] wr_addr, rd_addr;
+ wire [FIFOSIZE-1:0] wr_addr_sync, rd_addr_sync;
+ wire [FIFOSIZE-1:0] wr_addr_gray_sync, wr_addr_gray, rd_addr_gray_sync, rd_addr_gray;
+ synchronizer #(
+ .INITIAL_VAL(0),
+ .WIDTH(FIFOSIZE),
+ .STAGES(SYNC_STAGES))
+ synchronizer_rd_addr_gray (
+ .clk(i_aclk), .rst(o_rst_sync),
+ .in(rd_addr_gray), .out(rd_addr_gray_sync));
+ synchronizer #(
+ .INITIAL_VAL(0),
+ .WIDTH(FIFOSIZE),
+ .STAGES(SYNC_STAGES))
+ synchronizer_wr_addr_gray (
+ .clk(o_aclk), .rst(i_rst_sync),
+ .in(wr_addr_gray), .out(wr_addr_gray_sync));
+ bin2gray #(.WIDTH(FIFOSIZE))
+ bin2gray_wr_addr (.bin(wr_addr), .gray(wr_addr_gray));
+ bin2gray #(.WIDTH(FIFOSIZE))
+ bin2gray_rd_addr (.bin(rd_addr), .gray(rd_addr_gray));
+ gray2bin #(.WIDTH(FIFOSIZE))
+ gray2bin_wr_addr (.gray(wr_addr_gray_sync), .bin(wr_addr_sync));
+ gray2bin #(.WIDTH(FIFOSIZE))
+ gray2bin_rd_addr (.gray(rd_addr_gray_sync), .bin(rd_addr_sync));
+
+ reg [FIFOSIZE:0] i_occupied;
+ reg [FIFOSIZE:0] i_space;
+ reg i_full;
+ reg i_empty;
+ reg [FIFOSIZE:0] o_occupied;
+ reg [FIFOSIZE:0] o_space;
+ reg o_full;
+ reg o_empty;
+
+ reg [WIDTH:0] mem[0:2**(FIFOSIZE)-1];
+ integer i;
+ initial begin
+ for (i = 0; i < 1 << FIFOSIZE; i = i + 1) begin
+ mem[i] = 'd0;
+ end
+ end
+
+ // Write
+ always @(posedge i_aclk) begin
+ if (i_rst_sync) begin
+ wr_addr <= 'd0;
+ end else begin
+ if (i_tvalid & i_tready) begin
+ mem[wr_addr] <= i_tdata;
+ wr_addr <= wr_addr + 1'b1;
+ end
+ end
+ end
+
+ // Write ready, full, empty, occupied signals
+ always @(posedge i_aclk) begin
+ if (i_rst_sync) begin
+ i_tready <= 1'b0;
+ i_full <= 1'b0;
+ i_empty <= 1'b1;
+ i_occupied <= 'd0;
+ i_space <= (1'b1 << FIFOSIZE);
+ end else begin
+ if ((rd_addr_sync-1'b1 == wr_addr) & i_tvalid & i_tready) begin
+ i_tready <= 1'b0;
+ i_full <= 1'b1;
+ end else if ((rd_addr_sync != wr_addr) & i_full) begin
+ i_tready <= 1'b1;
+ i_full <= 1'b0;
+ end
+ if ((rd_addr_sync == wr_addr) & ~i_full) begin
+ i_tready <= 1'b1;
+ if (~i_tvalid) begin
+ i_empty <= 1'b1;
+ end
+ end else begin
+ i_empty <= 1'b0;
+ end
+ if (i_tvalid) begin
+ if (wr_addr == rd_addr_sync) begin
+ if (i_full) begin
+ i_occupied <= 1'b1 << FIFOSIZE;
+ i_space <= 'd0;
+ end else begin
+ i_occupied <= 'd1;
+ i_space <= (1'b1 << FIFOSIZE)-1'b1;
+ end
+ end else if (wr_addr > rd_addr_sync) begin
+ i_occupied <= wr_addr - rd_addr_sync + 1'b1;
+ i_space <= (1'b1 << FIFOSIZE) - (wr_addr - rd_addr_sync + 1'b1);
+ end else begin
+ i_occupied <= wr_addr+1'b1 + (1'b1 << FIFOSIZE)-1'b1 - rd_addr_sync + 1'b1;
+ i_space <= rd_addr_sync - wr_addr - 1'b1;
+ end
+ end else begin
+ if (wr_addr == rd_addr_sync) begin
+ if (i_full) begin
+ i_occupied <= 1'b1 << FIFOSIZE;
+ i_space <= 'd0;
+ end else begin
+ i_occupied <= 'd0;
+ i_space <= 1'b1 << FIFOSIZE;
+ end
+ end else if (wr_addr > rd_addr_sync) begin
+ i_occupied <= wr_addr - rd_addr_sync;
+ i_space <= (1'b1 << FIFOSIZE) - (wr_addr - rd_addr_sync);
+ end else begin
+ i_occupied <= wr_addr+1'b1 + (1'b1 << FIFOSIZE)-1'b1 - rd_addr_sync;
+ i_space <= rd_addr_sync - wr_addr;
+ end
+ end
+ end
+ end
+
+ // Read
+ always @(posedge o_aclk) begin
+ if (o_rst_sync) begin
+ rd_addr <= 'd0;
+ end else begin
+ if (o_tvalid & o_tready) begin
+ rd_addr <= rd_addr + 1'b1;
+ end
+ end
+ end
+
+ assign o_tdata = mem[rd_addr];
+
+ // Read valid, full, empty, occupied signals
+ always @(posedge o_aclk) begin
+ if (o_rst_sync) begin
+ o_tvalid <= 1'b0;
+ o_full <= 1'b0;
+ o_empty <= 1'b1;
+ o_occupied <= 'd0;
+ o_space <= 'd0;
+ end else begin
+ if ((rd_addr+1'b1 == wr_addr_sync) & o_tready & o_tvalid) begin
+ o_tvalid <= 1'b0;
+ o_empty <= 1'b1;
+ end else if ((rd_addr != wr_addr_sync) & o_empty) begin
+ o_tvalid <= 1'b1;
+ o_empty <= 1'b0;
+ end
+ if ((rd_addr == wr_addr_sync) & ~o_empty & ~o_tready) begin
+ o_full <= 1'b1;
+ end else begin
+ o_full <= 1'b0;
+ end
+ if (o_tready) begin
+ if (wr_addr_sync == rd_addr) begin
+ if (~o_empty) begin
+ o_occupied <= (1'b1 << FIFOSIZE) - 1'b1;
+ o_space <= 'd1;
+ end else begin
+ o_occupied <= 'd0;
+ o_space <= (1'b1 << FIFOSIZE);
+ end
+ end else if (wr_addr_sync > rd_addr) begin
+ o_occupied <= wr_addr_sync - rd_addr - 1'b1;
+ o_space <= (1'b1 << FIFOSIZE) - (wr_addr_sync - rd_addr - 1'b1);
+ end else begin
+ o_occupied <= wr_addr_sync+1'b1 + (1'b1 << FIFOSIZE)-1'b1 - rd_addr - 1'b1;
+ o_space <= rd_addr - wr_addr_sync + 1'b1;
+ end
+ end else begin
+ if (wr_addr_sync == rd_addr) begin
+ if (~o_empty) begin
+ o_occupied <= 1'b1 << FIFOSIZE;
+ o_space <= 'd0;
+ end else begin
+ o_occupied <= 'd0;
+ o_space <= 1'b1 << FIFOSIZE;
+ end
+ end else if (wr_addr_sync > rd_addr) begin
+ o_occupied <= wr_addr_sync - rd_addr;
+ o_space <= (1'b1 << FIFOSIZE) - (wr_addr_sync - rd_addr);
+ end else begin
+ o_occupied <= wr_addr_sync+1'b1 + (1'b1 << FIFOSIZE)-1'b1 - rd_addr;
+ o_space <= rd_addr - wr_addr_sync;
+ end
+ end
+ end
+ end
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/fifo/axi_fifo_32_64/axi_fifo_32_64_tb.v b/fpga/usrp3/lib/sim/fifo/axi_fifo_32_64/axi_fifo_32_64_tb.v
new file mode 100644
index 000000000..b3acab3ca
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_fifo_32_64/axi_fifo_32_64_tb.v
@@ -0,0 +1,121 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+`timescale 1ns/1ps
+
+module axi_fifo_32_64_tb();
+
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("axi_fifo_32_64_tb.vcd");
+ initial $dumpvars(0,axi_fifo_32_64_tb);
+
+ task send_packet;
+ input [63:0] data_start;
+ input [2:0] user;
+ input [31:0] len;
+
+ begin
+ @(posedge clk);
+ {i_tuser, i_tlast, i_tdata} <= { 3'd0, 1'b0, data_start };
+ repeat(len-1)
+ begin
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
+ end
+ i_tuser <= user;
+ i_tlast <= 1;
+ @(posedge clk);
+ i_tvalid <= 1'b0;
+ @(posedge clk);
+ end
+ endtask // send_packet
+
+ initial
+ begin
+ #1000 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ reg [63:0] i_tdata;
+ reg [2:0] i_tuser;
+ reg i_tlast;
+ reg i_tvalid;
+ wire i_tready;
+
+ wire [63:0] i_tdata_int;
+ wire [2:0] i_tuser_int;
+ wire i_tlast_int, i_tvalid_int, i_tready_int;
+
+ wire [63:0] o_tdata;
+ wire [31:0] o_tdata_int, o_tdata_int2;
+ wire [2:0] o_tuser;
+ wire [1:0] o_tuser_int, o_tuser_int2;
+ wire o_tlast, o_tlast_int, o_tvalid, o_tvalid_int, o_tready, o_tready_int;
+ wire o_tlast_int2, o_tvalid_int2, o_tready_int2;
+
+ localparam RPT_COUNT = 16;
+
+ initial
+ begin
+ i_tvalid <= 0;
+
+ while(reset)
+ @(posedge clk);
+ @(posedge clk);
+
+ send_packet(64'hA0000000_A0000001, 3'd7, 4);
+ @(posedge clk);
+ end // initial begin
+
+ axi_fifo #(.WIDTH(68), .SIZE(10)) fifo
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({i_tlast,i_tuser,i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata({i_tlast_int,i_tuser_int,i_tdata_int}), .o_tvalid(i_tvalid_int), .o_tready(i_tready_int));
+
+ axi_fifo64_to_fifo32 dut
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata(i_tdata_int), .i_tuser(i_tuser_int), .i_tlast(i_tlast_int), .i_tvalid(i_tvalid_int), .i_tready(i_tready_int),
+ .o_tdata(o_tdata_int), .o_tuser(o_tuser_int), .o_tlast(o_tlast_int), .o_tvalid(o_tvalid_int), .o_tready(o_tready_int));
+
+ /*
+ axi_fifo #(.WIDTH(35), .SIZE(10)) fifo_middle
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({o_tlast_int,o_tuser_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
+ .o_tdata({o_tlast_int2,o_tuser_int2,o_tdata_int2}), .o_tvalid(o_tvalid_int2), .o_tready(o_tready_int2));
+*/
+ assign o_tdata_int2 = o_tdata_int;
+ assign o_tlast_int2 = o_tlast_int;
+ assign o_tuser_int2 = o_tuser_int;
+ assign o_tvalid_int2 = o_tvalid_int;
+ assign o_tready_int = o_tready_int2;
+
+ axi_fifo32_to_fifo64 dut2
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata(o_tdata_int2), .i_tuser(o_tuser_int2), .i_tlast(o_tlast_int2), .i_tvalid(o_tvalid_int2), .i_tready(o_tready_int2),
+ .o_tdata(o_tdata), .o_tuser(o_tuser), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
+
+ assign o_tready = 1'b1;
+
+ always @(posedge clk)
+ if(i_tvalid & i_tready)
+ $display("IN: TUSER %x\tTLAST %x\tTDATA %x", i_tuser, i_tlast, i_tdata);
+
+ always @(posedge clk)
+ if(o_tvalid_int & o_tready_int)
+ $display("\t\t\t\t\t\tMIDDLE: TUSER %x\tTLAST %x\tTDATA %x", o_tuser_int, o_tlast_int, o_tdata_int);
+
+ always @(posedge clk)
+ if(o_tvalid & o_tready)
+ $display("\t\t\t\t\t\t\t\t\t\t\tOUT: TUSER %x\tTLAST %x\tTDATA %x", o_tuser, o_tlast, o_tdata);
+
+endmodule // axi_fifo_32_64_tb
diff --git a/fpga/usrp3/lib/sim/fifo/axi_packet_gate/axi_packet_gate_tb.v b/fpga/usrp3/lib/sim/fifo/axi_packet_gate/axi_packet_gate_tb.v
new file mode 100644
index 000000000..9df01baf0
--- /dev/null
+++ b/fpga/usrp3/lib/sim/fifo/axi_packet_gate/axi_packet_gate_tb.v
@@ -0,0 +1,112 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module axi_packet_gate_tb();
+
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("axi_packet_gate_tb.vcd");
+ initial $dumpvars(0,axi_packet_gate_tb);
+
+ task send_packet;
+ input [63:0] data_start;
+ input [2:0] user;
+ input [31:0] len;
+ input error;
+
+ begin
+ // Send a packet
+ @(posedge clk);
+ {i_terror, i_tuser, i_tlast, i_tdata} <= { 1'b0, user, 1'b0, data_start };
+ repeat(len-1)
+ begin
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tdata <= i_tdata + 1;
+ end
+ i_tlast <= 1;
+ i_terror <= error;
+ i_tdata <= i_tdata + 1;
+ @(posedge clk);
+ i_tvalid <= 1'b0;
+
+ @(posedge clk);
+ end
+ endtask // send_packet
+
+
+ initial
+ begin
+ #1000 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ wire [63:0] o_tdata;
+ reg [63:0] i_tdata;
+ wire [2:0] o_tuser;
+ reg [2:0] i_tuser;
+ reg i_tlast;
+ wire o_tlast;
+ wire o_tvalid, i_tready;
+ reg i_tvalid, o_tready;
+ reg i_terror;
+
+ localparam RPT_COUNT = 16;
+
+ initial
+ begin
+ i_tvalid <= 0;
+ o_tready <= 0;
+
+ while(reset)
+ @(posedge clk);
+ @(posedge clk);
+
+ send_packet(64'hA0,3'd0, 16, 0);
+ send_packet(64'hB0,3'd0, 16, 0);
+ o_tready <= 1;
+ send_packet(64'hC0,3'd0, 16, 1);
+ send_packet(64'hD0,3'd0, 16, 0);
+ send_packet(64'hE0,3'd0, 16, 0);
+ send_packet(64'hF0,3'd0, 16, 0);
+
+ @(posedge clk);
+
+ end // initial begin
+
+ wire i_terror_int, i_tlast_int, i_tready_int, i_tvalid_int;
+ wire [2:0] i_tuser_int;
+ wire [63:0] i_tdata_int;
+ wire o_tlast_int, o_tready_int, o_tvalid_int;
+ wire [2:0] o_tuser_int;
+ wire [63:0] o_tdata_int;
+
+ axi_fifo #(.WIDTH(69), .SIZE(10)) fifo
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({i_terror,i_tlast,i_tuser,i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata({i_terror_int,i_tlast_int,i_tuser_int,i_tdata_int}), .o_tvalid(i_tvalid_int), .o_tready(i_tready_int));
+
+ axi_packet_gate #(.WIDTH(67), .SIZE(10)) dut
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({i_tuser_int,i_tdata_int}), .i_terror(i_terror_int), .i_tlast(i_tlast_int), .i_tvalid(i_tvalid_int), .i_tready(i_tready_int),
+ .o_tdata({o_tuser_int,o_tdata_int}), .o_tlast(o_tlast_int), .o_tvalid(o_tvalid_int), .o_tready(o_tready_int));
+
+ axi_fifo #(.WIDTH(68), .SIZE(10)) fifo_out
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({o_tlast_int,o_tuser_int,o_tdata_int}), .i_tvalid(o_tvalid_int), .i_tready(o_tready_int),
+ .o_tdata({o_tlast,o_tuser,o_tdata}), .o_tvalid(o_tvalid), .o_tready(o_tready));
+
+ always @(posedge clk)
+ if(o_tvalid & o_tready)
+ $display("TUSER %x\tTLAST %x\tTDATA %x",o_tuser,o_tlast, o_tdata);
+
+endmodule // axi_packet_gate_tb
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/Makefile b/fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/Makefile
new file mode 100644
index 000000000..d80b63901
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/Makefile
@@ -0,0 +1,53 @@
+#
+# Copyright 2015 Ettus Research LLC
+# Copyright 2016 Ettus Research, a National Instruments Company
+#
+# SPDX-License-Identifier: LGPL-3.0-or-later
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble 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 $(BASE_DIR)/../lib/control/Makefile.srcs
+
+DESIGN_SRCS = $(abspath \
+$(CONTROL_LIB_SRCS) \
+)
+
+DESIGN_SRCS += $(abspath \
+../../../io_cap_gen/cap_pattern_verifier.v \
+)
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+include $(BASE_DIR)/../sim/general/Makefile.srcs
+include $(BASE_DIR)/../sim/axi/Makefile.srcs
+
+# Define only one toplevel module
+SIM_TOP = cap_pattern_verifier_tb
+
+SIM_SRCS = \
+$(abspath cap_pattern_verifier_tb.sv) \
+$(SIM_GENERAL_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/lib/sim/io_cap_gen/cap_pattern_verifier/cap_pattern_verifier_tb.sv b/fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/cap_pattern_verifier_tb.sv
new file mode 100644
index 000000000..53aae3719
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/cap_pattern_verifier/cap_pattern_verifier_tb.sv
@@ -0,0 +1,199 @@
+//
+// Copyright 2015 Ettus Research LLC
+// Copyright 2015 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+//
+
+
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 10
+
+`include "sim_clks_rsts.vh"
+`include "sim_exec_report.vh"
+`include "sim_axis_lib.svh"
+
+
+module cap_pattern_verifier_tb();
+ `TEST_BENCH_INIT("cap_pattern_verifier_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_CLK(clk, 5, 50) //100MHz sys_clk to generate DDR3 clocking
+ `DEFINE_RESET(rst, 0, 100) //100ns for GSR to deassert
+
+ axis_master data0 (.clk(clk));
+ axis_master data1 (.clk(clk));
+ assign data0.axis.tready = 1;
+ assign data1.axis.tready = 1;
+
+ wire [31:0] count0, errors0, count1, errors1;
+ wire locked0, failed0, locked1, failed1;
+
+ cap_pattern_verifier #(
+ .WIDTH(14),
+ .PATTERN("RAMP"),
+ .RAMP_START(14'h0000),
+ .RAMP_STOP(14'h3FFF),
+ .RAMP_INCR(14'h0001),
+ .NTH_CYCLE(1)
+ ) dut0 (
+ .clk(clk),
+ .rst(rst),
+ .valid(data0.axis.tvalid),
+ .data(data0.axis.tdata[13:0]),
+ .count(count0),
+ .errors(errors0),
+ .locked(locked0),
+ .failed(failed0)
+ );
+
+ cap_pattern_verifier #(
+ .WIDTH(14),
+ .PATTERN("RAMP"),
+ .RAMP_START(14'h0100),
+ .RAMP_STOP(14'h0FFF),
+ .RAMP_INCR(14'h0001),
+ .NTH_CYCLE(1)
+ ) dut1 (
+ .clk(clk),
+ .rst(rst),
+ .valid(data1.axis.tvalid),
+ .data(data1.axis.tdata[13:0]),
+ .count(count1),
+ .errors(errors1),
+ .locked(locked1),
+ .failed(failed1)
+ );
+
+ //------------------------------------------
+ //Main thread for testbench execution
+ //------------------------------------------
+ initial begin : tb_main
+ localparam ASYNC_RST_LEN = 10;
+ localparam OUTPUT_LATENCY = 2;
+
+ `TEST_CASE_START("Wait for reset");
+ while (rst) @(posedge clk);
+ @(posedge clk);
+ `TEST_CASE_DONE((rst==0));
+
+ repeat (10) @(posedge clk);
+
+ `TEST_CASE_START("Check reset state");
+ `ASSERT_ERROR(count0==0,"Invalid state: count");
+ `ASSERT_ERROR(errors0==0,"Invalid state: errors");
+ `ASSERT_ERROR(~locked0,"Invalid state: locked");
+ `ASSERT_ERROR(~failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Simple ramp");
+ data0.push_ramp_pkt(100, 64'd0, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==100,"Invalid state: count");
+ `ASSERT_ERROR(errors0==0,"Invalid state: errors");
+ `ASSERT_ERROR(locked0,"Invalid state: locked");
+ `ASSERT_ERROR(~failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ rst <= 1;
+ @(posedge clk);
+ rst <= 0;
+ repeat (ASYNC_RST_LEN) @(posedge clk);
+
+ `TEST_CASE_START("Multiple ramp iterations");
+ data0.push_ramp_pkt(65536, 64'd0, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==65536,"Invalid state: count");
+ `ASSERT_ERROR(errors0==0,"Invalid state: errors");
+ `ASSERT_ERROR(locked0,"Invalid state: locked");
+ `ASSERT_ERROR(~failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ #(`NS_PER_TICK*0.3333)
+ rst <= 1;
+ #(`NS_PER_TICK*3.25)
+ rst <= 0;
+ repeat (ASYNC_RST_LEN+1) @(posedge clk);
+
+ `TEST_CASE_START("Simple ramp after async reset");
+ data0.push_ramp_pkt(100, 64'd0, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==100,"Invalid state: count");
+ `ASSERT_ERROR(errors0==0,"Invalid state: errors");
+ `ASSERT_ERROR(locked0,"Invalid state: locked");
+ `ASSERT_ERROR(~failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ rst <= 1;
+ @(posedge clk);
+ rst <= 0;
+ repeat (ASYNC_RST_LEN) @(posedge clk);
+
+ `TEST_CASE_START("Simple failure");
+ data0.push_ramp_pkt(9, 64'd0, 64'h1);
+ data0.push_ramp_pkt(100, 64'd10, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==109,"Invalid state: count");
+ `ASSERT_ERROR(errors0==1,"Invalid state: errors");
+ `ASSERT_ERROR(locked0,"Invalid state: locked");
+ `ASSERT_ERROR(failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Late start success");
+ data1.push_ramp_pkt(4096, 64'd0, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count1==4096-256,"Invalid state: count");
+ `ASSERT_ERROR(errors1==0,"Invalid state: errors");
+ `ASSERT_ERROR(locked1,"Invalid state: locked");
+ `ASSERT_ERROR(~failed1,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ rst <= 1;
+ @(posedge clk);
+ rst <= 0;
+ repeat (ASYNC_RST_LEN) @(posedge clk);
+
+ `TEST_CASE_START("Late failure overshoot");
+ data1.push_ramp_pkt(4097, 64'd0, 64'h1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count1==4097-256,"Invalid state: count");
+ `ASSERT_ERROR(errors1==1,"Invalid state: errors");
+ `ASSERT_ERROR(locked1,"Invalid state: locked");
+ `ASSERT_ERROR(failed1,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Metastable data in reset");
+ @(posedge clk);
+ rst <= 1;
+ data0.push_word(14'hXXXX, 1'b0);
+ data0.push_word(14'hXXXX, 1'b1);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==0,"Invalid state: count");
+ `ASSERT_ERROR(errors0==0,"Invalid state: errors");
+ `ASSERT_ERROR(~locked0,"Invalid state: locked");
+ `ASSERT_ERROR(~failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ `TEST_CASE_START("Metastable data out of reset");
+ rst <= 0;
+ repeat (ASYNC_RST_LEN) @(posedge clk);
+ data0.push_word(14'h0000, 1'b0);
+ data0.push_word(14'h0001, 1'b0);
+ data0.push_word(14'h0002, 1'b0);
+ data0.push_word(14'hXXXX, 1'b0);
+ data0.push_word(14'hXXXX, 1'b0);
+ data0.push_word(14'h0005, 1'b0);
+ repeat (OUTPUT_LATENCY) @(posedge clk);
+ `ASSERT_ERROR(count0==6,"Invalid state: count");
+ `ASSERT_ERROR(errors0==2,"Invalid state: errors");
+ `ASSERT_ERROR(locked0,"Invalid state: locked");
+ `ASSERT_ERROR(failed0,"Invalid state: failed");
+ `TEST_CASE_DONE(1);
+
+ `TEST_BENCH_DONE;
+
+ end
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v
new file mode 100644
index 000000000..ecb744086
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_dual_mode_tb.v
@@ -0,0 +1,780 @@
+//
+// Copyright 2016 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: cat_io_lvds_dual_mode_tb
+//
+// Description: Testbench for cat_io_lvds_dual_mode.
+//
+
+`timescale 1ns/1ps
+
+module cat_io_lvds_dual_mode_tb();
+
+ localparam CLK_PERIOD = 10;
+ localparam CLK200_PERIOD = 2.5;
+
+ localparam USE_CLOCK_IDELAY = 1;
+ localparam USE_DATA_IDELAY = 1;
+ localparam DATA_IDELAY_MODE = "FIXED";
+ localparam CLOCK_IDELAY_MODE = "FIXED";
+ localparam INPUT_CLOCK_DELAY = 16;
+ localparam INPUT_DATA_DELAY = 0;
+ localparam USE_CLOCK_ODELAY = 1;
+ localparam USE_DATA_ODELAY = 1;
+ localparam DATA_ODELAY_MODE = "FIXED";
+ localparam CLOCK_ODELAY_MODE = "FIXED";
+ localparam OUTPUT_CLOCK_DELAY = 31;
+ localparam OUTPUT_DATA_DELAY = 0;
+
+ reg [8*19:0] test_status;
+ reg check_enabled; // Controls when output checking is performed
+
+ reg clk = 0;
+ reg rx_clk = 0;
+ reg clk200 = 0;
+
+ reg reset;
+ reg mimo;
+ reg tx_ch;
+ reg [5:0] rx_d;
+ reg rx_frame;
+ reg [7:0] rx_count = 0;
+
+ // Each channel's data begins with a unique identifier (A../B.. or C../D..)
+ // followed by a count, which should always be sequential.
+ wire [11:0] i0 = { 4'hA, rx_count };
+ wire [11:0] q0 = { 4'hB, rx_count };
+ wire [11:0] i1 = { 4'hC, rx_count };
+ wire [11:0] q1 = { 4'hD, rx_count };
+
+ wire radio_clk;
+
+ reg [11:0] tx_i0;
+ reg [11:0] tx_q0;
+ reg [11:0] tx_i1;
+ reg [11:0] tx_q1;
+
+ wire [11:0] rx_i0;
+ wire [11:0] rx_q0;
+ wire [11:0] rx_i1;
+ wire [11:0] rx_q1;
+
+ wire rx_aligned;
+
+ wire tx_clk_p, tx_clk_n;
+ wire tx_frame_p, tx_frame_n;
+ wire [5:0] tx_d_p, tx_d_n;
+
+ reg [4:0] ctrl_in_data_delay;
+ reg [4:0] ctrl_in_clk_delay;
+ reg ctrl_ld_in_data_delay;
+ reg ctrl_ld_in_clk_delay;
+
+ reg [4:0] ctrl_out_data_delay;
+ reg [4:0] ctrl_out_clk_delay;
+ reg ctrl_ld_out_data_delay;
+ reg ctrl_ld_out_clk_delay;
+
+
+ //---------------------------------------------------------------------------
+ // Clock Generation
+ //---------------------------------------------------------------------------
+
+ // IODELAYCTRL reference clock
+ always #(CLK200_PERIOD) clk200 = ~clk200;
+
+ // Create an internal clock we'll use to drive the data
+ always #(CLK_PERIOD) clk = ~clk;
+
+ // RF interface clock. Half the rate of clk and out of phase
+ always @(negedge clk) rx_clk <= ~rx_clk;
+
+
+ //---------------------------------------------------------------------------
+ // Tasks
+ //---------------------------------------------------------------------------
+
+ // Output a single burst of 2*len samples. In MIMO mode, this consists of len
+ // samples on each channel. In SISO mode, this consists of 2*len samples on
+ // the same channel.
+ task Burst;
+ input [31:0] len;
+ input do_mimo;
+ begin
+ repeat(len)
+ begin
+ mimo <= do_mimo;
+
+ // Channel 0 sample
+ @(posedge clk);
+ rx_d <= i0[11:6];
+ rx_frame <= 1;
+ @(posedge clk);
+ rx_d <= q0[11:6];
+ rx_frame <= 1;
+ @(posedge clk);
+ rx_d <= i0[5:0];
+ rx_frame <= do_mimo;
+ @(posedge clk);
+ rx_d <= q0[5:0];
+ rx_frame <= do_mimo;
+
+ // Channel 1 sample / Second channel 0 sample
+ @(posedge clk);
+ rx_d <= i1[11:6];
+ rx_frame <= ~do_mimo;
+ @(posedge clk);
+ rx_d <= q1[11:6];
+ rx_frame <= ~do_mimo;
+ @(posedge clk);
+ rx_d <= i1[5:0];
+ rx_frame <= 0;
+ @(posedge clk);
+ rx_d <= q1[5:0];
+ rx_frame <= 0;
+
+ rx_count <= rx_count + 1;
+ end
+ end
+ endtask // Burst
+
+
+ // Test receiving/transmitting 2*len samples, checking len-2 for correctness.
+ // The output is checked by the Tx and Rx Output Checkers below. We have to
+ // be a little bit careful when we enable output checking, because it takes a
+ // few clock cycles for data to propagate through, and we don't want to check
+ // the outputs when the outputs are not valid.
+ task TestBurst;
+ input [31:0] len;
+ input do_mimo;
+ begin
+ if (len <= 2) begin
+ $display("ERROR @%0t in %m: In TestBurst, len must be > 2", $time);
+ $finish;
+ end
+
+ // Input several bursts, to fill the pipeline and cause results on the
+ // outputs before we start checking.
+ Burst(1, do_mimo);
+
+ // Enable output checking
+ check_enabled <= 1'b1;
+
+ // Do the requested length, minus 1
+ Burst(len-2, do_mimo);
+
+ // Disable output checking
+ check_enabled <= 1'b0;
+
+ // Give an extra output to allow data to propagate to the output
+ Burst(1, do_mimo);
+ end
+ endtask // TestBurst
+
+
+ //---------------------------------------------------------------------------
+ // Test Procedure
+ //---------------------------------------------------------------------------
+
+ initial
+ begin
+ // Initial values
+ check_enabled <= 1'b0;
+ test_status <= "Reset";
+ reset = 1;
+ mimo = 1;
+ ctrl_in_clk_delay = INPUT_CLOCK_DELAY;
+ ctrl_in_data_delay = INPUT_DATA_DELAY;
+ ctrl_ld_in_data_delay = 1'b0;
+ ctrl_ld_in_clk_delay = 1'b0;
+ ctrl_out_clk_delay = OUTPUT_CLOCK_DELAY;
+ ctrl_out_data_delay = OUTPUT_DATA_DELAY;
+ ctrl_ld_out_data_delay = 1'b0;
+ ctrl_ld_out_clk_delay = 1'b0;
+ repeat(10) @(negedge rx_clk);
+ reset = 0;
+ @(negedge rx_clk);
+
+ //-----------------------------------------------------------------------
+ // Test Changing Delays
+
+ test_status <= "Load IO delays";
+
+ if (CLOCK_IDELAY_MODE == "VAR_LOAD") begin
+ ctrl_ld_in_clk_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_in_clk_delay = 1'b0;
+ @(negedge rx_clk);
+ end
+
+ if (DATA_IDELAY_MODE == "VAR_LOAD") begin
+ ctrl_ld_in_data_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_in_data_delay = 1'b0;
+ @(negedge rx_clk);
+ end
+
+ if (CLOCK_ODELAY_MODE == "VAR_LOAD") begin
+ ctrl_ld_out_clk_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_out_clk_delay = 1'b0;
+ @(negedge rx_clk);
+ end
+
+ if (DATA_ODELAY_MODE == "VAR_LOAD") begin
+ ctrl_ld_out_data_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_out_data_delay = 1'b0;
+ @(negedge rx_clk);
+ end
+
+ //-----------------------------------------------------------------------
+ // Startup
+
+ test_status <= "Startup";
+
+ // Pump a few clock cycles to get things started (flush out X values)
+ Burst(2,1);
+
+ //-----------------------------------------------------------------------
+ // Test MIMO
+
+ // Input data until the Rx circuit aligns
+ test_status <= "Wait align 1";
+ while (!rx_aligned) begin
+ Burst(1,1);
+ end
+
+ // Input some new samples
+ test_status <= "Burst 1 (MIMO)";
+ TestBurst(30, 1);
+
+ // Reset and do another burst
+ test_status <= "Reset 2";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns
+ test_status <= "Wait align 2";
+ while (!rx_aligned) begin
+ Burst(1,1);
+ end
+
+ // Input some new samples
+ test_status <= "Burst 2 (MIMO)";
+ TestBurst(23, 1);
+
+ //-----------------------------------------------------------------------
+ // Test SISO (transmit channel 0)
+
+ tx_ch <= 1'b0;
+
+ // Reset and do another burst
+ test_status <= "Reset 3";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns in SISO mode
+ test_status <= "Wait align 3";
+ while (!rx_aligned) begin
+ Burst(1,0);
+ end
+
+ // Test SISO mode
+ test_status <= "Burst 3 (SISO, Ch 0)";
+ TestBurst(25, 0);
+
+ // Reset and do another burst
+ test_status <= "Reset 4";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns in SISO mode
+ test_status <= "Wait align 4";
+ while (!rx_aligned) begin
+ Burst(1,0);
+ end
+
+ // Test SISO mode
+ test_status <= "Burst 4 (SISO, Ch 0)";
+ TestBurst(27, 0);
+
+ //-----------------------------------------------------------------------
+ // Test SISO (transmit channel 1)
+
+ tx_ch <= 1'b1;
+
+ // Reset and do another burst
+ test_status <= "Reset 5";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns in SISO mode
+ test_status <= "Wait align 5";
+ while (!rx_aligned) begin
+ Burst(1,0);
+ end
+
+ // Test SISO mode
+ test_status <= "Burst 5 (SISO, Ch 1)";
+ TestBurst(25, 0);
+
+ // Reset and do another burst
+ test_status <= "Reset 6";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns in SISO mode
+ test_status <= "Wait align 6";
+ while (!rx_aligned) begin
+ Burst(1,0);
+ end
+
+ // Test SISO mode
+ test_status <= "Burst 6 (SISO, Ch 1)";
+ TestBurst(27, 0);
+
+ //-----------------------------------------------------------------------
+ // Done
+
+ test_status <= "Finished";
+ repeat(50) @(negedge rx_clk);
+
+ $finish;
+ end
+
+
+ //---------------------------------------------------------------------------
+ // Rx Output Checker
+ //---------------------------------------------------------------------------
+ //
+ // In MIMO mode, we expect to see:
+ //
+ // rx_i0: A00, A01, A02, A03, ...
+ // rx_q0: B00, B01, B02, B03, ...
+ // rx_i1: C00, C01, C02, C03, ...
+ // rx_q1: D00, D01, D02, D03, ...
+ //
+ // In SISO mode, we expect to see (with twice the clock rate):
+ //
+ // rx_i0: A00, C00, A01, C01, ...
+ // rx_q0: B00, D00, B01, D01, ...
+ // rx_i1: A00, C00, A01, C01, ...
+ // rx_q1: B00, D00, B01, D01, ...
+ //
+ //---------------------------------------------------------------------------
+
+ reg first_rx_check = 1'b1;
+ reg [11:0] rx_i0_del1, rx_i0_del2;
+ reg [11:0] rx_q0_del1, rx_q0_del2;
+ reg [11:0] rx_i1_del1, rx_i1_del2;
+ reg [11:0] rx_q1_del1, rx_q1_del2;
+
+ always @(posedge radio_clk)
+ begin
+ if (check_enabled) begin
+ if (!first_rx_check) begin
+
+ if (mimo) begin
+
+ // Check prefix for channel 0
+ if (rx_i0[11:8] != 4'hA || rx_q0[11:8] != 4'hB) begin
+ $display("ERROR @%0t in %m: Rx channel 0 didn't have expected A/B prefix in MIMO mode", $time);
+ $finish;
+ end
+
+ // Check prefix for channel 1
+ if (rx_i1[11:8] != 4'hC || rx_q1[11:8] != 4'hD) begin
+ $display("ERROR @%0t in %m: Rx channel 1 didn't have expected C/D in MIMO mode", $time);
+ $finish;
+ end
+
+ // All outputs should have the same count in MIMO mode
+ if (! (rx_i0[7:0] == rx_q0[7:0] &&
+ rx_i0[7:0] == rx_i1[7:0] &&
+ rx_i0[7:0] == rx_q1[7:0]) ) begin
+ $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in MIMO mode", $time);
+ $finish;
+ end
+
+ // Make sure the count increments
+ if (rx_i0[7:0] != rx_i0_del1[7:0] + 8'd1 || rx_q0[7:0] != rx_q0_del1[7:0] + 8'd1 ||
+ rx_i1[7:0] != rx_i1_del1[7:0] + 8'd1 || rx_q1[7:0] != rx_q1_del1[7:0] + 8'd1) begin
+ $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time);
+ $finish;
+ end
+
+ end else begin // if (mimo)
+
+ // In SISO mode, both outputs should be the same
+ if (rx_i0 != rx_i1 || rx_q0 != rx_q1) begin
+ $display("ERROR @%0t in %m: Rx channel 0 and 1 don't match in SISO mode", $time);
+ $finish;
+ end
+
+ // Check channel 0 prefix. No need to check channel 1, since we
+ // already checked that the channels match.
+ if (!((rx_i0[11:8] == 4'hA && rx_q0[11:8] == 4'hB) ||
+ (rx_i0[11:8] == 4'hC && rx_q0[11:8] == 4'hD))) begin
+ $display("ERROR @%0t in %m: Rx data didn't have expected A/B or C/D prefix in SISO mode", $time);
+ $finish;
+ end
+
+ // Make sure we're alternating between channel data. No need to check
+ // channel 1, since we already checked that the channels match.
+ if (!((rx_i0[11:8] == 4'hA && rx_i0_del1[11:8] == 4'hC) ||
+ (rx_i0[11:8] == 4'hC && rx_i0_del1[11:8] == 4'hA) ||
+ (rx_q0[11:8] == 4'hB && rx_q0_del1[11:8] == 4'hD) ||
+ (rx_q0[11:8] == 4'hD && rx_q0_del1[11:8] == 4'hB))) begin
+ $display("ERROR @%0t in %m: Rx data not toggling between channel data in SISO mode", $time);
+ $finish;
+ end
+
+ // Make sure the counts are the same for both I and Q. No need to
+ // check channel 1, since we already checked that the channels match.
+ if (rx_i0[7:0] != rx_q0[7:0]) begin
+ $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in SISO mode", $time);
+ $finish;
+ end
+
+ // Make sure the count increments every other clock cycle. No need to
+ // check channel 1, since we already checked that the channels match.
+ if (!(
+ rx_i0[7:0] != rx_i0_del2[7:0] + 8'd1 && (rx_i0[7:0] == rx_i0_del1[7:0] || rx_i0[7:0] == rx_i0_del1[7:0] + 8'd1) &&
+ rx_q0[7:0] != rx_q0_del2[7:0] + 8'd1 && (rx_q0[7:0] == rx_q0_del1[7:0] || rx_q0[7:0] == rx_q0_del1[7:0] + 8'd1)
+ )) begin
+ $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time);
+ $finish;
+ end
+
+ end // if (mimo)
+ end // if (!first_rx_check)
+
+ // Make sure we've captured at least one set of values, so we have a
+ // previous set to look back to.
+ first_rx_check <= 1'b0;
+
+ end else begin // if (check_enabled)
+ first_rx_check <= 1'b1;
+ end // if (check_enabled)
+
+ // Save values seen this cycle
+ rx_i0_del1 <= rx_i0;
+ rx_q0_del1 <= rx_q0;
+ rx_i1_del1 <= rx_i1;
+ rx_q1_del1 <= rx_q1;
+ rx_i0_del2 <= rx_i0_del2;
+ rx_q0_del2 <= rx_q0_del2;
+ rx_i1_del2 <= rx_i1_del2;
+ rx_q1_del2 <= rx_q1_del2;
+ end
+
+
+ //---------------------------------------------------------------------------
+ // Tx Output Checker
+ //---------------------------------------------------------------------------
+ //
+ // The code implements a loopback, so the output should match the input. In
+ // SISO mode, however, the frame signal may not be aligned.
+ //
+ //---------------------------------------------------------------------------
+
+ reg first_tx_check;
+ reg [11:0] tx_i0_del1;
+ reg [11:0] tx_q0_del1;
+ reg [11:0] tx_i1_del1;
+ reg [11:0] tx_q1_del1;
+ reg tx_frame_del1;
+
+ reg [11:0] tx_i0_check;
+ reg [11:0] tx_q0_check;
+ reg [11:0] tx_i1_check;
+ reg [11:0] tx_q1_check;
+ reg [7:0] tx_frame_check;
+
+
+ always @(posedge tx_clk_p)
+ begin
+ tx_frame_del1 <= tx_frame_p;
+ end
+
+
+ always @(posedge tx_clk_p)
+ begin
+ if (tx_frame_p && !tx_frame_del1) begin
+ //-----------------------------------------------------------------------
+ // Grab two samples from the output, starting at frame boundary
+ //-----------------------------------------------------------------------
+
+ // Channel 0 sample
+ tx_i0_check[11:6] <= tx_d_p;
+ tx_frame_check[7] <= tx_frame_p;
+ @(posedge tx_clk_n);
+ tx_q0_check[11:6] <= tx_d_p;
+ tx_frame_check[6] <= tx_frame_p;
+ @(posedge tx_clk_p);
+ tx_i0_check[5:0] <= tx_d_p;
+ tx_frame_check[5] <= tx_frame_p;
+ @(posedge tx_clk_n);
+ tx_q0_check[5:0] <= tx_d_p;
+ tx_frame_check[4] <= tx_frame_p;
+
+ // Channel 1 sample / Second channel 0 sample
+ @(posedge tx_clk_p);
+ tx_i1_check[11:6] <= tx_d_p;
+ tx_frame_check[3] <= tx_frame_p;
+ @(posedge tx_clk_n);
+ tx_q1_check[11:6] <= tx_d_p;
+ tx_frame_check[2] <= tx_frame_p;
+ @(posedge tx_clk_p);
+ tx_i1_check[5:0] <= tx_d_p;
+ tx_frame_check[1] <= tx_frame_p;
+ @(posedge tx_clk_n);
+ tx_q1_check[5:0] <= tx_d_p;
+ tx_frame_check[0] <= tx_frame_p;
+
+ #1 // Minimum delay for *_check registers to update in simulation
+
+ if (check_enabled) begin
+ if (!first_tx_check) begin
+
+ if (mimo) begin
+ //-----------------------------------------------------------------
+ // Check MIMO output
+ //-----------------------------------------------------------------
+
+ // Check that the frame signal is correct
+ if (tx_frame_check != 8'b11110000) begin
+ $display("ERROR @%0t in %m: Tx frame was not correct in MIMO mode", $time);
+ $finish;
+ end
+
+ // Check prefix for channel 0
+ if (tx_i0_check[11:8] != 4'hA || tx_q0_check[11:8] != 4'hB) begin
+ $display("ERROR @%0t in %m: Tx channel 0 didn't have expected A/B prefix in MIMO mode", $time);
+ $finish;
+ end
+
+ // Check prefix for channel 1
+ if (tx_i1_check[11:8] != 4'hC || tx_q1_check[11:8] != 4'hD) begin
+ $display("ERROR @%0t in %m: Tx channel 1 didn't have expected C/D in MIMO mode", $time);
+ $finish;
+ end
+
+ // All outputs should have the same count in MIMO mode
+ if (! (tx_i0_check[7:0] == tx_q0_check[7:0] &&
+ tx_i0_check[7:0] == tx_i1_check[7:0] &&
+ tx_i0_check[7:0] == tx_q1_check[7:0]) ) begin
+ $display("ERROR @%0t in %m: Rx data counts didn't match on all outputs in MIMO mode", $time);
+ $finish;
+ end
+
+ // Make sure the count increments
+ if (tx_i0_check[7:0] != tx_i0_del1[7:0] + 8'd1 || tx_q0_check[7:0] != tx_q0_del1[7:0] + 8'd1 ||
+ tx_i1_check[7:0] != tx_i1_del1[7:0] + 8'd1 || tx_q1_check[7:0] != tx_q1_del1[7:0] + 8'd1) begin
+ $display("ERROR @%0t in %m: Rx data count didn't increment as expected", $time);
+ $finish;
+ end
+
+ end else begin
+ //-----------------------------------------------------------------
+ // Check SISO Output
+ //-----------------------------------------------------------------
+
+ // Check that the frame signal is correct
+ if (tx_frame_check != 8'b11001100) begin
+ $display("ERROR @%0t in %m: Tx frame was not correct in SISO mode", $time);
+ $finish;
+ end
+
+
+ // In SISO mode, the data we get depends on which channel is
+ // selected.
+ //
+ // Channel 0: Channel 1:
+ // ...,A01,B01,A02,B02,... OR ...,C01,D01,C02,D02,...
+ //
+ // So we should receive
+ //
+ // A01 A03 A05
+ // ... B01 B03 B05 ...
+ // A02 B04 A06
+ // B02 B04 A07
+ //
+ // or
+ // C01 C03 C05
+ // ... D01 D03 D05 ...
+ // C02 C04 C06
+ // D02 D04 D07
+ //
+
+ // Check prefixes
+ if (!(
+ // Either A,B on channel 0 or C,D on channel 1
+ ((tx_ch == 0 &&
+ tx_i0_check[11:8] == 4'hA &&
+ tx_q0_check[11:8] == 4'hB) ||
+ (tx_ch == 1 &&
+ tx_i0_check[11:8] == 4'hC &&
+ tx_q0_check[11:8] == 4'hD)) &&
+ // Samples 0 and 1 prefixes equal samples 2 and 3 prefixes
+ (tx_i0_check[11:8] == tx_i1_check[11:8] &&
+ tx_q0_check[11:8] == tx_q1_check[11:8])
+ )) begin
+ $display("ERROR @%0t in %m: Tx channel didn't have expected prefixes in SISO mode", $time);
+ $finish;
+ end
+
+ // Check that the data count matches between samples
+ if (!(
+ tx_i0_check[7:0] == tx_q0_check[7:0] &&
+ tx_i1_check[7:0] == tx_q1_check[7:0] &&
+ tx_i0_check[7:0] == tx_i1_check[7:0] - 8'd1
+ )) begin
+ $display("ERROR @%0t in %m: Tx channel data counts didn't correlate in SISO mode", $time);
+ $finish;
+ end
+
+ // Make sure the count increments form one burst to the next
+ if (tx_i0_check[7:0] != tx_i0_del1[7:0] + 8'd2 ||
+ tx_q0_check[7:0] != tx_q0_del1[7:0] + 8'd2 ||
+ tx_i1_check[7:0] != tx_i1_del1[7:0] + 8'd2 ||
+ tx_q1_check[7:0] != tx_q1_del1[7:0] + 8'd2) begin
+ $display("ERROR @%0t in %m: Tx data count didn't increment as expected", $time);
+ $finish;
+ end
+
+ end
+
+ end else begin // if (!first_tx_check)
+ // Make sure we've captured at least one set of values, so we have a
+ // previous set to look back to.
+ first_tx_check <= 1'b0;
+ end // if (!first_tx_check)
+
+ // Save values seen this cycle
+ tx_i0_del1 <= tx_i0_check;
+ tx_q0_del1 <= tx_q0_check;
+ tx_i1_del1 <= tx_i1_check;
+ tx_q1_del1 <= tx_q1_check;
+
+ end else begin // if (check_enabled)
+ first_tx_check <= 1'b1;
+
+ end // if (check_enabled)
+
+ end // if (tx_frame_p && !tx_frame_del1)
+
+ end
+
+
+ //---------------------------------------------------------------------------
+ // Tx Input Data Generation
+ //---------------------------------------------------------------------------
+ //
+ // Input a known data pattern similar to the Rx patten.
+ //
+ // I0: A01 A02 A03
+ // Q0: ... B01 B02 B03 ...
+ // I1: C01 C02 C03
+ // Q1: D01 D02 D03
+ //
+ //---------------------------------------------------------------------------
+
+ reg [7:0] tx_count = 0;
+
+ // Loop the Rx interface of DUT back to its Tx interface
+ always @(posedge radio_clk) begin
+ tx_i0 <= { 4'hA, tx_count };
+ tx_q0 <= { 4'hB, tx_count };
+ tx_i1 <= { 4'hC, tx_count };
+ tx_q1 <= { 4'hD, tx_count };
+ tx_count <= tx_count + 7'd1;
+ end
+
+
+ //---------------------------------------------------------------------------
+ // DUT
+ //---------------------------------------------------------------------------
+
+ cat_io_lvds_dual_mode #(
+ .INVERT_FRAME_RX (0),
+ .INVERT_DATA_RX (6'b00_0000),
+ .INVERT_FRAME_TX (0),
+ .INVERT_DATA_TX (6'b00_0000),
+ .USE_CLOCK_IDELAY (USE_CLOCK_IDELAY),
+ .USE_DATA_IDELAY (USE_DATA_IDELAY),
+ .DATA_IDELAY_MODE (DATA_IDELAY_MODE),
+ .CLOCK_IDELAY_MODE (CLOCK_IDELAY_MODE),
+ .INPUT_CLOCK_DELAY (INPUT_CLOCK_DELAY),
+ .INPUT_DATA_DELAY (INPUT_DATA_DELAY),
+ .USE_CLOCK_ODELAY (USE_CLOCK_ODELAY),
+ .USE_DATA_ODELAY (USE_DATA_ODELAY),
+ .DATA_ODELAY_MODE (DATA_ODELAY_MODE),
+ .CLOCK_ODELAY_MODE (CLOCK_ODELAY_MODE),
+ .OUTPUT_CLOCK_DELAY (OUTPUT_CLOCK_DELAY),
+ .OUTPUT_DATA_DELAY (OUTPUT_DATA_DELAY)
+ ) cat_io_lvds_dual_mode_dut (
+ .rst (reset),
+ .clk200 (clk200),
+
+ // Data and frame timing
+ .a_mimo (mimo),
+ .a_tx_ch (tx_ch),
+
+ // Delay control interface
+ .ctrl_clk (rx_clk),
+ //
+ .ctrl_in_data_delay (ctrl_in_data_delay),
+ .ctrl_in_clk_delay (ctrl_in_clk_delay),
+ .ctrl_ld_in_data_delay (ctrl_ld_in_data_delay),
+ .ctrl_ld_in_clk_delay (ctrl_ld_in_clk_delay),
+ //
+ .ctrl_out_data_delay (ctrl_out_data_delay),
+ .ctrl_out_clk_delay (ctrl_out_clk_delay),
+ .ctrl_ld_out_data_delay (ctrl_ld_out_data_delay),
+ .ctrl_ld_out_clk_delay (ctrl_ld_out_clk_delay),
+
+ // Baseband sample interface
+ .radio_clk (radio_clk),
+ .rx_aligned (rx_aligned),
+ //
+ .rx_i0 (rx_i0),
+ .rx_q0 (rx_q0),
+ .rx_i1 (rx_i1),
+ .rx_q1 (rx_q1),
+ //
+ .tx_i0 (tx_i0),
+ .tx_q0 (tx_q0),
+ .tx_i1 (tx_i1),
+ .tx_q1 (tx_q1),
+
+ // Catalina interface
+ .rx_clk_p (rx_clk),
+ .rx_clk_n (~rx_clk),
+ .rx_frame_p (rx_frame),
+ .rx_frame_n (~rx_frame),
+ .rx_d_p (rx_d),
+ .rx_d_n (~rx_d),
+ //
+ .tx_clk_p (tx_clk_p),
+ .tx_clk_n (tx_clk_n),
+ .tx_frame_p (tx_frame_p),
+ .tx_frame_n (tx_frame_n),
+ .tx_d_p (tx_d_p),
+ .tx_d_n (tx_d_n)
+ );
+
+endmodule // cat_io_lvds_dual_mode_tb
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_tb.v b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_tb.v
new file mode 100644
index 000000000..91cd6f938
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/cat_io_lvds/cat_io_lvds_tb.v
@@ -0,0 +1,350 @@
+//
+// Copyright 2016 Ettus Research, A National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+// Module: cat_io_lvds_tb
+//
+// Description: Testbench for cat_io_lvds.
+//
+
+`timescale 1ns/1ps
+
+module cat_io_lvds_tb();
+
+ localparam CLK_PERIOD = 10;
+ localparam CLK200_PERIOD = 2.5;
+
+ localparam FRAME_SAMPLE = 0;
+
+ localparam USE_CLOCK_IDELAY = 1;
+ localparam USE_DATA_IDELAY = 1;
+ localparam DATA_IDELAY_MODE = "VAR_LOAD";
+ localparam CLOCK_IDELAY_MODE = "VAR_LOAD";
+ localparam INPUT_CLOCK_DELAY = 0;
+ localparam INPUT_DATA_DELAY = 0;
+ localparam USE_CLOCK_ODELAY = 1;
+ localparam USE_DATA_ODELAY = 1;
+ localparam DATA_ODELAY_MODE = "VAR_LOAD";
+ localparam CLOCK_ODELAY_MODE = "VAR_LOAD";
+ localparam OUTPUT_CLOCK_DELAY = 0;
+ localparam OUTPUT_DATA_DELAY = 0;
+
+ reg [8*19:0] test_status;
+
+ reg clk = 0;
+ reg rx_clk = 0;
+ reg clk200 = 0;
+
+ reg reset;
+ reg mimo;
+ reg [5:0] rx_d;
+ reg rx_frame;
+ reg [7:0] count;
+
+// initial $dumpfile("catcap_ddr_lvds_tb.vcd");
+// initial $dumpvars(0,catcap_ddr_lvds_tb);
+
+ wire [11:0] i0 = {4'hA,count};
+ wire [11:0] q0 = {4'hB,count};
+ wire [11:0] i1 = {4'hC,count};
+ wire [11:0] q1 = {4'hD,count};
+
+ wire radio_clk;
+
+ reg [11:0] tx_i0;
+ reg [11:0] tx_q0;
+ reg [11:0] tx_i1;
+ reg [11:0] tx_q1;
+
+ wire [11:0] rx_i0;
+ wire [11:0] rx_q0;
+ wire [11:0] rx_i1;
+ wire [11:0] rx_q1;
+
+ wire rx_aligned;
+
+ wire tx_clk_p, tx_clk_n;
+ wire tx_frame_p, tx_frame_n;
+ wire [5:0] tx_d_p, tx_d_n;
+
+ reg [4:0] ctrl_in_data_delay;
+ reg [4:0] ctrl_in_clk_delay;
+ reg ctrl_ld_in_data_delay;
+ reg ctrl_ld_in_clk_delay;
+
+ reg [4:0] ctrl_out_data_delay;
+ reg [4:0] ctrl_out_clk_delay;
+ reg ctrl_ld_out_data_delay;
+ reg ctrl_ld_out_clk_delay;
+
+
+ //---------------------------------------------------------------------------
+ // Clock Generation
+ //---------------------------------------------------------------------------
+
+ // IODELAYCTRL reference clock
+ always #(CLK200_PERIOD) clk200 = ~clk200;
+
+ // Create an internal clock we'll use to drive the data
+ always #(CLK_PERIOD) clk = ~clk;
+
+ // RF interface clock. Half the rate of clk and out of phase
+ always @(negedge clk) rx_clk <= ~rx_clk;
+
+
+ //---------------------------------------------------------------------------
+ // Tasks
+ //---------------------------------------------------------------------------
+
+ task BURST;
+ input [31:0] len;
+ input do_mimo;
+ begin
+ count <= 0;
+ repeat(len)
+ begin
+ mimo <= do_mimo;
+
+ // Channel 0 sample
+ @(posedge clk);
+ rx_d <= i0[11:6];
+ rx_frame <= 1;
+ @(posedge clk);
+ rx_d <= q0[11:6];
+ rx_frame <= 1;
+ @(posedge clk);
+ rx_d <= i0[5:0];
+ rx_frame <= ~FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= q0[5:0];
+ rx_frame <= ~FRAME_SAMPLE;
+
+ if (do_mimo) begin
+ // Channel 1 sample
+ @(posedge clk);
+ rx_d <= i1[11:6];
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= q1[11:6];
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= i1[5:0];
+ rx_frame <= 0;
+ @(posedge clk);
+ rx_d <= q1[5:0];
+ rx_frame <= 0;
+ end else begin
+ if (!FRAME_SAMPLE) begin
+ // When we frame every two samples (one from each channel), in
+ // MIMO mode, we should only grab channel 0. So input garbage on
+ // channel 1 to make sure the data doesn't get used.
+ @(posedge clk);
+ rx_d <= 6'bXXXXXX;
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= 6'bXXXXXX;
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= 6'bXXXXXX;
+ rx_frame <= 0;
+ @(posedge clk);
+ rx_d <= 6'bXXXXXX;
+ rx_frame <= 0;
+ end else begin
+ // When every sample is framed, we might sync align to either
+ // channel (no way to tell them apart), so input the channel 1
+ // data, but we should only see one channel's data duplicated on
+ // both outputs.
+ @(posedge clk);
+ rx_d <= i1[11:6];
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= q1[11:6];
+ rx_frame <= FRAME_SAMPLE;
+ @(posedge clk);
+ rx_d <= i1[5:0];
+ rx_frame <= 0;
+ @(posedge clk);
+ rx_d <= q1[5:0];
+ rx_frame <= 0;
+ end
+ end
+
+ count <= count + 1;
+ end
+ end
+ endtask // BURST
+
+
+ //---------------------------------------------------------------------------
+ // Test Procedure
+ //---------------------------------------------------------------------------
+
+ initial
+ begin
+ // Initial values
+ test_status <= "Reset";
+ reset = 1;
+ mimo = 1;
+ ctrl_in_data_delay = 5'd0;
+ ctrl_in_clk_delay = 5'd8;
+ ctrl_ld_in_data_delay = 1'b0;
+ ctrl_ld_in_clk_delay = 1'b0;
+ ctrl_out_data_delay = 5'd0;
+ ctrl_out_clk_delay = 5'd16;
+ ctrl_ld_out_data_delay = 1'b0;
+ ctrl_ld_out_clk_delay = 1'b0;
+ repeat(10) @(negedge rx_clk);
+ reset = 0;
+ @(negedge rx_clk);
+
+ // Load new input delay values
+ test_status <= "Load input delays";
+ ctrl_ld_in_data_delay = 1'b1;
+ ctrl_ld_in_clk_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_in_data_delay = 1'b0;
+ ctrl_ld_in_clk_delay = 1'b0;
+
+ // Load new output delay values
+ test_status <= "Load output delays";
+ ctrl_ld_out_data_delay = 1'b1;
+ ctrl_ld_out_clk_delay = 1'b1;
+ @(negedge rx_clk);
+ ctrl_ld_out_data_delay = 1'b0;
+ ctrl_ld_out_clk_delay = 1'b0;
+
+ // Input data until the Rx circuit aligns
+ test_status <= "Wait align";
+ while (!rx_aligned) begin
+ BURST(1,1);
+ end
+
+ // Input some new samples
+ test_status <= "Burst 1 (MIMO)";
+ BURST(30, 1);
+
+ // Reset and do another burst
+ test_status <= "Reset 2";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns
+ test_status <= "Wait align 2";
+ while (!rx_aligned) begin
+ BURST(1,1);
+ end
+
+ // Input some new samples
+ test_status <= "Burst 2 (MIMO)";
+ BURST(30, 1);
+
+ // Reset and do another burst
+ test_status <= "Reset 3";
+ reset = 1;
+ repeat(20) @(negedge rx_clk);
+ reset = 0;
+ repeat(2) @(negedge rx_clk);
+
+ // Input data until the Rx circuit aligns in SISO mode
+ test_status <= "Wait align 3";
+ while (!rx_aligned) begin
+ BURST(1,0);
+ end
+
+ // Switch to SISO mode
+ test_status <= "Burst 3 (SISO)";
+ BURST(25,0);
+
+ repeat(50) @(negedge rx_clk);
+
+
+ $finish;
+ end
+
+
+ //---------------------------------------------------------------------------
+ // DUT
+ //---------------------------------------------------------------------------
+
+ // Loop the Rx interface of cat_io_lvds back to its Tx interface
+ always @(posedge radio_clk) begin
+ tx_i0 = rx_i0;
+ tx_q0 = rx_q0;
+ tx_i1 = rx_i1;
+ tx_q1 = rx_q1;
+ end
+
+ cat_io_lvds #(
+ .INVERT_FRAME_RX (0),
+ .INVERT_DATA_RX (6'b00_0000),
+ .INVERT_FRAME_TX (0),
+ .INVERT_DATA_TX (6'b00_0000),
+ .USE_CLOCK_IDELAY (USE_CLOCK_IDELAY ),
+ .USE_DATA_IDELAY (USE_DATA_IDELAY ),
+ .DATA_IDELAY_MODE (DATA_IDELAY_MODE ),
+ .CLOCK_IDELAY_MODE (CLOCK_IDELAY_MODE ),
+ .INPUT_CLOCK_DELAY (INPUT_CLOCK_DELAY ),
+ .INPUT_DATA_DELAY (INPUT_DATA_DELAY ),
+ .USE_CLOCK_ODELAY (USE_CLOCK_ODELAY ),
+ .USE_DATA_ODELAY (USE_DATA_ODELAY ),
+ .DATA_ODELAY_MODE (DATA_ODELAY_MODE ),
+ .CLOCK_ODELAY_MODE (CLOCK_ODELAY_MODE ),
+ .OUTPUT_CLOCK_DELAY (OUTPUT_CLOCK_DELAY),
+ .OUTPUT_DATA_DELAY (OUTPUT_DATA_DELAY )
+ ) cat_io_lvds_i0 (
+ .rst (reset),
+ .clk200 (clk200),
+
+ // Data and frame timing
+ .mimo (mimo),
+ .frame_sample (FRAME_SAMPLE[0]),
+
+ // Delay control interface
+ .ctrl_clk (rx_clk),
+ //
+ .ctrl_in_data_delay (ctrl_in_data_delay),
+ .ctrl_in_clk_delay (ctrl_in_clk_delay),
+ .ctrl_ld_in_data_delay (ctrl_ld_in_data_delay),
+ .ctrl_ld_in_clk_delay (ctrl_ld_in_clk_delay),
+ //
+ .ctrl_out_data_delay (ctrl_out_data_delay),
+ .ctrl_out_clk_delay (ctrl_out_clk_delay),
+ .ctrl_ld_out_data_delay (ctrl_ld_out_data_delay),
+ .ctrl_ld_out_clk_delay (ctrl_ld_out_clk_delay),
+
+ // Baseband sample interface
+ .radio_clk (radio_clk),
+ .radio_clk_2x (),
+ .rx_aligned (rx_aligned),
+ //
+ .rx_i0 (rx_i0),
+ .rx_q0 (rx_q0),
+ .rx_i1 (rx_i1),
+ .rx_q1 (rx_q1),
+ //
+ .tx_i0 (tx_i0),
+ .tx_q0 (tx_q0),
+ .tx_i1 (tx_i1),
+ .tx_q1 (tx_q1),
+
+ // Catalina interface
+ .rx_clk_p (rx_clk),
+ .rx_clk_n (~rx_clk),
+ .rx_frame_p (rx_frame),
+ .rx_frame_n (~rx_frame),
+ .rx_d_p (rx_d),
+ .rx_d_n (~rx_d),
+ //
+ .tx_clk_p (tx_clk_p),
+ .tx_clk_n (tx_clk_n),
+ .tx_frame_p (tx_frame_p),
+ .tx_frame_n (tx_frame_n),
+ .tx_d_p (tx_d_p),
+ .tx_d_n (tx_d_n)
+ );
+
+endmodule // cat_io_lvds_tb
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.build b/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.build
new file mode 100755
index 000000000..827ab0628
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.build
@@ -0,0 +1,21 @@
+
+#!/bin/sh
+
+rm -rf isim*
+rm -rf catcap_tb
+rm -rf fuse*
+\
+# --sourcelibdir ../../models \
+
+vlogcomp \
+ --sourcelibext .v \
+ --sourcelibdir ../../coregen \
+ --sourcelibdir ../../control_lib \
+ --sourcelibdir . \
+ --sourcelibdir $XILINX/verilog/src \
+ --sourcelibdir $XILINX/verilog/src/unisims \
+ --work work \
+ catcap_tb.v
+
+
+fuse -o catcap_tb catcap_tb \ No newline at end of file
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.v b/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.v
new file mode 100644
index 000000000..f300cc32f
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/catcap/catcap_tb.v
@@ -0,0 +1,115 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module catcap_tb();
+
+ wire GSR, GTS;
+ glbl glbl( );
+
+ reg clk = 0;
+ reg ddrclk = 0;
+ reg reset = 1;
+
+ always #100 clk = ~clk;
+ always @(negedge clk) ddrclk <= ~ddrclk;
+
+ initial $dumpfile("catcap_tb.vcd");
+ initial $dumpvars(0,catcap_tb);
+
+ wire [11:0] i0 = {4'hA,count};
+ wire [11:0] q0 = {4'hB,count};
+ wire [11:0] i1 = {4'hC,count};
+ wire [11:0] q1 = {4'hD,count};
+
+ reg mimo;
+ reg [11:0] pins;
+ reg frame;
+ reg [7:0] count;
+
+ initial
+ begin
+ #1000 reset = 0;
+ MIMO_BURST(4);
+ MIMO_BURST(5);
+ BURST(4);
+ BURST(5);
+ #2000;
+ $finish;
+ end
+
+ task BURST;
+ input [7:0] len;
+ begin
+ frame <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ mimo <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge ddrclk);
+ count <= 0;
+ repeat(len)
+ begin
+ @(posedge clk);
+ pins <= i0;
+ frame <= 1;
+ @(posedge clk);
+ pins <= q0;
+ frame <= 0;
+ count <= count + 1;
+ end
+ end
+ endtask // BURST
+
+ task MIMO_BURST;
+ input [7:0] len;
+ begin
+ frame <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ mimo <= 1;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge ddrclk);
+ count <= 0;
+ repeat(len)
+ begin
+ @(posedge clk);
+ pins <= i0;
+ frame <= 1;
+ @(posedge clk);
+ pins <= q0;
+ @(posedge clk);
+ pins <= i1;
+ frame <= 0;
+ @(posedge clk);
+ pins <= q1;
+ count <= count + 1;
+ end
+ @(posedge clk);
+ @(posedge clk);
+ end
+ endtask // MIMO_BURST
+
+ wire rx_clk, rx_strobe;
+ wire [11:0] i0o,i1o,q0o,q1o;
+
+ catcap_ddr_cmos catcap
+ (.data_clk(ddrclk),
+ .reset(reset),
+ .mimo(mimo),
+ .rx_frame(frame),
+ .rx_d(pins),
+ .rx_clk(rx_clk),
+ .rx_strobe(rx_strobe),
+ .i0(i0o),.q0(q0o),
+ .i1(i1o),.q1(q1o));
+
+endmodule // hb_chain_tb
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.build b/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.build
new file mode 100755
index 000000000..072495479
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.build
@@ -0,0 +1,21 @@
+
+#!/bin/sh
+
+rm -rf isim*
+rm -rf catgen_tb
+rm -rf fuse*
+\
+# --sourcelibdir ../../models \
+
+vlogcomp \
+ --sourcelibext .v \
+ --sourcelibdir ../../coregen \
+ --sourcelibdir ../../control_lib \
+ --sourcelibdir . \
+ --sourcelibdir $XILINX/verilog/src \
+ --sourcelibdir $XILINX/verilog/src/unisims \
+ --work work \
+ catgen_tb.v
+
+
+fuse -o catgen_tb catgen_tb \ No newline at end of file
diff --git a/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.v b/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.v
new file mode 100644
index 000000000..e55f2de32
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_cap_gen/catgen/catgen_tb.v
@@ -0,0 +1,103 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module catgen_tb();
+
+ wire GSR, GTS;
+ glbl glbl( );
+
+ reg clk = 0;
+ reg reset = 1;
+ wire ddrclk;
+
+ always #100 clk = ~clk;
+
+ initial $dumpfile("catgen_tb.vcd");
+ initial $dumpvars(0,catgen_tb);
+
+ wire [11:0] pins;
+ wire frame;
+
+ reg mimo;
+ reg [7:0] count;
+ reg tx_strobe;
+
+ wire [11:0] i0 = {4'hA,count};
+ wire [11:0] q0 = {4'hB,count};
+ wire [11:0] i1 = {4'hC,count};
+ wire [11:0] q1 = {4'hD,count};
+
+ initial
+ begin
+ #1000 reset = 0;
+ BURST(4);
+ BURST(5);
+ MIMO_BURST(4);
+ MIMO_BURST(5);
+ #2000;
+ $finish;
+ end
+
+ task BURST;
+ input [7:0] len;
+
+ begin
+ tx_strobe <= 0;
+ mimo <= 0;
+ count <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ repeat(len)
+ begin
+ tx_strobe <= 1;
+ @(posedge clk);
+ count <= count + 1;
+ end
+ tx_strobe <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end
+ endtask // BURST
+
+ task MIMO_BURST;
+ input [7:0] len;
+
+ begin
+ tx_strobe <= 0;
+ mimo <= 1;
+ count <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ repeat(len)
+ begin
+ tx_strobe <= 1;
+ @(posedge clk);
+ tx_strobe <= 0;
+ @(posedge clk);
+ count <= count + 1;
+ end
+ tx_strobe <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ end
+ endtask // BURST
+
+ catgen_ddr_cmos catgen
+ (.data_clk(ddrclk),
+ .reset(reset),
+ .mimo(mimo),
+ .tx_frame(frame),
+ .tx_d(pins),
+ .tx_clk(clk),
+ .tx_strobe(tx_strobe),
+ .i0(i0),.q0(q0),
+ .i1(i1),.q1(q1));
+
+endmodule // hb_chain_tb
diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v
new file mode 100644
index 000000000..2b6c40bdd
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_port2/pcie_dma_ctrl/pcie_dma_ctrl_tb.v
@@ -0,0 +1,92 @@
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+`timescale 500ps/1ps
+
+module pcie_dma_ctrl_tb();
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial begin
+ #100 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ function [63:0] iop2_msg_write;
+ input [19:0] address;
+ input [31:0] data;
+ input half_wd;
+ begin
+ // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
+ iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data};
+ end
+ endfunction // iop2_msg_write
+
+ function [63:0] iop2_msg_read;
+ input [19:0] address;
+ input half_wd;
+ begin
+ // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
+ iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0};
+ end
+ endfunction // iop2_msg_read
+
+ wire [3:0] clear;
+ wire [63:0] frame_size;
+ reg [3:0] pkt_stb = 0;
+ reg [3:0] samp_stb = 0;
+ reg [3:0] error = 0;
+ reg [7:0] rtr_sid = 4;
+ wire [3:0] rtr_dst;
+
+ reg [63:0] regi_tdata;
+ reg regi_tvalid;
+ wire regi_tready;
+ wire [63:0] rego_tdata;
+ wire rego_tvalid;
+ reg rego_tready;
+ reg [31:0] rego_payload;
+
+ always @(posedge clk)
+ if (rego_tdata[63] & rego_tvalid & rego_tready)
+ rego_payload <= rego_tdata[31:0];
+
+ initial begin
+ regi_tvalid <= 0;
+ rego_tready <= 0;
+ while (reset) @(posedge clk);
+
+ rego_tready <= 1;
+ @(posedge clk);
+
+ regi_tdata <= iop2_msg_write(20'h304, 32'hA, 0);
+ regi_tvalid <= 1;
+ @(posedge clk);
+ while (~regi_tready) @(posedge clk);
+ regi_tvalid <= 0;
+ @(posedge clk);
+
+ end // initial begin
+
+ pcie_dma_ctrl #(
+ .NUM_STREAMS(4), .FRAME_SIZE_W(16),
+ .REG_BASE_ADDR(20'h00200), .ENABLE_ROUTER(1),
+ .ROUTER_SID_W(8), .ROUTER_DST_W(4)
+ ) dut (
+ .clk(clk), .reset(reset),
+ .regi_tdata(regi_tdata), .regi_tvalid(regi_tvalid), .regi_tready(regi_tready),
+ .rego_tdata(rego_tdata), .rego_tvalid(rego_tvalid), .rego_tready(rego_tready),
+ .set_clear(clear), .set_frame_size(frame_size), .sample_stb(samp_stb), .packet_stb(pkt_stb),
+ .stream_err(error), .rtr_sid(rtr_sid), .rtr_dst(rtr_dst)
+ );
+
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v
new file mode 100644
index 000000000..fe566b1aa
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_port2/pcie_iop2_msg_arbiter/pcie_iop2_msg_arbiter_tb.v
@@ -0,0 +1,110 @@
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+`timescale 500ps/1ps
+
+module pcie_iop2_msg_arbiter_tb();
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial begin
+ #100 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ function [63:0] iop2_msg_write;
+ input [19:0] address;
+ input [31:0] data;
+ input half_wd;
+ begin
+ // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
+ iop2_msg_write = {1'b0, 1'b1, 1'b0, half_wd, 8'h00, address, data};
+ end
+ endfunction // iop2_msg_write
+
+ function [63:0] iop2_msg_read;
+ input [19:0] address;
+ input half_wd;
+ begin
+ // {rd_response, wr_request, rd_request, half_word, 8'h00, address, data};
+ iop2_msg_read = {1'b0, 1'b0, 1'b1, half_wd, 8'h00, address, 32'h0};
+ end
+ endfunction // iop2_msg_read
+
+ reg [63:0] msgi_tdata;
+ wire [63:0] msgo_tdata;
+ wire msgo_tvalid, msgi_tready;
+ reg msgo_tready, msgi_tvalid;
+
+ wire [63:0] basic_regi_tdata, zpu_regi_tdata;
+ wire basic_regi_tvalid, zpu_regi_tvalid;
+ reg basic_regi_tready, zpu_regi_tready;
+ reg [63:0] basic_rego_tdata, zpu_rego_tdata;
+ reg basic_rego_tvalid, zpu_rego_tvalid;
+ wire basic_rego_tready, zpu_rego_tready;
+
+ initial begin
+ //@TODO: Make this a self-checking TB
+ while (reset) @(posedge clk);
+
+ msgo_tready <= 1;
+ basic_regi_tready <= 1;
+ @(posedge clk);
+
+
+ msgi_tdata <= iop2_msg_write(20'h0, 32'hDEAD, 0);
+ msgi_tvalid <= 1;
+ while (~msgi_tready) @(posedge clk);
+ msgi_tvalid <= 0;
+ @(posedge clk);
+
+
+ msgi_tdata <= iop2_msg_read(20'h00000, 0);
+ msgi_tvalid <= 1;
+ while (~msgi_tready) @(posedge clk);
+ msgi_tvalid <= 0;
+ @(posedge clk);
+
+ zpu_rego_tdata <= {1, 31'h0, 32'h12345678};
+ zpu_rego_tvalid <= 1;
+ while (~zpu_rego_tready) @(posedge clk);
+ zpu_rego_tvalid <= 0;
+
+
+
+ end // initial begin
+
+ pcie_iop2_msg_arbiter #(
+ .E0_ADDR(20'h00000), .E0_MASK(20'hFFF00), //0x00000 - 0x000FF: Basic PCIe registers
+ .E1_ADDR(20'h00100), .E1_MASK(20'hFFF00), //0x00100 - 0x001FF: PCIe router registers
+ .E2_ADDR(20'h00200), .E2_MASK(20'hFFE00), //0x00200 - 0x003FF: DMA stream registers
+ .E3_ADDR(20'h40000), .E3_MASK(20'hC0000) //0x40000 - 0x7FFFF: Client address space
+ ) iop2_msg_arbiter (
+ .clk(clk), .reset(reset),
+ //Master
+ .regi_tdata(msgi_tdata), .regi_tvalid(msgi_tvalid), .regi_tready(msgi_tready),
+ .rego_tdata(msgo_tdata), .rego_tvalid(msgo_tvalid), .rego_tready(msgo_tready),
+ //Endpoint 0
+ .e0_regi_tdata(basic_regi_tdata), .e0_regi_tvalid(basic_regi_tvalid), .e0_regi_tready(basic_regi_tready),
+ .e0_rego_tdata(basic_rego_tdata), .e0_rego_tvalid(basic_rego_tvalid), .e0_rego_tready(basic_rego_tready),
+ //Endpoint 1
+ .e1_regi_tdata(), .e1_regi_tvalid(), .e1_regi_tready(1'b1),
+ .e1_rego_tdata(64'h0), .e1_rego_tvalid(1'b0), .e1_rego_tready(),
+ //Endpoint 2
+ .e2_regi_tdata(), .e2_regi_tvalid(), .e2_regi_tready(1'b1),
+ .e2_rego_tdata(64'h0), .e2_rego_tvalid(1'b0), .e2_rego_tready(),
+ //Endpoint 3
+ .e3_regi_tdata(zpu_regi_tdata), .e3_regi_tvalid(zpu_regi_tvalid), .e3_regi_tready(zpu_regi_tready),
+ .e3_rego_tdata(zpu_rego_tdata), .e3_rego_tvalid(zpu_rego_tvalid), .e3_rego_tready(zpu_rego_tready)
+ );
+
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v b/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v
new file mode 100644
index 000000000..62bec9eb4
--- /dev/null
+++ b/fpga/usrp3/lib/sim/io_port2/pcie_wb_reg_core/pcie_wb_reg_core_tb.v
@@ -0,0 +1,243 @@
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+`timescale 500ps/1ps
+`define CHECK_VALUE(val, expected, report) \
+ if (val == expected) \
+ $display("%s...Passed",report); \
+ else \
+ $display("%s...FAILED!!! (Val=0x%x, Exp=0x%x)",report,val,expected); \
+
+module pcie_wb_reg_core_tb();
+ reg clk = 0, reset = 1;
+ reg wb_stb_i = 0;
+ reg wb_we_i = 0;
+ reg [15:0] wb_adr_i = 0;
+ reg [31:0] wb_dat_i = 0;
+ wire wb_ack_o;
+ wire [31:0] wb_dat_o;
+
+ wire [63:0] msgo_data;
+ wire msgo_valid;
+ reg msgo_ready = 0;
+ reg [63:0] msgi_data = 0;
+ reg msgi_valid = 0;
+ wire msgi_ready;
+
+ reg [31:0] msgo_payload = 32'h0;
+ reg [31:0] msgo_ctrl = 32'h0;
+
+ reg [31:0] it;
+
+ always #10 clk = ~clk;
+
+ initial begin
+ #100 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ localparam READ = 3'b001;
+ localparam WRITE = 3'b010;
+ localparam RESPONSE = 3'b100;
+
+ task pcie_send;
+ input [2:0] op;
+ input [19:0] address;
+ input [31:0] data;
+ begin
+ //{rd_resp, wr_request, rd_request, half_word, 8'h00, address, data};
+ msgi_data <= {op, 1'b0, 8'h00, address, data};
+ msgi_valid <= 1'b1;
+
+ @(posedge clk);
+ while (~msgi_ready) @(posedge clk);
+
+ msgi_valid <= 1'b0;
+ @(posedge clk);
+ end
+ endtask // pcie_send
+
+ task pcie_recv;
+ input [2:0] op;
+ input [19:0] address;
+ input [31:0] data;
+ begin
+ while (~msgo_valid) @(posedge clk);
+
+ msgo_ready <= 1'b1;
+ @(posedge clk);
+
+ if (msgo_data[63] == op[2] || (msgo_data[62:61] == op[1:0] && msgo_data[51:32] == address))
+ msgo_payload <= msgo_data[31:0];
+ msgo_ctrl <= msgo_data[63:32];
+
+ msgo_ready <= 1'b0;
+ @(posedge clk);
+ end
+ endtask // pcie_recv
+
+ task wb_send;
+ input [2:0] op;
+ input [15:0] address;
+ input [31:0] data;
+ begin
+ wb_adr_i <= address;
+ wb_dat_i <= data;
+ wb_we_i <= op[1];
+ wb_stb_i <= 1'b1;
+
+ @(posedge clk);
+ while (~wb_ack_o) @(posedge clk);
+
+ wb_stb_i <= 1'b0;
+ end
+ endtask // pcie_send
+
+
+ initial begin
+ msgo_ready <= 1'b0;
+ msgi_valid <= 1'b0;
+ while (reset) @(posedge clk);
+ @(posedge clk);
+
+ $display("\n[TEST] ZPU Read from PCIe");
+ pcie_send(WRITE, 20'h6a000, 32'h0);
+ `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe readback before initiating read request");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating read");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after initiating second read");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h6, "Verify WB status after PCIe read request");
+ wb_send(READ, 16'h4, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h2000a000, "Verify WB control value after PCIe read request");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h4, "Verify WB status value after consuming PCIe read request");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status after WB consumes request only");
+ wb_send(WRITE, 16'h0, 32'hDEADBEEF);
+ wb_send(WRITE, 16'h4, 32'h80000000);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after responding to PCIe read request");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB responds to read request");
+ pcie_send(READ, 20'h7a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify PCIe read data");
+
+ $display("\n[TEST] ZPU Write from PCIe");
+ pcie_send(WRITE, 20'h7b000, 32'h12345678);
+ pcie_send(READ, 20'h7a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'hdeadbeef, "Verify that PCIe read data is still intact after write");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h2, "Verify WB status value after PCIe write request");
+ wb_send(READ, 16'h0, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h12345678, "Verify WB data value after PCIe read request");
+ wb_send(READ, 16'h4, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h4000b000, "Verify WB control value after PCIe read request");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after consuming PCIe write request");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after WB consumes request");
+
+ $display("\n[TEST] Chinch Write from ZPU");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating write request");
+ wb_send(WRITE, 16'h0, 32'h00beef00);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
+ wb_send(WRITE, 16'h4, 32'h40000200);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after initiating write");
+ pcie_recv(WRITE, 20'h200, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h00beef00, "Verify received PCIe data");
+ `CHECK_VALUE(msgo_ctrl, 32'h40000200, "Verify received PCIe control");
+ wb_send(WRITE, 16'h0, 32'h00feeb00);
+ wb_send(WRITE, 16'h4, 32'h400002fc);
+ pcie_recv(WRITE, 20'h200, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h00feeb00, "Verify second received PCIe data");
+ `CHECK_VALUE(msgo_ctrl, 32'h400002fc, "Verify second received PCIe control");
+
+ $display("\n[TEST] Chinch Read from ZPU");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value before initiating read request");
+ wb_send(WRITE, 16'h0, 32'hffffffff);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after writing just the data reg");
+ wb_send(WRITE, 16'h4, 32'h20000400);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value after initiating read request");
+ pcie_recv(READ, 20'h400, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'hffffffff, "Verify received PCIe data");
+ `CHECK_VALUE(msgo_ctrl, 32'h20000400, "Verify received PCIe control");
+ wb_send(READ, 16'hC, 32'h0);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status value before PCIe responds");
+ pcie_send(RESPONSE, 20'h000, 32'hace06666);
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status value after PCIe responds");
+ wb_send(READ, 16'h8, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'hace06666, "Verify WB read value after PCIe responds");
+
+ $display("\n[TEST] WB Outbound flood");
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h0, "Verify WB status before request flood");
+ for (it = 0; it < 64; it = it + 1) begin
+ wb_send(WRITE, 16'h4, 32'h20000400);
+ end
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h11, "Verify WB status after request flood");
+ for (it = 0; it < 64; it = it + 1) begin
+ pcie_recv(READ, 20'h400, 20'h0);
+ end
+ wb_send(READ, 16'hC, 32'h0);
+ `CHECK_VALUE(wb_dat_o, 32'h1, "Verify WB status after consuming requests");
+
+ $display("\n[TEST] PCIe Transaction Status");
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status before multiple reads");
+ pcie_send(WRITE, 20'h6a000, 32'h0);
+ pcie_send(WRITE, 20'h6a000, 32'h0);
+ pcie_send(WRITE, 20'h6a000, 32'h0);
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h1, "Verify PCIe status before multiple read requests and status queries");
+ wb_send(READ, 16'h4, 32'h0);
+ wb_send(WRITE, 16'h0, 32'hDEADBEEF);
+ wb_send(WRITE, 16'h4, 32'h80000000);
+ pcie_send(READ, 20'h6a000, 32'h0);
+ pcie_recv(RESPONSE, 20'h0, 20'h0);
+ `CHECK_VALUE(msgo_payload, 32'h0, "Verify PCIe status after response");
+
+ $display("\n[DONE]");
+
+
+ end // initial begin
+
+ pcie_wb_reg_core #(.WB_ADDRW(16), .WB_DATAW(32)) dut (
+ .clk(clk), .rst(reset),
+ .wb_stb_i(wb_stb_i), .wb_we_i(wb_we_i), .wb_adr_i(wb_adr_i),
+ .wb_dat_i(wb_dat_i), .wb_ack_o(wb_ack_o), .wb_dat_o(wb_dat_o),
+ .msgi_tdata(msgi_data), .msgi_tvalid(msgi_valid), .msgi_tready(msgi_ready),
+ .msgo_tdata(msgo_data), .msgo_tvalid(msgo_valid), .msgo_tready(msgo_ready),
+ .debug());
+
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/packet_proc/chdr_chunker/chdr_chunker_tb.v b/fpga/usrp3/lib/sim/packet_proc/chdr_chunker/chdr_chunker_tb.v
new file mode 100644
index 000000000..9e80f9c15
--- /dev/null
+++ b/fpga/usrp3/lib/sim/packet_proc/chdr_chunker/chdr_chunker_tb.v
@@ -0,0 +1,190 @@
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+`timescale 1ns/10ps
+
+module chdr_chunker_tb();
+
+ // TB stimulus
+ reg clk = 0;
+ reg reset = 1;
+ reg clear = 0;
+ reg [15:0] quantum;
+
+ // Check vars
+ reg [31:0] o_xfer_count = 0, i_xfer_count = 0;
+ reg [63:0] o_last_tdata = 0;
+
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("chdr_chunker_tb.vcd");
+ initial $dumpvars(0,chdr_chunker_tb);
+
+ function check_result;
+ input [31:0] o_xfer_count_arg;
+ input [31:0] i_xfer_count_arg;
+ input [63:0] o_last_tdata_arg;
+ input error_arg;
+ begin
+ //Check vars
+ check_result = 1;
+ check_result = check_result & ((o_xfer_count_arg == o_xfer_count) !== 0);
+ check_result = check_result & ((i_xfer_count_arg == i_xfer_count) !== 0);
+ check_result = check_result & ((o_last_tdata_arg == o_last_tdata) !== 0);
+ check_result = check_result & ((error_arg == error) != 0);
+
+ if (check_result) begin
+ $display ("... Passed");
+ end else begin
+ $display ("... FAILED!!!");
+ $display ("o_xfer_count = %d (Expected %d)",o_xfer_count,o_xfer_count_arg);
+ $display ("i_xfer_count = %d (Expected %d)",i_xfer_count,i_xfer_count_arg);
+ $display ("o_last_tdata = %h (Expected %h)",o_last_tdata,o_last_tdata_arg);
+ $display ("error = %d (Expected %d)",error,error_arg);
+ end
+
+ //Reset vars
+ o_xfer_count = 0;
+ i_xfer_count = 0;
+ o_last_tdata = 64'h0;
+ end
+ endfunction
+
+ task send_packet;
+ input [63:0] data_start;
+ input [31:0] len;
+
+ begin
+ if(len < 9) begin
+ {i_tlast, i_tdata} <= { 1'b1, data_start[63:32], len[15:0], data_start[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ end else begin
+ {i_tlast, i_tdata} <= { 1'b0, data_start[63:32], len[15:0], data_start[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ repeat(((len-1)/8)-1) begin
+ i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
+ @(posedge clk);
+ end
+ i_tdata <= i_tdata + 64'h0000_0002_0000_0002;
+ i_tlast <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ end // else: !if(len < 9)
+ end
+ endtask // send_packet
+
+ task reset_quantum_atomic;
+ input [15:0] quant;
+ begin
+ quantum <= quant;
+ clear <= 1;
+ @(posedge clk);
+ clear <= 0;
+ @(posedge clk);
+ end
+ endtask // reset_quantum_atomic
+
+
+ initial begin
+ #100 reset = 0;
+ #200000;
+ $finish;
+ end
+
+ reg [63:0] i_tdata;
+ reg i_tlast;
+ reg i_tvalid;
+ wire i_tready;
+
+ wire [63:0] o_tdata;
+ wire o_tlast, o_tvalid, o_tready;
+ wire error;
+
+ initial begin
+ quantum <= 256;
+ i_tvalid <= 0;
+ while(reset) @(posedge clk);
+
+ $write ("Running test case: First packet after reset");
+ send_packet(64'h00000001_00000000, 128);
+ while(o_tvalid) @(posedge clk);
+ check_result(256,16,64'hFFFFFFFF_FFFFFFFF,0);
+
+ reset_quantum_atomic(8);
+
+ $write ("Running test case: sizeof(packet) < quantum");
+ send_packet(64'h00000001_00000000, 40);
+ while(o_tvalid) @(posedge clk);
+ check_result(8,5,64'hFFFFFFFF_FFFFFFFF,0);
+
+ reset_quantum_atomic(5);
+
+ $write ("Running test case: sizeof(packet) == quantum");
+ send_packet(64'h00000001_00000000, 40);
+ while(o_tvalid) @(posedge clk);
+ check_result(5,5,64'h00000030_00000008,0);
+
+ $write ("Running test case: sizeof(packet) == quantum - 64bits");
+ send_packet(64'h00000001_00000000, 32);
+ while(o_tvalid) @(posedge clk);
+ check_result(5,4,64'hFFFFFFFF_FFFFFFFF,0);
+
+ $write ("Running test case: sizeof(packet) == quantum + 64bits");
+ send_packet(64'h00000001_00000000, 48);
+ while(o_tvalid) @(posedge clk);
+ check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,1);
+
+ $write ("Running test case: Error reset");
+ reset_quantum_atomic(8);
+ check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,0);
+
+ $write ("Running test case: sizeof(packet) > quantum");
+ send_packet(64'h00000001_00000000, 80);
+ while(o_tvalid) @(posedge clk);
+ check_result(32'hxxxxxxxx,32'hxxxxxxxx,64'hxxxxxxxx_xxxxxxxx,1);
+
+ reset_quantum_atomic(8);
+
+ $write ("Running test case: sizeof(packet) == 2");
+ send_packet(64'h00000001_00000000, 8);
+ while(o_tvalid) @(posedge clk);
+ check_result(8,1,64'hFFFFFFFF_FFFFFFFF,0);
+
+ $write ("Running test case: Multiple packets back-to-back");
+ send_packet(64'h00000001_00000000, 40);
+ while(o_tvalid) @(posedge clk);
+ send_packet(64'h00000001_00000000, 16);
+ while(o_tvalid) @(posedge clk);
+ send_packet(64'h00000001_00000000, 64);
+ while(o_tvalid) @(posedge clk);
+ check_result(24,15,64'h0000004e0000000e,0);
+
+ end // initial begin
+
+
+ chdr_chunker dut (
+ .clk(clk), .reset(reset), .clear(clear), .frame_size(quantum),
+ .i_tdata(i_tdata), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
+ .error(error));
+
+ assign o_tready = 1;
+
+ always @(posedge clk) begin
+ if (o_tvalid & o_tready) begin
+ o_xfer_count <= o_xfer_count + 1;
+ o_last_tdata <= o_tdata;
+ end
+ if (i_tvalid & i_tready) i_xfer_count <= i_xfer_count + 1;
+ end
+
+endmodule // chdr_chunker_tb
diff --git a/fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/Makefile b/fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/Makefile
new file mode 100644
index 000000000..f73cbdae9
--- /dev/null
+++ b/fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/Makefile
@@ -0,0 +1,33 @@
+#
+# Copyright 2016 Ettus Research
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preample after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = chdr_dechunker_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+chdr_dechunker_tb.sv \
+)
+
+MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/packet_proc/chdr_dechunker/chdr_dechunker_tb.sv b/fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/chdr_dechunker_tb.sv
new file mode 100644
index 000000000..38664c20f
--- /dev/null
+++ b/fpga/usrp3/lib/sim/packet_proc/chdr_dechunker/chdr_dechunker_tb.sv
@@ -0,0 +1,200 @@
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+// Copyright 2019 Ettus Research, a National Instruments Brand
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+`timescale 1ns/10ps
+
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 8
+
+`include "sim_exec_report.vh"
+
+
+module chdr_dechunker_tb();
+ `TEST_BENCH_INIT("chdr_dechunker_tb", `NUM_TEST_CASES, `NS_PER_TICK)
+
+ // TB stimulus
+ reg clk = 0;
+ reg reset = 1;
+ reg clear = 0;
+ reg [15:0] quantum;
+ wire error;
+
+ // Check vars
+ reg [31:0] o_xfer_count = 0, i_xfer_count = 0;
+ reg [63:0] o_last_tdata = 0;
+
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("chdr_dechunker_tb.vcd");
+ initial $dumpvars(0,chdr_dechunker_tb);
+
+ function check_result;
+ input [31:0] o_xfer_count_arg;
+ input [31:0] i_xfer_count_arg;
+ input [63:0] o_last_tdata_arg;
+ input error_arg;
+ begin
+ //Check vars
+ check_result = 1;
+ check_result = check_result & ((o_xfer_count_arg == o_xfer_count) !== 0);
+ check_result = check_result & ((i_xfer_count_arg == i_xfer_count) !== 0);
+ check_result = check_result & ((o_last_tdata_arg == o_last_tdata) !== 0);
+ check_result = check_result & ((error_arg == error) != 0);
+
+ if (!check_result) begin
+ $display ("o_xfer_count = %d (Expected %d)",o_xfer_count,o_xfer_count_arg);
+ $display ("i_xfer_count = %d (Expected %d)",i_xfer_count,i_xfer_count_arg);
+ $display ("o_last_tdata = %h (Expected %h)",o_last_tdata,o_last_tdata_arg);
+ $display ("error = %d (Expected %d)",error,error_arg);
+ `ASSERT_ERROR(0, "Result did not match expected value");
+ end
+
+ //Reset vars
+ o_xfer_count = 0;
+ i_xfer_count = 0;
+ o_last_tdata = 64'h0;
+ end
+ endfunction
+
+ task send_packet;
+ input [63:0] data_start;
+ input [31:0] len;
+ input [31:0] quant;
+
+ begin
+ if(quant < 2) begin
+ {i_tlast, i_tdata} <= { 1'b1, data_start[63:32], len[15:0], data_start[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ end else begin
+ {i_tlast, i_tdata} <= { 1'b0, data_start[63:32], len[15:0], data_start[15:0] };
+ i_tvalid <= 1;
+ @(posedge clk);
+ 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;
+ i_tlast <= 1;
+ @(posedge clk);
+ i_tvalid <= 1'b0;
+ end // else: !if(quant < 2)
+ end
+ endtask // send_packet
+
+ task reset_quantum_atomic;
+ input [15:0] quant;
+ begin
+ quantum <= quant;
+ clear <= 1;
+ @(posedge clk);
+ clear <= 0;
+ @(posedge clk);
+ end
+ endtask // reset_quantum_atomic
+
+
+ initial begin
+ #100 reset = 0;
+ end
+
+ reg [63:0] i_tdata;
+ reg i_tlast;
+ reg i_tvalid;
+ wire i_tready;
+
+ wire [63:0] o_tdata;
+ wire o_tlast, o_tvalid, o_tready;
+
+ reg result;
+ initial begin
+ quantum <= 8;
+ i_tvalid <= 0;
+ while(reset) @(posedge clk);
+
+ `TEST_CASE_START("Running test case: First packet after reset");
+ send_packet(64'h00000001_00000000, 32, 8);
+ @(posedge clk);
+ result = check_result(4,8,64'hxxxxxxxx_xxxxxx06, 0);
+ `TEST_CASE_DONE(result);
+
+ reset_quantum_atomic(10);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) < quantum");
+ send_packet(64'h00000001_00000000, 64, 10);
+ @(posedge clk);
+ result = check_result(8,10,64'hxxxxxxxx_xxxxxx0e, 0);
+ `TEST_CASE_DONE(result);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) == quantum");
+ send_packet(64'h00000001_00000000, 80, 10);
+ @(posedge clk);
+ result = check_result(10,10,64'hxxxxxxxx_xxxxxx12, 0);
+ `TEST_CASE_DONE(result);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) == quantum - 64bits");
+ send_packet(64'h00000001_00000000, 72, 10);
+ @(posedge clk);
+ result = check_result(9,10,64'hxxxxxxxx_xxxxxx10, 0);
+ `TEST_CASE_DONE(result);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) == quantum + 64bits");
+ send_packet(64'h00000001_00000000, 88, 10);
+ @(posedge clk);
+ result = check_result(32'hxxxxxxxx,10,64'hxxxxxxxx_xxxxxxxx, 1);
+ `TEST_CASE_DONE(result);
+
+ reset_quantum_atomic(10);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) > quantum");
+ send_packet(64'h00000001_00000000, 88, 10);
+ @(posedge clk);
+ result = check_result(32'hxxxxxxxx,10,64'hxxxxxxxx_xxxxxxxx, 1);
+ `TEST_CASE_DONE(result);
+
+ reset_quantum_atomic(8);
+
+ `TEST_CASE_START("Running test case: sizeof(packet) == 2");
+ send_packet(64'h00000001_00000000, 8, 8);
+ @(posedge clk);
+ result = check_result(1,8,64'hxxxxxxxx_xxxxxx00, 0);
+ `TEST_CASE_DONE(result);
+
+ `TEST_CASE_START("Running test case: Multiple packets");
+ send_packet(64'h00000001_00000000, 8, 8);
+ send_packet(64'h00000001_00000000, 16, 8);
+ send_packet(64'h00000001_00000000, 24, 8);
+ send_packet(64'h00000001_00000000, 32, 8);
+ @(posedge clk);
+ result = check_result(10,32,64'hxxxxxxxx_xxxxxx06, 0);
+ `TEST_CASE_DONE(result);
+
+ `TEST_BENCH_DONE;
+ end // initial begin
+
+
+ chdr_dechunker dut (
+ .clk(clk), .reset(reset), .clear(clear), .frame_size(quantum),
+ .i_tdata(i_tdata), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
+ .error(error));
+
+ assign o_tready = 1;
+
+ always @(posedge clk) begin
+ if (o_tvalid & o_tready) begin
+ o_xfer_count <= o_xfer_count + 1;
+ o_last_tdata <= o_tdata;
+ end
+ if (i_tvalid & i_tready) i_xfer_count <= i_xfer_count + 1;
+ end
+
+endmodule // chdr_dechunker_tb
diff --git a/fpga/usrp3/lib/sim/packet_proc/ip_hdr_checksum/ip_hdr_checksum_tb.v b/fpga/usrp3/lib/sim/packet_proc/ip_hdr_checksum/ip_hdr_checksum_tb.v
new file mode 100644
index 000000000..82deca656
--- /dev/null
+++ b/fpga/usrp3/lib/sim/packet_proc/ip_hdr_checksum/ip_hdr_checksum_tb.v
@@ -0,0 +1,43 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+module ip_hdr_checksum_tb();
+
+ initial $dumpfile("ip_hdr_checksum_tb.vcd");
+ initial $dumpvars(0,ip_hdr_checksum_tb);
+
+ reg clk;
+
+ wire [159:0] in = {
+ 16'h4500,
+ 16'h0030,
+ 16'h4422,
+ 16'h4000,
+ 16'h8006,
+ 16'h0000,
+ 16'h8c7c,
+ 16'h19ac,
+ 16'hae24,
+ 16'h1e2b
+ };
+
+ wire [15:0] out;
+ ip_hdr_checksum ip_hdr_checksum
+ (.clk(clk),
+ .in(in),
+ .out(out));
+
+ initial
+ begin
+ clk <= 0;
+ #100 clk <= 1;
+ #100 clk <= 0;
+ #100 clk <= 1;
+ #100 $display("Computed 0x%x, should be 0x442e", out);
+ #100 $finish;
+ end
+
+endmodule // ip_hdr_checksum_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/axi_pipe/axi_pipe_tb.v b/fpga/usrp3/lib/sim/rfnoc/axi_pipe/axi_pipe_tb.v
new file mode 100644
index 000000000..b84657b07
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_pipe/axi_pipe_tb.v
@@ -0,0 +1,74 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+module axi_pipe_tb;
+
+ initial $dumpfile("axi_pipe_tb.vcd");
+ initial $dumpvars(0,axi_pipe_tb);
+
+ reg clk = 0;
+ always #100 clk <= ~clk;
+ reg reset = 1;
+ initial #1000 @(posedge clk) reset <= 1'b0;
+ initial #30000 $finish;
+
+ localparam LEN=10;
+ wire [LEN-1:0] enables, valids;
+
+ wire o_tlast, i_tready, o_tvalid;
+ reg i_tvalid = 0;
+ reg o_tready = 0;
+ reg i_tlast = 0;
+
+ axi_pipe #(.STAGES(LEN)) axi_pipe
+ (.clk(clk), .reset(reset), .clear(0),
+ .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready),
+ .enables(enables), .valids(valids));
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (3)
+ @(posedge clk);
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ repeat (15) @(posedge clk);
+ @(posedge clk);
+ o_tready <= 1;
+ repeat (15) @(posedge clk);
+ o_tready <= 0;
+ i_tvalid <= 1;
+ repeat (15) @(posedge clk);
+ o_tready <= 1;
+ i_tvalid <= 0;
+ repeat (15) @(posedge clk);
+ o_tready <= 0;
+ i_tvalid <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ @(posedge clk);
+ i_tvalid <= 1;
+ @(posedge clk);
+ @(posedge clk);
+ i_tlast <= 1;
+ @(posedge clk);
+ i_tvalid <= 0;
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ @(posedge clk);
+ o_tready <= 1;
+
+ end
+
+endmodule // axi_pipe
diff --git a/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/Makefile b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/Makefile
new file mode 100644
index 000000000..fcf21b755
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/Makefile
@@ -0,0 +1,37 @@
+#
+# Copyright 2016 Ettus Research
+#
+
+#-------------------------------------------------
+# Top-of-Makefile
+#-------------------------------------------------
+# Define BASE_DIR to point to the "top" dir
+BASE_DIR = $(abspath ../../../../top)
+# Include viv_sim_preamble after defining BASE_DIR
+include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+#-------------------------------------------------
+# Testbench Specific
+#-------------------------------------------------
+# Define only one toplevel module
+SIM_TOP = axi_rate_change_tb
+
+# Add test bench, user design under test, and
+# additional user created files
+SIM_SRCS = $(abspath \
+axi_rate_change_tb.sv \
+$(LIB_DIR)/control/ram_2port.v \
+$(LIB_DIR)/fifo/axi_packet_gate.v \
+$(LIB_DIR)/rfnoc/axi_rate_change.v \
+$(LIB_DIR)/rfnoc/axi_drop_partial_packet.v \
+)
+
+MODELSIM_USER_DO = $(abspath wave.do)
+
+#-------------------------------------------------
+# 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/lib/sim/rfnoc/axi_rate_change/axi_rate_change_tb.sv b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/axi_rate_change_tb.sv
new file mode 100644
index 000000000..b16c2d26d
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/axi_rate_change_tb.sv
@@ -0,0 +1,323 @@
+`timescale 1ns/1ps
+`define NS_PER_TICK 1
+`define NUM_TEST_CASES 4
+
+`include "sim_exec_report.vh"
+`include "sim_clks_rsts.vh"
+`include "sim_cvita_lib.svh"
+`include "sim_axis_lib.svh"
+`include "sim_set_rb_lib.svh"
+
+module axi_rate_change_tb();
+ `TEST_BENCH_INIT("axi_rate_change_tb",`NUM_TEST_CASES,`NS_PER_TICK);
+ localparam CLK_PERIOD = $ceil(1e9/166.67e6);
+ `DEFINE_CLK(clk, CLK_PERIOD, 50);
+ `DEFINE_RESET(reset, 0, 100);
+
+ localparam SR_N_ADDR = 0;
+ localparam SR_M_ADDR = 1;
+ localparam SR_CONFIG_ADDR = 2;
+ localparam MAX_N = 16;
+ localparam MAX_M = 16;
+
+ logic [15:0] src_sid = 16'h0000;
+ logic [15:0] dst_sid = 16'h0010;
+ settings_bus_master sb (.clk(clk));
+ axis_master #(.DWIDTH(32+128)) m_axis (.clk(clk));
+ axis_slave #(.DWIDTH(32+128)) s_axis (.clk(clk));
+ logic clear, clear_user;
+ logic [31:0] m_axis_data_tdata, s_axis_data_tdata;
+ logic m_axis_data_tlast, m_axis_data_tvalid, m_axis_data_tready;
+ logic s_axis_data_tlast, s_axis_data_tvalid, s_axis_data_tready;
+ logic warning_long_throttle, error_extra_outputs, error_drop_pkt_lockup;
+ axi_rate_change #(
+ .WIDTH(32),
+ .MAX_N(MAX_N),
+ .MAX_M(MAX_M),
+ .SR_N_ADDR(SR_N_ADDR),
+ .SR_M_ADDR(SR_M_ADDR),
+ .SR_CONFIG_ADDR(SR_CONFIG_ADDR))
+ axi_rate_change (
+ .clk(clk), .reset(reset), .clear(clear), .clear_user(clear_user),
+ .src_sid(src_sid), .dst_sid(dst_sid),
+ .set_stb(sb.settings_bus.set_stb), .set_addr(sb.settings_bus.set_addr), .set_data(sb.settings_bus.set_data),
+ .i_tdata(m_axis.axis.tdata[31:0]), .i_tlast(m_axis.axis.tlast), .i_tvalid(m_axis.axis.tvalid), .i_tready(m_axis.axis.tready), .i_tuser(m_axis.axis.tdata[159:32]),
+ .o_tdata(s_axis.axis.tdata[31:0]), .o_tlast(s_axis.axis.tlast), .o_tvalid(s_axis.axis.tvalid), .o_tready(s_axis.axis.tready), .o_tuser(s_axis.axis.tdata[159:32]),
+ .m_axis_data_tdata(m_axis_data_tdata), .m_axis_data_tlast(m_axis_data_tlast),
+ .m_axis_data_tvalid(m_axis_data_tvalid), .m_axis_data_tready(m_axis_data_tready),
+ .s_axis_data_tdata(s_axis_data_tdata), .s_axis_data_tlast(s_axis_data_tlast),
+ .s_axis_data_tvalid(s_axis_data_tvalid), .s_axis_data_tready(s_axis_data_tready),
+ .warning_long_throttle(warning_long_throttle),
+ .error_extra_outputs(error_extra_outputs),
+ .error_drop_pkt_lockup(error_drop_pkt_lockup));
+
+ // Simulate user logic that can handle various decimation / interpolation rates
+ // - Generates a word count sequence that is checked in the test_rate() task.
+ // - Introduces a single clock cycle delay which is useful for testing that
+ // the DUT is not reliant on user logic having a large built in delay.
+ integer rate_n, rate_m, count_n, count_m, count_in, count_out;
+ always @(posedge clk) begin
+ if (reset | clear_user | clear) begin
+ s_axis_data_tlast <= 1'b0;
+ count_n <= 1;
+ count_m <= 1;
+ count_in <= 0;
+ count_out <= 0;
+ end else begin
+ // Rate change = N/M
+ if (m_axis_data_tvalid & m_axis_data_tready) begin
+ if (count_n == rate_n) begin
+ count_n <= 1;
+ count_in <= count_in + 1;
+ end else begin
+ count_n <= count_n + 1;
+ end
+ end
+ if (count_in != count_out) begin
+ if (s_axis_data_tvalid & s_axis_data_tready) begin
+ if (count_m == rate_m) begin
+ count_m <= 1;
+ count_out <= count_out + 1;
+ end else begin
+ count_m <= count_m + 1;
+ end
+ end
+ end
+ end
+ end
+
+ assign s_axis_data_tdata = {count_out[15:0], count_m[15:0]};
+ assign s_axis_data_tvalid = (count_in != count_out);
+ assign m_axis_data_tready = s_axis_data_tready;
+
+ // Used with test 3 to count output clock cycles
+ int clock_cnt;
+ logic clock_cnt_en = 1'b0;
+ logic clock_cnt_start = 1'b0;
+ always @(posedge clk) begin
+ if (clock_cnt_en == 1'b1) begin
+ // Wait until output data starts
+ if (s_axis.axis.tvalid & ~clock_cnt_start) begin
+ clock_cnt_start <= 1'b1;
+ clock_cnt <= clock_cnt + 1;
+ end else if (clock_cnt_start) begin
+ clock_cnt <= clock_cnt + 1;
+ end
+ end else begin
+ clock_cnt_start <= 1'b0;
+ clock_cnt <= 0;
+ end
+ end
+
+ /********************************************************
+ ** Verification
+ ********************************************************/
+ task random_wait(int unsigned min_cycles, int unsigned max_cycles);
+ begin
+ int unsigned num_cycles;
+ do begin
+ num_cycles = $random() & (2**($clog2(max_cycles))-1);
+ end while ((num_cycles < min_cycles) || (num_cycles > max_cycles));
+
+ if (num_cycles != 0) begin
+ for (int unsigned i = 0; i < num_cycles; i++) begin
+ @(posedge clk);
+ end
+ @(negedge clk); // Realign with negedge
+ end
+ end
+ endtask
+
+ task test_rate(int n, int m, int num_words, int spp = 16, bit rand_delay_in = 0, bit rand_delay_out = 0);
+ begin
+ clear = 1'b1;
+ @(posedge clk);
+ @(posedge clk);
+ clear = 1'b0;
+ @(posedge clk);
+ @(posedge clk);
+ rate_n = n;
+ rate_m = m;
+ sb.write(SR_N_ADDR, n);
+ sb.write(SR_M_ADDR, m);
+ @(posedge clk);
+ fork
+ begin
+ cvita_hdr_t send_header;
+ int words_left_to_send, words_to_send;
+ logic [31:0] words_sent;
+ real timestamp;
+ timestamp = 0.0;
+ words_sent = 0;
+ words_left_to_send = num_words;
+
+ while (words_left_to_send > 0) begin
+ // Setup header
+ send_header = '{default:0};
+ send_header.has_time = 1;
+ send_header.timestamp = longint'(timestamp);
+ send_header.eob = (words_left_to_send <= spp);
+ if (words_left_to_send >= spp) begin
+ send_header.length = 16+4*spp;
+ words_to_send = spp;
+ words_left_to_send -= spp;
+ end else begin
+ send_header.length = 16+4*words_left_to_send;
+ words_to_send = words_left_to_send;
+ words_left_to_send = 0;
+ end
+ // Send packet
+ for (int i = 0; i < words_to_send; i++) begin
+ if (rand_delay_in) random_wait(0,2*spp);
+ m_axis.push_word({send_header,words_sent + i},i == words_to_send-1);
+ end
+ words_sent += words_to_send;
+ // Update seq num, timestamp
+ send_header.seqnum++;
+ timestamp += (1.0*m/n)*words_to_send;
+ end
+ end
+ begin
+ string s;
+ cvita_hdr_t recv_header;
+ logic last, expected_eob;
+ real timestamp;
+ logic [63:0] expected_timestamp;
+ logic [31:0] word;
+ logic [15:0] word_cnt_div_m, word_cnt_div_m_frac;
+ logic [15:0] word_cnt_div_spp_frac;
+ int words_left_to_recv, words_recvd;
+ timestamp = 0.0;
+ expected_timestamp = 0; // Timestamp starts at 0
+ word_cnt_div_spp_frac = 0;
+ word_cnt_div_m = 0;
+ word_cnt_div_m_frac = 0;
+ words_recvd = 0;
+ words_left_to_recv = $floor(num_words/n)*m; // Order matters!
+
+ while (words_left_to_recv > 0) begin
+ s_axis.pull_word({recv_header,word},last);
+ word_cnt_div_spp_frac++;
+ word_cnt_div_m_frac++;
+ words_recvd++;
+ words_left_to_recv--;
+ timestamp += 1.0*n;
+ // Check packet length
+ if ((word_cnt_div_spp_frac == spp) || (words_left_to_recv == 0)) begin
+ `ASSERT_FATAL(last == 1, "Incorrect packet length! Last not asserted!");
+ word_cnt_div_spp_frac = 0;
+ end else begin
+ $sformat(s, "Incorrect packet length! Expected: %0d, Actual %0d", spp, words_recvd);
+ `ASSERT_FATAL(last == 0, s);
+ end
+ // Check for EOB
+ if (last) begin
+ words_recvd = 0;
+ expected_eob = (words_left_to_recv == 0);
+ $sformat(s, "Incorrect EOB state! Expected: %0d, Actual %0d", expected_eob, recv_header.eob);
+ `ASSERT_FATAL(recv_header.eob == expected_eob, s);
+ end
+ // Check timestamp
+ if (last) begin
+ $sformat(s, "Incorrect timestamp! Expected: %0d, Actual %0d", expected_timestamp, recv_header.timestamp);
+ `ASSERT_FATAL(recv_header.timestamp == expected_timestamp, s);
+ expected_timestamp = longint'(timestamp);
+ end
+ // Check word
+ $sformat(s, "Incorrect packet data! Expected: 0x%08h, Actual: 0x%08h", {word_cnt_div_m, word_cnt_div_m_frac}, word);
+ `ASSERT_FATAL(((word[31:16] == word_cnt_div_m) && (word[15:0] == word_cnt_div_m_frac)), s);
+ // Track number of received words, do at end of loop
+ if (word_cnt_div_m_frac == m) begin
+ word_cnt_div_m_frac = 0;
+ word_cnt_div_m++;
+ end
+ end
+ end
+ join
+ end
+ endtask
+
+ initial begin : tb_main
+ string s;
+ cvita_hdr_t tmp_header;
+ logic [63:0] word;
+ logic last;
+ integer spp, number_words;
+ spp = 16;
+
+ /********************************************************
+ ** Test 1 -- Reset
+ ********************************************************/
+ `TEST_CASE_START("Wait for Reset");
+ sb.reset();
+ m_axis.reset();
+ s_axis.reset();
+ while (reset) @(posedge clk);
+ `TEST_CASE_DONE(~reset);
+
+ /********************************************************
+ ** Test 2 -- Test various rates
+ ** - Try many decimation / interpolation rates (including
+ ** fractional rates) and use randomized delays.
+ ********************************************************/
+ `TEST_CASE_START("Check various rates");
+ for (int _n = 1; _n <= MAX_N; _n++) begin
+ for (int _m = 1; _m <= MAX_M; _m++) begin
+ $display("Testing rate %0d:%0d", _n, _m);
+ test_rate(_n, _m, _n*spp*3, spp, 1, 1);
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ #2000; // Delay to make the tests visually distinct in waveform viewer
+
+ /********************************************************
+ ** Test 3 -- Test partial packets
+ ** - Send packets with extra data that is less than SPP.
+ ** Module should output the maximum number of samples
+ ** possible while dropping the "partial" sample.
+ ********************************************************/
+ `TEST_CASE_START("Test partial packets");
+ for (int _n = 1; _n <= MAX_N; _n++) begin
+ for (int _m = 1; _m <= MAX_M; _m++) begin
+ $display("Testing rate %0d:%0d", _n, _m);
+ test_rate(_n, _m, _n*spp + spp-1, spp, 1, 1);
+ end
+ end
+ `TEST_CASE_DONE(1);
+
+ #2000;
+
+ /********************************************************
+ ** Test 3 -- Test for bubble states
+ ** - Send many packets at full rate and make sure number
+ ** of input clock cycles == output clock cycles. If
+ ** they do not match, then the module likely has
+ ** bubble states that would prevent it from running
+ ** continuously at full rate.
+ ********************************************************/
+ `TEST_CASE_START("Test for bubble states");
+ clock_cnt_en = 1'b1;
+ number_words = 100000;
+ test_rate(1, 1, number_words, spp, 0, 0);
+ $sformat(s, "Incorrect number of clock cycles -- Possible bubble states detected! Expected: %0d, Actual: %0d", number_words, clock_cnt);
+ `ASSERT_FATAL(clock_cnt == number_words, s);
+ clock_cnt_en = 1'b0;
+ `TEST_CASE_DONE(1);
+
+ `TEST_BENCH_DONE;
+
+ end
+
+ // The warning, error signals should never assert.
+ initial begin
+ while (reset) @(posedge clk);
+ forever begin
+ @(posedge clk);
+ `ASSERT_FATAL(~warning_long_throttle, "Throttle state deadlock!");
+ `ASSERT_FATAL(~error_extra_outputs, "Extra outputs detected!");
+ `ASSERT_FATAL(~error_drop_pkt_lockup, "Drop packet deadlock!");
+ end
+ end
+
+endmodule
diff --git a/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/wave.do b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/wave.do
new file mode 100644
index 000000000..f16b9d5a7
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_rate_change/wave.do
@@ -0,0 +1,115 @@
+onerror {resume}
+quietly WaveActivateNextPane {} 0
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/clk
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/reset
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/clear
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/clear_user
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/active
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_tuser
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_frac
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/in_pkt_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_reg_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_reg_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_reg_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_reg_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/i_reg_tuser
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/m_axis_data_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/m_axis_data_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/m_axis_data_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/m_axis_data_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/s_axis_data_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/s_axis_data_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/s_axis_data_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/s_axis_data_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/out_payload_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/payload_length_out
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_m
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_fifo_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_fifo_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/word_cnt_div_n_fifo_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/first_pkt_out
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/vita_time_out
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/vita_time_accum
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/vita_time_reg
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/header_fifo_out_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/header_fifo_out_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_reg_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_reg_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_reg_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_reg_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_reg_tuser
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/o_tuser
+add wave -noupdate -divider {AXI Drop Partial Packet}
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_terror
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_tlast_int
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/i_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/in_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/large_pkt
+add wave -noupdate {/axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/o_tdata[32]}
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/o_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/o_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/o_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/o_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/small_pkt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/flush
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/hold_last_sample
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/in_pkt_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/out_pkt_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/release_due_to_error
+add wave -noupdate -divider {AXI Drop Packet}
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/hold
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/i_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/i_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/i_terror
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/i_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/i_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/empty
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/full
+add wave -noupdate -radix unsigned /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/rd_addr
+add wave -noupdate -radix unsigned /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/wr_addr
+add wave -noupdate -radix unsigned /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/in_pkt_cnt
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/int_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/int_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/int_tlast
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/int_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/mem
+add wave -noupdate -radix hexadecimal /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/o_tdata
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/o_tvalid
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/o_tready
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/o_tlast
+add wave -noupdate -radix unsigned /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/out_pkt_cnt
+add wave -noupdate -radix unsigned /axi_rate_change_tb/axi_rate_change/axi_drop_partial_packet/axi_drop_packet/prev_wr_addr
+add wave -noupdate /axi_rate_change_tb/axi_rate_change/n
+TreeUpdate [SetDefaultTree]
+WaveRestoreCursors {{Cursor 1} {1112517 ps} 0} {{Cursor 2} {1974349848 ps} 0}
+quietly wave cursor active 2
+configure wave -namecolwidth 633
+configure wave -valuecolwidth 184
+configure wave -justifyvalue left
+configure wave -signalnamewidth 0
+configure wave -snapdistance 10
+configure wave -datasetprefix 0
+configure wave -rowmargin 4
+configure wave -childrowmargin 2
+configure wave -gridoffset 0
+configure wave -gridperiod 1
+configure wave -griddelta 40
+configure wave -timeline 0
+configure wave -timelineunits ns
+update
+WaveRestoreZoom {1974303474 ps} {1974374671 ps}
diff --git a/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/axi_wrapper_tb.v b/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/axi_wrapper_tb.v
new file mode 100644
index 000000000..7a15d1d86
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/axi_wrapper_tb.v
@@ -0,0 +1,144 @@
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module axi_wrapper_tb();
+
+ xlnx_glbl glbl (.GSR(),.GTS());
+
+ localparam STR_SINK_FIFOSIZE = 9;
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("axi_wrapper_tb.vcd");
+ initial $dumpvars(0,axi_wrapper_tb);
+
+ initial #1000000 $finish;
+
+ wire [31:0] set_data;
+ wire [7:0] set_addr;
+ wire set_stb;
+
+ wire [63:0] noci_tdata[PORTS-1:0];
+ wire noci_tlast[PORTS-1:0];
+ wire noci_tvalid[PORTS-1:0];
+ wire noci_tready[PORTS-1:0];
+
+ wire [63:0] noco_tdata[PORTS-1:0];
+ wire noco_tlast[PORTS-1:0];
+ wire noco_tvalid[PORTS-1:0];
+ wire noco_tready[PORTS-1:0];
+
+ reg [63:0] src_tdata;
+ reg src_tlast, src_tvalid;
+ wire src_tready;
+
+ localparam PORTS = 4;
+
+ wire [63:0] s1o_tdata, s1i_tdata;
+ wire s1o_tlast, s1i_tlast, s1o_tvalid, s1i_tvalid, s1o_tready, s1i_tready;
+
+ wire [31:0] pre_tdata, post_tdata;
+ wire pre_tlast, post_tlast, pre_tvalid, post_tvalid, pre_tready, post_tready;
+ wire [127:0] pre_tuser, post_tuser;
+
+ axi_wrapper #(.BASE(8), .NUM_AXI_CONFIG_BUS(1), .CONFIG_BUS_FIFO_DEPTH(5), .SIMPLE_MODE(1)) axi_wrapper_ce1
+ (.clk(clk), .reset(reset),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .i_tdata(src_tdata), .i_tlast(src_tlast), .i_tvalid(src_tvalid), .i_tready(src_tready),
+ .o_tdata(s1i_tdata), .o_tlast(s1i_tlast), .o_tvalid(s1i_tvalid), .o_tready(s1i_tready),
+ .m_axis_data_tdata(pre_tdata),
+ .m_axis_data_tuser(pre_tuser),
+ .m_axis_data_tlast(pre_tlast),
+ .m_axis_data_tvalid(pre_tvalid),
+ .m_axis_data_tready(pre_tready),
+ .s_axis_data_tdata(post_tdata),
+ .s_axis_data_tuser(post_tuser),
+ .s_axis_data_tlast(post_tlast),
+ .s_axis_data_tvalid(post_tvalid),
+ .s_axis_data_tready(post_tready)
+ );
+
+ axi_fifo #(.WIDTH(33)) afifo
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({pre_tlast,pre_tdata}), .i_tvalid(pre_tvalid), .i_tready(pre_tready),
+ .o_tdata({post_tlast,post_tdata}), .o_tvalid(post_tvalid), .o_tready(post_tready));
+
+ assign s1i_tready = 1'b1;
+
+
+ task SendPacket;
+ input [3:0] flags;
+ input [11:0] seqnum;
+ input [15:0] len;
+ input [31:0] sid;
+ input [63:0] data;
+
+ begin
+ @(posedge clk);
+ src_tdata <= { flags, seqnum, len+16'd8 + (flags[1] ? 16'd8 : 16'd0), sid };
+ src_tlast <= 0;
+ src_tvalid <= 1;
+ @(posedge clk);
+ while(~src_tready)
+ @(posedge clk);
+
+ // send time if flags request it
+ if(flags[1])
+ begin
+ src_tdata <= 64'h0123_4567_89ab_cdef;
+ src_tlast <= 0;
+ src_tvalid <= 1;
+ @(posedge clk);
+ while(~src_tready)
+ @(posedge clk);
+ end
+
+ src_tdata <= data;
+ repeat(len[15:3] + (len[2]|len[1]|len[0])- 1 )
+ begin
+ @(posedge clk);
+ while(~src_tready)
+ @(posedge clk);
+ src_tdata <= src_tdata + 64'd1;
+ end
+ src_tlast <= 1;
+ @(posedge clk);
+ while(~src_tready)
+ @(posedge clk);
+ src_tvalid <= 0;
+ @(posedge clk);
+ end
+ endtask // SendPacket
+
+ initial
+ begin
+ src_tdata <= 64'd0;
+ src_tlast <= 1'b0;
+ src_tvalid <= 1'b0;
+ @(negedge reset);
+ @(posedge clk);
+
+ @(posedge clk);
+
+ #10000;
+ SendPacket(4'h0, 12'd7, 16'd64, 32'h0002_0003, 64'hAAAA_AAAA_0000_0000); // data packet
+ SendPacket(4'h0, 12'd8, 16'd68, 32'h0004_0005, 64'hBBBB_BBBB_0000_0000); // data packet
+ //SendPacket(4'h0, 12'd2, 16'd8, 32'h0000_0001, 64'hCCCC_CCCC_0000_0000); // data packet
+ //SendPacket(4'h0, 12'd3, 16'd8, 32'h0000_0001, 64'hDDDD_DDDD_0000_0000); // data packet
+ //SendPacket(4'h0, 12'd4, 16'd8, 32'h0000_0001, 64'hEEEE_EEEE_0000_0000); // data packet
+ //SendPacket(4'h0, 12'd5, 16'd8, 32'h0000_0001, 64'hFFFF_FFFF_0000_0000); // data packet
+ //SendPacket(4'h0, 12'd6, 16'd8, 32'h0000_0001, 64'h2222_2222_0000_0000); // data packet
+ end
+
+endmodule // axi_wrapper_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/build_axi_wrapper_tb b/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/build_axi_wrapper_tb
new file mode 100755
index 000000000..49b8fe312
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/axi_wrapper/build_axi_wrapper_tb
@@ -0,0 +1 @@
+iverilog -o axi_wrapper_tb axi_wrapper_tb.v -y . -y ../control/ -y ../fifo/ -y /opt/Xilinx/14.6/ISE_DS/ISE/verilog/src/unisims/ -y ../packet_proc/ -y ../timing/ -y ../vita/ -y ../../top/x300/coregen -y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/XilinxCoreLib -y ../coregen/ -y ../ -y ../../../usrp2/models/ -Wall
diff --git a/fpga/usrp3/lib/sim/rfnoc/chdr_deframer/chdr_deframer_tb.v b/fpga/usrp3/lib/sim/rfnoc/chdr_deframer/chdr_deframer_tb.v
new file mode 100644
index 000000000..312ca478d
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/chdr_deframer/chdr_deframer_tb.v
@@ -0,0 +1,87 @@
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+//`timescale 1ns
+module chdr_deframer_tb();
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial $dumpfile("chdr_deframer_tb.vcd");
+ initial $dumpvars(0,chdr_deframer_tb);
+
+ reg [63:0] i_tdata;
+ reg i_tlast, i_tvalid;
+ wire i_tready;
+
+ wire [31:0] o_tdata;
+ wire [127:0] o_tuser;
+ wire o_tlast, o_tvalid;
+
+ reg o_tready = 1;
+
+ wire [63:0] int_tdata;
+ wire int_tlast, int_tvalid, int_tready;
+
+ axi_fifo #(.SIZE(10), .WIDTH(65)) fifo
+ (.clk(clk), .reset(reset), .clear(0),
+ .i_tdata({i_tlast, i_tdata}), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata({int_tlast, int_tdata}), .o_tvalid(int_tvalid), .o_tready(int_tready));
+
+ chdr_deframer chdr_deframer
+ (.clk(clk), .reset(reset), .clear(0),
+ .i_tdata(int_tdata), .i_tlast(int_tlast), .i_tvalid(int_tvalid), .i_tready(int_tready),
+ .o_tdata(o_tdata), .o_tuser(o_tuser), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
+
+ reg [63:0] hdr, vtime, data;
+
+ initial
+ begin
+ clk = 0;
+ reset = 1;
+ i_tlast = 0;
+ i_tvalid = 0;
+ hdr = 64'hFF00_AAB9_BEEF_0000;
+ vtime = 64'h8888_7777_6666_0000;
+ data = 64'hEEEE_0000_FFFF_0001;
+ #1000 reset = 0;
+ repeat (10)
+ @(posedge clk);
+ repeat (6)
+ begin
+ #1 i_tdata = hdr;
+ #1 i_tlast = 0;
+ #1 i_tvalid = 1;
+ @(posedge clk);
+ #1 i_tdata = vtime;
+ @(posedge clk);
+ #1 hdr = hdr + 1;
+ #1 vtime = vtime + 1;
+ repeat (10)
+ begin
+ #1 i_tdata = data;
+ #1 data = data + 64'h0000_0002_0000_0002;
+ @(posedge clk);
+ end
+ #1 i_tdata = data;
+ #1 data = data + 64'h0000_0002_0000_0002;
+ #1 i_tlast <= 1;
+ @(posedge clk);
+ end // repeat (20)
+ #1 i_tvalid <= 0;
+ #200000 $finish;
+ end
+
+ always @(posedge clk)
+ if(o_tvalid & o_tready)
+ if(o_tlast)
+ $display("%x LAST",o_tdata);
+ else
+ $display("%x",o_tdata);
+
+endmodule // chdr_deframer_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/chdr_framer/chdr_framer_tb.v b/fpga/usrp3/lib/sim/rfnoc/chdr_framer/chdr_framer_tb.v
new file mode 100644
index 000000000..71b507e35
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/chdr_framer/chdr_framer_tb.v
@@ -0,0 +1,80 @@
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+//`timescale 1ns
+module chdr_framer_tb();
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial $dumpfile("chdr_framer_tb.vcd");
+ initial $dumpvars(0,chdr_framer_tb);
+
+ reg [31:0] i_tdata;
+ reg [127:0] i_tuser;
+ reg i_tlast, i_tvalid;
+ wire i_tready;
+
+ wire [63:0] o_tdata;
+ wire o_tlast, o_tvalid;
+
+ reg o_tready = 0;
+
+ chdr_framer #(.SIZE(10)) chdr_framer
+ (.clk(clk), .reset(reset), .clear(0),
+ .i_tdata(i_tdata), .i_tuser(i_tuser), .i_tlast(i_tlast), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready));
+
+ always
+ begin
+ #1 o_tready = 1;
+ repeat (200)
+ @(posedge clk);
+ #1 o_tready = 0;
+ repeat (120)
+ @(posedge clk);
+ end
+
+
+ initial
+ begin
+ clk = 0;
+ reset = 1;
+ i_tlast = 0;
+ i_tvalid = 0;
+ i_tdata = 32'hBEEF_0000;
+ i_tuser = 128'hF123_4567_89ab_cdef_0011_2233_4455_0000;
+ #1000 reset = 0;
+ repeat (10)
+ @(posedge clk);
+ #1 i_tvalid = 1;
+ repeat (400)
+ begin
+ #1 i_tlast = 0;
+ repeat (22)
+ begin
+ #1 i_tdata = i_tdata + 1;
+ @(posedge clk);
+ end
+ #1 i_tdata = i_tdata + 1;
+ #1 i_tlast = 1;
+ @(posedge clk);
+ #1 i_tuser <= i_tuser + 1;
+ end // repeat (20)
+ #1 i_tvalid <= 0;
+ #100000 $finish;
+ end
+
+ always @(posedge clk)
+ if(o_tvalid & o_tready)
+ if(o_tlast)
+ $display("%x LAST",o_tdata);
+ else
+ $display("%x",o_tdata);
+
+endmodule // chdr_framer_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/display_samples.grc b/fpga/usrp3/lib/sim/rfnoc/display_samples.grc
new file mode 100644
index 000000000..d900da4cc
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/display_samples.grc
@@ -0,0 +1,413 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Wed May 28 15:07:06 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>top_block</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>wx_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 170)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_interleaved_short_to_complex</key>
+ <param>
+ <key>id</key>
+ <value>blocks_interleaved_short_to_complex_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vector_input</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(296, 296)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
+ <param>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ignoretag</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(524, 220)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_source</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_source_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>output.dat</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>short</value>
+ </param>
+ <param>
+ <key>repeat</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(165, 203)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_fftsink2_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>FFT Plot</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ref_scale</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>win</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>freqvar</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(751, 242)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_scopesink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_scopesink2_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>Scope Plot</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>v_scale</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>v_offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>t_scale</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ac_couple</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>xy_mode</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>num_inputs</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>trig_mode</key>
+ <value>wxgui.TRIG_MODE_AUTO</value>
+ </param>
+ <param>
+ <key>y_axis_label</key>
+ <value>Counts</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(750, 134)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>blocks_file_source_0</source_block_id>
+ <sink_block_id>blocks_interleaved_short_to_complex_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_interleaved_short_to_complex_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>wxgui_scopesink2_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/fpga/usrp3/lib/sim/rfnoc/gen_samples.grc b/fpga/usrp3/lib/sim/rfnoc/gen_samples.grc
new file mode 100644
index 000000000..568c538ba
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/gen_samples.grc
@@ -0,0 +1,381 @@
+<?xml version='1.0' encoding='ASCII'?>
+<flow_graph>
+ <timestamp>Wed May 28 15:55:45 2014</timestamp>
+ <block>
+ <key>options</key>
+ <param>
+ <key>id</key>
+ <value>top_block</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value></value>
+ </param>
+ <param>
+ <key>author</key>
+ <value></value>
+ </param>
+ <param>
+ <key>description</key>
+ <value></value>
+ </param>
+ <param>
+ <key>window_size</key>
+ <value>1280, 1024</value>
+ </param>
+ <param>
+ <key>generate_options</key>
+ <value>wx_gui</value>
+ </param>
+ <param>
+ <key>category</key>
+ <value>Custom</value>
+ </param>
+ <param>
+ <key>run_options</key>
+ <value>prompt</value>
+ </param>
+ <param>
+ <key>run</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>max_nouts</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>realtime_scheduling</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 10)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>variable</key>
+ <param>
+ <key>id</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>value</key>
+ <value>32000</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(10, 170)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_complex_to_interleaved_short</key>
+ <param>
+ <key>id</key>
+ <value>blocks_complex_to_interleaved_short_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(631, 265)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_file_sink</key>
+ <param>
+ <key>id</key>
+ <value>blocks_file_sink_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>file</key>
+ <value>test.dat</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>short</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>unbuffered</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>append</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(769, 142)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>wxgui_fftsink2</key>
+ <param>
+ <key>id</key>
+ <value>wxgui_fftsink2_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>title</key>
+ <value>FFT Plot</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>baseband_freq</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>y_per_div</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>y_divs</key>
+ <value>10</value>
+ </param>
+ <param>
+ <key>ref_level</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>ref_scale</key>
+ <value>2.0</value>
+ </param>
+ <param>
+ <key>fft_size</key>
+ <value>1024</value>
+ </param>
+ <param>
+ <key>fft_rate</key>
+ <value>15</value>
+ </param>
+ <param>
+ <key>peak_hold</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>average</key>
+ <value>False</value>
+ </param>
+ <param>
+ <key>avg_alpha</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>win</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>win_size</key>
+ <value></value>
+ </param>
+ <param>
+ <key>grid_pos</key>
+ <value></value>
+ </param>
+ <param>
+ <key>notebook</key>
+ <value></value>
+ </param>
+ <param>
+ <key>freqvar</key>
+ <value>None</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(626, 319)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>blocks_throttle</key>
+ <param>
+ <key>id</key>
+ <value>blocks_throttle_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samples_per_second</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>vlen</key>
+ <value>1</value>
+ </param>
+ <param>
+ <key>ignoretag</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(433, 164)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <block>
+ <key>analog_sig_source_x</key>
+ <param>
+ <key>id</key>
+ <value>analog_sig_source_x_0</value>
+ </param>
+ <param>
+ <key>_enabled</key>
+ <value>True</value>
+ </param>
+ <param>
+ <key>type</key>
+ <value>complex</value>
+ </param>
+ <param>
+ <key>samp_rate</key>
+ <value>samp_rate</value>
+ </param>
+ <param>
+ <key>waveform</key>
+ <value>analog.GR_COS_WAVE</value>
+ </param>
+ <param>
+ <key>freq</key>
+ <value>123.2435</value>
+ </param>
+ <param>
+ <key>amp</key>
+ <value>32000</value>
+ </param>
+ <param>
+ <key>offset</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>affinity</key>
+ <value></value>
+ </param>
+ <param>
+ <key>minoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>maxoutbuf</key>
+ <value>0</value>
+ </param>
+ <param>
+ <key>_coordinate</key>
+ <value>(218, 177)</value>
+ </param>
+ <param>
+ <key>_rotation</key>
+ <value>0</value>
+ </param>
+ </block>
+ <connection>
+ <source_block_id>analog_sig_source_x_0</source_block_id>
+ <sink_block_id>blocks_throttle_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>blocks_complex_to_interleaved_short_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_complex_to_interleaved_short_0</source_block_id>
+ <sink_block_id>blocks_file_sink_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+ <connection>
+ <source_block_id>blocks_throttle_0</source_block_id>
+ <sink_block_id>wxgui_fftsink2_0</sink_block_id>
+ <source_key>0</source_key>
+ <sink_key>0</sink_key>
+ </connection>
+</flow_graph>
diff --git a/fpga/usrp3/lib/sim/rfnoc/moving_sum/build_moving_sum_tb b/fpga/usrp3/lib/sim/rfnoc/moving_sum/build_moving_sum_tb
new file mode 100755
index 000000000..f7fd1e9c7
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/moving_sum/build_moving_sum_tb
@@ -0,0 +1 @@
+iverilog -o moving_sum_tb -y . -y ../control/ -y ../fifo/ moving_sum_tb.v -y /opt/Xilinx/14.4/ISE_DS/ISE/verilog/src/unisims/ -Wall
diff --git a/fpga/usrp3/lib/sim/rfnoc/moving_sum/moving_sum_tb.v b/fpga/usrp3/lib/sim/rfnoc/moving_sum/moving_sum_tb.v
new file mode 100644
index 000000000..4ce455af5
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/moving_sum/moving_sum_tb.v
@@ -0,0 +1,43 @@
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module moving_sum_tb();
+
+ //xlnx_glbl glbl (.GSR(),.GTS());
+
+ localparam STR_SINK_FIFOSIZE = 9;
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("moving_sum_tb.vcd");
+ initial $dumpvars(0,moving_sum_tb);
+
+ initial #1000000 $finish;
+
+ wire [15:0] i_tdata;
+ wire [25:0] o_tdata;
+ wire i_tvalid, i_tready, o_tvalid, o_tready;
+
+ moving_sum #(.MAX_LEN_LOG2(10), .WIDTH(16)) moving_sum
+ (.clk(clk), .reset(reset), .clear(0),
+ .len(20),
+ .i_tdata(i_tdata), .i_tlast(), .i_tvalid(i_tvalid), .i_tready(i_tready),
+ .o_tdata(o_tdata), .o_tlast(), .o_tvalid(o_tvalid), .o_tready(o_tready));
+
+ assign i_tdata = 1;
+ assign i_tvalid = 1;
+ assign o_tready = 1;
+
+
+endmodule // moving_sum_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/mult/mult_tb.v b/fpga/usrp3/lib/sim/rfnoc/mult/mult_tb.v
new file mode 100644
index 000000000..32b0d47fd
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/mult/mult_tb.v
@@ -0,0 +1,75 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module mult_tb();
+
+ xlnx_glbl glbl (.GSR(),.GTS());
+
+ localparam STR_SINK_FIFOSIZE = 9;
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("mult_tb.vcd");
+ initial $dumpvars(0,mult_tb);
+
+ initial #1000000 $finish;
+
+ localparam AW=25;
+ localparam BW=18;
+ localparam PW=48;
+
+ wire [AW-1:0] a_tdata;
+ wire [BW-1:0] b_tdata;
+ wire [PW-1:0] p_tdata;
+
+ wire a_tlast, a_tvalid, a_tready, b_tlast, b_tvalid, b_tready;
+ wire p_tlast, p_tvalid;
+ reg p_tready = 0;
+
+ reg ai_tvalid = 0;
+ reg bi_tvalid = 0;
+
+ counter #(.WIDTH(AW)) ca
+ (.clk(clk), .reset(reset), .clear(0),
+ .max(20),
+ .i_tlast(0), .i_tvalid(ai_tvalid), .i_tready(),
+ .o_tdata(a_tdata), .o_tlast(a_tlast), .o_tvalid(a_tvalid), .o_tready(a_tready));
+
+ counter #(.WIDTH(BW)) cb
+ (.clk(clk), .reset(reset), .clear(0),
+ .max(20),
+ .i_tlast(0), .i_tvalid(bi_tvalid), .i_tready(),
+ .o_tdata(b_tdata), .o_tlast(b_tlast), .o_tvalid(b_tvalid), .o_tready(b_tready));
+
+ mult #(.WIDTH_A(AW), .WIDTH_B(BW), .WIDTH_P(PW), .LATENCY(4)) mult
+ (.clk(clk), .reset(reset),
+ .a_tdata(a_tdata), .a_tlast(a_tlast), .a_tvalid(a_tvalid), .a_tready(a_tready),
+ .b_tdata(b_tdata), .b_tlast(b_tlast), .b_tvalid(b_tvalid), .b_tready(b_tready),
+ .p_tdata(p_tdata), .p_tlast(p_tlast), .p_tvalid(p_tvalid), .p_tready(p_tready));
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (100)
+ @(posedge clk);
+ ai_tvalid <= 1;
+ repeat (10)
+ @(posedge clk);
+ bi_tvalid <= 1;
+ repeat (10)
+ @(posedge clk);
+ p_tready <= 1;
+ end
+
+endmodule // mult_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/mult_add/mult_add_tb.v b/fpga/usrp3/lib/sim/rfnoc/mult_add/mult_add_tb.v
new file mode 100644
index 000000000..23e772aba
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/mult_add/mult_add_tb.v
@@ -0,0 +1,90 @@
+//
+// Copyright 2014 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module mult_add_tb();
+
+ xlnx_glbl glbl (.GSR(),.GTS());
+
+ localparam STR_SINK_FIFOSIZE = 9;
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("mult_add_tb.vcd");
+ initial $dumpvars(0,mult_add_tb);
+
+ initial #1000000 $finish;
+
+ localparam AW=25;
+ localparam BW=18;
+ localparam PW=48;
+
+ wire [AW-1:0] a_tdata;
+ wire [BW-1:0] b_tdata;
+ wire [PW-1:0] pin_tdata;
+ wire [PW-1:0] pout_tdata;
+
+ wire a_tlast, a_tvalid, a_tready, b_tlast, b_tvalid, b_tready;
+ wire pin_tlast, pin_tvalid;
+ wire pout_tlast, pout_tvalid;
+ wire pin_tready;
+ reg pout_tready = 0;
+
+ reg ai_tvalid = 0;
+ reg bi_tvalid = 0;
+ reg pi_tvalid = 0;
+
+ counter #(.WIDTH(AW)) ca
+ (.clk(clk), .reset(reset), .clear(0),
+ .max(25'd20),
+ .i_tlast(0), .i_tvalid(ai_tvalid), .i_tready(),
+ .o_tdata(a_tdata), .o_tlast(a_tlast), .o_tvalid(a_tvalid), .o_tready(a_tready));
+
+ counter #(.WIDTH(BW)) cb
+ (.clk(clk), .reset(reset), .clear(0),
+ .max(18'd20),
+ .i_tlast(0), .i_tvalid(bi_tvalid), .i_tready(),
+ .o_tdata(b_tdata), .o_tlast(b_tlast), .o_tvalid(b_tvalid), .o_tready(b_tready));
+
+ counter #(.WIDTH(PW)) cp
+ (.clk(clk), .reset(reset), .clear(0),
+ .max(48'd20),
+ .i_tlast(0), .i_tvalid(pi_tvalid), .i_tready(),
+ .o_tdata(pin_tdata), .o_tlast(pin_tlast), .o_tvalid(pin_tvalid), .o_tready(pin_tready));
+
+ mult_add #(.WIDTH_A(AW), .WIDTH_B(BW), .WIDTH_P(PW),
+ .LATENCY(3), .CASCADE_IN(1), .CASCADE_OUT(1)) mult_add
+ (.clk(clk), .reset(reset),
+ .a_tdata(a_tdata), .a_tlast(a_tlast), .a_tvalid(a_tvalid), .a_tready(a_tready),
+ .b_tdata(b_tdata), .b_tlast(b_tlast), .b_tvalid(b_tvalid), .b_tready(b_tready),
+ .c_tdata(pin_tdata), .c_tlast(pin_tlast), .c_tvalid(pin_tvalid), .c_tready(pin_tready),
+ .p_tdata(pout_tdata), .p_tlast(pout_tlast), .p_tvalid(pout_tvalid), .p_tready(pout_tready));
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (100)
+ @(posedge clk);
+ ai_tvalid <= 1;
+ repeat (10)
+ @(posedge clk);
+ bi_tvalid <= 1;
+ repeat (10)
+ @(posedge clk);
+ pi_tvalid <= 1;
+ repeat (10)
+ @(posedge clk);
+ pout_tready <= 1;
+ end
+
+endmodule // mult_add_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/null_source/null_source_tb.v b/fpga/usrp3/lib/sim/rfnoc/null_source/null_source_tb.v
new file mode 100644
index 000000000..c9cf29111
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/null_source/null_source_tb.v
@@ -0,0 +1,80 @@
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module null_source_tb();
+
+ reg clk, reset;
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("null_source_tb.vcd");
+ initial $dumpvars(0,null_source_tb);
+
+ //initial #10000000 $finish;
+
+ reg [31:0] set_data;
+ reg [7:0] set_addr;
+ reg set_stb=0;
+
+ wire [63:0] src_tdata;
+ wire src_tlast, src_tvalid;
+ wire src_tready;
+
+ assign src_tready = 1'b1;
+
+ localparam PORTS = 4;
+
+ null_source #(.BASE(0)) axi_wrapper_ce1
+ (.clk(clk), .reset(reset),
+ .set_stb(set_stb), .set_addr(set_addr), .set_data(set_data),
+ .o_tdata(src_tdata), .o_tlast(src_tlast), .o_tvalid(src_tvalid), .o_tready(src_tready) );
+
+ initial
+ begin
+
+ @(negedge reset);
+ @(posedge clk);
+ #100000;
+ @(posedge clk);
+ set_stb <= 1;
+ set_addr <= 0;
+ set_data <= 32'hDEADBEEF;
+ @(posedge clk);
+ set_stb <= 1;
+ set_addr <= 1; // Len
+ set_data <= 32'h8;
+ @(posedge clk);
+ set_stb <= 1;
+ set_addr <= 2;
+ set_data <= 32'h20; // Rate
+ @(posedge clk);
+ set_stb <= 1;
+ set_addr <= 3;
+ set_data <= 1; // enable
+ @(posedge clk);
+ set_stb <= 0;
+ @(posedge clk);
+ #1000000;
+ @(posedge clk);
+ set_stb <= 1;
+ set_addr <= 3;
+ set_data <= 0; // disable
+ @(posedge clk);
+ set_stb <= 0;
+ #1000000;
+
+ $finish;
+
+
+ end
+
+endmodule // null_source_tb
diff --git a/fpga/usrp3/lib/sim/rfnoc/window/build_window_tb b/fpga/usrp3/lib/sim/rfnoc/window/build_window_tb
new file mode 100755
index 000000000..1af299fd4
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/window/build_window_tb
@@ -0,0 +1 @@
+iverilog -o window_tb window_tb.v -y ../coregen -y ../../../usrp2/models -y . -y ../control/ -y ../fifo/ -y /opt/Xilinx/14.6/ISE_DS/ISE/verilog/src/unisims/ -y ../packet_proc/ -y ../timing/ -y ../vita/
diff --git a/fpga/usrp3/lib/sim/rfnoc/window/window_tb.v b/fpga/usrp3/lib/sim/rfnoc/window/window_tb.v
new file mode 100644
index 000000000..2449057c8
--- /dev/null
+++ b/fpga/usrp3/lib/sim/rfnoc/window/window_tb.v
@@ -0,0 +1,341 @@
+`timescale 1ns/1ps
+
+//
+// Copyright 2012-2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+module window_tb();
+ xlnx_glbl glbl (.GSR(),.GTS());
+
+ localparam STR_SINK_FIFOSIZE = 11;
+
+ reg clk, reset;
+
+ localparam PORTS = 5;
+
+ wire [63:0] noci_tdata[PORTS-1:0];
+ wire [PORTS-1:0] noci_tlast;
+ wire [PORTS-1:0] noci_tvalid;
+ wire [PORTS-1:0] noci_tready;
+
+ wire [63:0] noco_tdata[PORTS-1:0];
+ wire [PORTS-1:0] noco_tlast;
+ wire [PORTS-1:0] noco_tvalid;
+ wire [PORTS-1:0] noco_tready;
+
+ wire [63:0] src_tdata;
+ wire src_tlast, src_tvalid;
+ wire src_tready;
+
+ reg [63:0] cmdout_tdata;
+ reg cmdout_tlast, cmdout_tvalid;
+ wire cmdout_tready;
+
+ wire [63:0] dst_tdata;
+ wire dst_tlast, dst_tvalid;
+ wire dst_tready = 1;
+
+ reg set_stb_xbar;
+ reg [15:0] set_addr_xbar;
+ reg [31:0] set_data_xbar;
+
+ always
+ #100 clk = ~clk;
+
+ initial clk = 0;
+ initial reset = 1;
+ initial #1000 reset = 0;
+
+ initial $dumpfile("window_tb.vcd");
+ initial $dumpvars(0,window_tb);
+
+ initial #3000000 $finish;
+
+
+ axi_crossbar #(.FIFO_WIDTH(64), .DST_WIDTH(16), .NUM_INPUTS(PORTS), .NUM_OUTPUTS(PORTS)) crossbar
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .local_addr(8'd0),
+ .pkt_present({noci_tvalid[4],noci_tvalid[3],noci_tvalid[2],noci_tvalid[1],noci_tvalid[0]}),
+
+ .i_tdata({noci_tdata[4],noci_tdata[3],noci_tdata[2],noci_tdata[1],noci_tdata[0]}),
+ .i_tlast({noci_tlast[4],noci_tlast[3],noci_tlast[2],noci_tlast[1],noci_tlast[0]}),
+ .i_tvalid({noci_tvalid[4],noci_tvalid[3],noci_tvalid[2],noci_tvalid[1],noci_tvalid[0]}),
+ .i_tready({noci_tready[4],noci_tready[3],noci_tready[2],noci_tready[1],noci_tready[0]}),
+
+ .o_tdata({noco_tdata[4],noco_tdata[3],noco_tdata[2],noco_tdata[1],noco_tdata[0]}),
+ .o_tlast({noco_tlast[4],noco_tlast[3],noco_tlast[2],noco_tlast[1],noco_tlast[0]}),
+ .o_tvalid({noco_tvalid[4],noco_tvalid[3],noco_tvalid[2],noco_tvalid[1],noco_tvalid[0]}),
+ .o_tready({noco_tready[4],noco_tready[3],noco_tready[2],noco_tready[1],noco_tready[0]}),
+
+ .set_stb(set_stb_xbar), .set_addr(set_addr_xbar), .set_data(set_data_xbar),
+ .rb_rd_stb(1'b0), .rb_addr(4'd0), .rb_data());
+
+ // Generator on port 0
+ wire set_stb_0;
+ wire [7:0] set_addr_0;
+ wire [31:0] set_data_0;
+
+ noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_0
+ (.bus_clk(clk), .bus_rst(reset),
+ .i_tdata(noco_tdata[0]), .i_tlast(noco_tlast[0]), .i_tvalid(noco_tvalid[0]), .i_tready(noco_tready[0]),
+ .o_tdata(noci_tdata[0]), .o_tlast(noci_tlast[0]), .o_tvalid(noci_tvalid[0]), .o_tready(noci_tready[0]),
+ .clk(clk), .reset(reset),
+ .set_data(set_data_0), .set_addr(set_addr_0), .set_stb(set_stb_0), .rb_data(64'd0),
+
+ .cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
+ .ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
+
+ .str_sink_tdata(), .str_sink_tlast(), .str_sink_tvalid(), .str_sink_tready(1'b1), // unused port
+ .str_src_tdata(src_tdata), .str_src_tlast(src_tlast), .str_src_tvalid(src_tvalid), .str_src_tready(src_tready)
+ );
+
+ file_source #(.BASE(8), .FILENAME("test.dat")) file_source
+ (.clk(clk), .reset(reset),
+ .set_data(set_data_0), .set_addr(set_addr_0), .set_stb(set_stb_0),
+ .o_tdata(src_tdata), .o_tlast(src_tlast), .o_tvalid(src_tvalid), .o_tready(src_tready));
+
+ // Simple FIR on port 1
+ wire [31:0] set_data_1;
+ wire [7:0] set_addr_1;
+ wire set_stb_1;
+ wire [63:0] s1o_tdata, s1i_tdata;
+ wire s1o_tlast, s1i_tlast, s1o_tvalid, s1i_tvalid, s1o_tready, s1i_tready;
+
+ wire [31:0] pre_tdata, post_tdata;
+ wire pre_tlast, pre_tvalid, pre_tready;
+ wire post_tlast, post_tvalid, post_tready;
+
+ wire [15:0] pre_i = pre_tdata[31:16];
+ wire [15:0] pre_q = pre_tdata[15:0];
+ wire [15:0] post_i = post_tdata[31:16];
+ wire [15:0] post_q = post_tdata[15:0];
+
+ noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_1
+ (.bus_clk(clk), .bus_rst(reset),
+ .i_tdata(noco_tdata[1]), .i_tlast(noco_tlast[1]), .i_tvalid(noco_tvalid[1]), .i_tready(noco_tready[1]),
+ .o_tdata(noci_tdata[1]), .o_tlast(noci_tlast[1]), .o_tvalid(noci_tvalid[1]), .o_tready(noci_tready[1]),
+ .clk(clk), .reset(reset),
+ .set_data(set_data_1), .set_addr(set_addr_1), .set_stb(set_stb_1), .rb_data(64'd0),
+
+ .cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
+ .ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
+
+ .str_sink_tdata(s1o_tdata), .str_sink_tlast(s1o_tlast), .str_sink_tvalid(s1o_tvalid), .str_sink_tready(s1o_tready),
+ .str_src_tdata(s1i_tdata), .str_src_tlast(s1i_tlast), .str_src_tvalid(s1i_tvalid), .str_src_tready(s1i_tready)
+ );
+
+ wire [31:0] axis_config_tdata1;
+ wire axis_config_tvalid1, axis_config_tready1, axis_config_tlast1;
+
+ axi_wrapper #(.BASE(8)) axi_wrapper_ce1
+ (.clk(clk), .reset(reset),
+ .set_stb(set_stb_1), .set_addr(set_addr_1), .set_data(set_data_1),
+ .i_tdata(s1o_tdata), .i_tlast(s1o_tlast), .i_tvalid(s1o_tvalid), .i_tready(s1o_tready),
+ .o_tdata(s1i_tdata), .o_tlast(s1i_tlast), .o_tvalid(s1i_tvalid), .o_tready(s1i_tready),
+ .m_axis_data_tdata(pre_tdata),
+ .m_axis_data_tlast(pre_tlast),
+ .m_axis_data_tvalid(pre_tvalid),
+ .m_axis_data_tready(pre_tready),
+ .s_axis_data_tdata(post_tdata),
+ .s_axis_data_tlast(post_tlast),
+ .s_axis_data_tvalid(post_tvalid),
+ .s_axis_data_tready(post_tready),
+ .m_axis_config_tdata(axis_config_tdata1),
+ .m_axis_config_tlast(axis_config_tlast1),
+ .m_axis_config_tvalid(axis_config_tvalid1),
+ .m_axis_config_tready(axis_config_tready1)
+ );
+
+ window #(.BASE(0)) window
+ (.clk(clk), .reset(reset), .clear(clear),
+ .set_stb(set_stb_1), .set_addr(set_addr_1), .set_data(set_data_1),
+ .i_tdata(pre_tdata), .i_tlast(pre_tlast), .i_tvalid(pre_tvalid), .i_tready(pre_tready),
+ .o_tdata(post_tdata), .o_tlast(post_tlast), .o_tvalid(post_tvalid), .o_tready(post_tready));
+
+ assign axis_config_tready1 = 1'b1;
+
+ // Dumper on port 2
+ noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_2
+ (.bus_clk(clk), .bus_rst(reset),
+ .i_tdata(noco_tdata[2]), .i_tlast(noco_tlast[2]), .i_tvalid(noco_tvalid[2]), .i_tready(noco_tready[2]),
+ .o_tdata(noci_tdata[2]), .o_tlast(noci_tlast[2]), .o_tvalid(noci_tvalid[2]), .o_tready(noci_tready[2]),
+
+ .clk(clk), .reset(reset),
+ .set_data(), .set_addr(), .set_stb(), .rb_data(64'd0),
+
+ .cmdout_tdata(64'h0), .cmdout_tlast(1'b0), .cmdout_tvalid(1'b0), .cmdout_tready(),
+ .ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
+
+ .str_sink_tdata(dst_tdata), .str_sink_tlast(dst_tlast), .str_sink_tvalid(dst_tvalid), .str_sink_tready(dst_tready),
+ .str_src_tdata(64'd0), .str_src_tlast(1'd0), .str_src_tvalid(1'b0), .str_src_tready() // unused port
+ );
+
+ // Control Source on port 3
+ noc_shell #(.STR_SINK_FIFOSIZE(STR_SINK_FIFOSIZE)) noc_shell_3
+ (.bus_clk(clk), .bus_rst(reset),
+ .i_tdata(noco_tdata[3]), .i_tlast(noco_tlast[3]), .i_tvalid(noco_tvalid[3]), .i_tready(noco_tready[3]),
+ .o_tdata(noci_tdata[3]), .o_tlast(noci_tlast[3]), .o_tvalid(noci_tvalid[3]), .o_tready(noci_tready[3]),
+
+ .clk(clk), .reset(reset),
+ .set_data(), .set_addr(), .set_stb(), .rb_data(64'd0),
+
+ .cmdout_tdata(cmdout_tdata), .cmdout_tlast(cmdout_tlast), .cmdout_tvalid(cmdout_tvalid), .cmdout_tready(cmdout_tready),
+ .ackin_tdata(), .ackin_tlast(), .ackin_tvalid(), .ackin_tready(1'b1),
+
+ .str_sink_tdata(), .str_sink_tlast(), .str_sink_tvalid(), .str_sink_tready(1'b1), // unused port
+ .str_src_tdata(64'd0), .str_src_tlast(1'd0), .str_src_tvalid(1'b0), .str_src_tready() // unused port
+ );
+
+ // ////////////////////////////////////////////////////////////////////////////////////
+
+ task SetXbar;
+ input [15:0] start_reg;
+ input [7:0] start_val;
+
+ begin
+ repeat (PORTS)
+ begin
+ repeat (1)
+ begin
+ SetXbar_reg(start_reg,start_val);
+ start_reg <= start_reg + 1;
+ @(posedge clk);
+ end
+ start_val <= start_val + 1;
+ @(posedge clk);
+ end
+ end
+ endtask // SetXbar
+
+ task SetXbar_reg;
+ input [15:0] addr;
+ input [31:0] data;
+ begin
+ @(posedge clk);
+ set_stb_xbar <= 1'b1;
+ set_addr_xbar <= addr;
+ set_data_xbar <= data;
+ @(posedge clk);
+ set_stb_xbar <= 1'b0;
+ @(posedge clk);
+ end
+ endtask // set_xbar
+
+ task SendCtrlPacket;
+ input [11:0] seqnum;
+ input [31:0] sid;
+ input [63:0] data;
+
+ begin
+ @(posedge clk);
+ cmdout_tdata <= { 4'h8, seqnum, 16'h16, sid };
+ cmdout_tlast <= 0;
+ cmdout_tvalid <= 1;
+ while(~cmdout_tready) #1;
+
+ @(posedge clk);
+ cmdout_tdata <= data;
+ cmdout_tlast <= 1;
+ while(~cmdout_tready) #1;
+
+ @(posedge clk);
+ cmdout_tvalid <= 0;
+ @(posedge clk);
+ end
+ endtask // SendCtrlPacket
+
+ initial
+ begin
+ cmdout_tdata <= 64'd0;
+ cmdout_tlast <= 1'b0;
+ cmdout_tvalid <= 1'b0;
+
+ @(negedge reset);
+ @(posedge clk);
+ SetXbar(256,0);
+
+ @(posedge clk);
+ // Port 0
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'h0, 32'h0000_0003}); // Command packet to set up source control window size
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'h8, 32'h0000_0001}); // Command packet to set up SID
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'hA, 32'h0000_0002}); // Command packet to set up Rate
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'hB, 32'h0000_0001}); // Command packet to set up send_time_field
+ SendCtrlPacket(12'd0, 32'h0003_0000, {32'h9, 32'h0000_0200}); // Command packet to set up Len
+ #10000;
+ // Port 1
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h0, 32'h0000_0013}); // Command packet to set up source control window size
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h8, 32'h0001_0002}); // Rewrite SID, send on to port 2
+
+
+ #10000;
+ // Port 2
+ SendCtrlPacket(12'd0, 32'h0003_0002, {32'h0, 32'h0000_0003}); // Command packet to set up source control window size
+ SendCtrlPacket(12'd0, 32'h0003_0002, {32'h1, 32'h0000_0001}); // Command packet to set up source control window enable
+ SendCtrlPacket(12'd0, 32'h0003_0002, {32'h3, 32'h8000_0001}); // Command packet to set up flow control
+
+ #1000000;
+ // WINDOW filter
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd0}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd1}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd2}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd3}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd4}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd5}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd6}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd7}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h11, 32'd8}); // frame_len (FFTsize)
+
+ #1000000;
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h10, 32'd100000}); // frame_len (FFTsize)
+ SendCtrlPacket(12'd0, 32'h0003_0001, {32'h11, 32'd100000}); // frame_len (FFTsize)
+
+ end
+
+ reg in_packet = 0;
+
+ integer outfile;
+
+ initial
+ begin
+ outfile = $fopen("output.dat","wb");
+ //src_tready <= 1'b1;
+ end
+
+ wire signed [15:0] a,b,c,d;
+ assign a = src_tdata[63:48];
+ assign b = src_tdata[47:32];
+ assign c = src_tdata[31:16];
+ assign d = src_tdata[15:0];
+
+ always @(posedge clk)
+ if(src_tready & src_tvalid)
+ begin
+ if(src_tlast)
+ in_packet <= 0;
+ else
+ in_packet <= 1;
+ if(in_packet)
+ begin
+ //$fwrite(outfile,"%u",{q_out[15:0],i_out[15:0]}); // Correct endianness for GR
+ //$write("%d,%d,%d,%d,",a,b,c,d);
+ $fwrite(outfile,"%u",{dst_tdata[47:32],dst_tdata[63:48]});
+ $fwrite(outfile,"%u",{dst_tdata[15:0],dst_tdata[31:16]});
+ end
+ end
+
+endmodule // window_tb
diff --git a/fpga/usrp3/lib/sim/simple_gemac/ll8_to_axi64/ll8_to_axi64_tb.v b/fpga/usrp3/lib/sim/simple_gemac/ll8_to_axi64/ll8_to_axi64_tb.v
new file mode 100644
index 000000000..ef10a7c9a
--- /dev/null
+++ b/fpga/usrp3/lib/sim/simple_gemac/ll8_to_axi64/ll8_to_axi64_tb.v
@@ -0,0 +1,100 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+`timescale 1ns/1ps
+
+module ll8_to_axi64_tb();
+
+ reg clk = 0;
+ reg reset = 1;
+
+ always #10 clk = ~clk;
+
+ initial $dumpfile("ll8_to_axi64_tb.vcd");
+ initial $dumpvars(0,ll8_to_axi64_tb);
+
+ initial
+ begin
+ #1000 reset = 0;
+ #2000000;
+ $finish;
+ end
+
+ wire [63:0] tdata, tdata_int;
+ wire [3:0] tuser, tuser_int;
+ wire tlast, tlast_int;
+ wire tvalid, tvalid_int, tready, tready_int;
+
+ reg [7:0] ll_data;
+ reg ll_eof, ll_error, ll_src_rdy;
+ wire ll_dst_rdy;
+
+ wire [7:0] ll_data2;
+ wire ll_eof2, ll_src_rdy2, ll_dst_rdy2;
+
+ localparam RPT_COUNT = 12;
+
+ initial
+ begin
+ ll_src_rdy <= 0;
+
+ while(reset)
+ @(posedge clk);
+
+ @(posedge clk);
+
+ {ll_error, ll_eof, ll_data} <= { 1'b0, 1'b0, 8'hA0 };
+ repeat(RPT_COUNT-1)
+ begin
+ ll_src_rdy <= 1;
+ @(posedge clk);
+ ll_data <= ll_data + 1;
+ end
+ ll_eof <= 1;
+ ll_data <= ll_data + 1;
+ @(posedge clk);
+
+ {ll_error, ll_eof, ll_data} <= { 1'b0, 1'b0, 8'hC0 };
+ repeat(RPT_COUNT-1)
+ begin
+ ll_src_rdy <= 1;
+ @(posedge clk);
+ ll_data <= ll_data + 1;
+ end
+ ll_eof <= 1; ll_error <= 1;
+ ll_data <= ll_data + 1;
+ @(posedge clk);
+ ll_src_rdy <= 1'b0;
+
+ end
+
+ ll8_to_axi64 #(.START_BYTE(6), .LABEL(8'h89)) ll8_to_axi64
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .ll_data(ll_data), .ll_eof(ll_eof), .ll_error(ll_error), .ll_src_rdy(ll_src_rdy), .ll_dst_rdy(ll_dst_rdy),
+ .axi64_tdata(tdata), .axi64_tlast(tlast), .axi64_tuser(tuser), .axi64_tvalid(tvalid), .axi64_tready(tready) );
+
+ axi_fifo_short #(.WIDTH(69)) axi_fifo_short
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .i_tdata({tlast,tuser,tdata}), .i_tvalid(tvalid), .i_tready(tready),
+ .o_tdata({tlast_int,tuser_int,tdata_int}), .o_tvalid(tvalid_int), .o_tready(tready_int));
+
+ axi64_to_ll8 #(.START_BYTE(6)) axi64_to_ll8
+ (.clk(clk), .reset(reset), .clear(1'b0),
+ .axi64_tdata(tdata_int), .axi64_tlast(tlast_int), .axi64_tuser(tuser_int), .axi64_tvalid(tvalid_int), .axi64_tready(tready_int),
+ .ll_data(ll_data2), .ll_eof(ll_eof2), .ll_src_rdy(ll_src_rdy2), .ll_dst_rdy(ll_dst_rdy2) );
+
+ /*
+ always @(posedge clk)
+ if(ll_src_rdy2 & ll_dst_rdy2)
+ $display("EOF %x\tDATA %x",ll_eof2, ll_data2);
+
+ */
+ assign ll_dst_rdy2 = 1;
+
+ always @(posedge clk)
+ if(tvalid_int & tready_int)
+ $display("TERR %x\tTUSER %x\tTLAST %x\tTDATA %x",tuser_int[3],tuser_int[2:0], tlast_int, tdata_int);
+
+endmodule // ll8_to_axi64_tb
diff --git a/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_tb.v b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_tb.v
new file mode 100644
index 000000000..c65db6c98
--- /dev/null
+++ b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_tb.v
@@ -0,0 +1,208 @@
+//
+// Copyright 2011 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+
+
+module simple_gemac_tb;
+`include "eth_tasks.v"
+
+ reg clk = 0;
+ reg reset = 1;
+
+ initial #1000 reset = 0;
+ always #50 clk = ~clk;
+
+ wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK;
+ wire [7:0] GMII_RXD, GMII_TXD;
+
+ wire rx_valid, rx_error, rx_ack;
+ wire tx_ack, tx_valid, tx_error;
+
+ wire [7:0] rx_data, tx_data;
+
+ reg [15:0] pause_time;
+ reg pause_req = 0;
+
+ wire GMII_RX_CLK = GMII_GTX_CLK;
+
+ reg [7:0] FORCE_DAT_ERR = 0;
+ reg FORCE_ERR = 0;
+
+ // Loopback
+ assign GMII_RX_DV = GMII_TX_EN;
+ assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR;
+ assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR;
+
+ wire [47:0] ucast_addr = 48'hF1F2_F3F4_F5F6;
+ wire [47:0] mcast_addr = 0;
+ wire pass_ucast =1, pass_mcast=0, pass_bcast=1, pass_pause=0, pass_all=0;
+
+ simple_gemac simple_gemac
+ (.clk125(clk), .reset(reset),
+ .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
+ .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
+ .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
+ .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
+ .pause_req(pause_req), .pause_time(pause_time), .pause_en(1),
+ .ucast_addr(ucast_addr), .mcast_addr(mcast_addr),
+ .pass_ucast(pass_ucast), .pass_mcast(pass_mcast), .pass_bcast(pass_bcast),
+ .pass_pause(pass_pause), .pass_all(pass_all),
+ .rx_clk(rx_clk), .rx_data(rx_data),
+ .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
+ .tx_clk(tx_clk), .tx_data(tx_data),
+ .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack)
+ );
+
+ wire rx_ll_sof, rx_ll_eof, rx_ll_src_rdy, rx_ll_dst_rdy;
+ wire rx_ll_sof2, rx_ll_eof2, rx_ll_src_rdy2;
+ reg rx_ll_dst_rdy2 = 1;
+ wire [7:0] rx_ll_data, rx_ll_data2;
+ wire rx_ll_error, rx_ll_error2;
+
+ rxmac_to_ll8 rx_adapt
+ (.clk(clk), .reset(reset), .clear(0),
+ .rx_data(rx_data), .rx_valid(rx_valid), .rx_error(rx_error), .rx_ack(rx_ack),
+ .ll_data(rx_ll_data), .ll_sof(rx_ll_sof), .ll_eof(rx_ll_eof), .ll_error(rx_ll_error),
+ .ll_src_rdy(rx_ll_src_rdy), .ll_dst_rdy(rx_ll_dst_rdy));
+
+ ll8_shortfifo rx_sfifo
+ (.clk(clk), .reset(reset), .clear(0),
+ .datain(rx_ll_data), .sof_i(rx_ll_sof), .eof_i(rx_ll_eof),
+ .error_i(rx_ll_error), .src_rdy_i(rx_ll_src_rdy), .dst_rdy_o(rx_ll_dst_rdy),
+ .dataout(rx_ll_data2), .sof_o(rx_ll_sof2), .eof_o(rx_ll_eof2),
+ .error_o(rx_ll_error2), .src_rdy_o(rx_ll_src_rdy2), .dst_rdy_i(rx_ll_dst_rdy2));
+
+ wire tx_ll_sof, tx_ll_eof, tx_ll_src_rdy, tx_ll_dst_rdy;
+ reg tx_ll_sof2=0, tx_ll_eof2=0;
+ reg tx_ll_src_rdy2 = 0;
+ wire tx_ll_dst_rdy2;
+ wire [7:0] tx_ll_data;
+ reg [7:0] tx_ll_data2 = 0;
+ wire tx_ll_error;
+ wire tx_ll_error2 = 0;
+
+ ll8_shortfifo tx_sfifo
+ (.clk(clk), .reset(reset), .clear(clear),
+ .datain(tx_ll_data2), .sof_i(tx_ll_sof2), .eof_i(tx_ll_eof2),
+ .error_i(tx_ll_error2), .src_rdy_i(tx_ll_src_rdy2), .dst_rdy_o(tx_ll_dst_rdy2),
+ .dataout(tx_ll_data), .sof_o(tx_ll_sof), .eof_o(tx_ll_eof),
+ .error_o(tx_ll_error), .src_rdy_o(tx_ll_src_rdy), .dst_rdy_i(tx_ll_dst_rdy));
+
+ ll8_to_txmac ll8_to_txmac
+ (.clk(clk), .reset(reset), .clear(clear),
+ .ll_data(tx_ll_data), .ll_sof(tx_ll_sof), .ll_eof(tx_ll_eof),
+ .ll_src_rdy(tx_ll_src_rdy), .ll_dst_rdy(tx_ll_dst_rdy),
+ .tx_data(tx_data), .tx_valid(tx_valid), .tx_error(tx_error), .tx_ack(tx_ack));
+
+ initial $dumpfile("simple_gemac_tb.vcd");
+ initial $dumpvars(0,simple_gemac_tb);
+
+ integer i;
+ reg [7:0] pkt_rom[0:65535];
+ reg [1023:0] ROMFile;
+
+ initial
+ for (i=0;i<65536;i=i+1)
+ pkt_rom[i] <= 8'h0;
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (10)
+ @(posedge clk);
+ SendFlowCtrl(16'h0007); // Send flow control
+ @(posedge clk);
+ #30000;
+ @(posedge clk);
+ SendFlowCtrl(16'h0009); // Increas flow control before it expires
+ #10000;
+ @(posedge clk);
+ SendFlowCtrl(16'h0000); // Cancel flow control before it expires
+ @(posedge clk);
+
+ SendPacket_to_ll8(8'hAA,10); // This packet gets dropped by the filters
+ repeat (10)
+ @(posedge clk);
+
+ SendPacketFromFile_ll8(60,0,0); // The rest are valid packets
+ repeat (10)
+ @(posedge clk);
+
+ SendPacketFromFile_ll8(61,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_ll8(62,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_ll8(63,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_ll8(64,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_ll8(59,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_ll8(58,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_ll8(100,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_ll8(200,150,30); // waiting 14 empties the fifo, 15 underruns
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_ll8(100,0,30);
+ #10000 $finish;
+ end
+
+ // Force a CRC error
+ initial
+ begin
+ #90000;
+ @(posedge clk);
+ FORCE_DAT_ERR <= 8'h10;
+ @(posedge clk);
+ FORCE_DAT_ERR <= 8'h00;
+ end
+
+ // Force an RX_ER error (i.e. link loss)
+ initial
+ begin
+ #116000;
+ @(posedge clk);
+ FORCE_ERR <= 1;
+ @(posedge clk);
+ FORCE_ERR <= 0;
+ end
+
+ // Cause receive fifo to fill, causing an RX overrun
+ initial
+ begin
+ #126000;
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 0;
+ repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 1;
+ end
+
+ // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun
+ // Still need to test: CRC errors on Pause Frames
+
+ always @(posedge clk)
+ if(rx_ll_src_rdy2 & rx_ll_dst_rdy2)
+ begin
+ if(rx_ll_sof2 & ~rx_ll_eof2)
+ $display("RX-PKT-START %d",$time);
+ $display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2);
+ if(rx_ll_eof2 & ~rx_ll_sof2)
+ $display("RX-PKT-END %d",$time);
+ end
+
+endmodule // simple_gemac_tb
diff --git a/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper.build b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper.build
new file mode 100755
index 000000000..14e8500b3
--- /dev/null
+++ b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper.build
@@ -0,0 +1 @@
+iverilog -Wimplict -Wportbind -y ../fifo/ -y ../models/ -y . -y miim -y ../control -y ../coregen/ -y ../control_lib/ -o simple_gemac_wrapper_tb simple_gemac_wrapper_tb.v
diff --git a/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper_tb.v b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper_tb.v
new file mode 100644
index 000000000..b89589234
--- /dev/null
+++ b/fpga/usrp3/lib/sim/simple_gemac/simple_gemac_wrapper/simple_gemac_wrapper_tb.v
@@ -0,0 +1,213 @@
+//
+// Copyright 2011 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+
+
+module simple_gemac_wrapper_tb;
+`include "eth_tasks_f36.v"
+
+ reg reset = 1;
+ initial #1000 reset = 0;
+ wire wb_rst = reset;
+
+ reg eth_clk = 0;
+ always #50 eth_clk = ~eth_clk;
+
+ reg wb_clk = 0;
+ always #173 wb_clk = ~wb_clk;
+
+ reg sys_clk = 0;
+ always #77 sys_clk = ~ sys_clk;
+
+ wire GMII_RX_DV, GMII_RX_ER, GMII_TX_EN, GMII_TX_ER, GMII_GTX_CLK;
+ wire [7:0] GMII_RXD, GMII_TXD;
+
+ wire rx_valid, rx_error, rx_ack;
+ wire tx_ack, tx_valid, tx_error;
+
+ wire [7:0] rx_data, tx_data;
+
+ wire GMII_RX_CLK = GMII_GTX_CLK;
+
+ reg [7:0] FORCE_DAT_ERR = 0;
+ reg FORCE_ERR = 0;
+
+ // Loopback
+ assign GMII_RX_DV = GMII_TX_EN;
+ assign GMII_RX_ER = GMII_TX_ER | FORCE_ERR;
+ assign GMII_RXD = GMII_TXD ^ FORCE_DAT_ERR;
+
+
+ wire [31:0] wb_dat_o;
+ reg [31:0] wb_dat_i;
+ reg [7:0] wb_adr;
+ reg wb_stb=0, wb_cyc=0, wb_we=0;
+ wire wb_ack;
+
+ reg [35:0] tx_f36_data=0;
+ reg tx_f36_src_rdy = 0;
+ wire tx_f36_dst_rdy;
+ wire [35:0] rx_f36_data;
+ wire rx_f36_src_rdy;
+ wire rx_f36_dst_rdy = 1;
+
+ simple_gemac_wrapper simple_gemac_wrapper
+ (.clk125(eth_clk), .reset(reset),
+ .GMII_GTX_CLK(GMII_GTX_CLK), .GMII_TX_EN(GMII_TX_EN),
+ .GMII_TX_ER(GMII_TX_ER), .GMII_TXD(GMII_TXD),
+ .GMII_RX_CLK(GMII_RX_CLK), .GMII_RX_DV(GMII_RX_DV),
+ .GMII_RX_ER(GMII_RX_ER), .GMII_RXD(GMII_RXD),
+
+ .sys_clk(sys_clk), .rx_f36_data(rx_f36_data), .rx_f36_src_rdy(rx_f36_src_rdy), .rx_f36_dst_rdy(rx_f36_dst_rdy),
+ .tx_f36_data(tx_f36_data), .tx_f36_src_rdy(tx_f36_src_rdy), .tx_f36_dst_rdy(tx_f36_dst_rdy),
+
+ .wb_clk(wb_clk), .wb_rst(wb_rst), .wb_stb(wb_stb), .wb_cyc(wb_cyc), .wb_ack(wb_ack), .wb_we(wb_we),
+ .wb_adr(wb_adr), .wb_dat_i(wb_dat_i), .wb_dat_o(wb_dat_o),
+
+ .mdio(), .mdc(),
+ .debug() );
+
+ initial $dumpfile("simple_gemac_wrapper_tb.vcd");
+ initial $dumpvars(0,simple_gemac_wrapper_tb);
+
+ integer i;
+ reg [7:0] pkt_rom[0:65535];
+ reg [1023:0] ROMFile;
+
+ initial
+ for (i=0;i<65536;i=i+1)
+ pkt_rom[i] <= 8'h0;
+
+ initial
+ begin
+ @(negedge reset);
+ repeat (10)
+ @(posedge wb_clk);
+ WishboneWR(0,6'b111101);
+ WishboneWR(4,16'hA0B0);
+ WishboneWR(8,32'hC0D0_A1B1);
+ WishboneWR(12,16'h0000);
+ WishboneWR(16,32'h0000_0000);
+
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0007); // Send flow control
+ @(posedge eth_clk);
+ #30000;
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0009); // Increase flow control before it expires
+ #10000;
+ @(posedge eth_clk);
+ SendFlowCtrl(16'h0000); // Cancel flow control before it expires
+ @(posedge eth_clk);
+
+ repeat (1000)
+ @(posedge sys_clk);
+ SendPacket_to_fifo36(32'hA0B0C0D0,10); // This packet gets dropped by the filters
+ repeat (1000)
+ @(posedge sys_clk);
+
+ SendPacket_to_fifo36(32'hAABBCCDD,100); // This packet gets dropped by the filters
+ repeat (10)
+ @(posedge sys_clk);
+/*
+ SendPacketFromFile_f36(60,0,0); // The rest are valid packets
+ repeat (10)
+ @(posedge clk);
+
+ SendPacketFromFile_f36(61,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(62,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(63,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(64,0,0);
+ repeat (10)
+ @(posedge clk);
+ SendPacketFromFile_f36(59,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(58,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(100,0,0);
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(200,150,30); // waiting 14 empties the fifo, 15 underruns
+ repeat (1)
+ @(posedge clk);
+ SendPacketFromFile_f36(100,0,30);
+ */
+ #100000 $finish;
+ end
+
+ // Force a CRC error
+ initial
+ begin
+ #90000;
+ @(posedge eth_clk);
+ FORCE_DAT_ERR <= 8'h10;
+ @(posedge eth_clk);
+ FORCE_DAT_ERR <= 8'h00;
+ end
+
+ // Force an RX_ER error (i.e. link loss)
+ initial
+ begin
+ #116000;
+ @(posedge eth_clk);
+ FORCE_ERR <= 1;
+ @(posedge eth_clk);
+ FORCE_ERR <= 0;
+ end
+/*
+ // Cause receive fifo to fill, causing an RX overrun
+ initial
+ begin
+ #126000;
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 0;
+ repeat (30) // Repeat of 14 fills the shortfifo, but works. 15 overflows
+ @(posedge clk);
+ rx_ll_dst_rdy2 <= 1;
+ end
+ */
+ // Tests: Send and recv flow control, send and receive good packets, RX CRC err, RX_ER, RX overrun, TX underrun
+ // Still need to test: CRC errors on Pause Frames, MDIO, wishbone
+
+ task WishboneWR;
+ input [7:0] adr;
+ input [31:0] value;
+ begin
+ wb_adr <= adr;
+ wb_dat_i <= value;
+ wb_stb <= 1;
+ wb_cyc <= 1;
+ wb_we <= 1;
+ while (~wb_ack)
+ @(posedge wb_clk);
+ @(posedge wb_clk);
+ wb_stb <= 0;
+ wb_cyc <= 0;
+ wb_we <= 0;
+ end
+ endtask // WishboneWR
+ /*
+ always @(posedge clk)
+ if(rx_ll_src_rdy2 & rx_ll_dst_rdy2)
+ begin
+ if(rx_ll_sof2 & ~rx_ll_eof2)
+ $display("RX-PKT-START %d",$time);
+ $display("RX-PKT SOF %d EOF %d ERR%d DAT %x",rx_ll_sof2,rx_ll_eof2,rx_ll_error2,rx_ll_data2);
+ if(rx_ll_eof2 & ~rx_ll_sof2)
+ $display("RX-PKT-END %d",$time);
+ end
+ */
+endmodule // simple_gemac_wrapper_tb
diff --git a/fpga/usrp3/lib/sim/wishbone/simple_uart/simple_uart_tb.v b/fpga/usrp3/lib/sim/wishbone/simple_uart/simple_uart_tb.v
new file mode 100644
index 000000000..3a1ddda29
--- /dev/null
+++ b/fpga/usrp3/lib/sim/wishbone/simple_uart/simple_uart_tb.v
@@ -0,0 +1,132 @@
+//
+// Copyright 2016 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+module simple_uart_tb();
+
+ localparam SUART_CLKDIV = 0;
+ localparam SUART_TXLEVEL = 1;
+ localparam SUART_RXLEVEL = 2;
+ localparam SUART_TXCHAR = 3;
+ localparam SUART_RXCHAR = 4;
+
+ reg clk;
+ reg rst;
+
+ reg we_i;
+ reg stb_i;
+ reg cyc_i;
+ wire ack_o;
+ reg [2:0] adr_i;
+ reg [31:0] dat_i;
+ wire [31:0] dat_o;
+ wire rx_int_o;
+ wire tx_int_o;
+ wire tx_o;
+ reg rx_i;
+ wire baud_o;
+
+ reg [31:0] read_data;
+
+
+ initial
+ clk = 0;
+
+ // 200MHz clock
+ always
+ #2.5 clk = ~clk;
+
+ initial begin
+ rst <= 0;
+ we_i <= 0;
+ stb_i <= 0;
+ cyc_i <= 0;
+ adr_i <= 0;
+ dat_i <= 0;
+ rx_i <= 0;
+ end
+
+
+ task write_wb;
+ input [31:0] data_in;
+ input [2:0] addr_in;
+
+ begin
+ @(negedge clk);
+ dat_i <= data_in;
+ adr_i <= addr_in;
+ we_i <= 1;
+ stb_i <= 1;
+ cyc_i <= 1;
+ @(negedge clk);
+ while (ack_o == 0) begin
+ @(negedge clk);
+ end
+ dat_i <= 0;
+ adr_i <= 0;
+ we_i <= 0;
+ stb_i <= 0;
+ cyc_i <= 0;
+ end
+ endtask // write_wb
+
+
+ task read_wb;
+ output [31:0] data_out;
+ input [2:0] addr_in;
+
+ begin
+ @(negedge clk);
+ adr_i <= addr_in;
+ we_i <= 0;
+ stb_i <= 1;
+ cyc_i <= 1;
+ @(negedge clk);
+ while (ack_o == 0) begin
+ @(negedge clk);
+ end
+ data_out <= dat_o;
+ adr_i <= 0;
+ stb_i <= 0;
+ cyc_i <= 0;
+ end
+ endtask // write_wb
+
+ initial begin
+ @(negedge clk);
+ rst <= 1;
+ repeat(10) @(negedge clk);
+ rst <= 0;
+ repeat(10) @(negedge clk);
+ write_wb(4'h0620,SUART_CLKDIV);
+ repeat(10) @(negedge clk);
+ read_wb(read_data,SUART_TXLEVEL);
+ repeat(10) @(negedge clk);
+ end // initial begin
+
+
+
+ simple_uart
+ #(.CLKDIV_DEFAULT(16'd0))
+ simple_uart_i
+ (
+ .clk_i(clk),
+ .rst_i(rst),
+ .we_i(we_i),
+ .stb_i(stb_i),
+ .cyc_i(cyc_i),
+ .ack_o(ack_o),
+ .adr_i(adr_i),
+ .dat_i(dat_i),
+ .dat_o(dat_o),
+ .rx_int_o(rx_int_o),
+ .tx_int_o(tx_int_o),
+ .tx_o(tx_o),
+ .rx_i(rx_i),
+ .baud_o(baud_o)
+ );
+
+
+
+endmodule // simple_uart_tb