7.3 uvm_config_db in UVM

uvm_config_db类派生自uvm_resource_db类。它是uvm_resource_db顶部的另一层便利层,简化了用于uvm_component实例的基本接口(资源库的访问方法)。

下面uvm_config_db类的代码段取自uvm源代码。

class uvm_config_db#(type T=int) extends uvm_resource_db#(T);static uvm_pool#(string,uvm_resource#(T)) m_rsc[uvm_component];static local uvm_queue#(m_uvm_waiter) m_waiters[string];static function bit get(uvm_component cntxt,string inst_name,string field_name,inout T value);...endfunctionstatic function void set(uvm_component cntxt,string inst_name,string field_name,T value);...endfunction...
...
endclass

1. uvm_config_db methods

下表中除了wait_modified是静态任务外,其余都是的静态函数。

其中,

uvm_component cntxt:该context是可访问数据库条目的起点(hierarchical starting point)。

string inst_name:实例名称是限制数据库条目可访问性的路径。

string field_name:field_name是用于查找数据库条目的标记或标签。
T value: 是从数据库中set或者get的值。default是整数类型。

简单地说,完整path取决于 cntxt  和 inst_name拼接 {cntxt, “.” ,inst_name} .

例子:uvm_test_top.env.agent_o的层次路径可以从测试用例中提到为:

cntxt = null
inst_name = env.agent_oORcntxt = this
inst_name = "env.agent_o"

 Syntax for set method:

void uvm_config_db#(type T = int)::set(uvm_component cntxt,string inst_name,string field_name,T value);

Syntax for get method:

bit uvm_config_db#(type T=int)::get(uvm_component cntxt,string inst_name,string field_name,ref T value);

2. uvm_config_db example

在下面的示例中,control位存储在数据库中,作为在component_B中为my_component创建对象的使能条件(enable condition)。

名为“control”、类型为bit的新资源将从测试用例添加到资源池中。

uvm_config_db #(bit)::set(null, "*", "control", 1);//where,
//uvm_component cntxt= null;
//string inst_name = "*"
//String field_name = "control";
//T value = 1;// In component_B, 
if(!uvm_config_db #(bit)::get(this, "*", "control", ctrl))`uvm_fatal(get_type_name(), "get failed for resource in this scope");

使用get()static函数检索资源,该函数在数据库中以field_name作为“control”进行查找。如果get()在数据库中找不到“control”字符串field_name,将报告致命错误。尽管致命检查不是强制性的,但建议将其用于调试目的。一旦表中的查找成功,存储在资源数据库中的值就会在局部变量ctrl中更新。此控制位用于控制my_component对象的创建。 

 

`include "uvm_macros.svh"
import uvm_pkg::*;class component_A #(parameter ID_WIDTH = 8) extends uvm_component;bit [ID_WIDTH-1:0] id;`uvm_component_param_utils(component_A #(ID_WIDTH))function new(string name = "component_A", uvm_component parent = null);super.new(name, parent);id = 1;endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_A: id = %0d", id), UVM_LOW);endfunction
endclassclass mycomponent #(parameter ID_WIDTH = 8) extends uvm_component;bit [ID_WIDTH-1:0] id;`uvm_component_param_utils(mycomponent #(ID_WIDTH))function new(string name = "mycomponent", uvm_component parent = null);super.new(name, parent);id = 2;endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside mycomponent: id = %0d", id), UVM_LOW);endfunction
endclassclass component_B #(int ID_WIDTH = 8) extends component_A #(ID_WIDTH);bit ctrl;bit [ID_WIDTH-1:0] id;mycomponent #(8) my_comp;`uvm_component_param_utils(component_B #(ID_WIDTH))function new(string name = "component_B", uvm_component parent = null);super.new(name, parent);id = 3;endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db #(bit)::get(this, "*", "control", ctrl))`uvm_fatal(get_type_name(), "get failed for resource in this scope");if(ctrl)  my_comp = mycomponent #(8)::type_id::create("my_comp", this);endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_B: id = %0d, ctrl = %0d", id, ctrl), UVM_LOW);if(ctrl) void'(my_comp.display());endfunction
endclassclass my_test extends uvm_test;bit control;`uvm_component_utils(my_test)component_A #(32) comp_A;component_B #(16) comp_B;function new(string name = "my_test", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);comp_A = component_A #(32)::type_id::create("comp_A", this);comp_B = component_B #(16)::type_id::create("comp_B", this);uvm_config_db #(bit)::set(null, "*", "control", 1);//or//uvm_config_db #(bit)::set(this, "*", "control", 1);endfunctionfunction void end_of_elaboration_phase(uvm_phase phase);super.end_of_elaboration_phase(phase);uvm_top.print_topology();endfunctiontask run_phase(uvm_phase phase);super.run_phase(phase);void'(comp_A.display());void'(comp_B.display());endtask
endclassmodule tb_top;initial beginrun_test("my_test");end
endmodule

Output:

UVM_INFO /xcelium20.09/tools//methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
----------------------------------------
Name          Type           Size  Value
----------------------------------------
uvm_test_top  my_test        -     @1812comp_A      uvm_component  -     @1879comp_B      uvm_component  -     @1910my_comp   uvm_component  -     @1958
----------------------------------------UVM_INFO testbench.sv(14) @ 0: uvm_test_top.comp_A [uvm_component] inside component_A: id = 1
UVM_INFO testbench.sv(52) @ 0: uvm_test_top.comp_B [uvm_component] inside component_B: id = 3, ctrl = 1
UVM_INFO testbench.sv(28) @ 0: uvm_test_top.comp_B.my_comp [uvm_component] inside mycomponent: id = 2

3. precedence rule

有两个优先规则适用于uvm_config_db。在build_phase中,

1.在组件层次结构较高的上下文中的set()调用优先于层次结构路径较低的set()调用。

例子:

`include "uvm_macros.svh"
import uvm_pkg::*;class component_A extends uvm_component;int id;`uvm_component_utils(component_A)function new(string name = "component_A", uvm_component parent = null);super.new(name, parent);id = 1;endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_A: id = %0d", id), UVM_LOW);endfunction
endclassclass component_B extends component_A;int receive_value;int id;`uvm_component_utils(component_B)function new(string name = "component_B", uvm_component parent = null);super.new(name, parent);id = 2;endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db #(int)::get(this, "*", "value", receive_value))`uvm_fatal(get_type_name(), "get failed for resource in this scope");    endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_B: id = %0d, receive_value = %0d", id, receive_value), UVM_LOW);endfunction
endclassclass env extends uvm_env;`uvm_component_utils(env)component_A comp_A;component_B comp_B;function new(string name = "env", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);comp_A = component_A ::type_id::create("comp_A", this);comp_B = component_B ::type_id::create("comp_B", this);uvm_config_db #(int)::set(this, "*", "value", 200);endfunctiontask run_phase(uvm_phase phase);super.run_phase(phase);void'(comp_A.display());void'(comp_B.display());endtask
endclassclass my_test extends uvm_test;bit control;`uvm_component_utils(my_test)env env_o;function new(string name = "my_test", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env_o = env::type_id::create("env_o", this);uvm_config_db #(int)::set(null, "*", "value", 100);endfunctionfunction void end_of_elaboration_phase(uvm_phase phase);super.end_of_elaboration_phase(phase);uvm_top.print_topology();endfunction
endclassmodule tb_top;initial beginrun_test("my_test");end
endmodule

Output:

UVM_INFO /xcelium20.09/tools//methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------
Name          Type         Size  Value
--------------------------------------
uvm_test_top  my_test      -     @1810env_o       env          -     @1877comp_A    component_A  -     @1922comp_B    component_B  -     @1953
--------------------------------------UVM_INFO testbench.sv(14) @ 0: uvm_test_top.env_o.comp_A [component_A] inside component_A: id = 1
UVM_INFO testbench.sv(36) @ 0: uvm_test_top.env_o.comp_B [component_B] inside component_B: id = 2, receive_value = 100

2.在具有相同的上下文字段时,最后一个set()调用优先于前面的set()。

 Example:

`include "uvm_macros.svh"
import uvm_pkg::*;class component_A extends uvm_component;int id;`uvm_component_utils(component_A)function new(string name = "component_A", uvm_component parent = null);super.new(name, parent);id = 1;endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_A: id = %0d", id), UVM_LOW);endfunction
endclassclass component_B extends component_A;int receive_value;int id;`uvm_component_utils(component_B)function new(string name = "component_B", uvm_component parent = null);super.new(name, parent);id = 2;endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);if(!uvm_config_db #(int)::get(this, "*", "value", receive_value))`uvm_fatal(get_type_name(), "get failed for resource in this scope");    endfunctionfunction display();`uvm_info(get_type_name(), $sformatf("inside component_B: id = %0d, receive_value = %0d", id, receive_value), UVM_LOW);endfunction
endclassclass env extends uvm_env;`uvm_component_utils(env)component_A comp_A;component_B comp_B;function new(string name = "env", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);comp_A = component_A ::type_id::create("comp_A", this);comp_B = component_B ::type_id::create("comp_B", this);endfunctiontask run_phase(uvm_phase phase);super.run_phase(phase);void'(comp_A.display());void'(comp_B.display());endtask
endclassclass my_test extends uvm_test;bit control;`uvm_component_utils(my_test)env env_o;function new(string name = "my_test", uvm_component parent = null);super.new(name, parent);endfunctionfunction void build_phase(uvm_phase phase);super.build_phase(phase);env_o = env::type_id::create("env_o", this);uvm_config_db #(int)::set(null, "*", "value", 100);uvm_config_db #(int)::set(null, "*", "value", 200);endfunctionfunction void end_of_elaboration_phase(uvm_phase phase);super.end_of_elaboration_phase(phase);uvm_top.print_topology();endfunction
endclassmodule tb_top;initial beginrun_test("my_test");end
endmodule

Output:

 

UVM_INFO /xcelium20.09/tools//methodology/UVM/CDNS-1.2/sv/src/base/uvm_root.svh(605) @ 0: reporter [UVMTOP] UVM testbench topology:
--------------------------------------
Name          Type         Size  Value
--------------------------------------
uvm_test_top  my_test      -     @1810env_o       env          -     @1877comp_A    component_A  -     @1924comp_B    component_B  -     @1955
--------------------------------------UVM_INFO testbench.sv(14) @ 0: uvm_test_top.env_o.comp_A [component_A] inside component_A: id = 1
UVM_INFO testbench.sv(36) @ 0: uvm_test_top.env_o.comp_B [component_B] inside component_B: id = 2, receive_value = 200

4. uvm_config_db usage

  1. 将配置变量/类向下传递到testbench的层次结构中(如上面的示例所示)。
  2. 将虚拟接口从顶部层次结构传递到测试台层次结构中的组件。

5. Difference between uvm_config_db and uvm_resource_db 

  1. 虽然这两个类都在uvm资源facility上提供了一个方便层(便利),但uvm_config_db是从uvm_resource_db派生而来的。这将在uvm_resource_db方法之上添加其他方法。
  2. 关于组件层次结构,与具有两个字符串scope和name的uvm_resource相比,uvm_config_db具有一个参数作为上下文,其类型为uvm_component,实例名称为字符串,提供了更大的灵活性。由于上下文中提到了组件层次结构,因此它提供了对层次路径的更多控制。这个context = this参数提供组件的相对路径。这个context = null提供了一个绝对路径,这意味着上面没有层次路径。

With respect to component hierarchy, the uvm_config_db  has an argument as a context that has the type of uvm_component and instance name as a string that provides more flexibility as compared to uvm_resource that has two strings scope and name. Since component hierarchy is mentioned in the context, it provides more control over the hierarchical path.
The context = this argument provides a relative path from the component. The context = null provides an absolute path which means there is no hierarchical path above.

因此,建议总是使用uvm_config_db。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【GitHub精选项目】短信系统测试工具:SMSBoom 操作指南

前言 本文为大家带来的是 OpenEthan 开发的 SMSBoom 项目 —— 一种用于短信服务测试的工具。这个工具能够发送大量短信,通常用于测试短信服务的稳定性和处理能力。在合法和道德的范畴内,SMSBoom 可以作为一种有效的测试工具,帮助开发者和系统…

【编译原理】基于词法分析器的LL1语法分析器

【编译原理】基于词法分析器的LL1语法分析器 实验要求 设计一个满足以下要求的⽂法: (1)识别只包含变量声明语句和执行语句程序段的语法结构合法性; (2)变量声明中只使用int,char,float 3类基本类型&…

Android studio 花式按键

一、activity_main.xml代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.a…

【C++】STL 容器 - list 双向链表容器 ① ( 容器特点 | 容器操作时间复杂度 | 构造函数 )

文章目录 一、 list 双向链表容器简介1、容器特点2、容器操作时间复杂度3、遍历访问5、头文件 二、 list 双向链表容器 构造函数1、默认无参构造函数2、创建包含 n 个相同元素的 list 双向链表3、使用初始化列表构造 list 双向链表4、使用另外一个 list 容器 构造 list 双向链表…

【Java基础】Java中异常分类,他们之间的区别?

&#x1f341;Java中异常分哪两类 &#x1f341;Java中异常类&#x1f341;受检异常&#x1f341;非受检异常 &#x1f341;拓展知识仓&#x1f341;什么是Throwable&#x1f341;Error和Exception的区别和联系&#x1f341; 列举几个常用的RuntimeException&#x1f341;Java异…

关于“Python”的核心知识点整理大全41

目录 scoreboard.py game_functions.py game_functions.py 14.3.8 显示等级 game_stats.py scoreboard.py scoreboard.py scoreboard.py game_functions.py game_functions.py alien_invasion.py 14.3.9 显示余下的飞船数 ship.py scoreboard.py 我们将最高得分圆整…

微信这样分类客户,帮你轻松提升业绩!

无论是什么行业&#xff0c;都会遇到各种各样的客户&#xff0c;能不能成交这些客户&#xff0c;关键的一点在于有没有明确的客户分类。 今天就给大家分享几个高效分类客户的方法&#xff0c;帮助大家提高成交率和业绩。 1、分组管理 在微信中创建不同的分组&#xff0c;比如…

MyBatis——MyBatis的缓存

MyBatis的缓存 创建工程&#xff1a; 1缓存介绍 为什么使用缓存&#xff1f; 首次访问时&#xff0c;查询数据库&#xff0c;并将数据存储到内存中&#xff1b;再次访问时直接访问缓存&#xff0c;减少IO、硬盘读写次数、提高效率 Mybatis中的一级缓存和二级缓存&#xff1f;…

IP 地址归属地查询

IP 地址归属地查询 1. IP 地址归属地查询2. IP 地址归属地查询References 1. IP 地址归属地查询 https://tool.lu/ip/index.html 2. IP 地址归属地查询 https://www.ip.cn/ip/.html References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【JavaScript】Set、Map、WeakSet、WeakMap

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

Gin框架之使用 go-ini 加载.ini 配置文件

首先,联想一个问题,我们在部署服务时,通常为了方便,对于需要迭代更新的代码进行修改,但是比对shell,可以搞一个变量将需要修改的,以及修改起来变动处多的,写在变量内,到时候如果需要变更,可以直接变更变量即可; 那么,golang有没有什么方式可以将需要变的东西保存起…

TCP协议及工作原理(三)客户端的搭建

ui界面的搭建 &#xff1a; QTcpServer是基于TCP的服务器类提供一种方便的方式管理和创建TCP服务器&#xff0c;QTcpSocket处理TCP套接字编程用于建立TCP连接&#xff0c;发送接收数据等功能。 参考前两篇可深入理解&#xff01;&#xff01;&#xff01;&#xff01;&#xff…

php 不加后缀访问

实现不带后缀访问php文件的方法&#xff1a;首先在htaccess文件中加入内容“RewriteRule ^(api/token) token.php [L]”&#xff1b;然后通过根目录下的“token.php”来接受“api/token”&#xff1b;最后修改配置文件。 考虑的做法有&#xff1a; HTTP重写技术&#xff0c;让…

Win10电脑蓝牙默认音量100的设置教程

在Win10电脑操作过程中&#xff0c;用户想设置连接蓝牙后音量默认是100&#xff0c;但不知道具体的设置操作步骤。这时候用户需要打开Win10系统上的注册表&#xff0c;点击修改注册表来完成这一设置&#xff0c;下面就是Win10电脑蓝牙默认音量100的设置教程介绍&#xff0c;帮助…

【Java、Python】获取电脑当前网络IP进行位置获取(附源码)

我相信看到这篇博客的时候心里肯定是想解决自己的一个问题的&#xff0c;而这篇博客我就以简单快速的方式解决这些烦恼&#xff01; 一、获取当前IP 在Java中自带了一些自己的流对象来获取当前的IP地址&#xff0c;不多说我们直接上代码。 //获取当前网络ip地址 ipAddress Ine…

CentOS安装MongoDB

CentOS安装MongoDB 文章目录 CentOS安装MongoDB1. 安装并运行2. 创建用户/密码3. 测试语句4. 允许外网访问 1. 安装并运行 在 CentOS 上安装 MongoDB&#xff0c;你可以按照以下步骤进行&#xff1a; 导入 MongoDB 的 GPG 密钥&#xff1a; sudo rpm --import https://www.mon…

React快速入门之组件

组件 文件&#xff1a;Profile.js export default function Profile({isPacked true&#xff0c;head,stlyeTmp,src,size 80}) {if (isPacked) {head head " ✔";}return (<div><h1>{head}</h1><imgsrc{src}alt"Katherine Johnson&q…

MongoDB ReplicaSet 部署

文章目录 前言1. 环境准备2. 生成密钥3. 配置参数4. 创建 ReplicaSet5. 副本集维护5.1 新增成员5.2 移除节点5.4 主节点降级5.5 阻止选举5.6 允许副本节点读5.7 延迟观测 6. 连接副本集 后记 前言 本篇文章介绍 MongoDB ReplicaSet 如何搭建&#xff0c;及常用的维护方法。 1…

Redis-实践知识

转自极客时间Redis 亚风 原文视频&#xff1a;https://u.geekbang.org/lesson/535?article681062 Redis最佳实践 普通KEY Redis 的key虽然可以自定义&#xff0c;但是最好遵循下面几个实践的约定&#xff1a; 格式&#xff1a;[业务名称]:[数据名]:[id] 长度不超过44字节 不…

【Jmeter】Jmeter基础9-BeanShell介绍

3、BeanShell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法。 3.1、Jmeter中使用的BeanShell 在Jmeter中&#xff0c;除了配置元件&#xff0c;其他类型的元件中都有BeanShell。BeanShell 是一种完全符合Java语法规范的脚本语言,并且又拥…