SV中的virtual关键词和extern关键词
virtual在SV中的应用主要有三方面,分别是虚类,虚方法和虚接口。
1.虚类(也叫抽象类)
关键词为virtual class,应用不如其余两个广泛,一个例子是UVM中所有类的基类uvm_void,它不包含任何成员变量和方法,不能被例化,但可以被扩展。
virtual class uvm_void;
endclass
虚类不能被例化,只有被继承为子类后才可以例化为对象。
2.虚方法
关键词为virtual task/function,对应类的三要素中的多态。SV不允许一个子类句柄指向父类对象,但是可以让一个父类句柄指向子类对象。由于父类句柄只能访问父类的成员变量和方法,不利于验证环境的复用;所以为了让继承了同一父类的子类能将一个同名方法扩展为不同功能的方法,利用类的多态,将父类中的方法声明为virtual,而指向子类对象的句柄就可以根据指向的对象类型,而不是句柄类型来调用我们希望调用的方法。
下面引用SV绿皮书226页中的例子:
class Transaction;
rand bit [31:0]src,dst,data[8];
bit[31:0]crc;
virtual function void calc_crc();
crc = src^dst^data.xor;
endfunction
endclass
class BadTr extends Transaction;
rand bit bad_crc;
virtual function void calc_crc(); //子类的方法不是必须声明为virtual
super.calc_clc();
if(bad_crc) crc = ~crc;
endfunction
endclass
Transaction tr;
BadTr bad;
initial begin
tr = new(); //创建父类对象
tr.calc_clc(); //调用父类方法
bad = new(); //创建子类对象
bad.calc_clc();//调用子类方法
tr = bad; //父类句柄指向子类对象
tr.calc_clc(); //调用子类方法
end
如果Transaction有很多子类,并且希望拥有自己独特的calc_clc()方法,那么将父类方法声明为virtual会很实用。
3.虚接口
关键词为virtual interface. SV中interface的性质非常接近module,可以视为硬件,而在UVM将验证环境按软件和硬件分开时,interface应该在硬件域module中例化,而不是在软件域class中例化。为了将验证环境与DUT相连接,只将interface的句柄传进验证环境,既解决了例化问题,也使得软硬件的分离更加彻底。
extern在SV中可以用来限制整个类的代码段长度
在方法、任务声明前加关键词extern,不写具体的参数和方法实现,只起到一个占位声明的作用
class Transaction;
rand bit [31:0]addr,crc,data[8];
extern function void display();
endclass
function void Transaction::display();
$display("@% 0t:Transaction addr=%h,crc=%h",
$time,addr,crc);
$write("\tdata[0-7]=");
foreach(data[i])$write(data[i]);
$display();
endfunction