system verilog中virtual关键字的作用

在system verilog中,virtual关键字可以用在以下三个地方:形容变量,形容function和task,形容class。

virtual形容变量

virtual形容变量时,最常见的是在声明interface时,作用是将该interface变为一个句柄,并不是一个真实的interface,而是指向interface的一个指针。

一般用法是,在top定义interface,这个是真实存在的interface,相当于是个实例,在driver和monitor里面定义virtual interface,然后将top的interface赋值给virtual interface,该virtual interface就是top中interface的指针了。

这样做的目的是,提高driver和monitor的重用性,避免出现绝对路径。

virtual形容function和task

当用virtual形容function和task时,该函数就可以被子类重载,不过不用virtual,该函数就不能被子类重载。这点设置我认为其实有点没有必要,在java中,并没有这样的规则,因为既然是面向对象编程,就必须有多态,子类必须可以重载掉父类的函数。所以,我认为在sv里面可以将所有的function和task都加上virtual,并且这样最为保险。

例子:

不加virtual的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class bird;
function void f();
$display("bird f");
endfunction
endclass

class parrot extends bird;
function void f();
$display("parrot f");
endfunction
endclass

...
bird b;
parrot p;
p = new();
b = p;
b.f();
...

结果是:

1
bird f

加virtual的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class bird;
virtual function void f();
$display("bird f");
endfunction
endclass

class parrot extends bird;
virtual function void f();
$display("parrot f");
endfunction
endclass

...
bird b;
parrot p;
p = new();
b = p;
b.f();
...

结果是

1
parrot f

virtual形容class

用virtual形容class时,表示该类时虚类,即不能直接例化的类,必须要继承之后才能使用。一般这种类里面都会定义一些虚函数,即加pure形容的函数,这些函数在虚类里面只有声明,没有具体实现,必须由子类继承后实现。

例如

  1. 直接例化是会报错的
1
2
3
4
5
6
7
virtual class vc;
pure virtual function void f();
endclass

...
vc = new();
...
1
2
3
Error-[SE] Syntax error
Follow verilog source has syntax error:
6: token is '='
  1. 子类不实现虚类的函数也会报错
1
2
3
4
5
virtual class vc;
pure virtual function void f();
endclass
class tc extends vc;
endclass
1
Error-[SV-VMNI] Virtual method not implemented
  1. 只有对纯虚函数进行实现,才是对的
1
2
3
4
5
6
7
8
virtual class vc;
pure virtual function void f();
endclass
class tc extends vc;
virtual function void f();
$display("tc f");
endfunction
endclass

这样功能的出发点是,要求子类必须实现一些函数,这些函数是该父类必要的,如果没实现,就肯定有错。其实不用virtual和pure也可以,只不过加上了之后,如果出现了没有实现的函数,可以在编译阶段就发现。