I am stuck with do_pack and do_unpack, I want to pack the objects fields into bytes and bits. But I am unable to find out a good example on this in UserGuides. Please someone help out by providing one good example for packing and unpacking using OVM.
There is no need to implement do_pack and do_unpack. You can use the automation macros to implement the pack/unpack automatically. Here is an example of how to use the automation macros and how to call the pack/unpack methods.
When you are packing/unpacking an object which contains more than 4096 bits the inbuilt ovm pack/unpack won’t work. If Packing/Unpacking results in more than 4096 bit you need to write your own packing and unpacking function.
Hi Phuynh ,
is there any option for us to pack only physical fields. And I would also like to know the order in which the fields are packed (will they packed in the order we have declared in our class)?
In the above case first macro for x is declared and next macro for y is declared. So it will pack first x and y next.
Case2) If you have user defined pack function which are do_pack/do_unpack functions, it will pack in the order specified in do_pack/do_unpack functions.
I want to post here my problem because it’s related to do_pack function!
I was expecting to call the do_pack function and then i should have been able to get the packed bits out of a function or a field, but i could not do that unless i call a specific function (set_packed_size()) from ovm_packer class. That function refreshes the field m_packed_size with the count value and resets the count! I guess you people know better then me the internals of OVM :)
Is this a bug, or is it the default behaviour i should implement every time when using do_pack?
module do_pack;
//`include "ovm.svh";
import ovm_pkg::*;
`include "ovm_macros.svh"
class item2 extends ovm_sequence_item;
rand bit[0:4] field2;
rand int my_int;
function new(string name="item2");
super.new(name);
endfunction
`ovm_object_utils_begin(item2)
`ovm_field_int(field2,OVM_ALL_ON)
`ovm_field_int(my_int,OVM_ALL_ON)
`ovm_object_utils_end
function void do_pack(ovm_packer packer);
super.do_pack(packer);
packer.pack_field(field2, $bits(field2));
endfunction
endclass;
class item3 extends ovm_sequence_item;
rand bit[0:8] field3;
rand item2 my_item2;
function new(string name="item3");
super.new(name);
my_item2 = new(name);
endfunction
`ovm_object_utils_begin(item3)
`ovm_field_int(field3,OVM_ALL_ON)
`ovm_field_object(my_item2,OVM_ALL_ON)
`ovm_object_utils_end
function void do_pack(ovm_packer packer);
super.do_pack(packer);
packer.pack_field(field3, $bits(field3));
my_item2.do_pack(packer);
endfunction : do_pack
endclass
item3 my_item;
bit unsigned bits[];
initial begin
my_item = new();
my_item.randomize();
my_item.print();
my_item.do_pack(ovm_default_packer);
ovm_default_packer.set_packed_size();// if this line is missing the get bits will return an empty dynamic array of bits
ovm_default_packer.get_bits(bits);
$display("bits=%p",bits);
end
endmodule
Hi Phuynh ,
is there any option for us to pack only physical fields.
…
Best Regards,
Maverick
In SystemVerilog, there is no “tagging” for the physical fields (like in Specman); so, there is no automatic way to do it. However, if you don’t want to pack the “virtual” fields, you can either leave those out of the `ovm_field_* macros or use the OVM_NOPACK option for these fields (see my code example in previous message, the “virtual” field: parity_type, was specified with the OVM_NOPACK).
Now I have one more issue, I am trying to use OVM unpack_bytes macro but I am getting the error as:
ref formal and actual do not have equivalent data types ( expecting datatype compatible with ‘dynamic array of byte’ but found a different ‘dynamic array of byte’ instead).
actually I want to unpack into a pkt type which is inherited from ovm_object.
I am storing all the packed bytes into a dynamic array, now I want to unpack the entire dynamic array into this packet which is inherited from ovm_object.
I would say that the limitation can be “changed” in 2.0.3. You can globally change the limit using OVM_STREAMBITS, but be be warned of the performance impact because the packer treats every integral field as if it were OVM_STREAMBITS wide.
My suggestion is to use the SystemVerilog strearming operator and bitstream casts to perform packing/unpacking if performance is an issue. Here is the example submitted by aimunteanu re-written using bitstream casts and the streaming operators.
typedef bit bitstream[$];
module do_pack;
import ovm_pkg::*;
`include "ovm_macros.svh"
class item2 extends ovm_sequence_item;
rand bit[0:4] field2;
rand int my_int;
function new(string name="item2");
super.new(name);
endfunction
`ovm_object_utils_begin(item2)
`ovm_field_int(field2,OVM_ALL_ON)
`ovm_field_int(my_int,OVM_ALL_ON)
`ovm_object_utils_end
virtual function bitstream pack();
return bitstream'(field2);
endfunction
endclass;
class item3 extends ovm_sequence_item;
rand bit[0:8] field3;
rand item2 my_item2;
function new(string name="item3");
super.new(name);
my_item2 = new(name);
endfunction
`ovm_object_utils_begin(item3)
`ovm_field_int(field3,OVM_ALL_ON)
`ovm_field_object(my_item2,OVM_ALL_ON)
`ovm_object_utils_end
function bitstream pack();
return {>>{field3,my_item2.pack()}};
endfunction
endclass
item3 my_item;
bit unsigned bits[];
initial begin
my_item = new();
my_item.randomize();
my_item.print();
bits = my_item.pack();
$display("bits=%p",bits);
end
endmodule // do_pack
Hi All,
Now I have one more issue, I am trying to use OVM unpack_bytes macro but I am getting the error as: ref formal and actual do not have equivalent data types ( expecting datatype compatible with ‘dynamic array of byte’ but found a different ‘dynamic array of byte’ instead).
actually I want to unpack into a pkt type which is inherited from ovm_object.
I am storing all the packed bytes into a dynamic array, now I want to unpack the entire dynamic array into this packet which is inherited from ovm_object.
Thanks in Advance,
Best Regards,
Maverick
Hi Maverick,
My guess is that you unpacked from a “byte array” instead of from a “byte unsigned array”. unpack_bytes() expects its argument to be a “byte unsigned array”. If you look at my code example in previous message:
Thank you Phu Huynh,
Now I am trying to print the unpacked packet… but to my surprize the packet is null with out any fields. Could you please tell me where I went wrong.
Best Regards,
Maverick
Hi Maverick,
You might want to check to see that the unpacked packet was “newed” and has the correct fields. Check the return value of the unpack_bytes() too; it tells you how many bytes were extracted from the array. By the way, the example that I provided in the earlier message is a runnable example that you can play with to get familiar with the pack/unpack methods.
Hi phu yunh,
sorry phu, I have mistakenly written packed instead of writing unpacked… now I have modified it. so with the following code I am getting problem.
unpack is not working for me…I have newed the object but still I am getting the null result and the unpack method returned value is zero. I am unable to figure out the problem.
int pack_int;
packet unpacked;
byte unsigned up ;
unpacked= new();
-------- here i am collecting the packed data into the dynamic array
-------- and printing it successfully
after that I have this line
pack_int = (unpacked.unpack_bytes(up));
when i am printing the unpacked it is showing null.
Hi phu yunh,
unpack is not working for me…I have newed the object but still I am getting the null result and the unpack method returned value is zero. I am unable to figure out the problem.
int pack_int;
packet packed_packet;
byte unsigned up ;
packed_packet= new();
-------- here i am collecting the packed data into the dynamic array
-------- and printing it successfully
after that I have this line
pack_int = (unpacked.unpack_bytes(up));
when i am printing the unpacked it is showing null.
Please help me out as soon as possible.
Thanks in Advance
Best Regards,
Maverick
Maverick,
Looking at your code above, I didn’t see “unpacked” defined anywhere. Also, make sure that any dynamic array fields in the “unpacked packet” have been allocated before you unpack the byte stream into it; otherwise, there will be no place for those bytes :).
Phu
I am using OVM 2.0.3. Now I am getting new error. The Dut error I am getting is “Can not unpack into Null object”. I am trying to unpack array of bytes into a class object. I have newed the class object before unpacking into it. I have also used ovm_default_packer.use_metadata = 1. But still I am unable to get clear the error. Please help me out.