Pack and Unpack methods in UVM
The pack method is used to do bitwise concatenation of the class properties into an array of type bit/ byte/ int.
The unpack method is used to extract values from an array of type bit/ byte/ int and store it into a class format.
Note: It is mandatory to keep the same order for both pack and unpack methods otherwise the result would be different.
Pack |
Unpack |
pack: Do bitwise concatenation of the class properties into an array of type bit |
unpack: Extract values from an array of type bit and store it into a class format. |
pack_bytes: Do bitwise concatenation of the class properties into an array of type byte |
unpack_bytes: Extract values from an array of type byte and store it into a class format. |
pack_ints: Do bitwise concatenation of the class properties into an array of type int |
unpack_ints: Extract values from an array of type int and store it into a class format. |
Pack and Unpack methods example
typedef enum{RED, GREEN, BLUE} color_type;
class temp_class extends uvm_object;
rand bit [7:0] tmp_addr;
rand bit [7:0] tmp_data;
function new(string name = "temp_class");
super.new(name);
endfunction
`uvm_object_utils_begin(temp_class)
`uvm_field_int(tmp_addr, UVM_ALL_ON)
`uvm_field_int(tmp_data, UVM_ALL_ON)
`uvm_object_utils_end
endclass
class my_object extends uvm_object;
rand int value;
rand color_type colors;
rand byte data[4];
rand bit [7:0] addr;
rand temp_class tmp;
`uvm_object_utils_begin(my_object)
`uvm_field_int(value, UVM_ALL_ON)
`uvm_field_enum(color_type, colors, UVM_ALL_ON)
`uvm_field_sarray_int(data, UVM_ALL_ON)
`uvm_field_int(addr, UVM_ALL_ON)
`uvm_field_object(tmp, UVM_ALL_ON)
`uvm_object_utils_end
function new(string name = "my_object");
super.new(name);
tmp = new();
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_object obj;
bit packed_data_bits[];
byte unsigned packed_data_bytes[];
int unsigned packed_data_ints[];
my_object unpack_obj;
int pack_values[3];
int unpack_values[3];
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
obj = my_object::type_id::create("obj", this);
assert(obj.randomize());
`uvm_info(get_full_name(), $sformatf("obj = \n%s", obj.sprint()), UVM_LOW);
// pack methods
pack_values[0] = obj.pack(packed_data_bits);
pack_values[1] = obj.pack_bytes(packed_data_bytes);
pack_values[2] = obj.pack_ints(packed_data_ints);
`uvm_info(get_full_name(), $sformatf("packed_data_bits = %p", packed_data_bits), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("packed_data_bytes = %p", packed_data_bytes), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("packed_data_ints = %p", packed_data_ints), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("pack_values[BITS] = %0d, pack_values[BYTES] = %0d, pack_values[INTS] = %0d", pack_values[0], pack_values[1], pack_values[2]), UVM_LOW);
// unpack methods
unpack_obj = my_object::type_id::create("unpack_obj", this);
unpack_values[0] = unpack_obj.unpack(packed_data_bits);
`uvm_info(get_full_name(), $sformatf("bits: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
unpack_values[1] = unpack_obj.unpack_bytes(packed_data_bytes);
`uvm_info(get_full_name(), $sformatf("bytes: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
unpack_values[2] = unpack_obj.unpack_ints(packed_data_ints);
`uvm_info(get_full_name(), $sformatf("ints: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("unpack_values[BITS] = %0d, unpack_values[BYTES] = %0d, unpack_values[INTS] = %0d", unpack_values[0], unpack_values[1], unpack_values[2]), UVM_LOW);
endfunction
endclass
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
UVM_INFO testbench.sv(61) @ 0: uvm_test_top [uvm_test_top] obj =
--------------------------------------------
Name Type Size Value
--------------------------------------------
obj my_object - @349
value integral 32 'h1f135537
colors color_type 32 GREEN
data sa(integral) 4 -
[0] integral 8 'h9f
[1] integral 8 'h33
[2] integral 8 'h12
[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @350
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
--------------------------------------------
UVM_INFO testbench.sv(67) @ 0: uvm_test_top [uvm_test_top] packed_data_bits = '{'h0, 'h0, 'h0, 'h1, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h1, 'h1, 'h0, 'h1}
UVM_INFO testbench.sv(68) @ 0: uvm_test_top [uvm_test_top] packed_data_bytes = '{'h1f, 'h13, 'h55, 'h37, 'h0, 'h0, 'h0, 'h1, 'h9f, 'h33, 'h12, 'h9c, 'h2f, 'h39, 'hbd}
UVM_INFO testbench.sv(69) @ 0: uvm_test_top [uvm_test_top] packed_data_ints = '{'h1f135537, 'h1, 'h9f33129c, 'h2f39bd00}
UVM_INFO testbench.sv(70) @ 0: uvm_test_top [uvm_test_top] pack_values[BITS] = 120, pack_values[BYTES] = 120, pack_values[INTS] = 120
UVM_INFO testbench.sv(74) @ 0: uvm_test_top [uvm_test_top] bits: unpack_obj =
--------------------------------------------
Name Type Size Value
--------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors color_type 32 GREEN
data sa(integral) 4 -
[0] integral 8 'h9f
[1] integral 8 'h33
[2] integral 8 'h12
[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
--------------------------------------------
UVM_INFO testbench.sv(76) @ 0: uvm_test_top [uvm_test_top] bytes: unpack_obj =
--------------------------------------------
Name Type Size Value
--------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors color_type 32 GREEN
data sa(integral) 4 -
[0] integral 8 'h9f
[1] integral 8 'h33
[2] integral 8 'h12
[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
--------------------------------------------
UVM_INFO testbench.sv(78) @ 0: uvm_test_top [uvm_test_top] ints: unpack_obj =
--------------------------------------------
Name Type Size Value
--------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors color_type 32 GREEN
data sa(integral) 4 -
[0] integral 8 'h9f
[1] integral 8 'h33
[2] integral 8 'h12
[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
--------------------------------------------
UVM_INFO testbench.sv(79) @ 0: uvm_test_top [uvm_test_top] unpack_values[BITS] = 120, unpack_values[BYTES] = 120, unpack_values[INTS] = 120
do_pack and do_unpack methods in UVM
The do_pack/ do_unpack callback methods are user-defined hooks which are called by pack/ unpack() method. The derived class should override The `uvm_object_utils_begin..end and `uvm_field_* macros are not used.
do_pack and do_unpack methods example
typedef enum{RED, GREEN, BLUE} color_type;
class temp_class extends uvm_object;
rand bit [7:0] tmp_addr;
rand bit [7:0] tmp_data;
function new(string name = "temp_class");
super.new(name);
endfunction
`uvm_object_utils(temp_class)
function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_field_int("tmp_addr", tmp_addr, $bits(tmp_addr), UVM_HEX);
printer.print_field_int("tmp_data", tmp_data, $bits(tmp_data), UVM_HEX);
endfunction
function void do_pack(uvm_packer packer);
super.do_pack(packer);
packer.pack_field_int(tmp_addr, $bits(tmp_addr));
packer.pack_field_int(tmp_data, $bits(tmp_data));
endfunction
function void do_unpack(uvm_packer packer);
super.do_unpack(packer);
tmp_addr = packer.unpack_field_int($bits(tmp_addr));
tmp_data = packer.unpack_field_int($bits(tmp_data));
endfunction
endclass
class my_object extends uvm_object;
rand int value;
rand color_type colors;
rand byte data[4];
rand bit [7:0] addr;
rand temp_class tmp;
`uvm_object_utils(my_object)
function new(string name = "my_object");
super.new(name);
tmp = new();
endfunction
function void do_print(uvm_printer printer);
super.do_print(printer);
printer.print_field_int("value", value, $bits(value), UVM_HEX);
printer.print_string("colors", colors.name);
foreach(data[i])
printer.print_field_int($sformatf("data[%0d]", i), data[i], $bits(data[i]), UVM_HEX);
printer.print_field_int("addr", addr, $bits(addr), UVM_HEX);
printer.print_object("tmp", tmp);
endfunction
function void do_pack(uvm_packer packer);
super.do_pack(packer);
packer.pack_field_int(value, $bits(value));
packer.pack_field_int(colors, $bits(colors));
foreach(data[i])
packer.pack_field_int(data[i], $bits(data[i]));
packer.pack_field_int(addr, $bits(addr));
packer.pack_object(tmp);
endfunction
function void do_unpack(uvm_packer packer);
super.do_unpack(packer);
value = packer.unpack_field_int($bits(value));
colors = packer.unpack_field_int($bits(colors));
foreach(data[i])
data[i] = packer.unpack_field_int($bits(data[i]));
addr = packer.unpack_field_int($bits(addr));
packer.unpack_object(tmp);
endfunction
endclass
class my_test extends uvm_test;
`uvm_component_utils(my_test)
my_object obj;
bit packed_data_bits[];
byte unsigned packed_data_bytes[];
int unsigned packed_data_ints[];
my_object unpack_obj;
int pack_values[3];
int unpack_values[3];
function new(string name = "my_test", uvm_component parent = null);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
obj = my_object::type_id::create("obj", this);
assert(obj.randomize());
`uvm_info(get_full_name(), $sformatf("obj = \n%s", obj.sprint()), UVM_LOW);
// pack methods
pack_values[0] = obj.pack(packed_data_bits);
pack_values[1] = obj.pack_bytes(packed_data_bytes);
pack_values[2] = obj.pack_ints(packed_data_ints);
`uvm_info(get_full_name(), $sformatf("packed_data_bits = %p", packed_data_bits), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("packed_data_bytes = %p", packed_data_bytes), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("packed_data_ints = %p", packed_data_ints), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("pack_values[BITS] = %0d, pack_values[BYTES] = %0d, pack_values[INTS] = %0d", pack_values[0], pack_values[1], pack_values[2]), UVM_LOW);
// unpack methods
unpack_obj = my_object::type_id::create("unpack_obj", this);
unpack_values[0] = unpack_obj.unpack(packed_data_bits);
`uvm_info(get_full_name(), $sformatf("bits: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
unpack_values[1] = unpack_obj.unpack_bytes(packed_data_bytes);
`uvm_info(get_full_name(), $sformatf("bytes: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
unpack_values[2] = unpack_obj.unpack_ints(packed_data_ints);
`uvm_info(get_full_name(), $sformatf("ints: unpack_obj = \n%s", unpack_obj.sprint()), UVM_LOW);
`uvm_info(get_full_name(), $sformatf("unpack_values[BITS] = %0d, unpack_values[BYTES] = %0d, unpack_values[INTS] = %0d", unpack_values[0], unpack_values[1], unpack_values[2]), UVM_LOW);
endfunction
endclass
module tb_top;
initial begin
run_test("my_test");
end
endmodule
Output:
UVM_INFO testbench.sv(100) @ 0: uvm_test_top [uvm_test_top] obj =
------------------------------------------
Name Type Size Value
------------------------------------------
obj my_object - @349
value integral 32 'h1f135537
colors string 5 GREEN
data[0] integral 8 'h9f
data[1] integral 8 'h33
data[2] integral 8 'h12
data[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @350
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
------------------------------------------
UVM_INFO testbench.sv(106) @ 0: uvm_test_top [uvm_test_top] packed_data_bits = '{'h0, 'h0, 'h0, 'h1, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h0, 'h0, 'h1, 'h0, 'h0, 'h1, 'h0, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h0, 'h0, 'h1, 'h0, 'h1, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h1, 'h0, 'h0, 'h1, 'h1, 'h0, 'h1, 'h1, 'h1, 'h1, 'h0, 'h1}
UVM_INFO testbench.sv(107) @ 0: uvm_test_top [uvm_test_top] packed_data_bytes = '{'h1f, 'h13, 'h55, 'h37, 'h0, 'h0, 'h0, 'h1, 'h9f, 'h33, 'h12, 'h9c, 'h2f, 'h39, 'hbd}
UVM_INFO testbench.sv(108) @ 0: uvm_test_top [uvm_test_top] packed_data_ints = '{'h1f135537, 'h1, 'h9f33129c, 'h2f39bd00}
UVM_INFO testbench.sv(109) @ 0: uvm_test_top [uvm_test_top] pack_values[BITS] = 120, pack_values[BYTES] = 120, pack_values[INTS] = 120
UVM_INFO testbench.sv(113) @ 0: uvm_test_top [uvm_test_top] bits: unpack_obj =
------------------------------------------
Name Type Size Value
------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors string 5 GREEN
data[0] integral 8 'h9f
data[1] integral 8 'h33
data[2] integral 8 'h12
data[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
------------------------------------------
UVM_INFO testbench.sv(115) @ 0: uvm_test_top [uvm_test_top] bytes: unpack_obj =
------------------------------------------
Name Type Size Value
------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors string 5 GREEN
data[0] integral 8 'h9f
data[1] integral 8 'h33
data[2] integral 8 'h12
data[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
------------------------------------------
UVM_INFO testbench.sv(117) @ 0: uvm_test_top [uvm_test_top] ints: unpack_obj =
------------------------------------------
Name Type Size Value
------------------------------------------
unpack_obj my_object - @361
value integral 32 'h1f135537
colors string 5 GREEN
data[0] integral 8 'h9f
data[1] integral 8 'h33
data[2] integral 8 'h12
data[3] integral 8 'h9c
addr integral 8 'h2f
tmp temp_class - @362
tmp_addr integral 8 'h39
tmp_data integral 8 'hbd
------------------------------------------
UVM_INFO testbench.sv(118) @ 0: uvm_test_top [uvm_test_top] unpack_values[BITS] = 120, unpack_values[BYTES] = 120, unpack_values[INTS] = 120
UVM Tutorials