当前位置:网站首页>UVM中config_db机制的使用方法
UVM中config_db机制的使用方法
2022-06-27 00:46:00 【Alfred.HOO】
set函数与get函数的参数
config_db机制用于在UVM验证平台间传递参数。他们通常是成对出现的。set函数时寄信,get函数是收信。
如在某个测试用例的build_phase中可以使用如下方式寄信:uvm_config_db#(int)::set(this, "env.i_agt.drv" "pre_num", 100);
其中第一个参数和第二个参数联合起来组成目标路径,与此路径符合的目标才能收信。第一个参数必须是一个uvm_component实例的指针,第二个参数是相对此实例的路径。一般的,如果第一个参数被设置为this,那么第二个参数可以是一个空的字符串。第三个参数就是set函数中的第三个参数,这两个参数必须严格匹配,第四个参数则是要设置的变量。
在top_tb中通过config_db机制的set函数设置virtual interface时,set函数的第一个函数为null。在这种情况下,UVM会自动把第一个单数替换为uvm_root::get(),即uvm_top。换句话说,以下两种写法完全等价:
uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env.i_agt.drv", "vif", input_vif);
uvm_config_db#(virtual my_if)::set(uvm_root::get(), "uvm_test_top.env.i_agt.drv", "vif", input_vif);
set及get函数中第三个参数可以与get函数中第四个参数不一样。
umv_config_db#(int)::set(this, "env.i_agt.drv", "p_num", 100);
umv_config_db#(int)::set(this, "", "p_num", pre_num);
省略get语句
src/ch3/section3.5/3.5.3/my_driver.sv
7 int pre_num;
8 `uvm_component_utils_begin(my_driver)
9 `uvm_field_int(pre_num, UVM_ALL_ON)
10 `uvm_component_utils_end
11
12 function new(string name = "my_driver", uvm_component parent = null);
13 super.new(name, parent);
14 pre_num = 3;
15 endfunction
16
17 virtual function void build_phase(uvm_phase phase);
18 `uvm_info("my_driver", $sformatf("before super.build_phase, the pre_num is %0d", pre_num), UVM_LOW)
19 super.build_phase(phase);
20 `uvm_info("my_driver", $sformatf("after super.build_phase, the pre_num is %0d", pre_num), UVM_LOW)
21 if(!uvm_config_db#(virtual my_if)::get(this, "", "vif", vif))
22 `uvm_fatal("my_driver", "virtual interface must be set for vif!!!")
23 endfunction
uvm_config_db#(int)::get(this, "", "pre_num", pre_num);
这里的关键是build_phase中的super.build_phase语句,当执行到driver的super.build_phase时,会自动执行get语句。这种做法的前
提是:第一,my_driver必须使用uvm_component_utils宏注册;第二,pre_num必须使用uvm_field_int宏注册;第三,在调用set函数
的时候,set函数的第三个参数必须与要get函数中变量的名字相一致,即必须是pre_num。
跨层次的多重设置
在图3-4中,假如uvm_test_top和env中都对driver的pre_num的值进行了设置,在uvm_test_top中的设置语句如下:
文件:src/ch3/section3.5/3.5.4/normal/my_case0.sv
32 function void my_case0::build_phase(uvm_phase phase);
33 super.build_phase(phase);
…
39 uvm_config_db#(int)::set(this,
40 "env.i_agt.drv",
41 "pre_num",
42 999);
43 `uvm_info("my_case0", "in my_case0, env.i_agt.drv.pre_num is set to 999",UVM_LOW)
在env的设置语句如下:
文件:src/ch3/section3.5/3.5.4/normal/my_env.sv
19 virtual function void build_phase(uvm_phase phase);
20 super.build_phase(phase);
…
31 uvm_config_db#(int)::set(this,
32 "i_agt.drv",
33 "pre_num",
34 100);
35 `uvm_info("my_env", "in my_env, env.i_agt.drv.pre_num is set to 100",UVM_LOW)
36 endfunction
那么driver中获取到的值是100还是999呢?答案是999。UVM规定层次越高,那么它的优先级越高。这里的层次指的是在UVM
树中的位置,越靠近根结点uvm_top,则认为其层次越高。uvm_test_top的层次是高于env的,所以uvm_test_top中的set函数的优先
级高。
上述结论在set函数的第一个参数为this时是成立的,但是假如set函数的第一个参数不是this会如何呢?假设uvm_test_top的set语句是:
文件:src/ch3/section3.5/3.5.4/abnormal/my_case0.sv
32 function void my_case0::build_phase(uvm_phase phase);
33 super.build_phase(phase);
…
39 uvm_config_db#(int)::set(uvm_root::get(),
40 “uvm_test_top.env.i_agt.drv”,
41 “pre_num”,
42 999);
43 `uvm_info(“my_case0”, “in my_case0, env.i_agt.drv.pre_num is set to 999”, UVM_LOW)
而env的set语句是:
文件:src/ch3/section3.5/3.5.4/normal/my_env.sv
19 virtual function void build_phase(uvm_phase phase);
20 super.build_phase(phase);
…
31 uvm_config_db#(int)::set(uvm_root::get(),
32 “uvm_test_top.env.i_agt.drv”,
33 “pre_num”,
34 100);
35 `uvm_info(“my_env”, “in my_env, env.i_agt.drv.pre_num is set to 100”,UVM_LOW)
36 endfunction
这种情况下,driver得到的pre_num的值是100。由于set函数的第一个参数是uvm_root::get(),所以寄信人变成了uvm_top。在这种情况下,只能比较寄信的时间。UVM的build_phase是自上而下执行的,my_case0的build_phase先于my_env的build_phase执行。所以my_env对pre_num的设置在后,其设置成为最终的设置。
假如uvm_test_top中set函数的第一个参数是this,而env中set函数的第一个参数是uvm_root::get(),那么driver得到的
pre_num的值也是100。这是因为env中set函数的寄信人变成了uvm_top,在UVM树中具有最高的优先级。
因此,无论如何,在调用set函数时其第一个参数应该尽量使用this。在无法得到this指针的情况下(如在top_tb中),使用null
或者uvm_root::get()。
同一层次的多重设置
当跨层次来看待问题时,是高层次的set设置优先;当处于同一层次时,上节已经提过,是时间优先。
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 100);
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 109);
当上面两个语句同时出现在测试用例的build_phase中时,driver最终获取到的值将会是109。像上面的这种用法看起来完全是
胡闹,没有任何意义。
验证中写代码的一个原则是同样的语句只在一个地方出现,尽量避免在多个地方出现。解决这个问题的办法就是在base_test的
build_phase中使用config_db::set进行设置,这样,当由base_test派生而来的case1~case99在执行super.build_phase(phase)时,都会进行设置:
classs base_test extends uvm_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 7);
endfunction
endclass
class case1 extends base_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
endclass
…
class case99 extends base_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
endclass
但是对于第100个测试用例,则依然需要这么写:
class case100 extends base_test;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this, "env.i_agt.drv", pre_num_max, 100);
endfunction
endclass
case100的build_phase相当于如下所示连续设置了两次:
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 7);
uvm_config_db#(int)::set(this, "env.i_agt.drv", "pre_num", 100);
按照时间优先的原则,后面config_db::set的值将最终被driver得到。
边栏推荐
- Buuctf PWN write UPS (6)
- 用代码生成流程图,Markdown的使用方法
- About Random Numbers
- Keepalived 实现 Redis AutoFailover (RedisHA)12
- Kept to implement redis autofailover (redisha) 17
- Review the old and know the new -- constant renewal at normal temperature
- getReader() has already been called for this request
- 通过Rust语言计算加速技术突破图片识别性能瓶颈
- Find the minimum value in the rotation sort array ii[classical Abstract dichotomy + how to break the game left, middle and right are equal]
- leetcode 1143. Longest Commom Subsequence 最长公共子序列(中等)
猜你喜欢

Gaussian and Summary Stats

Flink 实战问题(七):No Watermark(Watermarks are only available EventTime is used)

Review the old and know the new -- constant renewal at normal temperature

世界很大,有人把二维码纹在脖子上

ArcGIS 镶嵌数据集切片丢失问题处理

IIS deploy static web site and FTP service

How to use ch423? Cheap domestic IO expansion chip

Gaussian and Summary Stats

持续交付-Blue Ocean 应用

TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘
随机推荐
Memcached foundation 7
Custom class loader encrypts and decrypts classes
Kept to implement redis autofailover (redisha) 17
3 - wire SPI Screen Drive
buuctf-pwn write-ups (6)
Amazon ElastiCache 飞速搭建缓存服务集群,这才叫快
The most difficult 618 in history, TCL won the first place in both jd.com and tmall.com shares in the TV industry
CH423要如何使用,便宜的国产IO扩展芯片
Implementation of ARP module in LwIP
Solution of idea hot start failure
网上开通证券账户安全吗 手机炒股靠谱吗
Employment prospect of GIS and remote sensing specialty and ranking selection of universities in 2022
Flink 实战问题(七):No Watermark(Watermarks are only available EventTime is used)
Generate flow chart with code, and how to use markdown
memcached基础1
Database interview questions +sql statement analysis
通过Rust语言计算加速技术突破图片识别性能瓶颈
Keepalived 实现 Redis AutoFailover (RedisHA)14
Unable to create a folder to save the sketch: MKDIR sketch
IIS 部署静态网站和 FTP 服务