Sharanbr
Sharanbr

Reputation: 355

is Systemverilog polymorphism different from other languages (e.g. C++)

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

Answers (1)

dave_59
dave_59

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

Related Questions