Reputation: 355
In languages like C++, the virtual method is called based on the object pointer value. Systemverilog LRM specifies that in case of virtual methods, only the method in the latest derived class takes effect.
The following text is from the LRM:
A method of a class may be identified with the keyword virtual. Virtual methods are a basic polymorphic construct. A virtual method shall override a method in all of its base classes, whereas a non-virtual method shall only override a method in that class and its descendants. One way to view this is that there is only one implementation of a virtual method per class hierarchy, and it is always the one in the latest derived class.
I don't know how to interpret this statement. The above statement seems to suggest that irrespective of the object handle value, only the latest definition in the derived class is resolved.
I tried the example from LRM but results are as the way I would expect in other languages like C++. Here is the code:
class BasePacket;
int A = 1;
int B = 2;
function void printA;
$display("BasePacket::A is %d", A);
endfunction : printA
virtual function void printB;
$display("BasePacket::B is %d", B);
endfunction : printB
endclass : BasePacket
class My_Packet extends BasePacket;
int A = 3;
int B = 4;
function void printA;
$display("My_Packet::A is %d", A);
endfunction: printA
virtual function void printB;
$display("My_Packet::B is %d", B);
endfunction : printB
endclass : My_Packet
BasePacket P1 = new;
My_Packet P2 = new;
initial begin
P1.printA; // displays 'BasePacket::A is 1'
P1.printB; // displays 'BasePacket::B is 2'
P1 = P2; // P1 has a handle to a My_packet object
P1.printA; // displays 'BasePacket::A is 1'
P1.printB; // displays 'My_Packet::B is 4' – latest derived method
P2.printA; // displays 'My_Packet::A is 3'
P2.printB; // displays 'My_Packet::B is 4'
end
I created a small code snippet to test this and somehow, it does not match what LRM says or what dave_59 seems to suggest (unless I have completely misinterpreted).
module x;
class B1;
virtual function void printme;
$display("Class B1");
endfunction : printme
endclass : B1
class B2 extends B1;
virtual function void printme;
$display("Class B2");
endfunction : printme
endclass : B2
class B3 extends B2;
virtual function void printme;
$display("Class B3");
endfunction : printme
endclass : B3
B1 b1_handle = new;
B2 b2_handle = new;
B3 b3_handle = new;
initial begin
b1_handle.printme;
b1_handle = b2_handle;
b1_handle.printme;
b1_handle = b3_handle;
b1_handle.printme;
end
endmodule
Here is the output:
Class B1 Class B2 Class B3
So, execution is based on value of the handle and not the latest implementation of virtual method. For example, the following line should have printed Class B3 if latest virtual method is resolved while it prints Class B.
b1_handle = b2_handle; b1_handle.printme;
BTW, the way the simulator behaves is exactly the way I expect it to. This expectation is based on what I have seen in C++. Only the statement in LRM confuses me.
Upvotes: 0
Views: 383
Reputation: 42623
SystemVerilog’s OOP model comes from Java (Both developed from work at Sun Microsystems). In the case of virtual methods, that’s the same as C++.
The SystemVerilog LRM matches your understanding, but said in a slightly different way if you think about it long enough.
Upvotes: 0