//
// -------------------------------------------------------------
//    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.
// -------------------------------------------------------------


//------------------------------------------------------------------------------
// CLASS: uvm_mem
//------------------------------------------------------------------------------
// Memory abstraction base class
//
// A memory is a collection of contiguous locations.
// A memory may be accessible via more than one address map.
//
// Unlike registers, memories are not mirrored because of the potentially
// large data space: tests that walk the entire memory space would negate
// any benefit from sparse memory modelling techniques.
// Rather than relying on a mirror, it is recommended that
// backdoor access be used instead.
//
//------------------------------------------------------------------------------

class uvm_mem extends uvm_object;

   typedef enum {UNKNOWNS, ZEROES, ONES, ADDRESS, VALUE, INCR, DECR} init_e;

   local bit               m_locked;
   local bit               m_read_in_progress;
   local bit               m_write_in_progress;
   local string            m_access;
   local longint unsigned  m_size;
   local uvm_reg_block     m_parent;
   local bit               m_maps[uvm_reg_map];
   local int unsigned      m_n_bits;
   local uvm_reg_backdoor  m_backdoor;
   local bit               m_is_powered_down;
   local int               m_has_cover;
   local int               m_cover_on;
   local string            m_fname;
   local int               m_lineno;
   local bit               m_vregs[uvm_vreg];
   local uvm_object_string_pool
               #(uvm_queue #(uvm_hdl_path_concat)) m_hdl_paths_pool;

   local static int unsigned  m_max_size;

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

   // Function: new
   //
   // Create a new instance and type-specific configuration
   //
   // Creates an instance of a memory abstraction class with the specified
   // name.
   //
   // ~size~ specifies the total number of memory locations.
   // ~n_bits~ specifies the total number of bits in each memory location.
   // ~access~ specifies the access policy of this memory and may be
   // one of "RW for RAMs and "RO" for ROMs.
   //
   // ~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,
                        longint unsigned size,
                        int unsigned     n_bits,
                        string           access = "RW",
                        int              has_coverage = UVM_NO_COVERAGE);

   
   // Function: configure
   //
   // Instance-specific configuration
   //
   // Specify the parent block of this memory.
   //
   // If this memory is implemented in a single HDL variable,
   // it's name is specified as the ~hdl_path~.
   // Otherwise, if the memory is implemented as a concatenation
   // of variables (usually one per bank), 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 parent,
                                   string        hdl_path = "");

   
   // Function: set_offset
   //
   // Modify the offset of the memory
   //
   // The offset of a memory within an address map is set using the
   // <uvm_reg_map::add_mem()> method.
   // This method is used to modify that offset dynamically.
   //
   // Note: Modifying the offset of a memory will make the abstract 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 parent);
   /*local*/ extern function void add_map(uvm_reg_map map);
   /*local*/ extern function void Xlock_modelX();
   /*local*/ extern function void Xadd_vregX(uvm_vreg vreg);
   /*local*/ extern function void Xdelete_vregX(uvm_vreg vreg);


   // variable: mam
   //
   // Memory allocation manager
   //
   // Memory allocation manager for the memory corresponding to this
   // abstraction class instance.
   // Can be used to allocate regions of consecutive addresses of
   // specific sizes, such as DMA buffers,
   // or to locate virtual register array.
   //
   uvm_mem_mam mam;


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

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

   // Function: get_full_name
   //
   // Get the hierarchical name
   //
   // Return the hierarchal name of this memory.
   // 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_n_maps
   //
   // Returns the number of address maps this memory is mapped in
   //
   extern virtual function int get_n_maps ();


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


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

   /*local*/ extern function uvm_reg_map get_default_map (string caller = "");


   // Function: get_rights
   //
   // Returns the access rights of this memory.
   //
   // Returns "RW", "RO" or "WO".
   // The access rights of a memory is always "RW",
   // unless it is 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 memory when written and read
   // via an address map.
   //
   // If the memory 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 a domain with read-only restrictions would return "RO". 
   //
   extern virtual function string get_access(uvm_reg_map map = null);


   // Function: get_size
   //
   // Returns the number of unique memory locations in this memory. 
   //
   extern function longint unsigned get_size();


   // Function: get_n_bytes
   //
   // Return the width, in number of bytes, of each memory location
   //
   extern function int unsigned get_n_bytes();


   // Function: get_n_bits
   //
   // Returns the width, in number of bits, of each memory location
   //
   extern function int unsigned get_n_bits();


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


   // Function: get_virtual_registers
   //
   // Return the virtual registers in this memory
   //
   // Fills the specified array with the abstraction class
   // for all of the virtual registers implemented in this memory.
   // The order in which the virtual registers are located in the array
   // is not specified. 
   //
   extern virtual function void get_virtual_registers(ref uvm_vreg regs[$]);


   // Function: get_virtual_fields
   //
   // Return  the virtual fields in the memory
   //
   // Fills the specified dynamic array with the abstraction class
   // for all of the virtual fields implemented in this memory.
   // The order in which the virtual fields are located in the array is
   // not specified. 
   //
   extern virtual function void get_virtual_fields(ref uvm_vreg_field fields[$]);


   // Function: get_vreg_by_name
   //
   // Find the named virtual register
   //
   // Finds a virtual register with the specified name
   // implemented in this memory and returns
   // its abstraction class instance.
   // If no virtual register with the specified name is found, returns ~null~. 
   //
   extern virtual function uvm_vreg get_vreg_by_name(string name);


   // Function: get_vfield_by_name
   //
   // Find the named virtual field
   //
   // Finds a virtual field with the specified name
   // implemented in this memory and returns
   // its abstraction class instance.
   // If no virtual field with the specified name is found, returns ~null~. 
   //
   extern virtual function uvm_vreg_field  get_vfield_by_name(string name);


   // Function: get_vreg_by_offset
   //
   // Find the virtual register implemented at the specified offset
   //
   // Finds the virtual register implemented in this memory
   // at the specified ~offset~ in the specified address ~map~
   // and returns its abstraction class instance.
   // If no virtual register at the offset is found, returns ~null~. 
   //
   extern virtual function uvm_vreg get_vreg_by_offset(uvm_reg_addr_t offset,
                                                       uvm_reg_map    map = null);

   
   // Function: get_offset
   //
   // Returns the base offset of a memory location
   //
   // Returns the base offset of the specified location in this memory
   // in an 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.
   //
   extern virtual function uvm_reg_addr_t  get_offset (uvm_reg_addr_t offset = 0,
                                                       uvm_reg_map    map = null);


   // Function: get_address
   //
   // Returns the base external physical address of a memory location
   //
   // Returns the base external physical address of the specified location
   // in this memory if accessed through the specified 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.
   //
   extern virtual function uvm_reg_addr_t  get_address(uvm_reg_addr_t  offset = 0,
                                                       uvm_reg_map   map = null);


   // Function: get_addresses
   //
   // Identifies the external physical address(es) of a memory location
   //
   // Computes all of the external physical addresses that must be accessed
   // to completely read or write the specified location in this memory.
   // 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 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.
   //
   extern virtual function int get_addresses(uvm_reg_addr_t     offset = 0,
                                             uvm_reg_map        map=null,
                                             ref uvm_reg_addr_t addr[]);


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

   // Task: write
   //
   // Write the specified value in a memory location
   //
   // Write ~value~ in the memory location that corresponds to this
   // abstraction class instance at the specified ~offset~
   // using the specified access ~path~. 
   // If the memory 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, a read-only memory will not be written.
   //
   extern virtual task write(output uvm_status_e       status,
                             input  uvm_reg_addr_t     offset,
                             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 a memory location
   //
   // Read and return ~value~ from the memory location that corresponds to this
   // abstraction class instance at the specified ~offset~
   // 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).
   //
   extern virtual task read(output uvm_status_e        status,
                            input  uvm_reg_addr_t      offset,
                            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: burst_write
   //
   // Write the specified values in memory locations
   //
   // Burst-write the specified ~values~ in the memory locations
   // beginning at the specified ~offset~.
   // If the memory is mapped in more than one address map, 
   // an address ~map~ must be specified if not using the backdoor.
   // If a back-door access path is used, the effect of writing
   // the register through a physical access is mimicked. For
   // example, a read-only memory will not be written.
   //
   extern virtual task burst_write(output uvm_status_e      status,
                                   input  uvm_reg_addr_t    offset,
                                   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: burst_read
   //
   // Read values from memory locations
   //
   // Burst-read into ~values~ the data the memory locations
   // beginning at the specified ~offset~.
   // If the memory is mapped in more than one address map, 
   // an address ~map~ must be specified if not using the backdoor.
   // If a back-door access path is used, the effect of writing
   // the register through a physical access is mimicked. For
   // example, a read-only memory will not be written.
   //
   extern virtual task burst_read(output uvm_status_e      status,
                                  input  uvm_reg_addr_t    offset,
                                  ref    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 a memory location
   //
   // Deposit the value in the DUT memory location corresponding to this
   // abstraction class instance at the secified ~offset~, as-is,
   // using a back-door access.
   //
   // Uses the HDL path for the design abstraction specified by ~kind~.
   //
   extern virtual task poke(output uvm_status_e       status,
                            input  uvm_reg_addr_t     offset,
                            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 a memory location
   //
   // Sample the value in the DUT memory location corresponding to this
   // absraction class instance at the specified ~offset~
   // using a back-door access.
   // The memory location value is sampled, not modified.
   //
   // Uses the HDL path for the design abstraction specified by ~kind~.
   //
   extern virtual task peek(output uvm_status_e       status,
                            input  uvm_reg_addr_t     offset,
                            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);



   extern protected function bit Xcheck_accessX (input uvm_reg_item rw,
                                                 output uvm_reg_map_info map_info,
                                                 input string caller);
   

   extern virtual task do_write (uvm_reg_item rw);
   extern virtual task do_read  (uvm_reg_item rw);


   //-----------------
   // Group: Frontdoor
   //-----------------

   // Function: set_frontdoor
   //
   // Set a user-defined frontdoor for this memory
   //
   // By default, memorys are mapped linearly into the address space
   // of the address maps that instantiate them.
   // If memorys are accessed using a different mechanism,
   // a user-defined access
   // mechanism must be defined and associated with
   // the corresponding memory abstraction class
   //
   // If the memory 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 memory
   //
   // If null, no user-defined frontdoor has been defined.
   // A user-defined frontdoor is defined
   // by using the <uvm_mem::set_frontdoor()> method. 
   //
   // If the memory 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 memory
   //
   // By default, memories are accessed via the built-in string-based
   // DPI routines if an HDL path has been specified using the
   // <uvm_mem::configure()> or <uvm_mem::add_hdl_path()> method.
   // If this default mechanism is not suitable (e.g. because
   // the memory is not implemented in pure SystemVerilog)
   // a user-defined access
   // mechanism must be defined and associated with
   // the corresponding memory abstraction class
   //
   extern function void set_backdoor (uvm_reg_backdoor bkdr,
                                      string fname = "",
                                      int lineno = 0);


   // Function: get_backdoor
   //
   // Returns the user-defined backdoor for this memory
   //
   // If null, no user-defined backdoor has been defined.
   // A user-defined backdoor is defined
   // by using the <uvm_reg::set_backdoor()> method. 
   //
   // If ~inherit~ is TRUE, returns the backdoor of the parent block
   // if none have been specified for this memory.
   //
   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 memory 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 memory instance for the specified
   // design abstraction. This method may be called more than once for the
   // same design abstraction if the memory is physically duplicated
   // in the design abstraction
   //
   extern function void add_hdl_path (uvm_hdl_path_slice slices[],
                                      string kind = "RTL");
   

   // Function: add_hdl_path_slice
   //
   // Add the specified HDL slice to the HDL path for the specified
   // design abstraction.
   // If ~first~ is TRUE, starts the specification of a duplicate
   // HDL implementation of the memory.
   //
   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 memory 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 memory instance.
   // Returns only the component of the HDL paths that corresponds to
   // the memory, 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_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 memory instance.
   // There may be more than one path returned even
   // if only one path was defined for the memory 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: 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: backdoor_read
   //
   // User-define backdoor read access
   //
   // Override the default string-based DPI backdoor access read
   // for this memory type.
   // By default calls <uvm_mem::backdoor_read_func()>.
   //
   extern virtual protected 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 memory 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 memory type.
   //
   extern virtual function uvm_status_e backdoor_read_func(uvm_reg_item rw);


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


   // Task: pre_write
   //
   // Called before memory write.
   //
   // If the ~offset~, ~value~, access ~path~,
   // or address ~map~ are modified, the updated offset, data value,
   // access path or address map will be used to perform the memory 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.
   //
   virtual task pre_write(uvm_reg_item rw); endtask


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


   // Task: pre_read
   //
   // Called before memory read.
   //
   // If the ~offset~, access ~path~ or address ~map~ are modified,
   // the updated offset, access path or address map will be used to perform
   // the memory 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.
   //
   virtual task pre_read(uvm_reg_item rw); endtask


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


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

   // Function: build_coverage
   //
   // Check if all of the specified coverage model must be built.
   //
   // Check which of the specified coverage model must be built
   // in this instance of the memory 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
   // memory 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 memory has coverage model(s)
   //
   // Returns TRUE if the memory 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 memory.
   // 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 memory abstraction classes,
   // then enabled during construction.
   // See the <uvm_mem::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_mem::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 memory abstraction class
   // whenever an address within one of its address map
   // is succesfully read or written.
   // The specified offset is the offset within the memory,
   // not an absolute address.
   //
   // 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_addr_t offset,
                                           bit            is_read,
                                           uvm_reg_map    map);
   endfunction

   /*local*/ function void XsampleX(uvm_reg_addr_t addr,
                                    bit            is_read,
                                    uvm_reg_map    map);
      sample(addr, is_read, map);
   endfunction

   // Core ovm_object operations

   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_mem



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


// new

function uvm_mem::new (string           name,
                       longint unsigned size,
                       int unsigned     n_bits,
                       string           access = "RW",
                       int              has_coverage = UVM_NO_COVERAGE);

   super.new(name);
   m_locked = 0;
   if (n_bits == 0) begin
      `uvm_error("RegModel", {"Memory '",get_full_name(),"' cannot have 0 bits"})
      n_bits = 1;
   end
   m_size      = size;
   m_n_bits    = n_bits;
   m_backdoor  = null;
   m_access    = access.toupper();
   m_has_cover = has_coverage;
   m_hdl_paths_pool = new("hdl_paths");

   if (n_bits > m_max_size)
      m_max_size = n_bits;

endfunction: new


// configure

function void uvm_mem::configure(uvm_reg_block  parent,
                                 string         hdl_path="");

   if (parent == null)
     `uvm_fatal("REG/NULL_PARENT","configure: parent argument is null") 

   m_parent = parent;

   if (m_access != "RW" && m_access != "RO") begin
      `uvm_error("RegModel", {"Memory '",get_full_name(),"' can only be RW or RO"})
      m_access = "RW";
   end

   begin
      uvm_mem_mam_cfg cfg = new;

      cfg.n_bytes      = ((m_n_bits-1) / 8) + 1;
      cfg.start_offset = 0;
      cfg.end_offset   = m_size-1;

      cfg.mode     = uvm_mem_mam::GREEDY;
      cfg.locality = uvm_mem_mam::BROAD;

      mam = new(get_full_name(), cfg, this);
   end

   m_parent.add_mem(this);

   if (hdl_path != "") add_hdl_path_slice(hdl_path, -1, -1);
endfunction: configure


// set_offset

function void uvm_mem::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 memory '",
                 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_mem_offset(this, offset, unmapped);
endfunction


// add_map

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


// Xlock_modelX

function void uvm_mem::Xlock_modelX();
   m_locked = 1;
endfunction: Xlock_modelX


// get_full_name

function string uvm_mem::get_full_name();
   if (m_parent == null)
      return get_name();
   
   return {m_parent.get_full_name(), ".", get_name()};

endfunction: get_full_name


// get_block

function uvm_reg_block uvm_mem::get_block();
   return m_parent;
endfunction: get_block


// get_n_maps

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


// get_maps

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


// is_in_map

function bit uvm_mem::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_mem::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", 
       {"Memory '",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_mem::get_default_map(string caller="");

   // if mem is not associated with any may, return null
   if (m_maps.num() == 0) begin
      `uvm_warning("RegModel", 
        {"Memory '",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
     void'(m_maps.first(get_default_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);
       if (local_map != null)
         return local_map;
     end
   end

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

   void'(m_maps.first(get_default_map));

endfunction


// get_access

function string uvm_mem::get_access(uvm_reg_map map = null);
   get_access = m_access;
   if (get_n_maps() == 1) return get_access;

   map = get_local_map(map, "get_access()");
   if (map == null) return get_access;

   // Is the memory restricted in this map?
   case (get_rights(map))
     "RW":
       // No restrictions
       return get_access;

     "RO":
       case (get_access)
         "RW", "RO": get_access = "RO";

         "WO":    `uvm_error("RegModel", {"WO memory '",get_full_name(),
                       "' restricted to RO in map '",map.get_full_name(),"'"})

         default: `uvm_error("RegModel", {"Memory '",get_full_name(),
                       "' has invalid access mode, '",get_access,"'"})
       endcase

     "WO":
       case (get_access)
         "RW", "WO": get_access = "WO";

         "RO":    `uvm_error("RegModel", {"RO memory '",get_full_name(),
                       "' restricted to WO in map '",map.get_full_name(),"'"})

         default: `uvm_error("RegModel", {"Memory '",get_full_name(),
                       "' has invalid access mode, '",get_access,"'"})
       endcase

     default: `uvm_error("RegModel", {"Shared memory '",get_full_name(),
                  "' is not shared in map '",map.get_full_name(),"'"})
   endcase
endfunction: get_access


// get_rights

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

   uvm_reg_map_info info;

   // No right restrictions if not shared
   if (m_maps.num() <= 1) begin
      return "RW";
   end

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

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

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

endfunction: get_rights


// get_offset

function uvm_reg_addr_t uvm_mem::get_offset(uvm_reg_addr_t offset = 0,
                                            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_mem_map_info(this);
   
   if (map_info.unmapped) begin
      `uvm_warning("RegModel", {"Memory '",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_offset



// get_virtual_registers

function void uvm_mem::get_virtual_registers(ref uvm_vreg regs[$]);
  foreach (m_vregs[vreg])
     regs.push_back(vreg);
endfunction


// get_virtual_fields

function void uvm_mem::get_virtual_fields(ref uvm_vreg_field fields[$]);

  foreach (m_vregs[l])
  begin
    uvm_vreg vreg = l;
    vreg.get_fields(fields);
  end
endfunction: get_virtual_fields


// get_vfield_by_name

function uvm_vreg_field uvm_mem::get_vfield_by_name(string name);
  // Return first occurrence of vfield matching name
  uvm_vreg_field vfields[$];

  get_virtual_fields(vfields);

  foreach (vfields[i])
    if (vfields[i].get_name() == name)
      return vfields[i];

  `uvm_warning("RegModel", {"Unable to find virtual field '",name,
                       "' in memory '",get_full_name(),"'"})
   return null;
endfunction: get_vfield_by_name


// get_vreg_by_name

function uvm_vreg uvm_mem::get_vreg_by_name(string name);

  foreach (m_vregs[l])
  begin
    uvm_vreg vreg = l;
    if (vreg.get_name() == name)
      return vreg;
  end

  `uvm_warning("RegModel", {"Unable to find virtual register '",name,
                       "' in memory '",get_full_name(),"'"})
  return null;

endfunction: get_vreg_by_name


// get_vreg_by_offset

function uvm_vreg uvm_mem::get_vreg_by_offset(uvm_reg_addr_t offset,
                                              uvm_reg_map map = null);
   `uvm_error("RegModel", "uvm_mem::get_vreg_by_offset() not yet implemented")
   return null;
endfunction: get_vreg_by_offset



// get_addresses

function int uvm_mem::get_addresses(uvm_reg_addr_t offset = 0,
                                    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 0;

   map_info = map.get_mem_map_info(this);

   if (map_info.unmapped) begin
      `uvm_warning("RegModel", {"Memory '",get_name(),
                   "' is unmapped in map '",
                   ((orig_map == null) ? map.get_full_name() : orig_map.get_full_name()),"'"})
      return 0;
   end

   addr = map_info.addr;

   foreach (addr[i])
      addr[i] = addr[i] + map_info.mem_range.stride * offset;

   return map.get_n_bytes();

endfunction


// get_address

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


// get_size

function longint unsigned uvm_mem::get_size();
   return m_size;
endfunction: get_size


// get_n_bits

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


// get_max_size

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


// get_n_bytes

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




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


function uvm_reg_cvr_t uvm_mem::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_mem::add_coverage(uvm_reg_cvr_t models);
   m_has_cover |= models;
endfunction: add_coverage


// has_coverage

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


// set_coverage

function uvm_reg_cvr_t uvm_mem::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_mem::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




//-----------
// HDL ACCESS
//-----------

// write
//------

task uvm_mem::write(output uvm_status_e      status,
                    input  uvm_reg_addr_t    offset,
                    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 = uvm_reg_item::type_id::create("mem_write",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_MEM;
   rw.kind         = UVM_WRITE;
   rw.offset       = offset;
   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;

endtask: write


// read

task uvm_mem::read(output uvm_status_e       status,
                   input  uvm_reg_addr_t     offset,
                   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);
   
   uvm_reg_item rw;
   rw = uvm_reg_item::type_id::create("mem_read",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_MEM;
   rw.kind         = UVM_READ;
   rw.value[0]     = 0;
   rw.offset       = offset;
   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: read


// burst_write

task uvm_mem::burst_write(output uvm_status_e       status,
                          input  uvm_reg_addr_t     offset,
                          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);

   uvm_reg_item rw;
   rw = uvm_reg_item::type_id::create("mem_burst_write",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_MEM;
   rw.kind         = UVM_BURST_WRITE;
   rw.offset       = offset;
   rw.value        = 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;

endtask: burst_write


// burst_read

task uvm_mem::burst_read(output uvm_status_e       status,
                         input  uvm_reg_addr_t     offset,
                         ref    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);

   uvm_reg_item rw;
   rw = uvm_reg_item::type_id::create("mem_burst_read",,get_full_name());
   rw.element      = this;
   rw.element_kind = UVM_MEM;
   rw.kind         = UVM_BURST_READ;
   rw.offset       = offset;
   rw.value        = value;
   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;

endtask: burst_read


// do_write

task uvm_mem::do_write(uvm_reg_item rw);

   uvm_mem_cb_iter  cbs = new(this);
   uvm_reg_map_info map_info;
   
   m_fname  = rw.fname;
   m_lineno = rw.lineno;

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

   m_write_in_progress = 1'b1;

   rw.status = UVM_IS_OK;
   
   // PRE-WRITE CBS
   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;

      return;
   end

   rw.status = UVM_NOT_OK;

   // FRONTDOOR
   if (rw.path == UVM_FRONTDOOR) begin

      uvm_reg_map system_map = rw.local_map.get_root_map();
      
      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
      else begin
         rw.local_map.do_write(rw);
      end

      if (rw.status != UVM_NOT_OK)
         for (uvm_reg_addr_t idx = rw.offset;
              idx <= rw.offset + rw.value.size();
              idx++) begin
            XsampleX(map_info.mem_range.stride * idx, 0, rw.map);
            m_parent.XsampleX(map_info.offset +
                             (map_info.mem_range.stride * idx),
                              0, rw.map);
         end
   end
      
   // BACKDOOR     
   else begin
      // Mimick front door access, i.e. do not write read-only memories
      if (get_access(rw.map) == "RW") begin
         uvm_reg_backdoor bkdr = get_backdoor();
         if (bkdr != null)
            bkdr.write(rw);
         else
            backdoor_write(rw);
      end
      else
         rw.status = UVM_IS_OK;
   end

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

   // REPORT
   if (uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")) begin
     string path_s,value_s,pre_s,range_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";

     if (rw.value.size() > 1) begin
       value_s = "='{";
       pre_s = "Burst ";
       foreach (rw.value[i])
         value_s = {value_s,$sformatf("%0h,",rw.value[i])};
       value_s[value_s.len()-1]="}";
       range_s = $sformatf("[%0d:%0d]",rw.offset,rw.offset+rw.value.size());
     end
     else begin
       value_s = $sformatf("=%0h",rw.value[0]);
       range_s = $sformatf("[%0d]",rw.offset);
     end

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

   m_write_in_progress = 1'b0;

endtask: do_write


// do_read

task uvm_mem::do_read(uvm_reg_item rw);

   uvm_mem_cb_iter cbs = new(this);
   uvm_reg_map_info map_info;
   
   m_fname = rw.fname;
   m_lineno = rw.lineno;

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

   m_read_in_progress = 1'b1;

   rw.status = UVM_IS_OK;
   
   // PRE-READ CBS
   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

   rw.status = UVM_NOT_OK;

   // FRONTDOOR
   if (rw.path == UVM_FRONTDOOR) begin
      
      uvm_reg_map system_map = rw.local_map.get_root_map();
         
      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
      else begin
         rw.local_map.do_read(rw);
      end

      if (rw.status != UVM_NOT_OK)
         for (uvm_reg_addr_t idx = rw.offset;
              idx <= rw.offset + rw.value.size();
              idx++) begin
            XsampleX(map_info.mem_range.stride * idx, 1, rw.map);
            m_parent.XsampleX(map_info.offset +
                             (map_info.mem_range.stride * idx),
                              1, rw.map);
         end
   end

   // BACKDOOR
   else begin
      uvm_reg_backdoor bkdr = get_backdoor();
      if (bkdr != null)
         bkdr.read(rw);
      else
         backdoor_read(rw);
   end

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

   // REPORT
   if (uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")) begin
     string path_s,value_s,pre_s,range_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";

     if (rw.value.size() > 1) begin
       value_s = "='{";
       pre_s = "Burst ";
       foreach (rw.value[i])
         value_s = {value_s,$sformatf("%0h,",rw.value[i])};
       value_s[value_s.len()-1]="}";
       range_s = $sformatf("[%0d:%0d]",rw.offset,(rw.offset+rw.value.size()));
     end
     else begin
       value_s = $sformatf("=%0h",rw.value[0]);
       range_s = $sformatf("[%0d]",rw.offset);
     end

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

   m_read_in_progress = 1'b0;

endtask: do_read


// Xcheck_accessX

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

   if (rw.offset >= m_size) begin
      `uvm_error(get_type_name(), 
         $sformatf("Offset 'h%0h exceeds size of memory, 'h%0h",
           rw.offset, m_size))
      rw.status = UVM_NOT_OK;
      return 0;
   end

   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 memory '",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 memory from map '",
            rw.map.get_full_name(),"'"})
        rw.status = UVM_NOT_OK;
        return 0;
     end

     map_info = rw.local_map.get_mem_map_info(this);

     if (map_info.frontdoor == null) begin

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

        if ((rw.value.size() > 1)) begin
           if (get_n_bits() > rw.local_map.get_n_bytes()*8) begin
              `uvm_error("RegModel",
                    $sformatf("Cannot burst a %0d-bit memory through a narrower data path (%0d bytes)",
                    get_n_bits(), rw.local_map.get_n_bytes()*8));
              rw.status = UVM_NOT_OK;
              return 0;
           end
           if (rw.offset + rw.value.size() > m_size) begin
              `uvm_error("RegModel",
                  $sformatf("Burst of size 'd%0d starting at offset 'd%0d exceeds size of memory, 'd%0d",
                      rw.value.size(), rw.offset, m_size))
              return 0;
           end
        end
     end

     if (rw.map == null)
       rw.map = rw.local_map;
   end

   return 1;
endfunction


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

// poke

task uvm_mem::poke(output uvm_status_e      status,
                   input  uvm_reg_addr_t    offset,
                   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_item rw;
   uvm_reg_backdoor bkdr = get_backdoor();

   m_fname = fname;
   m_lineno = lineno;

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

   // create an abstract transaction for this operation
   rw = uvm_reg_item::type_id::create("mem_poke_item",,get_full_name());
   rw.element      = this;
   rw.path         = UVM_BACKDOOR;
   rw.element_kind = UVM_MEM;
   rw.kind         = UVM_WRITE;
   rw.offset       = offset;
   rw.value[0]     = value & ((1 << m_n_bits)-1);
   rw.bd_kind      = kind;
   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 memory '%s[%0d]' with value 'h%h",
                              get_full_name(), offset, value),UVM_HIGH);

endtask: poke


// peek

task uvm_mem::peek(output uvm_status_e      status,
                   input  uvm_reg_addr_t    offset,
                   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", {"No backdoor access available in memory '",
                 get_full_name(),"'"})
      status = UVM_NOT_OK;
      return;
   end

   // 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_MEM;
   rw.kind         = UVM_READ;
   rw.offset       = offset;
   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 memory '%s[%0d]' has value 'h%h",
                         get_full_name(), offset, value),UVM_HIGH);
endtask: peek


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

// set_frontdoor

function void uvm_mem::set_frontdoor(uvm_reg_frontdoor ftdr,
                                     uvm_reg_map       map = null,
                                     string            fname = "",
                                     int               lineno = 0);
   uvm_reg_map_info map_info;
   m_fname = fname;
   m_lineno = lineno;

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

   if (map == null) begin
      `uvm_error("RegModel", {"Memory '",get_full_name(),
                 "' not found in map '", map.get_full_name(),"'"})
      return;
   end

   map_info = map.get_mem_map_info(this);
   map_info.frontdoor = ftdr;

endfunction: set_frontdoor


// get_frontdoor

function uvm_reg_frontdoor uvm_mem::get_frontdoor(uvm_reg_map map = null);
   uvm_reg_map_info map_info;

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

   if (map == null) begin
      `uvm_error("RegModel", {"Memory '",get_full_name(),
                 "' not found in map '", map.get_full_name(),"'"})
      return null;
   end

   map_info = map.get_mem_map_info(this);
   return map_info.frontdoor;

endfunction: get_frontdoor


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

// set_backdoor

function void uvm_mem::set_backdoor(uvm_reg_backdoor bkdr,
                                    string fname = "",
                                    int lineno = 0);
   m_fname = fname;
   m_lineno = lineno;
   m_backdoor = bkdr;
endfunction: set_backdoor


// get_backdoor

function uvm_reg_backdoor uvm_mem::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


// backdoor_read_func

function uvm_status_e uvm_mem::backdoor_read_func(uvm_reg_item rw);

  uvm_hdl_path_concat paths[$];
  uvm_hdl_data_t val;
  bit ok=1;

  get_full_hdl_path(paths,rw.bd_kind);

  foreach (rw.value[mem_idx]) begin
     string idx;
     idx.itoa(rw.offset + mem_idx);
     foreach (paths[i]) begin
        uvm_hdl_path_concat hdl_concat = paths[i];
        val = 0;
        foreach (hdl_concat.slices[j]) begin
           string hdl_path = {hdl_concat.slices[j].path, "[", idx, "]"};

           `uvm_info("RegModel", {"backdoor_read from ",hdl_path},UVM_DEBUG)
 
           if (hdl_concat.slices[j].offset < 0) begin
              ok &= uvm_hdl_read(hdl_path, val);
              continue;
           end
           begin
              uvm_reg_data_t slice;
              int k = hdl_concat.slices[j].offset;
              ok &= uvm_hdl_read(hdl_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[mem_idx] = val;

        if (val != rw.value[mem_idx]) 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[mem_idx], uvm_hdl_concat2string(paths[0]),
               val, uvm_hdl_concat2string(paths[i]))); 
           return UVM_NOT_OK;
         end
      end
  end

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

  return rw.status;
endfunction


// backdoor_read

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


// backdoor_write

task uvm_mem::backdoor_write(uvm_reg_item rw);

  uvm_hdl_path_concat paths[$];
  bit ok=1;

   
  get_full_hdl_path(paths,rw.bd_kind);
   
  foreach (rw.value[mem_idx]) begin
     string idx;
     idx.itoa(rw.offset + mem_idx);
     foreach (paths[i]) begin
       uvm_hdl_path_concat hdl_concat = paths[i];
       foreach (hdl_concat.slices[j]) begin
          `uvm_info("RegModel", $sformatf("backdoor_write to %s ",hdl_concat.slices[j].path),UVM_DEBUG);
 
          if (hdl_concat.slices[j].offset < 0) begin
             ok &= uvm_hdl_deposit({hdl_concat.slices[j].path,"[", idx, "]"},rw.value[mem_idx]);
             continue;
          end
          begin
            uvm_reg_data_t slice;
            slice = rw.value[mem_idx] >> hdl_concat.slices[j].offset;
            slice &= (1 << hdl_concat.slices[j].size)-1;
            ok &= uvm_hdl_deposit({hdl_concat.slices[j].path, "[", idx, "]"}, slice);
          end
       end
     end
  end
  rw.status = (ok ? UVM_IS_OK : UVM_NOT_OK);
endtask




// clear_hdl_path

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

  if (kind == "")
    kind = m_parent.get_default_hdl_path();

  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_mem::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_mem::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_mem::has_hdl_path(string kind = "");
  if (kind == "")
    kind = m_parent.get_default_hdl_path();
  
  return m_hdl_paths_pool.exists(kind);
endfunction


// get_hdl_path

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

  uvm_queue #(uvm_hdl_path_concat) hdl_paths;

  if (kind == "")
     kind = m_parent.get_default_hdl_path();

  if (!has_hdl_path(kind)) begin
    `uvm_error("RegModel",
        {"Memory 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
     uvm_hdl_path_concat t = hdl_paths.get(i);
     paths.push_back(t);
  end

endfunction


// get_hdl_path_kinds

function void uvm_mem::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_full_hdl_path

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

   if (kind == "")
      kind = m_parent.get_default_hdl_path();
   
   if (!has_hdl_path(kind)) begin
      `uvm_error("RegModel",
          {"Memory 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[$];

      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_parent

function void uvm_mem::set_parent(uvm_reg_block parent);
  m_parent = parent;
endfunction


// get_parent

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


// convert2string

function string uvm_mem::convert2string();

   string res_str;
   string prefix;

   $sformat(convert2string, "%sMemory %s -- %0dx%0d bits", prefix,
            get_full_name(), get_size(), get_n_bits());

   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;
       uvm_endianness_e endian_name;
       parent_map = this_map.get_parent_map();
       endian_name=this_map.get_endian();
       
       offset = parent_map == null ? this_map.get_base_addr(UVM_NO_HIER) :
                                     parent_map.get_submap_offset(this_map);
       prefix = {prefix, "  "};
       $sformat(convert2string, "%sMapped in '%s' -- buswidth %0d bytes, %s, offset 'h%0h, size 'h%0h, %s\n", prefix,
            this_map.get_full_name(), this_map.get_n_bytes(), endian_name.name(), offset,get_size(),get_access(this_map));
     end
   end
   prefix = "  ";
   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, "  ", 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, "  ", res_str,
                       "currently executing write method"}; 
   end
endfunction


// do_print

function void uvm_mem::do_print (uvm_printer printer);
  super.do_print(printer);
  //printer.print_generic(" ", " ", -1, convert2string());
  printer.print_int("n_bits",get_n_bits(),32, UVM_UNSIGNED);
  printer.print_int("size",get_size(),32, UVM_UNSIGNED);
endfunction


// clone

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

// do_copy

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


// do_compare

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


// do_pack

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


// do_unpack

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


// Xadd_vregX

function void uvm_mem::Xadd_vregX(uvm_vreg vreg);
  m_vregs[vreg] = 1;
endfunction


// Xdelete_vregX

function void uvm_mem::Xdelete_vregX(uvm_vreg vreg);
   if (m_vregs.exists(vreg))
     m_vregs.delete(vreg);
endfunction


