1.用途
config_db机制用于在UVM验证平台间转达参数,通常成对出现,其中set相当于寄信,get相当于收信。UVM提供的config_db机制可在组件实例化前就设定好设置信息,这样就可在tb的initial块中就进行设定了。真正将这些设置信息落实在各component,是在testbench运行过程build_phase中。
2.config_db参数
用法很简单,先使用uvm_config_db::set()将设置信息写好,相应的component使用uvm_config_db::get()获取设置信息,整个过程雷同寄信"和“收信”。例如:
- class uvm_config_db#(type T=int) extends uvm_resource_db#(T);
- ...
- static function bit get(uvm_component cntxt,
- string inst_name,
- string field_name,
- inout T value);
- ...
- static function void set(uvm_component cntxt,
- string inst_name,
- string field_name,
- T value);
- static function bit exists(uvm_component cntxt, string inst_name,
- string field_name, bit spell_chk=0);
- ...
- endclass
复制代码 那么它的几个参数详细指的是什么呢?
Type T:要设置的成员类型,默认为int;
uvm_component cntxt : set或get方法的发起者component,必须是一个component实例的指针;
string inst_name:从发起者component到要设置的目标component,在UVM树中的索引路径,这和上面一个参数联合构成了目标路径;
string field_name:域名称,一种标志,但一般为要设置的成员变量名;
T value: set方法中,表示将要为field_name成员设定的值。在get方法中,表示要赋值的成员。
来看一个例子:
- function void my_test::build_phase(uvm_phase phase);
- super.build_phase(phase);
- env = my_env::type_id_create("env",this);
- uvm_config_db#(int)::set(this,"env.i_agt.drv","pre_num",100);
- //以下均是为目标drv的pre_num配置100
- //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",100);
- //uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",100);
- ...
- endfunction
- function void my_driver::build_phase(uvm_phase phase);
- super.build_phase(phase);
- if(!uvm_config_db#(int)::get(this,"","pre_num",pre_num))
- uvm_report_info("CONFIG","PRE_NUM CONFIG FAILED!",UVM_LOW);
-
- //uvm_config_db#(int)::get(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",pre_num);
- //uvm_config_db#(int)::get(uvm_test_top,"env.i_agt.drv","pre_num",pre_num);
- ...
- endfunction
复制代码 对于几个差别的set语句,均是对pre_num进行100的配值,区别在于发起的component差别;而对差别的get来说 uvm_config_db#(int)::get(this,"","pre_num",pre_num)表示每创建一个my_driver对象都要为自己的pre_num成员get一个配值;而后两句get语句则表示只会为my_driver类对象drv的pre_num成员get一个配值。
3.多重设定
上面的代码引申出一个问题,当有多个set配值时,应该听谁的话呢?原则为:发起者层次越高,优先级越高;发起时间越晚,优先级越高。
- function void my_driver::build_phase(uvm_phase phase);
- super.build_phase(phase);
- uvm_config_db#(int)::get(this,"","pre_num",pre_num);
- ...
- endfunction
- function void my_test::build_phase(uvm_phase phase);
- super.build_phase(phase);
- uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",500);
- 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",999);
- ...
- endfunction
- function void my_env::build_phase(uvm_phase phase);
- super.build_phase(phase);
- uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.i_agt.drv","pre_num",200);
- ...
- endfunction
复制代码 在上面的代码中pre_num成员终极会被赋值为200,这是由于:发起者中层次最高的是第一句和最后一句的uvm_top(第二句是uvm_test_top,第三句是env,对层次了解不清楚可查阅uvm component树),而第四句的赋值时间晚于第一句,因此具有最高优先级,将pre_num成员终极会赋值为200。
假如是多次get呢?config机制允许set一次然后多次get,也就是说并不是get之后UVM就删除了该记录。
4.推荐用法
虽然set可以有多种多样的写法,一般来说,我们还是推荐固定写法:将发起者直接定为this。
- uvm_config_db#(int)::set(this,"env.i_agt.drv","pre_num",100);
- uvm_config_db#(int)::get(this,"","pre_num",pre_num);
复制代码 这样对我们来说也简单省事,直接一个this搞定,让uvm_test_top在build_phase中完成所有的参数设置。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |