目录
4.1 set_inst_override() 和set_type_override()
1.工厂机制
工厂模式的主要解决的问题是,将原来分布在各个地方的对象创建过程单独抽离出来,交给工厂类负责创建。其他地方想要使用对象直接找工厂(即调用工厂的方法)获取对象。
- UVM工厂的存在就是为了更方便地替换验证环境中的实例或者注册了的类型,同时工厂的注册机制也带来了配置的灵活性。
- 实例或类型替代,在UVM中称作覆盖,而被用来替换的对象或者类型,应该满足注册和多态的要求。
- uvm_component类构成了验证环境的层次,uvm_object类构成构成环境的属性和数据传输,这两种类是进出工厂的主要模具和生产对象。
- 对象由工厂生产是利用工厂生产模具可灵活替代的好处,在不修改原有验证环境层次和验证包的同时,实现对环境内部组件类型或者对象的覆盖。
2.工厂的创建
2.1 定义
例如:class comp1 extend uvm_component
2.2 注册
UVM提供了多个工厂机制的注册宏,下面给出一种我常用的注册宏。
`uvm_{component,object}_utils(class_type_name),
在工厂注册的类一般分为两大类型,即 uvm_componet 和 uvm_object
2.3 构建函数
- component 构建函数 function new (string name = " name", uvm_component parent = null)
创建对象comp_type::type_id::create(string name,uvm_component parent);
- object 构建函数 function new (string name = “name”)
创建对象object_type::type_id::create(string name);
例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); //构建函数
$display($sfortmatf("%s is ceated",name));
endfunction:new
注:以上两个代码的注册宏和new()函数是范式,结构和参数都不可更改。
1)创建uvm_object类
com_type::type_id::creat(string name)
2)创建uvm_componet
com_type::type_id::creat(string name,uvm_componet parent)
3. uvm_coreservice_t类
该类内置了uvm世界核心的组件和方法,主要包括:
- 唯一的uvm_factory,该组件用来注册、覆盖和例化
- 全局的report_server,该组件用来做消息统筹和报告
- 全局的tr_database,该组件用来记录transaction记录
- get_root()方法用来返回当前uvm环境的结构顶层对象
注意:uvm_coreservice_t不是component或者object类型,也并没有例化在uvm环境中,而是独立于uvm环境之外的。详细看红宝书p265。
4. 覆盖
- 要想实现覆盖特性,原有类型和新类型均需要注册
- 覆盖的新类型使用继承,是子类
- 覆盖盖发生时,可以使用“类型覆盖”或者“实例覆盖”
- 类型覆盖:uvm层次结构下的所有原有类型都被覆盖类型所替换
- 实例覆盖:在某些位置中的原有类型会被覆盖类型所替换
4.1 set_inst_override() 和set_type_override()
static function void set_inst_override(uvm_object_wrapper override_type,string inst_path,uvm_component parent=null);
string inst_path指向的是组件结构的路径字符串
uvm_component parent=null
如果缺省,表示inst_path为绝对路径,否则使用{parent.get_full_name().inst_path}作为目标路径
static function void set_type_override(uvm_object_wrapper override_type,bit replace=1);
uvm_object_wrapper override_type为某一个类在工厂注册时的句柄
bit replace=1,有覆盖存在,新覆盖会替代旧覆盖,否则,有覆盖存在,该覆盖不会生效
实例:
module factory_override;
import uvm_pkg::*;
'include "uvm_macros.svh"
class comp1 extends uvm_component;
'uvm_component_utils(copm1)
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 is said hello!",name));
endfunction
endclass
class comp2 extends comp1;
'uvm_component_utils(copm2)
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 is said hello!",name));
endfunction
endclass
comp1 c1,c2;
initial begin
comp1::type_id::set_type_override(comp2::get_type());
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 is said hello!
comp2::c2 is said hello!
注意:
- 新旧类型都要注册
- 新类型是继承的子类
- 父类用virtual
- factory的覆盖机制只会影响factory注册并且创建的对象
- 先做覆盖,再做类型对象创建
- 高层次的覆盖优先级更高