UVM_Sequence_item
Table of Contents
The sequence-item is written by extending the uvm_sequence_item, uvm_sequence_item inherits from the uvm_object via the uvm_transaction class. therefore uvm_sequence_item is of an object type.
Before moving to uvm_sequence_item will look into uvm_object concepts required to write uvm_sequence_item, The uvm_object has a number of virtual methods that are used to implement common data object functions (copy, clone, compare, print, transaction, and recording) and these should be implemented to make the sequence_item more general purpose.also, uvm_Object has macros defined in it, mainly Utility Macros and Field Macros.
UVM Utility Macros
The utility macros provide implementations of the create method (needed for cloning) and the get_type_name method (needed for debugging), etc.
objects with no field macros,
`uvm_object_utils(TYPE)
objects with field macros,
`uvm_object_utils_begin(TYPE) `uvm_field_*(FIELD,FLAG) `uvm_object_utils_end
UVM Field Macros
The `uvm_field_* macros are invoked inside of the `uvm_*_utils_begin and `uvm_*_utils_end, for the implementations of the methods: copy, compare, pack, unpack, record, print, and etc.
Each `uvm_field_* macro is named to correspond to a particular data type: integrals, strings, objects, queues, etc., and each has at least two arguments: FIELD and FLAG.
`uvm_field_*(FIELD,FLAG);
FLAG | Description |
---|---|
UVM_ALL_ON | Set all operations on (default) |
UVM_DEFAULT | Use the default flag settings |
UVM_NOCOPY | Do not copy this field |
UVM_NOCOMPARE | Do not compare this field |
UVM_NOPRINT | Do not print this field |
UVM_NODEFPRINT | Do not print the field if it is the same as its |
UVM_NOPACK | Do not pack or unpack this field |
UVM_PHYSICAL | Treat as a physical field. Use physical setting in policy class for this field |
UVM_ABSTRACT | Treat as an abstract field. Use the abstract setting in the policy class for this field |
UVM_READONLY | Do not allow the setting of this field from the set_*_local methods |
A radix for printing and recording can be specified by OR’ing one of the following constants in the FLAG argument
|
|
UVM_BIN | Print/record the field in binary (base-2) |
UVM_DEC | Print/record the field in decimal (base-10) |
UVM_UNSIGNED | Print/record the field in unsigned decimal (base-10) |
UVM_OCT | Print/record the field in octal (base-8). |
UVM_HEX | Print/record the field in hexadecimal (base-16) |
UVM_STRING | Print/record the field in string format |
UVM_TIME | Print/record the field in time format |
*detailed description on macros is described in later pages.
Sequence item:
The sequence-item consist of data fields required for generating the stimulus.In order to generate the stimulus, the sequence items are randomized in sequences. Therefore data properties in sequence items should generally be declared as rand and can have constraints defined.
Data fields represent the following types of information,
- Control Information – a type of transfer, transfer size, etc
- Payload Information – data content of the transfer
- Configuration Information – mode of operation, error behavior, etc
- Analysis Information – fields used to capture information from DUT, ex: read data, response, etc
as analysis information fields will be used for capturing response, except these fields the other fields can be declared as rand and can have constraints associated with it.
Sequence item example:
class mem_seq_item extends uvm_sequence_item; //Control Information rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; //Payload Information rand bit [7:0] wdata; //Analysis Information bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass
UVM Sequence item Methods
create():
The create method allocates a new object of the same type as this object and returns it via a base uvm_object handle.
print():
The print method deep-prints this object’s properties in a format and manner governed by the given printer argument;
Create() and Print() Method
class mem_seq_item extends uvm_sequence_item; //Control Information rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; //Payload Information rand bit [7:0] wdata; //Analysis Information bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to create and randomize sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item; initial begin //create method seq_item = mem_seq_item::type_id::create(); //randomizing the seq_item seq_item.randomize(); //printing the seq_item seq_item.print(); end endmodule
Simulator Output:
--------------------------------------- Name Type Size Value --------------------------------------- mem_seq_item mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ---------------------------------------
copy:
The copy makes this object a copy of the specified object.
Copy() Method
class mem_seq_item extends uvm_sequence_item; //Control Information rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; //Payload Information rand bit [7:0] wdata; //Analysis Information bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_1 = mem_seq_item::type_id::create("seq_item_1"); seq_item_0.randomize(); //randomizing the seq_item seq_item_0.print(); //printing the seq_item_0 //copy method seq_item_1.copy(seq_item_0); //copy seq_item_0 to seq_item_1 seq_item_1.print(); //printing the seq_item_1 end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 -------------------------------------
clone
The clone method creates and returns an exact copy of this object. clone = create() + copy();
Clone() Method
class mem_seq_item extends uvm_sequence_item; //data and control fields rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; rand bit [7:0] wdata; bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_0.randomize(); //randomizing the seq_item seq_item_0.print(); //printing the seq_item_0 //clone method $cast(seq_item_1,seq_item_0.clone()); //create seq_item_1 and copy seq_item_0 to seq_item_1 //changing the seq_item_1 values will not reflect on seq_item_0 values. seq_item_1.addr = 8; seq_item_1.wdata = 'h56; `uvm_info("","Printing seq_item_0", UVM_LOW) seq_item_0.print(); //printing the seq_item_0 `uvm_info("","Printing seq_item_1", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 //Note:: name of seq_item_1 will be printed as seq_item_0, because there is no option to pass argument to create method while calling the clone method. end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- UVM_INFO testbench.sv(52) @ 0: reporter [] Printing seq_item_0 ------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- UVM_INFO testbench.sv(54) @ 0: reporter [] Printing seq_item_1 ------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @338 addr integral 4 'h8 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h56 -------------------------------------
compare
Deep compares members of this data object with those of the object provided in the RHS (right-hand side) argument, returning 1 on a match, 0 otherwise.
Compare Method
class mem_seq_item extends uvm_sequence_item; //data and control fields rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; rand bit [7:0] wdata; bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_1 = mem_seq_item::type_id::create("seq_item_1"); //---------------Mismatch Case------------------------------ seq_item_0.randomize(); //randomizing the seq_item_0 seq_item_1.randomize(); //randomizing the seq_item_1 seq_item_0.print(); //printing the seq_item_0 seq_item_1.print(); //printing the seq_item_1 //compare method if(seq_item_0.compare(seq_item_1)) `uvm_info("","seq_item_0 matching with seq_item_1", UVM_LOW) else `uvm_error("","seq_item_0 is not matching with seq_item_1") //---------------Matching Case------------------------------ seq_item_1.copy(seq_item_0); //copy seq_item_0 to seq_item_1 //compare method if(seq_item_0.compare(seq_item_1)) `uvm_info("","seq_item_0 matching with seq_item_1", UVM_LOW) else `uvm_error("","seq_item_0 is not matching with seq_item_1") end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h5 wr_en integral 1 'h0 rd_en integral 1 'h1 wdata integral 8 'h33 ------------------------------------- UVM_INFO @ 0: reporter [MISCMP] Miscompare for seq_item_0.addr: lhs = 'h4 : rhs = 'h5 UVM_INFO @ 0: reporter [MISCMP] 1 Miscompare(s) for object seq_item_1@338 vs. seq_item_0@334 UVM_ERROR testbench.sv(54) @ 0: reporter [] seq_item_0 is not matching with seq_item_1 UVM_INFO testbench.sv(59) @ 0: reporter [] seq_item_0 matching with seq_item_1
pack, pack_bytes, pack_ints
The pack methods bitwise-concatenate this object’s properties into an array of bits, bytes, or ints.
unpack,unpack_bytes,unpack_ints
The unpack methods extract property values from an array of bits, bytes, or ints.
pack/unpack to/from Array of bit type
class mem_seq_item extends uvm_sequence_item; //data and control fields rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; rand bit [7:0] wdata; bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; bit bit_packed_data[]; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_1 = mem_seq_item::type_id::create("seq_item_1"); //---------------------- PACK ------------------------------ seq_item_0.randomize(); //randomizing the seq_item_0 seq_item_0.print(); //printing the seq_item_0 seq_item_0.pack(bit_packed_data); //pack method foreach(bit_packed_data[i]) `uvm_info("PACK",$sformatf("bit_packed_data[%0d] = %b",i,bit_packed_data[i]), UVM_LOW) //---------------------- UNPACK ------------------------------ `uvm_info("UNPACK","Before UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 seq_item_1.unpack(bit_packed_data); //unpack method `uvm_info("UNPACK","After UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[0] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[1] = 1 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[2] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[3] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[4] = 1 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[5] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[6] = 1 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[7] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[8] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[9] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[10] = 1 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[11] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[12] = 0 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] pack_data[13] = 0 UVM_INFO testbench.sv(54) @ 0: reporter [UNPACK] Before UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h0 wr_en integral 1 'h0 rd_en integral 1 'h0 wdata integral 8 'h0 ------------------------------------- UVM_INFO testbench.sv(57) @ 0: reporter [UNPACK] After UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 -------------------------------------
pack/unpack to/from Array of byte type
class mem_seq_item extends uvm_sequence_item; //data and control fields rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; rand bit [7:0] wdata; bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; byte unsigned byte_packed_data[]; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_1 = mem_seq_item::type_id::create("seq_item_1"); //---------------------- PACK ------------------------------ seq_item_0.randomize(); //randomizing the seq_item_0 seq_item_0.print(); //printing the seq_item_0 seq_item_0.pack_bytes(byte_packed_data); //pack method foreach(byte_packed_data[i]) `uvm_info("PACK",$sformatf("byte_packed_data[%0d] = %b",i,byte_packed_data[i]), UVM_LOW) //---------------------- UNPACK ------------------------------ `uvm_info("UNPACK","Before UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 seq_item_1.unpack_bytes(byte_packed_data); //unpack method `uvm_info("UNPACK","After UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- UVM_INFO testbench.sv(51) @ 0: reporter [PACK] byte_packed_data[0] = 01001010 UVM_INFO testbench.sv(51) @ 0: reporter [PACK] byte_packed_data[1] = 00100000 UVM_INFO testbench.sv(54) @ 0: reporter [UNPACK] Before UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h0 wr_en integral 1 'h0 rd_en integral 1 'h0 wdata integral 8 'h0 ------------------------------------- UVM_INFO testbench.sv(57) @ 0: reporter [UNPACK] After UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 -------------------------------------
pack/unpack to/from Array of int type
class mem_seq_item extends uvm_sequence_item; //data and control fields rand bit [3:0] addr; rand bit wr_en; rand bit rd_en; rand bit [7:0] wdata; bit [7:0] rdata; //Utility and Field macros, `uvm_object_utils_begin(mem_seq_item) `uvm_field_int(addr,UVM_ALL_ON) `uvm_field_int(wr_en,UVM_ALL_ON) `uvm_field_int(rd_en,UVM_ALL_ON) `uvm_field_int(wdata,UVM_ALL_ON) `uvm_object_utils_end //Constructor function new(string name = "mem_seq_item"); super.new(name); endfunction //constaint, to generate any one among write and read constraint wr_rd_c { wr_en != rd_en; }; endclass //------------------------------------------------------------------------- //Simple TestBench to access sequence item //------------------------------------------------------------------------- module seq_item_tb; //instance mem_seq_item seq_item_0; mem_seq_item seq_item_1; int unsigned int_packed_data[]; initial begin //create method seq_item_0 = mem_seq_item::type_id::create("seq_item_0"); seq_item_1 = mem_seq_item::type_id::create("seq_item_1"); //---------------------- PACK ------------------------------ seq_item_0.randomize(); //randomizing the seq_item_0 seq_item_0.print(); //printing the seq_item_0 seq_item_0.pack_ints(int_packed_data); //pack method foreach(int_packed_data[i]) `uvm_info("PACK",$sformatf("int_packed_data[%0d] = %b",i,int_packed_data[i]), UVM_LOW) //---------------------- UNPACK ------------------------------ `uvm_info("UNPACK","Before UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 seq_item_1.unpack_ints(int_packed_data); //unpack method `uvm_info("UNPACK","After UnPack", UVM_LOW) seq_item_1.print(); //printing the seq_item_1 end endmodule
Simulator Output:
------------------------------------- Name Type Size Value ------------------------------------- seq_item_0 mem_seq_item - @334 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 ------------------------------------- UVM_INFO testbench.sv(52) @ 0: reporter [PACK] int_packed_data[0] = 01001010001000000000000000000000 UVM_INFO testbench.sv(55) @ 0: reporter [UNPACK] Before UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h0 wr_en integral 1 'h0 rd_en integral 1 'h0 wdata integral 8 'h0 ------------------------------------- UVM_INFO testbench.sv(60) @ 0: reporter [UNPACK] After UnPack ------------------------------------- Name Type Size Value ------------------------------------- seq_item_1 mem_seq_item - @338 addr integral 4 'h4 wr_en integral 1 'h1 rd_en integral 1 'h0 wdata integral 8 'h88 -------------------------------------