UVM uvm_sequence_item do_copy and field macros


I was asked what would have if, in a class derived from a UVM uvm_sequence_item class, one overrode the do_copy method and also specified a copy method using the field macros. I said I think I knew, because I knew exactly what would happen if the case of the compare method and that I expected the same behaviour with the copy method. However, it pays to confirm this by having a play on EDA Playground.

So, what would happen with the compare method?

Well, (i) both methods would be called and (ii) the field macro method would be called first and (iii) the result from each would be ANDed together.

So, what would happen with the copy method?

I wrote some code to find out. Here is a class derived from a uvm_sequence_item class, with overridden do_compare and do_copy methods and field macros that also specified both.

It turns out that, just like with compare, (i) both methods would be called and (ii) the field macro method would be called first.

https://www.edaplayground.com/x/qTW

package pkg;

import uvm_pkg::*;
`include "uvm_macros.svh"

class seq_item extends uvm_sequence_item;

rand int A;
rand int B;

function new(string name = "seq_item");
  super.new(name);
endfunction

function void do_copy(uvm_object rhs);
  seq_item rhs_;

  if(!$cast(rhs_, rhs)) begin
    uvm_report_error("do_copy", "cast failed, check types");
  end
 
  // If we uncomment this, we see that A is set to 3, but B
  // is copied. So, the field macro copy must be called
  // first.
  //A = 3;
 
  // If we comment this, we see that A and B are still copied
  // (by the field macro copy)
  A = rhs_.A;
  B = rhs_.B;
endfunction: do_copy

function bit do_compare(uvm_object rhs, uvm_comparer comparer);
  seq_item rhs_;

  do_compare = $cast(rhs_, rhs) &&
               super.do_compare(rhs, comparer) &&

               // if we comment out the line below, the A field
               // is still compared (by the field macro compare
               // method)
               A == rhs_.A &&
               B == rhs_.B;
 
endfunction: do_compare

function string convert2string();
  return $sformatf(" A:\t%0h\n B:\t%0d", A, B);
endfunction: convert2string

`uvm_object_utils_begin(seq_item)
`uvm_field_int(A, UVM_DEFAULT)
`uvm_field_int(B, UVM_DEFAULT)
`uvm_object_utils_end

endclass: seq_item

endpackage: pkg

And here is a module that uses the seq_item class to have a play:

module M;

import uvm_pkg::*;
import pkg::*;

initial
  begin
    seq_item s1, s2;
    s1 = new("s1");
    s2 = new("s2");
    s1.randomize;
    $display("s1= %s", s1.convert2string);
    s2.copy(s1);
    $display("s2= %s", s2.convert2string);
    $display("s1==s2: ", s1.compare(s2));
  end
 
endmodule: M


A customer asked me about this. I didn't know the answer, so I wrote a few lines of code on EDA Playground. EDA Playground is great for that, because it's always on. You don't have to queue for licences, wait for EDA tools to start, create new files, fire up editors...

Comments

Popular posts from this blog

Bit Width Casting in SystemVerilog

How to convert a std_logic_vector to a hex string?

Can you add/remove more than 1 item from a queue?