class中的interface是在仿真运行态(代码层面来看是在initial里面)被连接上去的(通过config db方式),所以要加virtual。
如果不加virtual,那么意味着编译的时候就要和dut链接。
深层次原因其实是硬件描述语言与面向对象软件编程语言的差异点,要理解清楚这个差异我们看下面两段代码:
(1)
interface intfa;
logic a;
........................
endinterface
module a();
intfa intfa0;
endmodule
(2) class a;
intfa intfa1;
endclass
说明如下:
(1)第一段代码中,只要module里面定义了intfa0,那么编译的时候就知道这是一个硬件结构,是一种数据结构,需要分配内存空间来对应。可以抽象理解interface定义出来的是一种“静态存在”的数据结构。
(2)第二段代码中,如果我们也使用intfa intfa1,那么就意味着class a中有一个静态存在的接口,需要分配内存来对应,但是问题来了,class a本身还不存在,因为只有a这个类只有被实例化出来,才会被分配内存空间,通常是在别的地方被new这种方法(或者create方法)实例化出来。比如下面的代码:
function xxx
a a1;
a1 = new();
endfunction
只有在代码执行到new这一行的时候,a1这个对象才存在,才会被分配内存空间,请注意:此时一定是处于运行态,因为代码已经执行起来了。
那么这就有了一个矛盾:
在运行态才存在的a1里面有一个在静态就存在的interface!!!
如果把class比作母亲,interface比作孩子,就是:
妈妈(class)还没有生出来(创建出来),孩子就出来了(创建出来了)!!
这个明显逻辑就不通啊,当然对编译器和仿真器来说,看到这种情况,它也不知道怎么干活啊!
那么怎么办?
就是给class里面的interface加上virtual,含义就是:这个interface静态不存在!!!
只有当class的对象被创建出来以后,这个interface才存在。
此时在运行态再把这个动态的产生的interface和module里面定义的静态interface连接起来。
这逻辑上就通了,编译器和仿真器也知道该怎么干活了。
类似的,我们可以推断出来module和class也是类似的区别。