UVM Sequence Items
UVM sequence items are the fundamental units of data that are transferred between components in a UVM testbench, primarily between sequencers and drivers. They encapsulate the information needed to stimulate the design under verification (DUV). Understanding sequence items is crucial for creating effective and reusable test sequences.
Diagram of UVM Sequence Items
Your Roadmap
+-----------------------+
| UVM Environment |
| |
| +------------------+ |
| | Agent | |
| | +--------------+ | |
| | | Driver | | |
| | +--------------+ | |
| | +--------------+ | |
| | | Sequencer | | |
| | +--------------+ | |
| +------------------+ |
| |
| +------------------+ |
| | Sequence Item | |
| +------------------+ |
| ^ |
| | |
| +--------------+ |
| | Sequence | |
| +--------------+ |
+-----------------------+
|
v
+----------------------+
| DUT |
+----------------------+
Why Use Sequence Items?
- Encapsulation: Sequence items encapsulate all the data and control information related to a single transaction, making it easier to manage and manipulate data flow in the testbench.
- Randomization: Sequence items can be randomized, allowing you to generate a wide range of test scenarios automatically.
- Abstraction: Sequence items provide a level of abstraction between the sequencer (which generates transactions) and the driver (which drives them onto the DUV interface).
- Reusability: Sequence items can be reused in different sequences and test scenarios.
Key Concepts of UVM Sequence Items
- Sequence Item Class (
uvm_sequence_item
): A base class for creating transaction objects. - Randomization: Supports constrained random generation of transaction fields.
- Automation: Utilizes UVM macros to streamline the creation and manipulation of sequence items.
- Debugging: Provides built-in methods for printing and comparing sequence items.
Structure of a UVM Sequence Item:
A UVM sequence item is a class that extends uvm_sequence_item
. It typically contains the following key elements:
- `uvm_object_utils` Macro: This macro is essential for registering the sequence item with the UVM factory and enabling other UVM features like printing, copying, and comparing.
- Data Members: These members represent the data that will be transferred to the DUV. They can be of any data type, including basic types (e.g.,
bit
,int
,logic
), arrays, and user-defined structs or classes. new()
Constructor: The constructor is used to create an instance of the sequence item.- Constraint Blocks: These blocks are used to define constraints on the data members, allowing you to control the randomization process.
do_pack()
anddo_unpack()
(Optional): These methods are used for packing and unpacking the sequence item data into a bit stream, which is useful for transferring data over interfaces that require specific formatting.do_print()
(Recommended): This method customizes how the sequence item is printed, improving debuggability.do_copy()
(Recommended): This method customizes how the sequence item is copied.
Diagram 1: Sequence Item Structure
+-----------------------+
| uvm_sequence_item |
+-----------------------+
| `uvm_object_utils(...) |
| data_member_1; |
| data_member_2; |
| ... |
| new() |
| constraint ... |
| do_pack() (Optional) |
| do_unpack() (Optional)|
| do_print() |
| do_copy() |
+-----------------------+
Defining UVM Sequence Items
1. Sequence Item Class
Sequence items are defined as classes that extend from uvm_sequence_item
. They include fields that represent the data being transferred.
class my_transaction extends uvm_sequence_item;
`uvm_object_utils(my_transaction)
rand bit [31:0] addr;
rand bit [31:0] data;
bit write_enable;
function new(string name = "my_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));
printer.print_field_int("write_enable", write_enable, $bits(write_enable));
endfunction
endclass
2. Creating and Using Sequence Items in a Sequence
Sequences generate and manipulate sequence items. A sequence is derived from uvm_sequence
.
class my_sequence extends uvm_sequence#(my_transaction);
`uvm_object_utils(my_sequence)
task body();
my_transaction tx;
tx = my_transaction::type_id::create("tx");
start_item(tx);
if (!tx.randomize())
`uvm_fatal("RAND_ERR", "Randomization failed");
finish_item(tx);
endtask
endclass
Example Code:
`include "uvm_macros.svh"
class my_transaction extends uvm_sequence_item;
rand bit [7:0] address;
rand bit [31:0] data;
rand bit write_enable;
constraint addr_c { address inside {[0:255]}; }
`uvm_object_utils(my_transaction)
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("address", address, 8, UVM_HEX);
printer.print_field("data", data, 32, UVM_HEX);
printer.print_field("write_enable", write_enable, 1, UVM_DEC);
endfunction
function void do_copy(uvm_object rhs);
my_transaction rhs_;
super.do_copy(rhs);
$cast(rhs_, rhs);
if(rhs_ != null) begin
this.address = rhs_.address;
this.data = rhs_.data;
this.write_enable = rhs_.write_enable;
end
endfunction
endclass
Diagram 2: Sequence Item Usage in a Testbench
+-----------+ +-----------+ +---------+
| Sequencer |---->| Sequence |---->| Driver |----> DUV
+-----------+ +-----------+ +---------+
| get_next_ | | create() | | drive() |
| item() | | randomize()| | |
+-----------+ +-----------+ +---------+
^ |
| | Sequence Item
+-------------+
Explanation:
- The sequencer requests a new sequence item from the sequence.
- The sequence creates a new sequence item using the factory (
my_transaction::type_id::create()
). - The sequence randomizes the sequence item’s data members.
- The sequence sends the randomized sequence item to the driver.
- The driver drives the data from the sequence item onto the DUV interface.
Key Takeaways:
- Sequence items are the basic units of data transfer in UVM.
- They are randomized to generate various test scenarios.
- The `uvm_object_utils macro is essential for enabling UVM features.
do_print()
anddo_copy()
methods are highly recommended for good debuggability.- They are used in conjunction with sequencers and drivers to stimulate the DUV.