uvm_objectionuvm_component基础  

uvm_objectionuvm_componentuvm中两大基础类,刚开始学习的时候,对两个东西认识不深,以为它们俩差不多,谁知道它两是一个是“爷爷”,一个是孙子的关系,两者贯穿整个 uvm验证方法学。至于为什么要划分uvm_objectuvm_component呢,是因为前任在验证的过程中发现,对事情进行分工能降低复杂度,也能提高维护效率。uvm_objectuvm中的地方比较基础,如果按照OPP的思想,它是一个最基础(base)没有太多的物理含义,而uvm_component是高层次抽象后的,具有物理含义,更像一个“对象”,例如我们前面谈到的driver or montIor它们都有自己的意义和功能。

如下图所示,先来整体看一下,uvm方法学中核心的几个自带类型:

 

 

  • uvm_void:是是始祖类,人如其名,其中不包含任何函数和类
  • uvm_obect: 比较基础的类,包含一些比较基础的常用函数,如Copy函数、Clone函数、Compare函数、Print函数
  • uvm_component:uvm组件类,继承于该类的子类,用于构成UVM环境(uvm_tree),如在系列(一)中已经涉及过的uvm_driver、uvm_montior、uvm_envuvm_scoreboard,其他几个组件在后续讲述过程中将会全部涉及。

为了构建uvm_tree结构,uvm_component的实例化具有它自己的特色,需要采用create创建, 原码如下:

//uvm_object
static function T create(string name , uvm_component parent = null, string context="");
//uvm_component static
function T create(string name , uvm_component parent , string context="");

uvm_object在实例化过程中,可以指定 parent组件,也可以不指定;但是uvm_component在实例化过程中必须指定,只有指定了parent组件,该子compoent才能成功的挂载于uvm_tree中。

uvm_objectuvm_component的区别:

  • uvm_component继承于uvm_objection,包含一些uvm_objection没有的特性和函数,如phase系列函数
  • uvm_component必须通过create创建,uvm_objection可以采用new/create创建
  • uvm_component存在于验证的整个过程中,不会任何组件(component)不会被析构(释放内存空间),uvm_obect可以在验证的过程中任何时刻被创建实例和析构

为了使用uvm_objectuvm_component自带的函数和机制,我们需要把我们继承类均注册到一张表格中,这张表格主要用于类的继承重用,我们把这些称为工厂机制(factory)这个过程称为注册

uvm_object类注册:

  • uvm_object_utils: 用于把一个直接或者间接派生自uvm_object的类注册到factory
  • uvm_object_param_utils:用于把一个直接或者间接派生自uvm_object的参数化的类注册到factory

参数化类,形如 

class A#(int WIDTF=32) extend uvm_obejct

示例代码如下:

class regfile extends uvm_reg_file;
    `uvm_object_utils(regfile)
    function new(input string name="unnamed_regfile");
        super.new(name);
    endfunction
endclass    

uvm_object类及其成员注册:

  • uvm_object_utils_begin: (类) ... uvm_object_utils_end
  • uvm_object_param_utils_begin: (类) ... uvm_object_param_utils_end

只有将成员变量注册后,使用Copy函数、Clone函数、Compare函数、Print函数才能有效。

常用的变量的注册有以下几种;

`define uvm_field_int(ARG,FLAG)
`define uvm_field_real(ARG,FLAG)
`define uvm_field_enum(T,ARG,FLAG)
`define uvm_field_object(ARG,FLAG)
`define uvm_field_string(ARG,FLAG)
`define uvm_field_queue_enum(ARG,FLAG)
`define uvm_field_queue_int(ARG,FLAG)
`define uvm_field_queue_object(ARG,FLAG)

注册示例代码如下:

class my_transaction extends uvm_sequence_item;

   rand bit[47:0] dmac;
   rand bit[47:0] smac;
   rand bit[15:0] ether_type;
   rand byte      pload[];
   rand bit[31:0] crc;
   rand bit       crc_err;

   `uvm_object_utils_begin(my_transaction)
      `uvm_field_int(dmac, UVM_ALL_ON)
      `uvm_field_int(smac, UVM_ALL_ON)
      `uvm_field_int(ether_type, UVM_ALL_ON)
      `uvm_field_array_int(pload, UVM_ALL_ON)
      `uvm_field_int(crc, UVM_ALL_ON)
      `uvm_field_int(crc_err, UVM_ALL_ON | UVM_NOPACK)
   `uvm_object_utils_end

   function new(string name = "my_transaction");
      super.new();
   endfunction

endclass

uvm_component类注册

  • uvm_component_utils: 用于把一个直接或者间接派生自uvm_component的类注册到factory
  • uvm_component_param_utils:用于把一个直接或者间接派生自uvm_component的参数化的类注册到factory

uvm_component类及其成员注册:

  • uvm_component_utils_begin: (类) ... uvm_component_utils_end
  • uvm_component_param_utils_begin: (类) ... uvm_component_param_utils_end

  只有将ucm_component类注册到factory后,才能使用一些component重要的机制,那为什么要将comonpent的成员也注册呢,这是的意义不在于使用copy等函数,因为component组建copy等操作意义不大,比较容易想到的问题,复制的组件的父类是谁(专业一点说就是parent无法指定),两个两同的组件又有什么用呢,啥用也没有,它的最大的意义在于自动使用config_db来获取某些变量的值。置于什么是config_db,可以先理解为一个传递参数的工具,比较形象的比如是 写信者、邮递员和收信者之间传递信件,config_db就是邮递员。

 

内容来源于网络如有侵权请私信删除
你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!