Systemverilog多态性与其他语言(例如C ++)不同吗?

时间:2018-07-11 03:42:27

标签: system-verilog

在C ++之类的语言中,基于对象指针值调用虚拟方法。 Systemverilog LRM指定在使用虚拟方法的情况下,只有最新派生类中的方法才有效。

以下文字摘自LRM:

  

可以用关键字virtual标识类的方法。   虚方法是基本的多态构造。虚拟方法   应在其所有基类中覆盖一个方法,而   非虚拟方法只能覆盖该类及其中的方法   子孙。一种查看方式是,只有一种   每个类层次结构的虚拟方法的实现,它是   总是最新派生类中的一个。

我不知道如何解释这一说法。上面的陈述似乎表明,不管对象句柄值是多少,仅解析派生类中的最新定义。

我尝试了LRM中的示例,但结果与在其他语言(如C ++)中所期望的一样。这是代码:

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

我创建了一个小代码段进行测试,以某种方式,它与LRM所说的或dave_59似乎暗示的不匹配(除非我完全误解了)。

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

以下是输出:

  

B1级B2级B3级

因此,执行基于句柄的值,而不是虚拟方法的最新实现。例如,如果在打印B类时解决了最新的虚拟方法,则以下行应打印B3类。

  

b1_handle = b2_handle; b1_handle.printme;

顺便说一句,模拟器的行为方式恰好是我期望的方式。这种期望是基于我在C ++中看到的。只有LRM中的陈述使我感到困惑。

1 个答案:

答案 0 :(得分:0)

SystemVerilog的OOP模型来自Java(两者均来自Sun Microsystems的工作开发)。对于虚拟方法,这与C ++相同。

SystemVerilog LRM符合您的理解,但是如果您考虑足够长的时间,则表示方式会稍有不同。