It is always legal to assign a subclass variable to a variable of a class higher in the inheritance tree.
EXAMPLE class parent;
int i = 10;
endclass
class subclass extends parent;
int j;
function new();
j = super.i;
$display("J is %d",j);
endfunction endclass
program main;
initial begin subclass s;
s = new();
end endprogram RESULT
J is 10
It is never legal to directly assign a superclass variable to a variable of one of its subclasses.
However, it is legal to assign a superclass handle to a subclass variable if the superclass handle refers to an object of the given subclass.
SystemVerilog provides the $cast system task to assign values to variables that might not ordinarily be valid because of differing data type. To check whether the assignment is legal, the dynamic cast function $cast() is used . The syntax for $cast() is as follows:
task $cast( singular dest_handle, singular source_handle );
or
function int $cast( singular dest_handle, singular source_handle );
When called as a task, $cast attempts to assign the source expression to the destination variable. If the assignment is invalid, a run-time error occurs, and the destination variable is left unchanged.
EXAMPLE : $cast as task class B;
virtualtask print();
$display(" CLASS B ");
endtask endclass
class E_1 extends B;
virtualtask print();
$display(" CLASS E_1 ");
endtask endclass
class E_2 extends B;
virtualtask print();
$display(" CLASS E_2 ");
endtask endclass
program main;
initial begin B b;
E_1 e1;
E_2 e2;
e1 = new();
$cast(b,e1);
b.print();
end endprogram RESULT
CLASS E_1
EXAMPLE : $cast as task with error class B;
virtualtask print();
$display(" CLASS B ");
endtask endclass
class E_1 extends B;
virtualtask print();
$display(" CLASS E_1 ");
endtask endclass
class E_2 extends B;
virtualtask print();
$display(" CLASS E_2 ");
endtask endclass
program main;
initial begin B b;
E_1 e1;
E_2 e2;
e1 = new();
$cast(e2,e1);
end endprogram RESULT
Error: Dynamic cast failed
When called as a function, $cast attempts to assign the source expression to the destination variable and returns 1 if the cast is legal. If the cast fails, the function does not make the assignment and returns 0. When called as a function, no run-time error occurs, and the destination variable is left unchanged. It is important to note that $cast performs a run-time check. No type checking is done by the compiler, except to check that the destination variable and source expression are singulars.
EXAMPLE : $cast as function class B;
virtualtask print();
$display(" CLASS B ");
endtask endclass
class E_1 extends B;
virtualtask print();
$display(" CLASS E_1 ");
endtask endclass
class E_2 extends B;
virtualtask print();
$display(" CLASS E_2 ");
endtask endclass
program main;
initial begin B b;
E_1 e1;
E_2 e2;
e1 = new();
//calling $cast like a task
//Return value is not considered
$cast(b,e1);
which_class(b);
e2 = new();
//calling $cast like a task
//Return value is not considered
$cast(b,e2);
which_class(b);
end endprogram
task which_class(B b);
E_1 e1;
E_2 e2;
//calling $cast like a function
//Return value is considered for action
if($cast(e1,b))
$display(" CLASS E_1 ");
if($cast(e2,b))
$display(" CLASS E_2 ");
endtask RESULT
CLASS E_1 CLASS E_2
When used with object handles, $cast() checks the hierarchy tree (super and subclasses) of the source_expr to see whether it contains the class of dest_handle. If it does, $cast() does the assignment. Otherwise, the error is issued.
Assignment of Extended class object to Base class object is allowed. It is Illegal to assign Base class object to Extended class.
EXAMPLE class Base;
endclass
class Exten extends Base;
endclass
program main;
initial begin Base B;
Exten E;
B = new();
if(!$cast(E,B))
$display(" Base class object B canot be assigned to Extended class Handle.");
// Deallocate object B
B = null;
E = new();
if(!$cast(B,E))
$display(" Extended class object E canot be assigned to Base class Handle.");
end endprogram
RESULT
Base class object B canot be assigned to Extended class Handle.