Getting started with UVVM using Riviera-PRO


UVVM stands for Universal VHDL Verification Methodology. UVM and SystemVerilog are the latest in market with their Advanced ASIC & FPGA Verification benefits, but they are definitely not the answer to all FPGA projects. For almost all companies using VHDL for their FPGA development it does not make sense to change to UVM for Verification. Hence, UVVM has been introduced specifically for VHDL which comprises of all the features and benefits that UVM/SystemVerilog offers. In fact, it provides an added major improvement called VHDL Verification Components (VVC).


VHDL2008 has been a major improvement on the language itself. OSVVM (Open Source VHDL Verification Methodology), which is an open source library, has excellent support for advanced random generation and functional coverage. Although we have both these critical features, debugging remains the most important aspect for large designs and debugging features are severely lacking in VHDL2008 and OSVVM. UVVM fills this gap. The Bitvis Utility library, which is also open source, provides great support for logging/reporting, verbosity control, alert handling, and pre-defined value and event checkers. Now, the Bitvis UVVM (Universal VHDL Verification Methodology) provides the most important verification methodology aspect, the Verification Component. A basic VHDL testbench using UVVM Utility library includes the following:

One of the advantages offered by UVVM is the ability to run simulation with greater or fewer simulation messages without the need to re-compile the design or test-bench. With UVVM messages, the user specifies Verbosity, not priority. The verbosity control helps users eye their designs and testbenches in depth with very little added code.

For example, log(msg_id,msg[…]); prints the message with the particular message_id if and only if that message_id’s verbosity has been enabled.

This is another feature of UVVM which provides hierarchical alert reports for a hierarchy tree defined during run time. The alert summary is shown as a tree of defined scopes. The alert counter propagates up the tree to the top level and provides information to the users and thus keeps them updated.

For example, error(msg,[scope]); prints the error message if the simulation violates the scope.

Randomization is very important. It is nothing but driving random stimulus to the DUT by changing the characteristics of the data. Via randomization, hard to test corner cases can be reached. In UVVM, randomization can be done using very simple commands.

For example, command v_int = random(min_value,max_value); It generates an integer number between the range provided in the command.

To understand and go through the BFM examples and support, let’s first understand the definition of BFM. BFM stands for Bus Functional Model. It is a non-synthesizable software model of an integrated circuit component having one or more external buses. BFMs are usually defined as tasks in Hardware Description Languages, which applies stimulus to the DUT via complex waveforms and protocols. BFMs are often used as reusable building blocks to create simulation test-benches, where the signal ports on a design under test are connected to the appropriate BFMs in the test-bench for the purpose of simulation. They are also referred to as Transaction Level Models. Thus, BFM related support and examples too have been included as part of the UVVM package.

The basic idea of how coding changes using UVVM is given below using an example:

Handling transactions at a higher level (e.g. Read, Write, Send Packet, Configuration, etc…) becomes easy. So, if someone wants to write a 0xF0 into a register at address 0x22, it takes 7 steps to do so using normal vhdl while we can achieve that using UVVM in just 1 step. Below in Table 1 we can see that.

Table 1

Thus, UVVM provides a simple bus interface. Apart from this, when it comes to bigger and complex designs, we need more interfaces, more simultaneous activities on interfaces ,value related corner cases and cycle related corner cases. All these cases cannot be achieved with the help of OSVVM alone as it does not support VVC. When we talk about the corner cases, to find them out using verification, we need more logic. Making it simpler, it would be nice if we have the freedom to :

To achieve all this, UVVM provides a structure called VHDL Verification Component. You should wonder what it is and how is it helpful! Let’s go through it.

What is a VHDL Verification Component?

A VVC is a self-contained verification solution for a particular protocol interface or logic function, compatible with UVVM. It is procedural, and at the same time provides Transaction level modeling. VHDL Verification Component basically works as an interface which takes commands from a sequencer and depending on the command, executes it towards the receiver end. VVC is a VHDL entity/component. It allows multiple threads, autonomous operation. It is controllable via commands and at the same time encapsulated. Thus, helps hiding the important information that we would not want to be disclosed via our testbench.

Fig 1 - VVC in a block-diagram

A sequencer command using VVC : sbi_write(SBI_VVCT,C_ADDR_TX,x”2A”); results in a BFM being executed from a VVC towards the DUT. VVC also allows simultaneous execution of BFMs on different interfaces. Specifically, the BFM procedure is a blocking transaction while VVC is a non-blocking transaction. Also, it is important to understand the subtle difference between the VHDL Verification Component and Bus Functional Model. VVC basically follows Command Distribution Method (CDM). So, the BFM is executed towards the physical DUT immediately, whereas a CDM is always used to only distribute executable commands to a VVC for execution there (often via BFM inside the VVC)- immediately or later. Hence, a CDM is never wiggling signals on a physical DUT.

Working with VHDL Verification Component

A VVC is made up into 3 stages. Interpreter, Command Queue, and Executor. Interpreter is the one who receives the command from the sequencer. It checks whether the command is to be queued or not. If the command is to be queued then it is passed on to the 2nd stage Command Queue. From the Command Queue stage, it is passed on to the Executor stage where the command calls the relevant BFM and executes the transaction. The biggest advantage of such workings in the VVC is the fact that more than 90% of code and its structure remain same in interpreters and executor both apart from BFM calls.

Fig 2 - VVC Architecture

Getting Started with UVVM using Riviera-PRO:

The first step to get started with UVVM in Riviera-PRO is to download UVVM. You can download UVVM from the Bitvis website. Here is the link to download UVVM’s latest version. The latest version of UVVM includes a VVC Framework and Utility library, Various VHDL Verification Components, UVVM-OSVVM Support, Test-bench overview and coordination and many more. The following are the exact steps one needs to take in order to download UVVM and run it successfully.

Printed version of site: