// Command to run in questa
// 1. vlib work
// 2. vlog -sv top.sv
// 3. vsim top -c
// 4. run -all (in vsim prompt)
class base;
int a = 5;
endclass
class extend extends base;
int b = 1;
endclass
module top;
initial begin
base m_base;
extend m_extend;
m_extend = new();
m_base = new();
$cast(m_extend, m_base);
$display(m_extend.a);
end
endmodule
//Error: (vsim-3971) $cast to type 'class work.top1_sv_unit::extend' from 'class work.top1_sv_unit::base' failed in file top.sv
Meaning of a successfully casting from super-class(parent class) to sub-class(child class) is that the super-class is actually a sub-class.
class BasePacket;
int A = 1;
int C = 2;
function void printA;
$display("BasePacket::A is %d", A);
endfunction : printA
virtual function void printC;
$display("BasePacket::C is %d", C);
endfunction : printC
endclass : BasePacket
class My_Packet extends BasePacket;
int A = 3;
int C = 4;
function void printA;
$display("My_Packet::A is %d", A);
endfunction: printA
virtual function void printC;
$display("My_Packet::C is %d", C);
endfunction : printC
endclass : My_Packet
module top;
initial begin
My_Packet EXT = new;
BasePacket BASE;
BASE = EXT;
BASE.printA;
BASE.printC;
$cast(EXT, BASE);
EXT.printA;
EXT.printC;
end
endmodule : top
//Output:
// BasePacket::A is 1
// My_Packet::C is 4
// My_Packet::A is 3
// My_Packet::C is 4
// 1. vlib work
// 2. vlog -sv top.sv
// 3. vsim top -c
// 4. run -all (in vsim prompt)
class base;
int a = 5;
endclass
class extend extends base;
int b = 1;
endclass
module top;
initial begin
base m_base;
extend m_extend;
m_extend = new();
m_base = new();
$cast(m_extend, m_base);
$display(m_extend.a);
end
endmodule
//Error: (vsim-3971) $cast to type 'class work.top1_sv_unit::extend' from 'class work.top1_sv_unit::base' failed in file top.sv
Meaning of a successfully casting from super-class(parent class) to sub-class(child class) is that the super-class is actually a sub-class.
int A = 1;
int C = 2;
function void printA;
$display("BasePacket::A is %d", A);
endfunction : printA
virtual function void printC;
$display("BasePacket::C is %d", C);
endfunction : printC
endclass : BasePacket
class My_Packet extends BasePacket;
int A = 3;
int C = 4;
function void printA;
$display("My_Packet::A is %d", A);
endfunction: printA
virtual function void printC;
$display("My_Packet::C is %d", C);
endfunction : printC
endclass : My_Packet
module top;
initial begin
My_Packet EXT = new;
BasePacket BASE;
BASE = EXT;
BASE.printA;
BASE.printC;
$cast(EXT, BASE);
EXT.printA;
EXT.printC;
end
endmodule : top
//Output:
// BasePacket::A is 1
// My_Packet::C is 4
// My_Packet::A is 3
// My_Packet::C is 4
Here super-class in this example (BASE) is actually the sub-class (EXT), so the $cast is passed.
Here for first call (using BASE handle) of printA and printC, super-class (BASE) is acutally sub-class (EXT) and function printC is declared as virtual in super-class (BASE), so it will execute printC function of sub-class (EXT).
Here for first call (using BASE handle) of printA and printC, super-class (BASE) is acutally sub-class (EXT) and function printC is declared as virtual in super-class (BASE), so it will execute printC function of sub-class (EXT).
But, function printA is not declared as virtual in super-class (BASE), so it will execute printA function of super-class (BASE), in-spite of it is actually having memory of EXT class, because handle is of super-class.
One usual scenario to use the $cast is to pass some sub-class data into other class, and the developer of the receptor class even don't know if the incoming class is what kind of sub-class, so usually he will in the receptor class use a super(parent)-class to get the incoming data and then use $cast to check/transfer the data into certain sub-class.
No comments:
Post a Comment