九天猎人 发表于 前天 08:39

UVM-config_db机制和用法

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企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: UVM-config_db机制和用法