//
// -------------------------------------------------------------
//    Copyright 2004-2009 Synopsys, Inc.
//    Copyright 2010-2011 Mentor Graphics Corporation
//    Copyright 2010-2011 Cadence Design Systems, Inc.
//    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.
// -------------------------------------------------------------
//

typedef class uvm_reg_cbs;
typedef class uvm_reg_frontdoor;

//-----------------------------------------------------------------
// CLASS: uvm_reg
// Register abstraction base class
//
// A register represents a set of fields that are accessible
// as a single entity.
//
// A register may be mapped to one or more address maps,
// each with different access rights and policy.
//-----------------------------------------------------------------
virtual class uvm_reg extends uvm_object;

   local bit               m_locked;
   local uvm_reg_block     m_parent;
   local uvm_reg_file      m_regfile_parent;
   local int unsigned      m_n_bits;
   local int unsigned      m_n_used_bits;
   protected bit           m_maps[uvm_reg_map];
   protected uvm_reg_field m_fields[$];   // Fields in LSB to MSB order
   local int               m_has_cover;
   local int               m_cover_on;
   local semaphore         m_atomic;
   local process           m_process;
   local string            m_fname;
   local int               m_lineno;
   local bit               m_read_in_progress;
   local bit               m_write_in_progress; 
   protected bit           m_update_in_progress;
   /*local*/ bit           m_is_busy;
   /*local*/ bit           m_is_locked_by_field;
   local uvm_reg_backdoor  m_backdoor;

   local static int unsigned m_max_size;

   local uvm_object_string_pool
       #(uvm_queue #(uvm_hdl_path_concat)) m_hdl_paths_pool;

   //----------------------
   // Group: Initialization
   //----------------------

   // Function: new
   //
   // Create a new instance and type-specific configuration
   //
   // Creates an instance of a register abstraction class with the specified
   // name.
   //
   // ~n_bits~ specifies the total number of bits in the register.
   // Not all bits need to be implemented.
   // This value is usually a multiple of 8.
   //
   // ~has_coverage~ specifies which functional coverage models are present in
   // the extension of the register abstraction class.
   // Multiple functional coverage models may be specified by adding their
   // symbolic names, as defined by the <uvm_coverage_model_e> type.
   //
   extern function new (string name="",
                        int unsigned n_bits,
                        int has_coverage);


   // Function: configure
   //
   // Instance-specific configuration
   //
   // Specify the parent block of this register.
   // May also set a parent register file for this register,
   //
   // If the register is implemented in a single HDL variable,
   // it's name is specified as the ~hdl_path~.
   // Otherwise, if the register is implemented as a concatenation
   // of variables (usually one per field), then the HDL path
   // must be specified using the <add_hdl_path()> or
   // <add_hdl_path_slice> method.
   //
   extern function void configure (uvm_reg_block blk_parent,
                                   uvm_reg_file regfile_parent = null,
                                   string hdl_path = "");


   // Function: set_offset
   //
   // Modify the offset of the register
   //
   // The offset of a register within an address map is set using the
   // <uvm_reg_map::add_reg()> method.
   // This method is used to modify that offset dynamically.
   //  
   // Modifying the offset of a register will make the register model
   // diverge from the specification that was used to create it.
   //
   extern virtual function void set_offset (uvm_reg_map    map,
                                            uvm_reg_addr_t offset,
                                            bit            unmapped = 0);

   /*local*/ extern virtual function void set_parent (uvm_reg_block blk_parent,
                                                      uvm_reg_file regfile_parent);
   /*local*/ extern virtual function void add_field  (uvm_reg_field field);
   /*local*/ extern virtual function void add_map    (uvm_reg_map map);

   /*local*/ extern function void   Xlock_modelX;


   //---------------------
   // Group: Introspection
   //---------------------

   // Function: get_name
   //
   // Get the simple name
   //
   // Return the simple object name of this register.
   //

   // Function: get_full_name
   //
   // Get the hierarchical name
   //
   // Return the hierarchal name of this register.
   // The base of the hierarchical name is the root block.
   //
   extern virtual function string get_full_name();


   // Function: get_parent
   //
   // Get the parent block
   //
   extern virtual function uvm_reg_block get_parent ();
   extern virtual function uvm_reg_block get_block  ();


   // Function: get_regfile
   //
   // Get the parent register file
   //
   // Returns ~null~ if this register is instantiated in a block.
   //
   extern virtual function uvm_reg_file get_regfile ();


   // Function: get_n_maps
   //
   // Returns the number of address maps this register is mapped in
   //
   extern virtual function int get_n_maps ();


   // Function: is_in_map
   //
   // Returns 1 if this register is in the specified address ~map~
   //
   extern function bit is_in_map (uvm_reg_map map);


   // Function: get_maps
   //
   // Returns all of the address ~maps~ where this register is mapped
   //
   extern virtual function void get_maps (ref uvm_reg_map maps[$]);


   /*local*/ extern virtual function uvm_reg_map get_local_map   (uvm_reg_map map,
                                                                  string caller = "");
   /*local*/ extern virtual function uvm_reg_map get_default_map (string caller = "");


   // Function: get_rights
   //
   // Returns the accessibility ("RW, "RO", or "WO") of this register in the given ~map~.
   //
   // If no address map is specified and the register is mapped in only one
   // address map, that address map is used. If the register is mapped
   // in more than one address map, the default address map of the
   // parent block is used.
   //
   // Whether a register field can be read or written depends on both the field's
   // configured access policy (see <uvm_reg_field::configure>) and the register's
   // accessibility rights in the map being used to access the field. 
   //
   // If an address map is specified and
   // the register is not mapped in the specified
   // address map, an error message is issued
   // and "RW" is returned. 
   //
   extern virtual function string get_rights (uvm_reg_map map = null);


   // Function: get_n_bits
   //
   // Returns the width, in bits, of this register.
   //
   extern virtual function int unsigned get_n_bits ();


   // Function: get_n_bytes
   //
   // Returns the width, in bytes, of this register. Rounds up to
   // next whole byte if register is not a multiple of 8.
   //
   extern virtual function int unsigned get_n_bytes();


   // Function: get_max_size
   //
   // Returns the maximum width, in bits, of all registers. 
   //
   extern static function int unsigned get_max_size();


   // Function: get_fields
   //
   // Return the fields in this register
   //
   // Fills the specified array with the abstraction class
   // for all of the fields contained in this register.
   // Fields are ordered from least-significant position to most-significant
   // position within the register. 
   //
   extern virtual function void get_fields (ref uvm_reg_field fields[$]);


   // Function: get_field_by_name
   //
   // Return the named field in this register
   //
   // Finds a field with the specified name in this register
   // and returns its abstraction class.
   // If no fields are found, returns null. 
   //
   extern virtual function uvm_reg_field get_field_by_name(string name);


   /*local*/ extern function string Xget_fields_accessX(uvm_reg_map map);


   // Function: get_offset
   //
   // Returns the offset of this register
   //
   // Returns the offset of this register in an address ~map~.
   //
   // If no address map is specified and the register is mapped in only one
   // address map, that address map is used. If the register is mapped
   // in more than one address map, the default address map of the
   // parent block is used.
   //
   // If an address map is specified and
   // the register is not mapped in the specified
   // address map, an error message is issued.
   //
   extern virtual function uvm_reg_addr_t get_offset (uvm_reg_map map = null);


   // Function: get_address
   //
   // Returns the base external physical address of this register
   //
   // Returns the base external physical address of this register
   // if accessed through the specified address ~map~.
   //
   // If no address map is specified and the register is mapped in only one
   // address map, that address map is used. If the register is mapped
   // in more than one address map, the default address map of the
   // parent block is used.
   //
   // If an address map is specified and
   // the register is not mapped in the specified
   // address map, an error message is issued.
   //
   extern virtual function uvm_reg_addr_t get_address (uvm_reg_map map = null);


   // Function: get_addresses
   //
   // Identifies the external physical address(es) of this register
   //
   // Computes all of the external physical addresses that must be accessed
   // to completely read or write this register. The addressed are specified in
   // little endian order.
   // Returns the number of bytes transfered on each access.
   //
   // If no address map is specified and the register is mapped in only one
   // address map, that address map is used. If the register is mapped
   // in more than one address map, the default address map of the
   // parent block is used.
   //
   // If an address map is specified and
   // the register is not mapped in the specified
   // address map, an error message is issued.
   //
   extern virtual function int get_addresses (uvm_reg_map map = null,
                                              ref uvm_reg_addr_t addr[]);



   //--------------
   // Group: Access
   //--------------


   // Function: set
   //
   // Set the desired value for this register
   //
   // Sets the desired value of the fields in the register
   // to the specified value. Does not actually
   // set the value of the register in the design,
   // only the desired value in its corresponding
   // abstraction class in the RegModel model.
   // Use the <uvm_reg::update()> method to update the
   // actual register with the mirrored value or
   // the <uvm_reg::write()> method to set
   // the actual register and its mirrored value.
   //
   // Unless this method is used, the desired value is equal to
   // the mirrored value.
   //
   // Refer <uvm_reg_field::set()> for more details on the effect
   // of setting mirror values on fields with different
   // access policies.
   //
   // To modify the mirrored field values to a specific value,
   // and thus use the mirrored as a scoreboard for the register values
   // in the DUT, use the <uvm_reg::predict()> method. 
   //
   extern virtual function void set (uvm_reg_data_t  value,
                                     string          fname = "",
                                     int             lineno = 0);


   // Function: get
   //
   // Return the desired value of the fields in the register.
   //
   // Does not actually read the value
   // of the register in the design, only the desired value
   // in the abstraction class. Unless set to a different value
   // using the <uvm_reg::set()>, the desired value
   // and the mirrored value are identical.
   //
   // Use the <uvm_reg::read()> or <uvm_reg::peek()>
   // method to get the actual register value. 
   //
   // If the register contains write-only fields, the desired/mirrored
   // value for those fields are the value last written and assumed
   // to reside in the bits implementing these fields.
   // Although a physical read operation would something different
   // for these fields,
   // the returned value is the actual content.
   //
   extern virtual function uvm_reg_data_t  get(string  fname = "",
                                               int     lineno = 0);

   // Function: get_mirrored_value
   //
   // Return the mirrored value of the fields in the register.
   //
   // Does not actually read the value
   // of the register in the design
   //
   // If the register contains write-only fields, the desired/mirrored
   // value for those fields are the value last written and assumed
   // to reside in the bits implementing these fields.
   // Although a physical read operation would something different
   // for these fields, the returned value is the actual content.
   //
   extern virtual function uvm_reg_data_t  get_mirrored_value(string  fname = "",
                                               int     lineno = 0);


   // Function: needs_update
   //
   // Returns 1 if any of the fields need updating
   //
   // See <uvm_reg_field::needs_update()> for details.
   // Use the <uvm_reg::update()> to actually update the DUT register.
   //
   extern virtual function bit needs_update(); 


   // Function: reset
   //
   // Reset the desired/mirrored value for this register.
   //
   // Sets the desired and mirror value of the fields in this register
   // to the reset value for the specified reset ~kind~.
   // See <uvm_reg_field.reset()> for more details.
   //
   // Also resets the semaphore that prevents concurrent access
   // to the register.
   // This semaphore must be explicitly reset if a thread accessing
   // this register array was killed in before the access
   // was completed
   //
   extern virtual function void reset(string kind = "HARD");


   // Function: get_reset
   //
   // Get the specified reset value for this register
   //
   // Return the reset value for this register
   // for the specified reset ~kind~.
   //
   extern virtual function uvm_reg_data_t
                             get_reset(string kind = "HARD");


   // Function: has_reset
   //
   // Check if any field in the register has a reset value specified
   // for the specified reset ~kind~.
   // If ~delete~ is TRUE, removes the reset value, if any.
   //
   extern virtual function bit has_reset(string kind = "HARD",
                                         bit    delete = 0);


   // Function: set_reset
   //
   // Specify or modify the reset value for this register
   //
   // Specify or modify the reset value for all the fields in the register
   // corresponding to the cause specified by ~kind~.
   //
   extern virtual function void
                       set_reset(uvm_reg_data_t value,
                                 string         kind = "HARD");


   // Task: write
   //
   // Write the specified value in this register
   //
   // Write ~value~ in the DUT register that corresponds to this
   // abstraction class instance using the specified access
   // ~path~. 
   // If the register is mapped in more than one address map, 
   // an address ~map~ must be
   // specified if a physical access is used (front-door access).
   // If a back-door access path is used, the effect of writing
   // the register through a physical access is mimicked. For
   // example, read-only bits in the registers will not be written.
   //
   // The mirrored value will be updated using the <uvm_reg::predict()>
   // method.
   //
   extern virtual task write(output uvm_status_e      status,
                             input  uvm_reg_data_t    value,
                             input  uvm_path_e        path = UVM_DEFAULT_PATH,
                             input  uvm_reg_map       map = null,
                             input  uvm_sequence_base parent = null,
                             input  int               prior = -1,
                             input  uvm_object        extension = null,
                             input  string            fname = "",
                             input  int               lineno = 0);


   // Task: read
   //
   // Read the current value from this register
   //
   // Read and return ~value~ from the DUT register that corresponds to this
   // abstraction class instance using the specified access
   // ~path~. 
   // If the register is mapped in more than one address map, 
   // an address ~map~ must be
   // specified if a physical access is used (front-door access).
   // If a back-door access path is used, the effect of reading
   // the register through a physical access is mimicked. For
   // example, clear-on-read bits in the registers will be set to zero.
   //
   // The mirrored value will be updated using the <uvm_reg::predict()>
   // method.
   //
   extern virtual task read(output uvm_status_e      status,
                            output uvm_reg_data_t    value,
                            input  uvm_path_e        path = UVM_DEFAULT_PATH,
                            input  uvm_reg_map       map = null,
                            input  uvm_sequence_base parent = null,
                            input  int               prior = -1,
                            input  uvm_object        extension = null,
                            input  string            fname = "",
                            input  int               lineno = 0);


   // Task: poke
   //
   // Deposit the specified value in this register
   //
   // Deposit the value in the DUT register corresponding to this
   // abstraction class instance, as-is, using a back-door access.
   //
   // Uses the HDL path for the design abstraction specified by ~kind~.
   //
   // The mirrored value will be updated using the <uvm_reg::predict()>
   // method.
   //
   extern virtual task poke(output uvm_status_e      status,
                            input  uvm_reg_data_t    value,
                            input  string            kind = "",
                            input  uvm_sequence_base parent = null,
                            input  uvm_object        extension = null,
                            input  string            fname = "",
                            input  int               lineno = 0);


   // Task: peek
   //
   // Read the current value from this register
   //
   // Sample the value in the DUT register corresponding to this
   // absraction class instance using a back-door access.
   // The register value is sampled, not modified.
   //
   // Uses the HDL path for the design abstraction specified by ~kind~.
   //
   // The mirrored value will be updated using the <uvm_reg::predict()>
   // method.
   //
   extern virtual task peek(output uvm_status_e      status,
                            output uvm_reg_data_t    value,
                            input  string            kind = "",
                            input  uvm_sequence_base parent = null,
                            input  uvm_object        extension = null,
                            input  string            fname = "",
                            input  int               lineno = 0);


   // Task: update
   //
   // Updates the content of the register in the design to match the
   // desired value
   //
   // This method performs the reverse
   // operation of <uvm_reg::mirror()>.
   // Write this register if the DUT register is out-of-date with the
   // desired/mirrored value in the abstraction class, as determined by
   // the <uvm_reg::needs_update()> method.
   //
   // The update can be performed using the using the physical interfaces
   // (frontdoor) or <uvm_reg::poke()> (backdoor) access.
   // If the register is mapped in multiple address maps and physical access
   // is used (front-door), an address ~map~ must be specified.
   //
   extern virtual task update(output uvm_status_e      status,
                              input  uvm_path_e        path = UVM_DEFAULT_PATH,
                              input  uvm_reg_map       map = null,
                              input  uvm_sequence_base parent = null,
                              input  int               prior = -1,
                              input  uvm_object        extension = null,
                              input  string            fname = "",
                              input  int               lineno = 0);


   // Task: mirror
   //
   // Read the register and update/check its mirror value
   //
   // Read the register and optionally compared the readback value
   // with the current mirrored value if ~check~ is <UVM_CHECK>.
   // The mirrored value will be updated using the <uvm_reg::predict()>
   // method based on the readback value.
   //
   // The mirroring can be performed using the physical interfaces (frontdoor)
   // or <uvm_reg::peek()> (backdoor).
   //
   // If ~check~ is specified as UVM_CHECK,
   // an error message is issued if the current mirrored value
   // does not match the readback value. Any field whose check has been
   // disabled with <uvm_reg_field::set_compare()> will not be considered
   // in the comparison. 
   //
   // If the register is mapped in multiple address maps and physical
   // access is used (front-door access), an address ~map~ must be specified.
   // If the register contains
   // write-only fields, their content is mirrored and optionally
   // checked only if a UVM_BACKDOOR
   // access path is used to read the register. 
   //
   extern virtual task mirror(output uvm_status_e      status,
                              input uvm_check_e        check  = UVM_NO_CHECK,
                              input uvm_path_e         path = UVM_DEFAULT_PATH,
                              input uvm_reg_map        map = null,
                              input uvm_sequence_base  parent = null,
                              input int                prior = -1,
                              input  uvm_object        extension = null,
                              input string             fname = "",
                              input int                lineno = 0);


   // Function: predict
   //
   // Update the mirrored value for this register.
   //
   // Predict the mirror value of the fields in the register
   // based on the specified observed ~value~ on a specified adress ~map~,
   // or based on a calculated value.
   // See <uvm_reg_field::predict()> for more details.
   //
   // Returns TRUE if the prediction was succesful for each field in the
   // register.
   //
   extern virtual function bit predict (uvm_reg_data_t    value,
                                        uvm_reg_byte_en_t be = -1,
                                        uvm_predict_e     kind = UVM_PREDICT_DIRECT,
                                        uvm_path_e        path = UVM_FRONTDOOR,
                                        uvm_reg_map       map = null,
                                        string            fname = "",
                                        int               lineno = 0);


   // Function: is_busy
   //
   // Returns 1 if register is currently being read or written.
   //
   extern function bit is_busy();



   /*local*/ extern function void Xset_busyX(bit busy);

   /*local*/ extern task XreadX (output uvm_status_e      status,
                                 output uvm_reg_data_t    value,
                                 input  uvm_path_e        path,
                                 input  uvm_reg_map       map,
                                 input  uvm_sequence_base parent = null,
                                 input  int               prior = -1,
                                 input  uvm_object        extension = null,
                                 input  string            fname = "",
                                 input  int               lineno = 0);
   
   /*local*/ extern task XatomicX(bit on);

   /*local*/ extern virtual function bit Xcheck_accessX
                                (input uvm_reg_item rw,
                                 output uvm_reg_map_info map_info,
                                 input string caller);

   /*local*/ extern function bit Xis_locked_by_fieldX();


   extern virtual function bit do_check(uvm_reg_data_t expected,
                                        uvm_reg_data_t actual,
                                        uvm_reg_map    map);

   extern virtual task do_write(uvm_reg_item rw);

   extern virtual task do_read(uvm_reg_item rw);

   extern virtual function void do_predict
                                (uvm_reg_item      rw,
                                 uvm_predict_e     kind = UVM_PREDICT_DIRECT,
                                 uvm_reg_byte_en_t be = -1);
   //-----------------
   // Group: Frontdoor
   //-----------------

   // Function: set_frontdoor
   //
   // Set a user-defined frontdoor for this register
   //
   // By default, registers are mapped linearly into the address space
   // of the address maps that instantiate them.
   // If registers are accessed using a different mechanism,
   // a user-defined access
   // mechanism must be defined and associated with
   // the corresponding register abstraction class
   //
   // If the register is mapped in multiple address maps, an address ~map~
   // must be specified.
   //
   extern function void set_frontdoor(uvm_reg_frontdoor ftdr,
                                      uvm_reg_map       map = null,
                                      string            fname = "",
                                      int               lineno = 0);


   // Function: get_frontdoor
   //
   // Returns the user-defined frontdoor for this register
   //
   // If null, no user-defined frontdoor has been defined.
   // A user-defined frontdoor is defined
   // by using the <uvm_reg::set_frontdoor()> method. 
   //
   // If the register is mapped in multiple address maps, an address ~map~
   // must be specified.
   //
   extern function uvm_reg_frontdoor get_frontdoor(uvm_reg_map map = null);


   //----------------
   // Group: Backdoor
   //----------------


   // Function: set_backdoor
   //
   // Set a user-defined backdoor for this register
   //
   // By default, registers are accessed via the built-in string-based
   // DPI routines if an HDL path has been specified using the
   // <uvm_reg::configure()> or <uvm_reg::add_hdl_path()> method.
   //
   // If this default mechanism is not suitable (e.g. because
   // the register is not implemented in pure SystemVerilog)
   // a user-defined access
   // mechanism must be defined and associated with
   // the corresponding register abstraction class
   //
   // A user-defined backdoor is required if active update of the
   // mirror of this register abstraction class, based on observed
   // changes of the corresponding DUT register, is used.
   //
   extern function void set_backdoor(uvm_reg_backdoor bkdr,
                                     string          fname = "",
                                     int             lineno = 0);
   
   
   // Function: get_backdoor
   //
   // Returns the user-defined backdoor for this register
   //
   // If null, no user-defined backdoor has been defined.
   // A user-defined backdoor is defined
   // by using the <uvm_reg::set_backdoor()> method. 
   //
   // If ~inherited~ is TRUE, returns the backdoor of the parent block
   // if none have been specified for this register.
   //
   extern function uvm_reg_backdoor get_backdoor(bit inherited = 1);


   // Function: clear_hdl_path
   //
   // Delete HDL paths
   //
   // Remove any previously specified HDL path to the register instance
   // for the specified design abstraction.
   //
   extern function void clear_hdl_path (string kind = "RTL");


   // Function: add_hdl_path
   //
   // Add an HDL path
   //
   // Add the specified HDL path to the register instance for the specified
   // design abstraction. This method may be called more than once for the
   // same design abstraction if the register is physically duplicated
   // in the design abstraction
   //
   // For example, the following register
   //
   //|        1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
   //| Bits:  5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
   //|       +-+---+-------------+---+-------+
   //|       |A|xxx|      B      |xxx|   C   |
   //|       +-+---+-------------+---+-------+
   //
   // would be specified using the following literal value:
   //
   //| add_hdl_path('{ '{"A_reg", 15, 1},
   //|                 '{"B_reg",  6, 7},
   //|                 '{'C_reg",  0, 4} } );
   //
   // If the register is implementd using a single HDL variable,
   // The array should specify a single slice with its ~offset~ and ~size~
   // specified as -1. For example:
   //
   //| r1.add_hdl_path('{ '{"r1", -1, -1} });
   //
   extern function void add_hdl_path (uvm_hdl_path_slice slices[],
                                      string kind = "RTL");


   // Function: add_hdl_path_slice
   //
   // Append the specified HDL slice to the HDL path of the register instance
   // for the specified design abstraction.
   // If ~first~ is TRUE, starts the specification of a duplicate
   // HDL implementation of the register.
   //
   extern function void add_hdl_path_slice(string name,
                                           int offset,
                                           int size,
                                           bit first = 0,
                                           string kind = "RTL");


   // Function: has_hdl_path
   //
   // Check if a HDL path is specified
   //
   // Returns TRUE if the register instance has a HDL path defined for the
   // specified design abstraction. If no design abstraction is specified,
   // uses the default design abstraction specified for the parent block.
   //
   extern function bit has_hdl_path (string kind = "");


   // Function:  get_hdl_path
   //
   // Get the incremental HDL path(s)
   //
   // Returns the HDL path(s) defined for the specified design abstraction
   // in the register instance.
   // Returns only the component of the HDL paths that corresponds to
   // the register, not a full hierarchical path
   //
   // If no design asbtraction is specified, the default design abstraction
   // for the parent block is used.
   //
   extern function void get_hdl_path (ref uvm_hdl_path_concat paths[$],
                                      input string kind = "");


   // Function:  get_hdl_path_kinds
   //
   // Get design abstractions for which HDL paths have been defined
   //
   extern function void get_hdl_path_kinds (ref string kinds[$]);


   // Function:  get_full_hdl_path
   //
   // Get the full hierarchical HDL path(s)
   //
   // Returns the full hierarchical HDL path(s) defined for the specified
   // design abstraction in the register instance.
   // There may be more than one path returned even
   // if only one path was defined for the register instance, if any of the
   // parent components have more than one path defined for the same design
   // abstraction
   //
   // If no design asbtraction is specified, the default design abstraction
   // for each ancestor block is used to get each incremental path.
   //
   extern function void get_full_hdl_path (ref uvm_hdl_path_concat paths[$],
                                           input string kind = "",
                                           input string separator = ".");


   // Function: backdoor_read
   //
   // User-define backdoor read access
   //
   // Override the default string-based DPI backdoor access read
   // for this register type.
   // By default calls <uvm_reg::backdoor_read_func()>.
   //
   extern virtual task backdoor_read(uvm_reg_item rw);


   // Function: backdoor_write
   //
   // User-defined backdoor read access
   //
   // Override the default string-based DPI backdoor access write
   // for this register type.
   //
   extern virtual task backdoor_write(uvm_reg_item rw);


   // Function: backdoor_read_func
   //
   // User-defined backdoor read access
   //
   // Override the default string-based DPI backdoor access read
   // for this register type.
   //
   extern virtual function uvm_status_e backdoor_read_func(uvm_reg_item rw);


   // Function: backdoor_watch
   //
   // User-defined DUT register change monitor
   //
   // Watch the DUT register corresponding to this abstraction class
   // instance for any change in value and return when a value-change occurs.
   // This may be implemented a string-based DPI access if the simulation
   // tool provide a value-change callback facility. Such a facility does
   // not exists in the standard SystemVerilog DPI and thus no
   // default implementation for this method can be provided.
   //
   virtual task  backdoor_watch(); endtask


   //----------------
   // Group: Coverage
   //----------------

   // Function: include_coverage
   //
   // Specify which coverage model that must be included in
   // various block, register or memory abstraction class instances.
   //
   // The coverage models are specified by or'ing or adding the
   // <uvm_coverage_model_e> coverage model identifiers corresponding to the
   // coverage model to be included.
   //
   // The scope specifies a hierarchical name or pattern identifying
   // a block, memory or register abstraction class instances.
   // Any block, memory or register whose full hierarchical name
   // matches the specified scope will have the specified functional
   // coverage models included in them.
   //
   // The scope can be specified as a POSIX regular expression
   // or simple pattern.
   // See <uvm_resource_base::Scope Interface> for more details.
   //
   //| uvm_reg::include_coverage("*", UVM_CVR_ALL);
   //
   // The specification of which coverage model to include in
   // which abstraction class is stored in a <uvm_reg_cvr_t> resource in the
   // <uvm_resource_db> resource database,
   // in the "uvm_reg::" scope namespace.
   //
   extern static function void include_coverage(string scope,
                                                uvm_reg_cvr_t models,
                                                uvm_object accessor = null);

   // Function: build_coverage
   //
   // Check if all of the specified coverage models must be built.
   //
   // Check which of the specified coverage model must be built
   // in this instance of the register abstraction class,
   // as specified by calls to <uvm_reg::include_coverage()>.
   //
   // Models are specified by adding the symbolic value of individual
   // coverage model as defined in <uvm_coverage_model_e>.
   // Returns the sum of all coverage models to be built in the
   // register model.
   //
   extern protected function uvm_reg_cvr_t build_coverage(uvm_reg_cvr_t models);


   // Function: add_coverage
   //
   // Specify that additional coverage models are available.
   //
   // Add the specified coverage model to the coverage models
   // available in this class.
   // Models are specified by adding the symbolic value of individual
   // coverage model as defined in <uvm_coverage_model_e>.
   //
   // This method shall be called only in the constructor of
   // subsequently derived classes.
   //
   extern virtual protected function void add_coverage(uvm_reg_cvr_t models);


   // Function: has_coverage
   //
   // Check if register has coverage model(s)
   //
   // Returns TRUE if the register abstraction class contains a coverage model
   // for all of the models specified.
   // Models are specified by adding the symbolic value of individual
   // coverage model as defined in <uvm_coverage_model_e>.
   //
   extern virtual function bit has_coverage(uvm_reg_cvr_t models);


   // Function: set_coverage
   //
   // Turns on coverage measurement.
   //
   // Turns the collection of functional coverage measurements on or off
   // for this register.
   // The functional coverage measurement is turned on for every
   // coverage model specified using <uvm_coverage_model_e> symbolic
   // identifers.
   // Multiple functional coverage models can be specified by adding
   // the functional coverage model identifiers.
   // All other functional coverage models are turned off.
   // Returns the sum of all functional
   // coverage models whose measurements were previously on.
   //
   // This method can only control the measurement of functional
   // coverage models that are present in the register abstraction classes,
   // then enabled during construction.
   // See the <uvm_reg::has_coverage()> method to identify
   // the available functional coverage models.
   //
   extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);


   // Function: get_coverage
   //
   // Check if coverage measurement is on.
   //
   // Returns TRUE if measurement for all of the specified functional
   // coverage models are currently on.
   // Multiple functional coverage models can be specified by adding the
   // functional coverage model identifiers.
   //
   // See <uvm_reg::set_coverage()> for more details. 
   //
   extern virtual function bit get_coverage(uvm_reg_cvr_t is_on);


   // Function: sample
   //
   // Functional coverage measurement method
   //
   // This method is invoked by the register abstraction class
   // whenever it is read or written with the specified ~data~
   // via the specified address ~map~.
   // It is invoked after the read or write operation has completed
   // but before the mirror has been updated.
   //
   // Empty by default, this method may be extended by the
   // abstraction class generator to perform the required sampling
   // in any provided functional coverage model.
   //
   protected virtual function void sample(uvm_reg_data_t  data,
                                          uvm_reg_data_t  byte_en,
                                          bit             is_read,
                                          uvm_reg_map     map);
   endfunction

   // Function: sample_values
   //
   // Functional coverage measurement method for field values
   //
   // This method is invoked by the user
   // or by the <uvm_reg_block::sample_values()> method of the parent block
   // to trigger the sampling
   // of the current field values in the
   // register-level functional coverage model.
   //
   // This method may be extended by the
   // abstraction class generator to perform the required sampling
   // in any provided field-value functional coverage model.
   //
   virtual function void sample_values();
   endfunction

   /*local*/ function void XsampleX(uvm_reg_data_t  data,
                                    uvm_reg_data_t  byte_en,
                                    bit             is_read,
                                    uvm_reg_map     map);
      sample(data, byte_en, is_read, map);
   endfunction


   //-----------------
   // Group: Callbacks
   //-----------------
   `uvm_register_cb(uvm_reg, uvm_reg_cbs)
   

   // Task: pre_write
   //
   // Called before register write.
   //
   // If the specified data value, access ~path~ or address ~map~ are modified,
   // the updated data value, access path or address map will be used
   // to perform the register operation.
   // If the ~status~ is modified to anything other than <UVM_IS_OK>,
   // the operation is aborted.
   //
   // The registered callback methods are invoked after the invocation
   // of this method.
   // All register callbacks are executed before the corresponding
   // field callbacks
   //
   virtual task pre_write(uvm_reg_item rw); endtask


   // Task: post_write
   //
   // Called after register write.
   //
   // If the specified ~status~ is modified,
   // the updated status will be
   // returned by the register operation.
   //
   // The registered callback methods are invoked before the invocation
   // of this method.
   // All register callbacks are executed before the corresponding
   // field callbacks
   //
   virtual task post_write(uvm_reg_item rw); endtask


   // Task: pre_read
   //
   // Called before register read.
   //
   // If the specified access ~path~ or address ~map~ are modified,
   // the updated access path or address map will be used to perform
   // the register operation.
   // If the ~status~ is modified to anything other than <UVM_IS_OK>,
   // the operation is aborted.
   //
   // The registered callback methods are invoked after the invocation
   // of this method.
   // All register callbacks are executed before the corresponding
   // field callbacks
   //
   virtual task pre_read(uvm_reg_item rw); endtask


   // Task: post_read
   //
   // Called after register read.
   //
   // If the specified readback data or ~status~ is modified,
   // the updated readback data or status will be
   // returned by the register operation.
   //
   // The registered callback methods are invoked before the invocation
   // of this method.
   // All register callbacks are executed before the corresponding
   // field callbacks
   //
   virtual task post_read(uvm_reg_item rw); endtask


   extern virtual function void            do_print (uvm_printer printer);
   extern virtual function string          convert2string();
   extern virtual function uvm_object      clone      ();
   extern virtual function void            do_copy    (uvm_object rhs);
   extern virtual function bit             do_compare (uvm_object  rhs,
                                                       uvm_comparer comparer);
   extern virtual function void            do_pack    (uvm_packer packer);
   extern virtual function void            do_unpack  (uvm_packer packer);

endclass: uvm_reg


//------------------------------------------------------------------------------
// IMPLEMENTATION
//------------------------------------------------------------------------------

// new

function uvm_reg::new(string name="", int unsigned n_bits, int has_coverage);
   super.new(name);
   if (n_bits == 0) begin
      `uvm_error("RegModel", $sformatf("Register \"%s\" cannot have 0 bits", get_name()));
      n_bits = 1;
   end
   m_n_bits      = n_bits;
   m_has_cover   = has_coverage;
   m_atomic      = new(1);
   m_n_used_bits = 0;
   m_locked      = 0;
   m_is_busy     = 0;
   m_is_locked_by_field = 1'b0;
   m_hdl_paths_pool = new("hdl_paths");

   if (n_bits > m_max_size)
      m_max_size = n_bits;

endfunction: new


// configure

function void uvm_reg::configure (uvm_reg_block blk_parent,
                                  uvm_reg_file regfile_parent=null,
                                  string hdl_path = "");
   m_parent = blk_parent;
   m_parent.add_reg(this);
   m_regfile_parent = regfile_parent;
   if (hdl_path != "")
     add_hdl_path_slice(hdl_path, -1, -1);
endfunction: configure


// add_field

function void uvm_reg::add_field(uvm_reg_field field);
   int offset;
   int idx;
   
   if (m_locked) begin
      `uvm_error("RegModel", "Cannot add field to locked register model");
      return;
   end

   if (field == null) `uvm_fatal("RegModel", "Attempting to register NULL field");

   // Store fields in LSB to MSB order
   offset = field.get_lsb_pos();

   idx = -1;
   foreach (m_fields[i]) begin
      if (offset < m_fields[i].get_lsb_pos()) begin
         int j = i;
         m_fields.insert(j, field);
         idx = i;
         break;
      end
   end
   if (idx < 0) begin
      m_fields.push_back(field);
      idx = m_fields.size()-1;
   end

   m_n_used_bits += field.get_n_bits();
   
   // Check if there are too many fields in the register
   if (m_n_used_bits > m_n_bits) begin
      `uvm_error("RegModel",
         $sformatf("Fields use more bits (%0d) than available in register \"%s\" (%0d)",
            m_n_used_bits, get_name(), m_n_bits));
   end

   // Check if there are overlapping fields
   if (idx > 0) begin
      if (m_fields[idx-1].get_lsb_pos() +
          m_fields[idx-1].get_n_bits() > offset) begin
         `uvm_error("RegModel", $sformatf("Field %s overlaps field %s in register \"%s\"",
                                        m_fields[idx-1].get_name(),
                                        field.get_name(), get_name()));
      end
   end
   if (idx < m_fields.size()-1) begin
      if (offset + field.get_n_bits() >
          m_fields[idx+1].get_lsb_pos()) begin
         `uvm_error("RegModel", $sformatf("Field %s overlaps field %s in register \"%s\"",
                                        field.get_name(),
                                        m_fields[idx+1].get_name(),
                                      get_name()));
      end
   end
endfunction: add_field


// Xlock_modelX

function void uvm_reg::Xlock_modelX();
   if (m_locked)
     return;
   m_locked = 1;
endfunction


//----------------------
// Group- User Frontdoor
//----------------------

// set_frontdoor

function void uvm_reg::set_frontdoor(uvm_reg_frontdoor ftdr,
                                     uvm_reg_map       map = null,
                                     string            fname = "",
                                     int               lineno = 0);
   uvm_reg_map_info map_info;
   ftdr.fname = m_fname;
   ftdr.lineno = m_lineno;
   map = get_local_map(map, "set_frontdoor()");
   if (map == null)
     return;
   map_info = map.get_reg_map_info(this);
   if (map_info == null)
      map.add_reg(this, -1, "RW", 1, ftdr);
   else begin
      map_info.frontdoor = ftdr;
   end
endfunction: set_frontdoor


// get_frontdoor

function uvm_reg_frontdoor uvm_reg::get_frontdoor(uvm_reg_map map = null);
   uvm_reg_map_info map_info;
   map = get_local_map(map, "get_frontdoor()");
   if (map == null)
     return null;
   map_info = map.get_reg_map_info(this);
   return map_info.frontdoor;
endfunction: get_frontdoor


// set_backdoor

function void uvm_reg::set_backdoor(uvm_reg_backdoor bkdr,
                                    string           fname = "",
                                    int              lineno = 0);
   bkdr.fname = fname;
   bkdr.lineno = lineno;
   if (m_backdoor != null &&
       m_backdoor.has_update_threads()) begin
      `uvm_warning("RegModel", "Previous register backdoor still has update threads running. Backdoors with active mirroring should only be set before simulation starts.");
   end
   m_backdoor = bkdr;
endfunction: set_backdoor


// get_backdoor

function uvm_reg_backdoor uvm_reg::get_backdoor(bit inherited = 1);

   if (m_backdoor == null && inherited) begin
     uvm_reg_block blk = get_parent();
     uvm_reg_backdoor bkdr;
     while (blk != null) begin
       bkdr = blk.get_backdoor();
       if (bkdr != null) begin
         m_backdoor = bkdr;
         break;
       end
       blk = blk.get_parent();
     end
   end
   return m_backdoor;
endfunction: get_backdoor



// clear_hdl_path

function void uvm_reg::clear_hdl_path(string kind = "RTL");
  if (kind == "ALL") begin
    m_hdl_paths_pool = new("hdl_paths");
    return;
  end

  if (kind == "") begin
     if (m_regfile_parent != null)
        kind = m_regfile_parent.get_default_hdl_path();
     else
        kind = m_parent.get_default_hdl_path();
  end

  if (!m_hdl_paths_pool.exists(kind)) begin
    `uvm_warning("RegModel",{"Unknown HDL Abstraction '",kind,"'"})
    return;
  end

  m_hdl_paths_pool.delete(kind);
endfunction


// add_hdl_path

function void uvm_reg::add_hdl_path(uvm_hdl_path_slice slices[],
                                    string kind = "RTL");
    uvm_queue #(uvm_hdl_path_concat) paths = m_hdl_paths_pool.get(kind);
    uvm_hdl_path_concat concat = new();

    concat.set(slices);
    paths.push_back(concat);
endfunction


// add_hdl_path_slice

function void uvm_reg::add_hdl_path_slice(string name,
                                          int offset,
                                          int size,
                                          bit first = 0,
                                          string kind = "RTL");
    uvm_queue #(uvm_hdl_path_concat) paths = m_hdl_paths_pool.get(kind);
    uvm_hdl_path_concat concat;
    
    if (first || paths.size() == 0) begin
       concat = new();
       paths.push_back(concat);
    end
    else
       concat = paths.get(paths.size()-1);

   concat.add_path(name, offset, size);
endfunction


// has_hdl_path

function bit  uvm_reg::has_hdl_path(string kind = "");
  if (kind == "") begin
     if (m_regfile_parent != null)
        kind = m_regfile_parent.get_default_hdl_path();
     else
        kind = m_parent.get_default_hdl_path();
  end

  return m_hdl_paths_pool.exists(kind);
endfunction


// get_hdl_path_kinds

function void uvm_reg::get_hdl_path_kinds (ref string kinds[$]);
  string kind;
  kinds.delete();
  if (!m_hdl_paths_pool.first(kind))
    return;
  do
    kinds.push_back(kind);
  while (m_hdl_paths_pool.next(kind));
endfunction


// get_hdl_path

function void uvm_reg::get_hdl_path(ref uvm_hdl_path_concat paths[$],
                                        input string kind = "");

  uvm_queue #(uvm_hdl_path_concat) hdl_paths;

  if (kind == "") begin
     if (m_regfile_parent != null)
        kind = m_regfile_parent.get_default_hdl_path();
     else
        kind = m_parent.get_default_hdl_path();
  end

  if (!has_hdl_path(kind)) begin
    `uvm_error("RegModel",
       {"Register does not have hdl path defined for abstraction '",kind,"'"})
    return;
  end

  hdl_paths = m_hdl_paths_pool.get(kind);

  for (int i=0; i<hdl_paths.size();i++) begin
     paths.push_back(hdl_paths.get(i));
  end

endfunction


// get_full_hdl_path

function void uvm_reg::get_full_hdl_path(ref uvm_hdl_path_concat paths[$],
                                         input string kind = "",
                                         input string separator = ".");

   if (kind == "") begin
      if (m_regfile_parent != null)
         kind = m_regfile_parent.get_default_hdl_path();
      else
         kind = m_parent.get_default_hdl_path();
   end
   
   if (!has_hdl_path(kind)) begin
      `uvm_error("RegModel",
         {"Register ",get_full_name()," does not have hdl path defined for abstraction '",kind,"'"})
      return;
   end

   begin
      uvm_queue #(uvm_hdl_path_concat) hdl_paths = m_hdl_paths_pool.get(kind);
      string parent_paths[$];

      if (m_regfile_parent != null)
         m_regfile_parent.get_full_hdl_path(parent_paths, kind, separator);
      else
         m_parent.get_full_hdl_path(parent_paths, kind, separator);

      for (int i=0; i<hdl_paths.size();i++) begin
         uvm_hdl_path_concat hdl_concat = hdl_paths.get(i);

         foreach (parent_paths[j])  begin
            uvm_hdl_path_concat t = new;

            foreach (hdl_concat.slices[k]) begin
               if (hdl_concat.slices[k].path == "")
                  t.add_path(parent_paths[j]);
               else
                  t.add_path({ parent_paths[j], separator, hdl_concat.slices[k].path },
                             hdl_concat.slices[k].offset,
                             hdl_concat.slices[k].size);
            end
            paths.push_back(t);
         end
      end
   end
endfunction


// set_offset

function void uvm_reg::set_offset (uvm_reg_map    map,
                                   uvm_reg_addr_t offset,
                                   bit unmapped = 0);

   uvm_reg_map orig_map = map;

   if (m_maps.num() > 1 && map == null) begin
      `uvm_error("RegModel",{"set_offset requires a non-null map when register '",
                 get_full_name(),"' belongs to more than one map."})
      return;
   end

   map = get_local_map(map,"set_offset()");

   if (map == null)
     return;
   
   map.m_set_reg_offset(this, offset, unmapped);
endfunction


// set_parent

function void uvm_reg::set_parent(uvm_reg_block blk_parent,
                                      uvm_reg_file regfile_parent);
  if (m_parent != null) begin
     // ToDo: remove register from previous parent
  end
  m_parent = blk_parent;
  m_regfile_parent = regfile_parent;
endfunction


// get_parent

function uvm_reg_block uvm_reg::get_parent();
  return get_block();
endfunction


// get_regfile

function uvm_reg_file uvm_reg::get_regfile();
   return m_regfile_parent;
endfunction


// get_full_name

function string uvm_reg::get_full_name();

   if (m_regfile_parent != null)
      return {m_regfile_parent.get_full_name(), ".", get_name()};

   if (m_parent != null)
      return {m_parent.get_full_name(), ".", get_name()};
   
   return get_name();
endfunction: get_full_name


// add_map

function void uvm_reg::add_map(uvm_reg_map map);
  m_maps[map] = 1;
endfunction


// get_maps

function void uvm_reg::get_maps(ref uvm_reg_map maps[$]);
   foreach (m_maps[map])
     maps.push_back(map);
endfunction


// get_n_maps

function int uvm_reg::get_n_maps();
   return m_maps.num();
endfunction


// is_in_map

function bit uvm_reg::is_in_map(uvm_reg_map map);
   if (m_maps.exists(map))
     return 1;
   foreach (m_maps[l]) begin
     uvm_reg_map local_map = l;
     uvm_reg_map parent_map = local_map.get_parent_map();

     while (parent_map != null) begin
       if (parent_map == map)
         return 1;
       parent_map = parent_map.get_parent_map();
     end
   end
   return 0;
endfunction



// get_local_map

function uvm_reg_map uvm_reg::get_local_map(uvm_reg_map map, string caller="");
   if (map == null)
     return get_default_map();
   if (m_maps.exists(map))
     return map; 
   foreach (m_maps[l]) begin
     uvm_reg_map local_map=l;
     uvm_reg_map parent_map = local_map.get_parent_map();

     while (parent_map != null) begin
       if (parent_map == map)
         return local_map;
       parent_map = parent_map.get_parent_map();
     end
   end
   `uvm_warning("RegModel", 
       {"Register '",get_full_name(),"' is not contained within map '",map.get_full_name(),"'",
        (caller == "" ? "": {" (called from ",caller,")"}) })
   return null;
endfunction



// get_default_map

function uvm_reg_map uvm_reg::get_default_map(string caller="");

   // if reg is not associated with any map, return null
   if (m_maps.num() == 0) begin
      `uvm_warning("RegModel", 
        {"Register '",get_full_name(),"' is not registered with any map",
         (caller == "" ? "": {" (called from ",caller,")"})})
      return null;
   end

   // if only one map, choose that
   if (m_maps.num() == 1) begin
     uvm_reg_map map;
     void'(m_maps.first(map));
     return map;
   end

   // try to choose one based on default_map in parent blocks.
   foreach (m_maps[l]) begin
     uvm_reg_map map = l;
     uvm_reg_block blk = map.get_parent();
     uvm_reg_map default_map = blk.get_default_map();
     if (default_map != null) begin
       uvm_reg_map local_map = get_local_map(default_map,"get_default_map()");
       if (local_map != null)
         return local_map;
     end
   end

   // if that fails, choose the first in this reg's maps

   begin
     uvm_reg_map map;
     void'(m_maps.first(map));
     return map;
   end

endfunction


// get_rights

function string uvm_reg::get_rights(uvm_reg_map map = null);

   uvm_reg_map_info info;

   map = get_local_map(map,"get_rights()");

   if (map == null)
     return "RW";

   info = map.get_reg_map_info(this);
   return info.rights;

endfunction



// get_block

function uvm_reg_block uvm_reg::get_block();
   get_block = m_parent;
endfunction


// get_offset

function uvm_reg_addr_t uvm_reg::get_offset(uvm_reg_map map = null);

   uvm_reg_map_info map_info;
   uvm_reg_map orig_map = map;

   map = get_local_map(map,"get_offset()");

   if (map == null)
     return -1;
   
   map_info = map.get_reg_map_info(this);
   
   if (map_info.unmapped) begin
      `uvm_warning("RegModel", {"Register '",get_name(),
                   "' is unmapped in map '",
                   ((orig_map == null) ? map.get_full_name() : orig_map.get_full_name()),"'"})
      return -1;
   end
         
   return map_info.offset;

endfunction


// get_addresses

function int uvm_reg::get_addresses(uvm_reg_map map=null, ref uvm_reg_addr_t addr[]);

   uvm_reg_map_info map_info;
   uvm_reg_map system_map;
   uvm_reg_map orig_map = map;

   map = get_local_map(map,"get_addresses()");

   if (map == null)
     return -1;

   map_info = map.get_reg_map_info(this);

   if (map_info.unmapped) begin
      `uvm_warning("RegModel", {"Register '",get_name(),
                   "' is unmapped in map '",
                   ((orig_map == null) ? map.get_full_name() : orig_map.get_full_name()),"'"})
      return -1;
   end
 
   addr = map_info.addr;
   system_map = map.get_root_map();
   return map.get_n_bytes();

endfunction


// get_address

function uvm_reg_addr_t uvm_reg::get_address(uvm_reg_map map = null);
   uvm_reg_addr_t  addr[];
   void'(get_addresses(map,addr));
   return addr[0];
endfunction


// get_n_bits

function int unsigned uvm_reg::get_n_bits();
   return m_n_bits;
endfunction


// get_n_bytes

function int unsigned uvm_reg::get_n_bytes();
   return ((m_n_bits-1) / 8) + 1;
endfunction


// get_max_size

function int unsigned uvm_reg::get_max_size();
   return m_max_size;
endfunction: get_max_size


// get_fields

function void uvm_reg::get_fields(ref uvm_reg_field fields[$]);
   foreach(m_fields[i])
      fields.push_back(m_fields[i]);
endfunction


// get_field_by_name

function uvm_reg_field uvm_reg::get_field_by_name(string name);
   foreach (m_fields[i])
      if (m_fields[i].get_name() == name)
         return m_fields[i];
   `uvm_warning("RegModel", {"Unable to locate field '",name,
                            "' in register '",get_name(),"'"})
   return null;
endfunction


// Xget_field_accessX
//
// Returns "WO" if all of the fields in the registers are write-only
// Returns "RO" if all of the fields in the registers are read-only
// Returns "RW" otherwise.

function string uvm_reg::Xget_fields_accessX(uvm_reg_map map);
   bit is_R;
   bit is_W;
   
   foreach(m_fields[i]) begin
      case (m_fields[i].get_access(map))
       "RO",
         "RC",
         "RS":
            is_R = 1;
       
       "WO",
          "WOC",
          "WOS",
          "WO1":
             is_W = 1;
       
       default:
          return "RW";
      endcase
      
      if (is_R && is_W) return "RW";
   end

   case ({is_R, is_W})
    2'b01: return "WO";
    2'b10: return "RO";
   endcase
   return "RW";
endfunction

      
//---------
// COVERAGE
//---------


// include_coverage

function void uvm_reg::include_coverage(string scope,
                                        uvm_reg_cvr_t models,
                                        uvm_object accessor = null);
   uvm_reg_cvr_rsrc_db::set({"uvm_reg::", scope},
                            "include_coverage",
                            models, accessor);
endfunction


// build_coverage

function uvm_reg_cvr_t uvm_reg::build_coverage(uvm_reg_cvr_t models);
   build_coverage = UVM_NO_COVERAGE;
   void'(uvm_reg_cvr_rsrc_db::read_by_name({"uvm_reg::", get_full_name()},
                                           "include_coverage",
                                           build_coverage, this));
   return build_coverage & models;
endfunction: build_coverage


// add_coverage

function void uvm_reg::add_coverage(uvm_reg_cvr_t models);
   m_has_cover |= models;
endfunction: add_coverage


// has_coverage

function bit uvm_reg::has_coverage(uvm_reg_cvr_t models);
   return ((m_has_cover & models) == models);
endfunction: has_coverage


// set_coverage

function uvm_reg_cvr_t uvm_reg::set_coverage(uvm_reg_cvr_t is_on);
   if (is_on == uvm_reg_cvr_t'(UVM_NO_COVERAGE)) begin
      m_cover_on = is_on;
      return m_cover_on;
   end

   m_cover_on = m_has_cover & is_on;

   return m_cover_on;
endfunction: set_coverage


// get_coverage

function bit uvm_reg::get_coverage(uvm_reg_cvr_t is_on);
   if (has_coverage(is_on) == 0)
      return 0;
   return ((m_cover_on & is_on) == is_on);
endfunction: get_coverage



//---------
// ACCESS
//---------


// set

function void uvm_reg::set(uvm_reg_data_t  value,
                           string          fname = "",
                           int             lineno = 0);
   // Split the value into the individual fields
   m_fname = fname;
   m_lineno = lineno;

   foreach (m_fields[i])
      m_fields[i].set((value >> m_fields[i].get_lsb_pos()) &
                       ((1 << m_fields[i].get_n_bits()) - 1));
endfunction: set


// predict

function bit uvm_reg::predict (uvm_reg_data_t    value,
                               uvm_reg_byte_en_t be = -1,
                               uvm_predict_e     kind = UVM_PREDICT_DIRECT,
                               uvm_path_e        path = UVM_FRONTDOOR,
                               uvm_reg_map       map = null,
                               string            fname = "",
                               int               lineno = 0);
  uvm_reg_item rw = new;
  rw.value[0] = value;
  rw.path = path;
  rw.map = map;
  rw.fname = fname;
  rw.lineno = lineno;
  do_predict(rw, kind, be);
  predict = (rw.status == UVM_NOT_OK) ? 0 : 1;
endfunction: predict


// do_predict

function void uvm_reg::do_predict(uvm_reg_item      rw,
                                  uvm_predict_e     kind = UVM_PREDICT_DIRECT,
                                  uvm_reg_byte_en_t be = -1);

   uvm_reg_data_t reg_value = rw.value[0];
   m_fname = rw.fname;
   m_lineno = rw.lineno;

   rw.status = UVM_IS_OK;

   if (m_is_busy && kind == UVM_PREDICT_DIRECT) begin
      `uvm_warning("RegModel", {"Trying to predict value of register '",
                  get_full_name(),"' while it is being accessed"})
      rw.status = UVM_NOT_OK;
      return;
   end
   
   foreach (m_fields[i]) begin
      rw.value[0] = (reg_value >> m_fields[i].get_lsb_pos()) &
                                 ((1 << m_fields[i].get_n_bits())-1);
      m_fields[i].do_predict(rw, kind, be>>(m_fields[i].get_lsb_pos()/8));
   end

   rw.value[0] = reg_value;

endfunction: do_predict


// get

function uvm_reg_data_t  uvm_reg::get(string  fname = "",
                                      int     lineno = 0);
   // Concatenate the value of the individual fields
   // to form the register value
   m_fname = fname;
   m_lineno = lineno;

   get = 0;
   
   foreach (m_fields[i])
      get |= m_fields[i].get() << m_fields[i].get_lsb_pos();
endfunction: get


// get_mirrored_value

function uvm_reg_data_t  uvm_reg::get_mirrored_value(string  fname = "",
                                      int     lineno = 0);
   // Concatenate the value of the individual fields
   // to form the register value
   m_fname = fname;
   m_lineno = lineno;

   get_mirrored_value = 0;
   
   foreach (m_fields[i])
      get_mirrored_value |= m_fields[i].get_mirrored_value() << m_fields[i].get_lsb_pos();
endfunction: get_mirrored_value


// reset

function void uvm_reg::reset(string kind = "HARD");
   foreach (m_fields[i])
      m_fields[i].reset(kind);
   // Put back a key in the semaphore if it is checked out
   // in case a thread was killed during an operation
   void'(m_atomic.try_get(1));
   m_atomic.put(1);
   m_process = null;
endfunction: reset


// get_reset

function uvm_reg_data_t uvm_reg::get_reset(string kind = "HARD");
   // Concatenate the value of the individual fields
   // to form the register value
   get_reset = 0;
   
   foreach (m_fields[i])
      get_reset |= m_fields[i].get_reset(kind) << m_fields[i].get_lsb_pos();
endfunction: get_reset


// has_reset

function bit uvm_reg::has_reset(string kind = "HARD",
                                bit    delete = 0);

   has_reset = 0;
   foreach (m_fields[i]) begin
      has_reset |= m_fields[i].has_reset(kind, delete);
      if (!delete && has_reset)
        return 1;
   end
endfunction: has_reset


// set_reset

function void uvm_reg::set_reset(uvm_reg_data_t value,
                                 string         kind = "HARD");
   foreach (m_fields[i]) begin
      m_fields[i].set_reset(value >> m_fields[i].get_lsb_pos(), kind);
   end
endfunction: set_reset


//-----------
// BUS ACCESS
//-----------

// needs_update

function bit uvm_reg::needs_update();
   needs_update = 0;
   foreach (m_fields[i]) begin
      if (m_fields[i].needs_update()) begin
         return 1;
      end
   end
endfunction: needs_update


// update

task uvm_reg::update(output uvm_status_e      status,
                     input  uvm_path_e        path = UVM_DEFAULT_PATH,
                     input  uvm_reg_map       map = null,
                     input  uvm_sequence_base parent = null,
                     input  int               prior = -1,
                     input  uvm_object        extension = null,
                     input  string            fname = "",
                     input  int               lineno = 0);
   uvm_reg_data_t upd;

   status = UVM_IS_OK;

   if (!needs_update()) return;

   // Concatenate the write-to-update values from each field
   // Fields are stored in LSB or MSB order
   upd = 0;
   foreach (m_fields[i])
      upd |= m_fields[i].XupdateX() << m_fields[i].get_lsb_pos();

   write(status, upd, path, map, parent, prior, extension, fname, lineno);
endtask: update



// write

task uvm_reg::write(output uvm_status_e      status,
                    input  uvm_reg_data_t    value,
                    input  uvm_path_e        path = UVM_DEFAULT_PATH,
                    input  uvm_reg_map       map = null,
                    input  uvm_sequence_base parent = null,
                    input  int               prior = -1,
                    input  uvm_object        extension = null,
                    input  string            fname = "",
                    input  int               lineno = 0);

   // create an abstract transaction for this operation
   uvm_reg_item rw;

   XatomicX(1);

   set(value);

   rw = uvm_reg_item::type_id::create("write_item",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_REG;
   rw.kind         = UVM_WRITE;
   rw.value[0]     = value;
   rw.path         = path;
   rw.map          = map;
   rw.parent       = parent;
   rw.prior        = prior;
   rw.extension    = extension;
   rw.fname        = fname;
   rw.lineno       = lineno;

   do_write(rw);

   status = rw.status;

   XatomicX(0);

endtask


// do_write

task uvm_reg::do_write (uvm_reg_item rw);

   uvm_reg_cb_iter  cbs = new(this);
   uvm_reg_map_info map_info;
   uvm_reg_data_t   value; 

   m_fname  = rw.fname;
   m_lineno = rw.lineno;

   if (!Xcheck_accessX(rw,map_info,"write()"))
     return;

   XatomicX(1);

   m_write_in_progress = 1'b1;

   rw.value[0] &= ((1 << m_n_bits)-1);
   value = rw.value[0];

   rw.status = UVM_IS_OK;

   // PRE-WRITE CBS - FIELDS
   begin : pre_write_callbacks
      uvm_reg_data_t  msk;
      int lsb;

      foreach (m_fields[i]) begin
         uvm_reg_field_cb_iter cbs = new(m_fields[i]);
         uvm_reg_field f = m_fields[i];
         lsb = f.get_lsb_pos();
         msk = ((1<<f.get_n_bits())-1) << lsb;
         rw.value[0] = (value & msk) >> lsb;
         f.pre_write(rw);
         for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next()) begin
            rw.element = f;
            rw.element_kind = UVM_FIELD;
            cb.pre_write(rw);
         end

         value = (value & ~msk) | (rw.value[0] << lsb);
      end
   end
   rw.element = this;
   rw.element_kind = UVM_REG;
   rw.value[0] = value;

   // PRE-WRITE CBS - REG
   pre_write(rw);
   for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
      cb.pre_write(rw);

   if (rw.status != UVM_IS_OK) begin
     m_write_in_progress = 1'b0;

     XatomicX(0);
         
     return;
   end
         
   // EXECUTE WRITE...
   case (rw.path)
      
      // ...VIA USER BACKDOOR
      UVM_BACKDOOR: begin
         uvm_reg_data_t final_val;
         uvm_reg_backdoor bkdr = get_backdoor();

         value = rw.value[0];

         // Mimick the final value after a physical read
         rw.kind = UVM_READ;
         if (bkdr != null)
           bkdr.read(rw);
         else
           backdoor_read(rw);

         if (rw.status == UVM_NOT_OK) begin
           m_write_in_progress = 1'b0;
           return;
         end

         begin
            foreach (m_fields[i]) begin
               uvm_reg_data_t field_val;
               int lsb = m_fields[i].get_lsb_pos();
               int sz  = m_fields[i].get_n_bits();
               field_val = m_fields[i].XpredictX((rw.value[0] >> lsb) & ((1<<sz)-1),
                                                 (value >> lsb) & ((1<<sz)-1),
                                                 rw.local_map);
               final_val |= field_val << lsb;
            end
         end
         rw.kind = UVM_WRITE;
         rw.value[0] = final_val;

         if (bkdr != null)
           bkdr.write(rw);
         else
           backdoor_write(rw);

         do_predict(rw, UVM_PREDICT_WRITE);
      end

      UVM_FRONTDOOR: begin

         uvm_reg_map system_map = rw.local_map.get_root_map();

         m_is_busy = 1;

         // ...VIA USER FRONTDOOR
         if (map_info.frontdoor != null) begin
            uvm_reg_frontdoor fd = map_info.frontdoor;
            fd.rw_info = rw;
            if (fd.sequencer == null)
              fd.sequencer = system_map.get_sequencer();
            fd.start(fd.sequencer, rw.parent);
         end

         // ...VIA BUILT-IN FRONTDOOR
         else begin : built_in_frontdoor

            rw.local_map.do_write(rw);

         end

         m_is_busy = 0;

         if (system_map.get_auto_predict()) begin
            uvm_status_e status;
            if (rw.status != UVM_NOT_OK) begin
               sample(value, -1, 0, rw.map);
               m_parent.XsampleX(map_info.offset, 0, rw.map);
            end

            status = rw.status; // do_predict will override rw.status, so we save it here
            do_predict(rw, UVM_PREDICT_WRITE);
            rw.status = status;
         end
      end
      
   endcase

   value = rw.value[0];

   // POST-WRITE CBS - REG
   for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
      cb.post_write(rw);
   post_write(rw);

   // POST-WRITE CBS - FIELDS
   foreach (m_fields[i]) begin
      uvm_reg_field_cb_iter cbs = new(m_fields[i]);
      uvm_reg_field f = m_fields[i];
      
      rw.element = f;
      rw.element_kind = UVM_FIELD;
      rw.value[0] = (value >> f.get_lsb_pos()) & ((1<<f.get_n_bits())-1);
      
      for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
         cb.post_write(rw);
      f.post_write(rw);
   end
   
   rw.value[0] = value;
   rw.element = this;
   rw.element_kind = UVM_REG;

   // REPORT
   if (uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")) begin
     string path_s,value_s;
     if (rw.path == UVM_FRONTDOOR)
       path_s = (map_info.frontdoor != null) ? "user frontdoor" :
                                               {"map ",rw.map.get_full_name()};
     else
       path_s = (get_backdoor() != null) ? "user backdoor" : "DPI backdoor";

     value_s = $sformatf("=0x%0h",rw.value[0]);

      uvm_report_info("RegModel", {"Wrote register via ",path_s,": ",
                                   get_full_name(),value_s}, UVM_HIGH);
   end

   m_write_in_progress = 1'b0;

   XatomicX(0);

endtask: do_write

// read

task uvm_reg::read(output uvm_status_e      status,
                   output uvm_reg_data_t    value,
                   input  uvm_path_e        path = UVM_DEFAULT_PATH,
                   input  uvm_reg_map       map = null,
                   input  uvm_sequence_base parent = null,
                   input  int               prior = -1,
                   input  uvm_object        extension = null,
                   input  string            fname = "",
                   input  int               lineno = 0);
   XatomicX(1);
   XreadX(status, value, path, map, parent, prior, extension, fname, lineno);
   XatomicX(0);
endtask: read


// XreadX

task uvm_reg::XreadX(output uvm_status_e      status,
                     output uvm_reg_data_t    value,
                     input  uvm_path_e        path,
                     input  uvm_reg_map       map,
                     input  uvm_sequence_base parent = null,
                     input  int               prior = -1,
                     input  uvm_object        extension = null,
                     input  string            fname = "",
                     input  int               lineno = 0);
   
   // create an abstract transaction for this operation
   uvm_reg_item rw;
   rw = uvm_reg_item::type_id::create("read_item",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_REG;
   rw.kind         = UVM_READ;
   rw.value[0]     = 0;
   rw.path         = path;
   rw.map          = map;
   rw.parent       = parent;
   rw.prior        = prior;
   rw.extension    = extension;
   rw.fname        = fname;
   rw.lineno       = lineno;

   do_read(rw);

   status = rw.status;
   value = rw.value[0];

endtask: XreadX


// do_read

task uvm_reg::do_read(uvm_reg_item rw);

   uvm_reg_cb_iter  cbs = new(this);
   uvm_reg_map_info map_info;
   uvm_reg_data_t   value;
   uvm_reg_data_t   exp;

   m_fname   = rw.fname;
   m_lineno  = rw.lineno;
   
   if (!Xcheck_accessX(rw,map_info,"read()"))
     return;

   m_read_in_progress = 1'b1;

   rw.status = UVM_IS_OK;

   // PRE-READ CBS - FIELDS
   foreach (m_fields[i]) begin
      uvm_reg_field_cb_iter cbs = new(m_fields[i]);
      uvm_reg_field f = m_fields[i];
      rw.element = f;
      rw.element_kind = UVM_FIELD;
      m_fields[i].pre_read(rw);
      for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
         cb.pre_read(rw);
   end

   rw.element = this;
   rw.element_kind = UVM_REG;

   // PRE-READ CBS - REG
   pre_read(rw);
   for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
      cb.pre_read(rw);

   if (rw.status != UVM_IS_OK) begin
     m_read_in_progress = 1'b0;

     return;
   end
         
   // EXECUTE READ...
   case (rw.path)
      
      // ...VIA USER BACKDOOR
      UVM_BACKDOOR: begin
         uvm_reg_backdoor bkdr = get_backdoor();

         uvm_reg_map map = uvm_reg_map::backdoor();
         if (map.get_check_on_read()) exp = get();
   
         if (bkdr != null)
           bkdr.read(rw);
         else
           backdoor_read(rw);

         value = rw.value[0];

         // Need to clear RC fields, set RS fields and mask WO fields
         if (rw.status != UVM_NOT_OK) begin

            uvm_reg_data_t wo_mask;

            foreach (m_fields[i]) begin
               string acc = m_fields[i].get_access(uvm_reg_map::backdoor());
               if (acc == "RC" ||
                   acc == "WRC" ||
                   acc == "WSRC" ||
                   acc == "W1SRC" ||
                   acc == "W0SRC") begin
                  value &= ~(((1<<m_fields[i].get_n_bits())-1)
                                          << m_fields[i].get_lsb_pos());
               end
               else if (acc == "RS" ||
                        acc == "WRS" ||
                        acc == "WCRS" ||
                        acc == "W1CRS" ||
                        acc == "W0CRS") begin
                  value |= (((1<<m_fields[i].get_n_bits())-1)
                                          << m_fields[i].get_lsb_pos());
               end
               else if (acc == "WO" ||
                        acc == "WOC" ||
                        acc == "WOS" ||
                        acc == "WO1") begin
                  wo_mask |= ((1<<m_fields[i].get_n_bits())-1)
                                          << m_fields[i].get_lsb_pos();
               end
            end

            if (value != rw.value[0]) begin
              uvm_reg_data_t saved;
              saved = rw.value[0];
              rw.value[0] = value;
              if (bkdr != null)
                 bkdr.write(rw);
              else
                 backdoor_write(rw);
              rw.value[0] = saved;
            end

            rw.value[0] &= ~wo_mask;

            if (map.get_check_on_read() &&
               rw.status != UVM_NOT_OK) begin
               void'(do_check(exp, rw.value[0], map));
            end
       
            do_predict(rw, UVM_PREDICT_READ);
         end
      end


      UVM_FRONTDOOR: begin

         uvm_reg_map system_map = rw.local_map.get_root_map();

         m_is_busy = 1;

         if (rw.local_map.get_check_on_read()) exp = get();
   
         // ...VIA USER FRONTDOOR
         if (map_info.frontdoor != null) begin
            uvm_reg_frontdoor fd = map_info.frontdoor;
            fd.rw_info = rw;
            if (fd.sequencer == null)
              fd.sequencer = system_map.get_sequencer();
            fd.start(fd.sequencer, rw.parent);
         end

         // ...VIA BUILT-IN FRONTDOOR
         else begin
            rw.local_map.do_read(rw);
         end

         m_is_busy = 0;

         if (system_map.get_auto_predict()) begin
            uvm_status_e status;
            if (rw.local_map.get_check_on_read() &&
                rw.status != UVM_NOT_OK) begin
               void'(do_check(exp, rw.value[0], system_map));
            end

            if (rw.status != UVM_NOT_OK) begin
               sample(rw.value[0], -1, 1, rw.map);
               m_parent.XsampleX(map_info.offset, 1, rw.map);
            end

            status = rw.status; // do_predict will override rw.status, so we save it here
            do_predict(rw, UVM_PREDICT_READ);
            rw.status = status;
         end
      end
      
   endcase

   value = rw.value[0]; // preserve 

   // POST-READ CBS - REG
   for (uvm_reg_cbs cb = cbs.first(); cb != null; cb = cbs.next())
      cb.post_read(rw);
   post_read(rw);

   // POST-READ CBS - FIELDS
   foreach (m_fields[i]) begin
      uvm_reg_field_cb_iter cbs = new(m_fields[i]);
      uvm_reg_field f = m_fields[i];

      rw.element = f;
      rw.element_kind = UVM_FIELD;
      rw.value[0] = (value >> f.get_lsb_pos()) & ((1<<f.get_n_bits())-1);

      for (uvm_reg_cbs cb=cbs.first(); cb!=null; cb=cbs.next())
         cb.post_read(rw);
      f.post_read(rw);
   end

   rw.value[0] = value; // restore
   rw.element = this;
   rw.element_kind = UVM_REG;

   // REPORT
   if (uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")) begin
     string path_s,value_s;
     if (rw.path == UVM_FRONTDOOR)
       path_s = (map_info.frontdoor != null) ? "user frontdoor" :
                                               {"map ",rw.map.get_full_name()};
     else
       path_s = (get_backdoor() != null) ? "user backdoor" : "DPI backdoor";

     value_s = $sformatf("=%0h",rw.value[0]);

      uvm_report_info("RegModel", {"Read  register via ",path_s,": ",
                                   get_full_name(),value_s}, UVM_HIGH);
   end

   m_read_in_progress = 1'b0;

endtask: do_read


// Xcheck_accessX

function bit uvm_reg::Xcheck_accessX (input uvm_reg_item rw,
                                      output uvm_reg_map_info map_info,
                                      input string caller);


   if (rw.path == UVM_DEFAULT_PATH)
     rw.path = m_parent.get_default_path();

   if (rw.path == UVM_BACKDOOR) begin
      if (get_backdoor() == null && !has_hdl_path()) begin
         `uvm_warning("RegModel",
            {"No backdoor access available for register '",get_full_name(),
            "' . Using frontdoor instead."})
         rw.path = UVM_FRONTDOOR;
      end
      else
        rw.map = uvm_reg_map::backdoor();
   end


   if (rw.path != UVM_BACKDOOR) begin

     rw.local_map = get_local_map(rw.map,caller);

     if (rw.local_map == null) begin
        `uvm_error(get_type_name(), 
           {"No transactor available to physically access register on map '",
            rw.map.get_full_name(),"'"})
        rw.status = UVM_NOT_OK;
        return 0;
     end

     map_info = rw.local_map.get_reg_map_info(this);

     if (map_info.frontdoor == null && map_info.unmapped) begin
          `uvm_error("RegModel", {"Register '",get_full_name(),
             "' unmapped in map '",
             (rw.map==null)? rw.local_map.get_full_name():rw.map.get_full_name(),
             "' and does not have a user-defined frontdoor"})
          rw.status = UVM_NOT_OK;
          return 0;
     end

     if (rw.map == null)
       rw.map = rw.local_map;
   end
   return 1;
endfunction


// is_busy

function bit uvm_reg::is_busy();
   return m_is_busy;
endfunction
    

// Xset_busyX

function void uvm_reg::Xset_busyX(bit busy);
   m_is_busy = busy;
endfunction
    

// Xis_loacked_by_fieldX

function bit uvm_reg::Xis_locked_by_fieldX();
  return m_is_locked_by_field;
endfunction
    

// backdoor_write

task  uvm_reg::backdoor_write(uvm_reg_item rw);
  uvm_hdl_path_concat paths[$];
  bit ok=1;
  get_full_hdl_path(paths,rw.bd_kind);
  foreach (paths[i]) begin
     uvm_hdl_path_concat hdl_concat = paths[i];
     foreach (hdl_concat.slices[j]) begin
        `uvm_info("RegMem", {"backdoor_write to ",
                  hdl_concat.slices[j].path},UVM_DEBUG)

        if (hdl_concat.slices[j].offset < 0) begin
           ok &= uvm_hdl_deposit(hdl_concat.slices[j].path,rw.value[0]);
           continue;
        end
        begin
           uvm_reg_data_t slice;
           slice = rw.value[0] >> hdl_concat.slices[j].offset;
           slice &= (1 << hdl_concat.slices[j].size)-1;
           ok &= uvm_hdl_deposit(hdl_concat.slices[j].path, slice);
        end
     end
  end
  rw.status = (ok ? UVM_IS_OK : UVM_NOT_OK);
endtask


// backdoor_read

task  uvm_reg::backdoor_read (uvm_reg_item rw);
  rw.status = backdoor_read_func(rw);
endtask


// backdoor_read_func

function uvm_status_e uvm_reg::backdoor_read_func(uvm_reg_item rw);
  uvm_hdl_path_concat paths[$];
  uvm_reg_data_t val;
  bit ok=1;
  get_full_hdl_path(paths,rw.bd_kind);
  foreach (paths[i]) begin
     uvm_hdl_path_concat hdl_concat = paths[i];
     val = 0;
     foreach (hdl_concat.slices[j]) begin
        `uvm_info("RegMem", {"backdoor_read from %s ",
               hdl_concat.slices[j].path},UVM_DEBUG)

        if (hdl_concat.slices[j].offset < 0) begin
           ok &= uvm_hdl_read(hdl_concat.slices[j].path,val);
           continue;
        end
        begin
           uvm_reg_data_t slice;
           int k = hdl_concat.slices[j].offset;
           
           ok &= uvm_hdl_read(hdl_concat.slices[j].path, slice);
      
           repeat (hdl_concat.slices[j].size) begin
              val[k++] = slice[0];
              slice >>= 1;
           end
        end
     end

     val &= (1 << m_n_bits)-1;

     if (i == 0)
        rw.value[0] = val;

     if (val != rw.value[0]) begin
        `uvm_error("RegModel", $sformatf("Backdoor read of register %s with multiple HDL copies: values are not the same: %0h at path '%s', and %0h at path '%s'. Returning first value.",
               get_full_name(),
               rw.value[0], uvm_hdl_concat2string(paths[0]),
               val, uvm_hdl_concat2string(paths[i]))); 
        return UVM_NOT_OK;
      end
      `uvm_info("RegMem", 
         $sformatf("returned backdoor value 0x%0x",rw.value[0]),UVM_DEBUG);
      
  end

  rw.status = (ok) ? UVM_IS_OK : UVM_NOT_OK;
  return rw.status;
endfunction


// poke

task uvm_reg::poke(output uvm_status_e      status,
                   input  uvm_reg_data_t    value,
                   input  string            kind = "",
                   input  uvm_sequence_base parent = null,
                   input  uvm_object        extension = null,
                   input  string            fname = "",
                   input  int               lineno = 0);

   uvm_reg_backdoor bkdr = get_backdoor();
   uvm_reg_item rw;

   m_fname = fname;
   m_lineno = lineno;


   if (bkdr == null && !has_hdl_path(kind)) begin
      `uvm_error("RegModel",
        {"No backdoor access available to poke register '",get_full_name(),"'"})
      status = UVM_NOT_OK;
      return;
   end

   if (!m_is_locked_by_field)
     XatomicX(1);

   // create an abstract transaction for this operation
   rw = uvm_reg_item::type_id::create("reg_poke_item",,get_full_name());
   rw.element      = this;
   rw.path         = UVM_BACKDOOR;
   rw.element_kind = UVM_REG;
   rw.kind         = UVM_WRITE;
   rw.bd_kind      = kind;
   rw.value[0]     = value & ((1 << m_n_bits)-1);
   rw.parent       = parent;
   rw.extension    = extension;
   rw.fname        = fname;
   rw.lineno       = lineno;

   if (bkdr != null)
     bkdr.write(rw);
   else
     backdoor_write(rw);

   status = rw.status;

   `uvm_info("RegModel", $sformatf("Poked register \"%s\": 'h%h",
                              get_full_name(), value),UVM_HIGH);

   do_predict(rw, UVM_PREDICT_WRITE);

   if (!m_is_locked_by_field)
     XatomicX(0);
endtask: poke


// peek

task uvm_reg::peek(output uvm_status_e      status,
                   output uvm_reg_data_t    value,
                   input  string            kind = "",
                   input  uvm_sequence_base parent = null,
                   input  uvm_object        extension = null,
                   input  string            fname = "",
                   input  int               lineno = 0);

   uvm_reg_backdoor bkdr = get_backdoor();
   uvm_reg_item rw;

   m_fname = fname;
   m_lineno = lineno;

   if (bkdr == null && !has_hdl_path(kind)) begin
      `uvm_error("RegModel",
        $sformatf("No backdoor access available to peek register \"%s\"",
                  get_full_name()));
      status = UVM_NOT_OK;
      return;
   end

   if(!m_is_locked_by_field)
      XatomicX(1);

   // create an abstract transaction for this operation
   rw = uvm_reg_item::type_id::create("mem_peek_item",,get_full_name());
   rw.element      = this;
   rw.path         = UVM_BACKDOOR;
   rw.element_kind = UVM_REG;
   rw.kind         = UVM_READ;
   rw.bd_kind      = kind;
   rw.parent       = parent;
   rw.extension    = extension;
   rw.fname        = fname;
   rw.lineno       = lineno;

   if (bkdr != null)
     bkdr.read(rw);
   else
     backdoor_read(rw);

   status = rw.status;
   value = rw.value[0];

   `uvm_info("RegModel", $sformatf("Peeked register \"%s\": 'h%h",
                          get_full_name(), value),UVM_HIGH);

   do_predict(rw, UVM_PREDICT_READ);

   if (!m_is_locked_by_field)
      XatomicX(0);
endtask: peek


// do_check
function bit uvm_reg::do_check(input uvm_reg_data_t expected,
                               input uvm_reg_data_t actual,
                               uvm_reg_map          map);

   uvm_reg_data_t  dc = 0;

   foreach(m_fields[i]) begin
      string acc = m_fields[i].get_access(map);
      acc = acc.substr(0, 1);
      if (m_fields[i].get_compare() == UVM_NO_CHECK ||
          acc == "WO") begin
         dc |= ((1 << m_fields[i].get_n_bits())-1)
            << m_fields[i].get_lsb_pos();
      end
   end

   if ((actual|dc) === (expected|dc)) return 1;
   
   `uvm_error("RegModel", $sformatf("Register \"%s\" value read from DUT (0x%h) does not match mirrored value (0x%h)",
                                    get_full_name(), actual, (expected ^ ('x & dc))));
                                     
   foreach(m_fields[i]) begin
      string acc = m_fields[i].get_access(map);
      acc = acc.substr(0, 1);
      if (!(m_fields[i].get_compare() == UVM_NO_CHECK ||
            acc == "WO")) begin
         uvm_reg_data_t mask  = ((1 << m_fields[i].get_n_bits())-1);
         uvm_reg_data_t val   = actual   >> m_fields[i].get_lsb_pos() & mask;
         uvm_reg_data_t exp   = expected >> m_fields[i].get_lsb_pos() & mask;

         if (val !== exp) begin
            `uvm_info("RegModel",
                      $sformatf("Field %s (%s[%0d:%0d]) mismatch read=%0d'h%0h mirrored=%0d'h%0h ",
                                m_fields[i].get_name(), get_full_name(),
                                m_fields[i].get_lsb_pos() + m_fields[i].get_n_bits() - 1,
                                m_fields[i].get_lsb_pos(),
                                m_fields[i].get_n_bits(), val,
                                m_fields[i].get_n_bits(), exp),
                      UVM_NONE)
         end
      end
   end

   return 0;
endfunction
       

// mirror

task uvm_reg::mirror(output uvm_status_e       status,
                     input  uvm_check_e        check = UVM_NO_CHECK,
                     input  uvm_path_e         path = UVM_DEFAULT_PATH,
                     input  uvm_reg_map        map = null,
                     input  uvm_sequence_base  parent = null,
                     input  int                prior = -1,
                     input  uvm_object         extension = null,
                     input  string             fname = "",
                     input  int                lineno = 0);
   uvm_reg_data_t  v;
   uvm_reg_data_t  exp;
   uvm_reg_backdoor bkdr = get_backdoor();

   XatomicX(1);
   m_fname = fname;
   m_lineno = lineno;


   if (path == UVM_DEFAULT_PATH)
     path = m_parent.get_default_path();

   if (path == UVM_BACKDOOR && (bkdr != null || has_hdl_path()))
     map = uvm_reg_map::backdoor();
   else
     map = get_local_map(map, "read()");

   if (map == null)
     return;
   
   // Remember what we think the value is before it gets updated
   if (check == UVM_CHECK)
     exp = get_mirrored_value();

   XreadX(status, v, path, map, parent, prior, extension, fname, lineno);

   if (status == UVM_NOT_OK) begin
      XatomicX(0);
      return;
   end

   if (check == UVM_CHECK) void'(do_check(exp, v, map));

   XatomicX(0);
endtask: mirror


// XatomicX

task uvm_reg::XatomicX(bit on);
   process m_reg_process;
   m_reg_process=process::self();

   if (on) begin
     if (m_reg_process == m_process)
       return;
     m_atomic.get(1);
     m_process = m_reg_process; 
   end
   else begin
      // Maybe a key was put back in by a spurious call to reset()
      void'(m_atomic.try_get(1));
      m_atomic.put(1);
      m_process = null;
   end
endtask: XatomicX


//-------------
// STANDARD OPS
//-------------

// convert2string

function string uvm_reg::convert2string();
   string res_str;
   string t_str;
   bit with_debug_info;

   string prefix;

   $sformat(convert2string, "Register %s -- %0d bytes, mirror value:'h%h",
            get_full_name(), get_n_bytes(),get());

   if (m_maps.num()==0)
     convert2string = {convert2string, "  (unmapped)\n"};
   else
     convert2string = {convert2string, "\n"};
   foreach (m_maps[map]) begin
     uvm_reg_map parent_map = map;
     int unsigned offset;
     while (parent_map != null) begin
       uvm_reg_map this_map = parent_map;
       parent_map = this_map.get_parent_map();
       offset = parent_map == null ? this_map.get_base_addr(UVM_NO_HIER) :
                                     parent_map.get_submap_offset(this_map);
       prefix = {prefix, "  "};
       begin
            uvm_endianness_e e = this_map.get_endian();
            $sformat(convert2string, 
                "%sMapped in '%s' -- %d bytes, %s, offset 'h%0h\n",
                prefix, this_map.get_full_name(), this_map.get_n_bytes(),
                e.name(), offset);
       end
     end
   end
   prefix = "  ";
   foreach(m_fields[i]) begin
      $sformat(convert2string, "%s\n%s", convert2string,
               m_fields[i].convert2string());
   end

   if (m_read_in_progress == 1'b1) begin
      if (m_fname != "" && m_lineno != 0)
         $sformat(res_str, "%s:%0d ",m_fname, m_lineno);
      convert2string = {convert2string, "\n", res_str,
                        "currently executing read method"}; 
   end
   if ( m_write_in_progress == 1'b1) begin
      if (m_fname != "" && m_lineno != 0)
         $sformat(res_str, "%s:%0d ",m_fname, m_lineno);
      convert2string = {convert2string, "\n", res_str,
                        "currently executing write method"}; 
   end

endfunction: convert2string


// do_print

function void uvm_reg::do_print (uvm_printer printer);
  uvm_reg_field f[$];
  super.do_print(printer);
  get_fields(f);
  foreach(f[i]) printer.print_generic(f[i].get_name(),f[i].get_type_name(),-2,f[i].convert2string());
endfunction



// clone

function uvm_object uvm_reg::clone();
  `uvm_fatal("RegModel","RegModel registers cannot be cloned")
  return null;
endfunction

// do_copy

function void uvm_reg::do_copy(uvm_object rhs);
  `uvm_fatal("RegModel","RegModel registers cannot be copied")
endfunction


// do_compare

function bit uvm_reg::do_compare (uvm_object  rhs,
                                        uvm_comparer comparer);
  `uvm_warning("RegModel","RegModel registers cannot be compared")
  return 0;
endfunction


// do_pack

function void uvm_reg::do_pack (uvm_packer packer);
  `uvm_warning("RegModel","RegModel registers cannot be packed")
endfunction


// do_unpack

function void uvm_reg::do_unpack (uvm_packer packer);
  `uvm_warning("RegModel","RegModel registers cannot be unpacked")
endfunction


