config db
用法:
- 传递virtual interface到环境中;
- 配置单一变量值,例如int、string、enum等;
- 传递配置对象(config_object)到环境;
uvm_config_db #(type)::get( //type类型可以是int、string等类型,也可以是接口interface、对象object等类型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**
);
- 在使用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的全局顶层实例。
- 在set()方法第一个参数使用当前层次的前提下,对于同一组件的同一变量,如果有多个高层组件对该变量进行配置,那么较高层组件的配置会覆盖较低层的配置;但是如果是同一层次组件对该变量进行配置时,应当遵循后面的配置覆盖前面的配置。
注意⚠️
- 接口传递应发生在run_test()之前。这保证了在进入build_phase之前,virtual interface已经被传递到uvm_config_db中。
- 用户应当把interface与virtual interface区分开来,在传递过程中的类型应当为virtual interface,即实际接口的句柄。
function void build_phase(uvm_phase phase);if(!uvm_config_db #(virtual intf1)::get(this,"","vif",vif)) begin //**3. 获取配置接口vif = intf**`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
其中关于config object 对象传递
我们可以整合各个组件中的变量,将其放置在一个uvm_object中,再对中心化的配置对象进行传递
,将有利于整体环境的修改维护,体改代码的复用性
class config1 extends uvm_object;
//**1. 创建一个配置类,将需要配置的变量放于其中**`uvm_object_utils(config1)int val1 = 1;int str1 = "null";...
endclassclass comp1 extends uvm_component; //组件`uvm_component_utils(comp1)config1 cfg ; //声明配置类句柄...function void build_phase(uvm_phase phase);uvm_object tmp; //声明类句柄uvm_config_db #(uvm_object)::get(this,"","cfg",tmp); //**3. 获取变量配置**void`($cast(cfg,tmp)); //类型转韩,将传到tmp中的值赋给cfg`uvm_info("SETVAL",$sformatf("cfg.val1 is %d after get",cfg.val1),UVM_LOW) `uvm_info("SETVAL",$sformatf("cfg.str1 is %d after get",cfg.str1),UVM_LOW) endfunction
endclassclass test1 extends uvm_test; //测试用例层, 启动配置`uvm_component_utils(test1)comp1 c1, c2;config1 cfg1, cfg2;...function void build_phase(uvm_phase phase);cfg1 = config1::type_id::create("cfg1");cfg2 = config1::type_id::create("cfg2");c1 = comp1::type_id::create("c1"); c2 = comp1::type_id::create("c2"); //创建对象cfg1.val1 = 30;cfg1.str1 = "c1";cfg2.val1 = 50;cfg2.str1 = "c2";uvm_config_db #(uvm_object)::set(this,"c1","cfg",cfg1); //**2. 启动变量配置** uvm_config_db #(uvm_object)::set(this,"c2","cfg",cfg2); //启动变量配置 endfunction
endclass