工厂机制(factory)—UVM

  • Post author:
  • Post category:其他




简介

  • 工厂的存在,就是为了更方便地替换验证环境中的实例或者注册了的类型,同时工厂的注册机制也带来了配置的灵活性;

  • 实例或者类型的替代,在UVM中称作覆盖

    (override),而**被用来替换的对象或者类型,应该满足注册(registration)和多态(polymorphism)**的要求;
  • uvm的验证环境构成可以分为两个部分:一部分构成了环境的层次,通过ucm_component类完成;另一部分构成了环境的属性(例如配置)和数据传输,这部分通过uvm_object类完成。
  • ucm_component类继承与uvm_object,这两种类也是进出工厂的主要模具和生产对象。之所以称为模具,是因为通过注册,可以利用工厂完成对象的创建;
  • 之所以由工厂创建对象,也是利用了工厂生产模具可以灵活替代的好处,这使得在不修改原有验证环境层次和验证包的同时,实现了对环境内部组件类型或者对象的覆盖。



ucm_component和uvm_object的例化

  • 必须要有的步骤:


    定义——>注册——>构建

  • 注册:`uvm_component_utils(T,parent) 或者 uvm_object_utils(T)
class comp1 extends uvm_component;//定义
    `uvm_component_utils(comp1)   //注册
    function new(string name ="comp1",uvm_component parent = null);//构建函数
        super.new(name,parent);
    endfunction:new  
endclass

class obj1 extends uvm_object;//定义
    `uvm_object_utils(obj1)   //注册
    function new(string name ="obj1");//构建函数
        super.ner(name);
    endfunction:new  
endclass

//两种对象的创建方式
comp1 c1,c2;
obj1 o1,o2;
initial begin
    c1 = new("c1");
    o1 = new("o1");
    //uvm中要求用下面这种
    c2 = comp1::type_id::create("c2",null);//利用工厂创建
    o2 = obj1::type_id::create("o2");
end



为什么需要宏呢?

  • 两个宏的作用就是将类注册到factory中。注意,factory是独有的,有且只有一个,这保证了多有的类都注册在一个“机构”中。

  • 只要一个类使用宏uvm_component_utils注册,且被实例化了之后,这个类里面的run_phase就会被自动调用



uvm_coreservice_t类

这个类并不是uvm_component 和uvm_object,也并没有例化在UVM环境中,而是独立于UVM环境之外。

这个类内置了UVM世界核心的组件和方法,主要包括:

  • 唯一的uvm_factory,该组件用来注册、覆盖和例化
  • 全局的report_server,该组件用来做消息统筹和报告
  • 全局的tr_database,该组件用来记录transaction
  • get_root()方法用来返回当前UVM环境的结构顶层对象

uvm_coreservice_t只会被UVM系统在仿真开始时例化一次。用户无需,也不应该自行再额外例化该核心服务组件。




注册后的对象创建(component或者object)

  • 最终创建出来的uvm_component是会在UVM层次结构中,而uvm_object则不会显示在层次中。

  • uvm_component::new(name,parent)保留两个参数,是为了通过parent起到“钩子”的作用,一层层由底层勾住上层,这样就能够将整个UVM结构串起来


  • uvm_object::new(name)中没有parent参数,所有不会显示在层次结构中

    ,只能作为configuration或者transaction等,用来做传递的配置结构体或者抽象数据传输的数据结构体,称为uvm_component的成员变量




component/object与工厂有关的方法

uvm_component和uvm_object提供的,配合工厂注册、创建和覆盖的方法:

  • create()
  • create_component()
  • get()
  • get_type_name()
  • set_inst_override()
  • set_type_override()



工厂创建component/object的方法

除了使用component/object来创建实例,也可以用factory来创建:

  • create_component_by_name()
  • create_component_by_type()
  • create_object_by_name()
  • create_object_by_type()



覆盖方法



覆盖(override)机制可以将原来所属的类型替换成另外一个新的类型



在覆盖之后,

原本用来创建原型类型的请求,将由工厂来创建新的替换类型

  • 无需修改原始代码,继而保证了原有代码的封装性
  • 新的替换类型必须与被替换类型相兼容,否则稍后的句柄赋值将失败,所以使用继承(用子类覆盖原来的父类)
  • 做顶层修改时,非常方便

要想使用覆盖,

原有类型和新类型均需要注册


当时用create()来创建对象时:

  • 工厂会检查,是否原有类型被覆盖;
  • 如果是,那么工厂会创建一个新类型(覆盖后的)的对象;
  • 如果不是,那么它会创建一个原有类型的对象;

覆盖发生时,可以使用“类型覆盖”或者“实例覆盖”

  • 类型覆盖(set_type_override)是指,UVM层次结构下所有的原有类型都被覆盖类型所替换。
  • 实例覆盖(set_inst_override )是指,在某些位置中的原有类型会被覆盖类型所替代。


set_type_override

()

static function void set_type_override(uvm_object_wrapper override_type,
                                       bit replace = 1 );
//调用
    origin_type::type_id::set_type_override(new_type::get_type())
  • uvm_object_wrapper override_type 是注册过后的某一个类在工厂中注册时的句柄。

    怎么找到这个句柄?

    使用静态函数new_type::get_type()

  • bit replace = 1

    1:如果已经有覆盖存在,那么新的覆盖会替代旧的覆盖

    0:如果已经有覆盖存在,那么该覆盖将不会生效


set_inst_override()

static function void set_inst_override(uvm_object_wrapper override_type,
                                       string inst_path,
                                       uvm_component parent = null);

//调用
origin_type::type_id::set_type_override(new_type::get_type(),"orig_inst_path");
   
  • string inst_path指向的是组件结构的路径字符串,比如root里面的test,test里面有env,env有checker,这个路径就是 “root.test.env.checker”

  • uvm_component parent = null

    如果缺省,表示inst_path内容为绝对路径

    如果有传递值,则使用{parent.get_full_name(),’.’,inst_path}来作为目标路径

注意:

set_type_override()和set_inst_override()都是覆盖工厂创建的对象

,如果用new()调用,不是通过工厂创建对象




确保正确覆盖的代码要求

  • 将UVM环境中的所有类都注册到工厂中,并通过工厂来创建对象。
  • 在使用某些类时,确保该类已经被导入到当前域中
  • 通过工厂创建对象时,句柄名称应该同传递到create()方法中的字符串名字相同。

  • 覆盖操作在对象创建之前

  • 覆盖类最好是原始类的子类,而调用成员方法(原始类中)也应当声明为虚方法
  • 为了确保运行时覆盖类型句柄正确使用的方式,需要通过$cast()进行动态类型转换



版权声明:本文为SummerXRT原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。