Tutorials

Learn More

copy method in UVM

The copy method does a copy of the mentioned object. It performs a deep copy.

copy method 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;
       string     names;
  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_string(names, 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();
    this.names = "UVM";
  endfunction
endclass

class my_test extends uvm_test;
  `uvm_component_utils(my_test)
  my_object obj_A, obj_B;
  bit packed_data_bits[];
  byte unsigned packed_data_bytes[];
  int unsigned packed_data_ints[];
  
  my_object unpack_obj;
  
  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_A = my_object::type_id::create("obj_A", this);
    obj_B = my_object::type_id::create("obj_B", this);
    assert(obj_A.randomize());
    assert(obj_B.randomize());
    `uvm_info(get_full_name(), $sformatf("Before copying: obj_A = \n%s and obj_B = \n%s", obj_A.sprint(), obj_B.sprint()), UVM_LOW);
    obj_B.copy(obj_A);
    `uvm_info(get_full_name(), $sformatf("After copying: obj_A = \n%s and obj_B = \n%s", obj_A.sprint(), obj_B.sprint()), UVM_LOW);
  endfunction
endclass

module tb_top;
  initial begin
    run_test("my_test");
  end
endmodule

Output:

UVM_INFO testbench.sv(65) @ 0: uvm_test_top [uvm_test_top] Before copying: obj_A = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_A         my_object     -     @349      
  value       integral      32    'h1f135537
  names       string        3     UVM       
  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      
--------------------------------------------
 and obj_B = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_B         my_object     -     @351      
  value       integral      32    'he96c3deb
  names       string        3     UVM       
  colors      color_type    32    RED       
  data        sa(integral)  4     -         
    [0]       integral      8     'hcb      
    [1]       integral      8     'h49      
    [2]       integral      8     'hcc      
    [3]       integral      8     'h49      
  addr        integral      8     'h6d      
  tmp         temp_class    -     @352      
    tmp_addr  integral      8     'h66      
    tmp_data  integral      8     'h27      
--------------------------------------------

UVM_INFO testbench.sv(67) @ 0: uvm_test_top [uvm_test_top] After copying: obj_A = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_A         my_object     -     @349      
  value       integral      32    'h1f135537
  names       string        3     UVM       
  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      
--------------------------------------------
 and obj_B = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_B         my_object     -     @351      
  value       integral      32    'h1f135537
  names       string        3     UVM       
  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    -     @355      
    tmp_addr  integral      8     'h39      
    tmp_data  integral      8     'hbd      
--------------------------------------------

do_copy method

The do_copy() callback method is a user-defined hook that is called by the copy() method. The derived class should override The uvm_object_utils_begin, uvm_object_utils_end and `uvm_field_* macros are not used.

do_copy method example

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

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_copy(uvm_object local_h);
    temp_class tmp_h;
    super.do_copy(local_h);
    // $cast is necessary: uvm_object local_h do not have temp_class properties (tmp_addr and tmp_data)
    // temp_class is extended from uvm_object, so child class temp_class handle is required for copying each property.
    $cast(tmp_h, local_h);
    tmp_addr = tmp_h.tmp_addr;
    tmp_data = tmp_h.tmp_data;
  endfunction
endclass

class my_object extends uvm_object;
  rand int        value;
       string     names;
  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_copy(uvm_object local_h);
    my_object my_obj;
    super.do_copy(local_h);
    $cast(my_obj, local_h);
    value = my_obj.value;
    names = my_obj.names;
    colors= my_obj.colors;
    data = my_obj.data;
    addr = my_obj.addr;
    tmp.copy(my_obj.tmp);
  endfunction
endclass

class my_test extends uvm_test;
  `uvm_component_utils(my_test)
  my_object obj_A, obj_B;
  
  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_A = my_object::type_id::create("obj_A", this);
    obj_B = my_object::type_id::create("obj_B", this);
    assert(obj_A.randomize());
    assert(obj_B.randomize());
    `uvm_info(get_full_name(), "Before copying", UVM_LOW);
    obj_print(obj_A);
    obj_print(obj_B);
    obj_B.copy(obj_A);
    `uvm_info(get_full_name(), "After copying", UVM_LOW);
    obj_print(obj_B);
  endfunction
  
  function void obj_print(uvm_object obj);
    my_object my_obj;
    string out;
    $cast(my_obj, obj);
    $display("-----------------------------");
    $display("----------  %s  ----------", my_obj.get_name);
    $display("-----------------------------");
    $sformat(out, "value = %0h, names = %s, addr = %0h", my_obj.value, my_obj.names, my_obj.addr); 
    `uvm_info(get_full_name(), $sformatf("%s", out), UVM_LOW);
    foreach(my_obj.data[i]) `uvm_info(get_full_name(), $sformatf("data[%0d] = %h", i, my_obj.data[i]), UVM_LOW);
    $sformat(out, "tmp_addr = %0h, tmp_data = %0h", my_obj.tmp.tmp_addr, my_obj.tmp.tmp_data); 
    `uvm_info(get_full_name(), $sformatf("tmp: %s", out), UVM_LOW);
  endfunction
endclass

module tb_top;
  initial begin
    run_test("my_test");
  end
endmodule

Output:

UVM_INFO testbench.sv(69) @ 0: uvm_test_top [uvm_test_top] Before copying
-----------------------------
----------  obj_A  ----------
-----------------------------
UVM_INFO testbench.sv(85) @ 0: uvm_test_top [uvm_test_top] value = 1f135537, names = , addr = 2f
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[0] = 9f
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[1] = 33
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[2] = 12
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[3] = 9c
UVM_INFO testbench.sv(88) @ 0: uvm_test_top [uvm_test_top] tmp: tmp_addr = 39, tmp_data = bd
-----------------------------
----------  obj_B  ----------
-----------------------------
UVM_INFO testbench.sv(85) @ 0: uvm_test_top [uvm_test_top] value = e96c3deb, names = , addr = 6d
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[0] = cb
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[1] = 49
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[2] = cc
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[3] = 49
UVM_INFO testbench.sv(88) @ 0: uvm_test_top [uvm_test_top] tmp: tmp_addr = 66, tmp_data = 27
UVM_INFO testbench.sv(73) @ 0: uvm_test_top [uvm_test_top] After copying
-----------------------------
----------  obj_B  ----------
-----------------------------
UVM_INFO testbench.sv(85) @ 0: uvm_test_top [uvm_test_top] value = 1f135537, names = , addr = 2f
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[0] = 9f
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[1] = 33
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[2] = 12
UVM_INFO testbench.sv(86) @ 0: uvm_test_top [uvm_test_top] data[3] = 9c
UVM_INFO testbench.sv(88) @ 0: uvm_test_top [uvm_test_top] tmp: tmp_addr = 39, tmp_data = bd

clone method in UVM

The clone method calls the create() method followed by copy(). Thus, it creates and returns a copy of an object.

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

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;
       string     names;
  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_string(names, 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_A, obj_B;
  
  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_A = my_object::type_id::create("obj_A", this);
    assert(obj_A.randomize());
    if(obj_B == null) `uvm_info(get_full_name(), "obj_B is not created", UVM_LOW);
    $cast(obj_B, obj_A.clone());
    `uvm_info(get_full_name(), $sformatf("AFter clone:\n obj_A = \n%s and obj_B = \n%s", obj_A.sprint(), obj_B.sprint()), UVM_LOW);
  endfunction
endclass

module tb_top;
  initial begin
    run_test("my_test");
  end
endmodule

Output:

UVM_INFO testbench.sv(55) @ 0: uvm_test_top [uvm_test_top] obj_B is not created
UVM_INFO testbench.sv(57) @ 0: uvm_test_top [uvm_test_top] AFter clone:
 obj_A = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_A         my_object     -     @1877     
  value       integral      32    'ha4a4f87e
  names       string        0     ""        
  colors      color_type    32    RED       
  data        sa(integral)  4     -         
    [0]       integral      8     'hc6      
    [1]       integral      8     'h4c      
    [2]       integral      8     'hf       
    [3]       integral      8     'h89      
  addr        integral      8     'h53      
  tmp         temp_class    -     @1878     
    tmp_addr  integral      8     'hea      
    tmp_data  integral      8     'hdf      
--------------------------------------------
 and obj_B = 
--------------------------------------------
Name          Type          Size  Value     
--------------------------------------------
obj_A         my_object     -     @1881     
  value       integral      32    'ha4a4f87e
  names       string        0     ""        
  colors      color_type    32    RED       
  data        sa(integral)  4     -         
    [0]       integral      8     'hc6      
    [1]       integral      8     'h4c      
    [2]       integral      8     'hf       
    [3]       integral      8     'h89      
  addr        integral      8     'h53      
  tmp         temp_class    -     @1852     
    tmp_addr  integral      8     'hea      
    tmp_data  integral      8     'hdf      
--------------------------------------------