当前位置:网站首页>uvm中的config机制方法总结(一)
uvm中的config机制方法总结(一)
2022-06-27 00:46:00 【Alfred.HOO】
在验证环境的创建过程build phase中,除了组件的实例化过程,配置阶段也是必不可少的。为了验证环境的复用性,通过外部的参数配置,使得环境在创建的时候可以根据参数的不同来选择创建的组件、组件的实例个数、组件之间的连接以及组件的运行模式等等。在更细致的环境调节(environment tuning)中,有更多的变量需要配置,例如for-loop的阈值、字符串名称、随机变量的生成比重等等。 无论是配置哪些参数,用户都可以在编译时间或者仿真时间来设置。对于编译时间中要调整这些变量,可以通过修改参数、或者引入预处理指令(compiler directive,例如ifdef/
ifndef/else/
elsif/`endif)来修改。比起重新编译而言,在仿真中可以通过变量设置来修改环境,就显得更灵活了,而UVM config机制正是提供这么做的方法。
UVM提供了uvm_config_db的配置类以及几种很方便的变量设置方法来实现在仿真时的环境控制。常见的uvm_config_db的使用方式包括有:
1.传递virtual interface到环境中。
2.设置单一变量值,例如int、string、enum等。
3.传递配置对象(config object)到环境。
下面的几段例码分别来对这几种方式进行说明。
1.interface传递
首先来看看interface的传递,通过这种方便的传递方式很好地解决了连接硬件世界和软件世界。而在之前关于SV的核心篇章中,读者们可以看到,虽然SV可以通过层次化interface的索引来完成传递,但是这种方式不利于软件环境的封装和复用。下面这种方式,使得接口的传递和获取彻底分离开来,而在后台对virtual interface的传递立下功劳的便是uvm_config_db。
interface intf1;
logic enable = 0;
endinterface
module config_interface;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
virtual intf1 vif;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
if(!uvm_config_db#(virtual intf1)::get(this, "", "vif", vif)) begin
`uvm_error("GETVIF", "no virtual interface is assigned")
end
`uvm_info("SETVAL", $sformatf("vif.enable is %b before set", vif.enable), UVM_LOW)
vif.enable = 1;
`uvm_info("SETVAL", $sformatf("vif.enable is %b after set", vif.enable), UVM_LOW)
endfunction
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
comp1 c1;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
c1 = comp1::type_id::create("c1", this);
endfunction
endclass
intf1 intf();
initial begin
uvm_config_db#(virtual intf1)::set(uvm_root::get(), "uvm_test_top.c1", "vif", intf);
run_test("test1");
end
endmodule
输出结果
UVM_INFO @ 0: reporter [RNTST] Running test test1...
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] vif.enable is 0 before set
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] vif.enable is 1 after set
从上面这个例子可以看到,接口的传递从硬件世界到UVM环境中的传递可以通过uvm_config_db来实现。在实现过程中需要注意几点:
接口的传递应该发生在run_test()之前。这保证了在进入build phase之前,virtual interface已经传递进入uvm_config_db中。
用户应当把interface与virtual interface的声明区分开来。在传递过程中的类型应当为virtual interface,即实际接口的句柄。
2.变量设置
在各个test中,可以在build phase阶段对底层组件中的变量加以配置,进而完成在环境例化之前完成配置,使得环境可以按照预期运行。
module config_variable;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
int val1 = 1;
string str1 = "null";
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
`uvm_info("SETVAL", $sformatf("val1 is %d before get", val1), UVM_LOW)
`uvm_info("SETVAL", $sformatf("str1 is %s before get", str1), UVM_LOW)
uvm_config_db#(int)::get(this, "", "val1", val1);
uvm_config_db#(string)::get(this, "", "str1", str1);
`uvm_info("SETVAL", $sformatf("val1 is %d after get", val1), UVM_LOW)
`uvm_info("SETVAL", $sformatf("str1 is %s after get", str1), UVM_LOW)
endfunction
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
comp1 c1;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
uvm_config_db#(int)::set(this, "c1", "val1", 100);
uvm_config_db#(string)::set(this, "c1", "str1", "comp1");
c1 = comp1::type_id::create("c1", this);
endfunction
endclass
initial begin
run_test("test1");
end
endmodule
输出结果
UVM_INFO @ 0: reporter [RNTST] Running test test1...
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] val1 is 1 before get
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] str1 is null before get
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] val1 is 100 after get
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] str1 is comp1 after get
- config object传递
在实际的test配置中,需要配置的参数不单单数量多,而且还分属于不同的组件。那么,如果对这么多层次中的变量做出类似上面的单一变量设置,一方面需要更多的代码,这就容易出错,不易于阅读,另外一方面也不易于复用,毕竟底层组件的变量有添加或者减少,通过uvm_config_db::set是无法得知是否设置成功的。因此,如果将每个组件中的变量加以整合,首先放置到一个uvm_object中用于传递,那么将会更有利于整体进行配置。
import uvm_pkg::*;
`include "uvm_macros.svh"
class config1 extends uvm_object;
int val1 = 1;
int str1 = "null";
`uvm_object_utils(config1)
function new(string name = "config1");
super.new(name);
endfunction
endclass
class comp1 extends uvm_component;
`uvm_component_utils(comp1)
config1 cfg;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
uvm_object tmp;
uvm_config_db#(uvm_object)::get(this, "", "cfg", tmp);
void'($cast(cfg, tmp));
`uvm_info("SETVAL", $sformatf("cfg.val1 is %d after get", cfg.val1), UVM_LOW)
`uvm_info("SETVAL", $sformatf("cfg.str1 is %s after get", cfg.str1), UVM_LOW)
endfunction
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
comp1 c1, c2;
config1 cfg1, cfg2;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
cfg1 = config1::type_id::create("cfg1");
cfg2 = config1::type_id::create("cfg2");
cfg1.val1 = 30;
cfg1.str1= "c1";
cfg2.val1 = 50;
cfg2.str1= "c2";
uvm_config_db#(uvm_object)::set(this, "c1", "cfg", cfg1);
uvm_config_db#(uvm_object)::set(this, "c2", "cfg", cfg2);
c1 = comp1::type_id::create("c1", this);
c2 = comp1::type_id::create("c2", this);
endfunction
endclass
initial begin
run_test("test1");
end
endmodule
输出结果
UVM_INFO @ 0: reporter [RNTST] Running test test1...
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] cfg.val1 is 30 after get
UVM_INFO @ 0: uvm_test_top.c1 [SETVAL] cfg.str1 is c1 after get
UVM_INFO @ 0: uvm_test_top.c2 [SETVAL] cfg.val1 is 50 after get
UVM_INFO @ 0: uvm_test_top.c2 [SETVAL] cfg.str1 is c2 after get
边栏推荐
- Amazon ElastiCache 飞速搭建缓存服务集群,这才叫快
- Analysis of ideal L9 product power: the price is 459800 yuan, the four cylinder engine is adopted, and the endurance is 1315km
- Unable to create a folder to save the sketch: MKDIR sketch
- TopoLVM: 基于LVM的Kubernetes本地持久化方案,容量感知,动态创建PV,轻松使用本地磁盘
- 对象的访问机制及其他
- Encapsulation of unified result set
- 乔治·华盛顿大学 : Hanhan Zhou | PAC:多智能体强化学习中具有反事实预测的辅助价值因子分解
- The world is very big. Some people tattoo QR codes on their necks
- Live review | Ziya &ccf TF: Discussion on software supply chain risk management technology under cloud native scenario
- Keepalived 实现 Redis AutoFailover (RedisHA)17
猜你喜欢
Timing mechanism of LwIP
Solve the problem that stc8g1k08 program cannot run and port configuration
JSON parsing, esp32 easy access to time, temperature and weather
Gaussian and Summary Stats
Esp32 experiment - self built web server distribution network 02
How to use ch423? Cheap domestic IO expansion chip
Lambda expression
Operating instructions and Q & A of cec-i China learning machine
2022年地理信息系统与遥感专业就业前景与升学高校排名选择
The world is very big. Some people tattoo QR codes on their necks
随机推荐
CLIP:从自然语言监督中学习可迁移的视觉模型
Play OLED, u8g2 animation, increasing numbers, random triangles, etc
使用NetworkX对社交网络进行系统的分析:Facebook网络分析案例
XSS笔记(下)
memcached基础6
Keepalived 实现 Redis AutoFailover (RedisHA)13
Interface test framework practice (I) | requests and interface request construction
自定义JSP[if,foreach,数据,select]标签
持续交付-Blue Ocean 应用
memcached基础7
Custom class loader encrypts and decrypts classes
在线文本数字识别列表求和工具
Operating instructions and Q & A of cec-i China learning machine
Find the minimum value in the rotation sort array ii[classical Abstract dichotomy + how to break the game left, middle and right are equal]
Kept to implement redis autofailover (redisha) 16
Law of Large Numbers
Skills needing attention in selection and purchase of slip ring
Count the logarithm of points that cannot reach each other in an undirected graph [classic adjacency table building +dfs Statistics - > query set optimization] [query set manual / write details]
Generate flow chart with code, and how to use markdown
Is it safe to open a securities account online? Is it reliable to speculate in stocks by mobile phone