这部分我们将要详细介绍uvm_config_db机制时如何解决uvm_resource_db机制带来的弊端的
首先我们来看看uvm_config_db是如何工作的,
两个核心方法set和get
package UVM_cmd;
import uvm_pkg::*'
`include "uvm_macros.svh"
class unit_agent extends uvm_agent;
int A=10;
int i;
local int b;
uvm_resource#(int) re;
uvm_resource_types::rsrc_q_t rq;
uvm_resource_pool rp;
`uvm_component_utils(unit_agent)
function new(string name);
super.new(name);
endfunction
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
re=uvm_resource#(int)::get_type();
rp=uvm_resource_pool::get();
rq=rp.lookup_name("abcd","A",re);
`uvm_info("INT",$sformatf("before the config the a is %d",A),UVM_LOW)
if(!uvm_config_db#(int)::get(this,"",“A”,A))
`uvm_error("error","the read is error")
else
`uvm_info("INT",$sformatf("after the config the a is %d",A),UVM_LOW)
`uvm_info("precedence",$sformatf("the precedence is %d",re.precednce),UVM_LOW)
`uvm_info("size",$sformatf("the size is %d",rq.size()),UVM_LOW)
while(rq.size()>0)begin
uvm_resource_base n;
uvm_resource#(int) n1;
n-rq.pop_front();
if(n!=null) begin
`void($cast(n1,n))
`uvm_info("precedence",$sformatf("the precedence is %d",n.precedence),UVM_LOW)
`uvm_info("precedence",$sformatf("the data is %d",n1.read()),UVM_LOW)
end
end
endfunction
function int ret();
return b;
endfunction
endclass
class unit_agent_child extends unit_agent;
`uvm_component_utils(unit_agent_child)
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
endfunction
endclass
class unit_env extends uvm_env;
unit_agent un;
unit_agent_child un_ch;
`uvm_component_utils(unit_env)
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this,"un","A",20);
//un=unit_agent::type_id::create("un",this);
//un_ch=unit_agent_child::type_id::create("un_ch",this);
endfunction
endclass
class my_test extends uvm_test;
unit_env env;;
`uvm_component_utils(my_test)
function new(string name,uvm_component parent);
super.new(name,parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
uvm_config_db#(int)::set(this,"env.un","A",30);
uvm_config_db#(int)::set("this","env.un","A",40);
env=unit_env::type_id::create("env",this);
endfunction
endclass
endpackage
例子如上
首先调用set方法.顺序依次是
uvm_config_db#(int)::set(this,“env.un”,“A”,30)
uvm_config_db#(int)::set(this,“env.un”,“A”,40)
uvm_config_db#(int)::set(this,“un”,“A”,20)
我们还是要追踪uvm_resource_pool中关键的变量
uvm_queues#(uvm_resource_base) rtab[string]
第一次调用是在uvm_test中调用
uvm_config_db#(int)::set(this,“env.un”,“A”,30)
会穿件一个scope是uvm_test_top.env.un,name是"A",类型是int的一个资源,在例化uvn_test_top时,depth是1,那么第一个资源的优先级=default_precedence-1=999;
这是时候uvm_queues#(uvm_resource_base) rtab[string]出现元素是
rtab[“A”]
接着再uvm_test中调用第二次set
uvm_config_db#(int)::set(this,“env.un”,“A”,40)
这个时候第二个资源的优先级依旧是999,但是插入到rtab[“A”]的方式时push_front,不是push_back(本质上调用set_override的方法)
最后再uvm_env中第三次调用了set方法
uvm_config_db#(int)::set(this,“un”,“A”,20)
这个时候,这个资源的优先级时998
上面完成了3个资源的插入
在uvm_agent中调用 uvm_config_db#(int)::get(this,"",“A”,A),这样子就可以取到合适的资源(与uvm_resource_db的read_by_name机制一样,这里就不多介绍。
注:只有在build_phase中调用uvm_config_db::set方法在可以实现上述的效果,得到我们想要的结果,这里符合UVM-phase的工作机制,在使用的过程中要在build-phase中set,(当然纯粹为了学习乐趣的话,当你深入了解之后,可以尝试在别的地方set)。