在继承中,我们看到由基类句柄调用的指向子类实例的方法最终将执行基类方法,而不是子类中的方法。 如果基类中的该函数被声明为虚函数,则仅将执行子类方法。
bc = sc; // 基类句柄指向子类
bc.display (); // 这会在基类而不是我们可能认为的子类中调用display()
没有虚拟 virtual 关键字
// Without declaring display() as virtual
class Packet;
int addr;
function new (int addr);
this.addr = addr;
endfunction
// 这是一个正常的函数定义,以关键字“ function”开头
function void display ();
$display ("[Base] addr=0x%0h", addr);
endfunction
endclass
module tb;
Packet bc;
ExtPacket sc;
initial begin
sc = new (32'hfeed_feed, 32'h1234_5678);
bc = sc;
bc.display ();
end
endmodule
Simulation Log
ncsim> run
[Base] addr=0xfeedfeed
ncsim: *W,RNQUIE: Simulation is complete.
使用 virtual 关键字
class Packet;
int addr;
function new (int addr);
this.addr = addr;
endfunction
// Here the function is declared as "virtual"
// so that a different definition can be given
// in any child class
virtual function void display ();
$display ("[Base] addr=0x%0h", addr);
endfunction
endclass
module tb;
Packet bc;
ExtPacket sc;
initial begin
sc = new (32'hfeed_feed, 32'h1234_5678);
bc = sc;
bc.display ();
end
endmodule
Simulation Log
ncsim> run
[Child] addr=0xfeedfeed data=0x12345678
ncsim: *W,RNQUIE: Simulation is complete.
请注意,**将基类函数设为虚拟时,将执行子类display()函数**。
关键要点是,您应该始终将基类方法声明为虚拟方法,以便现有的基类句柄现在将引用子类中的函数重写。
参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-virtual-methods