Application of $cast() in UVM

Dear All,

I came across mostly some of $cast() method are used as below when I study of object copy and clone.

$cast(my_obj, obj);

or

$cast(_pkt, rhs);

example1 of snippet.



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

example2 of snippet

class Packet extends uvm_object;
  rand bit[15:0] 	m_addr;
  
  // Function is used to return contents of this class in a 
  // string format
  virtual function string convert2string();
    string contents;
    contents = $sformatf("m_addr=0x%0h", m_addr);
  endfunction

  `uvm_object_utils(Packet)
  
  // Implementation of "do_copy". A generic uvm_object called "rhs"
  // is received and type casted into Packet called "_pkt". Then 
  // m_addr is copied from _pkt to the variable in current class
  virtual function void do_copy(uvm_object rhs);
    Packet _pkt;
    super.do_copy(rhs);
    $cast(_pkt, rhs);
   	m_addr = _pkt.m_addr;
    `uvm_info(get_name(), "In Packet::do_copy()", UVM_LOW)
  endfunction

I’m confused that If I run without $cast(), it still can do run with alternative way.
such as in alternative example1 of snippet, I will use “obj” instead “my_obj”. Does this make any problem?
For another alternative example2 of snippet, I will use "rhs: instead using of “_pkt”. Does this make any problem?
Is there any reason for using the different data type in clone and copy functionality class?

In reply to UVM_LOVE:

You need $cast to downcast the function argument from uvm_object variable to a derived class variable. Otherwise you will not be able to access the derived class members from the uvm_object variable.