SystemVerilog Casting

 casting 

Dynamic casts can be used to safely cast a super-class pointer (or reference) into a pointer (or reference) to a subclass in a class hierarchy. If the cast is invalid because the real type of the object pointed to is not the type of the desired subclass, the dynamic will fail gracefully.

Lets see how we can use the casting,

It is always legal to assign a child class variable to a variable of a class higher in the inheritance tree (parent class).
             parent_class = child_class; //allowed

It is never legal to directly assign a super-class (parent class) variable to a variable of one of its sub classes (child class).
 child_class  = parent_class; //not-allowed

However, it is legal to assign a super-class (parent class) handle to a subclass (child class) variable if the super-class (parent class) handle refers to an object of the given subclass(child class).
         parent_class = child_class ;
child_class  = parent_class; //allowed because parent_class is pointing to child_class.

Though parent_class is pointing to the child_class, we will get a compilation error saying its not compatible type for the assignment.

This we can over come by make use of $cast method, i.e,

$cast(child_class,parent_class);

 Example - 1 

 assigning child class handle to parent class handle

class parent_class;
  bit [31:0] addr;
  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;
  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p=new();
    child_class  c=new();
    c.addr = 10;
    c.data = 20;
    p = c;        //assigning child class handle to parent class handle
    c.display();
  end
endmodule

 Simulator Output  
Addr = 10
Data = 20
Execute the above code on 


 Example - 2 

assigning parent class handle to child class handle, lead to compilation error.

class parent_class;
  bit [31:0] addr;
  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p=new();
    child_class  c=new();
    c.addr = 10;
    c.data = 20;
    c = p;        //assigning child class handle to parent class handle
    c.display();
  end
endmodule


 Simulator Output  
"c = p;"
  Expression 'p' on rhs is not a class or a compatible class and hence cannot
  be assigned to a class handle on lhs.
  Please make sure that the lhs and rhs expressions are compatible.
Execute the above code on 

 Example - 3 

assigning parent class handle(which is pointing to child class handle) to child class handle, lead to compilation error.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;
  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass
module inheritence;
  initial begin
    parent_class p;
    child_class  c=new();
    child_class  c1;
    c.addr = 10;
    c.data = 20;
    p  = c;        //p is pointing to child class handle c.
    c1 = p;        //type check fails during compile time.
    c1.display();
  end
endmodule


 Simulator Output  
"c1 = p;"
  Expression 'p' on rhs is not a class or a compatible class and hence cannot
  be assigned to a class handle on lhs.
  Please make sure that the lhs and rhs expressions are compatible.
Execute the above code on 

 Example - 4 

with the use of $cast(), type check during compile time can be skipped.

class parent_class;
  bit [31:0] addr;

  function display();
    $display("Addr = %0d",addr);
  endfunction
endclass

class child_class extends parent_class;
  bit [31:0] data;

  function display();
    super.display();
    $display("Data = %0d",data);
  endfunction
endclass

module inheritence;
  initial begin
    parent_class p;
    child_class  c=new();
    child_class  c1;
    c.addr = 10;
    c.data = 20;

    p = c;         //p is pointing to child class handle c.
    $cast(c1,p);   //with the use of $cast, type chek will occur during runtime

    c1.display();
  end
endmodule


 Simulator Output  
Addr = 10
Data = 20

Execute the above code on