Merge FPGA repository back into UHD repository

The FPGA codebase was removed from the UHD repository in 2014 to reduce
the size of the repository. However, over the last half-decade, the
split between the repositories has proven more burdensome than it has
been helpful. By merging the FPGA code back, it will be possible to
create atomic commits that touch both FPGA and UHD codebases. Continuous
integration testing is also simplified by merging the repositories,
because it was previously difficult to automatically derive the correct
UHD branch when testing a feature branch on the FPGA repository.

This commit also updates the license files and paths therein.

We are therefore merging the repositories again. Future development for
FPGA code will happen in the same repository as the UHD host code and
MPM code.

== Original Codebase and Rebasing ==

The original FPGA repository will be hosted for the foreseeable future
at its original local location: https://github.com/EttusResearch/fpga/

It can be used for bisecting, reference, and a more detailed history.

The final commit from said repository to be merged here is
05003794e2da61cabf64dd278c45685a7abad7ec. This commit is tagged as
v4.0.0.0-pre-uhd-merge.

If you have changes in the FPGA repository that you want to rebase onto
the UHD repository, simply run the following commands:

- Create a directory to store patches (this should be an empty
  directory):

    mkdir ~/patches

- Now make sure that your FPGA codebase is based on the same state as
  the code that was merged:

    cd src/fpga # Or wherever your FPGA code is stored
    git rebase v4.0.0.0-pre-uhd-merge

  Note: The rebase command may look slightly different depending on what
  exactly you're trying to rebase.

- Create a patch set for your changes versus v4.0.0.0-pre-uhd-merge:

    git format-patch v4.0.0.0-pre-uhd-merge -o ~/patches

  Note: Make sure that only patches are stored in your output directory.
  It should otherwise be empty. Make sure that you picked the correct
  range of commits, and only commits you wanted to rebase were exported
  as patch files.

- Go to the UHD repository and apply the patches:

    cd src/uhd # Or wherever your UHD repository is stored
    git am --directory fpga ~/patches/*
    rm -rf ~/patches # This is for cleanup

== Contributors ==

The following people have contributed mainly to these files (this list
is not complete):

Co-authored-by: Alex Williams <alex.williams@ni.com>
Co-authored-by: Andrej Rode <andrej.rode@ettus.com>
Co-authored-by: Ashish Chaudhari <ashish@ettus.com>
Co-authored-by: Ben Hilburn <ben.hilburn@ettus.com>
Co-authored-by: Ciro Nishiguchi <ciro.nishiguchi@ni.com>
Co-authored-by: Daniel Jepson <daniel.jepson@ni.com>
Co-authored-by: Derek Kozel <derek.kozel@ettus.com>
Co-authored-by: EJ Kreinar <ej@he360.com>
Co-authored-by: Humberto Jimenez <humberto.jimenez@ni.com>
Co-authored-by: Ian Buckley <ian.buckley@gmail.com>
Co-authored-by: Jörg Hofrichter <joerg.hofrichter@ni.com>
Co-authored-by: Jon Kiser <jon.kiser@ni.com>
Co-authored-by: Josh Blum <josh@joshknows.com>
Co-authored-by: Jonathon Pendlum <jonathan.pendlum@ettus.com>
Co-authored-by: Martin Braun <martin.braun@ettus.com>
Co-authored-by: Matt Ettus <matt@ettus.com>
Co-authored-by: Michael West <michael.west@ettus.com>
Co-authored-by: Moritz Fischer <moritz.fischer@ettus.com>
Co-authored-by: Nick Foster <nick@ettus.com>
Co-authored-by: Nicolas Cuervo <nicolas.cuervo@ettus.com>
Co-authored-by: Paul Butler <paul.butler@ni.com>
Co-authored-by: Paul David <paul.david@ettus.com>
Co-authored-by: Ryan Marlow <ryan.marlow@ettus.com>
Co-authored-by: Sugandha Gupta <sugandha.gupta@ettus.com>
Co-authored-by: Sylvain Munaut <tnt@246tNt.com>
Co-authored-by: Trung Tran <trung.tran@ettus.com>
Co-authored-by: Vidush Vishwanath <vidush.vishwanath@ettus.com>
Co-authored-by: Wade Fife <wade.fife@ettus.com>


Original-commit: bafa9d95453387814ef25e6b6256ba8db2df612f
This commit is contained in:
Martin Braun
2020-01-28 09:35:36 -08:00
co-authored by Alex Williams Andrej Rode Ashish Chaudhari Ben Hilburn Ciro Nishiguchi Daniel Jepson Derek Kozel EJ Kreinar Humberto Jimenez Ian Buckley Jörg Hofrichter Jon Kiser Josh Blum Jonathon Pendlum Matt Ettus Michael West Moritz Fischer Nick Foster Nicolas Cuervo Paul Butler Paul David Ryan Marlow Sugandha Gupta Sylvain Munaut Trung Tran Vidush Vishwanath Wade Fife
parent 74893643ca
commit 6b67702ad7
2157 changed files with 1282567 additions and 0 deletions
+26
View File
@@ -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) \
)
+47
View File
@@ -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
+112
View File
@@ -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
+49
View File
@@ -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
@@ -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
+35
View File
@@ -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
@@ -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
+46
View File
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+94
View File
@@ -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 //
+18
View File
@@ -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
@@ -0,0 +1,4 @@
fuse*
isim*
*.exe
*.wcfg
+101
View File
@@ -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
+17
View File
@@ -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
+9
View File
@@ -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
@@ -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
@@ -0,0 +1,4 @@
fuse*
isim*
*.exe
*.wcfg
+17
View File
@@ -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
+9
View File
@@ -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
+136
View File
@@ -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
+45
View File
@@ -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
@@ -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
+50
View File
@@ -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
+47
View File
@@ -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
@@ -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
+412
View File
@@ -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>
+16
View File
@@ -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
@@ -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>
+17
View File
@@ -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
@@ -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;
@@ -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>
+19
View File
@@ -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
@@ -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;
+34
View File
@@ -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
+134
View File
@@ -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
@@ -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
+230
View File
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+21
View File
@@ -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
+115
View File
@@ -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
+21
View File
@@ -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
+103
View File
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
+74
View File
@@ -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
+37
View File
@@ -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
@@ -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
+115
View File
@@ -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}
+144
View File
@@ -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
+1
View File
@@ -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
@@ -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
@@ -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
+413
View File
@@ -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>
+381
View File
@@ -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>
+1
View File
@@ -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
+43
View File
@@ -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
+75
View File
@@ -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
+90
View File
@@ -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
@@ -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
+1
View File
@@ -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/
+341
View File
@@ -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
@@ -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
+208
View File
@@ -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
@@ -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
@@ -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
@@ -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