systemverilog 中 'new' 和 'virtual' 的目的是什么?

What is the purpose the 'new' and 'virtual' in systemverilog?

我正在尝试学习 SystemVerilog。在阅读它时,我遇到了以下代码,我无法完全理解它:

测试 1.

class A ; 
  task disp();
    $display(" This is class A "); 
  endtask 
endclass 

class EA extends A ; 
  task disp (); 
    $display(" This is Extended class A "); 
  endtask 
endclass 

program main ; 
  EA my_ea; 
  A my_a; 

  initial 
  begin 
    my_a.disp(); 
    my_a = my_ea; 
    my_a.disp(); 
  end 
endprogram 

测试 2.

class A ; 
  virtual task disp (); 
    $display(" This is class A "); 
  endtask 
endclass 
 
class EA extends A ; 
  task disp (); 
    $display(" This is Extended class A "); 
  endtask 
endclass 

program main ; 
  EA my_ea; 
  A my_a; 

  initial 
  begin 
    my_a = new(); 
    my_a.disp(); 

    my_ea = new(); 
    my_a = my_ea; 
    my_a.disp(); 
  end 
endprogram 

我对上面的 test1 代码有一些疑问。有对某些 'new' 函数的调用,但未在任何地方提供该函数的实现。这段代码如何编译然后运行?

同样在test2中,可以看到'virtual'关键字。我不明白使用 'virtual' 背后的原因。你能解释一下为什么我们必须在这种情况下使用 'virtual' 吗?

更新

我想实现 Greg 的示例代码。 但我遇到了一些问题,如下所示

                         Chronologic VCS (TM)
         Version J-2014.12-SP1-1 -- Wed Aug  8 08:33:23 2018
               Copyright (c) 1991-2014 by Synopsys Inc.
                         ALL RIGHTS RESERVED

This program is proprietary and confidential information of Synopsys Inc.
and may be used and disclosed only as authorized in a license agreement
controlling such use and disclosure.

Parsing design file 'design.sv'
Parsing design file 'testbench.sv'

Error-[SE] Syntax error
  Following verilog source has syntax error :
  "testbench.sv", 21: token is '('
    function(A a);
             ^

1 error
CPU time: .073 seconds to compile
Exit code expected: 0, received: 1
Done

new关键字是构造函数,它创建对象。由于 new 未定义,它正在推断默认构造函数:

function new();
endfunction

必须在调用任何方法之前构造对象。 Test1应该通过一个空指针错误,因为你调用了一个尚未构造的对象的方法。

virtual 关键字和概念在 C++、Java 等中是相同的。在 virtual 主题和多态性上已经回答了很多对此的解释,例如: Why do we need virtual functions in C++?

简而言之,如果它是虚拟的,则指向子对象的父句柄可以执行该对象的方法。最好的理解方式是创建一个 class 和一个同时具有虚拟和非虚拟方法的子 class。示例:

module main ; 
  class A ; 
    function void disp (); 
      $display(" Non-Virtual from A "); 
    endfunction
    virtual function void vdisp (); 
      $display(" Virtual from A "); 
    endfunction
  endclass 

  class EA extends A ;
    function void disp (); 
      $display(" Non-Virtual from EA "); 
    endfunction
    virtual function void vdisp (); 
      $display(" Virtual from EA "); 
    endfunction
  endclass 

  function void disp(A a);
    a.disp();
    a.vdisp();
  endfunction

  EA my_ea; 
  A my_a; 

  initial 
  begin 
    my_a = new(); 
    my_ea = new(); 
    disp(my_a); 
    disp(my_ea); 
    my_a = my_ea; 
    disp(my_a); 
  end 
endmodule