《UVM实战》笔记part2(第三章)

目录

三、UVM基础

3.1 uvm_component派生自uvm_object

常用的派生自uvm_object的类:

uvm_component的限制

3.2 UVM的树形结构

m_children与parent:

UVM树的根

层次结构相关函数

3.3 field automation机制的常用函数

3.4 UVM中打印信息的控制

冗余度阈值

重载打印信息的严重性

设置计数的目标

UVM的断点功能

将输出信息导入文件中

控制打印信息的行为

3.5 config_db机制

set与get函数的参数

跨层次的多重设置

同一层次的多重设置


三、UVM基础

3.1 uvm_component派生自uvm_object

事实说明了uvm_component拥有uvm_object的特性,同时又有自己的一些特质。但是uvm_component的一些特性,uvm_object则不一定具有。这是面向对象编程中经常用到的一条规律。

uvm_component有两大特性是uvm_object所没有的:

一是通过在new的时候指定parent参数来形成一种树形的组织结构,

二是有phase的自动执行特点。

从uvm_object派生出了两个分支,所有的UVM树的结点都是由uvm_component组成的,只有基于uvm_component派生的类才可能成为UVM树的结点;最左边分支的类或者直接派生自uvm_object的类,是不可能以结点的形式出现在UVM树上的。

 

uvm_object:分子,可以搭建成许多的东西

uvm_component:高级生命

sequence_item:则是由其搭建成的血液,它流通在各个高级生命(uvm_component)之间sequence:则是众多sequence_item的组合;

config:是由其搭建成的用于规范高级生命(uvm_component)行为方式的准则。

常用的派生自uvm_object的类:

uvm_sequence、config、uvm_sequence_item、寄存器相关的众多的类

注意config与config_db的区别。在上一章中已经见识了使用config_db进行参数配置,这里的config其实指的是把所有的参数放在一个object中,如10.5节所示。然后通过config_db的方式设置给所有需要这些参数的component。

uvm_component的限制

1、uvm_component无法使用clone函数,但是可以使用copy函数.

2、位于同一个父结点下的不同的component,在实例化时不能使用相同的名字。

 

3.2 UVM的树形结构

m_children与parent:

当b_inst实例化的时候,指定一个parent的变量,同时在每一个component的内部维护一个数组m_children,当b_inst实例化时,就把b_inst的指针加入到A的m_children数组中。只有这样才能让A知道b_inst是自己的孩子,同时也才能让b_inst知道A是自己的父母。当b_inst有了自己的孩子时,即在b_inst的m_children中加入孩子的指针。

 

UVM树的根

uvm_top是一个全局变量,它是uvm_root的一个实例(而且也是唯一的一个实例 [1],它的实现方式非常巧妙),而uvm_root派生自uvm_component,所以uvm_top本质上是一个uvm_component,它是树的根。

每个component都是一个节点。

如果一个component在实例化时,其parent被设置为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top。

如果一个component在实例化时,其parent被设置为null,那么这个component的parent将会被系统设置为系统中唯一的uvm_root的实例uvm_top

 

层次结构相关函数

与get_parent不同的是,get_child需要一个string类型的参数name,表示此child实例在实例化时指定的名字。因为一个component

只有一个parent,所以get_parent不需要指定参数;而可能有多个child,所以必须指定name参数

3.3 field automation机制的常用函数

把某个A实例复制到B实例中,那么应该使用B.copy(A)。

要比较A与B是否一样,可以使用A.compare(B),也可以使用B.compare(A)。当两者一致时,返回1;

pack_bytes函数用于将所有的字段打包成byte流

pack函数用于将所有的字段打包成bit流

unpack函数用于将一个bit流逐一恢复到某个类的实例中

3.4 UVM中打印信息的控制

冗余度阈值

UVM会比较要显示信息的冗余度级别与默认的冗余度阈值,如果小于等于阈值,就会显示,否则不会显示。

默认的冗余度阈值是UVM_MEDIUM,所有低于等于UVM_MEDIUM(如UVM_LOW)的信息都会被打印出来。

重载打印信息的严重性

.set_report_severity_override(UVM_WARNING, UVM_ERROR);

WARNING变成----ERROR(类比赋值)

 

UVM_ERROR到达一定数量结束仿真

set_report_max_quit_count()函数

 

get_max_quit_count,可以用于查询当前的退出阈值

设置计数的目标

set_report_severity_action函数。

set_report_id_action所有信息加入到计数中,无论是UVM_INFO,还是UVM_WARNING或者是UVM_ERROR、UVM_FATAL

env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_COUNT);

hier代表递归,上述代码把ID为my_drv的所有信息加入到计数中

UVM的断点功能

当env.i_agt.drv中出现UVM_WARNING时,立即停止仿真,进入交互模式,方便调试。

这里用到了set_report_severity_action函数:

env.i_agt.drv.set_report_severity_action(UVM_WARNING, UVM_DISPLAY| UVM_STOP);

env.i_agt.set_report_id_action_hier("my_drv", UVM_DISPLAY| UVM_COUNT);

只要将其中的UVM_COUNT替换为UVM_STOP,就可以实现相应的断点功能

将输出信息导入文件中

按照重要性env.i_agt.drv.set_report_severity_file(UVM_INFO, info_log);

按照ID地址env.i_agt.drv.set_report_id_file("my_driver", driver_log);

两者结合env.i_agt.drv.set_report_severity_id_file(UVM_INFO, "my_drv", drv_log);

 

控制打印信息的行为

typedef enum
{UVM_NO_ACTION = 'b000000, //不做任何操作
UVM_DISPLAY = 'b000001, //输出到标准输出上
UVM_LOG = 'b000010, //输出到日志文件中
UVM_COUNT = 'b000100, //作为计数目标
UVM_EXIT = 'b001000, //直接退出仿真
UVM_CALL_HOOK = 'b010000,   //调用一个回调函数
UVM_STOP = 'b100000  // 停止仿真,进入命令行交互模式(断点)
} uvm_action_type;

 

3.5 config_db机制

config_db机制用于在UVM验证平台间传递参数。它们通常都是成对出现的。

set函数是寄信,而get函数是收信。

set与get函数的参数

uvm_config_db#(int)::set(this, 
                     "env.i_agt.drv", 
                     "pre_num", 
                      100);

第一、二个参数联合起来组成目标路径,与此路径符合的目标才能收信。

第一个参数必须是一个uvm_component实例的指针,

第二个参数是相对此实例的路径。

第三个参数表示一个记号,用以说明这个值是传给目标中的哪个成员的,

第四个参数是要设置的值。

跨层次的多重设置

1、先比较层级:

UVM规定层次越高,那么它的优先级越高。越靠近根结点uvm_top,则认为其层次越高。uvm_test_top的层次是高于env的,所以uvm_test_top中的set函数的优先级高。

2、再比较时间:

UVM的build_phase是自上而下执行的,my_case0的build_phase先于my_env的

build_phase执行。所以my_env对pre_num的设置在后,其设置成为最终的设置

注意:在调用set函数时其第一个参数应该尽量使用this。在无法得到this指针的情况下(如在top_tb中),使用null或者uvm_root::get()。

同一层次的多重设置

当跨层次来看待问题时,是高层次的set设置优先;当处于同一层次时,是时间优先。

写代码的一个原则是同样的语句只在一个地方出现,尽量避免在多个地方出现。解决这个问题的办法就是在base_test的build_phase(一种function)中使用config_db::set进行设置(设置好数值),这样,当由base_test派生而来的case1~case99在执行super.build_phase(phase)时,都会进行相同的设置。

——————————————————————————————————————————————————
爱吃鱼的嗷大喵(知乎同号),走过很多弯路的材料专业在读硕士,
正在转行中,
不定期发布心得体会,
有兴趣可以关注我。

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我在哪我是谁啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值