8.1 KiB
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.
start_tb(string tb_name, realtime time_limit = 10ms)
Called at the start of the testbench. A time limit can be specified to prevent the testbench from never ending.end_tb(bit finish = 1)
Called at the end of the testbench. Displays final results and optionally calls$finish.start_test(string test_name, realtime time_limit = 0)
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.end_test(int test_result = 1)
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 thetest_exec.svhmacros, 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.start_timeout(
output timeout_t handle,
input realtime timeout_delay,
input string message = "Timeout",
input severity_t severity = SEV_ERROR)
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.end_timeout(timeout_t handle)
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.
ASSERT_FATAL(EXPR, MESSAGE)
Encapsulates a SystemVerilog $assert with a $fatal severity.ASSERT_ERROR(EXPR, MESSAGE)
Encapsulates a SystemVerilog $assert with a $error severity.ASSERT_WARNING(EXPR, MESSAGE)
Encapsulates a SystemVerilog $assert with a $warning severity.ASSERT_INFO(EXPR, MESSAGE)
Encapsulates a SystemVerilog $assert with an $info severity.
Where:
EXPRis the condition for the assertion (what you expect to be true)MESSAGEis 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.
RfnocBlockCtrlBfm::run()
Start the BFMs running. This should be called at the start of the testbench afterstart_tb()and before the BFM is used.RfnocBlockCtrlBfm::reg_read(input ctrl_address_t addr, output ctrl_word_t word)
Read a register from the RFNoC block.RfnocBlockCtrlBfm::reg_write(ctrl_address_t addr, ctrl_word_t word)
Write to a register on the RFNoC block.send_items(int port, item_t items[$], chdr_word_t metadata[$] = {}, packet_info_t pkt_info = 0)
Enqueue a packet of samples (or other data items) to be sent by the BFM to the RFNoC block on the indicated block port.recv(int port, output chdr_word_t data[$], output int data_bytes)
Recv a packet of samples (or other data items) from the indicated port on the RFNoC block.set_master_stall_prob(int stall_probability = DEF_STALL_PROB)
Set the probability, as value from 0-100, of the BFM's AXI-Stream master stalling (deasserting TVALID) between transfers.set_slave_stall_prob(int stall_probability = DEF_STALL_PROB)
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.