#//
#// -------------------------------------------------------------
#// Copyright 2004-2009 Synopsys, Inc.
#// Copyright 2010-2011 Mentor Graphics Corporation
#// Copyright 2010 Cadence Design Systems, Inc.
#// Copyright 2019-2020 Tuomas Poikela (tpoikela)
#// 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.
#// -------------------------------------------------------------
import cocotb
from ..macros import uvm_error, uvm_info
from ..base import sv, UVM_MEDIUM
#//------------------------------------------------------------------------------
#//
#// Title: Memory Allocation Manager
#//
#// Manages the exclusive allocation of consecutive memory locations
#// called ~regions~.
#// The regions can subsequently be accessed like little memories of
#// their own, without knowing in which memory or offset they are
#// actually located.
#//
#// The memory allocation manager should be used by any
#// application-level process
#// that requires reserved space in the memory,
#// such as DMA buffers.
#//
#// A region will remain reserved until it is explicitly released.
#//
#//------------------------------------------------------------------------------
#//------------------------------------------------------------------------------
#// CLASS: UVMMemMam
#//------------------------------------------------------------------------------
#// Memory allocation manager
#//
#// Memory allocation management utility class similar to C's malloc()
#// and free().
#// A single instance of this class is used to manage a single,
#// contiguous address space.
#//------------------------------------------------------------------------------
[docs]class UVMMemMam:
# //----------------------
# // Group: Initialization
# //----------------------
# // Type: alloc_mode_e
# //
# // Memory allocation mode
# //
# // Specifies how to allocate a memory region
# //
# // GREEDY - Consume new, previously unallocated memory
# // THRIFTY - Reused previously released memory as much as possible (not yet implemented)
# //
# typedef enum {GREEDY, THRIFTY} alloc_mode_e
GREEDY = 0
THRIFTY = 1
# // Type: locality_e
# //
# // Location of memory regions
# //
# // Specifies where to locate new memory regions
# //
# // BROAD - Locate new regions randomly throughout the address space
# // NEARBY - Locate new regions adjacent to existing regions
#
# typedef enum {BROAD, NEARBY} locality_e
BROAD = 0
NEARBY = 1
def __init__(self, name, cfg, mem=None):
"""
Function: new
Create a new manager instance
Create an instance of a memory allocation manager
with the specified name and configuration.
This instance manages all memory region allocation within
the address range specified in the configuration descriptor.
If a reference to a memory abstraction class is provided, the memory
locations within the regions can be accessed through the region
descriptor, using the <UVMMemRegion::read()> and
<UVMMemRegion::write()> methods.
extern def __init__(self, name,
UVMMemMamCfg cfg,
uvm_mem mem=None)
Args:
name:
cfg:
mem:
"""
self.cfg = cfg
self.memory = mem
self.in_use = [] # UVMMemRegion
self.for_each_idx = -1 # type: int
self.fname = "" # type: str
self.lineno = 0 # type: int
# // Variable: default_alloc
# //
# // Region allocation policy
# //
# // This object is repeatedly randomized when allocating new regions.
self.default_alloc = UVMMemMamPolicy()
# self.len = None # type: unsigned
# self.n_bytes = None # type: unsigned
# self.parent = None # type: UVMMemMam
# self.fname = # type: string
# self.lineno = 0 # type: int
# self.XvregX = None # type: uvm_vreg
# self.len = None # type: unsigned
# self.start_offset = None # type: bit
# self.min_offset = None # type: bit
# self.max_offset = None # type: bit
# self.in_use = None # type: UVMMemRegion
# self.t = None # type: min_offse
# self.n_bytes = None # type: unsigned
# self.start_offset = None # type: bit
# self.end_offset = None # type: bit
# self.mode = None # type: alloc_mode_e
# self.locality = None # type: ity_e
# self.t = None # type: start_offse
# self.4 = None # type: 6
#endfunction: new
# // Function: reconfigure
# //
# // Reconfigure the manager
# //
# // Modify the maximum and minimum addresses of the address space managed by
# // the allocation manager, allocation mode, or locality.
# // The number of bytes per memory location cannot be modified
# // once an allocation manager has been constructed.
# // All currently allocated regions must fall within the new address space.
# //
# // Returns the previous configuration.
# //
# // if no new configuration is specified, simply returns the current
# // configuration.
# //
# extern def UVMMemMamCfg reconfigure(self,UVMMemMamCfg cfg = None):
# //-------------------------
# // Group: Memory Management
# //-------------------------
# // Function: reserve_region
# //
# // Reserve a specific memory region
# //
# // Reserve a memory region of the specified number of bytes
# // starting at the specified offset.
# // A descriptor of the reserved region is returned.
# // If the specified region cannot be reserved, ~None~ is returned.
# //
# // It may not be possible to reserve a region because
# // it overlaps with an already-allocated region or
# // it lies outside the address range managed
# // by the memory manager.
# //
# // Regions can be reserved to create "holes" in the managed address space.
# //
# extern function UVMMemRegion reserve_region(bit [63:0] start_offset,
# int unsigned n_bytes,
# string fname = "",
# int lineno = 0)
[docs] def reserve_region(self, start_offset, n_bytes, fname = "", lineno=0):
end_offset = 0
self.fname = fname
self.lineno = lineno
if n_bytes == 0:
uvm_error("RegModel", "Cannot reserve 0 bytes")
return None
if start_offset < self.cfg.start_offset:
uvm_error("RegModel", sv.sformatf(
"Cannot reserve before start of memory space: 'h%h < 'h%h",
start_offset, self.cfg.start_offset))
return None
end_offset = start_offset + int((n_bytes-1) / self.cfg.n_bytes)
n_bytes = (end_offset - start_offset + 1) * self.cfg.n_bytes
if end_offset > self.cfg.end_offset:
uvm_error("RegModel", sv.sformatf("Cannot reserve past end of memory space: 'h%h > 'h%h",
end_offset, self.cfg.end_offset))
return None
uvm_info("RegModel",sv.sformatf("Attempting to reserve ['h%h:'h%h]...",
start_offset, end_offset),UVM_MEDIUM)
for i in range(len(self.in_use)):
if (start_offset <= self.in_use[i].get_end_offset() and
end_offset >= self.in_use[i].get_start_offset()):
# Overlap!
uvm_error("RegModel", sv.sformatf(
"Cannot reserve ['h%h:'h%h] because it overlaps with %s",
start_offset, end_offset,
self.in_use[i].convert2string()))
return None
# Regions are stored in increasing start offset
if start_offset > self.in_use[i].get_start_offset():
reserve_region = UVMMemRegion(start_offset, end_offset,
end_offset - start_offset + 1, n_bytes, self)
self.in_use.insert(i, reserve_region)
return reserve_region
reserve_region = UVMMemRegion(start_offset, end_offset,
end_offset - start_offset + 1, n_bytes, self)
self.in_use.append(reserve_region)
return reserve_region
#endfunction: reserve_region
# // Function: request_region
# //
# // Request and reserve a memory region
# //
# // Request and reserve a memory region of the specified number
# // of bytes starting at a random location.
# // If an policy is specified, it is randomized to determine
# // the start offset of the region.
# // If no policy is specified, the policy found in
# // the <UVMMemMam::default_alloc> class property is randomized.
# //
# // A descriptor of the allocated region is returned.
# // If no region can be allocated, ~None~ is returned.
# //
# // It may not be possible to allocate a region because
# // there is no area in the memory with enough consecutive locations
# // to meet the size requirements or
# // because there is another contradiction when randomizing
# // the policy.
# //
# // If the memory allocation is configured to ~THRIFTY~ or ~NEARBY~,
# // a suitable region is first sought procedurally.
# //
# extern function UVMMemRegion request_region(int unsigned n_bytes,
# UVMMemMamPolicy alloc = None,
# string fname = "",
# int lineno = 0)
#
#
# // Function: release_region
# //
# // Release the specified region
# //
# // Release a previously allocated memory region.
# // An error is issued if the
# // specified region has not been previously allocated or
# // is no longer allocated.
# //
# extern def void release_region(self,UVMMemRegion region):
#
#
# // Function: release_all_regions
# //
# // Forcibly release all allocated memory regions.
# //
# extern def void release_all_regions(self):
#
#
# //---------------------
# // Group: Introspection
# //---------------------
#
# // Function: convert2string
# //
# // Image of the state of the manager
# //
# // Create a human-readable description of the state of
# // the memory manager and the currently allocated regions.
# //
# extern def string convert2string(self):
#
#
# // Function: for_each
# //
# // Iterate over all currently allocated regions
# //
# // If reset is ~TRUE~, reset the iterator
# // and return the first allocated region.
# // Returns ~None~ when there are no additional allocated
# // regions to iterate on.
# //
# extern def UVMMemRegion for_each(self,bit reset = 0):
#
#
# // Function: get_memory
# //
# // Get the managed memory implementation
# //
# // Return the reference to the memory abstraction class
# // for the memory implementing
# // the locations managed by self instance of the allocation manager.
# // Returns ~None~ if no
# // memory abstraction class was specified at construction time.
# //
# extern def uvm_mem get_memory(self):
#endclass: UVMMemMam
#//------------------------------------------------------------------------------
#// CLASS: UVMMemRegion
#//------------------------------------------------------------------------------
#// Allocated memory region descriptor
#//
#// Each instance of this class describes an allocated memory region.
#// Instances of this class are created only by
#// the memory manager, and returned by the
#// <UVMMemMam::reserve_region()> and <UVMMemMam::request_region()>
#// methods.
#//------------------------------------------------------------------------------
[docs]class UVMMemRegion:
#
# /*local*/ bit [63:0] Xstart_offsetX; // Can't be local since function
# /*local*/ bit [63:0] Xend_offsetX; // calls not supported in constraints
#
# local int unsigned len
# local int unsigned n_bytes
# local UVMMemMam parent
# local string fname
# local int lineno
#
# /*local*/ uvm_vreg XvregX
#
def __init__(self, start_offset, end_offset, _len, n_bytes, parent):
"""
extern /*local*/ function new(bit [63:0] start_offset,
bit [63:0] end_offset,
int unsigned len,
int unsigned n_bytes,
UVMMemMam parent)
Args:
start_offset:
end_offset:
_len:
n_bytes:
parent:
"""
self.Xstart_offsetX = start_offset
self.Xend_offsetX = end_offset
self.len = _len
self.n_bytes = n_bytes
self.parent = parent
self.fname = ""
self.lineno = 0
self.XvregX = None
#endfunction: new
#
# // Function: get_start_offset
# //
# // Get the start offset of the region
# //
# // Return the address offset, within the memory,
# // where self memory region starts.
# //
# extern def bit [63:0] get_start_offset(self):
#
#
# // Function: get_end_offset
# //
# // Get the end offset of the region
# //
# // Return the address offset, within the memory,
# // where self memory region ends.
# //
# extern def bit [63:0] get_end_offset(self):
#
#
# // Function: get_len
# //
# // Size of the memory region
# //
# // Return the number of consecutive memory locations
# // (not necessarily bytes) in the allocated region.
# //
# extern def int unsigned get_len(self):
#
#
# // Function: get_n_bytes
# //
# // Number of bytes in the region
# //
# // Return the number of consecutive bytes in the allocated region.
# // If the managed memory contains more than one byte per address,
# // the number of bytes in an allocated region may
# // be greater than the number of requested or reserved bytes.
# //
# extern def int unsigned get_n_bytes(self):
#
#
# // Function: release_region
# //
# // Release self region
# //
# extern def void release_region(self):
#
#
# // Function: get_memory
# //
# // Get the memory where the region resides
# //
# // Return a reference to the memory abstraction class
# // for the memory implementing self allocated memory region.
# // Returns ~None~ if no memory abstraction class was specified
# // for the allocation manager that allocated self region.
# //
# extern def uvm_mem get_memory(self):
#
#
# // Function: get_virtual_registers
# //
# // Get the virtual register array in self region
# //
# // Return a reference to the virtual register array abstraction class
# // implemented in self region.
# // Returns ~None~ if the memory region is
# // not known to implement virtual registers.
# //
# extern def uvm_vreg get_virtual_registers(self):
#
#
# // Task: write
# //
# // Write to a memory location in the region.
# //
# // Write to the memory location that corresponds to the
# // specified ~offset~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::write()> for more details.
# //
# extern def write(self,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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# // Task: read
# //
# // Read from a memory location in the region.
# //
# // Read from the memory location that corresponds to the
# // specified ~offset~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::read()> for more details.
# //
# extern def read(self,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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# // Task: burst_write
# //
# // Write to a set of memory location in the region.
# //
# // Write to the memory locations that corresponds to the
# // specified ~burst~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::burst_write()> for more details.
# //
# extern def burst_write(self,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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# // Task: burst_read
# //
# // Read from a set of memory location in the region.
# //
# // Read from the memory locations that corresponds to the
# // specified ~burst~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::burst_read()> for more details.
# //
# extern def burst_read(self,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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# // Task: poke
# //
# // Deposit in a memory location in the region.
# //
# // Deposit the specified value in the memory location
# // that corresponds to the
# // specified ~offset~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::poke()> for more details.
# //
# extern def poke(self,output uvm_status_e status,
# input uvm_reg_addr_t offset,
# input uvm_reg_data_t value,
# input uvm_sequence_base parent = None,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# // Task: peek
# //
# // Sample a memory location in the region.
# //
# // Sample the memory location that corresponds to the
# // specified ~offset~ within self region.
# // Requires that the memory abstraction class be associated with
# // the memory allocation manager that allocated self region.
# //
# // See <uvm_mem::peek()> for more details.
# //
# extern def peek(self,output uvm_status_e status,
# input uvm_reg_addr_t offset,
# output uvm_reg_data_t value,
# input uvm_sequence_base parent = None,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
#
# extern def string convert2string(self):
#
#endclass
#//------------------------------------------------------------------------------
#// Class: UVMMemMamPolicy
#//------------------------------------------------------------------------------
#//
#// An instance of this class is randomized to determine
#// the starting offset of a randomly allocated memory region.
#// This class can be extended to provide additional constraints
#// on the starting offset, such as word alignment or
#// location of the region within a memory page.
#// If a procedural region allocation policy is required,
#// it can be implemented in the pre/post_randomize() method.
#//------------------------------------------------------------------------------
[docs]class UVMMemMamPolicy:
# // variable: len
# // Number of addresses required
# int unsigned len
#
# // variable: start_offset
# // The starting offset of the region
# rand bit [63:0] start_offset
#
# // variable: min_offset
# // Minimum address offset in the managed address space
# bit [63:0] min_offset
#
# // variable: max_offset
# // Maximum address offset in the managed address space
# bit [63:0] max_offset
#
# // variable: in_use
# // Regions already allocated in the managed address space
# UVMMemRegion in_use[$]
#
# constraint uvm_mem_mam_policy_valid {
# start_offset >= min_offset
# start_offset <= max_offset - len + 1
# }
#
# constraint uvm_mem_mam_policy_no_overlap {
# foreach (in_use[i]) {
# !(start_offset <= in_use[i].Xend_offsetX and
# start_offset + len - 1 >= in_use[i].Xstart_offsetX)
# }
# }
def __init__(self):
"""
Constructor
"""
self.len = 0
self.start_offset = 0
self.min_offset = 0
self.max_offset = 0
self.in_use = []
#// CLASS: UVMMemMamCfg
#// Specifies the memory managed by an instance of a <UVMMemMam> memory
#// allocation manager class.
[docs]class UVMMemMamCfg:
# // variable: n_bytes
# // Number of bytes in each memory location
# rand int unsigned n_bytes
#
#// FIXME start_offset and end_offset should be "longint unsigned" to match the memory addr types
# // variable: start_offset
# // Lowest address of managed space
# rand bit [63:0] start_offset
#
# // variable: end_offset
# // Last address of managed space
# rand bit [63:0] end_offset
#
# // variable: mode
# // Region allocation mode
# rand UVMMemMam::alloc_mode_e mode
#
# // variable: locality
# // Region location mode
# rand UVMMemMam::locality_e locality
#
# constraint uvm_mem_mam_cfg_valid {
# end_offset > start_offset
# n_bytes < 64
# }
def __init__(self):
"""
Constructor
"""
self.n_bytes = 0
self.start_offset = 0
self.end_offset = 0
self.mode = 0
self.locality = 0
#//------------------------------------------------------------------
#// Implementation
#//------------------------------------------------------------------
#
#def bit [63:0] UVMMemRegion::get_start_offset(self):
# return self.Xstart_offsetX
#endfunction: get_start_offset
#
#
#def bit [63:0] UVMMemRegion::get_end_offset(self):
# return self.Xend_offsetX
#endfunction: get_end_offset
#
#
#def int unsigned UVMMemRegion::get_len(self):
# return self.len
#endfunction: get_len
#
#
#def int unsigned UVMMemRegion::get_n_bytes(self):
# return self.n_bytes
#endfunction: get_n_bytes
#
#
#def string UVMMemRegion::convert2string(self):
# $sformat(convert2string, "['h%h:'h%h]",
# self.Xstart_offsetX, self.Xend_offsetX)
#endfunction: convert2string
#
#
#def void UVMMemRegion::release_region(self):
# self.parent.release_region(self)
#endfunction
#
#
#def uvm_mem UVMMemRegion::get_memory(self):
# return self.parent.get_memory()
#endfunction: get_memory
#
#
#def uvm_vreg UVMMemRegion::get_virtual_registers(self):
# return self.XvregX
#endfunction: get_virtual_registers
#
#
#
#
#def UVMMemMamCfg UVMMemMam::reconfigure(self,UVMMemMamCfg cfg = None):
# uvm_root top
# uvm_coreservice_t cs
# if (cfg is None)
# return self.cfg
#
# cs = uvm_coreservice_t::get()
# top = cs.get_root()
#
# // Cannot reconfigure n_bytes
# if (cfg.n_bytes != self.cfg.n_bytes):
# top.uvm_report_error("UVMMemMam",
# sv.sformatf("Cannot reconfigure Memory Allocation Manager with a different number of bytes (%0d != %0d)",
# cfg.n_bytes, self.cfg.n_bytes), UVM_LOW)
# return self.cfg
# end
#
# // All currently allocated regions must fall within the new space
# foreach (self.in_use[i]):
# if (self.in_use[i].get_start_offset() < cfg.start_offset or
# self.in_use[i].get_end_offset() > cfg.end_offset):
# top.uvm_report_error("UVMMemMam",
# sv.sformatf("Cannot reconfigure Memory Allocation Manager with a currently allocated region outside of the managed address range ([%0d:%0d] outside of [%0d:%0d])",
# self.in_use[i].get_start_offset(),
# self.in_use[i].get_end_offset(),
# cfg.start_offset, cfg.end_offset), UVM_LOW)
# return self.cfg
# end
# end
#
# reconfigure = self.cfg
# self.cfg = cfg
#endfunction: reconfigure
#
#
#
#
#function UVMMemRegion UVMMemMam::request_region(int unsigned n_bytes,
# UVMMemMamPolicy alloc = None,
# string fname = "",
# int lineno = 0)
# self.fname = fname
# self.lineno = lineno
# if (alloc is None) alloc = self.default_alloc
#
# alloc.len = (n_bytes-1) / self.cfg.n_bytes + 1
# alloc.min_offset = self.cfg.start_offset
# alloc.max_offset = self.cfg.end_offset
# alloc.in_use = self.in_use
#
# if (!alloc.randomize()):
# `uvm_error("RegModel", "Unable to randomize policy")
# return None
# end
#
# return reserve_region(alloc.start_offset, n_bytes)
#endfunction: request_region
#
#
#def void UVMMemMam::release_region(self,UVMMemRegion region):
#
# if (region is None) return
#
# foreach (self.in_use[i]):
# if (self.in_use[i] == region):
# self.in_use.delete(i)
# return
# end
# end
# `uvm_error("RegModel", {"Attempting to release unallocated region\n",
# region.convert2string()})
#endfunction: release_region
#
#
#def void UVMMemMam::release_all_regions(self):
# in_use.delete()
#endfunction: release_all_regions
#
#
#def string UVMMemMam::convert2string(self):
# convert2string = "Allocated memory regions:\n"
# foreach (self.in_use[i]):
# $sformat(convert2string, "%s %s\n", convert2string,
# self.in_use[i].convert2string())
# end
#endfunction: convert2string
#
#
#def UVMMemRegion UVMMemMam::for_each(self,bit reset = 0):
# if (reset) self.for_each_idx = -1
#
# self.for_each_idx++
#
# if (self.for_each_idx >= self.in_use.size()):
# return None
# end
#
# return self.in_use[self.for_each_idx]
#endfunction: for_each
#
#
#def uvm_mem UVMMemMam::get_memory(self):
# return self.memory
#endfunction: get_memory
#
#
#@cocotb.coroutine
#task UVMMemRegion::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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
#
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::write() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to write to an offset outside of the allocated region (%0d > %0d)",
# offset, self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.write(status, offset + self.get_start_offset(), value,
# path, map, parent, prior, extension)
#endtask: write
#
#
#@cocotb.coroutine
#task UVMMemRegion::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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::read() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to read from an offset outside of the allocated region (%0d > %0d)",
# offset, self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.read(status, offset + self.get_start_offset(), value,
# path, map, parent, prior, extension)
#endtask: read
#
#
#@cocotb.coroutine
#task UVMMemRegion::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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::burst_write() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset + value.size() > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to burst-write to an offset outside of the allocated region (burst to [%0d:%0d] > mem_size %0d)",
# offset,offset+value.size(),self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.burst_write(status, offset + get_start_offset(), value,
# path, map, parent, prior, extension)
#
#endtask: burst_write
#
#
#@cocotb.coroutine
#task UVMMemRegion::burst_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 = None,
# input uvm_sequence_base parent = None,
# input int prior = -1,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::burst_read() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset + value.size() > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to burst-read to an offset outside of the allocated region (burst to [%0d:%0d] > mem_size %0d)",
# offset,offset+value.size(),self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.burst_read(status, offset + get_start_offset(), value,
# path, map, parent, prior, extension)
#
#endtask: burst_read
#
#
#@cocotb.coroutine
#task UVMMemRegion::poke(output uvm_status_e status,
# input uvm_reg_addr_t offset,
# input uvm_reg_data_t value,
# input uvm_sequence_base parent = None,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::poke() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to poke to an offset outside of the allocated region (%0d > %0d)",
# offset, self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.poke(status, offset + self.get_start_offset(), value, "", parent, extension)
#endtask: poke
#
#
#@cocotb.coroutine
#task UVMMemRegion::peek(output uvm_status_e status,
# input uvm_reg_addr_t offset,
# output uvm_reg_data_t value,
# input uvm_sequence_base parent = None,
# input uvm_object extension = None,
# input string fname = "",
# input int lineno = 0)
# uvm_mem mem = self.parent.get_memory()
# self.fname = fname
# self.lineno = lineno
#
# if (mem is None):
# `uvm_error("RegModel", "Cannot use UVMMemRegion::peek() on a region that was allocated by a Memory Allocation Manager that was not associated with a uvm_mem instance")
# status = UVM_NOT_OK
# return
# end
#
# if (offset > self.len):
# `uvm_error("RegModel",
# sv.sformatf("Attempting to peek from an offset outside of the allocated region (%0d > %0d)",
# offset, self.len))
# status = UVM_NOT_OK
# return
# end
#
# mem.peek(status, offset + self.get_start_offset(), value, "", parent, extension)
#endtask: peek