当前位置:首页 > 芯闻号 > IC技术圈
[导读]有些朋友在使用UVM构建测试平台时调用`uvm_info时发现波形中信号变化的时间和`uvm_info显示的时间不一致(本文以`uvm_info为例说明),并且使用UVM-1.1和UVM-1.2居然`uvm_info显示的时间还不一样,这到底是怎么回事儿呢?下面本文将通过追究下到底是什么原因导致的,并且给出自定义消息格式的一些方法。

作者简介:

硅芯思见,主理人nano,主要从事芯片验证工作,平时会在公众号分享一些在芯片设计、验证的学习过程中遇到的各种问题,以及一些个人的想法。


前面讨论过$time和$realtime显示时间时,log信息中显示的时间会跟仿真波形不一致,有一些差异(详见《硅心思见:【157】SystemVerilog中的time的一些事儿》)。有些朋友在使用UVM构建测试平台时调用`uvm_info时发现波形中信号变化的时间和`uvm_info显示的时间不一致(本文以`uvm_info为例说明),并且使用UVM-1.1和UVM-1.2居然`uvm_info显示的时间还不一样,这到底是怎么回事儿呢?下面本文将通过追究下到底是什么原因导致的,并且给出自定义消息格式的一些方法。

【示例】

1.png

【仿真结果】 使用UVM-1.1进行仿真

2.png

【仿真结果】 使用UVM-1.2进行仿真

3.png

通过上面两个示例结果我们发现UVM-1.2和UVM-1.1的结果相差还是比较大的,并且UVM-1.2仿真波形结果与log信息差别还是比较大的,这是为什么呢?下面一块挖掘下这到底是为啥?

【使用UVM-1.1进行仿真现象分析】

首先我们知道`uvm_info实际上都来自于下图中这个宏,其中实现打印的实际上是uvm_report_info这个function,所以需要关心下uvm_report_info怎么实现的。

4.png

uvm_report_info这个function定义在uvm_globals.svh中,如下图。

5.png

在这个方法中,可以看到uvm_report_info的主要实现是通过uvm_root这个类中的uvm_report_info这个方法实现的,下面我们继续查找uvm_root这个类,在uvm_root中并没有找到这个方法的实现,所以继续查找uvm_root的父类uvm_component,很遗憾,uvm_component里头也么有uvm_report_info这个方法的实现,那么这个哥们去哪里呢?uvm_component还有一个父类是uvm_report_object,在uvm_report_object.svh中定义的uvm_report_object类中找到了uvm_report_object这个方法的定义,如下图。

6.png

从上面代码中可以看到uvm_report_info中通过m_rh调用了report()这个方法,这个方法来自于句柄m_rh的类型,在uvm_report_object类中m_rh的类型从上述代码中可以看到是uvm_report_handler,所以report()这个方法至少应该来自于uvm_report_handler中,下面是在uvm_report_handler这个类找到的report方法的定义,如下图。

7.png

在report()方法中,又通过srvr这个句柄调用了report方法,此时的这个report方法至少应该在srvr这个句柄的类型uvm_report_server这个类中,uvm_report_sever这个类中果然有report这个方法的定义,如下图。

8.png

在report这个方法中实际上实现输出消息的是通过process_report这个方法,但是在这个方法中并没有关于时间显示的信息,关于时间信息实际上是来自于compose_message这个方法,如上图。在compose_message这个方法中实现了当前仿真时间的获取(如图中红色阴影),可以看到这个时间是通过$realtime获取的,而$realtime获取的时间是一个实数,但是在显示的时间受$timeformat设置的默认值的影响,即此时显示的时间单位是该语句执行时所在域的时间精度,所以此时我们看到\`uvm_info调用时在log中显示的时间是一个五位数,与波形上期望的小数有一些差异,如果期望对这个数据显示格式进行约束,可以在顶层调用\`uvm_info宏之前通过$timeformat进行设置。

【使用UVM-1.2进行仿真现象分析】

在UVM-1.2中关于`uvm_info的分析在uvm_message_defines.svh、uvm_globals.svh、uvm_root.svh、uvm_component.svh和UVM-1.1基本是一样的,没有太大变化,但是在uvm_report_object.svh中有一些差异。在uvm_report_object中,uvm_report_info方法的定义如下。

9.png

在uvm_report_object中,uvm_report_info方法调用了uvm_report这个方法,uvm_report这个方法中实现信息处理的是uvm_process_report_message这个方法,此方法中实现信息处理的实际上是通过其中的m_rh.process_report_message实现的,所以m_rh调用的这个方法应该在m_rh这个句柄的类型定义中,而m_rh的类型为uvm_report_handler,所以关于消息打印的追踪进入到uvm_report_handler中,在uvm_report_handler中process_report_message的定义如下图所示。

10.png

在uvm_report_handler中process_report_message的定义中,实际上对于信息处理的来自于srver.process_report_message,而srver这个句柄的类型为uvm_report_server,所以process_report_message至少来自于uvm_report_server,打开uvm_report_server.svh着实被惊喜到了,因为在uvm_report_server中process_report_message是个纯虚方法,其定义如下。

11.png

那么process_report_message要实现功能,必须在uvm_report_server的一个子类中实现,在UVM-1.2中这个子类就是uvm_default_report_server,在uvm_default_report_server中process_report_message的定义如下。

12.png

这个方法中,处理信息的实际上是compose_report_message,这个方法虽然是通过svr(uvm_report_server)调用的,所以此时的compose_report_message()其实也来自于uvm_report_server的子类中,其定义如下。

13.png

在compose_report_message这个方法中实现了当前仿真时间的获取(如图中红色阴影),可以看到这个时间是通过$time(注意:这里与UVM-1.1不同)获取的,而$time获取的时间是一个整型数据,并且此时显示的时间也受$timeformat设置的默认值的影响,即此时显示的时间单位是该语句执行时所在域的时间精度,所以此时我们看到\`uvm_info调用时在log中显示的时间是一个五位数并且只保留了对应时间单位的整数部分数字,显示的时间就与波形上期望的小数存在了较大的差异,此时虽然可以通过$timeformat进行设置,但是也不会获得时间精度对应的具体小数部分的数字了。

那么,既然库里提供的默认显示时间与用户期望的不一致,有没有办法可以解决呢?其实只要注意是上述最终实现消息字符串的实际上都是虚方法,那么就可以通过派生子类重写该方法,然后将子类句柄指向的对象传递给实现消息机制的父类句柄,从而就可以实现对于消息机制的重定义了。下面我们通过一个示例来说明如何自定义消息格式,同样的分别针对UVM-1.1和UVM-1.2进行示例说明如何定制消息格式。

【UVM-1.1消息格式定制】

第一步:定义usr_report_server(类名根据需要自定义)类,因为UVM中消息最终实现都是在uvm_report_server中,所以usr_report_server也拓展自uvm_report_server。

14.png

第二步:在用户拓展自uvm_test的测试类的build_phase中,声明一个第一步定义的usr_report_server类的句柄usr_svr,并且在build_phase中将其通过new函数创建对象;

第三步:在build_phase中将指向创建好对象的句柄usr_svr传递给uvm_report_server::set_server(usr_svr),代码如下例。

15.png

第四步:运行仿真,下面是仿真实例结果。

16.png

【UVM-1.2消息格式定制】

第一步:定义usr_report_server(类名根据需要自定义)类,因为UVM中消息最终实现都是在uvm_default_report_server中,所以usr_report_server也拓展自uvm_default_report_server。

17.png

第二步:在用户拓展自uvm_test的测试类的build_phase中,声明一个第一步定义的usr_report_server类的句柄usr_svr,并且在build_phase中将其通过new函数创建对象;

第三步:在build_phase中将指向创建好对象的句柄usr_svr传递给uvm_report_server::set_server(usr_svr),代码同【UVM-1.1消息格式定制】第三步的代码截图;

第四步:运行仿真,下面是仿真实例结果。

18.png

通过上述方式,用户就可以自己定义显示消息的方法,并且可以根据需要控制显示时间等信息。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭