systemverilog中的virtual function

virtual类型的函数在extern声明了之后,展开声明时还需要写virtual吗?

这是一个非常经典且容易产生困惑的 SystemVerilog 语法问题。

核心结论

在类体外(extern)展开声明时,不需要(也不建议)再写 virtual 关键字。

一旦你在类内部声明该函数为 virtual,这个属性就自动伴随该函数,无论是在类外定义还是在子类中重写,它永远都是虚函数。

1. 代码对比

正确写法:
cpp 复制代码
class my_driver extends uvm_driver;
    // 1. 类内声明:必须写 virtual
    extern virtual function void build_phase(uvm_phase phase);
endclass

// 2. 类外展开:不要写 virtual
function void my_driver::build_phase(uvm_phase phase);
    super.build_phase(phase);
    // ... 逻辑内容
endfunction
错误(或冗余)写法:

如果在类外写成 virtual function void my_driver::build_phase...,编译器通常会报错,或者至少会给出一个警告。因为 virtual 是成员的属性修饰符 ,而类外定义只是内容的填充


2. 为什么会有这种规定?

这主要源于底层语言的设计逻辑(类似于 C++):

  • 属性在"户口本"上: 类内部的声明(Declaration)就像是函数的"户口本",它定义了函数的名称、参数、返回值以及属性(是否为 virtual、是否为 local 等)。

  • 类外只是"施工现场": 类外的定义(Implementation)只是告诉编译器函数具体怎么执行。此时编译器已经通过类内的声明知道了它是 virtual,因此不需要重复。

3. 相关规则扩展

关键字 类内声明 (Inside) 类外展开 (Outside) 说明
virtual 必须写 不能写 虚函数属性在声明时确定。
static 必须写 不能写 静态成员函数的定义不带 static。
local / protected 必须写 不能写 访问权限仅由类内声明决定。
default 参数 写在声明处 不能写 参数默认值(如 int a=5)只能出现在类内。

4. 总结

你只需要记住:关键字(virtual, static, local)只在"类体内部"这个地盘生效,一旦出了类的大门(extern 展开),这些修饰符统统脱掉。

相关推荐
Nick.Q1 天前
$cast用法
systemverilog
不会武功的火柴3 天前
UVM验证入门(18)-Callback机制
systemverilog·ic验证·uvm方法学
不会武功的火柴7 天前
UVM验证入门(15)-uvm_agent代理
systemverilog·ic验证·uvm方法学
zhuangzhunag23 天前
【SV验证入门】接口在设计和验证中的使用
systemverilog
FPGA_小田老师1 个月前
FPGA语法基础(二):SystemVerilog 数组清零方法详解
fpga开发·systemverilog·数组清零·systemverilog数组·systemverilog语法
m0_713541843 个月前
systemverilog如何解决不能使用变量索引来进行位选择的范围指定
算法·systemverilog
那么菜4 个月前
《SVA断言系统学习之路》【02】并发断言
systemverilog
SuperGQB4 个月前
UVM验证(三)—UVM机制(1)
systemverilog·ic验证·uvm方法
一只迷茫的小狗7 个月前
关于systemverilog中在task中使用force语句的注意事项
systemverilog