diff options
Diffstat (limited to 'fpga/usrp3/lib/sim')
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 |