Tips for new UVM users

Or: What I forgot in class

When I first learned UVM, there were many things that baffled me. What was still fuzzy after you took a UVM course?

Here is a diagram with the testbench layers, and orange transactions flowing from the test-level sequence into an agent.

  • Sequencer vs. sequence. That little ‘r’ confuses a lot of people. If you are new to UVM, just remember:
    • A sequencer is basically a smart pipe that carries transactions from the test level to the driver. (Yes, it can do more…)
    • Multiple transactions are called a sequence. A single transaction won’t find many bugs, but a flock of them can be dangerous!
  • Why are multiple transactions put in a task?
    • OK, I am generating transactions. Why don’t I just put them into an array?
    • The fourth dimension of your testbench is time! If I just made an array of transaction handles, how do I add delays? If I have two sequences running side by side, into two different interfaces, how do I synchronize them?
    • Each sequence needs to run in the body() task so I can do all this. (Remember, a function can’t have any delays.)
    • What about reactive stimulus? An array of transaction handles is static. What if you want to send in transaction A, check the result, and send in B on success, or C on failure? Or take the value from a read transaction and write that to a new location? This is easy in a SystemVerilog task, but hard with an array of handles.
  • When does my UVM class constructor have one argument vs. two? This is because are two major types of UVM classes.
    • Components such as monitors and drivers. These are part of a testbench hierarchy, the boxes shown above.
      • A test has an environment, which has an agent, which has a monitor, driver, and sequencer. When you create a component, it needs to know its name and parent. So its new() must have these two arguments.
    • Transactions or sequence items, the orange circles above. These objects are created at the test level, and are sent to an agent. Or created by a monitor and sent to a scoreboard or psychiatrist for analysis. They don’t have a fixed location in the testbench. That’s why their new() only has a single name argument.
  • What does it mean to “start a sequence”?
    • A sequence generates transactions. Where do they go? If they are UART transactions, obviously they go to the UART agent. What if there are 4 UARTS in your design? Then your testbench has 4 UART agents. Your test needs to pick one.
    • An agent is just a container for other components. So a sequence needs to connect to a driver. However, what if two sequences both want to send to a single driver. Aha – you need a smart connection, a sequencer. That is why your test class passes a sequencer handle into the sequence start() task.
    • I prefer to say, “start a sequence with a sequencer“, instead of, “start a sequence on a sequencer“. A sequencer does not execute a sequence, and virtual sequences usually don’t have a sequencer.
    • OK, that ‘r‘ is getting annoying. You get the picture.

Want to see more SystemVerilog and UVM tips? Sign up for my upcoming webinar UVM Coding Guidelines: Tip & Tricks You Probably Didn’t Know.

Enjoy your verification journey!
Chris Spear

Any questions or ideas?
Want to stay up to date on news from Siemens Digital Industries Software? Click here to choose content that's right for you


One thought about “Tips for new UVM users

Leave a Reply

This article first appeared on the Siemens Digital Industries Software blog at