天天看点

uvm中config_db机制梳理(省略get和跨层次)

1. 关于省略get

假设在环境env的build_phase中进行了config_db::set,目标是agent中driver包含的一个变量num,那么要想在driver的build_phase中省略config_db::get需要满足三点:

(1)这个driver必须用 uvm_component_utils注册;

(2)变量num必须在driver中用uvm_field_int宏进行了域的自动化声明;

(3)set的第三个参数和get的第三个参数以及第四个参数保持一致,即set里第三个参数为num,get里第三第四个参数也为num;

class driver1 extends uvm_driver;

int num;//声明变量

`uvm_component_utils_begin(driver1)//注册和域的自动化
`uvm_field_int(num,UVM_ALL_ON)
`uvm_component_utils_end

function new(string name="driver1",uvm_component parent=null);
super.new(name,parent);

num=5;//赋新值

endfunction

function void build_phase(uvm_phase phase);
`uvm_info("driver1","before super.build_phase, num is %0d",num)
super.build_phase(phase);//满足上述三个条件,则在super.build_phase()时会自动执行config_db::get()
`uvm_info("driver1","after super.build_phase, num is %0d",num)

if(!uvm_config_db#(virtual intereface1)::get(this,"","vif",vif))
`uvm_fatal("driver1","can not get vif handle")
endfunction

endclass
           

2. 关于跨层次

假如对一个层次中的某一变量进行多次set,那么根据不同情况,该变量get的结果不同,有如下两种情况:

(1)后set的决定最后的get结果,先set的忽略;

(2)权威性高的set决定最后的get结果。权威性低的set忽略;

在uvm世界中,采用的是第二种情况,即根据set的权威性来决定最后get的结果。

以如下代码为例:

//在test1中对driver中的变量num进行了设置

class test1 extends uvm_test;
...
function void build_phase(uvm_phase phase);
super.build_phase(phase);

uvm_config_db#(int)::set(this,"env.agt.drv","num",100);
`uvm_info("test1","env.agt.drv.num is set to 100",UVM_LOW)

endfunction
endclass

//在env中也对driver中的变量num进行了设置

class env extends uvm_env;
..
function void build_phase(uvm_phase phase);
super.build_phase(phase);

uvm_config#(int)::set(this,"agt.drv","num",99);
`uvm_info("env","env.agt.drv.num is set to 99",UVM_low)

endfunction
endclass
           

最终的结果,num的值get到100。因为test1的层次高于env,在uvm树中,test1更接近于uvm_top。上述代码的set,可以认为起点就不同,test1的起点是uvm_test_top(test1的实例名),而env就是env(实例化的名字)。

而当变成如下情况:

class test1 extends uvm_test;
...
function void build_phase(uvm_phase phase);
super.build_phase(phase);

uvm_config_db#(int)::set(uvm_root::get(),"uvm_test_top.env.agt.drv","num",100);
`uvm_info("test1","env.agt.drv.num is set to 100",UVM_LOW)

endfunction
endclass


class env extends uvm_env;
..
function void build_phase(uvm_phase phase);
super.build_phase(phase);

uvm_config#(int)::set(uvm_root::get(),"uvm_test_top.env.agt.drv","num",99);
`uvm_info("env","env.agt.drv.num is set to 99",UVM_low)

endfunction
endclass
           

这种情况下最后get的值是99,因set起点都是uvm_top,而build_phase是自顶向下构建,env的set会后发生,会覆盖掉之前test1的set,所以最后值get到99。

因此,在实际使用中,set的第一个参数应尽量使用this,给与不同的set起点(也可以说是权威性)。而在无法得到this指针的情况下(比如top_tb中),使用null(变相设置成uvm_root::get())或者uvm_root::get()。

继续阅读