The Universal Verification Methodology (UVM) provides a powerful and flexible framework for verifying digital designs. One of the key building blocks in UVM is the UVM object, which is used for data storage, stimulus generation, and communication between different verification components.
In this article, we’ll explore UVM objects, the UVM utility macros, and the UVM field macros—which simplify object creation, debugging, and automation. We’ll also provide examples to illustrate their use.
What is a UVM Object?
A UVM object is a class that extends uvm_object and is primarily used for data storage and communication. Unlike uvm_component, which represents structural elements like testbenches and drivers, uvm_object is lightweight and does not have a hierarchy or phases.
Common Uses of UVM Objects:
- Transaction classes (e.g., representing packets or bus transfers)
- Configuration objects (e.g., passing test settings)
- Stimulus generation (e.g., sequences and sequence items)
Creating a UVM Object
To define a UVM object, we create a class that extends uvm_object and use UVM utility macros to enable factory registration, printing, copying, and comparison capabilities.
Basic Example of a UVM Object:
class my_transaction extends uvm_object;
`uvm_object_utils(my_transaction) // Register the object with the factory
rand bit [7:0] addr; // Randomizable field
rand bit [31:0] data; // Randomizable field
// Constructor
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass
UVM Utility Macros
UVM provides several macros to simplify working with objects. The most commonly used is the `uvm_object_utils macro.
1. uvm_object_utils Macro
`uvm_object_utils(my_transaction)
This macro performs the following:
- Registers the object with the UVM factory, allowing dynamic creation and override.
- Enables built-in functions like printing (
print()) and cloning (copy()).
Without this macro, we’d have to manually register the object, making the code more complex.
UVM Field Macros
UVM also provides field macros to automate copying, printing, comparison, and packing/unpacking of object fields. These macros reduce boilerplate code when dealing with UVM objects.
2. uvm_field_* Macros
These macros help define how fields behave in UVM operations.
Commonly Used Field Macros:
| Macro | Functionality |
|---|---|
uvm_field_int | Registers an integer field for printing, copying, comparison, etc. |
uvm_field_real | Registers a real number field. |
uvm_field_enum | Registers an enum type field. |
uvm_field_array_int | Registers an array of integers. |
uvm_field_string | Registers a string field. |
Example with Field Macros:
class my_transaction extends uvm_object;
`uvm_object_utils_begin(my_transaction)
`uvm_field_int(addr, UVM_ALL_ON) // Registers 'addr' field with all properties enabled
`uvm_field_int(data, UVM_ALL_ON) // Registers 'data' field
`uvm_object_utils_end
rand bit [7:0] addr;
rand bit [31:0] data;
function new(string name = "my_transaction");
super.new(name);
endfunction
endclass
Breaking Down the Macros Used:
- uvm_object_utils_begin(my_transaction) and
uvm_object_utils_end- Define the beginning and end of the field registration block.
- uvm_field_int(addr, UVM_ALL_ON)
- Registers the
addrfield with copy, compare, print, and pack/unpack enabled. They should have two arguments: field and flag.
- Registers the
- UVM_ALL_ON
- This flag enables all field operations. Other options include
UVM_DEFAULT,UVM_COPY,UVM_NOPRINT, etc.
- This flag enables all field operations. Other options include
Key Takeaways:
✅ Use uvm_object for lightweight, non-hierarchical objects.
✅ Register objects with uvm_object_utils for factory automation.
✅ Use field macros (uvm_field_int, etc.) for easy copying, comparison, and printing.
✅ Leverage UVM utilities to simplify debugging and improve testbench maintainability.
UVM Flags:
UVM flags are predefined constants that define how fields inside a UVM object behave when using built-in UVM operations like:
- Copying (
copy()) - Comparison (
compare()) - Printing (
print()) - Recording (
record()) - Packing/Unpacking (
pack() / unpack()) - Randomization (
do_randomize())
These flags are primarily used in UVM field macros (uvm_field_int, uvm_field_string, etc.) to control the behavior of each field.
List of UVM Flags and Their Functions
Here is a breakdown of all UVM flags along with their functionalities:
| UVM Flag | Description |
|---|---|
UVM_DEFAULT | Uses the default settings (copy, compare, print, pack, unpack). |
UVM_COPY | Enables copying of the field using copy(). |
UVM_NOCOPY | Prevents copying of the field. |
UVM_COMPARE | Enables comparison of the field using compare(). |
UVM_NOCOMPARE | Prevents comparison of the field. |
UVM_PRINT | Enables printing of the field using print(). |
UVM_NOPRINT | Prevents printing of the field. |
UVM_RECORD | Enables recording of the field for debugging and waveform visualization. |
UVM_NORECORD | Prevents recording of the field. |
UVM_PACK | Enables packing of the field using pack(). |
UVM_NOPACK | Prevents packing of the field. |
UVM_UNPACK | Enables unpacking of the field using unpack(). |
UVM_NOUNPACK | Prevents unpacking of the field. |
UVM_SEMANTIC | Marks a field as significant for semantic operations. |
UVM_ALL_ON | Enables all available operations (copy, compare, print, record, pack, unpack). |
UVM_ALL_OFF | Disables all operations. |
Differences between uvm_object and uvm_component:
In UVM, uvm_object and uvm_component are two fundamental base classes, but they serve different purposes in a testbench. Here are the key differences between them:
| Feature | uvm_object | uvm_component |
|---|---|---|
| Base Class | Derived from uvm_object | Derived from uvm_component, which extends uvm_object |
| Use Case | Used for data structures like transactions, sequence items, and configuration objects | Used for structural elements like drivers, monitors, agents, sequencers, and scoreboards |
| Lifecycle | Created and managed explicitly in code | Created hierarchically using UVM factory and follows UVM phasing |
| Factory Registration | Uses uvm_object_utils macro | Uses uvm_component_utils macro |
| Phasing Support | No phase methods (build_phase, run_phase, etc.) | Supports UVM phases (build_phase, connect_phase, run_phase, etc.) |
| Hierarchy | No concept of hierarchy | Has a parent-child hierarchy (components can contain sub-components) |