[CU]config_db机制2-uvm_resource_pool/uvm_resource/uvm_resource_db/uvm_config_db常用函数

注1:该篇文章主要涉及config_db机制的一些函数;

1.资源的写入

1.1. uvm_resource_pool

1.1.1. uvm_resource_pool.get

 1 class uvm_resource_pool;
 2 
 3   static local uvm_resource_pool rp = get();
 4 
 5   uvm_resource_types::rsrc_q_t rtab [string];
 6   uvm_resource_types::rsrc_q_t ttab [uvm_resource_base];
 7 
 8   get_t get_record [$];  // history of gets
 9 
10   local function new();
11   endfunction
12 
13 
14   // Function: get
15   //
16   // Returns the singleton handle to the resource pool
17 
18   static function uvm_resource_pool get();
19     if(rp == null)
20       rp = new();
21     return rp;
22   endfunction
23 
24   ...
25 endclass

1.1.2. uvm_resource_pool.set

set函数主要实现两点功能: 

(1) 把输入参数rsrc插入到rtab的某条记录的队列中,记录的索引是字符串,即资源的名字; 此外,还会根据输入的override参数,决定把rsrc插入到队列的最前面还是最后面;

(2) 把输入参数rsrc插入到ttab的某条记录的队列中,并且也会根据override信息决定把rsrc放在队列的前面还是后面;

 1 class uvm_resource_pool;
 2 
 3   static local uvm_resource_pool rp = get();
 4 
 5   uvm_resource_types::rsrc_q_t rtab [string];
 6   uvm_resource_types::rsrc_q_t ttab [uvm_resource_base];
 7   ...
 8 
 9   // Function: set
10   //
11   // Add a new resource to the resource pool.  The resource is inserted
12   // into both the name map and type map so it can be located by
13   // either.
14   //
15   // An object creates a resources and ~sets~ it into the resource pool.
16   // Later, other objects that want to access the resource must ~get~ it
17   // from the pool
18   //
19   // Overrides can be specified using this interface.  Either a name
20   // override, a type override or both can be specified.  If an
21   // override is specified then the resource is entered at the front of
22   // the queue instead of at the back.  It is not recommended that users
23   // specify the override parameter directly, rather they use the
24   // <set_override>, <set_name_override>, or <set_type_override>
25   // functions.
26   //
27   function void set (uvm_resource_base rsrc, 
28                      uvm_resource_types::override_t override = 0);
29 
30     uvm_resource_types::rsrc_q_t rq;
31     string name;
32     uvm_resource_base type_handle;
33 
34     // If resource handle is ~null~ then there is nothing to do.
35     if(rsrc == null)
36       return;
37 
38     // insert into the name map.  Resources with empty names are
39     // anonymous resources and are not entered into the name map
40     name = rsrc.get_name();     //get_name is the function of uvm_object;
41     if(name != "") begin
42       if(rtab.exists(name))
43         rq = rtab[name];
44       else
45         rq = new();
46 
47       // Insert the resource into the queue associated with its name.
48       // If we are doing a name override then insert it in the front of
49       // the queue, otherwise insert it in the back.
50       if(override & uvm_resource_types::NAME_OVERRIDE)
51         rq.push_front(rsrc);
52       else
53         rq.push_back(rsrc);
54 
55       rtab[name] = rq;
56     end
57 
58     // insert into the type map
59     type_handle = rsrc.get_type_handle();
60     if(ttab.exists(type_handle))
61       rq = ttab[type_handle];
62     else
63       rq = new();
64 
65     // insert the resource into the queue associated with its type.  If
66     // we are doing a type override then insert it in the front of the
67     // queue, otherwise insert it in the back of the queue.
68     if(override & uvm_resource_types::TYPE_OVERRIDE)
69       rq.push_front(rsrc);
70     else
71       rq.push_back(rsrc);
72     ttab[type_handle] = rq;
73 
74   endfunction
75   ...
76 endclass

1.2.uvm_resource

1.2.1.uvm_resource#(T).new

(1) new函数主要实现: (a) 设置scope信息; (b) 设置precedence信息;

 1 virtual class uvm_resource_base extends uvm_object;
 2 
 3   protected string scope;
 4   protected bit modified;
 5   protected bit read_only;
 6 
 7   uvm_resource_types::access_t access[string];
 8 
 9   // variable: precedence
10   //
11   // This variable is used to associate a precedence that a resource
12   // has with respect to other resources which match the same scope
13   // and name. Resources are set to the <default_precedence> initially,
14   // and may be set to a higher or lower precedence as desired.
15 
16   int unsigned precedence;
17 
18   // variable: default_precedence
19   //
20   // The default precedence for an resource that has been created.
21   // When two resources have the same precedence, the first resource
22   // found has precedence.
23   //
24 
25   static int unsigned default_precedence = 1000;
26 
27   // Function: new
28   //
29   // constructor for uvm_resource_base.  The constructor takes two
30   // arguments, the name of the resource and a regular expression which
31   // represents the set of scopes over which this resource is visible.
32 
33   function new(string name = "", string s = "*");
34     super.new(name);
35 set_scope(s); 
36     modified = 0;
37     read_only = 0;
38     precedence = default_precedence;
39   endfunction
40   ...
41 endclass
 1 class uvm_resource #(type T=int) extends uvm_resource_base;
 2 
 3   typedef uvm_resource#(T) this_type;
 4 
 5   // singleton handle that represents the type of this resource
 6   static this_type my_type = get_type();
 7 
 8   // Can't be rand since things like rand strings are not legal.
 9   protected T val;
10 
11   ...
12   function new(string name="", scope="");
13     super.new(name, scope);
14     
15 `ifndef UVM_NO_DEPRECATED
16 begin
17     for(int i=0;i<name.len();i++) begin
18         if(name.getc(i) inside {".","/","[","*","{"}) begin
19             `uvm_warning("UVM/RSRC/NOREGEX", $sformatf("a resource with meta characters in the field name has been created \"%s\"",name))
20             break;
21         end    
22     end    
23 end
24 
25 `endif    
26   endfunction
27   ...
28 endclass

1.2.2.uvm_resource#(T).write

 1 //----------------------------------------------------------------------
 2 // Class: uvm_resource #(T)
 3 //
 4 // Parameterized resource.  Provides essential access methods to read
 5 // from and write to the resource database. 
 6 //----------------------------------------------------------------------
 7 
 8 class uvm_resource #(type T=int) extends uvm_resource_base;
 9 
10   typedef uvm_resource#(T) this_type;
11 
12   // singleton handle that represents the type of this resource
13   static this_type my_type = get_type();
14 
15   // Can't be rand since things like rand strings are not legal.
16   protected T val;
17   ...
18   // Function: write
19   // Modify the object stored in this resource container.  If the
20   // resource is read-only then issue an error message and return
21   // without modifying the object in the container.  If the resource is
22   // not read-only and an ~accessor~ object has been supplied then also
23   // update the accessor record.  Lastly, replace the object value in
24   // the container with the value supplied as the argument, ~t~, and
25   // release any processes blocked on
26   // <uvm_resource_base::wait_modified>.  If the value to be written is
27   // the same as the value already present in the resource then the
28   // write is not done.  That also means that the accessor record is not
29   // updated and the modified bit is not set.
30 
31   function void write(T t, uvm_object accessor = null);
32 
33     if(is_read_only()) begin
34       uvm_report_error("resource", $sformatf("resource %s is read only -- cannot modify", get_name()));
35       return;
36     end
37 
38     // Set the modified bit and record the transaction only if the value
39     // has actually changed.
40     if(val == t)
41       return;
42 
43     record_write_access(accessor);
44 
45     // set the value and set the dirty bit
46     val = t;
47     modified = 1;
48   endfunction
49   ...
50 endclass

1.2.3.uvm_resource#(T).set

 1 class uvm_resource #(type T=int) extends uvm_resource_base;
 2 
 3   typedef uvm_resource#(T) this_type;
 4 
 5   // singleton handle that represents the type of this resource
 6   static this_type my_type = get_type();
 7 
 8   // Can't be rand since things like rand strings are not legal.
 9   protected T val;
10   ...
11   // Function: set
12   //
13   // Simply put this resource into the global resource pool
14 
15   function void set();
16     uvm_resource_pool rp = uvm_resource_pool::get();    //uvm_resource_pool::get();
17     rp.set(this);                                       //uvm_resource_pool::set();
18   endfunction
19   ...
20 endclass

1.2.4.uvm_resource#(T).set_override

(1)调用uvm_resource_pool.set函数,并传入override参数;

 1   // Function: set_override
 2   //
 3   // Put a resource into the global resource pool as an override.  This
 4   // means it gets put at the head of the list and is searched before
 5   // other existing resources that occupy the same position in the name
 6   // map or the type map.  The default is to override both the name and
 7   // type maps.  However, using the ~override~ argument you can specify
 8   // that either the name map or type map is overridden.
 9 
10   function void set_override(uvm_resource_types::override_t override = 2'b11);
11     uvm_resource_pool rp = uvm_resource_pool::get();
12     rp.set(this, override);
13   endfunction

1.3. uvm_resource_db

1.3.1.uvm_resource_db::set

 1   static function void set(input string scope, input string name,
 2                            T val, input uvm_object accessor = null);
 3 
 4     rsrc_t rsrc = new(name, scope);       //uvm_resource#(T).new();
 5     rsrc.write(val, accessor);            //uvm_resource#(T).write();
 6     rsrc.set();                           //uvm_resource#(T).set();
 7 
 8     if(uvm_resource_db_options::is_tracing())
 9       m_show_msg("RSRCDB/SET", "Resource","set", scope, name, accessor, rsrc);
10   endfunction
1 uvm_resource_db#(type)::set("scope", "name", value, accessor);
2 //path=scope+name, default value of accessor is null;
3 uvm_resource_db#(int)::set("test", "loop_cnt", 10, this);
4 
5 uvm_resource_db#(type)::read_by_name("scope", "name", var, accessor); //accessor is not necessary;
6 uvm_resource_db#(type)::read_type("scope", var, accessor);

1.3.2.uvm_resource_db::set_default

(1) 往resource_pool内添加resource. 写入的resource采用的是默认值.

1   static function rsrc_t set_default(string scope, string name);
2 
3     rsrc_t r;
4     
5     r = new(name, scope);            //uvm_resource#(T).new();
6     r.set();                         //uvm_resource#(T).set();
7     return r;
8   endfunction

(2) uvm_resource_db::set()与uvm_resource_db::set_default()的对比: set_default函数与set函数几乎一样,只是没有调用uvm_resource#(T)的write函数. 因此,如果name参数不为空,uvm_resource_pool的rtabttab相应的队列中将各自插入一条记录,否则将只会在ttab的相应队列中插入一条记录.插入的这条记录的val值是默认的值,而没有经过设置,亦即default值.

1.3.3.uvm_resource_db::set_anonymous

 (1)这个函数与set函数相似,唯一区别是实例化rsrc时,输入的名字为空,所以只会向uvm_resource_pool的ttab中插入一条记录,不会向rtab中插入记录.

 1   static function void set_anonymous(input string scope,
 2                                      T val, input uvm_object accessor = null);
 3 
 4     rsrc_t rsrc = new("", scope);     //uvm_resource#(T).new();
 5     rsrc.write(val, accessor);        //uvm_resource#(T).write();
 6     rsrc.set();                       //uvm_resource#(T).set();
 7 
 8     if(uvm_resource_db_options::is_tracing())
 9       m_show_msg("RSRCDB/SETANON","Resource", "set", scope, "", accessor, rsrc);
10   endfunction

1.3.4. uvm_resource_db::set_override()

(1)该函数与uvm_resource_db::set函数比较像,唯一区别是uvm_resource_db::set_override内部调用的是uvm_resource的set_override函数,而不是rsrc的set函数;

 1 //class uvm_resource_db
 2   static function void set_override(input string scope, input string name,
 3                                     T val, uvm_object accessor = null);
 4     rsrc_t rsrc = new(name, scope);
 5     rsrc.write(val, accessor);
 6 rsrc.set_override();
 7 
 8     if(uvm_resource_db_options::is_tracing())
 9       m_show_msg("RSRCDB/SETOVRD", "Resource","set", scope, name, accessor, rsrc);
10   endfunction
1 //class uvm_resource;
2   function void set_override(uvm_resource_types::override_t override = 2'b11);
3     uvm_resource_pool rp = uvm_resource_pool::get();
4 rp.set(this, override);
5   endfunction

(2) uvm_resource#(T)的set_override函数的override参数默认值为2’b11,所以会同时进行NAME_OVERRIDE和TYPE_OVERRIDE.

(3) 如果uvm_resource_db::set_override的name参数不为空,那么uvm_resource_pool的rtab和ttab相应的队列中将各自插入一条记录,否则将会只在ttab的相应队列中插入一条记录.插入的这条记录放在相应队列的最前端.

1.3.5. uvm_resource_db::set_override_type

1   static function void set_override_type(input string scope, input string name,
2                                          T val, uvm_object accessor = null);
3     rsrc_t rsrc = new(name, scope);
4     rsrc.write(val, accessor);
5     rsrc.set_override(uvm_resource_types::TYPE_OVERRIDE);
6 
7     if(uvm_resource_db_options::is_tracing())
8       m_show_msg("RSRCDB/SETOVRDTYP","Resource", "set", scope, name, accessor, rsrc);
9   endfunction

(1) uvm_resource_db::set_override_type与uvm_resource_db::set_override类似,只是内部调用的是uvm_resource#(T)的set_override函数时,传入了TYPE_OVERRIDE参数,从而uvm_resource#(T)的set_override在调用uvm_resource_pool的set函数时,会传入TYPE_OVERRIDE参数.

(2) 函数的执行结果: 如果name参数不为空,那么uvm_resource_pool的rtab和ttab相应的队列中将各自插入一条记录,否则只会在ttab的相应队列中插入一条记录.ttab中插入的这条记录放在相应队列的最前端,而rtab中插入的这条记录(如果插入了)是放在相应队列的最后端.

1.3.6. uvm_resource_db::set_override_name

1   static function void set_override_name(input string scope, input string name,
2                                   T val, uvm_object accessor = null);
3     rsrc_t rsrc = new(name, scope);
4     rsrc.write(val, accessor);
5     rsrc.set_override(uvm_resource_types::NAME_OVERRIDE);
6 
7     if(uvm_resource_db_options::is_tracing())
8       m_show_msg("RSRCDB/SETOVRDNAM","Resource", "set", scope, name, accessor, rsrc);
9   endfunction

(1) uvm_resource_db::set_override_name与uvm_resource_db::set_override_type函数类似,只是在调用uvm_resource#(T)的set_override函数时,传入了NAME_OVERRIDE参数,从而uvm_resource#(T)的set_override在调用uvm_resource_pool的set函数时会传入NAME_OVERRIDE参数.

(2) 函数的执行结果: 如果name参数不为空,那么uvm_resource_pool的rtab和ttab相应的队列中将各自插入一条记录,否则将只会在ttab的相应队列中插入一条记录.ttab中插入的这条记录是放在相应队列的最后端,而rtab中插入的这条记录(假如插入了)是放在相应队列的最前端.

1.3.7. uvm_resource_db::write_by_name()

 1   static function bit write_by_name(input string scope, input string name,
 2                                     input T val, input uvm_object accessor = null);
 3 
 4     rsrc_t rsrc = get_by_name(scope, name);
 5 
 6     if(uvm_resource_db_options::is_tracing())
 7       m_show_msg("RSRCDB/WR","Resource", "written", scope, name, accessor, rsrc);
 8 
 9     if(rsrc == null)
10       return 0;
11 
12     rsrc.write(val, accessor);
13 
14     return 1;
15 
16   endfunction

(1) write_by_name函数并不会在rtab和ttab的相应队列中新插入记录,而是会更新记录. 这里的更新不止更新rtab中相应队列中的相应记录,同时也会更新ttab中相应队列的相应记录.

1.3.8. uvm_resource_db::write_by_type

 1   static function bit write_by_type(input string scope,
 2                                     input T val, input uvm_object accessor = null);
 3 
 4     rsrc_t rsrc = get_by_type(scope);
 5 
 6     if(uvm_resource_db_options::is_tracing())
 7       m_show_msg("RSRCDB/WRTYP", "Resource","written", scope, "", accessor, rsrc);
 8 
 9     if(rsrc == null)
10       return 0;
11 
12     rsrc.write(val, accessor);
13 
14     return 1;
15   endfunction

(1) uvm_resource_db的write_by_type函数与write_by_name函数几乎一样,区别在于前者是根据输入的参数scope查找,后者是根据输入的scope和name查找.

(2) uvm_resource_db::write_by_type和uvm_resource_db::write_by_name都只更新rtab和ttab中相应队列中的记录,而不会向相应队列中插入一条新的记录.

1.3.9.uvm_resource_db::read_by_name && uvm_resource_db::read_by_type

(1)这两个函数比较类似,先通过get_by_type或者get_by_name得到要读取的资源的指针,之后调用uvm_resource#(T)的read函数;

1.4. uvm_config_db

(1) uvm_config_db从uvm_resource_db派生而来,对uvm_resource_db的一些功能进行了扩展,主要体现在对资源的写入和读取上.

(2) 在资源的写入操作上,它重载了uvm_resource_db的set函数;

(3) 在资源的读取操作上, 它新建了一个称为get的函数.

1.4.1. uvm_config_db::set(void函数)

1  static function void set(uvm_component cntxt,
2                            string inst_name,
3                            string field_name,
4                            T value);

(1)使用格式: uvm_config_db#(data type)::set(uvm_component context, string instance_name, string field_name, T value);

(2)使用示例: uvm_config_db#(int)::set(this,"env.agent.sqr","count",10);

1.4.2. uvm_config_db::get(返回值为bit类型函数,返回值常用于判断是否成功get)

 

 1   static function bit get(uvm_component cntxt,
 2                           string inst_name,
 3                           string field_name,
 4                           inout T value);
 5 //TBD: add file/line
 6     int unsigned p;
 7     uvm_resource#(T) r, rt;
 8     uvm_resource_pool rp = uvm_resource_pool::get();
 9     uvm_resource_types::rsrc_q_t rq;
10     uvm_coreservice_t cs = uvm_coreservice_t::get();
11 
12     if(cntxt == null) 
13       cntxt = cs.get_root();
14     if(inst_name == "") 
15       inst_name = cntxt.get_full_name();
16     else if(cntxt.get_full_name() != "") 
17       inst_name = {cntxt.get_full_name(), ".", inst_name};
18  
19     rq = rp.lookup_regex_names(inst_name, field_name, uvm_resource#(T)::get_type());
20     r = uvm_resource#(T)::get_highest_precedence(rq);
21     
22     if(uvm_config_db_options::is_tracing())
23       m_show_msg("CFGDB/GET", "Configuration","read", inst_name, field_name, cntxt, r);
24 
25     if(r == null)
26       return 0;
27 
28     value = r.read(cntxt);
29 
30     return 1;
31   endfunction

 

(1)使用格式:uvm_config_db#(type)::get(uvm_component context, string instance_name, string field_name, inout T variable);

(2)uvm_config_db#(int)::get(this,"",count,count);

1.4.3. uvm_config_db::wait_modified

1   // Function: wait_modified
2   //
3   // Wait for a configuration setting to be set for ~field_name~
4   // in ~cntxt~ and ~inst_name~. The task blocks until a new configuration
5   // setting is applied that effects the specified field.
6 
7   static task wait_modified(uvm_component cntxt, string inst_name,
8       string field_name);

 

1.4.4. uvm_config_db::exists

 

posted on 2021-11-15 14:18  知北游。。  阅读(807)  评论(0编辑  收藏  举报

导航