UVM Object
The
uvm_object
is the cornerstone of the Universal Verification Methodology (UVM). It’s the base class for almost all other classes in UVM, providing fundamental functionalities that are essential for building robust and reusable verification environments.UVM Object Diagram
Your Roadmap
Here’s a simplified diagram to illustrate the relationship between various UVM objects:
+----------------------+
| uvm_object |
| |
| +----------------+ |
| | uvm_component | |
| +----------------+ |
+----------------------+
|
v
+----------------------+
| uvm_sequence_item |
+----------------------+
|
v
+----------------------+
| uvm_sequence |
+----------------------+
|
v
+----------------------+
| uvm_transaction |
+----------------------+
Key Concepts of UVM Objects:
- Class-based Verification: UVM objects are class-based, which allows for encapsulation, inheritance, and polymorphism—essential features of object-oriented programming.
- Transactions and Sequence Items: These are the data objects that represent the communication between different components in the verification environment.
- Sequences: These are collections of transactions that describe complex stimulus generation.
- Configuration Objects: These objects hold configuration information and are used to configure other components in the testbench.
Why is uvm_object
Important?
- Foundation for Polymorphism: It enables polymorphism, allowing you to treat objects of derived classes as objects of the base class. This is crucial for creating flexible and extensible testbenches.
- Common Functionality: It provides common methods for object creation, copying, printing, comparison, and recording, which are used throughout UVM.
- Transaction Recording: It provides the base for transaction recording mechanisms.
- Reporting: It provides the base for UVM reporting.
Key Features and Methods of uvm_object
:
-
Object Creation (
create()
):- The
create()
method is the preferred way to create UVM objects. It uses the UVM factory, which allows you to override the default object creation with derived types. - Syntax:
static function uvm_object create(string name="");
my_transaction trans = my_transaction::type_id::create("my_trans");
- The
-
Copying (
copy()
):- The
copy()
method creates a deep copy of an object, including all its members. - Syntax:
virtual function void copy(uvm_object rhs);
my_transaction trans_copy = new(); trans_copy.copy(trans);
- The
-
Printing (
print()
):- The
print()
method prints the contents of an object to the UVM message stream. - Syntax:
virtual function void print(uvm_printer printer=null);
trans.print();
- The
-
Comparison (
compare()
):- The
compare()
method compares two objects for equality. - Syntax:
virtual function bit compare(uvm_object rhs, uvm_comparer comparer=null);
if (trans.compare(other_trans)) begin // Objects are equal end
- The
-
Cloning (
clone()
):- The
clone()
method creates a new object that is an exact copy of the original object. It returns auvm_object
handle. - Syntax:
virtual function uvm_object clone();
uvm_object cloned_trans = trans.clone(); my_transaction actual_clone; $cast(actual_clone, cloned_trans);
- The
-
Recording (
record()
):- The
record()
method records the object’s data for later analysis. - Syntax:
virtual function void record(uvm_recorder recorder=null);
- The
-
get_type()
andget_type_name()
:get_type()
returns the type handle of the object.get_type_name()
returns the string name of the object’s type.
uvm_object_wrapper type = trans.get_type(); string type_name = trans.get_type_name();
Diagram 1: uvm_object
in the UVM Hierarchy
uvm_void
└── uvm_object
├── uvm_component
│ ├── uvm_env
│ │ └── ...
│ ├── uvm_agent
│ │ ├── uvm_driver
│ │ ├── uvm_sequencer
│ │ └── uvm_monitor
│ └── ...
└── uvm_sequence_item (and thus, user-defined transactions)
Diagram 2: Key uvm_object
Methods
+-----------------+
| uvm_object |
+-----------------+
| create() |
| copy() |
| print() |
| compare() |
| clone() |
| record() |
| get_type() |
| get_type_name() |
+-----------------+
Example Usage in a Transaction Class:
class my_transaction extends uvm_sequence_item;
rand bit [7:0] data;
`uvm_object_utils(my_transaction) // Crucial for factory and other UVM features
function new(string name = "my_transaction", uvm_component parent = null);
super.new(name, parent);
endfunction
function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_field("data", data, 8, UVM_DEC);
endfunction
endclass
Defining UVM Objects
1. Transaction (uvm_sequence_item)
Transactions are the basic units of communication in UVM testbenches. They are derived from uvm_sequence_item
.
class transaction extends uvm_sequence_item;
`uvm_object_utils(transaction)
rand bit [31:0] addr;
rand bit [31:0] data;
function new(string name = "transaction");
super.new(name);
endfunction
function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_field_int("addr", addr, $bits(addr));
printer.print_field_int("data", data, $bits(data));
endfunction
endclass
2. Sequence (uvm_sequence)
Sequences are collections of transactions used to generate stimulus.
class my_sequence extends uvm_sequence#(transaction);
`uvm_object_utils(my_sequence)
task body();
transaction t;
t = transaction::type_id::create("t");
start_item(t);
if (!t.randomize())
`uvm_fatal("RAND_ERR", "Randomization failed")
finish_item(t);
endtask
endclass
3. Configuration Object
Configuration objects hold configuration parameters used by various components in the testbench.
class config extends uvm_object;
`uvm_object_utils(config)
rand bit [31:0] addr_width;
rand bit [31:0] data_width;
function new(string name = "config");
super.new(name);
endfunction
function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_field_int("addr_width", addr_width, $bits(addr_width));
printer.print_field_int("data_width", data_width, $bits(data_width));
endfunction
endclass
Usage of UVM Objects in a Testbench
In a UVM testbench, these objects are instantiated and used within components like drivers, monitors, and agents.
Example: Using Transactions and Sequences
class my_driver extends uvm_driver#(transaction);
`uvm_component_utils(my_driver)
task main_phase(uvm_phase phase);
transaction t;
forever begin
seq_item_port.get_next_item(t);
// Drive transaction to DUT
seq_item_port.item_done();
end
endtask
endclass
Key Takeaways:
uvm_object
is the root of most UVM classes.- It provides essential methods for object management.
- The
\
uvm_object_utils` macro is crucial for enabling UVM features like the factory and reporting. - Understanding
uvm_object
is fundamental for working with UVM.