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

//------------------------------------------------------------------------------
// Title: Virtual Registers
//------------------------------------------------------------------------------
//
// A virtual register is a collection of fields,
// overlaid on top of a memory, usually in an array.
// The semantics and layout of virtual registers comes from
// an agreement between the software and the hardware,
// not any physical structures in the DUT.
//
//------------------------------------------------------------------------------

typedef class uvm_mem_region;
typedef class uvm_mem_mam;

typedef class uvm_vreg_cbs;


//------------------------------------------------------------------------------
// Class: uvm_vreg
//
// Virtual register abstraction base class
//
// A virtual register represents a set of fields that are
// logically implemented in consecutive memory locations.
//
// All virtual register accesses eventually turn into memory accesses.
//
// A virtual register array may be implemented on top of
// any memory abstraction class and possibly dynamically
// resized and/or relocated.
//
//------------------------------------------------------------------------------

class uvm_vreg extends uvm_object;

   `uvm_register_cb(uvm_vreg, uvm_vreg_cbs)

   local bit locked;
   local uvm_reg_block parent;
   local int unsigned  n_bits;
   local int unsigned  n_used_bits;

   local uvm_vreg_field fields[$];   // Fields in LSB to MSB order

   local uvm_mem          mem;     // Where is it implemented?
   local uvm_reg_addr_t   offset;  // Start of vreg[0]
   local int unsigned     incr;    // From start to start of next
   local longint unsigned size;    //number of vregs
   local bit              is_static;

   local uvm_mem_region   region;    // Not NULL if implemented via MAM
  
   local semaphore atomic;   // Field RMW operations must be atomic
   local string fname;
   local int lineno;
   local bit read_in_progress;
   local bit write_in_progress;

   //
   // Group: Initialization
   //

   //
   // FUNCTION: new
   // Create a new instance and type-specific configuration
   //
   // Creates an instance of a virtual register abstraction class
   // with the specified name.
   //
   // ~n_bits~ specifies the total number of bits in a virtual register.
   // Not all bits need to be mapped to a virtual field.
   // This value is usually a multiple of 8.
   //
   extern function new(string       name,
                       int unsigned n_bits);
                       

   //
   // Function: configure
   // Instance-specific configuration
   //
   // Specify the ~parent~ block of this virtual register array.
   // If one of the other parameters are specified, the virtual register
   // is assumed to be dynamic and can be later (re-)implemented using
   // the <uvm_vreg::implement()> method.
   //
   // If ~mem~ is specified, then the virtual register array is assumed
   // to be statically implemented in the memory corresponding to the specified
   // memory abstraction class and ~size~, ~offset~ and ~incr~
   // must also be specified.
   // Static virtual register arrays cannot be re-implemented.
   //
   extern function void configure(uvm_reg_block     parent,
                                  uvm_mem       mem    = null,
                                  longint unsigned  size   = 0,
                                  uvm_reg_addr_t    offset = 0,
                                  int unsigned      incr   = 0);

   //
   // FUNCTION: implement
   // Dynamically implement, resize or relocate a virtual register array
   //
   // Implement an array of virtual registers of the specified
   // ~size~, in the specified memory and ~offset~.
   // If an offset increment is specified, each
   // virtual register is implemented at the specified offset increment
   // from the previous one.
   // If an offset increment of 0 is specified,
   // virtual registers are packed as closely as possible
   // in the memory.
   //
   // If no memory is specified, the virtual register array is
   // in the same memory, at the same base offset using the same
   // offset increment as originally implemented.
   // Only the number of virtual registers in the virtual register array
   // is modified.
   //
   // The initial value of the newly-implemented or
   // relocated set of virtual registers is whatever values
   // are currently stored in the memory now implementing them.
   //
   // Returns TRUE if the memory
   // can implement the number of virtual registers
   // at the specified base offset and offset increment.
   // Returns FALSE otherwise.
   //
   // The memory region used to implement a virtual register array
   // is reserved in the memory allocation manager associated with
   // the memory to prevent it from being allocated for another purpose.
   //
   extern virtual function bit implement(longint unsigned  n,
                                         uvm_mem       mem    = null,
                                         uvm_reg_addr_t    offset = 0,
                                         int unsigned      incr   = 0);

   //
   // FUNCTION: allocate
   // Randomly implement, resize or relocate a virtual register array
   //
   // Implement a virtual register array of the specified
   // size in a randomly allocated region of the appropriate size
   // in the address space managed by the specified memory allocation manager.
   //
   // The initial value of the newly-implemented
   // or relocated set of virtual registers is whatever values are
   // currently stored in the
   // memory region now implementing them.
   //
   // Returns a reference to a <uvm_mem_region> memory region descriptor
   // if the memory allocation manager was able to allocate a region
   // that can implement the virtual register array.
   // Returns ~null~ otherwise.
   //
   // A region implementing a virtual register array
   // must not be released using the <uvm_mem_mam::release_region()> method.
   // It must be released using the <uvm_vreg::release_region()> method.
   // 
   extern virtual function uvm_mem_region allocate(longint unsigned n,
                                                   uvm_mem_mam          mam);

   //
   // FUNCTION: get_region
   // Get the region where the virtual register array is implemented
   //
   // Returns a reference to the <uvm_mem_region> memory region descriptor
   // that implements the virtual register array.
   //
   // Returns ~null~ if the virtual registers array
   // is not currently implemented.
   // A region implementing a virtual register array
   // must not be released using the <uvm_mem_mam::release_region()> method.
   // It must be released using the <uvm_vreg::release_region()> method.
   // 
   extern virtual function uvm_mem_region get_region();

   //
   // FUNCTION: release_region
   // Dynamically un-implement a virtual register array
   //
   // Release the memory region used to implement a virtual register array
   // and return it to the pool of available memory 
   // that can be allocated by the memory's default allocation manager.
   // The virtual register array is subsequently considered as unimplemented
   // and can no longer be accessed.
   //
   // Statically-implemented virtual registers cannot be released.
   //
   extern virtual function void release_region();


   /*local*/ extern virtual function void set_parent(uvm_reg_block parent);
   /*local*/ extern function void Xlock_modelX();
   
   /*local*/ extern function void add_field(uvm_vreg_field field);
   /*local*/ extern task XatomicX(bit on);

   //
   // 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_memory
   // Get the memory where the virtual regoster array is implemented
   //
   extern virtual function uvm_mem get_memory();

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

   //
   // Function: is_in_map
   // Return TRUE if this virtual register array 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 virtual register array is mapped
   //
   extern virtual function void            get_maps        (ref uvm_reg_map maps[$]);

   //
   // FUNCTION: get_rights
   // Returns the access rights of this virtual reigster array
   //
   // Returns "RW", "RO" or "WO".
   // The access rights of a virtual register array is always "RW",
   // unless it is implemented in a shared memory
   // with access restriction in a particular address map.
   //
   // If no address map is specified and the memory is mapped in only one
   // address map, that address map is used. If the memory 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 memory 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_access
   // Returns the access policy of the virtual register array
   // when written and read via an address map.
   //
   // If the memory implementing the virtual register array
   // is mapped in more than one address map,
   // an address ~map~ must be specified.
   // If access restrictions are present when accessing a memory
   // through the specified address map, the access mode returned
   // takes the access restrictions into account.
   // For example, a read-write memory accessed
   // through an address map with read-only restrictions would return "RO". 
   //
   extern virtual function string get_access(uvm_reg_map map = null);

   //
   // FUNCTION: get_size
   // Returns the size of the virtual register array. 
   //
   extern virtual function int unsigned get_size();

   //
   // FUNCTION: get_n_bytes
   // Returns the width, in bytes, of a virtual register.
   //
   // The width of a virtual register is always a multiple of the width
   // of the memory locations used to implement it.
   // For example, a virtual register containing two 1-byte fields
   // implemented in a memory with 4-bytes memory locations is 4-byte wide. 
   //
   extern virtual function int unsigned get_n_bytes();

   //
   // FUNCTION: get_n_memlocs
   // Returns the number of memory locations used
   // by a single virtual register. 
   //
   extern virtual function int unsigned get_n_memlocs();

   //
   // FUNCTION: get_incr
   // Returns the number of memory locations
   // between two individual virtual registers in the same array. 
   //
   extern virtual function int unsigned get_incr();

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

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

   //
   // FUNCTION: get_offset_in_memory
   // Returns the offset of a virtual register
   //
   // Returns the base offset of the specified virtual register,
   // in the overall address space of the memory
   // that implements the virtual register array.
   //
   extern virtual function uvm_reg_addr_t  get_offset_in_memory(longint unsigned idx);

   //
   // FUNCTION: get_address
   // Returns the base external physical address of a virtual register
   //
   // Returns the base external physical address of the specified
   // virtual reigster if accessed through the specified address ~map~.
   //
   // If no address map is specified and the memory implementing
   // the virtual register array is mapped in only one
   // address map, that address map is used. If the memory 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 memory is not mapped in the specified
   // address map, an error message is issued.
   //
   extern virtual function uvm_reg_addr_t  get_address(longint unsigned idx,
                                                       uvm_reg_map map = null);

   //
   // Group: HDL Access
   //

   //
   // TASK: write
   // Write the specified value in a virtual register
   //
   // Write ~value~ in the DUT memory location(s) that implements
   // the virtual register array that corresponds to this
   // abstraction class instance using the specified access
   // ~path~. 
   //
   // If the memory implementing the virtual register array
   // is mapped in more than one address map, 
   // an address ~map~ must be
   // specified if a physical access is used (front-door access).
   //
   // The operation is eventually mapped into set of
   // memory-write operations at the location where the virtual register
   // specified by ~idx~ in the virtual register array is implemented.
   //
   extern virtual task write(input  longint unsigned   idx,
                             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  uvm_object         extension = null,
                             input  string             fname = "",
                             input  int                lineno = 0);

   //
   // TASK: read
   // Read the current value from a virtual register
   //
   // Read from the DUT memory location(s) that implements
   // the virtual register array that corresponds to this
   // abstraction class instance using the specified access
   // ~path~ and return the readback ~value~.
   //
   // If the memory implementing the virtual register array
   // is mapped in more than one address map, 
   // an address ~map~ must be
   // specified if a physical access is used (front-door access).
   //
   // The operation is eventually mapped into set of
   // memory-read operations at the location where the virtual register
   // specified by ~idx~ in the virtual register array is implemented.
   //
   extern virtual task read(input  longint unsigned    idx,
                            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  uvm_object          extension = null,
                            input  string              fname = "",
                            input  int                 lineno = 0);

   //
   // TASK: poke
   // Deposit the specified value in a virtual register
   //
   // Deposit ~value~ in the DUT memory location(s) that implements
   // the virtual register array that corresponds to this
   // abstraction class instance using the memory backdoor access.
   //
   // The operation is eventually mapped into set of
   // memory-poke operations at the location where the virtual register
   // specified by ~idx~ in the virtual register array is implemented.
   //
   extern virtual task poke(input  longint unsigned    idx,
                            output uvm_status_e   status,
                            input  uvm_reg_data_t      value,
                            input  uvm_sequence_base   parent = null,
                            input  uvm_object          extension = null,
                            input  string              fname = "",
                            input  int                 lineno = 0);

   //
   // TASK: peek
   // Sample the current value in a virtual register
   //
   // Sample the DUT memory location(s) that implements
   // the virtual register array that corresponds to this
   // abstraction class instance using the memory backdoor access,
   // and return the sampled ~value~.
   //
   // The operation is eventually mapped into set of
   // memory-peek operations at the location where the virtual register
   // specified by ~idx~ in the virtual register array is implemented.
   //
   extern virtual task peek(input  longint unsigned    idx,
                            output uvm_status_e   status,
                            output uvm_reg_data_t      value,
                            input  uvm_sequence_base   parent = null,
                            input  uvm_object          extension = null,
                            input  string              fname = "",
                            input  int                 lineno = 0);
  
   //
   // Function: reset
   // Reset the access semaphore
   //
   // Reset the semaphore that prevents concurrent access
   // to the virtual register.
   // This semaphore must be explicitly reset if a thread accessing
   // this virtual register array was killed in before the access
   // was completed
   //
   extern function void reset(string kind = "HARD");


   //
   // Group: Callbacks
   //

   //
   // TASK: pre_write
   // Called before virtual 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 virtual register operation.
   //
   // The registered callback methods are invoked after the invocation
   // of this method.
   // All register callbacks are executed after the corresponding
   // field callbacks
   // The pre-write virtual register and field callbacks are executed
   // before the corresponding pre-write memory callbacks
   //
   virtual task pre_write(longint unsigned     idx,
                          ref uvm_reg_data_t   wdat,
                          ref uvm_path_e  path,
                          ref uvm_reg_map      map);
   endtask: pre_write

   //
   // TASK: post_write
   // Called after virtual register write.
   //
   // If the specified ~status~ is modified,
   // the updated status will be
   // returned by the virtual register operation.
   //
   // The registered callback methods are invoked before the invocation
   // of this method.
   // All register callbacks are executed before the corresponding
   // field callbacks
   // The post-write virtual register and field callbacks are executed
   // after the corresponding post-write memory callbacks
   //
   virtual task post_write(longint unsigned       idx,
                           uvm_reg_data_t         wdat,
                           uvm_path_e        path,
                           uvm_reg_map            map,
                           ref uvm_status_e  status);
   endtask: post_write

   //
   // TASK: pre_read
   // Called before virtual 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.
   //
   // The registered callback methods are invoked after the invocation
   // of this method.
   // All register callbacks are executed after the corresponding
   // field callbacks
   // The pre-read virtual register and field callbacks are executed
   // before the corresponding pre-read memory callbacks
   //
   virtual task pre_read(longint unsigned     idx,
                         ref uvm_path_e  path,
                         ref uvm_reg_map      map);
   endtask: pre_read

   //
   // TASK: post_read
   // Called after virtual 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
   // The post-read virtual register and field callbacks are executed
   // after the corresponding post-read memory callbacks
   //
   virtual task post_read(longint unsigned       idx,
                          ref uvm_reg_data_t     rdat,
                          input uvm_path_e  path,
                          input uvm_reg_map      map,
                          ref uvm_status_e  status);
   endtask: post_read

   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_vreg



//------------------------------------------------------------------------------
// Class: uvm_vreg_cbs
//
// Pre/post read/write callback facade class
//
//------------------------------------------------------------------------------

class uvm_vreg_cbs extends uvm_callback;

   string fname;
   int    lineno;

   function new(string name = "uvm_reg_cbs");
      super.new(name);
   endfunction
   

   //
   // Task: pre_write
   // Callback called before a write operation.
   //
   // The registered callback methods are invoked after the invocation
   // of the <uvm_vreg::pre_write()> method.
   // All virtual register callbacks are executed after the corresponding
   // virtual field callbacks
   // The pre-write virtual register and field callbacks are executed
   // before the corresponding pre-write memory callbacks
   //
   // The written value ~wdat~, access ~path~ and address ~map~,
   // if modified, modifies the actual value, access path or address map
   // used in the virtual register operation.
   //
   virtual task pre_write(uvm_vreg         rg,
                          longint unsigned     idx,
                          ref uvm_reg_data_t   wdat,
                          ref uvm_path_e  path,
                          ref uvm_reg_map   map);
   endtask: pre_write


   //
   // TASK: post_write
   // Called after register write.
   //
   // The registered callback methods are invoked before the invocation
   // of the <uvm_reg::post_write()> method.
   // All register callbacks are executed before the corresponding
   // virtual field callbacks
   // The post-write virtual register and field callbacks are executed
   // after the corresponding post-write memory callbacks
   //
   // The ~status~ of the operation,
   // if modified, modifies the actual returned status.
   //
   virtual task post_write(uvm_vreg           rg,
                           longint unsigned       idx,
                           uvm_reg_data_t         wdat,
                           uvm_path_e        path,
                           uvm_reg_map         map,
                           ref uvm_status_e  status);
   endtask: post_write


   //
   // TASK: pre_read
   // Called before register read.
   //
   // The registered callback methods are invoked after the invocation
   // of the <uvm_reg::pre_read()> method.
   // All register callbacks are executed after the corresponding
   // virtual field callbacks
   // The pre-read virtual register and field callbacks are executed
   // before the corresponding pre-read memory callbacks
   //
   // The access ~path~ and address ~map~,
   // if modified, modifies the actual access path or address map
   // used in the register operation.
   //
   virtual task pre_read(uvm_vreg         rg,
                         longint unsigned     idx,
                         ref uvm_path_e  path,
                         ref uvm_reg_map   map);
   endtask: pre_read


   //
   // TASK: post_read
   // Called after register read.
   //
   // The registered callback methods are invoked before the invocation
   // of the <uvm_reg::post_read()> method.
   // All register callbacks are executed before the corresponding
   // virtual field callbacks
   // The post-read virtual register and field callbacks are executed
   // after the corresponding post-read memory callbacks
   //
   // The readback value ~rdat~ and the ~status~ of the operation,
   // if modified, modifies the actual returned readback value and status.
   //
   virtual task post_read(uvm_vreg           rg,
                          longint unsigned       idx,
                          ref uvm_reg_data_t     rdat,
                          input uvm_path_e  path,
                          input uvm_reg_map   map,
                          ref uvm_status_e  status);
   endtask: post_read
endclass: uvm_vreg_cbs


//
// Type: uvm_vreg_cb
// Convenience callback type declaration
//
// Use this declaration to register virtual register callbacks rather than
// the more verbose parameterized class
//
typedef uvm_callbacks#(uvm_vreg, uvm_vreg_cbs) uvm_vreg_cb;

//
// Type: uvm_vreg_cb_iter
// Convenience callback iterator type declaration
//
// Use this declaration to iterate over registered virtual register callbacks
// rather than the more verbose parameterized class
//
typedef uvm_callback_iter#(uvm_vreg, uvm_vreg_cbs) uvm_vreg_cb_iter;



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

function uvm_vreg::new(string       name,
                           int unsigned n_bits);
   super.new(name);

   if (n_bits == 0) begin
      `uvm_error("RegModel", $sformatf("Virtual register \"%s\" cannot have 0 bits", this.get_full_name()));
      n_bits = 1;
   end
   if (n_bits > `UVM_REG_DATA_WIDTH) begin
      `uvm_error("RegModel", $sformatf("Virtual register \"%s\" cannot have more than %0d bits (%0d)", this.get_full_name(), `UVM_REG_DATA_WIDTH, n_bits));
      n_bits = `UVM_REG_DATA_WIDTH;
   end
   this.n_bits = n_bits;

   this.locked    = 0;
endfunction: new

function void uvm_vreg::configure(uvm_reg_block      parent,
                                      uvm_mem        mem = null,
                                      longint unsigned   size = 0,
                                      uvm_reg_addr_t     offset = 0,
                                      int unsigned       incr = 0);
   this.parent = parent;

   this.n_used_bits = 0;

   if (mem != null) begin
      void'(this.implement(size, mem, offset, incr));
      this.is_static = 1;
   end
   else begin
      this.mem = null;
      this.is_static = 0;
   end
   this.parent.add_vreg(this);

   this.atomic = new(1);
endfunction: configure



function void uvm_vreg::Xlock_modelX();
   if (this.locked) return;

   this.locked = 1;
endfunction: Xlock_modelX


function void uvm_vreg::add_field(uvm_vreg_field field);
   int offset;
   int idx;
   
   if (this.locked) begin
      `uvm_error("RegModel", "Cannot add virtual field to locked virtual register model");
      return;
   end

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

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

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

   this.n_used_bits += field.get_n_bits();
   
   // Check if there are too many fields in the register
   if (this.n_used_bits > this.n_bits) begin
      `uvm_error("RegModel", $sformatf("Virtual fields use more bits (%0d) than available in virtual register \"%s\" (%0d)",
                                     this.n_used_bits, this.get_full_name(), this.n_bits));
   end

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

                                        this.get_full_name()));
      end
   end
endfunction: add_field


task uvm_vreg::XatomicX(bit on);
   if (on) this.atomic.get(1);
   else begin
      // Maybe a key was put back in by a spurious call to reset()
      void'(this.atomic.try_get(1));
      this.atomic.put(1);
   end
endtask: XatomicX


function void uvm_vreg::reset(string kind = "HARD");
   // Put back a key in the semaphore if it is checked out
   // in case a thread was killed during an operation
   void'(this.atomic.try_get(1));
   this.atomic.put(1);
endfunction: reset


function string uvm_vreg::get_full_name();
   uvm_reg_block blk;

   get_full_name = this.get_name();

   // Do not include top-level name in full name
   blk = this.get_block();
   if (blk == null) return get_full_name;
   if (blk.get_parent() == null) return get_full_name;

   get_full_name = {this.parent.get_full_name(), ".", get_full_name};
endfunction: get_full_name

function void uvm_vreg::set_parent(uvm_reg_block parent);
   this.parent = parent;
endfunction: set_parent

function uvm_reg_block uvm_vreg::get_parent();
   get_parent = this.parent;
endfunction: get_parent

function uvm_reg_block uvm_vreg::get_block();
   get_block = this.parent;
endfunction: get_block


function bit uvm_vreg::implement(longint unsigned n,
                                     uvm_mem      mem = null,
                                     uvm_reg_addr_t   offset = 0,
                                     int unsigned     incr = 0);

   uvm_mem_region region;

   if(n < 1)
   begin
     `uvm_error("RegModel", $sformatf("Attempting to implement virtual register \"%s\" with a subscript less than one doesn't make sense",this.get_full_name()));
      return 0;
   end

   if (mem == null) begin
      `uvm_error("RegModel", $sformatf("Attempting to implement virtual register \"%s\" using a NULL uvm_mem reference", this.get_full_name()));
      return 0;
   end

   if (this.is_static) begin
      `uvm_error("RegModel", $sformatf("Virtual register \"%s\" is static and cannot be dynamically implemented", this.get_full_name()));
      return 0;
   end

   if (mem.get_block() != this.parent) begin
      `uvm_error("RegModel", $sformatf("Attempting to implement virtual register \"%s\" on memory \"%s\" in a different block",
                                     this.get_full_name(),
                                     mem.get_full_name()));
      return 0;
   end

   begin
      int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1;
      if (incr == 0) incr = min_incr;
      if (min_incr > incr) begin
         `uvm_error("RegModel", $sformatf("Virtual register \"%s\" increment is too small (%0d): Each virtual register requires at least %0d locations in memory \"%s\".",
                                        this.get_full_name(), incr,
                                        min_incr, mem.get_full_name()));
         return 0;
      end
   end

   // Is the memory big enough for ya?
   if (offset + (n * incr) > mem.get_size()) begin
      `uvm_error("RegModel", $sformatf("Given Offset for Virtual register \"%s[%0d]\" is too big for memory %s@'h%0h", this.get_full_name(), n, mem.get_full_name(), offset));
      return 0;
   end

   region = mem.mam.reserve_region(offset,n*incr*mem.get_n_bytes());

   if (region == null) begin
      `uvm_error("RegModel", $sformatf("Could not allocate a memory region for virtual register \"%s\"", this.get_full_name()));
      return 0;
   end

   if (this.mem != null) begin
      `uvm_info("RegModel", $sformatf("Virtual register \"%s\" is being moved re-implemented from %s@'h%0h to %s@'h%0h",
                                 this.get_full_name(),
                                 this.mem.get_full_name(),
                                 this.offset,
                                 mem.get_full_name(), offset),UVM_MEDIUM);
      this.release_region();
   end

   this.region = region;
   this.mem    = mem;
   this.size   = n;
   this.offset = offset;
   this.incr   = incr;
   this.mem.Xadd_vregX(this);

   return 1;
endfunction: implement


function uvm_mem_region uvm_vreg::allocate(longint unsigned n,
                                               uvm_mem_mam          mam);

   uvm_mem mem;

   if(n < 1)
   begin
     `uvm_error("RegModel", $sformatf("Attempting to implement virtual register \"%s\" with a subscript less than one doesn't make sense",this.get_full_name()));
      return null;
   end

   if (mam == null) begin
      `uvm_error("RegModel", $sformatf("Attempting to implement virtual register \"%s\" using a NULL uvm_mem_mam reference", this.get_full_name()));
      return null;
   end

   if (this.is_static) begin
      `uvm_error("RegModel", $sformatf("Virtual register \"%s\" is static and cannot be dynamically allocated", this.get_full_name()));
      return null;
   end

   mem = mam.get_memory();
   if (mem.get_block() != this.parent) begin
      `uvm_error("RegModel", $sformatf("Attempting to allocate virtual register \"%s\" on memory \"%s\" in a different block",
                                     this.get_full_name(),
                                     mem.get_full_name()));
      return null;
   end

   begin
      int min_incr = (this.get_n_bytes()-1) / mem.get_n_bytes() + 1;
      if (incr == 0) incr = min_incr;
      if (min_incr < incr) begin
         `uvm_error("RegModel", $sformatf("Virtual register \"%s\" increment is too small (%0d): Each virtual register requires at least %0d locations in memory \"%s\".",
                                        this.get_full_name(), incr,
                                        min_incr, mem.get_full_name()));
         return null;
      end
   end

   // Need memory at least of size num_vregs*sizeof(vreg) in bytes.
   allocate = mam.request_region(n*incr*mem.get_n_bytes());
   if (allocate == null) begin
      `uvm_error("RegModel", $sformatf("Could not allocate a memory region for virtual register \"%s\"", this.get_full_name()));
      return null;
   end

   if (this.mem != null) begin
     `uvm_info("RegModel", $sformatf("Virtual register \"%s\" is being moved re-allocated from %s@'h%0h to %s@'h%0h",
                                this.get_full_name(),
                                this.mem.get_full_name(),
                                this.offset,
                                mem.get_full_name(),
                                allocate.get_start_offset()),UVM_MEDIUM);

      this.release_region();
   end

   this.region = allocate;

   this.mem    = mam.get_memory();
   this.offset = allocate.get_start_offset();
   this.size   = n;
   this.incr   = incr;

   this.mem.Xadd_vregX(this);
endfunction: allocate


function uvm_mem_region uvm_vreg::get_region();
   return this.region;
endfunction: get_region


function void uvm_vreg::release_region();
   if (this.is_static) begin
      `uvm_error("RegModel", $sformatf("Virtual register \"%s\" is static and cannot be dynamically released", this.get_full_name()));
      return;
   end

   if (this.mem != null)
      this.mem.Xdelete_vregX(this);

   if (this.region != null) begin
      this.region.release_region();
   end

   this.region = null;
   this.mem    = null;
   this.size   = 0;
   this.offset = 0;

   this.reset();
endfunction: release_region


function uvm_mem uvm_vreg::get_memory();
   return this.mem;
endfunction: get_memory


function uvm_reg_addr_t  uvm_vreg::get_offset_in_memory(longint unsigned idx);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_offset_in_memory() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return 0;
   end

   return this.offset + idx * this.incr;
endfunction


function uvm_reg_addr_t  uvm_vreg::get_address(longint unsigned idx,
                                                   uvm_reg_map map = null);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot get address of of unimplemented virtual register \"%s\".", this.get_full_name()));
      return 0;
   end

   return this.mem.get_address(this.get_offset_in_memory(idx), map);
endfunction: get_address


function int unsigned uvm_vreg::get_size();
   if (this.size == 0) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_size() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return 0;
   end

   return this.size;
endfunction: get_size


function int unsigned uvm_vreg::get_n_bytes();
   return ((this.n_bits-1) / 8) + 1;
endfunction: get_n_bytes


function int unsigned uvm_vreg::get_n_memlocs();
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_n_memlocs() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return 0;
   end

   return (this.get_n_bytes()-1) / this.mem.get_n_bytes() + 1;
endfunction: get_n_memlocs


function int unsigned uvm_vreg::get_incr();
   if (this.incr == 0) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_incr() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return 0;
   end

   return this.incr;
endfunction: get_incr


function int uvm_vreg::get_n_maps();
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_n_maps() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return 0;
   end

   return this.mem.get_n_maps();
endfunction: get_n_maps


function void uvm_vreg::get_maps(ref uvm_reg_map maps[$]);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_maps() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return;
   end

   this.mem.get_maps(maps);
endfunction: get_maps


function bit uvm_vreg::is_in_map(uvm_reg_map map);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::is_in_map() on unimplemented virtual register \"%s\"",
                                  this.get_full_name()));
      return 0;
   end

   return this.mem.is_in_map(map);
endfunction


function string uvm_vreg::get_access(uvm_reg_map map = null);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_rights() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return "RW";
   end

   return this.mem.get_access(map);
endfunction: get_access


function string uvm_vreg::get_rights(uvm_reg_map map = null);
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot call uvm_vreg::get_rights() on unimplemented virtual register \"%s\"",
                                     this.get_full_name()));
      return "RW";
   end

   return this.mem.get_rights(map);
endfunction: get_rights


function void uvm_vreg::get_fields(ref uvm_vreg_field fields[$]);
   foreach(this.fields[i])
      fields.push_back(this.fields[i]);
endfunction: get_fields


function uvm_vreg_field uvm_vreg::get_field_by_name(string name);
   foreach (this.fields[i]) begin
      if (this.fields[i].get_name() == name) begin
         return this.fields[i];
      end
   end
   `uvm_warning("RegModel", $sformatf("Unable to locate field \"%s\" in virtual register \"%s\".",
                                    name, this.get_full_name()));
   get_field_by_name = null;
endfunction: get_field_by_name


task uvm_vreg::write(input  longint unsigned   idx,
                         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  uvm_object         extension = null,
                         input  string             fname = "",
                         input  int                lineno = 0);
   uvm_vreg_cb_iter cbs = new(this);

   uvm_reg_addr_t  addr;
   uvm_reg_data_t  tmp;
   uvm_reg_data_t  msk;
   int lsb;

   this.write_in_progress = 1'b1;
   this.fname = fname;
   this.lineno = lineno;
   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot write to unimplemented virtual register \"%s\".", this.get_full_name()));
      status = UVM_NOT_OK;
      return;
   end

   if (path == UVM_DEFAULT_PATH)
     path = this.parent.get_default_path();

   foreach (fields[i]) begin
      uvm_vreg_field_cb_iter cbs = new(fields[i]);
      uvm_vreg_field f = fields[i];
      
      lsb = f.get_lsb_pos_in_register();
      msk = ((1<<f.get_n_bits())-1) << lsb;
      tmp = (value & msk) >> lsb;

      f.pre_write(idx, tmp, path, map);
      for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
           cb = cbs.next()) begin
         cb.fname = this.fname;
         cb.lineno = this.lineno;
         cb.pre_write(f, idx, tmp, path, map);
      end

      value = (value & ~msk) | (tmp << lsb);
   end
   this.pre_write(idx, value, path, map);
   for (uvm_vreg_cbs cb = cbs.first(); cb != null;
        cb = cbs.next()) begin
      cb.fname = this.fname;
      cb.lineno = this.lineno;
      cb.pre_write(this, idx, value, path, map);
   end

   addr = this.offset + (idx * this.incr);

   lsb = 0;
   status = UVM_IS_OK;
   for (int i = 0; i < this.get_n_memlocs(); i++) begin
      uvm_status_e s;

      msk = ((1<<(this.mem.get_n_bytes()*8))-1) << lsb;
      tmp = (value & msk) >> lsb;
      this.mem.write(s, addr + i, tmp, path, map , parent, , extension, fname, lineno);
      if (s != UVM_IS_OK && s != UVM_HAS_X) status = s;
      lsb += this.mem.get_n_bytes() * 8;
   end

   for (uvm_vreg_cbs cb = cbs.first(); cb != null;
        cb = cbs.next()) begin
      cb.fname = this.fname;
      cb.lineno = this.lineno;
      cb.post_write(this, idx, value, path, map, status);
   end
   this.post_write(idx, value, path, map, status);
   foreach (fields[i]) begin
      uvm_vreg_field_cb_iter cbs = new(fields[i]);
      uvm_vreg_field f = fields[i];
      
      lsb = f.get_lsb_pos_in_register();
      msk = ((1<<f.get_n_bits())-1) << lsb;
      tmp = (value & msk) >> lsb;

      for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
           cb = cbs.next()) begin
         cb.fname = this.fname;
         cb.lineno = this.lineno;
         cb.post_write(f, idx, tmp, path, map, status);
      end
      f.post_write(idx, tmp, path, map, status);

      value = (value & ~msk) | (tmp << lsb);
   end

   `uvm_info("RegModel", $sformatf("Wrote virtual register \"%s\"[%0d] via %s with: 'h%h",
                              this.get_full_name(), idx,
                              (path == UVM_FRONTDOOR) ? "frontdoor" : "backdoor",
                              value),UVM_MEDIUM);
   
   this.write_in_progress = 1'b0;
   this.fname = "";
   this.lineno = 0;

endtask: write


task uvm_vreg::read(input  longint unsigned   idx,
                        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  uvm_object         extension = null,
                        input  string             fname = "",
                        input  int                lineno = 0);
   uvm_vreg_cb_iter cbs = new(this);

   uvm_reg_addr_t  addr;
   uvm_reg_data_t  tmp;
   uvm_reg_data_t  msk;
   int lsb;
   this.read_in_progress = 1'b1;
   this.fname = fname;
   this.lineno = lineno;

   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot read from unimplemented virtual register \"%s\".", this.get_full_name()));
      status = UVM_NOT_OK;
      return;
   end

   if (path == UVM_DEFAULT_PATH)
     path = this.parent.get_default_path();

   foreach (fields[i]) begin
      uvm_vreg_field_cb_iter cbs = new(fields[i]);
      uvm_vreg_field f = fields[i];

      f.pre_read(idx, path, map);
      for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
           cb = cbs.next()) begin
         cb.fname = this.fname;
         cb.lineno = this.lineno;
         cb.pre_read(f, idx, path, map);
      end
   end
   this.pre_read(idx, path, map);
   for (uvm_vreg_cbs cb = cbs.first(); cb != null;
        cb = cbs.next()) begin
      cb.fname = this.fname;
      cb.lineno = this.lineno;
      cb.pre_read(this, idx, path, map);
   end

   addr = this.offset + (idx * this.incr);

   lsb = 0;
   value = 0;
   status = UVM_IS_OK;
   for (int i = 0; i < this.get_n_memlocs(); i++) begin
      uvm_status_e s;

      this.mem.read(s, addr + i, tmp, path, map, parent, , extension, fname, lineno);
      if (s != UVM_IS_OK && s != UVM_HAS_X) status = s;

      value |= tmp << lsb;
      lsb += this.mem.get_n_bytes() * 8;
   end

   for (uvm_vreg_cbs cb = cbs.first(); cb != null;
        cb = cbs.next()) begin
      cb.fname = this.fname;
      cb.lineno = this.lineno;
      cb.post_read(this, idx, value, path, map, status);
   end
   this.post_read(idx, value, path, map, status);
   foreach (fields[i]) begin
      uvm_vreg_field_cb_iter cbs = new(fields[i]);
      uvm_vreg_field f = fields[i];

      lsb = f.get_lsb_pos_in_register();

      msk = ((1<<f.get_n_bits())-1) << lsb;
      tmp = (value & msk) >> lsb;

      for (uvm_vreg_field_cbs cb = cbs.first(); cb != null;
           cb = cbs.next()) begin
         cb.fname = this.fname;
         cb.lineno = this.lineno;
         cb.post_read(f, idx, tmp, path, map, status);
      end
      f.post_read(idx, tmp, path, map, status);

      value = (value & ~msk) | (tmp << lsb);
   end

   `uvm_info("RegModel", $sformatf("Read virtual register \"%s\"[%0d] via %s: 'h%h",
                              this.get_full_name(), idx,
                              (path == UVM_FRONTDOOR) ? "frontdoor" : "backdoor",
                              value),UVM_MEDIUM);
   
   this.read_in_progress = 1'b0;
   this.fname = "";
   this.lineno = 0;
endtask: read


task uvm_vreg::poke(input longint unsigned   idx,
                        output uvm_status_e status,
                        input  uvm_reg_data_t    value,
                        input  uvm_sequence_base parent = null,
                        input  uvm_object        extension = null,
                        input  string            fname = "",
                        input  int               lineno = 0);
   uvm_reg_addr_t  addr;
   uvm_reg_data_t  tmp;
   uvm_reg_data_t  msk;
   int lsb;
   this.fname = fname;
   this.lineno = lineno;

   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot poke in unimplemented virtual register \"%s\".", this.get_full_name()));
      status = UVM_NOT_OK;
      return;
   end

   addr = this.offset + (idx * this.incr);

   lsb = 0;
   status = UVM_IS_OK;
   for (int i = 0; i < this.get_n_memlocs(); i++) begin
      uvm_status_e s;

      msk = ((1<<(this.mem.get_n_bytes() * 8))-1) << lsb;
      tmp = (value & msk) >> lsb;

      this.mem.poke(status, addr + i, tmp, "", parent, extension, fname, lineno);
      if (s != UVM_IS_OK && s != UVM_HAS_X) status = s;

      lsb += this.mem.get_n_bytes() * 8;
   end

   `uvm_info("RegModel", $sformatf("Poked virtual register \"%s\"[%0d] with: 'h%h",
                              this.get_full_name(), idx, value),UVM_MEDIUM);
   this.fname = "";
   this.lineno = 0;

endtask: poke


task uvm_vreg::peek(input longint unsigned   idx,
                        output uvm_status_e status,
                        output uvm_reg_data_t    value,
                        input  uvm_sequence_base parent = null,
                        input  uvm_object        extension = null,
                        input  string            fname = "",
                        input  int               lineno = 0);
   uvm_reg_addr_t  addr;
   uvm_reg_data_t  tmp;
   uvm_reg_data_t  msk;
   int lsb;
   this.fname = fname;
   this.lineno = lineno;

   if (this.mem == null) begin
      `uvm_error("RegModel", $sformatf("Cannot peek in from unimplemented virtual register \"%s\".", this.get_full_name()));
      status = UVM_NOT_OK;
      return;
   end

   addr = this.offset + (idx * this.incr);

   lsb = 0;
   value = 0;
   status = UVM_IS_OK;
   for (int i = 0; i < this.get_n_memlocs(); i++) begin
      uvm_status_e s;

      this.mem.peek(status, addr + i, tmp, "", parent, extension, fname, lineno);
      if (s != UVM_IS_OK && s != UVM_HAS_X) status = s;

      value |= tmp << lsb;
      lsb += this.mem.get_n_bytes() * 8;
   end

   `uvm_info("RegModel", $sformatf("Peeked virtual register \"%s\"[%0d]: 'h%h",
                              this.get_full_name(), idx, value),UVM_MEDIUM);
   
   this.fname = "";
   this.lineno = 0;

endtask: peek


function void uvm_vreg::do_print (uvm_printer printer);
  super.do_print(printer);
  printer.print_generic("initiator", parent.get_type_name(), -1, convert2string());
endfunction

function string uvm_vreg::convert2string();
   string res_str;
   string t_str;
   bit with_debug_info;
   $sformat(convert2string, "Virtual register %s -- ", 
            this.get_full_name());

   if (this.size == 0)
     $sformat(convert2string, "%sunimplemented", convert2string);
   else begin
      uvm_reg_map maps[$];
      mem.get_maps(maps);

      $sformat(convert2string, "%s[%0d] in %0s['h%0h+'h%0h]\n", convert2string,
             this.size, this.mem.get_full_name(), this.offset, this.incr); 
      foreach (maps[i]) begin
        uvm_reg_addr_t  addr0 = this.get_address(0, maps[i]);

        $sformat(convert2string, "  Address in map '%s' -- @'h%0h+%0h",
        maps[i].get_full_name(), addr0, this.get_address(1, maps[i]) - addr0);
      end
   end
   foreach(this.fields[i]) begin
      $sformat(convert2string, "%s\n%s", convert2string,
               this.fields[i].convert2string());
   end

endfunction: convert2string



//TODO - add fatal messages
function uvm_object uvm_vreg::clone();
  return null;
endfunction

function void uvm_vreg::do_copy   (uvm_object rhs);
endfunction

function bit uvm_vreg::do_compare (uvm_object  rhs,
                                        uvm_comparer comparer);
  return 0;
endfunction

function void uvm_vreg::do_pack (uvm_packer packer);
endfunction

function void uvm_vreg::do_unpack (uvm_packer packer);
endfunction


