概述
工厂的意义:为了更方便的替换验证环境中的实例或已注册的类型,使注册机制更加灵活。
UVM验证环境的两大类:uvm_component,uvm_object。
从关系上来看,uvm_component 继承于 uvm_report_objec t继承于 uvm_object。uvm_component实现了验证环境的层次化,uvm_object实现了环境的配置和数据的传输。
uvm_component是静态的组件类,对应sv中的generator,stimulator,monitor,agent,checker,refmod,env,test等
uvm_object是动态的验证场景,对应sv中的transaction,从generator流向stimulator的数据包。
---------------------------------------------------------------------------------------------------------------------------------
工厂类的三个步骤:定义、注册、创建
class comp1 extends uvm_component; //定义comp类
'uvm_component_utils(comp1) //注册
function new(string name = "comp1", uvm_component parent = null); //创建
super.new(name, parent);
$display($sformatf("%s is creates", name));
endfunction: new
endclass
component类中的new函数中的参数(name,parent)不可进行更改,其中parent是例化该实例(comp1)的对象
class obj1 extends uvm_object; //定义comp类
'uvm_object_utils(obj1) //注册
function new(string name = "obj1"); //创建
super.new(name);
$display($sformatf("%s is creates", name));
endfunction: new
endclass
object类相较于component类,new函数中只有一个参数(name)
---------------------------------------------------------------------------------------------------------------------------------
如果需要创建component或object对象,可采用下列方式:
//创建uvm_component对象
comp_type::type_id::create(string name, uvm_component parent);
//创建uvm_object对象
object_type::type_id::create(string name);
可以简单的理解为工人(comp_type)从工厂里找到模具(type_id),并放到机器上进行加工(create) 。create会在后台调用new函数进行创建。
---------------------------------------------------------------------------------------------------------------------------------
uvm_coreservice_t类包括:
- uvm_factory:注册,覆盖,例化
- report_server:全局,消息统筹,报告
- tr_database:全局,记录transaction
- get_root():返回当前UVM环境的结构顶层对象
需要注意, uvm_coreservice_t不是uvm_component或uvm_object类型,并且它所包含的类都是唯一的。
---------------------------------------------------------------------------------------------------------------------------------
对象创建方法
- type_id
c2 = comp1::type_id::create("c2", null); c2 = obj1::type_id::create("o2");
- creat
- 通过coreservice句柄拿到factory句柄里的方法进行创建:
create_component_by_name(),
create_component_by_type()
create_object_by_name()
create_object_by_type()
component中name和parent的作用:uvm_component::new(name, parent)保留这两个参数,可以将结构一层一层的连接起来,如同“钩子”勾住上层结构。而object中没有parent参数,所以不会显示在UVM层次中。
---------------------------------------------------------------------------------------------------------------------------------
覆盖 override
在SV中,如果需要修改别人的driver,就会对源代码进行改动,导致:1.影响他人使用;2.遇到无法修改的ip。因此UVM提供覆盖方法,将原来的类型替换成另一个类型,在覆盖之后,原来用于创建原属类型的请求,将由工厂创建新的替换类型,但是新的类型一定要继承于原有类型,且原有类型和新类型都需要注册。
使用覆盖的优点:
- 无需修改原始代码,保证源代码的封装性,也确保句柄不会失效
- 使顶层修改更加方便,可使用子类覆盖父类,也可使用不同的对象修改代码行为
覆盖方法:
- 类型替换set_type_override(),UVM层次结构下所有的原有类型都被覆盖类型所替换。
- 实例替换set_inst_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
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
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"); //因为使用new创建而非工厂创建,所以结果为comp1::c1 is created
c2 = comp1::type_id::create("c2", null);//首先调用comp1的new()打印comp1::c2 is
//created,然后调用comp2的new()函数打印
//comp2::c2 is created此处就是用new创
//建和工厂创建的区别
c1.hello("c1");
c2.hello("c2"); //先调用comp1类型,那么会查看comp1::hello(),又由于该方法在定义时
//被指定为虚函数,这就通过了多态性的方法调用,转而调用了
//comp2::hello()函数
end
endmodule
输出结果
--------------------------------------------------------------------------------------------------------------------------------
最后是factory的三个核心要素:注册、创建、覆盖
- 'uvm_{component,object}_utils
- uvm_{component,object}::type_id::create()
- set_{type,inst}_override{,_by_type}()
最后
以上就是自然超短裙为你收集整理的UVM——工厂机制,覆盖方法的全部内容,希望文章能够帮你解决UVM——工厂机制,覆盖方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复