UVM的创建离不开factory的三个核心要素:注册、创建和覆盖
`uvm_{component,object}_utils()
uvm_{component,object}::type_id::create()
uvm_{type,inst}_override{,_by_type}()
其中覆盖实例程序:通过类型覆盖方法set_type_override来说明。
module factory_override;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
function new(string name="comp1", uvm_component parent=null);
super.new(name, parent);
$display($sformatf("comp1:: %s is created", name));
endfunction: new
virtual function void hello(string name);
$display($sformatf("comp1:: %s said hello!", name));
endfunction
endclass
class comp2 extends comp1;
`uvm_component_utils(comp2)
function new(string name="comp2", uvm_component parent=null);
super.new(name, parent);
$display($sformatf("comp2:: %s is created", name));
endfunction: new
function void hello(string name);
$display($sformatf("comp2:: %s said hello!", name));
endfunction
endclass
comp1 c1, c2;
initial begin
comp1::type_id::set_type_override(comp2::get_type()); //comp2类型覆盖了comp1类型
c1 = new("c1");
c2 = comp1::type_id::create("c2", null);
c1.hello("c1");
c2.hello("c2");
end
endmodule
输出结果:
comp1:: c1 is created
comp1:: c2 is created
comp2:: c2 is created
comp1:: c1 said hello!
comp2:: c2 said hello!
在上面的例码中,comp2类型覆盖了comp1类型
comp1::type_id::set_type_override(comp2::get_type());
紧接着对c1和c2对象进行了创建,可以从输出结果看到的是c1的所属类型仍然是comp1,c2的所属类型则变为了comp2。这说明了factory的覆盖机制只会影响通过factory方法来创建的对象。
所以,通过type_id::create()和factory的类型覆盖可以实现对象类型在例化时的灵活替换。在上面的例子中,有几点隐藏的重点需要读者注意:
- 在例化c2之前,首先应该用comp2来替换comp1的类型。只有先完成了类型替换,才可以在后面的例化时由factory选择正确的类型。
- 上面的例码中较好地反映了一些实际情况。首先在声明c2时,由于verifier不知道今后可能存在覆盖的情况,所以类型为comp1。在后面发生了类型替换以后,如果原有的代码不做更新,那么c2句柄的类型仍然为comp1,却指向了comp2类型的对象。这就要求,**comp2应该是comp1的子类,**只有这样,句柄指向才是合法安全的。
- c2在调用hello()方法时,由于首先是comp1类型,那么会查看comp1::hello(),又由于该方法在定义时被指定为虚函数,这就通过了多态性的方法调用,转而调用了comp2::hello()函数。因此,显示的结果也是“comp2:: c2 said hello!”。
常见错误:
直接用vcs跑代码:
vcs factory_override.sv
报错:为什么编译代码时报错:source file “uvm_macros.svh” connot be opened for reading due to ‘No such file or dictionary’.
需要导入UVM库
添加 -ntb_opts uvm 参数,即:
vcs -sverilog -ntb_opts uvm my_file.sv
生成simv,就会出仿真结果了。
参考:https://blog.eetop.cn/blog-1561828-2331497.html
https://blog.csdn.net/qq_37960317/article/details/117046310
如有错误请指正,谢谢。