aboutsummaryrefslogtreecommitdiffstats
path: root/fpga
diff options
context:
space:
mode:
authorWade Fife <wade.fife@ettus.com>2020-09-08 20:04:56 -0500
committermichael-west <michael.west@ettus.com>2020-09-11 00:44:25 -0700
commit830455fae53e9e63146798ba075460cfa2e6ae3a (patch)
treea62fcf57efc7fa8852ea4f7fc4c5429b37753889 /fpga
parenta25f9306274583513531fb0537372b8bf03625da (diff)
downloaduhd-830455fae53e9e63146798ba075460cfa2e6ae3a.tar.gz
uhd-830455fae53e9e63146798ba075460cfa2e6ae3a.tar.bz2
uhd-830455fae53e9e63146798ba075460cfa2e6ae3a.zip
fpga: docs: Update user manual for UHD 4.0
Diffstat (limited to 'fpga')
-rw-r--r--fpga/docs/usrp3/build_instructions.md70
-rw-r--r--fpga/docs/usrp3/sim/legacy_testbenches.md240
-rw-r--r--fpga/docs/usrp3/sim/libs_axi.md10
-rw-r--r--fpga/docs/usrp3/sim/libs_general.md15
-rw-r--r--fpga/docs/usrp3/sim/running_testbenches.md108
-rw-r--r--fpga/docs/usrp3/sim/simulation_libraries.md180
-rw-r--r--fpga/docs/usrp3/sim/writing_sim_makefile.md240
-rw-r--r--fpga/docs/usrp3/sim/writing_sim_top.md198
-rw-r--r--fpga/docs/usrp3/sim/writing_testbenches.md467
-rw-r--r--fpga/docs/usrp3/simulation.md13
-rw-r--r--fpga/docs/usrp3/vivado_env_utils.md43
11 files changed, 1042 insertions, 542 deletions
diff --git a/fpga/docs/usrp3/build_instructions.md b/fpga/docs/usrp3/build_instructions.md
index 034f1be03..d70c633b7 100644
--- a/fpga/docs/usrp3/build_instructions.md
+++ b/fpga/docs/usrp3/build_instructions.md
@@ -7,11 +7,11 @@
The USRP FPGA build system requires a UNIX-like environment with the following dependencies
- [Xilinx Vivado 2019.1](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/2019-1.html) (For 7 Series FPGAs)
-- [Xilinx ISE 14.7](http://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/design-tools/v2012_4---14_7.html) (For all other FPGAs)
+- [Xilinx ISE 14.7](https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/vivado-design-tools/archive-ise.html) (For all other FPGAs)
- [GNU Make 3.6+](https://www.gnu.org/software/make/)
- [GNU Bash 4.0+](https://www.gnu.org/software/bash/)
-- [Python 2.7.x](https://www.python.org/)
-- [Doxygen](http://www.stack.nl/~dimitri/doxygen/index.html) (Optional: To build the manual)
+- [Python 3.5](https://www.python.org/)
+- [Doxygen](https://www.doxygen.nl/index.html) (Optional: To build the manual)
- [ModelSim](https://www.mentor.com/products/fv/modelsim/) (Optional: For simulation)
The following USRPs work with the free WebPack versions:
@@ -39,14 +39,15 @@ The following USRPs work with the free WebPack versions:
### Download and Install Xilinx Tools
Download and install Xilinx Vivado or Xilinx ISE based on the target USRP.
-- The recommended installation directory is `/opt/Xilinx/` for Linux and `C:\Xilinx` in Windows
-- Please check the Xilinx Requirements document above for the FPGA technology used by your USRP device.
+- The recommended installation directory is `/opt/Xilinx/` for Linux and `C:\Xilinx` in Windows.
+- Please check the Xilinx requirements for the FPGA technology used by your USRP device.
- You may need to acquire a synthesis and implementation license from Xilinx to build some USRP designs.
-- You may need to acquire a simulation license from Xilinx to run some testbenches
+- You may need to acquire a simulation license from Xilinx to run some testbenches.
### Download and Install ModelSim (Optional)
-Download and install Mentor ModelSim using the link above.
+If you prefer to use ModelSim, download and install Mentor ModelSim using the
+link above.
- The recommended installation directory is `/opt/mentor/modelsim` for Linux and `C:\mentor\modelsim` in Windows
- Supported versions are PE, DE, SE, DE-64 and SE-64
- You may need to acquire a license from Mentor Graphics to run ModelSim
@@ -75,17 +76,17 @@ Download the latest version on [Cygwin](https://cygwin.com/install.html) (64-bit
and install it using [these instructions](http://x.cygwin.com/docs/ug/setup-cygwin-x-installing.html).
The following additional packages are also required and can be selected in the GUI installer
- python patch patchutils bash make doxygen
+ python3 patch patchutils bash make gcc-core doxygen
## Build Instructions (Xilinx Vivado only)
### Makefile based Builder
-- Navigate to `usrp3/top/{project}` where project is:
- + x300: For USRP X300 and USRP X310
- + e31x: For USRP E310
- + e320: For USRP E320
- + n3xx: For USRP N300/N310/N320
+- Navigate to `<repo>/fpga/usrp3/top/{project}` where `{project}` is:
+ + `x300:` For USRP X300 and USRP X310
+ + `e31x:` For USRP E310
+ + `e320:` For USRP E320
+ + `n3xx:` For USRP N300/N310/N320
- To add vivado to the PATH and to setup up the Ettus Xilinx build environment run
+ `source setupenv.sh` (If Vivado is installed in the default path /opt/Xilinx/Vivado) _OR_
@@ -96,22 +97,22 @@ The following additional packages are also required and can be selected in the G
`make help`.
- The build output will be specific to the product and will be located in the
- `usrp3/top/{project}/build` directory. Run `make help` for more information.
+ `<repo>/fpga/usrp3/top/{project}/build` directory. Run `make help` for more information.
-### Environment Utilies
+### Environment Utilities
-The build environment also defines many ease-of-use utilites. Please use the \subpage md_usrp3_vivado_env_utils "Vivado Utility Reference" page for
+The build environment also defines many ease-of-use utilities. Please use the \subpage md_usrp3_vivado_env_utils "Vivado Utility Reference" page for
a list and usage information
## Build Instructions (Xilinx ISE only)
-### Makefile based Builder
+### Makefile Based Builder
- To add xtclsh to the PATH and to setup up the Xilinx build environment run
+ `source <install_dir>/Xilinx/14.7/ISE_DS/settings64.sh` (64-bit platform)
+ `source <install_dir>/Xilinx/14.7/ISE_DS/settings32.sh` (32-bit platform)
-- Navigate to `usrp3/top/{project}` where project is:
+- Navigate to `<repo>/fpga/usrp3/top/{project}` where `{project}` is:
+ b200: For USRP B200 and USRP B210
+ b200mini: For USRP B200mini
@@ -120,7 +121,7 @@ a list and usage information
`make help`.
- The build output will be specific to the product and will be located in the
- `usrp3/top/{project}/build` directory. Run `make help` for more information.
+ `<repo>/fpga/usrp3/top/{project}/build` directory. Run `make help` for more information.
## Targets and Outputs
@@ -159,8 +160,10 @@ a list and usage information
### E310 Targets and Outputs
#### Supported Targets
-- E310_SG1 or E310 : Builds the USRP E310 speed grade 1.
-- E310_SG3 or E310_sg3: Builds the USRP E310 speed grade 3.
+- E310_SG1 or E310: Builds the USRP E310 (speed grade 1).
+- E310_SG3 or E310_sg3: Builds the USRP E310 (speed grade 3).
+- E310_SG1_IDLE: Builds the USRP E310 idle design (speed grade 1).
+- E310_SG3_IDLE: Builds the USRP E310 idle design (sSpeed grade 3).
#### Outputs
- `build/usrp_<product>_fpga.bit` : Configuration bitstream with header
@@ -204,7 +207,8 @@ combination of motherboard and daughterboards.
- N320_HG: 1GigE on SFP0, 10GigE on SFP1
- N320_XG: 10GigE on both SFP+ ports
- N320_XQ: White Rabbit on SFP0, 10 GigE on QSFP0 and QSFP1
-- N320_WX: White Rabbit on SFP0, 10GigE on SFP1
+- N320_WX: White Rabbit on SFP0, 10GigE on SFP1
+- N320_AA: Aurora on SFP+ Port0, Aurora on SFP+ Port1
For the N320 targets see also the N320 manual page on the UHD manual.
@@ -215,11 +219,21 @@ For the N320 targets see also the N320 manual page on the UHD manual.
### Additional Build Options
-It is possible to make a target and specific additional options in the form VAR=VALUE in
-the command. For example: `make B210 PROJECT_ONLY=1`
+It is possible to make a target and specify additional options in the form VAR=VALUE in
+the command. For example:
+
+$ make X310 GUI=1
+
+The options available are described in the following subsections.
+
+#### Xilinx Vivado Make Options
+
+- `GUI=1` : Run the Vivado build in GUI mode instead of batch mode. After the build is complete, Vivado provides an option to save the fully configured project for customization
+- `CHECK=1` : Run elaboration only to check HDL syntax
+- `SYNTH=1` : Run synthesis only
+- `TOP=<module>` : Specify an alternate top-level module for syntax checking
-Here are the supported options:
+#### Xilinx ISE Make Options
-- `PROJECT_ONLY=1` : Only create a Xilinx project for the specified target(s). Useful for use with the ISE GUI. (*NOTE*: this option is only valid for Xilinx ISE)
-- `EXPORT_ONLY=1` : Export build targets from a GUI build to the build directory. Requires the project in build-\*_\* to be built. (*NOTE*: this option is only valid for Xilinx ISE)
-- `GUI=1` : Run the Vivado build in GUI mode instead of batch mode. After the build is complete, Vivado provides an option to save the fully configured project for customization (*NOTE*: this option is only valid for Xilinx Vivado)
+- `PROJECT_ONLY=1` : Only create a Xilinx project for the specified target(s). Useful for use with the ISE GUI.
+- `EXPORT_ONLY=1` : Export build targets from a GUI build to the build directory. Requires the project in build-\*_\* to be built.
diff --git a/fpga/docs/usrp3/sim/legacy_testbenches.md b/fpga/docs/usrp3/sim/legacy_testbenches.md
new file mode 100644
index 000000000..91d7a4583
--- /dev/null
+++ b/fpga/docs/usrp3/sim/legacy_testbenches.md
@@ -0,0 +1,240 @@
+# Legacy Testbenches
+
+Some existing testbenches use the following testbench style and infrastructure.
+This documentation is from UHD 3.x but is included here due to its continued
+use.
+
+Below is a sample legacy SystemVerilog testbench.
+
+ //
+ // Copyright 2015 Ettus Research LLC
+ //
+
+ `timescale 1ns/1ps
+ `define NS_PER_TICK 1
+ `define NUM_TEST_CASES 3
+
+ `include "sim_clks_rsts.vh"
+ `include "sim_exec_report.vh"
+ `include "sim_cvita_lib.sv"
+
+ module example_fifo_tb();
+ `TEST_BENCH_INIT("example_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ // Define all clocks and resets
+ `DEFINE_CLK(bus_clk, 1000/166.6667, 50) //166MHz bus_clk
+ `DEFINE_RESET(bus_rst, 0, 100) //100ns for GSR to deassert
+
+ cvita_stream_t chdr_i (.clk(bus_clk));
+ cvita_stream_t chdr_o (.clk(bus_clk));
+
+ // Initialize DUT
+ axi_fifo #(.WIDTH(65), .SIZE(24)) dut_single (
+ .clk(bus_clk),
+ .reset(bus_rst),
+ .clear(1'b0),
+
+ .i_tdata({chdr_i.axis.tlast, chdr_i.axis.tdata}),
+ .i_tvalid(chdr_i.axis.tvalid),
+ .i_tready(chdr_i.axis.tready),
+
+ .o_tdata({chdr_o.axis.tlast, chdr_o.axis.tdata}),
+ .o_tvalid(chdr_o.axis.tvalid),
+ .o_tready(chdr_o.axis.tready),
+
+ .space(),
+ .occupied()
+ );
+
+ //Testbench variables
+ cvita_hdr_t header, header_out;
+ cvita_stats_t stats;
+
+ //------------------------------------------
+ //Main thread for testbench execution
+ //------------------------------------------
+ initial begin : tb_main
+
+ `TEST_CASE_START("Wait for reset");
+ while (bus_rst) @(posedge bus_clk);
+ `TEST_CASE_DONE((~bus_rst));
+
+ repeat (200) @(posedge bus_clk);
+
+ header = '{
+ pkt_type:DATA, has_time:0, eob:0, seqno:12'h666,
+ length:0, sid:$random, timestamp:64'h0};
+
+ `TEST_CASE_START("Fill up empty FIFO then drain (short packet)");
+ chdr_o.axis.tready = 0;
+ chdr_i.push_ramp_pkt(16, 64'd0, 64'h100, header);
+ chdr_o.axis.tready = 1;
+ chdr_o.wait_for_pkt_get_info(header_out, stats);
+ `ASSERT_ERROR(stats.count==16, "Bad packet: Length mismatch");
+ `ASSERT_ERROR(header.sid==header_out.sid, "Bad packet: Wrong SID");
+ `ASSERT_ERROR(chdr_i.axis.tready, "Bus not ready");
+ `TEST_CASE_DONE(1);
+
+ header = '{
+ pkt_type:DATA, has_time:1, eob:0, seqno:12'h666,
+ length:0, sid:$random, timestamp:64'h0};
+
+ `TEST_CASE_START("Concurrent read and write (single packet)");
+ chdr_o.axis.tready = 1;
+ fork
+ begin
+ chdr_i.push_ramp_pkt(20, 64'd0, 64'h100, header);
+ end
+ begin
+ chdr_o.wait_for_pkt_get_info(header_out, stats);
+ end
+ join
+ `ASSERT_ERROR(stats.count==20, "Bad packet: Length mismatch");
+ `TEST_CASE_DONE(1);
+ end
+ endmodule
+
+
+Each testbench should have the following basic components:
+
+## Timescale Defines and Includes
+
+ `timescale 1ns/1ps
+ `define NS_PER_TICK 1
+ `define NUM_TEST_CASES 3
+
+ `include "sim_clks_rsts.vh"
+ `include "sim_exec_report.vh"
+ `include "sim_cvita_lib.sv"
+
+In addition to the timescale, the infrastructure needs to know the number of
+nanoseconds per simulator tick. This can be a floating point number.
+
+
+In addition to the timescale, you may include any Verilog/SystemVerilog headers here.
+
+## Main Module Definition
+
+ `include "sim_exec_report.vh"
+
+ module example_fifo_tb();
+ `TEST_BENCH_INIT("example_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
+
+ ...
+
+ //------------------------------------------
+ //Main thread for testbench execution
+ //------------------------------------------
+ initial begin : tb_main
+
+ ...
+
+ end
+ endmodule
+
+The name of the main module must match the ``SIM_TOP`` variable value in the Makefile.
+To register this module with the framework, the ``TEST_BENCH_INIT`` macro must be called.
+This macro is defined in ``<repo>/usrp3/sim/general/sim_exec_report.vh``.
+
+``TEST_BENCH_INIT``:
+
+ // Initializes state for a test bench.
+ // This macro *must be* called within the testbench module but
+ // outside the primary initial block
+ // Its sets up boilerplate code for:
+ // - Logging to console
+ // - Test execution tracking
+ // - Gathering test results
+ // - Bounding execution time based on the SIM_RUNTIME_US vdef
+ //
+ // Usage: `TEST_BENCH_INIT(test_name,min_tc_run_count,ns_per_tick)
+ // where
+ // - tb_name: Name of the testbench. (Only used during reporting)
+ // - min_tc_run_count: Number of test cases in testbench. (Used to detect stalls and inf-loops)
+ // - ns_per_tick: The time_unit_base from the timescale declaration
+
+The testbench must also have at least one initial block that consists tests cases (covered later).
+For the sake of convention it should be called ``tb_main``. *All test cases must live in ``tb_main``*. You may
+have other initial block but they must not call macros from ``sim_exec_report.vh`` because the code
+there is not thread-safe.
+
+## Test Cases
+
+A test case in this context is defined as an independent entity that validates an aspect of the DUT behavior
+and which is independent from other test cases i.e. the result of one test case should ideally not affect others.
+
+
+Test cases are wrapped in the ``TEST_CASE_START`` and ``TEST_CASE_DONE`` macros:
+
+ `TEST_CASE_START("Fill up empty FIFO then drain (short packet)");
+ chdr_o.axis.tready = 0;
+ chdr_i.push_ramp_pkt(16, 64'd0, 64'h100, header);
+ chdr_o.axis.tready = 1;
+ chdr_o.wait_for_pkt_get_info(header_out, stats);
+ `ASSERT_ERROR(stats.count==16, "Bad packet: Length mismatch");
+ `ASSERT_ERROR(header.sid==header_out.sid, "Bad packet: Wrong SID");
+ `ASSERT_ERROR(chdr_i.axis.tready, "Bus not ready");
+ `TEST_CASE_DONE(1);
+
+Here are the signatures of the two macros:
+
+``TEST_CASE_START``:
+
+ // Indicates the start of a test case
+ // This macro *must be* called inside the primary initial block
+ //
+ // Usage: `TEST_CASE_START(test_name)
+ // where
+ // - test_name: The name of the test.
+ //
+
+``TEST_CASE_DONE``:
+
+ // Indicates the end of a test case
+ // This macro *must be* called inside the primary initial block
+ // The pass/fail status of test case is determined based on the
+ // the user specified outcome and the number of fatal or error
+ // ASSERTs triggered in the test case.
+ //
+ // Usage: `TEST_CASE_DONE(test_result)
+ // where
+ // - test_result: User specified outcome
+ //
+
+In addition to the test case status, it is also possible to have asserts within
+a test case. We have wrappers for the different kinds of SystemVerilog asserts
+that additionally fail the test case in case the assert fails. An assert triggered
+in a test case will not affect the outcome of another (except for a fatal assert which
+halts the simulator). Supported assert macros:
+
+ // Wrapper around a an assert.
+ // ASSERT_FATAL throws an error assertion and halts the simulator
+ // if cond is not satisfied
+ //
+ // Usage: `ASSERT_FATAL(cond,msg)
+ // where
+ // - cond: Condition for the assert
+ // - msg: Message for the assert
+ //
+
+
+ // Wrapper around a an assert.
+ // ASSERT_ERROR throws an error assertion and fails the test case
+ // if cond is not satisfied. The simulator will *not* halt
+ //
+ // Usage: `ASSERT_ERROR(cond,msg)
+ // where
+ // - cond: Condition for the assert
+ // - msg: Message for the assert
+ //
+
+
+ // Wrapper around a an assert.
+ // ASSERT_WARNING throws an warning assertion but does not fail the
+ // test case if cond is not satisfied. The simulator will *not* halt
+ //
+ // Usage: `ASSERT_WARNING(cond,msg)
+ // where
+ // - cond: Condition for the assert
+ // - msg: Message for the assert
+ //
diff --git a/fpga/docs/usrp3/sim/libs_axi.md b/fpga/docs/usrp3/sim/libs_axi.md
index a260aabdd..912d889e3 100644
--- a/fpga/docs/usrp3/sim/libs_axi.md
+++ b/fpga/docs/usrp3/sim/libs_axi.md
@@ -1,4 +1,7 @@
-# AXI Interface Libraries
+# Legacy AXI Interface Libraries
+
+This document describes legacy AXI interface libraries used by some
+testbenches. They are included here due to their continued use.
## AXI4 Stream (sim\_axis\_lib.vh)
@@ -61,7 +64,10 @@ receive data on the bus.
// - ramp_start: Start value for the ramp
// - ramp_inc: Increment per clock cycle
-## Compressed VITA [CHDR] (sim\_chdr\_lib.vh)
+## Compressed VITA (sim\_chdr\_lib.vh)
+
+Note: This section describes legacy CHDR in 3.x and earlier. As of UHD 4.0,
+the CHDR protocol and format has changed.
Defines ``cvita_stream_t``, an AXI Stream bus interface that implements the CHDR protocol and
several tasks to send and receive data on the bus.
diff --git a/fpga/docs/usrp3/sim/libs_general.md b/fpga/docs/usrp3/sim/libs_general.md
index 4bc154dc2..f4f110968 100644
--- a/fpga/docs/usrp3/sim/libs_general.md
+++ b/fpga/docs/usrp3/sim/libs_general.md
@@ -1,4 +1,7 @@
-# General Purpose Libraries
+# Legacy Simulation Libraries
+
+This document describes legacy simulation libraries used by some testbenches.
+They are included here due to their continued use.
## Execution and Reporting (sim\_exec\_report.vh)
@@ -130,20 +133,12 @@ Shortcut macros to create typical clock and reset signals.
// - reset_duration: Duration of reset assertion
//
-## File I/O (sim\_file\_io.sv)
+## File I/O (sim\_file\_io.svh)
### interface data\_file\_t
Defines a ``data_file_t`` interface with the following functions:
-#### ctor
-
- // Create a handle to a data_file with
- // - FILENAME: Name of the file
- // - FORMAT: Data format (HEX, DEC, OCT, BIN, FLOAT)
- // - DWIDTH: Width of each element stored in the file (one line per word)
- //
-
#### open
// Open the data file for reading or writing.
diff --git a/fpga/docs/usrp3/sim/running_testbenches.md b/fpga/docs/usrp3/sim/running_testbenches.md
index 4afd66fe0..2b56af86d 100644
--- a/fpga/docs/usrp3/sim/running_testbenches.md
+++ b/fpga/docs/usrp3/sim/running_testbenches.md
@@ -18,7 +18,8 @@ all supported simulator targets. Currently, the following targets will work:
xsim: Run the simulation using the Xilinx Vivado Simulator
xclean: Cleanup Xilinx Vivado Simulator intermediate files
vsim: Run the simulation using ModelSim simulator via Vivado
- modelsim: Runs the simulation using ModelSim without Vivado
+ modelsim: Run the simulation using ModelSim without Vivado
+ vlint: Compile the simulation using ModelSim
vclean: Cleanup ModelSim intermediate files
@@ -30,9 +31,9 @@ prerequisites for building an FPGA image, then you don't need to install anythin
Follow these steps to run a testbench:
- Navigate to the directory that contains the top level testbench and Makefile
- - Run the setenv.sh script for the USRP product that you are trying to simulate
+ - Run the setupenv.sh script for the USRP product that you are trying to simulate
- ``$ source <repo>/usrp3/top/<product>/setupenv.sh``
+ ``$ source <repo>/fpga/usrp3/top/<product>/setupenv.sh``
This step is required even if the simulation is generic because the toolchain requires
an FPGA part number to load simulation models.
@@ -43,38 +44,43 @@ Follow these steps to run a testbench:
## Using Mentor Graphics ModelSim
+### Setting Up ModelSim
+
ModelSim is a third-party simulation tool that is compatible with Vivado and the USRP
FPGA build infrastructure.
-Use the following one-time setup to install and configure Modelsim on your system
+Use the following one-time setup to install and configure ModelSim on your system
- - Install Modelsim from the [Mentor Graphics](http://www.mentor.com/) website.
+ - Install ModelSim from the [Mentor Graphics](http://www.mentor.com/) website.
It is recommended that you install it to the default location (/opt/mentor/modelsim)
- - Run the setenv.sh script for the USRP product that you are trying to simulate
+ - Run the setupenv.sh script for the USRP product that you are trying to simulate
- ``$ source <repo>/usrp3/top/<product>/setupenv.sh``
+ ``$ source <repo>/fpga/usrp3/top/<product>/setupenv.sh``
This step is required even if the simulation is generic because the toolchain requires
an FPGA part number to load simulation models.
- Build the Xilinx simulation libraries
+
``$ build_simlibs``
-To validate that everything was install properly run ``setupenv.sh`` again. You should see the following
+To validate that everything was installed properly run ``setupenv.sh`` again. You should see the following
Setting up X3x0 FPGA build environment (64-bit)...
- - Vivado: Found (/opt/Xilinx/Vivado/2014.4/bin)
+ - Vivado: Found (/opt/Xilinx/Vivado/2019.1/bin)
- Modelsim: Found (/opt/mentor/modelsim/modeltech/bin)
- - Modelsim Compiled Libs: Found (/opt/Xilinx/Vivado/2014.4/modelsim)
+ - Modelsim Compiled Libs: Found (/opt/Xilinx/Vivado/2019.1/modelsim)
Environment successfully initialized.
-Follow these steps to run a testbench:
+### Simulating with ModelSim through Vivado
+
+Follow these steps to run a testbench using ModelSim with Vivado:
- Navigate to the directory that contains the top level testbench and Makefile
- - Run the setenv.sh script for the USRP product that you are trying to simulate
+ - Run the setupenv.sh script for the USRP product that you are trying to simulate
- ``$ source <repo>/usrp3/top/<product>/setupenv.sh``
+ ``$ source <repo>/fpga/usrp3/top/<product>/setupenv.sh``
This step is required even if the simulation is generic because the toolchain requires
an FPGA part number to load simulation models.
@@ -82,53 +88,99 @@ Follow these steps to run a testbench:
``$ make vsim``
+Using this method launches Vivado and uses Vivado to launch ModelSim. This
+ensures that Xilinx IP is properly included in the simulation.
+
+To run the simulation in the Vivado GUI for debugging, add the GUI option:
+
+``$ make vsim GUI=1``
+
+### Simulating with ModelSim Natively
+
+To run the simulation using ModelSim natively, the process is the same as
+above, except use the `modelsim` make target.
+
+``$ make modelsim``
+
+This calls into Vivado only if Xilinx IP needs to be generated. Otherwise it
+calls ModelSim directly without invoking Vivado. This leads to significantly
+faster compile and load times for the simulation. However, this method does not
+work with all testbenches because some Xilinx IP requires special handling by
+Vivado.
+
+To load the simulation into the ModelSim GUI for debugging, add the GUI option.
+
+``$ make modelsim GUI=1``
+
+You may also need to specify special arguments or libraries to use with
+ModelSim. These can be added using the `MODELSIM_ARGS` and `MODELSIM_LIBS`
+arguments. For example:
+
+``$ make modelsim MODELSIM_ARGS="-t 1fs" MODELSIM_LIBS="secureip xpm"``
+
+ARGS are simply appended to the ModelSim `vsim` command line invocation. LIBS
+are added to the "-L" vsim command line argument. These can also be added to
+the Makefile for the testbench.
+
+### Compiling the Simulation with ModelSim
+
+To compile your code in ModelSim, use the `vlint` target.
+
+``$ make vlint``
+
+This can be used to quickly check for syntax errors, or to recompile your code
+prior to restarting a simulation from within ModelSim.
+
+Using the `modelsim` and `vlint` targets allows for very rapid simulation
+iterations.
+
## Troubleshooting
#### Vivado Not Found
-If running the setupenv.sh script return an error like the following:
+If running the setupenv.sh script returns an error like the following:
Vivado: Not found! (ERROR.. Builds and simulations will not work)
then it is possible that Vivado was not installed or it was not installed in the default
location. If Vivado is installed in a non-default location, just run the following:
- ``$ source <repo>/usrp3/top/<product>/setupenv.sh --vivado-path=<PATH>``
+``$ source <repo>/fpga/usrp3/top/<product>/setupenv.sh --vivado-path=<PATH>``
-#### Modelsim Not Found
+#### ModelSim Not Found
-If running the setupenv.sh script return an error like the following:
+If running the setupenv.sh script returns an error like the following:
- Setting up X3x0 FPGA build environment (64-bit)...
- - Vivado: Found (/opt/Xilinx/Vivado/2014.4/bin)
+ Setting up a 64-bit FPGA build environment for the USRP-X3x0...
+ - Vivado: Found (/opt/Xilinx/Vivado/2019.1/bin)
- Modelsim: Not found! (WARNING.. Simulations with vsim will not work)
Environment successfully initialized.
or something like this (even when Modelsim is installed)
- Setting up X3x0 FPGA build environment (64-bit)...
- - Vivado: Found (/opt/Xilinx/Vivado/2014.4/bin)
+ Setting up a 64-bit FPGA build environment for the USRP-X3x0...
+ - Vivado: Found (/opt/Xilinx/Vivado/2019.1/bin)
Environment successfully initialized.
then it is possible that Modelsim was not installed or it was not installed in the default
location. If Modelsim is installed in a non-default location, just run the following:
- ``$ source <repo>/usrp3/top/<product>/setupenv.sh --modelsim-path=<PATH>``
+``$ source <repo>/fpga/usrp3/top/<product>/setupenv.sh --modelsim-path=<PATH>``
-#### Modelsim Simulation Libraries Not Found
+#### ModelSim Simulation Libraries Not Found
-If running the setupenv.sh script return an error like the following:
+If running the setupenv.sh script returns an error like the following:
- Setting up X3x0 FPGA build environment (64-bit)...
- - Vivado: Found (/opt/Xilinx/Vivado/2014.4/bin)
+ Setting up a 64-bit FPGA build environment for the USRP-X3x0...
+ - Vivado: Found (/opt/Xilinx/Vivado/2019.1/bin)
- Modelsim: Found (/opt/mentor/modelsim/modeltech/bin)
- Modelsim Compiled Libs: Not found! (Run build_simlibs to generate them.)
Environment successfully initialized.
-just run the following
+Just run the following:
- $ build_simlibs \ No newline at end of file
+`$ build_simlibs`
diff --git a/fpga/docs/usrp3/sim/simulation_libraries.md b/fpga/docs/usrp3/sim/simulation_libraries.md
new file mode 100644
index 000000000..bd9b87763
--- /dev/null
+++ b/fpga/docs/usrp3/sim/simulation_libraries.md
@@ -0,0 +1,180 @@
+# Simulation Libraries
+
+Several simulation libraries are available for use in your testbenches, in the
+form of SystemVerilog packages, classes, and interfaces. The bus functional
+models (BFM) are implemented as SystemVerilog classes and use SystemVerilog
+interfaces to connect to your device under test (DUT). These classes provide
+member functions and tasks for communicating with the BFMs.
+
+A few commonly used SystemVerilog packages are described below. See each
+package file for additional documentation.
+
+## PktTestExec
+
+`PktTestExec.sv` contains utilities for testbench reporting, assertions, and
+simulation timeouts. The associated header file, `test_exec.svh`, contains
+macros for use with PkgTestExec. These macros are used to implement
+SystemVerilog assertions. The header also defines `timeunit` and
+`timeprecision`.
+
+**Note:** The `timeunit` must be `1ns` in order for PkgTestExec to use
+and report times correctly.
+
+### PkgTestExec Tasks and Functions
+
+Below are some of the methods available in PkgTestExec. See `PkgTestExec.sv`
+for additional documentation.
+
+- <b>`start_tb(string tb_name, realtime time_limit = 10ms)`</b><br>
+Called at the start of the testbench. A time limit can be specified to prevent
+the testbench from never ending.
+- <b>`end_tb(bit finish = 1)`</b><br>
+Called at the end of the testbench. Displays final results and optionally calls
+`$finish`.
+- <b>`start_test(string test_name, realtime time_limit = 0)`</b><br>
+Called at the start of a test. A time limit can be given to cause an error if
+the test takes longer than expected or never ends.
+- <b>`end_test(int test_result = 1)`</b><br>
+Called at the end of a test. A pass (1) or fail (0) can be passed to indicate
+if the test passed or failed. Any failed assertion, using the `test_exec.svh`
+macros, will also be considered when deciding if the test passed or failed. If
+any fatal or error assertions failed during the test then it will be considered
+to have failed.
+- <b>`start_timeout(`<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;`output timeout_t  handle,`<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;`input  realtime   timeout_delay,`<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;`input  string     message = "Timeout",`<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;`input  severity_t severity = SEV_ERROR)`<br></b>
+Called to start a timeout countdown. If the timeout is not ended before the
+indicated simulation time elapses then an assertion of the given severity will
+be thrown. This is very useful for ensuring that tests complete in a timely
+manner and to report which timeout was exceeded.
+- <b>`end_timeout(timeout_t handle)`</b><br>
+Called to end a timeout countdown when it is no longer needed.
+
+### Macros
+
+The following macros are defined in `test_exec.svh`. These update internal
+variables to track the state of the testbench and to report the final results.
+
+- <b>`ASSERT_FATAL(EXPR, MESSAGE)`</b><br>
+Encapsulates a SystemVerilog $assert with a $fatal severity.
+- <b>`ASSERT_ERROR(EXPR, MESSAGE) `</b><br>
+Encapsulates a SystemVerilog $assert with a $error severity.
+- <b>`ASSERT_WARNING(EXPR, MESSAGE)`</b><br>
+Encapsulates a SystemVerilog $assert with a $warning severity.
+- <b>`ASSERT_INFO(EXPR, MESSAGE)`</b><br>
+Encapsulates a SystemVerilog $assert with an $info severity.
+
+Where:
+- <b>`EXPR`</b> is the condition for the assertion (what you expect to be true)
+- <b>`MESSAGE`</b> is the message string to report if the assertion fails
+
+## PkgChdrUtils
+
+The `PkgChdrUtils` package includes various definitions and functions for
+interacting with the RFNoC network protocol, called the Condensed Hierarchical
+Datagram for RFNoC (CHDR). See `PkgChdrUtils.sv` for additional documentation.
+
+## PkgChdrData
+
+The `PkgChdrData` package contains the CHDR and item data types, as well as
+utilities, that are useful for interacting with RFNoC data. An *item* refers to
+an RF data sample or whatever unit of data an RFNoC block expects.
+
+For example, the CHDR protocol data word type (`chdr_word_t`) and the RF sample
+data type (`item_t`) can be defined using the following example:
+
+ localparam CHDR_W = 64; // CHDR bus width
+ localparam ITEM_W = 32; // RF data sample size (sc16)
+ typedef ChdrData #(CHDR_W, ITEM_W)::chdr_word_t chdr_word_t;
+ typedef ChdrData #(CHDR_W, ITEM_W)::item_t item_t;
+
+SystemVerilog queues are used to store CHDR words and data samples. A queue of
+CHDR words or data samples can be reorganized into queues of different data
+widths using the following example:
+
+ chdr_word_t chdr_words[$]; // Queue of CHDR packet words
+ item_t samples[$]; // Queue of RF data samples
+ logic [7:0] bytes[$]; // Queue of bytes
+
+ // Convert the CHDR words to samples
+ samples = ChdrData#(CHDR_W, ITEM_W)::chdr_to_item(chdr_words);
+
+ // Convert the samples to CHDR words
+ chdr_words = ChdrData#(CHDR_W, ITEM_W)::item_to_chdr(samples);
+
+ // Convert the samples to a queue of bytes
+ bytes = ChdrData#(ITEM_W, 8)::chdr_to_item(samples);
+
+ // Convert the bytes to a queue of samples
+ bytes = ChdrData#(ITEM_W, 8)::item_to_chdr(samples);
+
+## PkgRfnocBlockCtrlBfm
+
+The `PkgRfnocBlockCtrlBfm` package contains the `RfnocBlockCtrlBfm` bus
+functional model (BFM) used to emulate a software block controller for an RFNoC
+block. This is the BFM used to interact with an RFNoC block in simulation. See
+the \ref md_usrp3_sim_writing_sim_top "testbench example" for an example
+of how to instantiate and connect the BFM to your DUT.
+
+To be used, the BFM must be connected to the RFNoC block using an
+`RfnocBackendIf` interface for the RFNoC backend interface and `AxiStreamIf`
+interfaces for the AXIS-CHDR ports.
+
+Once connected, several member functions are available through the BFM. A few
+examples are shown below, but many more are available. Refer to
+`PkgRfnocBlockCtrlBfm.sv` for additional documentation.
+
+- <b>`RfnocBlockCtrlBfm::run()`</b><br>
+Start the BFMs running. This should be called at the start of the testbench
+after `start_tb()` and before the BFM is used.
+- <b>`RfnocBlockCtrlBfm::reg_read(input ctrl_address_t addr, output ctrl_word_t word)`</b><br>
+Read a register from the RFNoC block.
+- <b>`RfnocBlockCtrlBfm::reg_write(ctrl_address_t addr, ctrl_word_t word)`</b><br>
+Write to a register on the RFNoC block.
+- <b>`send_items(int port, item_t items[$], chdr_word_t metadata[$] = {}, packet_info_t pkt_info = 0)`</b><br>
+Enqueue a packet of samples (or other data items) to be sent by the BFM to the
+RFNoC block on the indicated block port.
+- <b>`recv(int port, output chdr_word_t data[$], output int data_bytes)`</b><br>
+Recv a packet of samples (or other data items) from the indicated port on the
+RFNoC block.
+- <b>`set_master_stall_prob(int stall_probability = DEF_STALL_PROB)`</b><br>
+Set the probability, as value from 0-100, of the BFM's AXI-Stream master
+stalling (deasserting TVALID) between transfers.
+- <b>`set_slave_stall_prob(int stall_probability = DEF_STALL_PROB)`</b><br>
+Set the probability, as value from 0-100, of the BFM's AXI-Stream slave
+stalling (deasserting TREADY) on a given clock cycle.
+
+The level of push-back on the flow control used by the AXI-Stream interfaces of
+the BFM are controlled by setting a probability. This allows you to easily test
+underflow and overflow tolerance in your testbenches.
+
+Low-level tasks and functions are also available for inputting raw packets
+directly.
+
+## sim_clock_gen
+
+The `sim_clock_gen` module makes it easy create clocks and synchronous resets,
+and to interact with them. See `sim_clock_gen.sv` for additional documentation.
+
+Some features include:
+
+- Start and stop the clock
+- Change the frequency
+- Change the duty cycle
+- Kill the clock (prevent any new simulation events)
+- Wait for \em n rising/falling clock edges
+
+## PkgAxiStream
+
+The `PkgAxiStreamBfm` package contains the `AxistreamPacket` and `AxiStreamBfm`
+classes which are used to model AXI4-Stream interfaces in the testbenches.
+`AxiStreamIf` is the interface used for AXI-Stream. The RFNoC CHDR BFMs inherit
+from AxiStreamBfm in order to implement the AXI-Stream interfaces used by
+RFNoC.
+
+The AXI-Stream BFMs provide typical SystemVerilog `put()`, `get()`,
+`try_put()`, and `try_get()` tasks and functions for interacting with the
+models. Many other useful functions are also available. See the package file
+for details. \ No newline at end of file
diff --git a/fpga/docs/usrp3/sim/writing_sim_makefile.md b/fpga/docs/usrp3/sim/writing_sim_makefile.md
new file mode 100644
index 000000000..c503e7e04
--- /dev/null
+++ b/fpga/docs/usrp3/sim/writing_sim_makefile.md
@@ -0,0 +1,240 @@
+# Writing a Simulation Makefile
+
+The testbench Makefile tells the build tools what to build, where to build it,
+dependency information, and runtime information. The build infrastructure will
+handle the how-to part for each supported simulation tool.
+
+An example makefile for a testbench is shown below. If creating a testbench for
+RFNoC, it is recommended to use the RFNoC ModTool to generate a Makefile
+template for your RFNoC block.
+
+ #
+ # Copyright 2020 Ettus Research, a National Instruments Brand
+ #
+ # SPDX-License-Identifier: LGPL-3.0-or-later
+ #
+
+ #-------------------------------------------------
+ # Top-of-Makefile
+ #-------------------------------------------------
+ # Define BASE_DIR to point to the "top" dir. Note:
+ # UHD_FPGA_DIR must be passed into this Makefile.
+ ifndef UHD_FPGA_DIR
+ $(error "UHD_FPGA_DIR is not set! Must point to UHD FPGA repository!")
+ endif
+ BASE_DIR = $(UHD_FPGA_DIR)/usrp3/top
+ # Include viv_sim_preample after defining BASE_DIR
+ include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+ #-------------------------------------------------
+ # Design Specific
+ #-------------------------------------------------
+ # Define part using PART_ID (<device>/<package>/<speedgrade>)
+ ARCH = kintex7
+ PART_ID = xc7k410t/ffg900/-2
+
+ # Include makefiles and sources for the DUT and its dependencies
+ include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs
+ include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs
+ include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+ include $(BASE_DIR)/../lib/axi/Makefile.srcs
+ include $(BASE_DIR)/../lib/control/Makefile.srcs
+
+ DESIGN_SRCS += $(abspath \
+ $(RFNOC_CORE_SRCS) \
+ $(RFNOC_UTIL_SRCS) \
+ $(RFNOC_OOT_SRCS) \
+ $(FIFO_SRCS) \
+ $(AXI_SRCS) \
+ $(CONTROL_LIB_SRCS) \
+ )
+
+ #-------------------------------------------------
+ # IP Specific
+ #-------------------------------------------------
+ # If simulation contains IP, define the IP_DIR and point
+ # it to the base level IP directory
+ IP_DIR = $(BASE_DIR)/x300/ip
+ LIB_IP_DIR = $(BASE_DIR)/../lib/ip
+
+ # Include makefiles and sources for all IP components
+ # *after* defining the IP_DIR
+ include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+ include $(LIB_IP_DIR)/axi_fft/Makefile.inc
+
+ DESIGN_SRCS += $(abspath \
+ $(IP_FIFO_4K_2CLK_SRCS) \
+ $(LIB_IP_AXI_FFT_SRCS) \
+ rfnoc_block_example.v \
+ )
+
+ #-------------------------------------------------
+ # Testbench Specific
+ #-------------------------------------------------
+ include $(BASE_DIR)/../sim/general/Makefile.srcs
+ include $(BASE_DIR)/../sim/axi/Makefile.srcs
+
+ # Define only one top-level module
+ SIM_TOP = rfnoc_block_example_tb
+
+ # Simulation runtime in microseconds
+ SIM_RUNTIME_US = 1000
+
+ SIM_SRCS = \
+ $(abspath rfnoc_block_example_tb.sv) \
+
+ #-------------------------------------------------
+ # Bottom-of-Makefile
+ #-------------------------------------------------
+ # Include all simulator specific makefiles here
+ # Each should define a unique target to simulate
+ # e.g. xsim, vsim, etc and a common "clean" target
+ include $(BASE_DIR)/../tools/make/viv_simulator.mak
+
+You will notice that the Makefile has 5 distinct sections.
+
+## Section 1: Boilerplate
+
+ #-------------------------------------------------
+ # Top-of-Makefile
+ #-------------------------------------------------
+ # Define BASE_DIR to point to the "top" dir. Note:
+ # UHD_FPGA_DIR must be passed into this Makefile.
+ ifndef UHD_FPGA_DIR
+ $(error "UHD_FPGA_DIR is not set! Must point to UHD FPGA repository!")
+ endif
+ BASE_DIR = $(UHD_FPGA_DIR)/usrp3/top
+ # Include viv_sim_preample after defining BASE_DIR
+ include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
+
+Before declaring any variables or using any recipes, the following must be
+performed (in order):
+
+- Define `BASE_DIR` to tell the build system where the `<repo>/fpga/usrp3/top`
+ directory is relative to the current testbench directory
+- Include `viv_sim_preamble.mak` to initialize boilerplate variables and
+ functions
+
+This example uses the make variable UHD_FPGA_DIR to specify the location of the
+FPGA repository. This is useful for out-of-tree modules. UHD_FPGA_DIR is the
+variable used by CMake for the RFNoC examples.
+
+## Section 2: Design Specific
+
+ #-------------------------------------------------
+ # Design Specific
+ #-------------------------------------------------
+ # Define part using PART_ID (<device>/<package>/<speedgrade>)
+ ARCH = kintex7
+ PART_ID = xc7k410t/ffg900/-2
+
+ # Include makefiles and sources for the DUT and its dependencies
+ include $(BASE_DIR)/../lib/rfnoc/core/Makefile.srcs
+ include $(BASE_DIR)/../lib/rfnoc/utils/Makefile.srcs
+ include $(BASE_DIR)/../lib/fifo/Makefile.srcs
+ include $(BASE_DIR)/../lib/axi/Makefile.srcs
+ include $(BASE_DIR)/../lib/control/Makefile.srcs
+
+ DESIGN_SRCS += $(abspath \
+ $(RFNOC_CORE_SRCS) \
+ $(RFNOC_UTIL_SRCS) \
+ $(RFNOC_OOT_SRCS) \
+ $(FIFO_SRCS) \
+ $(AXI_SRCS) \
+ $(CONTROL_LIB_SRCS) \
+ )
+
+This section contains pointers to sources and other variables needed for the
+DUT to function. In the example above, we are including all sources from the
+`lib/fifo`, `lib/axi`, `lib/control` directories. These may not be needed for
+your simulation, in which case they can be removed to reduce compile times.
+
+The following makefile variables are special and should be defined:
+
+- `ARCH`: The architecture targeted for the simulation.
+- `PART_ID`: The exact part targeted for the simulation. Format:
+ `<device>/<package>/<speedgrade>`
+- `DESIGN_SRCS`: Space-separated paths to the DUT and all of its dependencies.
+
+If `ARCH` and `PART_ID` are not specified, a default part will be assumed. This
+may be fine if your DUT doesn't have any architecture-specific IP.
+
+## Section 3: IP Specific
+
+ #-------------------------------------------------
+ # IP Specific
+ #-------------------------------------------------
+ # If simulation contains IP, define the IP_DIR and point
+ # it to the base level IP directory
+ IP_DIR = $(BASE_DIR)/x300/ip
+ LIB_IP_DIR = $(BASE_DIR)/../lib/ip
+
+ # Include makefiles and sources for all IP components
+ # *after* defining the IP_DIR
+ include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
+ include $(LIB_IP_DIR)/axi_fft/Makefile.inc
+
+ DESIGN_SRCS += $(abspath \
+ $(IP_FIFO_4K_2CLK_SRCS) \
+ $(LIB_IP_AXI_FFT_SRCS) \
+ rfnoc_block_example.v \
+ )
+
+If the DUT depends on any Xilinx IP then this section is required. It tells the
+tools which IP cores need to be built in order to run the simulation. The IP
+specific Makefile `include` statements handle the "how" part of building IP. As
+long as the correct Makefile is included and the IP XCI sources are added to
+`DESIGN_SRCS`, the IP intermediates will be built correctly.
+
+The `IP_DIR` variable shown here is defined to point to the base IP directory
+that contains target-specific IP sources. The `IP_LIB_DIR` variable shown here
+is defined to point to the base IP directory that contains target-independent
+IP sources.
+
+The IP included in this example may not be needed for your testbench, in which
+case it can be removed to reduce compile times.
+
+## Section 4: Testbench Specific
+
+ #-------------------------------------------------
+ # Testbench Specific
+ #-------------------------------------------------
+ include $(BASE_DIR)/../sim/general/Makefile.srcs
+ include $(BASE_DIR)/../sim/axi/Makefile.srcs
+
+ # Define only one top-level module
+ SIM_TOP = rfnoc_block_example_tb
+
+ # Simulation runtime in microseconds
+ SIM_RUNTIME_US = 1000
+
+ SIM_SRCS = \
+ $(abspath rfnoc_block_example_tb.sv) \
+
+This section contains all sources and parameters for the actual testbench. Any simulation
+dependency makefiles can be included here.
+
+The following variables should be defined:
+
+- `SIM_TOP`: The top-level module name for the simulation.
+- `SIM_RUNTIME_US`: The maximum runtime of the simulation in microseconds. At
+ this time `$finish` will be called to terminate the testbench.
+- `SIM_SRCS`: This is similar to DESIGN_SRCS except that it should contain a
+ path to `SIM_TOP` and all of its dependencies.
+
+## Section 5: Tool Support
+
+ #-------------------------------------------------
+ # 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
+
+Now that the Makefile knows all the basic information about the testbench,
+include tool-specific makefiles to implement simulation targets. Currently the
+following simulator makefiles exits:
+
+- `<repo>/fpga/tools/make/viv_simulator.mak`<br>
+ This makefile supports both Vivado and ModelSim simulators.
diff --git a/fpga/docs/usrp3/sim/writing_sim_top.md b/fpga/docs/usrp3/sim/writing_sim_top.md
new file mode 100644
index 000000000..e7fdc2720
--- /dev/null
+++ b/fpga/docs/usrp3/sim/writing_sim_top.md
@@ -0,0 +1,198 @@
+# Writing a Top-level Simulation Module
+
+The top-level simulation module will instantiate the DUT and implement
+self-checking behavior. Testbenches can be written in any language
+(SystemVerilog, Verilog, VHDL) but to take advantage of our repository of
+simulation libraries, it is recommended that SystemVerilog be used.
+
+An example testbench is shown below. This example is for an RFNoC block. If
+creating a testbench for RFNoC, it is recommended to use the RFNoC ModTool to
+generate a testbench template for your RFNoC block.
+
+See \ref md_usrp3_sim_simulation_libraries for documentation on the simulation
+libraries used in this example.
+
+ //
+ // Copyright 2020 Ettus Research, A National Instruments Company
+ //
+ // SPDX-License-Identifier: LGPL-3.0-or-later
+ //
+ // Module: rfnoc_block_example_tb
+ //
+ // Description: An example top-level testbench
+ //
+
+ `default_nettype none
+
+
+ module rfnoc_block_example_tb;
+
+ `include "test_exec.svh"
+
+ import PkgTestExec::*;
+ import PkgChdrUtils::*;
+ import PkgRfnocBlockCtrlBfm::*;
+
+ //---------------------------------------------------------------------------
+ // Testbench Configuration
+ //---------------------------------------------------------------------------
+
+ localparam [ 9:0] THIS_PORTID = 10'h123;
+ localparam int CHDR_W = 64;
+ localparam int ITEM_W = 32;
+ localparam int NUM_PORTS_I = 1;
+ localparam int NUM_PORTS_O = 1;
+ localparam int MTU = 13;
+ localparam int SPP = 64;
+ localparam int PKT_SIZE_BYTES = SPP * (ITEM_W/8);
+ localparam int STALL_PROB = 25; // Default BFM stall probability
+ localparam real CHDR_CLK_PER = 5.0; // 200 MHz
+ localparam real CTRL_CLK_PER = 25.0; // 40 MHz
+
+ //---------------------------------------------------------------------------
+ // Clocks and Resets
+ //---------------------------------------------------------------------------
+
+ bit rfnoc_chdr_clk;
+ bit rfnoc_ctrl_clk;
+
+ sim_clock_gen #(CHDR_CLK_PER) rfnoc_chdr_clk_gen (.clk(rfnoc_chdr_clk), .rst());
+ sim_clock_gen #(CTRL_CLK_PER) rfnoc_ctrl_clk_gen (.clk(rfnoc_ctrl_clk), .rst());
+
+ //---------------------------------------------------------------------------
+ // Bus Functional Models
+ //---------------------------------------------------------------------------
+
+ // Backend Interface
+ RfnocBackendIf backend (rfnoc_chdr_clk, rfnoc_ctrl_clk);
+
+ // AXIS-Ctrl Interface
+ AxiStreamIf #(32) m_ctrl (rfnoc_ctrl_clk, 1'b0);
+ AxiStreamIf #(32) s_ctrl (rfnoc_ctrl_clk, 1'b0);
+
+ // AXIS-CHDR Interfaces
+ AxiStreamIf #(CHDR_W) m_chdr [NUM_PORTS_I] (rfnoc_chdr_clk, 1'b0);
+ AxiStreamIf #(CHDR_W) s_chdr [NUM_PORTS_O] (rfnoc_chdr_clk, 1'b0);
+
+ // Block Controller BFM
+ RfnocBlockCtrlBfm #(CHDR_W, ITEM_W) blk_ctrl = new(backend, m_ctrl, s_ctrl);
+
+ // CHDR word and item/sample data types
+ typedef ChdrData #(CHDR_W, ITEM_W)::chdr_word_t chdr_word_t;
+ typedef ChdrData #(CHDR_W, ITEM_W)::item_t item_t;
+
+ // Connect block controller to BFMs
+ for (genvar i = 0; i < NUM_PORTS_I; i++) begin : gen_bfm_input_connections
+ initial begin
+ blk_ctrl.connect_master_data_port(i, m_chdr[i], PKT_SIZE_BYTES);
+ blk_ctrl.set_master_stall_prob(i, STALL_PROB);
+ end
+ end
+ for (genvar i = 0; i < NUM_PORTS_O; i++) begin : gen_bfm_output_connections
+ initial begin
+ blk_ctrl.connect_slave_data_port(i, s_chdr[i]);
+ blk_ctrl.set_slave_stall_prob(i, STALL_PROB);
+ end
+ end
+
+ //---------------------------------------------------------------------------
+ // Device Under Test (DUT)
+ //---------------------------------------------------------------------------
+
+ // DUT Slave (Input) Port Signals
+ logic [CHDR_W*NUM_PORTS_I-1:0] s_rfnoc_chdr_tdata;
+ logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tlast;
+ logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tvalid;
+ logic [ NUM_PORTS_I-1:0] s_rfnoc_chdr_tready;
+
+ // DUT Master (Output) Port Signals
+ logic [CHDR_W*NUM_PORTS_O-1:0] m_rfnoc_chdr_tdata;
+ logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tlast;
+ logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tvalid;
+ logic [ NUM_PORTS_O-1:0] m_rfnoc_chdr_tready;
+
+ // Map the array of BFMs to a flat vector for the DUT connections
+ for (genvar i = 0; i < NUM_PORTS_I; i++) begin : gen_dut_input_connections
+ // Connect BFM master to DUT slave port
+ assign s_rfnoc_chdr_tdata[CHDR_W*i+:CHDR_W] = m_chdr[i].tdata;
+ assign s_rfnoc_chdr_tlast[i] = m_chdr[i].tlast;
+ assign s_rfnoc_chdr_tvalid[i] = m_chdr[i].tvalid;
+ assign m_chdr[i].tready = s_rfnoc_chdr_tready[i];
+ end
+ for (genvar i = 0; i < NUM_PORTS_O; i++) begin : gen_dut_output_connections
+ // Connect BFM slave to DUT master port
+ assign s_chdr[i].tdata = m_rfnoc_chdr_tdata[CHDR_W*i+:CHDR_W];
+ assign s_chdr[i].tlast = m_rfnoc_chdr_tlast[i];
+ assign s_chdr[i].tvalid = m_rfnoc_chdr_tvalid[i];
+ assign m_rfnoc_chdr_tready[i] = s_chdr[i].tready;
+ end
+
+ rfnoc_block_example #(
+ .THIS_PORTID (THIS_PORTID),
+ .CHDR_W (CHDR_W),
+ .MTU (MTU)
+ ) dut (
+ .rfnoc_chdr_clk (rfnoc_chdr_clk),
+ .rfnoc_ctrl_clk (rfnoc_ctrl_clk),
+ .rfnoc_core_config (backend.cfg),
+ .rfnoc_core_status (backend.sts),
+ .s_rfnoc_chdr_tdata (s_rfnoc_chdr_tdata),
+ .s_rfnoc_chdr_tlast (s_rfnoc_chdr_tlast),
+ .s_rfnoc_chdr_tvalid (s_rfnoc_chdr_tvalid),
+ .s_rfnoc_chdr_tready (s_rfnoc_chdr_tready),
+ .m_rfnoc_chdr_tdata (m_rfnoc_chdr_tdata),
+ .m_rfnoc_chdr_tlast (m_rfnoc_chdr_tlast),
+ .m_rfnoc_chdr_tvalid (m_rfnoc_chdr_tvalid),
+ .m_rfnoc_chdr_tready (m_rfnoc_chdr_tready),
+ .s_rfnoc_ctrl_tdata (m_ctrl.tdata),
+ .s_rfnoc_ctrl_tlast (m_ctrl.tlast),
+ .s_rfnoc_ctrl_tvalid (m_ctrl.tvalid),
+ .s_rfnoc_ctrl_tready (m_ctrl.tready),
+ .m_rfnoc_ctrl_tdata (s_ctrl.tdata),
+ .m_rfnoc_ctrl_tlast (s_ctrl.tlast),
+ .m_rfnoc_ctrl_tvalid (s_ctrl.tvalid),
+ .m_rfnoc_ctrl_tready (s_ctrl.tready)
+ );
+
+ //---------------------------------------------------------------------------
+ // Main Test Process
+ //---------------------------------------------------------------------------
+
+ initial begin : tb_main
+
+ // Initialize the test exec object for this testbench
+ test.start_tb("example");
+
+ // Start the BFMs running
+ //blk_ctrl.run();
+
+ //--------------------------------
+ // Reset
+ //--------------------------------
+
+ test.start_test("Flush block then reset it", 10us);
+ //blk_ctrl.flush_and_reset();
+ test.end_test();
+
+ //--------------------------------
+ // Test Sequences
+ //--------------------------------
+
+ test.start_test("This is an example test", 10us);
+ // < Add test code here >
+ test.end_test();
+
+ //--------------------------------
+ // Finish Up
+ //--------------------------------
+
+ // Display final statistics and results
+ test.end_tb();
+ end : tb_main
+
+ endmodule : rfnoc_block_example_tb
+
+
+ `default_nettype wire
+
+
diff --git a/fpga/docs/usrp3/sim/writing_testbenches.md b/fpga/docs/usrp3/sim/writing_testbenches.md
index cfbbcdbce..2c30434d2 100644
--- a/fpga/docs/usrp3/sim/writing_testbenches.md
+++ b/fpga/docs/usrp3/sim/writing_testbenches.md
@@ -6,466 +6,19 @@ Even recurring tasks like reporting and monitoring are implemented by framework
Each executable FPGA unit test must have the following components:
-1. A Makefile
-2. A Testbench top-level module
+1. \ref md_usrp3_sim_writing_sim_makefile "A simulation Makefile"
+2. \ref md_usrp3_sim_writing_sim_top "A top-level simulation module"
-## Testbench Makefile
-
-The Testbench Makefile tell the build tools what to build, where to build it, dependency information and runtime information.
-The build infrastructure will handle the how-to part for each supported simulation tool.
-
-Here is a sample Makefile (you are encouraged to use this as a starting point)
-
- #
- # Copyright 2015 Ettus Research LLC
- #
-
- #-------------------------------------------------
- # Top-of-Makefile
- #-------------------------------------------------
- # Define BASE_DIR to point to the "top" dir
- BASE_DIR = $(abspath ../../..)
- # Include viv_sim_preample after defining BASE_DIR
- include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
-
- #-------------------------------------------------
- # Design Specific
- #-------------------------------------------------
- # Define part using PART_ID (<device>/<package>/<speedgrade>)
- ARCH = kintex7
- PART_ID = xc7k410t/ffg900/-2
-
- # Include makefiles and sources for the DUT and its dependencies
- include $(BASE_DIR)/../lib/fifo/Makefile.srcs
- include $(BASE_DIR)/../lib/axi/Makefile.srcs
- include $(BASE_DIR)/../lib/control/Makefile.srcs
-
- DESIGN_SRCS = $(abspath \
- $(FIFO_SRCS) \
- $(AXI_SRCS) \
- $(CONTROL_LIB_SRCS) \
- )
-
- #-------------------------------------------------
- # IP Specific
- #-------------------------------------------------
- # If simulation contains IP, define the IP_DIR and point
- # it to the base level IP directory
- IP_DIR = ../../ip
-
- # Include makefiles and sources for all IP components
- # *after* defining the IP_DIR
- include $(IP_DIR)/ddr3_32bit/Makefile.inc
- include $(IP_DIR)/axi_intercon_2x64_128/Makefile.inc
- include $(IP_DIR)/fifo_short_2clk/Makefile.inc
- include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
- include $(IP_DIR)/axi4_bram_1kx64/Makefile.inc
-
- DESIGN_SRCS += $(abspath \
- $(IP_DDR3_32BIT_SRCS) \
- $(IP_AXI_INTERCON_2X64_128_SRCS) \
- $(IP_FIFO_4K_2CLK_SRCS) \
- $(IP_FIFO_SHORT_2CLK_SRCS) \
- $(IP_AXI4_BRAM_1KX64_SRCS) \
- )
-
- #-------------------------------------------------
- # Testbench Specific
- #-------------------------------------------------
- include $(BASE_DIR)/../sim/general/Makefile.srcs
- include $(BASE_DIR)/../sim/axi/Makefile.srcs
-
- # Define only one toplevel module
- SIM_TOP = dram_fifo_tb
- # Simulation runtime in microseconds
- SIM_RUNTIME_US = 80
-
- SIM_SRCS = \
- $(abspath dram_fifo_tb.sv) \
- $(abspath axis_dram_fifo_single.sv) \
- $(IP_DDR3_32BIT_SIM_OUTS) \
- $(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
-
-You will notice that the Makefile has 5 distinct sections.
-
-### Section 1: Boilerplate
-
- #-------------------------------------------------
- # Top-of-Makefile
- #-------------------------------------------------
- # Define BASE_DIR to point to the "top" dir
- BASE_DIR = $(abspath ../../..)
- # Include viv_sim_preample after defining BASE_DIR
- include $(BASE_DIR)/../tools/make/viv_sim_preamble.mak
-
-Before declaring any variables or using any recipes, the following must be done (in order):
-
-- Define `BASE_DIR` to tell the build system where the `<repo>/usrp3/top` directory is relative to the
- current testbench directory.
-- Include `viv_sim_preamble.mak` to initialize boilerplate variables and functions
-
-### Section 2: Design Specific
-
- #-------------------------------------------------
- # Design Specific
- #-------------------------------------------------
- # Define part using PART_ID (<device>/<package>/<speedgrade>)
- ARCH = kintex7
- PART_ID = xc7k410t/ffg900/-2
-
- # Include makefiles and sources for the DUT and its dependencies
- include $(BASE_DIR)/../lib/fifo/Makefile.srcs
- include $(BASE_DIR)/../lib/axi/Makefile.srcs
- include $(BASE_DIR)/../lib/control/Makefile.srcs
-
- DESIGN_SRCS = $(abspath \
- $(FIFO_SRCS) \
- $(AXI_SRCS) \
- $(CONTROL_LIB_SRCS) \
- )
-
-This section contains pointers to sources and other variables for the DUT to function. In the
-example above, we are including all sources from the lib/fifo, lib/axi, lib/control directories.
-
-The following makefile variables are special and must be defined:
-
-- `ARCH`: The architecture targeted for the simulation.
-- `PART_ID`: The exact part targeted for the simulation. Format: `<device>/<package>/<speedgrade>`
-- `DESIGN_SRCS`: Space-separated paths to the DUT and all of its dependencies.
-
-### Section 3: IP Specific
-
- #-------------------------------------------------
- # IP Specific
- #-------------------------------------------------
- # If simulation contains IP, define the IP_DIR and point
- # it to the base level IP directory
- IP_DIR = ../../ip
-
- # Include makefiles and sources for all IP components
- # *after* defining the IP_DIR
- include $(IP_DIR)/ddr3_32bit/Makefile.inc
- include $(IP_DIR)/axi_intercon_2x64_128/Makefile.inc
- include $(IP_DIR)/fifo_short_2clk/Makefile.inc
- include $(IP_DIR)/fifo_4k_2clk/Makefile.inc
- include $(IP_DIR)/axi4_bram_1kx64/Makefile.inc
-
- DESIGN_SRCS += $(abspath \
- $(IP_DDR3_32BIT_SRCS) \
- $(IP_AXI_INTERCON_2X64_128_SRCS) \
- $(IP_FIFO_4K_2CLK_SRCS) \
- $(IP_FIFO_SHORT_2CLK_SRCS) \
- $(IP_AXI4_BRAM_1KX64_SRCS) \
- )
-
-If the DUT depends on any Xilinx IP then this section is required. It tell the tools
-which IP cores need to be built in order to run the simulation. The IP specific Makefile
-includes handle the "how" part of building IP. As long as the correct Mafefile is included
-and the IP XCI sources are added to `DESIGN_SRCS`, the IP intermediates will be built correctly.
-
-The `IP_DIR` variable must be defined to point to the base ip directory that contains XCI sources.
-
-### Section 4: Testbench Specific
-
- #-------------------------------------------------
- # Testbench Specific
- #-------------------------------------------------
- include $(BASE_DIR)/../sim/general/Makefile.srcs
- include $(BASE_DIR)/../sim/axi/Makefile.srcs
-
- # Define only one toplevel module
- SIM_TOP = dram_fifo_tb
- # Simulation runtime in microseconds
- SIM_RUNTIME_US = 80
-
- SIM_SRCS = \
- $(abspath dram_fifo_tb.sv) \
- $(abspath axis_dram_fifo_single.sv) \
- $(IP_DDR3_32BIT_SIM_OUTS) \
- $(SIM_GENERAL_SRCS) \
- $(SIM_AXI_SRCS)
-
-This section contains all sources and parameters for the actual testbench. Any simulation
-dependency makefiles can be included here.
-
-The following variables must be defined:
-
-- `SIM_TOP`: The toplevel module name for the simulation project
-- `SIM_RUNTIME_US`: The maximum runtime of the simulation in microseconds. At this time $finish will be called to terminate the testbench.
-- `SIM_SRCS`: This is similar to DESIGN_SRCS except that that should contain a path to `SIM_TOP` and all of its dependencies.
-
-### Section 5: Tool Support
-
- #-------------------------------------------------
- # 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
-
-Now that the Makefile knows all the basic information about the testbench, include tool-specific
-makefiles to implement simulation targets. Currently the following simulator makefiles exits:
-
-- ``<repo>/tools/make/viv_simulator.mak``
-
-Please refer to the next section for more information about targets
-
-
-## Testbench Top Level
-
-The top-level module will instantiate the DUT and implement self-checking behavior.
-Test benches could be written in any language (SystemVerilog, Verilog, VHDL) but
-to take advantage of our repository of simulation libraries, it is recommended that SystemVerilog be used.
-
-Here is a sample SystemVerilog top module (you are encouraged to use this as a starting point)
-
- //
- // Copyright 2015 Ettus Research LLC
- //
-
- `timescale 1ns/1ps
- `define NS_PER_TICK 1
- `define NUM_TEST_CASES 3
-
- `include "sim_clks_rsts.vh"
- `include "sim_exec_report.vh"
- `include "sim_cvita_lib.sv"
-
- module example_fifo_tb();
- `TEST_BENCH_INIT("example_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
-
- // Define all clocks and resets
- `DEFINE_CLK(bus_clk, 1000/166.6667, 50) //166MHz bus_clk
- `DEFINE_RESET(bus_rst, 0, 100) //100ns for GSR to deassert
-
- cvita_stream_t chdr_i (.clk(bus_clk));
- cvita_stream_t chdr_o (.clk(bus_clk));
-
- // Initialize DUT
- axi_fifo #(.WIDTH(65), .SIZE(24)) dut_single (
- .clk(bus_clk),
- .reset(bus_rst),
- .clear(1'b0),
-
- .i_tdata({chdr_i.axis.tlast, chdr_i.axis.tdata}),
- .i_tvalid(chdr_i.axis.tvalid),
- .i_tready(chdr_i.axis.tready),
-
- .o_tdata({chdr_o.axis.tlast, chdr_o.axis.tdata}),
- .o_tvalid(chdr_o.axis.tvalid),
- .o_tready(chdr_o.axis.tready),
-
- .space(),
- .occupied()
- );
-
- //Testbench variables
- cvita_hdr_t header, header_out;
- cvita_stats_t stats;
-
- //------------------------------------------
- //Main thread for testbench execution
- //------------------------------------------
- initial begin : tb_main
-
- `TEST_CASE_START("Wait for reset");
- while (bus_rst) @(posedge bus_clk);
- `TEST_CASE_DONE((~bus_rst));
-
- repeat (200) @(posedge bus_clk);
-
- header = '{
- pkt_type:DATA, has_time:0, eob:0, seqno:12'h666,
- length:0, sid:$random, timestamp:64'h0};
-
- `TEST_CASE_START("Fill up empty FIFO then drain (short packet)");
- chdr_o.axis.tready = 0;
- chdr_i.push_ramp_pkt(16, 64'd0, 64'h100, header);
- chdr_o.axis.tready = 1;
- chdr_o.wait_for_pkt_get_info(header_out, stats);
- `ASSERT_ERROR(stats.count==16, "Bad packet: Length mismatch");
- `ASSERT_ERROR(header.sid==header_out.sid, "Bad packet: Wrong SID");
- `ASSERT_ERROR(chdr_i.axis.tready, "Bus not ready");
- `TEST_CASE_DONE(1);
-
- header = '{
- pkt_type:DATA, has_time:1, eob:0, seqno:12'h666,
- length:0, sid:$random, timestamp:64'h0};
-
- `TEST_CASE_START("Concurrent read and write (single packet)");
- chdr_o.axis.tready = 1;
- fork
- begin
- chdr_i.push_ramp_pkt(20, 64'd0, 64'h100, header);
- end
- begin
- chdr_o.wait_for_pkt_get_info(header_out, stats);
- end
- join
- `ASSERT_ERROR(stats.count==20, "Bad packet: Length mismatch");
- `TEST_CASE_DONE(1);
- end
- endmodule
-
-
-Each testbench should have the following basic components:
-
-### Timescale Defines and Includes
-
- `timescale 1ns/1ps
- `define NS_PER_TICK 1
- `define NUM_TEST_CASES 3
-
- `include "sim_clks_rsts.vh"
- `include "sim_exec_report.vh"
- `include "sim_cvita_lib.sv"
-
-In addition to the timescale, the infrastructure needs to know the number of
-nanoseconds per simulator tick. This can be a floating point number.
-
-
-In addition to the timescale, you may include any Verilog/SystemVerilog headers here.
-
-### Main Module Definition
-
- `include "sim_exec_report.vh"
-
- module example_fifo_tb();
- `TEST_BENCH_INIT("example_fifo_tb",`NUM_TEST_CASES,`NS_PER_TICK)
-
- ...
-
- //------------------------------------------
- //Main thread for testbench execution
- //------------------------------------------
- initial begin : tb_main
-
- ...
-
- end
- endmodule
-
-The name of the main module must match the ``SIM_TOP`` variable value in the Makefile.
-To register this module with the framework, the ``TEST_BENCH_INIT`` macro must be called.
-This macro is defined in ``<repo>/usrp3/sim/general/sim_exec_report.vh``.
-
-``TEST_BENCH_INIT``:
-
- // Initializes state for a test bench.
- // This macro *must be* called within the testbench module but
- // outside the primary initial block
- // Its sets up boilerplate code for:
- // - Logging to console
- // - Test execution tracking
- // - Gathering test results
- // - Bounding execution time based on the SIM_RUNTIME_US vdef
- //
- // Usage: `TEST_BENCH_INIT(test_name,min_tc_run_count,ns_per_tick)
- // where
- // - tb_name: Name of the testbench. (Only used during reporting)
- // - min_tc_run_count: Number of test cases in testbench. (Used to detect stalls and inf-loops)
- // - ns_per_tick: The time_unit_base from the timescale declaration
-
-The testbench must also have at least one initial block that consists tests cases (covered later).
-For the sake of convention it should be called ``tb_main``. *All test cases must live in ``tb_main``*. You may
-have other initial block but they must not call macros from ``sim_exec_report.vh`` because the code
-there is not thread-safe.
-
-### Test Cases
-
-A test case in this context is defined as an independent entity that validates an aspect of the DUT behavior
-and which is independent from other test cases i.e. the result of one test case should ideally not affect others.
-
-
-Test cases are wrapped in the ``TEST_CASE_START`` and ``TEST_CASE_DONE`` macros:
-
- `TEST_CASE_START("Fill up empty FIFO then drain (short packet)");
- chdr_o.axis.tready = 0;
- chdr_i.push_ramp_pkt(16, 64'd0, 64'h100, header);
- chdr_o.axis.tready = 1;
- chdr_o.wait_for_pkt_get_info(header_out, stats);
- `ASSERT_ERROR(stats.count==16, "Bad packet: Length mismatch");
- `ASSERT_ERROR(header.sid==header_out.sid, "Bad packet: Wrong SID");
- `ASSERT_ERROR(chdr_i.axis.tready, "Bus not ready");
- `TEST_CASE_DONE(1);
-
-Here are the signatures of the two macros:
-
-``TEST_CASE_START``:
-
- // Indicates the start of a test case
- // This macro *must be* called inside the primary initial block
- //
- // Usage: `TEST_CASE_START(test_name)
- // where
- // - test_name: The name of the test.
- //
-
-``TEST_CASE_DONE``:
-
- // Indicates the end of a test case
- // This macro *must be* called inside the primary initial block
- // The pass/fail status of test case is determined based on the
- // the user specified outcome and the number of fatal or error
- // ASSERTs triggered in the test case.
- //
- // Usage: `TEST_CASE_DONE(test_result)
- // where
- // - test_result: User specified outcome
- //
-
-In addition to the test case status, it is also possible to have asserts within
-a test case. We have wrappers for the different kinds of SystemVerilog asserts
-that additionally fail the test case in case the assert fails. An assert triggered
-in a test case will not affect the outcome of another (except for a fatal assert which
-halts the simulator). Supported assert macros:
-
- // Wrapper around a an assert.
- // ASSERT_FATAL throws an error assertion and halts the simulator
- // if cond is not satisfied
- //
- // Usage: `ASSERT_FATAL(cond,msg)
- // where
- // - cond: Condition for the assert
- // - msg: Message for the assert
- //
-
-
- // Wrapper around a an assert.
- // ASSERT_ERROR throws an error assertion and fails the test case
- // if cond is not satisfied. The simulator will *not* halt
- //
- // Usage: `ASSERT_ERROR(cond,msg)
- // where
- // - cond: Condition for the assert
- // - msg: Message for the assert
- //
-
-
- // Wrapper around a an assert.
- // ASSERT_WARNING throws an warning assertion but does not fail the
- // test case if cond is not satisfied. The simulator will *not* halt
- //
- // Usage: `ASSERT_WARNING(cond,msg)
- // where
- // - cond: Condition for the assert
- // - msg: Message for the assert
- //
-
-### Optional Libraries
+If creating a testbench for an RFNoC block, it is recommended to use the RFNoC
+ModTool (rfnoc_create_verilog.py) to create a template Makefile and testbench
+for your RFNoC block.
It is encouraged to use (and create) reusable libraries in product specific
test benches. Libraries can provide macros, modules, tasks and functions for
ease-of-use with particular protocols and subsystems.
-The \ref md_usrp3_sim_writing_testbenches page has more information.
+See the following manual pages for information about how to create the Makefile
+and top-level simulation file.
+
+- \subpage md_usrp3_sim_writing_sim_makefile "Writing a Simulation Makefile"
+- \subpage md_usrp3_sim_writing_sim_top "Writing a Top-level Simulation Module" \ No newline at end of file
diff --git a/fpga/docs/usrp3/simulation.md b/fpga/docs/usrp3/simulation.md
index 16afed462..ad0a9ec6d 100644
--- a/fpga/docs/usrp3/simulation.md
+++ b/fpga/docs/usrp3/simulation.md
@@ -2,10 +2,15 @@
## Instructions
- - \subpage md_usrp3_sim_running_testbenches "Running Testbenches"
- - \subpage md_usrp3_sim_writing_testbenches "Writing Testbenches"
+ - \subpage md_usrp3_sim_running_testbenches "Running a Testbench"
+ - \subpage md_usrp3_sim_writing_testbenches "Writing a Testbench"
## Library Reference
- - \subpage md_usrp3_sim_libs_general "General Purpose"
- - \subpage md_usrp3_sim_libs_axi "AXI"
+ - \subpage md_usrp3_sim_simulation_libraries "Testbench Simulation Libraries"
+
+## Legacy Library Reference
+
+ - \subpage md_usrp3_sim_legacy_testbenches "Legacy Testbenches"
+ - \subpage md_usrp3_sim_libs_general "Legacy General Purpose Simulation Libraries"
+ - \subpage md_usrp3_sim_libs_axi "Legacy AXI Interface Libraries"
diff --git a/fpga/docs/usrp3/vivado_env_utils.md b/fpga/docs/usrp3/vivado_env_utils.md
index ad5c6266e..601b9b5a5 100644
--- a/fpga/docs/usrp3/vivado_env_utils.md
+++ b/fpga/docs/usrp3/vivado_env_utils.md
@@ -2,22 +2,23 @@
## Environment Setup
-- Navigate to `usrp3/top/{project}` where project is:
- + x300: For USRP X300 and USRP X310
- + e3xx: For USRP E310
- + e320: For USRP E320
- + n3xx: For USRP N300/N310/N320
+- Navigate to `<repo>/fpga/usrp3/top/{project}` where {project} is:
+ + `x300:` For USRP X300/X310
+ + `e31x:` For USRP E310
+ + `e320:` For USRP E320
+ + `n3xx:` For USRP N300/N310/N320
- To setup up the Ettus Research Xilinx build environment run
+ `source setupenv.sh` (If Vivado is installed in the default path /opt/Xilinx/Vivado) _OR_
+ `source setupenv.sh --vivado-path=<VIVADO_PATH>` (where VIVADO_PATH is a non-default installation path)
-- This should not only enable building USRP FPGAs but also make the following utlities available
+- This should not only enable building USRP FPGAs but also make available the
+ utilities described in the following sections.
## ModelSim Specific
-The setupenv.sh script will search the system for ModelSim installations and setup everything to run it natively and
-within Vivado. The currently support versions of ModelSim are PE, DE, SE, DE-64, SE-64.
+The `setupenv.sh` script will search the system for ModelSim installations and setup everything to run it natively and
+within Vivado. The currently supported versions of ModelSim are PE, DE, SE, DE-64, SE-64.
The following functions are also available in the environment:
@@ -27,9 +28,9 @@ The following functions are also available in the environment:
### Create Vivado IP
- viv_create_new_ip: Create a new Vivado IP instance and a Makefile for it
+ viv_create_ip: Create a new Vivado IP instance and a Makefile for it
- Usage: viv_create_new_ip <IP Name> <IP Location> <IP VLNV> <Product>
+ Usage: viv_create_ip <IP Name> <IP Location> <IP VLNV> <Product>
- <IP Name>: Name of the IP instance
- <IP Location>: Base location for IP
- <IP VLNV>: The vendor, library, name, and version (VLNV) string for the IP as defined by Xilinx
@@ -40,7 +41,23 @@ The following functions are also available in the environment:
viv_modify_ip: Modify an existing Vivado IP instance
Usage: viv_modify_ip <IP XCI Path>
- - <IP XCI Path>: Path to the IP XCI file.
+ - <IP XCI Path>: Path to the IP XCI file
+
+### Modify existing Vivado Block Design (BD)
+
+ viv_modify_bd: Modify an existing Vivado BD instance
+
+ Usage: viv_modify_bd <BD File Path> <Product>
+ - <BD File Path>: Path to the BD file.
+ - <Product>: Product to generate IP for
+
+### Modify existing Vivado Tcl-based Block Design
+
+ viv_modify_tcl_bd: Modify an existing Vivado BD instance
+
+ Usage: viv_modify_tcl_bd <Tcl File Path> <Product>
+ - <Tcl File Path>: Path to the Tcl file for the block design.
+ - <Product>: Product to generate IP for
### List supported Vivado IP
@@ -62,7 +79,7 @@ The following functions are also available in the environment:
viv_hw_console: Launch the Tcl hardware console
- Usage: viv_upgrade_ip
+ Usage: viv_hw_console
### List connected JTAG devices
@@ -81,7 +98,7 @@ The following functions are also available in the environment:
### Probe Xilinx bitfile
- probe_bitfile: Probe a Xilinx bit file and report header information
+ probe_bitfile: Probe a Xilinx bitfile and report header information
Usage: probe_bitfile <Bitfile Path>
- <Bitfile Path>: Path to a .bit FPGA configuration file