目录
print_oerride_info(原类型) 列出原始类型和新类型
一.利用factory机制可以做什么?
引用白皮书中的话,UVM工厂的存在,"是为了更方便的替换验证环境中的实例或者注册了的类型,同时工厂的注册机制也带来了配置的灵活性".利用工厂机制,主要完成完成的工作为以下两点:
1.根据类名创建类的实例;
2.不对原代码进行改动的前提下,完成类的覆盖;
(override--是工厂机制优势最大的体现,实现了代码最大的复用性)
二.实现步骤(范式得背)
1.注册(必选项)
`uvm_component_utils(类名)
function new(string name='类名',uvm_componet parent=xx)
`uvm_object_utils(类名)
function new(string name='类名')
注册宏与new函数都是范式,死记硬背!
相较于object,component组件在new函数需要指定父类,因此,component与object无法互相重载
example
//例1 uvm_object类型:
class obj extends uvm_object;
`uvm_object_utlis(obj)
function new(string name='obj');
super.new(name);
$display($sfortmatf("%s is ceated",name));
endfunction:new
//例2 uvm_componet类型:
class comp extends uvm_componet;
`uvm_componet_utlis(obj)
function new(string name='comp',uvm_componet parent=null);
super.new(name,parent);
$display($sfortmatf("%s is ceated",name));
endfunction:new
2.重载(可选项)
无论之后是否对组件进行覆改,都需要将其注册到工厂中。
与注册类似,component与object在覆改时也是结构相似,但略有不同。
//comp与obj 各有四种方法,这里只列了两种常用的//
set_type_override_by_type
(uvm_object_wrapper original_type, 被重载类型
uvm_object_wrapper override_type, 重载类型
bit replace = 1 一般不用,为0时重载失败 )
该方法为全局覆盖,相当于整个验证环境中的A类型被全部替换为B类型
set_inst_override_by_type
(string relatve_inst_path, 相对路径
uvm_object_wrapper original_type, 被重载类型
uvm_object_wrapper override_type, 重载类型)
该方法为局部覆盖,只会重载相对路径下的类型
example
class driver_2 extends driver; //driver_2继承与driver
`uvm_component_utils(driver_2)
...
endclass
class monitor_2 extends monitor; //monitor_2继承自monitor
`uvm_component_utils(monitor_2)
...
endclass
class test_factory extends uvm_test;
`uvm_component_utils(test_factory)
env t_env;
...
function new(string name="test1", uvm_component parent=null);
super.new(name, parent);
factory.set_type_override_by_type(driver::get_type(),driver_2::get_type(),"*"); // 1. 通过组件对象进行覆盖
factory.set_type_override_by_name("monitor","monitor_2","*"); //2.通过组件名进行覆盖
factory.print(); //3. 打印结果检查对象是否被替换
endfunction: new
...
endclass
3.例化(必选项)
工厂机制中,更推荐使用::type_id::create的方式进行例化,而不是new的方式;
如果要进行重载,则只能通过::type_id::create的方式。
与注册和覆盖类似,component与object在覆改时也是结构相似,但略有不同。
comp_type::type_id::create(string name, uvm_component parent);
obj_type::type_id::create(string name);
example
module object_create;
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); //对父类new函数的继承
$display($sformatf("%s is created", name));
endfunction: new
function void build_phase(uvm_phase phase); //phase机制
super.build_phase(phase);
endfunction: build_phase
endclass
//注意分清楚component和object类
class obj1 extends uvm_object;
`uvm_object_utils(obj1)
function new(string name="obj1"); //注意没有parent
super.new(name);
$display($sformatf("%s is created", name));
endfunction: new
endclass
comp1 c1, c2;
obj1 o1, o2; //例化
initial begin
c1 = new("c1");
o1 = new("o1"); //SV创建方式
c2 = comp1::type_id::create("c2", null);
o2 = obj1::type_id::create("o2"); //UVM工厂创建方式
end
endmodule
输出结果:
c1 is created
o1 is created
c2 is created
obj1 is created
三.实现重载的条件(理解)
1.注册
重载类和被重载类在定义时注册到factory机制中;
2.例化
重载类和被重载类均需要使用type_id::create的方式例化;
3.派生
重载类和被重载类之间必须有派生关系,即只有子类才能重载父类;
(指的是最终的重载关系,因为连续重载中,过程中的重载双方可以没有派生关系,但是最终被重载的和重载的之间必须有关系(有点绕)
举个例子:B,C继承于A,则可以使B重载A,C重载B,最终得到结果是C重载A,C是A的子类,所以是没有问题的)
4. 同类
component与object之间无法相互重载;
四.factory的调试(了解一下)
print_oerride_info(原类型) 列出原始类型和新类型
print_topology 显示整颗uvm树的树形结构
factory.print(0/1/2) 打印所有被重载实例和类型,以及用户/系统创建和注 册到factory中的类名