电力电子转战数字IC20220713day47——覆盖方法

目录

4. 覆盖方法

set_type_override()

set_inst_override()

确保正确覆盖的代码要求(工厂的好处3)


4. 覆盖方法

工厂提供的便利

  • 作用:将原来所属的类型替换成另一个新的类型
  • 条件1:覆盖之后原本用来创建原属类型的请求,将由工厂来创建新的替换类型。不需要修改源代码,保证了代码的封装性;新的替换类型必须与被替换类型相兼容,否则稍后的句柄赋值将失败,所以使用继承
  • 条件2:要想实现覆盖特性,原有类型和新类型都需要注册
  • 优点:顶层修改方便,可灵活配置,用子类覆盖父类;允许不同对象修改其代码行为
  • create()创建对象时,工厂会检查if (原有类型被覆盖?) 创建一个新类型的对象;else 创建一个原有类型的对象
  • 分类:覆盖发生时,可以使用类型覆盖——uvm层次结构夏的所有原有类型都被覆盖类型替换;实例覆盖——某些位置中的原有类型被覆盖类型替换。

set_type_override()

static function void set_type_override ( uvm_object_wrapper override_type, bit replace =1);
  • uvm_object_wrapper override_type是注册过后的某一个类在工厂中注册时的句柄,用new_type::get_type()找到
  • bit replace=1
    • 1:如果已经有覆盖存在,新覆盖替代旧覆盖
    • 0:如果已经有覆盖存在,该覆盖不会生效
  • set_type_override是静态函数,调用如下
orig_type::type_id::set_type_override (new_type::get_type())
//typedef            静态函数               静态函数
//用new_type新类型替换原来的类型orig_type::type_id

set_inst_override()

static function void set_inst_override ( uvm_object_wrapper override_type, string inst_path, uvm_component parent=null);
  • string inst_path指向组件结构的路径字符串(?)
  • parent为null表示使用inst_path内容为绝对路径。如果有值传递就用 parent.get_full_name(),’.’,inst_path 来作为目标路径
orig_type::type_id::set_inst_override ( new_type::get_type(), "orig_inst_path")
//typedef            静态函数               静态函数

环境配置最顶层为root,然后是test,然后是env,如果再往下有个checker,路径为root.test.env.checker

  • 多个类都有提供与覆盖有关的函数
    • uvm_component::set_{type, inst}_override{_by_type}
    • uvm_component_registry::set_{type, inst}_override
    • uvm_component_registyr::set_{type, inst}_override
    • uvm_factory::set_{type, inst}_override
  • 上述的orig_type::type_id调用覆盖函数;在uvm_component的域直接调用;用uvm_factory做覆盖
module factory_override;
import uvm_pkg::*;//可直接import和include,编译器已经包含了
`inculde "uvm_macros.svh"

class comp1 entends uvm_component;//1声明
`uvm_component_utils(comp1)//2注册

function new (string name="comp1", uvm_component parent= null);//3new函数
	super.new(name, parent);
	$display ($sformatf("comp1::%s is created", name));
	endfunction

virtual function void hello (string name);
	$display ( $sformatf("comp1:: %s is 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 is said hello!", name);
endfunction
endclass

comp1 c1, c2;//两个句柄都是comp1的类型
initial begin
comp1::type_id::set_type_override (comp2::get_type());//调用覆盖函数
c1= new("c1");//例化c1(comp1),没有通过工厂。打印comp1::c1 is created,
c2= comp2::type_id::creare("c2",null);//工厂创建的对象,create返回一个comp2句柄给c2
//但是c2是父类的句柄,这里就是子类句柄覆盖父类句柄。所以必须是继承关系
//用工厂注册,就一定要用工厂来创建,达到便利的目的
//打印comp1::c2 is created,comp2::c2 is created
c1.hello("c1");//调用comp1的hello,打印 comp1::c1 is said hello
c2.hello("c2");//调用comp2的hello,打印 comp2::c2 is said hello
end

endmodule

 

  • 工厂的覆盖机制只会影响通过factory注册并且创建的对象c2
  • 在create c2之前要先用comp2替换comp1的类型
  • c2的类型是comp1,这改变不了,但是可以改变对象,指向了comp2的对象
  • hello函数必须是virtual!调用c2.hello才会指向子类的hello
  • 需要被继承和覆盖的方法都要用virtual虚方法

确保正确覆盖的代码要求(工厂的好处3)

  • 将uvm环境中所有类都注册到工厂,并通过工厂创建对象
  • 使用类时确保已经被import到当前域scope
  • 通过工厂例化时,句柄名称应该和传递到create()方法中的字符串名称系统
  • 无论是通过层次路径名称来覆盖还是配置,将例化组件的句柄名称和创建时create()方法中的字符串名称保持一致
  • 覆盖采用的parent wins模式,所以要注意在同一个顶层build_phase()中覆盖方法应该发生在对象创建之前。即:先覆盖,再例化
  • 要覆盖的类一定要继承于被覆盖的类,调用的成员方法一定要virtual虚方法
  • 另外一种确保覆盖类型句柄正确使用的方式,$cast动态类型转换

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值