UVM Object and Utility Macros

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:

MacroFunctionality
uvm_field_intRegisters an integer field for printing, copying, comparison, etc.
uvm_field_realRegisters a real number field.
uvm_field_enumRegisters an enum type field.
uvm_field_array_intRegisters an array of integers.
uvm_field_stringRegisters 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 addr field with copy, compare, print, and pack/unpack enabled. They should have two arguments: field and flag.
  • UVM_ALL_ON
    • This flag enables all field operations. Other options include UVM_DEFAULT, UVM_COPY, UVM_NOPRINT, etc.

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 FlagDescription
UVM_DEFAULTUses the default settings (copy, compare, print, pack, unpack).
UVM_COPYEnables copying of the field using copy().
UVM_NOCOPYPrevents copying of the field.
UVM_COMPAREEnables comparison of the field using compare().
UVM_NOCOMPAREPrevents comparison of the field.
UVM_PRINTEnables printing of the field using print().
UVM_NOPRINTPrevents printing of the field.
UVM_RECORDEnables recording of the field for debugging and waveform visualization.
UVM_NORECORDPrevents recording of the field.
UVM_PACKEnables packing of the field using pack().
UVM_NOPACKPrevents packing of the field.
UVM_UNPACKEnables unpacking of the field using unpack().
UVM_NOUNPACKPrevents unpacking of the field.
UVM_SEMANTICMarks a field as significant for semantic operations.
UVM_ALL_ONEnables all available operations (copy, compare, print, record, pack, unpack).
UVM_ALL_OFFDisables 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:

Featureuvm_objectuvm_component
Base ClassDerived from uvm_objectDerived from uvm_component, which extends uvm_object
Use CaseUsed for data structures like transactions, sequence items, and configuration objectsUsed for structural elements like drivers, monitors, agents, sequencers, and scoreboards
LifecycleCreated and managed explicitly in codeCreated hierarchically using UVM factory and follows UVM phasing
Factory RegistrationUses uvm_object_utils macroUses uvm_component_utils macro
Phasing SupportNo phase methods (build_phase, run_phase, etc.)Supports UVM phases (build_phase, connect_phase, run_phase, etc.)
HierarchyNo concept of hierarchyHas a parent-child hierarchy (components can contain sub-components)