UVM. It’s Organized and Systematic.

Mastering the fundamentals

Henry Chan, Applications Engineer
Like(2)  Comments  (0)

One of the reasons I like using UVM is its tendency toward an organized structure and uniformity. Some may find it annoying to adhere to such a strict format in UVM, but I think it’s a good way to keep the basics of UVM engrained in your brain. You always want a good foundation and development of strong fundamentals in any endeavor. Verification is no different and UVM hammers the fundamentals home.


UVM has a great structure and organization paradigm. I consider there to be two distinct and fundamental elements in the UVM structure: Components and Objects. Now this characterization isn’t strictly correct because uvm_components are extended from uvm_objects, but I think they are used in such a way that warrants the distinction. I consider it similar to the idea of trucks and cars. In my view, trucks are also cars, but it’s useful to note the difference.


1. Components


Generally, the components make up the static parts of the UVM structure. I like to think about components as the walls and rooms of a house. They divide the home into different parts with different purposes. Similarly, components divide the verification process into different roles. Doors allow passage from one room to the next just as the ports of components allow for information transfer between components.


Components consist of common methods similar to how many different rooms in a house contain similar features: lights, windows, or outlets. Many of the shared major parts or methods among UVM components are:

  • Factory registration and handler instantiations
  • Constructors
  • Build_phases
  • Connect_phases
  • Run_phases


Factory Registration and handler instantiations

When you register something with the factory using the `uvm_component_utils() macro, you are entering it into a lookup table where you will be able to access it later. Using this registration functionality makes it possible to override components in the future when developing advanced tests, but that is beyond the scope of what I am discussing here. Handlers are needed to hold the instantiations of components and are typically created after the factory registration.



Fig. 1: Generic factory registration with handler instantiations for an analysis port, driver, monitor, and sequencer.



A staple of object-oriented programming, these are methods to create instantiations of classes.


The build phase is where the walls and rooms of the house are erected. In this phase, the components are being built and the house is taking shape.



Fig. 2: A sample agent build_phase function



This is where you start to install the doors to connect different rooms together. This method deals with linking components together in order to allow the passage of transactions. TLM concepts are heavily used in UVM and it is most evident here. TLM allows the abstraction of communication between components, thus facilitating reuse of component code and easy rerouting between components.



Fig. 3: A generic agent class with factory registration, handler instantiation, constructor, build_phase, and connect_phase



This is where the fun starts. I can’t think of a great equivalent to the house analogy, but basically the run_phase is where movement starts to take place. Transactions are passed around and time starts to elapse. Information is taken from or put into transactions as they make their way through different components.

A basic travel plan for a transaction might include:


  1. Sequencer obtains sequences and passes along transactions to the driver.
  2. The driver randomizes the values in the transaction and passes it to the DUT
  3. The DUT changes the transaction values based on the DUT function
  4. Monitors obtain the data and pass it along to any subscribers
  5. A Scoreboard subscriber evaluates the data from the transaction and determines if the DUT is behaving correctly.


An important feature of UVM that exists in the run_phase is objections. Objections are the brilliant ways in which UVM decides when tests are finished. I think of objections as flags that are raised when the component wants to do something. When the component is done with whatever it was doing, it drops the objection and the test is then finished when all objections are dropped.



Fig. 4: Oobjections being raised and dropped in the run_phase of a generic test class


2. Objects


Objects are the moving parts of the UVM verification structure. They carry information around the structure to and from different components. When I think of objects, I think mainly of transactions and sequences. Although configuration and register objects may also fit into the category, they are more advanced concepts and not what I am referring to. Sequences and transactions consist of common parts and methods amongst each other:


  • Factory registration
  • Variable and constraint declarations
  • Constructors
  • Bodies (Sequences only)


Factory Registration

Similar to component factory registration, sequences and transactions are also registered with the factory using the `uvm_object_utils() macro.


Variable and constraint declarations

The stimulus variables are developed here. Generally the test stimulus variables are declared, then constraints are put on them in order to push the design in interesting scenarios.



There is nothing too special about object constructors. They’re purpose is similar to component constructors, but object constructors don’t have a parent argument in the function.



Body functions are usually found in sequences and are similar to the run_phase of a component given that both consume time. The body of a sequence might be used to create multiple transactions while varying the value of variables in those transactions.



Fig. 5: Generic sequence class with factory registration, variable and constraint declaration, constructor, and body function.


Suffice it to say that this is not an exhaustive list of all UVM has to offer, but I hope it gives some clarity into the basic functionality behind UVM and allows new users to get started quickly. For more information on UVM, users can visit our website and take the Fast Track To UVM Training.

As an Aldec Applications Engineer, Henry has intimate knowledge of the inner workings behind the latest verification tools, languages, and methodologies. He has a wide breadth of experience across various areas including simulation, emulation, and embedded systems. Henry received his B.S. in Computer Engineering from the University of Nevada, Las Vegas.


Ask Us a Question
Ask Us a Question
Captcha ImageReload Captcha
Incorrect data entered.
Thank you! Your question has been submitted. Please allow 1-3 business days for someone to respond to your question.
Internal error occurred. Your question was not submitted. Please contact us using Feedback form.
We use cookies to ensure we give you the best user experience and to provide you with content we believe will be of relevance to you. If you continue to use our site, you consent to our use of cookies. A detailed overview on the use of cookies and other website information is located in our Privacy Policy.