一、config机制
参考链接添加链接描述
参考链接添加链接描述
在验证环境的创建过程build phase中,除了组件的实例化,配置也是必不可少的。
在底层创建之前,完成配置!!!
- 传递virtual interface到环境中
- 设置单一变量值,例如int、string、enum等
- 传递配置对象(config object)到环境中
uvm_config_db #(type)::get( //type类型可以是int、string等类型,也可以是接口interface、对象object、sequencer等类型
uvm_component context, //组件中的目标,常设置为this(针对类),或者null(非类,如module模块)
string instance_name, //路径索引,相对于第一个参数的相对路径
string field_name,
inout T variable //2. **底层获取变量值,即variable = field_name,**如果不设置,变量保持原始值
);
uvm_config_db #(type)::set( //set()与get()中的类型type应该保持一致
uvm_component context, //组件中的目标,常设置为this(针对类),或者null(非类,如module模块)
string instance_name, //路径索引(set操作的目标组件实例名)
string field_name,
T value //1. **顶层设置变量值,即field_name = value**
);
————————————————
版权声明:本文为CSDN博主「Zing冰」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43830240/article/details/110868841
#(T):参数类,T表示传递的类型,如int等;
set:对顶层环境做配置;
get:从底层环境拿到变量;
uvm_component cntxt:组件名;
string inst_name:实例名;
string field_name:实例对应的某一个变量;
T value:实例的信息;
set,set只允许发生在组件中,并且set要在run,get之前,且set和get传递的类型要保持一致,路径也保持一致。
uvm_config_db#(T)::set(uvm_component cntxt, string inst_name, string field_name, T value);
uvm_config_db#(T)::get(uvm_component cntxt, string inst_name, string field_name, inout T value);
二、interface传递
在SV中,我们可以通过层次化的interface索引完成传递,例如用户想拿到drv的interface,可以通过test_intf→env_intf→drv_intf获得,但是这样的层次传递不利于代码的封装利用。
而在UVM中,使用uvm_config_db可以使接口传递和获取分离,从而直接配置和得到drv_intf。
object传递
为了更好的维护环境,可以将每个组件中的变量整合到uvm_object中,再进行传递。
interface传递可以很好地解决了连接硬件世界和软件世界
而在之前SV验证模块中,虽然SV可以通过层次化的interface的索引来完成了传递,但是这种方式不利于软件环境的封装和复用
UVM的uvm_config_db使得接口的传递和获取彻底分离开来。
说明:简单理解就是uvm_config_db做为一个容器,然后把要传递的interface在run_test()之前set进这个容器中,然后在底层的build_phase阶段get到放进容器的interface即完成了传递,相比于sv中接口的传递来说:
1、减少了层层传递,UVM中可以随意层次之间传递;
2、SV中传递建立在底层创建之后,而UVM恰恰相反,在底层创建之前,完成传递即可。
在实现接口传递的过程中需要注意:
接口传递应该发生在run test()之前。这保证了在进入build phase之前virtuali nterface已经被传递到uvm_config_db中。
用户应当把interface与virtual interface的声明区分开来,在传递过程中的类型应当virtual interface,实际接口的句柄
————————————————
3.config object对象传递(重要)
在test配置中,需要配置的参数不只是数量多,可能还分属于不同的组件。对这么多层次的变量做出类似上边的单一变量传递,需要更多的代码,容易出错且不易复用。如果整合各个组件中的变量,将其放置在一个uvm_object中,再对中心化的配置对象进行传递,将有利于整体环境的修改维护,体改代码的复用性。
1set与get各自用该放在哪里
set与get一般都成对出现。
set:自顶层向下set,如从top_tb向driver设置参数,即在top_tb中set。
uvm_config_db#(int)::set(this, “env.agt.drv”, “num”, 100);
第一个参数this与第二个参数“env.agt.drv”——构成目标路径;因此也可以为(this.env, “agt.drv”, “num”, 100)
第三个参数是传给该路径的哪个成员;
第四个参数是要设置的值。
get:从底层向顶层get,如从driver中的build_phase使用get。
uvm_config_db#(int)::get(this, “”,“num”, pre_num);
第一个参数必须是uvm_component实例的指针,第二个参数是相对此实例的路径。一般的,如果第一个参数被设置成this,第二个参数可以是一个空的字符串。
第三个参数要与set中的第三个参数严格一致。
第四个参数是要设置的值。
有些情况下get可以省略:
这里的关键在于:build_phase中的super.build_phase语句,当执行到driver的的super.build_phase时,会自动执行get语句。
config 机制建议
在使用set()/get()方法时,传递的参数类型应当保持一致。对于uvm_object等实例的传递,如果get类型和set类型不一致,应当首先通过$cast()完成类型转换,再对类型转换后的对象进行操作。
在参数传递时,“”表示默认当前层次,也可以使用通配符 * 来表示任意层次。需要注意“*.comp”与“*comp”的区别,前者表示在当前层次下所有名称为“comp”的组件,而后者表示包括当前层次以及当前层次以下所有名为“comp”的组件。
在module环境中使用uvm_config_db::set(),则传递的第一个参数一般用来表示当前的层次(用this表示),此时第二个参数为相对路径;如果当前层次为最高层,用户可以设置为null(module模块,非类不可以用this),此时第二个参数为绝对路径(uvm_test_top.xxx);也可以设置为uvm_root::get()来表示uvm_root的全局顶层实例。
在使用uvm_config_db::get()方法时,添加便于调式的语句。例如通过UVM报告信息得知get()方法中配置的变量是否从uvm_config_db获取到,如果没有获取到,是否采取其他必要措施。
在set()方法第一个参数使用当前层次的前提下,对于同一组件的同一变量,如果有多个高层组件对该变量进行配置,那么较高层组件的配置会覆盖较低层的配置;但是如果是同一层次组件对该变量进行配置时,应当遵循后面的配置覆盖前面的配置。