UVM1.2究竟在UVM1.1上做了哪些升级

news2024/9/9 0:30:55

想必大家平时也没有很注意UVM1.1版本和UVM1.2版本的不同之处,只有在用一些以前UVM1.1能支持的功能,到了UVM1.2却出现编译报错,找不到对应的变量或者函数或者类的时候,才意识到这两个版本的差异。笔者也是遇到了1个打印问题,去研究下UVM1.2的Release Notes,并整理了这一篇文章,说明了比较重要的修改内容和影响,当然还有一些小修小改在这里就不提了,希望能帮助到大家。

1. Configuration的修改

UVM1.1中的set_config_[int, string, object]()和get_config_[int, string, object]()方法在UVM1.2中已弃用。根据UVM编码指导,用户应该使用uvm_config_db::[set,get]() API来替代。UVM1.2使用typedef也预先定义了一些便捷类型给大家使用,比如:

typedef uvm_config_db#(uvm_bitstream_t) uvm_config_int;
typedef uvm_config_db#(string) uvm_config_string;
typedef uvm_config_db#(uvm_object) uvm_config_object;
typedef uvm_config_db#(uvm_object_wrapper) uvm_config_wrapper;

但是uvm_config_db里的uvm_bitstream_t类型默认长度是4096bits,会占用0.5KB的内存,对资源高效利用非常不友好,如果有整型类型的数据需要set()或get()的话,最好使用所配置值的实际类型。

另外需要注意的是UVM1.1的set_config_object和get_config_object可以通过参数指定是否自动clone,在切换到uvm_config_object后,已经没有提供这个参数了

2. 定义全新的uvm_coreservice_t类,将各全局组件打包起来

UVM1.2新定义了一个uvm_coreservice_t类,它把UVM1.1中分散的uvm_factory和uvm_report_server包起来了,也打包了新增的uvm_tr_database和uvm_visitor。这样用户以后就不需要直接引用这些单独的组件,因为在uvm_coreservice_t类的singleton中提供了API来获取到这些组件。以获取uvm_factory的object为例,UVM1.2里的标准流程为:

uvm_coreservice_t  cs = uvm_coreservice_t::get();
uvm_factory f = cs.get_factory();

不过由于uvm_factory类是singleton类型的,直接使用uvm_factory f=uvm_factory::get()其实也蛮方便的。同样的,对于uvm_report_server的object的获取,也可以直接使用:

uvm_report_server rs=uvm_report_server:: get_server();

另一点就是UVM1.2很神奇,user可以扩展uvm_coreservice_t类型,然后通过UVM_CORESERVICE_TYPE把UVM自带的uvm_coreservice_t给替换掉,不过我觉得99%人不会用这个吧。

3. 将原来的类拆成抽象类和”default”子类

在UVM1.1中,uvm_factory和uvm_report_server基类可以被用户直接定制。而在UVM1.2中,这些基类都是抽象类,原先基类的功能被转移到从抽象类扩展出来的”default”子类中。这些”default”子类定义如下:

class uvm_default_factory extends uvm_factory;
  ...
endclass
class uvm_default_report_server extends uvm_report_server;
  ...
endclass

因此,如果有用户在UVM1.1中是在uvm_factory或uvm_report_server基础上扩展出子类,那么在UVM1.2中需要更新到从对应”default”类上扩展。比如:

UVM1.1的写法:class user_factory extends uvm_factory;
UVM1.2的写法:class user_factory extends uvm_default_factory;

4. 舍弃uvm_pkg::factory来获取uvm_factory对象

在UVM1.1中,可以直接使用uvm_pkg::factory来引用singleton的uvm_factory,也就是说uvm_pkg::factory和uvm_factory::get()两者是等价的。

但在UVM1.2中,删掉了uvm_pkg::factory方式,必须通过uvm_factory::get()方式。

5. Factory override功能的增强

在使用factory override去覆写uvm_factory返回的类型。典型的流程是创建1个从基本test扩展的test,并在扩展test中指定覆盖对象。因此,当创建object或component时,用户肯定要知道返回的具体类型是什么。Factory按类型override的语法如下:

<original_type>::type_id::set_type_override(<substitute_type>::get_type(), replace);

在UVM1.1中,如果<substitute_type>和<original_type>一样,那么什么都不会发生,之前的任何override都继续有效。但在UVM1.2中,如果<substitute_type>和<original_type>一样,它会移除掉对<original_type>的所有的覆写,也相当于是撤销factory override功能。不过好的TB永远不应该使用这个特性。例子如下:

// Perform an override
set_type_override_by_type(old_type::get_type(), new_type::get_type());
// Undo the override (撤销override)
set_type_override_by_type(old_type::get_type(), old_type::get_type());

6. message宏打印的增强

UVM1.2在message处理上做了一些改动,把之前`uvm_xxx_context的宏的里CNTXT名字替换成RO名字,这个RO传递的是uvm_report_object类型或它子类的object。对于标准的message宏(uvm_info等)倒没有做任何改动。

另外,UVM1.2提供了一系列新的begin-end宏来创建具有相同severity的message对象。

`uvm_info_begin(ID, MSG, VERBOSITY, RM = __uvm_msg)
`uvm_info_end
`uvm_warning_begin(ID, MSG, RM = __uvm_msg)
`uvm_warning_end
`uvm_error_begin(ID, MSG, RM = __uvm_msg)
`uvm_error_end
`uvm_fatal_begin(ID, MSG, RM = __uvm_msg)
`uvm_fatal_end
`uvm_info_context_begin(ID, MSG, VERBOSITY, RO, RM = __uvm_msg)
`uvm_info_context_end
`uvm_warning_context_begin(ID, MSG, RO, RM = __uvm_msg)
`uvm_warning_context_end
`uvm_error_context_begin(ID, MSG, RO, RM = __uvm_msg)
`uvm_error_context_end
`uvm_fatal_context_begin(ID, MSG, RO, RM = __uvm_msg)
`uvm_fatal_context_end

这些message宏也有ID和VERBOSITY,因此set_report_action和其它message函数仍然可以对它们进行处理。用这些message宏的一个好处就是现在可以通过是使用额外的宏向message对象里添加字段,这些额外的宏有:

`uvm_message_add_tag(NAME, VALUE, ACTION=(UVM_LOG|UVM_RM_RECORD))
`uvm_message_add_int(VAR, RADIX, LABEL = "", ACTION=(UVM_LOG|UVM_RM_RECORD))
`uvm_message_add_string(VAR, LABEL = "", ACTION=(UVM_LOG|UVM_RM_RECORD))
`uvm_message_add_object(VAR, LABEL = "", ACTION=(UVM_LOG|UVM_RM_RECORD))

上述两者宏结合起来的使用例子如下:

`uvm_info_begin("MY_ID", "This is my message...", UVM_LOW)
     `uvm_message_add_tag("my_color", "red")
     `uvm_message_add_int(my_int, UVM_DEC)
     `uvm_message_add_string(my_string)
     `uvm_message_add_object(my_obj)
`uvm_info_end

主要对message对象的每次添加字段都允许指定自己的操作(ACTION=xxx)。TB很少需要对message的各个部分指定不同的操作,但是这个功能也算是给了一种使用新方式了。

7. objection管理

UVM1.2向uvm_objection增加了set_propagate_mode()函数,以允许对objection的raise和drop绕过UVM hierarchy的所有中间层,并立即向上传播到uvm_top。UVM编码指南也是建议objection只应该在testcase level中raise和drop,testcase和uvm_top之间没有中间层,因此好的TB永远也不需要使用set_propagate_mode()这个特性。

如果没有使用set_propagate_mode()把m_prop_mode设置为1,那么1个组件raise objection会传播给parent,parent再继续向上传播,直至uvm_test_top。虽然这样的传播可能是有用的,但如果它们没有被TB使用,那么它们只是一个不必要的性能损失。因此如果TB不打算使用这个功能,那么可以通过将传播模式m_prop_mode设置为0来提高性能,这样1个组件raise objection的话,只会传播给uvm_test_top,UVM hierarchy中间节点的组件完全没感知到。

另外,UVM1.2舍弃了uvm_sequence_base::starting_phase的方式,也就是不能直接在sequence里使用starting_phase,然后调用starting_phase.raise_objection(this),因为直接使用starting_phase是不受writes-after-reads保护的,如果phase的objection在raise和drop之间被改变了值,这将导致奇怪的行为(包括fatals或hang)。对应的,它是在uvm_sequence_base类中增加了set_automatic_phase_objection()函数来完成之前starting_phase的功能的,而且更简便。用户只需要调用set_automatic_phase_objection(1)函数,那么sequence在启动的时候会自动raise和drop objection。举个例子:

// 如果在my_sequence的new函数了调用了set_automatic_phase_objection(1)
function my_sequence::new(string name="unnamed");
    super.new(name);
    set_automatic_phase_objection(1);
endfunction : new
// 那么从时间轴角度来看,objection的自动raise和drop节点像下面一样:
start() is executed
    --! Objection is raised !--
    pre_start() is executed
    pre_body() is optionally executed
    body() is executed
    post_body() is optionally executed
    post_start() is executed
    --! Objection is dropped !--
start() unblocks

不过使用set_automatic_phase_objection(1)函数去自动控制objection违反了UVM编码指南,其实还是不建议使用的。大家还是直接在testcase level去控制objection最好。

8. 枚举名的改动

UVM1.2将uvm_sequencer_arb_mode枚举变量的元素名改了。原先是:

SEQ_ARB_FIFO (Default)
SEQ_ARB_WEIGHTED
SEQ_ARB_RANDOM
SEQ_ARB_STRICT_FIFO
SEQ_ARB_STRICT_RANDOM
SEQ_ARB_USE

现在是:(其实就是在元素名前加上UVM_)

UVM_SEQ_ARB_FIFO (Default)
UVM_SEQ_ARB_WEIGHTED
UVM_SEQ_ARB_RANDOM
UVM_SEQ_ARB_STRICT_FIFO
UVM_SEQ_ARB_STRICT_RANDOM
UVM_SEQ_ARB_USER

9. 新增record的宏

Transaction记录是通过在UVM中使用宏来进行的,以允许特定工具或EDA供应商将跟踪的信息写入数据库。在UVM1.1中,宏是:

`uvm_record_attribute // never call directly
`uvm_record_field

与message的改动类似,除了以上的宏,UVM1.2新增了一些宏来记录特定类型,用户可以指定要记录的名称和值。有以下这些新增宏:

`uvm_record_int
`uvm_record_string
`uvm_record_time
`uvm_record_real

10. uvm_event变为参数化类

UVM1.2的uvm_event是一个参数化类,且uvm_event类被拆成两个类,1个是抽象uvm_event_base类,然后uvm_event#(T)从这个抽象类扩展出来。

其实这个改动是很小的,UVM1.1的uvm_event相当于是UVM1.2的uvm_event#(T= uvm_object)。

11. 支持command line用string配置枚举值

UVM1.2支持在command line上按string名称设置枚举值。这个功能是通过uvm_enum_wrapper#(T)类的from_name()函数实现的,在执行自动配置是由`uvm_field_enum宏使用,因此可以用set using uvm_config_db#(string)或uvm_cmdline_processor::+uvm_set_config_string去设置枚举变量的值。

UVM1.2也支持在command line上设置default sequence。命令格式为:

<sim command> +uvm_set_default_sequence=path.to.sequencer,main_phase,seq_type

12. 枚举类型名字变换

枚举类型uvm_severity_type名字改成uvm_severity。

13. phase增加callback接口

增加了phase状态切换的callbacks,增加uvm_phase_cb和uvm_phase_cb_pool来提供额外的phase APIs接口。

14. uvm_object子类的强制构造函数

UVM1.2需要从uvm_object扩展的任何类都指定以下形式的构造函数:

class my_obj extends uvm_object;
    ...
    `uvm_object_utils(my_obj)
    function new(string name = "my_obj")
      super.new(name);
      ...
    endfunction
    ...
endclass

也就是说必须在构造函数里传递string名字,否则编译会报错。然而在UVM1.1中,这种类型构造函数并不是UVM强制的,它们是可选的。如果没有指定构造函数,则由SystemVerilog提供默认的构造函数。如果用户想用UVM1.1的这种方案,那么需要定义UVM_OBJECT_DO_NOT_NEED_CONSTRUCTOR宏,但是不建议,因为UVM1.3版本将彻底使用强制的方案。

针对UVM1.2的这个强制要求,UVM也提供了add_uvm_object_new.pl脚本去帮助处理,有需要的可以用下。

15. 引入uvm_integral_t新整型类型

为了提升memory性能,UVM1.2引进了uvm_integral_t新类型,它的定义如下:

typedef logic signed [63:0] uvm_integral_t;

相比uvm_bitstream_t的4096-bit位宽,uvm_integral_t只用了64-bit,大大减少memory的开销。 对这种新类型的支持也添加到uvm_printer、uvm_packer、uvm_recorder和uvm_comparer,以及由“uvm_field_*”宏提供的自动配置中。

为了提供一致的API,uvm_printer::print_int()函数已经被不推荐使用了,取而代之的是uvm_printer::print_field_int(),它最多可以打印64-bit的整型数据。

16. Message系统的管理采用基于对象的方式

UVM1.2对Message系统的管理进行了修改,将系统彻底改造为使用基于对象的方法传递message,而不是多次传递多个字段,这同时扩展了message传递的API功能。uvm_report_server::process_report已经被uvm_report_server::execute_report_message替代了。uvm_report_server::compose_message已经被uvm_report_server::compose_report_message替代了。在对uvm_recorder的支持上,也增加了uvm_tr_stream和uvm_tr_database两个类。

对message系统的更改对大部分用户其实还好,只是UVM1.2用了另一种方式实现了之前UVM1.1的功能。

顺便说一下,平时跑testcase结束的时候,UVM会自动打印出” UVM Report Summary”,也就有几个UVM_INFO/ UVM_WARNING/ UVM_ERROR/ UVM_FATAL之类的,这个在UVM1.1是强制的,但在UVM1.2下,如果UVM_VERBOSITY设置为UVM_NONE,那testcase结束时将不会打印出” UVM Report Summary”,这一点大家需要注意的。特别在跑regression的时候,我们经常会将UVM_VERBOSITY设置为UVM_NONE。

结语

UVM1.2虽然把UVM1.1的一些旧功能舍弃了,但提供了UVM_NO_DEPRECATED宏,如果用户没有定义这个宏的话(默认是没有定义这个宏),那么UVM1.1被丢弃的功能仍然可以在UVM1.2中使用。但建议用户如果使用UVM1.2的话,要定义上UVM_NO_DEPRECATED宏。约束自己早点把代码迁移到UVM1.2上,而不是一直在UVM1.1上。UVM之所以提供了UVM_NO_DEPRECATED宏,就是想暂时给用户留点迁移代码的时间,在UVM1.3版本上,UVM1.1的旧功能将彻底丢弃了。

从UVM1.1版本过渡到UVM1.2版本引起的许多向后兼容性问题可以通过在用户代码中进行相当简单的搜索和替换来解决。另外,UVM官方提供了uvm11-to-uvm12.pl的脚本来帮助过渡。下面的命令将更新位于当前工作目录和任何子目录中的所有SystemVerilog源文件:

uvm11-to-uvm12.pl --write

有关脚本的使用详情,可以加—help命令行选项查看。

不过这个脚本可能无法自动识别所有向后不兼容的情况,用户可能需要手动修复一些情况。这些问题中的大多数都会导致编译报错,所以它们很容易被识别出来。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/674795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用Django的视图类TemplateView将模板、视图与模板变量方便快速的整合在一起

TemplateView是Django提供的通用视图类之一&#xff0c;它允许您在不编写任何Python代码的情况下将模板与视图关联起来。下面是关于TemplateView类的一些介绍&#xff1a; 渲染模板&#xff1a;TemplateView负责渲染指定的模板并返回生成的HTML响应。您只需提供模板名称或路径即…

华为OD机试真题B卷 Java 实现【删除字符串中出现次数最少的字符】,附详细解题思路

一、题目描述 删除字符串中出现次数最少的字符&#xff0c;如果多个字符出现次数一样则都删除。 二、输入描述 一个字符串。 三、输出描述 删除字符串中出现次数最少的字符&#xff0c;如果多个字符出现次数一样则都删除&#xff0c;如果都被删除 则换为empty。 四、解题…

【安装lnmp实操】

文章目录 一、安装Nginx服务1.安装依赖包2、创建运行用户3、编译安装4、优化路径5、添加 Nginx 系统服务 二、【安装 MySQL 服务】1、安装Mysql环境依赖包2、创建运行用户3、编译安装4、修改mysql 配置文件5、更改mysql安装目录和配置文件的属主属组6、设置路径环境变量7、初始…

MySQL数据库高级SQL语句(图文详解!)

一、MySQL高级语句 1.SELECT 2.DISTINST 3.WHERE 4.AND|OR ​5.IN 6.BETWEEN 7.通配符 8.LIKE 9.ORDER BY 10.函数 &#xff08;1&#xff09;数学函数 &#xff08;2&#xff09;聚合函数 &#xff08;3&#xff09;字符串函数 11.GROUP BY 12.HAVING 13.别名 14.子查询 …

团体程序设计天梯赛-练习集L1篇③

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;Hello大家好呀&#xff0c;我是陈童学&#xff0c;一个与你一样正在慢慢前行的普通人。 &#x1f3c0;个人主页&#xff1a;陈童学哦CSDN &#x1f4a1;所属专栏&#xff1a;PTA &#x1f381;希望各…

插件 - 插件机制触手可及

文章目录 Pre方案流程图优点缺点Code小结Pre 插件 - 一份配置,离插件机制只有一步之遥 中是不是有依赖, 我不想依赖 ,肿么办? 方案 应用A定义服务接口,约定插件实现的功能规范。应用B,C,D等各自实现该接口,并打包成jar包,放置在应用A约定的读取目录下。应用A在运行时,读取…

MATLAB 动画的制作与保存

matlab有三种方法来创建动画&#xff1a; ①以质点运动轨迹的方式来创建动画 theta0:0.001:2*pi; %定义圆的半径 r10; %生成圆上各点的横纵坐标 xr*cos(theta); yr*sin(theta); comet(x,y); 生成的动画效果如下 &#xff08;其中的某一步&#xff09; 最终结果如下 comet(x,…

怎么将存入此电脑中的图片放入电脑D盘

先找到图片的目录&#xff0c; 目录为&#xff1a;xxx 然后 现在图片目录就移动到D盘了

算法设计 - KMP算法

字符串模式匹配问题 假设有两个字符串S&#xff0c;T&#xff0c;其中S是主串&#xff08;正文串&#xff09;&#xff0c;T为子串&#xff08;模式串&#xff09;&#xff0c; 我们需要在S中查找与T相匹配的子串&#xff0c;如果成功找到&#xff0c;则返回匹配的子串第一个…

华为OD机试真题 JavaScript 实现【太阳能板最大面积】【2022Q4 100分】,附详细解题思路

一、题目描述 给航天器一侧加装长方形或正方形的太阳能板&#xff08;图中的红色斜线区域&#xff09;&#xff0c;需要先安装两个支柱&#xff08;图中的黑色竖条&#xff09;&#xff0c;再在支柱的中间部分固定太阳能板。 但航天器不同位置的支柱长度不同&#xff0c;太阳…

logback日志框架基本知识

本文来说下logback日志框架基本知识 文章目录 概述logback简介SpringBoot对logback的支持SpringBoot的集成 概述 Spring Boot已经将logback做为默认集成的日志框架&#xff0c;全面了解学习是必然了。曾经log4j是流行的日志框架&#xff0c;现在已被它的继任者logback替代&…

第三节 折线图

文章目录 折线图1.1 numpy介绍1.2 预测趋势1.3 折线图流程工具 Pandas1.3.1 读取并生成 CSV1.3.2 输出列数据1.3.3 画折线图1.5 添加横纵坐标,标题 屏幕属性 1.4 画双折线图1.5 扩展:做三线图 折线图 1.1 numpy介绍 上节课我们学了柱状图, 通过柱状图可以了解, numpy主要是科…

部署lnmp框架nginx在上一章节

目录 一.安装mysql服务 1.下载mysql和模块boost并解压包到/opt目录下 2.创建运行用户 3.进入mysql包目录下面进行编译安装 4.创建普通用户管理mysql useradd -s /sbin/nologin mysqlchown -R mysql:mysql /usr/local/mysql/ 5.修改配置文件 6.设置环境变量&#xff0c;申…

等约束二次规划中的特征分解研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C++——用红黑树封装map和set

目录 1. 前言 2. 红黑树模板参数的控制 3. 模板参数中仿函数的增加 4. 红黑树迭代器的实现 5. 红黑树的begin()和end() 6. 红黑树的Find查找函数 7. 红黑树封装map和set源码 7.1 map.h 7.2 set.h 7.3 test.cpp 1. 前言 我们都知道set是K模型的容器&#xff0c;而map…

【深度学习】6-3 卷积神经网络 - 卷积层和池化层的实现

卷积层和池化层的实现 如前所述&#xff0c;CNN 中各层间传递的数据是 4 维数据。所谓 4 维数据&#xff0c;比如数据的形状是 (10, 1, 28, 28)&#xff0c;则它对应 10 个高为 28、长为 28、通道为 1 的数据。用 Python 来实现的话&#xff0c;如下所示 >>> x np.r…

CentOS 7.9 安装 Docker

CentOS 7.9 安装 Docker 文章目录 CentOS 7.9 安装 Docker一、相关博客二、安装 Docker1、安装 device-mapper-persistent-data 和 lvm2 两个依赖2、添加阿里云 Docker 镜像源3、安装 Docker 社区版4、启动5、运行测试 三、配置阿里云镜像加速器 一、相关博客 【Docker】002-D…

基于ASP.NET MVC的网络书店系统/书店商城

摘 要 随着书店规模的不断扩大&#xff0c;人流数量的急剧增加&#xff0c;有关书店的各种信息量也在不断成倍增长。面对庞大的信息量&#xff0c;就需要有网络书店来提高书店工作的效率。通过这样的系统&#xff0c;我们可以做到信息的规范管理和快速查询&#xff0c;从而减少…

1Panel 安装部署

1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。 1. 环境要求 安装前请确保您的系统符合安装条件&#xff1a; 操作系统&#xff1a;支持主流 Linux 发行版本&#xff08;基于 Debian / RedHat&#xff0c;包括国产操作系统&#xff09;&#xff1b; 服务器架构&#…

LangChain: LLM应用开发框架

GitHub - hwchase17/langchain: ⚡ Building applications with LLMs through composability ⚡⚡ Building applications with LLMs through composability ⚡ - GitHub - hwchase17/langchain: ⚡ Building applications with LLMs through composability ⚡https://github.c…