[CU]config_db机制1-config_db作用,优点及原理

注1:该篇文章涉及的几个关键类: uvm_resource_pool, uvm_resource & uvm_resource_base, uvm_resource_db & uvm_config_db;

注2:该篇文章主要描述config_db机制原理性的内容;

1. 作用,优点

(1) UVM中用于在不同component之间共享资源的一种机制,即实现了资源共享(也可描述为在UVM验证平台间传递参数),又避免了全局变量的弊端.

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

注1:具体应用如将virtual interface传递到环境中(实现DUT与TB的交互)或传递配置对象(config object)到环境或变量的设置(如命令行中设置参数).

2. 原理

问题1: 资源存放在什么地方, 队列/关联数组/动态数组?    

(1) 资源存放在uvm_resource_pool类的关联数组中;

(2) uvm_resources是uvm_resource_pool类的全局唯一实例,用于存储和释放配置资源信息;

复制代码
 1 class uvm_resource_types;
 2 
 3   // types uses for setting overrides
 4   typedef bit[1:0] override_t;
 5   typedef enum override_t { TYPE_OVERRIDE = 2'b01,
 6                             NAME_OVERRIDE = 2'b10 } override_e;
 7 
 8    // general purpose queue of resourcex
 9   typedef uvm_queue#(uvm_resource_base) rsrc_q_t;
10 
11   // enum for setting resource search priority
12   typedef enum { PRI_HIGH, PRI_LOW } priority_e;
13 
14   // access record for resources.  A set of these is stored for each
15   // resource by accessing object.  It's updated for each read/write.
16   typedef struct
17   {
18     time read_time;
19     time write_time;
20     int unsigned read_count;
21     int unsigned write_count;
22   } access_t;
23 
24 endclass
复制代码
复制代码
 //src/base/uvm_resource.svh
1
class uvm_resource_pool; 2 static local uvm_resource_pool rp = get(); 3 4 uvm_resource_types::rsrc_q_t rtab [string]; //name table; 5 uvm_resource_types::rsrc_q_t ttab [uvm_resource_base]; //type table; 6 get_t get_record [$]; // history of gets 7 8 local function new(); 9 endfunction 10 11 12 // Function: get 13 // 14 // Returns the singleton handle to the resource pool 15 16 static function uvm_resource_pool get(); 17 if(rp == null) 18 rp = new(); 19 return rp; 20 endfunction 21 22 ... 23 endclass
复制代码
1 //----------------------------------------------------------------------
2 // static global resource pool handle
3 //----------------------------------------------------------------------
4 const uvm_resource_pool uvm_resources = uvm_resource_pool::get();

(3) uvm_resources中有两个resource数组用于存放配置信息,这两个数组一个是由层次名字索引,一个是由类型索引;

注1: rtab是一个联合数组,索引为string,内容是一个队列;

注2: ttab是关联数组,索引是uvm_resource_base类型,内容也是队列;

1 uvm_resource_types::rsrc_q_t rtab [string];
2 uvm_resource_types::rsrc_q_t ttab [uvm_resource_base];

(4) uvm_config_db::set()通过层次和变量名,将这些信息放置到uvm_pkg唯一的全局变量uvm_pkg::uvm_resources中;

(5) uvm_config_db::get()通过层次,在uvm_resources已有的配置信息池中,索引到该配置;

问题2: 资源以什么形式存放?     

(1) uvm_resource#(type T)类(派生于uvm_resource_base),可以用来存放任意数据的容器数据结构;

(2) uvm_resource中会包含资源名称(name),类型(type),可见范围(scope)和值(value)等信息;

复制代码
 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   ...
42 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   //----------------------
13   // Group: Type Interface
14   //----------------------
15   //
16   // Resources can be identified by type using a static type handle.
17   // The parent class provides the virtual function interface
18   // <get_type_handle>.  Here we implement it by returning the static type
19   // handle.
20 
21   // Function: get_type
22   //
23   // Static function that returns the static type handle.  The return
24   // type is this_type, which is the type of the parameterized class.
25 
26   static function this_type get_type();
27     if(my_type == null)
28       my_type = new();
29     return my_type;
30   endfunction
31   ...
32 endclass
复制代码
复制代码
 1 class uvm_resource #(type T=int) extends uvm_resource_base;
 2 
 3   typedef uvm_resource#(T) this_type;
 4 
 5   ...
 6   // Function: get_by_name
 7   //
 8   // looks up a resource by ~name~ in the name map. The first resource
 9   // with the specified name, whose type is the current type, and is
10   // visible in the specified ~scope~ is returned, if one exists.  The
11   // ~rpterr~ flag indicates whether or not an error should be reported
12   // if the search fails.  If ~rpterr~ is set to one then a failure
13   // message is issued, including suggested spelling alternatives, based
14   // on resource names that exist in the database, gathered by the spell
15   // checker.
16 
17   static function this_type get_by_name(string scope,
18                                         string name,
19                                         bit rpterr = 1);
20 
21     uvm_resource_pool rp = uvm_resource_pool::get();
22     uvm_resource_base rsrc_base;
23     this_type rsrc;
24     string msg;
25 
26     rsrc_base = rp.get_by_name(scope, name, my_type, rpterr);
27     if(rsrc_base == null)
28       return null;
29 
30     if(!$cast(rsrc, rsrc_base)) begin
31       if(rpterr) begin
32         $sformat(msg, "Resource with name %s in scope %s has incorrect type", name, scope);
33         `uvm_warning("RSRCTYPE", msg);
34       end
35       return null;
36     end
37 
38     return rsrc;
39     
40   endfunction
41 
42   // Function: get_by_type
43   //
44   // looks up a resource by ~type_handle~ in the type map. The first resource
45   // with the specified ~type_handle~ that is visible in the specified ~scope~ is
46   // returned, if one exists. If there is no resource matching the specifications,
47   // ~null~ is returned.
48 
49   static function this_type get_by_type(string scope = "",
50                                         uvm_resource_base type_handle);
51 
52     uvm_resource_pool rp = uvm_resource_pool::get();
53     uvm_resource_base rsrc_base;
54     this_type rsrc;
55     string msg;
56 
57     if(type_handle == null)
58       return null;
59 
60     rsrc_base = rp.get_by_type(scope, type_handle);
61     if(rsrc_base == null)
62       return null;
63 
64     if(!$cast(rsrc, rsrc_base)) begin
65       $sformat(msg, "Resource with specified type handle in scope %s was not located", scope);
66       `uvm_warning("RSRCNF", msg);
67       return null;
68     end
69 
70     return rsrc;
71 
72   endfunction
73 
74   ...
75 endclass
复制代码

题3: 资源如何存取? 怎么通过set函数把要共享的资源放入要存放的地方,怎么使用get函数把资源从存放的地方取出? 

(1) uvm_resource_db#(type T)类;

复制代码
 1 class uvm_resource_db #(type T=uvm_object);
 2 
 3   typedef uvm_resource #(T) rsrc_t;
 4 
 5   protected function new();
 6   endfunction
 7 
 8   // function: get_by_type
 9   //
10   // Get a resource by type.  The type is specified in the db
11   // class parameter so the only argument to this function is the
12   // ~scope~.
13 
14   static function rsrc_t get_by_type(string scope);
15     return rsrc_t::get_by_type(scope, rsrc_t::get_type());
16   endfunction
17 
18   // function: get_by_name
19   //
20   // Imports a resource by ~name~.  The first argument is the current 
21   // ~scope~ of the resource to be retrieved and the second argument is
22   // the ~name~. The ~rpterr~ flag indicates whether or not to generate
23   // a warning if no matching resource is found.
24 
25   static function rsrc_t get_by_name(string scope,
26                                      string name,
27                                      bit rpterr=1);
28 
29     return rsrc_t::get_by_name(scope, name, rpterr);
30   endfunction  // function: read_by_name
31   //
32   // locate a resource by ~name~ and ~scope~ and read its value. The value 
33   // is returned through the output argument ~val~.  The return value is a bit 
34   // that indicates whether or not the read was successful. The ~accessor~
35   // is used for auditing.
36   static function bit read_by_name(input string scope,
37                                    input string name,
38                                    inout T val, input uvm_object accessor = null);
39 
40     rsrc_t rsrc = get_by_name(scope, name);  //retrieve uvm_resource;
41 
42     if(uvm_resource_db_options::is_tracing())
43       m_show_msg("RSRCDB/RDBYNAM","Resource", "read", scope, name, accessor, rsrc);
44 
45     if(rsrc == null)
46       return 0;
47 
48     val = rsrc.read(accessor);              //retrieve value stored in uvm_resource;
49 
50     return 1;
51   
52   endfunction
53 
54   // function: read_by_type
55   //
56   // Read a value by type.  The value is returned through the output
57   // argument ~val~.  The ~scope~ is used for the lookup. The return
58   // value is a bit that indicates whether or not the read is successful.
59   // The ~accessor~ is used for auditing.
60   static function bit read_by_type(input string scope,
61                                    inout T val,
62                                    input uvm_object accessor = null);
63     
64     rsrc_t rsrc = get_by_type(scope);     //retrieve uvm_resource;
65 
66     if(uvm_resource_db_options::is_tracing())
67       m_show_msg("RSRCDB/RDBYTYP", "Resource","read", scope, "", accessor, rsrc);
68 
69     if(rsrc == null)
70       return 0;
71 
72     val = rsrc.read(accessor);            //retrieve value stored in uvm_resource;
73 
74     return 1;
75 
76   endfunction
77 
78   ...
79 endclass
复制代码

2.1. 资源共享所记录的信息

(1) 以uvm_config_db#(int)::set(this, “tb.env.agent.driver”, “ifg_num”, 8)为例:

问题1: 资源的类型?        int;

问题2: 谁进行了资源的存放(由最顶层的case,还是tb,还是env)?     this,即顶层的case;

问题3: 这个资源要共享给谁?  tb.env.agent.driver(对应uvm_resource new函数中的scope), ifg_num(对应uvm_resource new函数中的name); 

问题4: 共享资源的值?    8.

复制代码
class uvm_config_db#(type T=int) extends uvm_resource_db#(T);

  ...
  static function void set(uvm_component cntxt,
                           string inst_name,
                           string field_name,
                           T value);

    uvm_root top;
    uvm_phase curr_phase;
    uvm_resource#(T) r;
    bit exists;
    string lookup;
    uvm_pool#(string,uvm_resource#(T)) pool;
    string rstate;
    uvm_coreservice_t cs = uvm_coreservice_t::get();
     
    //take care of random stability during allocation
    process p = process::self();
    if(p != null) 
          rstate = p.get_randstate();
          
    top = cs.get_root();

    curr_phase = top.m_current_phase;

    if(cntxt == null) 
      cntxt = top;
    if(inst_name == "") 
      inst_name = cntxt.get_full_name();
    else if(cntxt.get_full_name() != "") 
      inst_name = {cntxt.get_full_name(), ".", inst_name};

    if(!m_rsc.exists(cntxt)) begin
      m_rsc[cntxt] = new;
    end
    pool = m_rsc[cntxt];

    // Insert the token in the middle to prevent cache
    // oddities like i=foobar,f=xyz and i=foo,f=barxyz.
    // Can't just use '.', because '.' isn't illegal
    // in field names
    lookup = {inst_name, "__M_UVM__", field_name};

    if(!pool.exists(lookup)) begin
       r = new(field_name, inst_name);
       pool.add(lookup, r);
    end
    else begin
      r = pool.get(lookup);
      exists = 1;
    end
      
    if(curr_phase != null && curr_phase.get_name() == "build")
      r.precedence = uvm_resource_base::default_precedence - (cntxt.get_depth());
    else
      r.precedence = uvm_resource_base::default_precedence;

    r.write(value, cntxt);

    if(exists) begin
      uvm_resource_pool rp = uvm_resource_pool::get();
      rp.set_priority_name(r, uvm_resource_types::PRI_HIGH);
    end
    else begin
      //Doesn't exist yet, so put it in resource db at the head.
      r.set_override();
    end

    //trigger any waiters
    if(m_waiters.exists(field_name)) begin
      m_uvm_waiter w;
      for(int i=0; i<m_waiters[field_name].size(); ++i) begin
        w = m_waiters[field_name].get(i);
        if(uvm_re_match(uvm_glob_to_re(inst_name),w.inst_name) == 0)
           ->w.trigger;  
      end
    end

    if(p != null)
        p.set_randstate(rstate);

    if(uvm_config_db_options::is_tracing())
      m_show_msg("CFGDB/SET", "Configuration","set", inst_name, field_name, cntxt, r);
  endfunction

  ...
endclass
复制代码

(2) 与以上记录内容相对应的变量如下:

(2.1) uvm_resource_base中有一个整型变量int unsigned precedence来存放优先级信息.

(2.2) uvm_resource_base中有一个字符串变量scope用来存放目标路径信息,即protected string scope;

(2.3) uvm_resource#(type T)中有一个变量val用来存放变量值,即protected T val.

2.2. uvm_resource #(type T) (资源的存放形式)

(1)uvm_resource是uvm_resource_base的参数化子类;

复制代码
 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 endclass
复制代码

(2) uvm_resource在uvm_resource_base的基础上又添加了一个value成员变量,之所以放到uvm_resource中,是因为uvm_resource创建时已经知道了资源的类型;

复制代码
 1 //----------------------------------------------------------------------
 2 // Class: uvm_resource_base
 3 //
 4 // Non-parameterized base class for resources.  Supports interfaces for
 5 // scope matching, and virtual functions for printing the resource and
 6 // for printing the accessor list
 7 //----------------------------------------------------------------------
 8 
 9 virtual class uvm_resource_base extends uvm_object;
10 
11   protected string scope;
12   protected bit modified;
13   protected bit read_only;
14 
15   uvm_resource_types::access_t access[string];
16 
17   // variable: precedence
18   //
19   // This variable is used to associate a precedence that a resource
20   // has with respect to other resources which match the same scope
21   // and name. Resources are set to the <default_precedence> initially,
22   // and may be set to a higher or lower precedence as desired.
23 
24   int unsigned precedence;
25 
26   // variable: default_precedence
27   //
28   // The default precedence for an resource that has been created.
29   // When two resources have the same precedence, the first resource
30   // found has precedence.
31   //
32 
33   static int unsigned default_precedence = 1000;
34   ...
35 
36 endclass
复制代码

2.2.1. uvm_resource_base

(1) uvm_resource_base是资源的非参数化基类,它描述一个资源该有的属性,包括资源的名字(name),可见范围(scope,定义哪些层次范围内能看到该资源),只读属性(read-only)、修改标记(modified)、访问记录表(access[string],string记录访问者的名字,value包含访问者对该资源的读写次数和最近一次的读写时间)以及优先级(precedence).

2.2.2. functions/tasks of resource

复制代码
  1 class uvm_resource #(type T=int) extends uvm_resource_base;
  2   ...
  3   // Function: get_by_name
  4   //
  5   // looks up a resource by ~name~ in the name map. The first resource
  6   // with the specified name, whose type is the current type, and is
  7   // visible in the specified ~scope~ is returned, if one exists.  The
  8   // ~rpterr~ flag indicates whether or not an error should be reported
  9   // if the search fails.  If ~rpterr~ is set to one then a failure
 10   // message is issued, including suggested spelling alternatives, based
 11   // on resource names that exist in the database, gathered by the spell
 12   // checker.
 13 
 14   static function this_type get_by_name(string scope,
 15                                         string name,
 16                                         bit rpterr = 1);
 17 
 18     uvm_resource_pool rp = uvm_resource_pool::get();
 19     uvm_resource_base rsrc_base;
 20     this_type rsrc;
 21     string msg;
 22 
 23     rsrc_base = rp.get_by_name(scope, name, my_type, rpterr);
 24     if(rsrc_base == null)
 25       return null;
 26 
 27     if(!$cast(rsrc, rsrc_base)) begin
 28       if(rpterr) begin
 29         $sformat(msg, "Resource with name %s in scope %s has incorrect type", name, scope);
 30         `uvm_warning("RSRCTYPE", msg);
 31       end
 32       return null;
 33     end
 34 
 35     return rsrc;
 36     
 37   endfunction
 38   // Function: get_by_type
 39   //
 40   // looks up a resource by ~type_handle~ in the type map. The first resource
 41   // with the specified ~type_handle~ that is visible in the specified ~scope~ is
 42   // returned, if one exists. If there is no resource matching the specifications,
 43   // ~null~ is returned.
 44 
 45   static function this_type get_by_type(string scope = "",
 46                                         uvm_resource_base type_handle);
 47 
 48     uvm_resource_pool rp = uvm_resource_pool::get();
 49     uvm_resource_base rsrc_base;
 50     this_type rsrc;
 51     string msg;
 52 
 53     if(type_handle == null)
 54       return null;
 55 
 56     rsrc_base = rp.get_by_type(scope, type_handle);
 57     if(rsrc_base == null)
 58       return null;
 59 
 60     if(!$cast(rsrc, rsrc_base)) begin
 61       $sformat(msg, "Resource with specified type handle in scope %s was not located", scope);
 62       `uvm_warning("RSRCNF", msg);
 63       return null;
 64     end
 65 
 66     return rsrc;
 67 
 68   endfunction
 69 
 70   //----------------------------
 71   // Group: Read/Write Interface
 72   //----------------------------
 73   //
 74   // <read> and <write> provide a type-safe interface for getting and
 75   // setting the object in the resource container.  The interface is
 76   // type safe because the value argument for <write> and the return
 77   // value of <read> are T, the type supplied in the class parameter.
 78   // If either of these functions is used in an incorrect type context
 79   // the compiler will complain.
 80 
 81   // Function: read
 82   //
 83   // Return the object stored in the resource container.  If an ~accessor~
 84   // object is supplied then also update the accessor record for this
 85   // resource.
 86 
 87   function T read(uvm_object accessor = null);
 88     record_read_access(accessor);
 89     return val;
 90   endfunction
 91 
 92   // Function: write
 93   // Modify the object stored in this resource container.  If the
 94   // resource is read-only then issue an error message and return
 95   // without modifying the object in the container.  If the resource is
 96   // not read-only and an ~accessor~ object has been supplied then also
 97   // update the accessor record.  Lastly, replace the object value in
 98   // the container with the value supplied as the argument, ~t~, and
 99   // release any processes blocked on
100   // <uvm_resource_base::wait_modified>.  If the value to be written is
101   // the same as the value already present in the resource then the
102   // write is not done.  That also means that the accessor record is not
103   // updated and the modified bit is not set.
104 
105   function void write(T t, uvm_object accessor = null);
106 
107     if(is_read_only()) begin
108       uvm_report_error("resource", $sformatf("resource %s is read only -- cannot modify", get_name()));
109       return;
110     end
111 
112     // Set the modified bit and record the transaction only if the value
113     // has actually changed.
114     if(val == t)
115       return;
116 
117     record_write_access(accessor);
118 
119     // set the value and set the dirty bit
120     val = t;
121     modified = 1;
122   endfunction
123 
124   ...
125 endclass
复制代码

2.3. uvm_resource_pool (资源放在什么地方)

复制代码
 1 //----------------------------------------------------------------------
 2 // Class: uvm_resource_pool
 3 //
 4 // The global (singleton) resource database.
 5 //
 6 // Each resource is stored both by primary name and by type handle.  The
 7 // resource pool contains two associative arrays, one with name as the
 8 // key and one with the type handle as the key.  Each associative array
 9 // contains a queue of resources.  Each resource has a regular
10 // expression that represents the set of scopes over which it is visible.
复制代码
1 // The scope is stored in the resource itself (not in the pool) so
2 // whether you get by name or by type the resource's visibility is
3 // the same.

(1) resource pool包含两个关联数组,一个用名字作为索引,一个用类型作为索引; 每个索引对应的值都是一个resources队列;

(2)每一个resource都通过名字和type进行存储;

(3)每一个resource都有一个正则表达式,用于代表哪些范围可见该资源; scope信息存储在resource内,所以无论是通过get_by_name还是get_by_type, resource的scope是相同的;

复制代码
 1 //
 2 //|  +------+------------+                          +------------+------+
 3 //|  | name | rsrc queue |                          | rsrc queue | type |
 4 //|  +------+------------+                          +------------+------+
 5 //|  |      |            |                          |            |      |
 6 //|  +------+------------+                  +-+-+   +------------+------+
 7 //|  |      |            |                  | | |<--+---*        |  T   |
 8 //|  +------+------------+   +-+-+          +-+-+   +------------+------+
 9 //|  |  A   |        *---+-->| | |           |      |            |      |
10 //|  +------+------------+   +-+-+           |      +------------+------+
11 //|  |      |            |      |            |      |            |      |
12 //|  +------+------------+      +-------+  +-+      +------------+------+
13 //|  |      |            |              |  |        |            |      |
14 //|  +------+------------+              |  |        +------------+------+
15 //|  |      |            |              V  V        |            |      |
16 //|  +------+------------+            +------+      +------------+------+
17 //|  |      |            |            | rsrc |      |            |      |
18 //|  +------+------------+            +------+      +------------+------+
19 //
复制代码

(4)上面方框图展示了一个名字为A,类型为T的资源在resource_pool内是怎么存储的;

(4.1) 对于type T, resource_pool在type map内包含一个与之对应的entry; 对于name A, resource_pool在name type内包含一个与之对应的entry;

(4.2) resource_pool的两个关联数组的queue里面都会包含一个 resource entry,该resource的name为A, type为T;

(4.3) name_map中,对于索引为A的resource queue,其内部可能包含名字为A,但类型可能是T也可能不是T的资源; 类似地, type map中,对于索引为T的resource queue,其内部可能包含类型为T,但名字可能是A也可能不是A的资源;

(5) 可以通过调用resource_pool.set将资源添加到pool中,通过调用get_by_type或者get_by_name可以从resource_pool中获取该resource;

2.3.1. functions/tasks of resource_pool

 

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

2.3.2 uvm_resource_types

 

 

2.4. uvm_resource_db(访问存在uvm_resource_pool中的uvm_resource/资源的接口)

 

复制代码
1 // The <uvm_resource_db> class provides a convenience interface for
2 // the resources facility.  In many cases basic operations such as
3 // creating and setting a resource or getting a resource could take
4 // multiple lines of code using the interfaces in <uvm_resource_base> or
5 // <uvm_resource#(T)>.  The convenience layer in <uvm_resource_db>
6 // reduces many of those operations to a single line of code.
7 //
8 // If the run-time ~+UVM_RESOURCE_DB_TRACE~ command line option is
9 // specified, all resource DB accesses (read and write) are displayed.
复制代码

(1) 资源的存取可以通过uvm_resource_db类实现;相较于直接使用uvm_resource_base或者uvm_resource的方法,通过使用uvm_resource_db提供的静态方法可以容易实现资源的存取;

以uvm_resource_db::set为例描述,uvm_resource_db::set实现往uvm_resource_pool中写入资源,set函数的四个参数:scope表示路径信息; name表示名字; val表示共享的资源;

复制代码
 1 class uvm_resource_db #(type T=uvm_object);
 2 
 3   ...
 4   // function: set
 5   //
 6   // Create a new resource, write a ~val~ to it, and set it into the
 7   // database using ~name~ and ~scope~ as the lookup parameters. The
 8   // ~accessor~ is used for auditing.
 9   static function void set(input string scope, input string name,
10                            T val, input uvm_object accessor = null);
11 
12     rsrc_t rsrc = new(name, scope);     //typedef uvm_resource #(T) rsrc_t;
13     rsrc.write(val, accessor);          //uvm_resource.write();
14     rsrc.set();                         //put uvm_resource into uvm_resource_pool;        
15 
16     if(uvm_resource_db_options::is_tracing())
17       m_show_msg("RSRCDB/SET", "Resource","set", scope, name, accessor, rsrc);
18   endfunction
19   ...
20 endclass
复制代码

(2) 该类的所有成员变量都是静态的,所以,是否实例化并不重要.

2.4.1. functions/tasks of uvm_resource_db

 

 

2.5. uvm_config_db(访问存在uvm_resource_pool中的uvm_resource/资源的接口)

 

 

 

posted on   知北游。。  阅读(1048)  评论(0编辑  收藏  举报

编辑推荐:
· .NET 依赖注入中的 Captive Dependency
· .NET Core 对象分配(Alloc)底层原理浅谈
· 聊一聊 C#异步 任务延续的三种底层玩法
· 敏捷开发:如何高效开每日站会
· 为什么 .NET8线程池 容易引发线程饥饿
阅读排行:
· .NET 9.0 使用 Vulkan API 编写跨平台图形应用
· 终于决定:把自己家的能源管理系统开源了!
· [.NET] 使用客户端缓存提高API性能
· AsyncLocal的妙用
· .NetCore依赖注入(DI)之生命周期
< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8

导航

统计

点击右上角即可分享
微信分享提示