UVM配置之resource机制(2)

这部分我们将要详细介绍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)。


版权声明:本文为liuwei848原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。