How to use ovm_transaction to define "Packet"?

Dear all,
Do OVM provide an guide: how to use ovm_transaction to define “Packet”?
1.Define method and process?method override?macro?
2.what’s the benefit ovm_transaction provide?
3.how to print or compare the array data?
If “Packet” derived from ovm_transaction has a object property and this object has array,how to comapre this array.
such as:
class GPon_Packet …
Ether_Packet eth_pkt;

endclass

class Ether_Packet …
bit [7:0] payload;

endclass
GPon_Packet g_pkt1,g_pkt2;
how to compare the g_pkt1.eth_pkt.payload and g_pkt2.eth_pkt.payload?
Do ovm_transaction provide defautly comapre funtion to do it?
Thank you!

Hello ahan,

The OVM Reference Manual provides details on which default methods are available for ovm_transaction.

Because ovm_transaction is extended from ovm_object, the copy, compare, print, pack, unpack, etc methods are specified - and if you use the OVM utility macros, these methods are automatically implemented for you. The copy, compare, clone, print, etc are “deep” by default, so you will get a deep compare, deep copy, when using them. All of these methods are also customizable - so take a look at the Reference Manual for more details.

ovm_transaction provides additional capabilities, namely the ability to capture time, and the ability to do transaction recording.

I have included a simple example that shows how to use the copy and compare methods. This should run on IUS8.1 with the following command-line:

irun -ovm packet.sv

I hope this helps!

Kathleen

// packet.sv
module test;
`include "ovm.svh"
class Ether_Packet extends ovm_transaction;
  rand bit [7:0] payload [];  // dynamic array
  rand int size;

  constraint c1 { payload.size() == size; size > 0; size < 10; }

  function new (input string name = "Ether_Packet");
    super.new(name);
  endfunction : new
// OVM Utility Macros
  `ovm_object_utils_begin(Ether_Packet)
     `ovm_field_int(size, OVM_ALL_ON)
     `ovm_field_array_int(payload, OVM_ALL_ON)
  `ovm_object_utils_end
endclass : Ether_Packet

class GPon_Packet extends ovm_transaction;
  rand Ether_Packet eth_pkt;
  typedef enum {ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT} ptype_enum;
  randc ptype_enum ptype;

  function new (input string name = "GPon_Packet");
    super.new(name);
    eth_pkt = new();
  endfunction : new

  `ovm_object_utils_begin(GPon_Packet)
     `ovm_field_enum(ptype_enum, ptype, OVM_ALL_ON)
     `ovm_field_object(eth_pkt, OVM_ALL_ON)
  `ovm_object_utils_end
endclass : GPon_Packet

GPon_Packet my_packet, my_copy_pkt;

initial begin
  my_packet = new("my_packet");
  repeat (3) begin
    void'(my_packet.randomize());
    my_packet.print();                    // print
  end
  my_copy_pkt = new("my_copy_pkt");
  my_copy_pkt.copy(my_packet);            // deep copy
  my_copy_pkt.eth_pkt.payload[0] = 8'h55; // force an error
  my_copy_pkt.print();
  if (my_copy_pkt.compare(my_packet))     // compare
     $display("Packet Mismatch Identified");
  else $display("Packets Match");
end
endmodule : test

Hello Kathleen,
Thanks for your nice example.
But I found:
even I did not force to error,ovm still treat them as diffirent data.
please delete this code and run:

my_copy_pkt.eth_pkt.payload[0] = 8'h55; // force an error

Could you share your log file previous and this one?
Because,if compare error but simulator can not report where is the data error,it’s hard to debug.We still need to code our own comapre method to do it.
Thank you!

Hello ahan,

Here is the section of the log file that indicates the compare mismatch:

OVM_INFO @ 0: reporter [MISCMP] Miscompare for my_copy_pkt.eth_pkt.payload[0]: lhs = 85 : rhs = 7
OVM_INFO @ 0: reporter [MISCMP] 1 Miscompare(s) for object my_packet@443 vs. my_copy_pkt@525

The OVM Reference Manual (page 114) gives details on the optional comparer argument to the compare() method. I instanced a comparer class and changed some fields to show the impact.

For example, I added:

ovm_comparer my_comparer;
my_comparer = new();
my_comparer.show_max = 5;    // default is 1
my_comparer.sev = OVM_ERROR;  // default is OVM_INFO
. . . 

if (my_copy_pkt.compare(my_packet, my_comparer))
   $display("Packets Match");    // NOTE - FIX from my original example...
else $display("Packet Mismatch Identified");
. . .

And here is what I got in the IUS (8.1p2) log file when I forced two additional mismatches:

OVM_INFO @ 0: reporter [MISCMP] Miscompare for my_copy_pkt.eth_pkt.payload[0]: lhs = 85 : rhs = 148
OVM_INFO @ 0: reporter [MISCMP] Miscompare for my_copy_pkt.eth_pkt.payload[1]: lhs = 85 : rhs = 123
OVM_INFO @ 0: reporter [MISCMP] Miscompare for my_copy_pkt.eth_pkt.payload[2]: lhs = 85 : rhs = 225
OVM_ERROR @ 0: reporter [MISCMP] 3 Miscompare(s) for object my_packet@452 vs. my_copy_pkt@526

What additional information do you need to identify the error?

Kathleen

Hi ahan,

I just re-read your post. I made a mistake in the original code I posted. The compare method returns a ‘1’ if the compare is good and returns a ‘0’ if the compare is a failure. Please fix the code in my example as shown below and you will get the correct result.

if (my_copy_pkt.compare(my_packet))     // compare
     $display("Packets Match");
  else $display("Packet Mismatch Identified");

I could not find the definition in the OVM Reference which indicates that the compare returns a ‘1’ if the compare is successful.

Sorry about that.

Kathleen

Hi Kathleen,
Thank for your kind help!
Your example help me to learn more about the ability of ovm_transaction.
Thank you!