UVM中uvm_config_db机制背后的大功臣

news2024/11/14 22:48:21

1. 前言

本次讲一下UVM中的uvm_config_db,在UVM中提供了一个内部数据库,可以在其中存储给定名称下的值,之后可以由其它TB组件去检索。这样的数据库允许我们以不同的名称存储不同的配置设置,这些配置可以在需要时潜在地配置TB组件,而无需修改实际的TB代码。比如说,我们需要TB打开某个checker,我们只需要提供这个checker的路径并将数据库中的变量设置为1,checker就可以检查这个变量值,如果它打开了,就开始检查DUT功能。uvm_config_db提供了访问这个数据库的接口,最常见的就是get()和set()函数,函数定义如下:

static function void set(uvm_component cntxt,
                         string inst_name,
                         string field_name,
                         T value);
static function bit get(uvm_component cntxt,
                        string inst_name,
                        string field_name,
                        inout T value);

这两个函数如何使用我想大家都清楚,调用一次set()就是往数据库内设置1个scope为{cntxt,”.”, inst_name},匹配符为field_name,值为value的配置。其中inst_name和field_name是支持正则匹配或glob类型匹配的。调用一次get()就是用scope为{cntxt,”.”, inst_name},匹配符为field_name的访问方式在数据库里检索是否有匹配的设置,注意,这里的inst_name和field_name不支持正则匹配或glob类型匹配的,下面会具体说明。如果get()返回1就是找到了,返回0就算没有找到。上述两个函数中,如果cntxt传递的是null,那么UVM自动会使用uvm_root::get()替换它。大家如果需要调试uvm_config_db的话,可以使用+UVM_CONFIG_DB_TRACE或uvm_config_db_options类内的turn_on_tracing()/turn_off_tracing()/is_tracing()函数来进行。

多啰嗦一下,如果uvm_config_db::set()对同1个配置在不同时间或不同地点设置了多次,那么uvm_config_db::get()的时候将会采用哪一次的呢?UVM会给它们指定不同的优先级,结论就是:如果是在build_phase指定的话,是按UVM hierarchy来的,层次越高优先级越高,也就是uvm_test的优先级会高于uvm_env,以此类推。但如果两个组件是同一个UVM hierarchy的话,就是按时间顺序来的,越往后set优先级越高。在build_phase之后,就不在于UVM hierarchy了,都是按照时间顺序来的,越往后set优先级越高。

那么UVM中是如何做到uvm_config_db::set()和uvm_config_db::get()的匹配呢?这就涉及到了本文的主题了。简单说就是字符串的正则匹配,在UVM内部是通过uvm_glob_to_re()uvm_re_match()这两个函数来实现的,它们是在uvm_config_db背后默默工作的功臣。

在TB调用uvm_config_db::set()的时候,set函数会将参数cntxt和inst_name拼接起来后,调用用uvm_glob_to_re()转换格式,再存到uvm_resource类里的scope字符串变量,set()的值也是放在uvm_resource类里。当TB调用uvm_config_db::get()的时候,get函数也会将参数cntxtinst_name拼接起来,再调用uvm_re_match()uvm_resource_base类里的scope字符串进行匹配,如果匹配成功,就返回这个uvm_resource类的值。这就完成了set()设置值和get()查找值的过程了。uvm_glob_to_re()uvm_re_match()在其中扮演重要的角色,我们就来看看这两个函数

这两个函数都支持C版本和SV版本,两个版本的功能有点差别,默认是使用C版本,功能更强大点。如果TB没有定义了UVM_REGEX_NO_DPIUVM_NO_DPI宏的话,那么用的是DPI-C import进来的C版本,反之是Systemverilog版本的

2. uvm_glob_to_re()函数

C版本的uvm_glob_to_re()函数定义如下:

const char * uvm_glob_to_re(const char *glob)
import "DPI-C" function string uvm_glob_to_re(string glob);

它会将输入的glob字符串(glob类型匹配格式)转成真正的正则表达式格式(POSIX regular expression)。也就是把输入字符串中glob元字符替换为正则元字符,并在开头和结尾分别加上/^$/glob类型匹配和正则匹配区别,大家可以自行查找资料下。

SV版本的uvm_glob_to_re()函数定义如下:

function string uvm_glob_to_re(string glob);
  return glob;
endfunction

从这个函数内容就可以看出,它不对输入的字符串做任何处理。

3. uvm_re_match()函数

C版本的uvm_re_match()函数定义如下:

int uvm_re_match(const char * re, const char *str)
import "DPI-C" function int uvm_re_match(string re, string str);

可以看到它有两个参数,第一个参数(re)是匹配的正则表达式,第二个参数(str)匹配的字符串,如果re在str里找到它要匹配的字符串,就返回0,反之返回1。

SV版本的uvm_re_match()函数定义如下:

function int uvm_re_match(string re, string str);

它的参数和返回值与C版本定义一样,不过它是支持glob类型匹配,也就是re必须是glob类型格式的。

对于uvm_config_db来说,在调用get()函数检索数据库的时候,get()函数传递的{cntxt,”.”, inst_name}会作为uvm_re_match()的str的实参,set()函数设置的{cntxt,”.”, inst_name}在经过uvm_glob_to_re()处理后作为uvm_re_match()的实参,这也就是为什么set()参数的inst_name支持正则格式,而get()参数的inst_name只是简单字符而已。

4. 例子分析

测试源代码如下:

str_re = "uvm_test_top.*monitor";
$display("uvm_glob_to_re() converts %s to %s", str_re, uvm_glob_to_re(str_re));
str = "uvm_test_top.a.b.c.monitor";
$display("%s and %s, match result is: %s", str_re, str, 
         uvm_re_match(uvm_glob_to_re(str_re), str)==1'b0 ? "MATCH" : "MISMATCH");
uvm_config_db #(bit)::set(null, str_re, "test_var", 1'b1);
if ( uvm_config_db #(bit)::get(null, str, "test_var", test_var) )
    $display("Get the test_var from path: %s", str);
else
    $display("Not get the test_var from path: %s", str);
str = "uvm_test.*.monitor";
$display("%s and %s, match result is: %s", str_re, str,
         uvm_re_match(uvm_glob_to_re(str_re), str)==1'b0 ? "MATCH" : "MISMATCH");
uvm_config_db #(bit)::set(null, str_re, "test_var", 1'b1);
if ( uvm_config_db #(bit)::get(null, str, "test_var", test_var) )
    $display("Get the test_var from path: %s", str);
else
    $display("Not get the test_var from path: %s", str);
str_re = "zhuanxinzhizhier";
str = "yes_zhuanxinzhizhier_yes";
$display("%s and %s, match result is: %s", str_re, str,
         uvm_re_match(str_re, str)==1'b0 ? "MATCH" : "MISMATCH");

当TB没有定义UVM_REGEX_NO_DPIUVM_NO_DPI宏时,也就是函数采用C版本函数,Questasim输出的结果为:

# uvm_glob_to_re() converts uvm_test_top.*monitor to /^uvm_test_top\..*monitor$/
# uvm_test_top.*monitor and uvm_test_top.a.b.c.monitor, match result is: MATCH
# Get the test_var from path: uvm_test_top.a.b.c.monitor
# uvm_test_top.*monitor and uvm_test.*.monitor, match result is: MISMATCH
# Not get the test_var from path: uvm_test.*.monitor
# zhuanxinzhizhier and yes_zhuanxinzhizhier_yes, match result is: MATCH

当TB有定义UVM_REGEX_NO_DPIUVM_NO_DPI宏时,也就是函数采用SV版本,Questasim输出的结果为:

# uvm_glob_to_re() converts uvm_test_top.*monitor to uvm_test_top.*monitor
# uvm_test_top.*monitor and uvm_test_top.a.b.c.monitor, match result is: MATCH
# Get the test_var from path: uvm_test_top.a.b.c.monitor
# uvm_test_top.*monitor and uvm_test.*.monitor, match result is: MISMATCH
# Not get the test_var from path: uvm_test.*.monitor
# zhuanxinzhizhier and yes_zhuanxinzhizhier_yes, match result is: MISMATCH

从上述两个log的最后一行打印我们可以看出C版本函数功能还是更加强大。大家使用uvm_config_db::set()和uvm_config_db::get()时,要牢记set()的参数inst_name是支持正则匹配的,而get()的参数inst_name是不支持正则匹配的也就是get()的参数inst_name里就算包含*/?/+等特殊字符,也是会当作普通字符而已,而不会被处理成正则匹配里的元字符。

另外之前看到有个在线测试正则表达式的网站,大家有需要的话,可以去试试。网址:Regex Tester and Debugger Online - Javascript, PCRE, PHP

 

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

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

相关文章

spring.session 随笔0 集成设计

0. 上个月划水时间关注的,最近断断续续的了解了一些 RUNOOB redis命令:APPEND 整合shiro实现分布式session同步(定制cacheManager) 我想想,还是照自己思绪发散的顺序开始描述这块的内容吧,可能侧重点有些奇怪。 由于工程使用的spring.boot.…

树莓派+Docker+cpolar(内网穿透)+Nignx

首先安装Raspberry Pi Imager,用于给SD卡安装系统镜像。 使用Raspberry Pi Imager(树莓派镜像烧录器)烧录镜像文件到SD中,操作步骤如下图所示: docker安装nginx提供web服务 获取最新版本的docker安装包: su…

linux上启动两个nginx实例

一台机器上启动两个nginx实例,主要是端口冲突问题,另外,如果一个是通过编译安装,另一个是拷贝的,那么还需要修改静态文件根路径。 这里,我第一个nginx是通过源码编译安装,安装目录是默认的/usr/…

live555交叉编译

下载live555最新源码:http://www.live555.com/liveMedia/public/live555-latest.tar.gz 如果是要下载具体的live555版本,比如2023.06.14发布的版本,则可以浏览器输入:http://www.live555.com/liveMedia/public/live.2023.06.14.t…

GPT 模型的工作原理 你知道吗?

动动发财的小手,点个赞吧! Source[1] 简介 当我使用 GPT 模型编写我的前几行代码时是 2021 年,那一刻我意识到文本生成已经到了一个拐点。在此之前,我在研究生院从头开始编写语言模型,并且我有使用其他文本生成系统的经…

GPT-4满分通过MIT本科数学考试这套提示词火了

万万想不到啊,MIT数学考试,被GPT-4攻破了?! 突然有人在最新论文工作中高调宣布: GPT-4在MIT的数学和EECS(电气工程和计算机科学系)本科学位考试中,表现出的能力完全满足毕业要求。…

图解左连接、右连接、内连接、全连接(小白入门)

目录 一、七种连接情况二、左连接具体例子:力扣数据库题目 175. 组合两个表答案1. 连接条件为:on Person.PersonId Address.personId2. 连接条件为:on Person.PersonId ! Address.personId 三、左连接不包含内连接四、右连接五、右连接不包含…

利用腾讯云函数隐藏C2服务器

1、简介 腾讯云函数,可以为企业和开发者提供无服务器执行环境,无需购买和管理服务器,只需要在腾讯云上使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性 安全地运行代码。 C2服务器所有流量通过腾…

CSS入门(网络安全方向)——id与class

CSS (Cascading Style Sheets,层叠样式表),是一种用来为结构化文档(如 HTML 文档或 XML 应用)添加样式(字体、间距和颜色等)的计算机语言,CSS 文件扩展名为 .css。 通过使用 CSS 我…

Python电商数据分析系列-薪资预测

Python电商数据分析系列-薪资预测 学习目标: 快速掌握简单且常用的数据分析任务 自己实现预测简单预测任务 学习内容: 搭建 Java 开发环境掌握 Java 基本语法掌握条件语句掌握循环语句 学习对象 想快速入门的本科生转行人员想学习新技能&#xff0c…

【Python】遇到 from PIL import Image 报错怎么办?

嗨害大家好鸭!我是小熊猫~ 很久之前有一个辛苦的小程序员 它在做验证码识别的的时候 遇上了一个小小的错误沙堆 经过它一点也不辛苦的努力,解决了它 于是它决定把这个宝贵的经历分享给大家~ 问题的出现: 前方出现红色波浪线 开始感到有一…

基于风险的测试

测试级别划分 测试级别的划分能对应解决软件开发的复杂性问题。将一个大规模复杂的系统分解,从小的模块开始(单元测试),逐步放大到整个系统级别。 测试类型的设计和安排,将测试类型安排在最适合对应的测试级别中来识别…

精准医疗、空间组学、细胞图谱,腾讯AI Lab用深度学习助力生命科学研究

近日,腾讯 AI Lab 三项研究分别入选国际顶级学术期刊 Nature Methods 和 Nature Communications,再次展示了在生命科学前沿领域上国际领先的技术实力。 这三项研究成果都属于生物细胞研究中的空间组学技术,对于推动精准医疗、细胞图谱绘制、人…

lua自动回收机制gc的理解

gc主要回收哪些垃圾? 在 Lua 中,垃圾回收(garbage collection,简称 GC)机制主要用于回收动态分配的内存和关闭未关闭的文件句柄。具体来说,Lua 的 GC 机制主要用于回收以下类型的垃圾: 对象&am…

力扣日记剑指 Offer II 003

1. 题目 LeetCode 剑指 Offer II 003. 前 n 个数字二进制中 1 的个数 1.1 题意 计算 0 到 n 之间的每个数的二进制表示中 1 的个数 1.2 分析 看时间复杂度,O(32n)应该能过(也就是每个数一位一位去数1的个数),知道low-bit这个运…

插入排序代码

时间复杂度O(n)

开源中文医疗大模型

中文医疗大模型 中文医疗大模型是指通过利用自然语言处理技术和机器学习算法,在大量的医疗文本数据中预训练出来的模型。它可以实现对医疗信息的分类、摘要、问答系统、机器翻译等功能,是医疗行业中的重要工具。在医疗领域中,大规模语言模型&…

答应我,不会回答这五个问题,不要去面试好吗?

1、创建坐席组的功能模块,如何进行测试用例设计? 解答: 功能测试,使用等价类划分法去分析创建坐席的每个输入项的有效及无效类,同步考虑边界值去设计对应的测试用例: 先进行冒烟测试,正常创建…

CSS基础学习--17 布局 - 水平 垂直对齐

一、元素居中对齐 要水平居中对齐一个元素(如 <div>), 可以使用 margin: auto;。设置到元素的宽度将防止它溢出到容器的边缘。元素通过指定宽度&#xff0c;并将两边的空外边距平均分配&#xff1a; <!DOCTYPE html> <html> <head> <meta charset&q…

关于sub-gaussian 和 sub-exponential随机变量的集中不等式

Concentration inequalities under sub-Gaussian and sub-exponential conditions sub-guassian范数和sub-exponential范数&#xff1a; 如果 f k ( X ) f_{k}(X) fk​(X)为sub-gaussian随机变量&#xff0c;则有如下的定理&#xff1a; 应用&#xff1a; 1.向量值集中 2.…