当前位置: 首页 > article >正文

【学习记录丨UVM】2.1uvm_component 与uvm_object

UVM中常用类的继承关系

1.uvm_component派生自uvm_object

         上图展示了UVM中常用类的继承关系,可以看到:

(一) uvm_conponent是继承自uvm_object的。这说明了uvm_component继承了object的特性,又同时有自己的特别属性:1. 能够在new的时候指定parent参数来形成UVM平台组件间的树形组织结构2. 有phase的自动执行特点

(二) 所有UVM树的结点都是由uvm_component组成的。这些在前边也介绍过。只有派生自uvm_component的类才能成为UVM树的节点。

可以回顾一下前边的介绍,看一下各个类都是从哪个派生出来的。【学习记录丨UVM】1.11建造测试用例-CSDN博客

 2.常用的派生自uvm_object的类

在验证平台中经常遇到的派生自uvm_object的类有:

uvm_sequence_item :

uvm_sequence_item派生自uvm_transaction,在继承了uvm_transaction的性质基础上多了些实用的成员变量和函数/任务。所以,我们在验证平台中的transaction是派生自uvm_sequence_item。

class my_transaction extends uvm_sequence_item;
  ...
endclass

uvm_sequence

所有的sequence都派生自uvm_sequence,sequence就是sequence_item的组合。 sequence直接和sequencer打交道,当driver向sequence索要数据时,sequencer会检查是否有sequence要发送数据。当发现有sequence_item(transaction)待发送时,就会把sequence_item交给driver。可以回顾:【学习记录丨UVM】1.10UVM的终极大作:sequence_uvm function new(string name=-CSDN博客

class my_sequence extends uvm_sequence#(my_transaction);
  my_transaction m_trans;
 
  `uvm_object_utils(my_sequence)//factory注册
  function new(string name="my_sequence");
    super.new(name);
  endfunction
 
  virtual task body();//当一个sequence启动后会自动执行body()中的代码
    repeat(10)begin
      `uvm_do(m_trans)//调用宏产生事务对象,每调用一次产生一个
    end
    #1000;
  endtask
endclass

 config:

这个前边还没出场过,可以先简单了解,后边的文章会有介绍。 config一般直接派生自uvm_object。 config的主要功能是规范验证平台的行为方式。

 uvm_reg_item:

它派生自uvm_sequence_item,用于register model中。

uvm_reg_map,uvm_mem,uvm_reg_field,uvm_reg,uvm_reg_file,uvm_reg_block等与寄存器相关的众多类都是派生自uvm_object,用于register model中。

uvm_phase:

派生自uvm_object,主要用于控制uvm_component的行为方式,使得uvm_component平滑地在各个不同的phase之间依次运转。

 3.常用的派生自uvm_component的类

在验证平台中经常遇到的派生自uvm_component的类有(前文介绍的验证平台组件都是):

uvm_driver :

driver派生自uvm_driver。driver的主要功能是向sequencer索要sequence_item (transaction),并且将sequence_item里的信息驱动到DUT端口上。     与uvm_component相比,uvm_driver多了如下几个成员变量:

uvm_sequence_item_pull_port #(REQ, RSP) seq_item_port;
uvm_sequence_item_pull_port #(REQ, RSP) seq_item_pord_if;
uvm_analysis_port #(RSP) rsp_port;
REQ req;
RSP rsp;

其中seq_item_port用于和sequencer之间信息通道的连接,有介绍过【学习记录丨UVM】1.10UVM的终极大作:sequence_uvm function new(string name=-CSDN博客

uvm_monitor :

monitor派生自uvm_monitor。monitor做的事情与driver相反,driver向DUT的pin上发送数据,而 monitor则是从DUT的pin上接收数据。

uvm_sequencer:

sequencer派生自uvm_sequencer。sequencer的功能是组织管理sequence,当driver要求数据时, 它就把sequence生成的sequence_item转发给driver。与uvm_component相比,uvm_sequencer做了很多扩展,额,咕咕咕🕊一定会在之后的文章中介绍。

uvm_scoreboard:

scoreboard派生自uvm_scoreboard。scoreboard的功能就是比较reference model和monitor分别发送来的数据,根据比较结果判断DUT是否正确工作。与uvm_monitor类似,uvm_scoreboard也几乎没有在uvm_component的基础上做扩展。所以,当定义自己的scoreboard时,可以直接从uvm_component派生。

reference model:

reference model都是直接派生自 uvm_component。reference model的作用就是模仿DUT,完成与DUT相同的功能。DUT是用Verilog写成的时序电路,而reference model则可以直接使用SystemVerilog高级语言的特性,同时还可以通过DPI等接口调用其他语言来完成与DUT相同的功能。

uvm_agent:

所有的agent要派生自uvm_agent。与前面几个比起来,uvm_agent的作用并不是那么明显。它只是把driver和 monitor封装在一起,根据参数值来决定是只实例化monitor还是要同时实例化driver和monitor。agent的使用主要是从可重用性的角 度来考虑的。如果在做验证平台时不考虑可重用性,那么agent其实是可有可无的。与uvm_component相比,uvm_agent的最大改动 在于引入了一个变量is_active:【学习记录丨UVM】1.6代理人agent_uvm agent-CSDN博客

uvm_env :

所有的env都派生自uvm_env。env把验证平台上的component都封装在一起。这样,当要运行不同的测试用例时,只需要在测试用例中实例化此env即可。

uvm_test:

所有的测试用例都要派生自 uvm_test或者其派生类,且都需要在其中实例化env。

class base_test extends uvm_test;//派生自uvm_test
  my_env env;
  `uvm_component_utils(base_test)//factory注册
 
  function new(string name="base_test",uvm_component parent);
    super.new(name,parent);
  endfunction
 
  extern virtual function void build_phase(uvm_phase phase);
  extern virtual function void report_phase(uvm_phase phase);
endclass
function void base_test::build_phase(uvm_phase phase);
  super.build_phase(phase);
  env = my_env::type_id::create("env",this);//实例化env
  uvm_config_db#(uvm_object_wrapper)::set(this,//设置sequencer的default_sequence
                                          "env.i_agt.sqr.main_phase",
                                          "default_sequence",
                                          my_sequence::type_id::get());
endfunction
function void base_test::report_phase(uvm_phase phase);
  uvm_report_server server;
  int err_num;
  super.report_phase(phase);
 
  server=get_report_server();
  err_num = server.get_severity_count(UVM_ERROR);
 
  if(err_num != 0)begin
    $display("TEST CASE FAILED");
  end
  else begin
    $display("TEST CASE PASSED");
  end
endfunction

 4.与uvm_object相关的宏

uvm_object_utils:把派生自uvm_object的类注册到factory中。

uvm_object_param_utils:把派生自uvm_object的参数化的类注册到factory中。参数化的类在代码可重用性中经常用到。所谓参数化的类,是指类似于如下的类:

class A#(int WIDTH=32) extends uvm_object;

uvm_object_utils_begin:  当需要使用field_automation机制时,需要使用此宏。【学习记录丨UVM】1.9field_automation机制_uvm field automation-CSDN博客

uvm_object_param_utils_begin:与 uvm_object_utils_begin一样,只是它用于参数化的类使用field_automation机制时。

uvm_object_utils_end: 它总是和uvm_object_*_begin成对出现,作为factory注册的结束标志。

 5.与uvm_component相关的宏  

uvm_component_utils:类同不再介绍;

uvm_component_param_utils:类同不再介绍;

uvm_component_utils_begin:使用field_automation机制时,需要使用此宏。field_automation机制对component的最大意义在于可以自动使用config_db来获得某些变量的值。后边的文章会举例。

uvm_component_param_utils_begin;

uvm_component_utils_end;

6.uvm_component的限制

限制一:不能使用uvm_object的clone函数

在uvm_object中有clone函数。它用于分配一块内存空间,并把另一个实例复制到这块新的内存空间中。clone函数的使用方法如下;

class A extends uvm_object;
  ...
endclass

class my_env extends uvm_env;
  virtual function void build_phase(uvm_phase phase);
    A a1;
    A a2;
    a1 = new("a1");
    a1.data = 8'h9;
    $cast(a2,a1.clone());//为a2分配一块内存空间,并复制a1给它
  endfunction
endclass

clone函数可以拆分为两步:1.分配内存空间,即 new 函数;2. 复制,即 copy 函数。没错,copy也是uvm_object中的一个函数,在目标实例已用new分配过内存空间后,才能使用。显然clone = new + copy.

uvm_component中可以使用copy函数,但是无法使用clone函数,因为新clone出来的类其parent参数没经过new函数指定。 

限制二:parent相同的component,实例化时不能使用相同的名字

错误示例:

注意这是错误示例,这样写是绝对不行的!

class A extends uvm_component;
  ...
endclass

class my_env extends uvm_env;
  virtual function void build_phase(uvm_phase phase);
    A a1;
    A a2;
    a1 = new("a1",this);
    a2 = new("a1",this);//这样写,是会出错的哦~!
  endfunction
endclass

 ok!祝大家今天也愉快自洽的一天!


http://www.kler.cn/a/390354.html

相关文章:

  • Springboot 日志处理(非常详细)
  • HarmonyOS SDK下的实践与探索
  • 【前端学习指南】Vue computed 计算属性 watch 监听器
  • LeetCode【0031】下一个排列
  • 开源vs闭源:你更看好哪一方?
  • 中文书籍对《人月神话》的引用(161-210本):微软的秘密
  • 人到一定年纪,要学会远离多巴胺
  • 群控系统服务端开发模式-应用开发-前端框架
  • 必应 Bing 国内广告开户及代运营服务的优势有哪些?
  • UE5.3 CineCameraRigRail组件实测
  • 实现3D热力图
  • VPN相关学习笔记
  • 企业级工位管理:Spring Boot实践
  • wget命令之Tomcat(三)
  • JVM垃圾回收详解二(重点)
  • 【数据结构】线性表——链表
  • 区块链技术在电子政务中的应用
  • 5 分钟内最多允许用户尝试登录3次,如果错误次数超过限制,需要对该用户进行锁定。如何实现?
  • 《Django 5 By Example》阅读笔记:p1-p16
  • Spark 的容错机制:保障数据处理的稳定性与高效性
  • 「IDE」集成开发环境专栏目录大纲
  • 【c++篇】:掌握list--实用的基本使用方法与模拟实现思路
  • 练习LabVIEW第四十二题
  • [CKS] 关闭API凭据自动挂载
  • 深入浅出rust内存对齐
  • 【机器学习】机器学习中用到的高等数学知识-1.线性代数 (Linear Algebra)