//----------------------------------------------------------------------
// Copyright 2010-2011 Paradigm Works
// Copyright 2010-2018 Mentor Graphics Corporation
// Copyright 2015 Analog Devices, Inc.
// Copyright 2014 Semifore
// Copyright 2017 Intel Corporation
// Copyright 2010-2014 Synopsys, Inc.
// Copyright 2010-2018 Cadence Design Systems, Inc.
// Copyright 2010-2011 AMD
// Copyright 2013-2018 NVIDIA Corporation
// Copyright 2017-2018 Cisco Systems, Inc.
// Copyright 2011-2012 Cypress Semiconductor Corp.
// Copyright 2017-2018 Verific
//   All Rights Reserved Worldwide
//
//   Licensed under the Apache License, Version 2.0 (the
//   "License"); you may not use this file except in
//   compliance with the License.  You may obtain a copy of
//   the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in
//   writing, software distributed under the License is
//   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
//   CONDITIONS OF ANY KIND, either express or implied.  See
//   the License for the specific language governing
//   permissions and limitations under the License.
//----------------------------------------------------------------------




//----------------------------------------------------------------------
// Class - get_t
//
// Instances of get_t are stored in the history list as a record of each
// get.  Failed gets are indicated with rsrc set to ~null~.  This is part
// of the audit trail facility for resources.
//----------------------------------------------------------------------
class get_t;
  string name;
  string scope;
  uvm_resource_base rsrc;
  time t;
endclass

typedef class uvm_tree_printer ;

// Title: Resources

//----------------------------------------------------------------------
// Class -- NODOCS -- uvm_resource_pool
//
// The global (singleton) resource database.
//
// Each resource is stored both by primary name and by type handle.  The
// resource pool contains two associative arrays, one with name as the
// key and one with the type handle as the key.  Each associative array
// contains a queue of resources.  Each resource has a regular
// expression that represents the set of scopes over which it is visible.
//
//|  +------+------------+                          +------------+------+
//|  | name | rsrc queue |                          | rsrc queue | type |
//|  +------+------------+                          +------------+------+
//|  |      |            |                          |            |      |
//|  +------+------------+                  +-+-+   +------------+------+
//|  |      |            |                  | | |<--+---*        |  T   |
//|  +------+------------+   +-+-+          +-+-+   +------------+------+
//|  |  A   |        *---+-->| | |           |      |            |      |
//|  +------+------------+   +-+-+           |      +------------+------+
//|  |      |            |      |            |      |            |      |
//|  +------+------------+      +-------+  +-+      +------------+------+
//|  |      |            |              |  |        |            |      |
//|  +------+------------+              |  |        +------------+------+
//|  |      |            |              V  V        |            |      |
//|  +------+------------+            +------+      +------------+------+
//|  |      |            |            | rsrc |      |            |      |
//|  +------+------------+            +------+      +------------+------+
//
// The above diagrams illustrates how a resource whose name is A and
// type is T is stored in the pool.  The pool contains an entry in the
// type map for type T and an entry in the name map for name A.  The
// queues in each of the arrays each contain an entry for the resource A
// whose type is T.  The name map can contain in its queue other
// resources whose name is A which may or may not have the same type as
// our resource A.  Similarly, the type map can contain in its queue
// other resources whose type is T and whose name may or may not be A.
//
// Resources are added to the pool by calling <set>; they are retrieved
// from the pool by calling <get_by_name> or <get_by_type>.  When an object 
// creates a new resource and calls <set> the resource is made available to be
// retrieved by other objects outside of itself; an object gets a
// resource when it wants to access a resource not currently available
// in its scope.
//
// The scope is stored in the resource itself (not in the pool) so
// whether you get by name or by type the resource's visibility is
// the same.
//
// As an auditing capability, the pool contains a history of gets.  A
// record of each get, whether by <get_by_type> or <get_by_name>, is stored 
// in the audit record.  Both successful and failed gets are recorded. At
// the end of simulation, or any time for that matter, you can dump the
// history list.  This will tell which resources were successfully
// located and which were not.  You can use this information
// to determine if there is some error in name, type, or
// scope that has caused a resource to not be located or to be incorrectly
// located (i.e. the wrong resource is located).
//
//----------------------------------------------------------------------

// @uvm-ieee 1800.2-2017 auto C.2.4.1
class uvm_resource_pool;

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

  // struct for scope and precedence associated with each resource
  typedef struct { 
     string scope ;
     int unsigned precedence;
  } rsrc_info_t ;
  // table to set/get scope and precedence for resources
  static rsrc_info_t ri_tab [uvm_resource_base];

  get_t get_record [$];  // history of gets

  // @uvm-ieee 1800.2-2017 auto C.2.4.2.1
  function new();
  endfunction


  // Function -- NODOCS -- get
  //
  // Returns the singleton handle to the resource pool

  // @uvm-ieee 1800.2-2017 auto C.2.4.2.2
  static function uvm_resource_pool get();
    uvm_resource_pool t_rp;
    uvm_coreservice_t cs = uvm_coreservice_t::get();
    t_rp = cs.get_resource_pool();
    return t_rp;
  endfunction


  // Function -- NODOCS -- spell_check
  //
  // Invokes the spell checker for a string s.  The universe of
  // correctly spelled strings -- i.e. the dictionary -- is the name
  // map.

  function bit spell_check(string s);
    return uvm_spell_chkr#(uvm_resource_types::rsrc_q_t)::check(rtab, s);
  endfunction

  //-----------
  // Group -- NODOCS -- Set
  //-----------

  // Function -- NODOCS -- set
  //
  // Add a new resource to the resource pool.  The resource is inserted
  // into both the name map and type map so it can be located by
  // either.
  //
  // An object creates a resources and ~sets~ it into the resource pool.
  // Later, other objects that want to access the resource must ~get~ it
  // from the pool
  //
  // Overrides can be specified using this interface.  Either a name
  // override, a type override or both can be specified.  If an
  // override is specified then the resource is entered at the front of
  // the queue instead of at the back.  It is not recommended that users
  // specify the override parameter directly, rather they use the
  // <set_override>, <set_name_override>, or <set_type_override>
  // functions.
  //
`ifdef UVM_ENABLE_DEPRECATED_API
  function void set (uvm_resource_base rsrc, 
                     uvm_resource_types::override_t override = 0);

    // If resource handle is ~null~ then there is nothing to do.
    if (rsrc == null) return ;
    if (override) 
        set_override(rsrc, rsrc.get_scope()) ;
    else
        set_scope(rsrc, rsrc.get_scope()) ; 

  endfunction
`endif //UVM_ENABLE_DEPRECATED_API

  // @uvm-ieee 1800.2-2017 auto C.2.4.3.1
  function void set_scope (uvm_resource_base rsrc, string scope); 

    uvm_resource_types::rsrc_q_t rq;
    string name;
    uvm_resource_base type_handle;
    uvm_resource_base r;
    int unsigned i;

    // If resource handle is ~null~ then there is nothing to do.
    if(rsrc == null) begin
      uvm_report_warning("NULLRASRC", "attempting to set scope of a null resource");
      return;
    end

    // Insert into the name map.  Resources with empty names are
    // anonymous resources and are not entered into the name map
    name = rsrc.get_name();
    if ((name != "") && rtab.exists(name)) begin
      rq = rtab[name];

      for(i = 0; i < rq.size(); i++) begin
        r = rq.get(i);
        if(r == rsrc) begin 
          ri_tab[rsrc].scope = uvm_glob_to_re(scope);
          return ;
        end
      end
    end 

    if (rq == null) 
       rq = new(name);

    // Insert the resource into the queue associated with its name.
    // Insert it with low priority (in the back of queue) .
    rq.push_back(rsrc);

    rtab[name] = rq;

    // Insert into the type map
    type_handle = rsrc.get_type_handle();
    if(ttab.exists(type_handle))
      rq = ttab[type_handle];
    else 
      rq = new();

    // Insert the resource into the queue associated with its type.  
    // Insert it with low priority (in the back of queue) .
    rq.push_back(rsrc);
    ttab[type_handle] = rq;

    // Set the scope of resource. 
    ri_tab[rsrc].scope = uvm_glob_to_re(scope);
    ri_tab[rsrc].precedence = get_default_precedence();

  endfunction


  // Function -- NODOCS -- set_override
  //
  // The resource provided as an argument will be entered into the pool
  // and will override both by name and type.
  // Default value to 'scope' argument is violating 1800.2-2017 LRM, but it
  // is added to make the routine backward compatible

  // @uvm-ieee 1800.2-2017 auto C.2.4.3.2
  function void set_override(uvm_resource_base rsrc, string scope = "");
     string s = scope;
`ifdef UVM_ENABLE_DEPRECATED_API
     if ((scope == "") && (rsrc != null)) s = rsrc.get_scope();
`endif //UVM_ENABLE_DEPRECATED_API
     set_scope(rsrc, s);
     set_priority(rsrc, uvm_resource_types::PRI_HIGH);
  endfunction


  // Function -- NODOCS -- set_name_override
  //
  // The resource provided as an argument will entered into the pool
  // using normal precedence in the type map and will override the name.
  // Default value to 'scope' argument is violating 1800.2-2017 LRM, but it
  // is added to make the routine backward compatible

  // @uvm-ieee 1800.2-2017 auto C.2.4.3.3
  function void set_name_override(uvm_resource_base rsrc, string scope = "");
    string s = scope;
`ifdef UVM_ENABLE_DEPRECATED_API
    if ((scope == "") && (rsrc != null)) s = rsrc.get_scope();
`endif //UVM_ENABLE_DEPRECATED_API
    set_scope(rsrc, s);
    set_priority_name(rsrc, uvm_resource_types::PRI_HIGH);
  endfunction


  // Function -- NODOCS -- set_type_override
  //
  // The resource provided as an argument will be entered into the pool
  // using normal precedence in the name map and will override the type.
  // Default value to 'scope' argument is violating 1800.2-2017 LRM, but it
  // is added to make the routine backward compatible

  // @uvm-ieee 1800.2-2017 auto C.2.4.3.4
  function void set_type_override(uvm_resource_base rsrc, string scope = "");
    string s = scope;
`ifdef UVM_ENABLE_DEPRECATED_API
    if ((scope == "") && (rsrc != null)) s = rsrc.get_scope();
`endif //UVM_ENABLE_DEPRECATED_API
    set_scope(rsrc, s);
    set_priority_type(rsrc, uvm_resource_types::PRI_HIGH);
  endfunction

  
  // @uvm-ieee 1800.2-2017 auto C.2.4.3.5
  virtual function bit get_scope(uvm_resource_base rsrc,
                                 output string scope);

    uvm_resource_types::rsrc_q_t rq;
    string name;
    uvm_resource_base r;
    int unsigned i;

    // If resource handle is ~null~ then there is nothing to do.
    if(rsrc == null) 
      return 0;

    // Search the resouce in the name map.  Resources with empty names are
    // anonymous resources and are not entered into the name map
    name = rsrc.get_name();
    if((name != "") && rtab.exists(name)) begin
      rq = rtab[name];

      for(i = 0; i < rq.size(); i++) begin
        r = rq.get(i);
        if(r == rsrc) begin 
          // Resource is in pool, set the scope 
          scope = ri_tab[rsrc].scope;
          return 1;
        end
      end
    end

    // Resource is not in pool
    scope = "";
    return 0;

  endfunction

  // Function -- NODOCS -- delete
  // 
  // If rsrc exists within the pool, then it is removed from all internal maps. If the rsrc is null, or does not exist
  // within the pool, then the request is silently ignored.

 
  // @uvm-ieee 1800.2-2017 auto C.2.4.3.6
  virtual function void delete ( uvm_resource_base rsrc );
    string name;
    uvm_resource_base type_handle;

    if (rsrc != null) begin
      name = rsrc.get_name();
      if(name != "") begin
        if(rtab.exists(name))
          rtab.delete(name);
      end
      
      type_handle = rsrc.get_type_handle();
      if(ttab.exists(type_handle)) begin
          int q_size = ttab[type_handle].size();
          
          if (q_size == 1)
              ttab.delete(type_handle);
          else begin
              int i;
              for (i=0; i<q_size; i++) begin
                  if (ttab[type_handle].get(i) == rsrc) begin
                      ttab[type_handle].delete(i);
                      break;
                  end
              end              
          end   
      end

      if (ri_tab.exists(rsrc))
         ri_tab.delete(rsrc);
    end    
  endfunction


  // function - push_get_record
  //
  // Insert a new record into the get history list.

  function void push_get_record(string name, string scope,
                                  uvm_resource_base rsrc);
    get_t impt;

    // if auditing is turned off then there is no reason
    // to save a get record
    if(!uvm_resource_options::is_auditing())
      return;

    impt = new();

    impt.name  = name;
    impt.scope = scope;
    impt.rsrc  = rsrc;
    impt.t     = $realtime;

    get_record.push_back(impt);
  endfunction

  // function - dump_get_records
  //
  // Format and print the get history list.

  function void dump_get_records();

    get_t record;
    bit success;
    string qs[$];

    qs.push_back("--- resource get records ---\n");
    foreach (get_record[i]) begin
      record = get_record[i];
      success = (record.rsrc != null);
      qs.push_back($sformatf("get: name=%s  scope=%s  %s @ %0t\n",
               record.name, record.scope,
               ((success)?"success":"fail"),
               record.t));
    end
    `uvm_info("UVM/RESOURCE/GETRECORD",`UVM_STRING_QUEUE_STREAMING_PACK(qs),UVM_NONE)
  endfunction

  //--------------
  // Group -- NODOCS -- Lookup
  //--------------
  //
  // This group of functions is for finding resources in the resource database.  
  //
  // <lookup_name> and <lookup_type> locate the set of resources that
  // matches the name or type (respectively) and is visible in the
  // current scope.  These functions return a queue of resources.
  //
  // <get_highest_precedence> traverse a queue of resources and
  // returns the one with the highest precedence -- i.e. the one whose
  // precedence member has the highest value.
  //
  // <get_by_name> and <get_by_type> use <lookup_name> and <lookup_type>
  // (respectively) and <get_highest_precedence> to find the resource with
  // the highest priority that matches the other search criteria.


  // Function -- NODOCS -- lookup_name
  //
  // Lookup resources by ~name~.  Returns a queue of resources that
  // match the ~name~, ~scope~, and ~type_handle~.  If no resources
  // match the queue is returned empty. If ~rpterr~ is set then a
  // warning is issued if no matches are found, and the spell checker is
  // invoked on ~name~.  If ~type_handle~ is ~null~ then a type check is
  // not made and resources are returned that match only ~name~ and
  // ~scope~.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.1
  function uvm_resource_types::rsrc_q_t lookup_name(string scope = "",
                                                    string name,
                                                    uvm_resource_base type_handle = null,
                                                    bit rpterr = 1);
    uvm_resource_types::rsrc_q_t rq;
    uvm_resource_types::rsrc_q_t q;
    uvm_resource_base rsrc;
    uvm_resource_base r;
    string rsrcs;

     // ensure rand stability during lookup
     begin
	process p = process::self();
	string s;
	if(p!=null) s=p.get_randstate();
	q=new();
	if(p!=null) p.set_randstate(s);
     end

     
    // resources with empty names are anonymous and do not exist in the name map
    if(name == "")
      return q;

    // Does an entry in the name map exist with the specified name?
    // If not, then we're done
    if(!rtab.exists(name)) begin
	    if(rpterr) void'(spell_check(name));	
		return q;
    end	

    rsrc = null;
    rq = rtab[name];
    for(int i=0; i<rq.size(); ++i) begin 
      r = rq.get(i);
      rsrcs = ri_tab.exists(r) ? ri_tab[r].scope: "";
      // does the type and scope match?
      if(((type_handle == null) || (r.get_type_handle() == type_handle)) &&
          uvm_is_match(rsrcs, scope))
        q.push_back(r);
    end

    return q;

  endfunction

  // Function -- NODOCS -- get_highest_precedence
  //
  // Traverse a queue, ~q~, of resources and return the one with the highest
  // precedence.  In the case where there exists more than one resource
  // with the highest precedence value, the first one that has that
  // precedence will be the one that is returned.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.2
  // @uvm-ieee 1800.2-2017 auto C.2.4.5.8
  static function uvm_resource_base get_highest_precedence(ref uvm_resource_types::rsrc_q_t q);

    uvm_resource_base rsrc;
    uvm_resource_base r;
    int unsigned i;
    int unsigned prec;
    int unsigned c_prec;

    if(q.size() == 0)
      return null;

    // get the first resources in the queue
    rsrc = q.get(0);
    prec = (ri_tab.exists(rsrc)) ? ri_tab[rsrc].precedence: 0;

    // start searching from the second resource
    for(int i = 1; i < q.size(); ++i) begin
      r = q.get(i);
      c_prec = (ri_tab.exists(r)) ? ri_tab[r].precedence: 0;
      if(c_prec > prec) begin
        rsrc = r;
        prec = c_prec;
      end
    end

    return rsrc;

  endfunction

  // Function -- NODOCS -- sort_by_precedence
  //
  // Given a list of resources, obtained for example from <lookup_scope>,
  // sort the resources in  precedence order. The highest precedence
  // resource will be first in the list and the lowest precedence will
  // be last. Resources that have the same precedence and the same name
  // will be ordered by most recently set first.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.3
  static function void sort_by_precedence(ref uvm_resource_types::rsrc_q_t q);
    uvm_resource_types::rsrc_q_t all[int];
    uvm_resource_base r;
    int unsigned prec;

    for(int i=0; i<q.size(); ++i) begin
      r = q.get(i);
      prec = (ri_tab.exists(r)) ? ri_tab[r].precedence: 0;
      if(!all.exists(prec))
         all[prec] = new;
      all[prec].push_front(r); //since we will push_front in the final
    end
    q.delete();
    foreach(all[i]) begin
      for(int j=0; j<all[i].size(); ++j) begin
        r = all[i].get(j);
        q.push_front(r);
      end
    end
  endfunction


  // Function -- NODOCS -- get_by_name
  //
  // Lookup a resource by ~name~, ~scope~, and ~type_handle~.  Whether
  // the get succeeds or fails, save a record of the get attempt.  The
  // ~rpterr~ flag indicates whether to report errors or not.
  // Essentially, it serves as a verbose flag.  If set then the spell
  // checker will be invoked and warnings about multiple resources will
  // be produced.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.4
  function uvm_resource_base get_by_name(string scope = "",
                                         string name,
                                         uvm_resource_base type_handle,
                                         bit rpterr = 1);

    uvm_resource_types::rsrc_q_t q;
    uvm_resource_base rsrc;

    q = lookup_name(scope, name, type_handle, rpterr);

    if(q.size() == 0) begin
      push_get_record(name, scope, null);
      return null;
    end

    rsrc = get_highest_precedence(q);
    push_get_record(name, scope, rsrc);
    return rsrc;
    
  endfunction


  // Function -- NODOCS -- lookup_type
  //
  // Lookup resources by type. Return a queue of resources that match
  // the ~type_handle~ and ~scope~.  If no resources match then the returned
  // queue is empty.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.5
  function uvm_resource_types::rsrc_q_t lookup_type(string scope = "",
                                                    uvm_resource_base type_handle);

    uvm_resource_types::rsrc_q_t q = new();
    uvm_resource_types::rsrc_q_t rq;
    uvm_resource_base r;
    int unsigned i;

    if(type_handle == null || !ttab.exists(type_handle)) begin
      return q;
    end

    rq = ttab[type_handle];
    for(int i = 0; i < rq.size(); ++i) begin 
      r = rq.get(i);
      if(ri_tab.exists(r) && uvm_is_match(ri_tab[r].scope, scope))
        q.push_back(r);
    end

    return q;

  endfunction

  // Function -- NODOCS -- get_by_type
  //
  // Lookup a resource by ~type_handle~ and ~scope~.  Insert a record into
  // the get history list whether or not the get succeeded.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.6
  function uvm_resource_base get_by_type(string scope = "",
                                         uvm_resource_base type_handle);

    uvm_resource_types::rsrc_q_t q;
    uvm_resource_base rsrc;

    q = lookup_type(scope, type_handle);

    if(q.size() == 0) begin
      push_get_record("<type>", scope, null);
      return null;
    end

    rsrc = q.get(0);
    push_get_record("<type>", scope, rsrc);
    return rsrc;
    
  endfunction

  // Function -- NODOCS -- lookup_regex_names
  //
  // This utility function answers the question, for a given ~name~,
  // ~scope~, and ~type_handle~, what are all of the resources with requested name,
  // a matching scope (where the resource scope may be a
  // regular expression), and a matching type? 
  // ~name~ and ~scope~ are explicit values.

  function uvm_resource_types::rsrc_q_t lookup_regex_names(string scope,
                                                           string name,
                                                           uvm_resource_base type_handle = null);
      return lookup_name(scope, name, type_handle, 0);
  endfunction

  // Function -- NODOCS -- lookup_regex
  //
  // Looks for all the resources whose name matches the regular
  // expression argument and whose scope matches the current scope.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.7
  function uvm_resource_types::rsrc_q_t lookup_regex(string re, scope);

    uvm_resource_types::rsrc_q_t rq;
    uvm_resource_types::rsrc_q_t result_q;
    int unsigned i;
    uvm_resource_base r;
    string s;

    result_q = new();

    foreach (rtab[name]) begin
      if ( ! uvm_is_match(re, name) )
        continue;
      rq = rtab[name];
      for(i = 0; i < rq.size(); i++) begin
        r = rq.get(i);
        if(ri_tab.exists(r) && uvm_is_match(ri_tab[r].scope, scope))
          result_q.push_back(r);
      end
    end

    return result_q;

  endfunction

  // Function -- NODOCS -- lookup_scope
  //
  // This is a utility function that answers the question: For a given
  // ~scope~, what resources are visible to it?  Locate all the resources
  // that are visible to a particular scope.  This operation could be
  // quite expensive, as it has to traverse all of the resources in the
  // database.

  // @uvm-ieee 1800.2-2017 auto C.2.4.4.8
  function uvm_resource_types::rsrc_q_t lookup_scope(string scope);

    uvm_resource_types::rsrc_q_t rq;
    uvm_resource_base r;
    int unsigned i;

    int unsigned err;
    uvm_resource_types::rsrc_q_t q = new();

    //iterate in reverse order for the special case of autoconfig
    //of arrays. The array name with no [] needs to be higher priority.
    //This has no effect an manual accesses.
    string name;

    if(rtab.last(name)) begin
    do begin
      rq = rtab[name];
      for(int i = 0; i < rq.size(); ++i) begin
        r = rq.get(i);
        if(ri_tab.exists(r) && uvm_is_match(ri_tab[r].scope, scope)) begin
          q.push_back(r);
        end
      end
    end while(rtab.prev(name));
    end

    return q;
    
  endfunction

  //--------------------
  // Group -- NODOCS -- Set Priority
  //--------------------
  //
  // Functions for altering the search priority of resources.  Resources
  // are stored in queues in the type and name maps.  When retrieving
  // resources, either by type or by name, the resource queue is search
  // from front to back.  The first one that matches the search criteria
  // is the one that is returned.  The ~set_priority~ functions let you
  // change the order in which resources are searched.  For any
  // particular resource, you can set its priority to UVM_HIGH, in which
  // case the resource is moved to the front of the queue, or to UVM_LOW in
  // which case the resource is moved to the back of the queue.

  // function- set_priority_queue
  //
  // This function handles the mechanics of moving a resource to either
  // the front or back of the queue.

  local function void set_priority_queue(uvm_resource_base rsrc,
                                         ref uvm_resource_types::rsrc_q_t q,
                                         uvm_resource_types::priority_e pri);

    uvm_resource_base r;
    int unsigned i;

    string msg;
    string name = rsrc.get_name();

    for(i = 0; i < q.size(); i++) begin
      r = q.get(i);
      if(r == rsrc) break;
    end

    if(r != rsrc) begin
      $sformat(msg, "Handle for resource named %s is not in the name name; cannot change its priority", name);
      uvm_report_error("NORSRC", msg);
      return;
    end

    q.delete(i);

    case(pri)
      uvm_resource_types::PRI_HIGH: q.push_front(rsrc);
      uvm_resource_types::PRI_LOW:  q.push_back(rsrc);
    endcase

  endfunction


  // Function -- NODOCS -- set_priority_type
  //
  // Change the priority of the ~rsrc~ based on the value of ~pri~, the
  // priority enum argument.  This function changes the priority only in
  // the type map, leaving the name map untouched.

  // @uvm-ieee 1800.2-2017 auto C.2.4.5.1
  function void set_priority_type(uvm_resource_base rsrc,
                                  uvm_resource_types::priority_e pri);

    uvm_resource_base type_handle;
    string msg;
    uvm_resource_types::rsrc_q_t q;

    if(rsrc == null) begin
      uvm_report_warning("NULLRASRC", "attempting to change the serach priority of a null resource");
      return;
    end

    type_handle = rsrc.get_type_handle();
    if(!ttab.exists(type_handle)) begin
      $sformat(msg, "Type handle for resrouce named %s not found in type map; cannot change its search priority", rsrc.get_name());
      uvm_report_error("RNFTYPE", msg);
      return;
    end

    q = ttab[type_handle];
    set_priority_queue(rsrc, q, pri);
  endfunction


  // Function -- NODOCS -- set_priority_name
  //
  // Change the priority of the ~rsrc~ based on the value of ~pri~, the
  // priority enum argument.  This function changes the priority only in
  // the name map, leaving the type map untouched.

  // @uvm-ieee 1800.2-2017 auto C.2.4.5.2
  function void set_priority_name(uvm_resource_base rsrc,
                                  uvm_resource_types::priority_e pri);

    string name;
    string msg;
    uvm_resource_types::rsrc_q_t q;

    if(rsrc == null) begin
      uvm_report_warning("NULLRASRC", "attempting to change the serach priority of a null resource");
      return;
    end

    name = rsrc.get_name();
    if(!rtab.exists(name)) begin
      $sformat(msg, "Resrouce named %s not found in name map; cannot change its search priority", name);
      uvm_report_error("RNFNAME", msg);
      return;
    end

    q = rtab[name];
    set_priority_queue(rsrc, q, pri);

  endfunction


  // Function -- NODOCS -- set_priority
  //
  // Change the search priority of the ~rsrc~ based on the value of ~pri~,
  // the priority enum argument.  This function changes the priority in
  // both the name and type maps.

  // @uvm-ieee 1800.2-2017 auto C.2.4.5.3
  function void set_priority (uvm_resource_base rsrc,
                              uvm_resource_types::priority_e pri);
    set_priority_type(rsrc, pri);
    set_priority_name(rsrc, pri);
  endfunction


  // @uvm-ieee 1800.2-2017 auto C.2.4.5.4
  static function void set_default_precedence( int unsigned precedence);
    uvm_coreservice_t cs = uvm_coreservice_t::get();
    cs.set_resource_pool_default_precedence(precedence);
  endfunction


  static function int unsigned get_default_precedence();
    uvm_coreservice_t cs = uvm_coreservice_t::get();
    return cs.get_resource_pool_default_precedence(); 
  endfunction

  
  // @uvm-ieee 1800.2-2017 auto C.2.4.5.6
  virtual function void set_precedence(uvm_resource_base r,
                                       int unsigned p=uvm_resource_pool::get_default_precedence());

    uvm_resource_types::rsrc_q_t q;
    string name;
    int unsigned i;
    uvm_resource_base rsrc;

    if(r == null) begin
      uvm_report_warning("NULLRASRC", "attempting to set precedence of a null resource");
      return;
    end

    name = r.get_name();
    if(rtab.exists(name)) begin
      q = rtab[name];

      for(i = 0; i < q.size(); i++) begin
        rsrc = q.get(i);
        if(rsrc == r) break;
      end
    end 
  
    if(r != rsrc) begin
      uvm_report_warning("NORSRC", $sformatf("resource named %s is not placed within the pool", name));
      return;
    end

    ri_tab[r].precedence = p;

  endfunction


  virtual function int unsigned get_precedence(uvm_resource_base r);

    uvm_resource_types::rsrc_q_t q;
    string name;
    int unsigned i;
    uvm_resource_base rsrc;

    if(r == null) begin
      uvm_report_warning("NULLRASRC", "attempting to get precedence of a null resource");
      return uvm_resource_pool::get_default_precedence();
    end

    name = r.get_name();
    if(rtab.exists(name)) begin
      q = rtab[name];

      for(i = 0; i < q.size(); i++) begin
        rsrc = q.get(i);
        if(rsrc == r) break;
      end
    end 
  
    if(r != rsrc) begin
      uvm_report_warning("NORSRC", $sformatf("resource named %s is not placed within the pool", name));
      return uvm_resource_pool::get_default_precedence();
    end

    return ri_tab[r].precedence;

  endfunction


  //--------------------------------------------------------------------
  // Group -- NODOCS -- Debug
  //--------------------------------------------------------------------

`ifdef UVM_ENABLE_DEPRECATED_API
  // Function -- NODOCS -- find_unused_resources
  //
  // Locate all the resources that have at least one write and no reads

  function uvm_resource_types::rsrc_q_t find_unused_resources();

    uvm_resource_types::rsrc_q_t rq;
    uvm_resource_types::rsrc_q_t q = new;
    int unsigned i;
    uvm_resource_base r;
    uvm_resource_types::access_t a;
    int reads;
    int writes;

    foreach (rtab[name]) begin
      rq = rtab[name];
      for(int i=0; i<rq.size(); ++i) begin
        r = rq.get(i);
        reads = 0;
        writes = 0;
        foreach(r.access[str]) begin
          a = r.access[str];
          reads += a.read_count;
          writes += a.write_count;
        end
        if(writes > 0 && reads == 0)
          q.push_back(r);
      end
    end

    return q;

  endfunction
`endif // UVM_ENABLE_DEPRECATED_API

  // Prints resouce queue into ~printer~, non-LRM
  function void m_print_resources(uvm_printer printer,
                                  uvm_resource_types::rsrc_q_t rq,
                                  bit audit = 0);
    
    printer.push_element(rq.get_name(),
                         "uvm_queue#(uvm_resource_base)",
                         $sformatf("%0d",rq.size()),
                         uvm_object_value_str(rq));

    for(int i=0; i<rq.size(); ++i) begin
      uvm_resource_base r;
      string scope;
      printer.push_element($sformatf("[%0d]", i),
                           "uvm_resource",
                           "-",
                           "-");

      r = rq.get(i);
      void'(get_scope(r, scope));
        
      printer.print_string("name", r.get_name());

      printer.print_generic_element("value",
                                    r.m_value_type_name(),
                                    "",
                                    r.m_value_as_string());
                                    
      printer.print_string("scope", scope);

      printer.print_field_int("precedence", get_precedence(r), 32, UVM_UNSIGNED);

      if (audit && r.access.size()) begin
        printer.print_array_header("accesses",
                                  r.access.size(),
                                  "queue");
        foreach(r.access[i]) begin
          printer.print_string($sformatf("[%s]", i),
                               $sformatf("reads: %0d @ %0t  writes: %0d @ %0t",
                                         r.access[i].read_count,
                                         r.access[i].read_time,
                                         r.access[i].write_count,
                                         r.access[i].write_time));
        end // foreach(r.access[i])

        printer.print_array_footer(r.access.size());
      end // (audit && r.access.size())

      printer.pop_element();
    end // int i=0

    printer.pop_element();

  endfunction : m_print_resources
                                  
  
  // Function -- NODOCS -- print_resources
  //
  // Print the resources that are in a single queue, ~rq~.  This is a utility
  // function that can be used to print any collection of resources
  // stored in a queue.  The ~audit~ flag determines whether or not the
  // audit trail is printed for each resource along with the name,
  // value, and scope regular expression.

  function void print_resources(uvm_resource_types::rsrc_q_t rq, bit audit = 0);

    int unsigned i;
    string id;
    static uvm_tree_printer printer = new();

    // Basically this is full implementation of something
    // like uvm_object::print, but we're interleaving
    // scope data, so it's all manual.
    printer.flush();
    if (rq == null)
      printer.print_generic_element("",
                                    "uvm_queue#(uvm_resource_base)",
                                    "",
                                    "<null>");
    else
      m_print_resources(printer, rq, audit);
    `uvm_info("UVM/RESOURCE_POOL/PRINT_QUEUE",
              printer.emit(),
              UVM_NONE)
  endfunction


  // Function -- NODOCS -- dump
  //
  // dump the entire resource pool.  The resource pool is traversed and
  // each resource is printed.  The utility function print_resources()
  // is used to initiate the printing. If the ~audit~ bit is set then
  // the audit trail is dumped for each resource.

  function void dump(bit audit = 0, uvm_printer printer = null);

    string name;
    static uvm_tree_printer m_printer;

    if (m_printer == null) begin
      m_printer = new();
      m_printer.set_type_name_enabled(1);
    end
      

    if (printer == null)
      printer = m_printer;
    
    printer.flush();
    printer.push_element("uvm_resource_pool",
                         "",
                         $sformatf("%0d",rtab.size()),
                         "");
    
    foreach (rtab[name]) begin
      m_print_resources(printer, rtab[name], audit);
    end

    printer.pop_element();
    
    `uvm_info("UVM/RESOURCE/DUMP", printer.emit(), UVM_NONE)

  endfunction
  
endclass

//----------------------------------------------------------------------
// Class: uvm_resource #(T)
// Implementation of uvm_resource#(T) as defined in section C.2.5.1 of
// 1800.2-2017.
//----------------------------------------------------------------------

// @uvm-ieee 1800.2-2017 auto C.2.5.1
class uvm_resource #(type T=int) extends uvm_resource_base;

  typedef uvm_resource#(T) this_type;

  // singleton handle that represents the type of this resource
  static this_type my_type = get_type();

  // Can't be rand since things like rand strings are not legal.
  protected T val;

  // Because of uvm_resource#(T)::get_type, we can't use
  // the macros.  We need to do it all manually.
  typedef uvm_object_registry#(this_type) type_id;
  virtual function uvm_object_wrapper get_object_type();
    return type_id::get();
  endfunction : get_object_type
  virtual function uvm_object create (string name="");
    this_type tmp;
    if (name=="") tmp = new();
    else tmp = new(name);
    return tmp;
  endfunction : create
  `uvm_type_name_decl($sformatf("uvm_resource#(%s)", `uvm_typename(T)))
  
  
`ifdef UVM_ENABLE_DEPRECATED_API
  function new(string name="", scope="");
    super.new(name, scope);
  endfunction
`else
  // @uvm-ieee 1800.2-2017 auto C.2.5.2
  function new(string name="");
    super.new(name);
  endfunction
`endif // UVM_ENABLE_DEPRECATED_API

  virtual function string m_value_type_name();
    return `uvm_typename(T);
  endfunction : m_value_type_name
                                    
  virtual function string m_value_as_string();
    return $sformatf("%0p", val);
  endfunction : m_value_as_string
                                    
  //----------------------
  // Group -- NODOCS -- Type Interface
  //----------------------
  //
  // Resources can be identified by type using a static type handle.
  // The parent class provides the virtual function interface
  // <get_type_handle>.  Here we implement it by returning the static type
  // handle.

  // Function -- NODOCS -- get_type
  //
  // Static function that returns the static type handle.  The return
  // type is this_type, which is the type of the parameterized class.

  static function this_type get_type();
    if(my_type == null)
      my_type = new();
    return my_type;
  endfunction

  // Function -- NODOCS -- get_type_handle
  //
  // Returns the static type handle of this resource in a polymorphic
  // fashion.  The return type of get_type_handle() is
  // uvm_resource_base.  This function is not static and therefore can
  // only be used by instances of a parameterized resource.

  // @uvm-ieee 1800.2-2017 auto C.2.5.3.2
  function uvm_resource_base get_type_handle();
    return get_type();
  endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
  //-------------------------
  // Group -- NODOCS -- Set/Get Interface
  //-------------------------
  //
  // uvm_resource#(T) provides an interface for setting and getting a
  // resources.  Specifically, a resource can insert itself into the
  // resource pool.  It doesn't make sense for a resource to get itself,
  // since you can't call a function on a handle you don't have.
  // However, a static get interface is provided as a convenience.  This
  // obviates the need for the user to get a handle to the global
  // resource pool as this is done for him here.

  // Function -- NODOCS -- set
  //
  // Simply put this resource into the global resource pool

  function void set();
    uvm_resource_pool rp = uvm_resource_pool::get();
    rp.set_scope(this, get_scope());
  endfunction

  
  // Function -- NODOCS -- set_override
  //
  // Put a resource into the global resource pool as an override.  This
  // means it gets put at the head of the list and is searched before
  // other existing resources that occupy the same position in the name
  // map or the type map.  The default is to override both the name and
  // type maps.  However, using the ~override~ argument you can specify
  // that either the name map or type map is overridden.

  function void set_override(uvm_resource_types::override_t override = 2'b11);
    uvm_resource_pool rp = uvm_resource_pool::get();
    if(override)
      rp.set_override(this, get_scope());
    else
      rp.set_scope(this, get_scope());
  endfunction

  // Function -- NODOCS -- get_by_name
  //
  // looks up a resource by ~name~ in the name map. The first resource
  // with the specified name, whose type is the current type, and is
  // visible in the specified ~scope~ is returned, if one exists.  The
  // ~rpterr~ flag indicates whether or not an error should be reported
  // if the search fails.  If ~rpterr~ is set to one then a failure
  // message is issued, including suggested spelling alternatives, based
  // on resource names that exist in the database, gathered by the spell
  // checker.

  static function this_type get_by_name(string scope,
                                        string name,
                                        bit rpterr = 1);

    uvm_resource_pool rp = uvm_resource_pool::get();
    uvm_resource_base rsrc_base;
    this_type rsrc;
    string msg;

    rsrc_base = rp.get_by_name(scope, name, my_type, rpterr);
    if(rsrc_base == null)
      return null;

    if(!$cast(rsrc, rsrc_base)) begin
      if(rpterr) begin
        $sformat(msg, "Resource with name %s in scope %s has incorrect type", name, scope);
        `uvm_warning("RSRCTYPE", msg)
      end
      return null;
    end

    return rsrc;
    
  endfunction

  // Function -- NODOCS -- get_by_type
  //
  // looks up a resource by ~type_handle~ in the type map. The first resource
  // with the specified ~type_handle~ that is visible in the specified ~scope~ is
  // returned, if one exists. If there is no resource matching the specifications,
  // ~null~ is returned.

  static function this_type get_by_type(string scope = "",
                                        uvm_resource_base type_handle);

    uvm_resource_pool rp = uvm_resource_pool::get();
    uvm_resource_base rsrc_base;
    this_type rsrc;
    string msg;

    if(type_handle == null)
      return null;

    rsrc_base = rp.get_by_type(scope, type_handle);
    if(rsrc_base == null)
      return null;

    if(!$cast(rsrc, rsrc_base)) begin
      $sformat(msg, "Resource with specified type handle in scope %s was not located", scope);
      `uvm_warning("RSRCNF", msg)
      return null;
    end

    return rsrc;

  endfunction
`endif // UVM_ENABLE_DEPRECATED_API
  
  //----------------------------
  // Group -- NODOCS -- Read/Write Interface
  //----------------------------
  //
  // <read> and <write> provide a type-safe interface for getting and
  // setting the object in the resource container.  The interface is
  // type safe because the value argument for <write> and the return
  // value of <read> are T, the type supplied in the class parameter.
  // If either of these functions is used in an incorrect type context
  // the compiler will complain.

  // Function: read
  //
  //| function T read(uvm_object accessor = null);
  //
  // This function is the implementation of the uvm_resource#(T)::read 
  // method detailed in IEEE1800.2-2017 section C.2.5.4.1
  //
  // It calls uvm_resource_base::record_read_access before returning the value.
  //
  // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2


  // @uvm-ieee 1800.2-2017 auto C.2.5.4.1
  function T read(uvm_object accessor = null);
    record_read_access(accessor);
    return val;
  endfunction

  // Function: write
  //
  //| function void write(T t, uvm_object accessor = null);
  //
  // This function is the implementation of the uvm_resource#(T)::write 
  // method detailed in IEEE1800.2-2017 section C.2.5.4.2
  //
  // It calls uvm_resource_base::record_write_access before writing the value.
  //
  // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2


  // @uvm-ieee 1800.2-2017 auto C.2.5.4.2
  function void write(T t, uvm_object accessor = null);

    if(is_read_only()) begin
      uvm_report_error("resource", $sformatf("resource %s is read only -- cannot modify", get_name()));
      return;
    end

    // Set the modified bit and record the transaction only if the value
    // has actually changed.
    if(val == t)
      return;

    record_write_access(accessor);

    // set the value and set the dirty bit
    val = t;
    modified = 1;
  endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
  //----------------
  // Group -- NODOCS -- Priority
  //----------------
  //
  // Functions for manipulating the search priority of resources.  These
  // implementations of the interface defined in the base class delegate
  // to the resource pool. 


  // Function -- NODOCS -- set priority
  //
  // Change the search priority of the resource based on the value of
  // the priority enum argument, ~pri~.

  function void set_priority (uvm_resource_types::priority_e pri);
    uvm_resource_pool rp = uvm_resource_pool::get();
    rp.set_priority(this, pri);
  endfunction

`endif // UVM_ENABLE_DEPRECATED_API

  // Function -- NODOCS -- get_highest_precedence
  //
  // In a queue of resources, locate the first one with the highest
  // precedence whose type is T.  This function is static so that it can
  // be called from anywhere.

  static function this_type get_highest_precedence(ref uvm_resource_types::rsrc_q_t q);

    this_type rsrc;
    this_type r;
    uvm_resource_types::rsrc_q_t tq;
    uvm_resource_base rb;
    uvm_resource_pool rp = uvm_resource_pool::get();

    if(q.size() == 0)
      return null;

    tq = new();
    rsrc = null;

    for(int i = 0; i < q.size(); ++i) begin
      if($cast(r, q.get(i))) begin
        tq.push_back(r) ;
      end
    end

    rb = rp.get_highest_precedence(tq);
    if (!$cast(rsrc, rb))
       return null;
 
    return rsrc;

  endfunction

endclass

