OSVVM 2020.12: Virtual Transaction Interfaces
OSVVM’s 2020.12 release introduces Virtual Transaction Interfaces (VTIs). VTIs allow us to connect to verification components (VCs) without using any ports or signals in the testbench framework. This capability is important when the verification component is embedded in the design – such as an embedded processor like ZYNQ. In this situation, we want to avoid adding “testbench” ports to the DUT.
Virtual Transaction Interfaces are a simple modification to our historical, Connected Transaction Interfaces (CTIs) so there are no big changes to the OSVVM methodology. In fact, to test the new VTI verification components, we did some simple modifications to the CTI test harness and test sequencer entity, and use the exact same test cases (for both CTI and VTI).
The OSVVM Testbench Framework
The objective of any verification framework is to make the Device Under Test (DUT) “feel like” it has been plugged into the board. Hence, the framework must be able to produce the same waveforms and sequence of waveforms that the DUT will see on the board.
The OSVVM testbench framework looks identical to other frameworks, including SystemVerilog. The top level of the testbench (shown in Figure 1) instantiates the verification components (Axi4Master, Axi4Responder, and Axi4Memory), the test sequencer (TestCtrl), and the device under test (DUT). Often this structure is called a test harness. Connections between the verification components and the test sequencer (TestCtrl), shown as dashed lines, use either VTIs or CTIs. Connections between the verification components and the DUT are the DUT interfaces (such as AxiStream, UART, AXI4, SPI, and I2C). Tests are written in separate architectures of TestCtrl by calling transactions (more on this below).
Figure 1. OSVVM Test Frame work
Using Connected Transaction Interfaces (CTIs)
In the CTI approach, the transaction interface is an entity port whose type is a record and mode is inout (See Axi4Master.vhd). To solve the multiple driver issue, we use resolution functions from the OSVVM package ResolutionPkg.
In this methodology we simply connect up the interfaces, just like we would with ports on an RTL design. In the test harness (the top level of the structure), for each transaction interface, there is a corresponding signal that is the physical connection between the entities.
OSVVM supplies its complete test suite for AXI4. For more details on how to connect to the AXI4 CTI in a testbench, see OsvvmLibraries/AXI4/Axi4/testbench/TbAxi4.vhd on GitHub.
Using Virtual Transaction Interfaces
In the VTI approach, the transaction interface is a signal defined in the verification component whose type is a record (See Axi4MasterVti.vhd). To create a VTI verification component from a CTI VC, we simply move the transaction port of the CTI to an internal signal (preferably in the entity declarative region).
In this methodology, there are no transaction interface connections in the test harness. Instead, the test sequencer (TestCtrl) uses VHDL-2008 external names (preferably in the entity declaration) to connect to the verification components. For more details on how to connect the AXI4 VTI, see OsvvmLibraries/AXI4/Axi4/testbenchVti/TestCtrl_e.vhd. For an alternative, see OsvvmLibraries/Axi4/AxiStream/testbenchVti_Mentor/TbAxiStream.vhd (where we use external names in the test harness rather than the test sequencer).
Writing Tests in OSVVM
Writing tests is all about creating waveforms at an interface. In a basic test approach, each test directly drives and wiggles interface waveforms. This is tedious and error prone.
In OSVVM, signal wiggling is replaced by transactions. A transaction is an abstract representation of an interface waveform (such as Write) or a directive to the VC (such as wait for clock). A transaction is initiated using a procedure call in the test sequencer (TestCtrl). In a VC based approach, the procedure call collects the transaction information and passes it to the VC via the transaction interface (either VTI or CTI). The VC then decodes this information and creates the corresponding interface waveforms.
Using transactions simplifies creating tests and increases their readability and reviewability. Figure 2 shows calls to the Write, Read, and ReadCheck transactions for an Axi4Master VC. In this test, the responses are provided by an Axi4Memory VC. Note that the style of interface (VTI vs CTI) does not change what we do here – as long as both name the transaction interface “MasterRec”, both can run the same code.
MasterProc : process
Begin
. . .
log("Write and Read with ByteAddr = 0, 4 Bytes") ;
Write(MasterRec, X"0000_0000", X"5555_5555" ) ;
Read(MasterRec, X"0000_0000", Data) ;
AffirmIfEqual(Data, X"5555_5555", "Super Read Data: ") ;
--
log("Write and Read with 1 Byte, and ByteAddr = 1") ;
Write(MasterRec, X"0000_0011", X"22" ) ;
ReadCheck(MasterRec, X"0000_0011", X"22" ) ;
--
log("Write and Read with 3 Bytes and ByteAddr = 0") ;
Write(MasterRec, X"0000_0050", X"33_2211" ) ;
ReadCheck(MasterRec, X"0000_0050", X"33_2211" ) ;
Figure 2. Calls to Axi4Master Write, Read, and ReadCheck Transactions
Transaction Based Testing is New Right?
No. SynthWorks has been teaching the Transaction Based testing using the CTIs since 1997. OTOH, the methodology is newer to OSVVM as we did not release ResolutionPkg and TbUtilPkg (both necessary in implementing the framework) to OSVVM until 2016.
If you like history type things, the first paper I published our transaction approach was titled, Accelerating Verification Through Pre-Use of System-Level Testbench Components, at DesignCon in 2003. In this paper you can see some of the awkwardness of the transaction interface needing to be initialized – this has been replaced by using the resolution functions from ResolutionPkg instead of std_logic_1164.
OSVVM Verification Components with VTIs
Currently in the OSVVM verification component library, Virtual Transaction Interfaces have been added to the AXI4 family of verification components (Axi4MasterVti.vhd, Axi4ResponderVti_Transactor.vhd, and Axi4MemoryVti.vhd) and the AxiStream family of verification components (AxiStreamTransmitterVti.vhd and AxiStreamReceiverVti.vhd).
For OSVVM verification components, we use the suffix “Vti” in the entity name to denote that it has a Virtual Transaction Interface.
Axi4Lite and UART will be updated to have Virtual Transaction Interfaces sometime in early 2021.
If you need a ZYNQ verification component please reach out to me. We will be needing beta testers shortly.
Do Other VHDL Methodologies Use Virtual Transaction Interfaces?
Yes. UVVM and VUnit also use VTI. However, only the implementations in OSVVM and Vunit are VHDL compliant. UVVM’s VTI methodology is based on the deprecated and removed VHDL feature, shared variables of an ordinary type. Shared variables of an ordinary type were temporarily added to the language in 1076-1993. In 1076-2000, protected types were added and shared variables of an ordinary type were deprecated and removed.
More About Using OSVVM AXI4 and AxiStream
The Axi4 VC User Guide and the AxiStream User Guide provide more detail about AXI4 and AxiStream Verification Components, including OSVVM Testbench Architecture, VTI and CTI interfaces, Writing Tests, and details of how use each component.
Getting Started with OSVVM
The fastest way to get started with OSVVM is SynthWorks’ Advanced VHDL Testbenches and Verification which is available world wide either on-line or on-site (once we can travel again). Here is our current class schedule.