URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [reg/] [uvm_reg_block.svh] - Rev 16
Compare with Previous | Blame | View Log
//// -------------------------------------------------------------// Copyright 2004-2011 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_reg_block//// Block abstraction base class//// A block represents a design hierarchy. It can contain registers,// register files, memories and sub-blocks.//// A block has one or more address maps, each corresponding to a physical// interface on the block.////------------------------------------------------------------------------virtual class uvm_reg_block extends uvm_object;local uvm_reg_block parent;local static bit m_roots[uvm_reg_block];local int unsigned blks[uvm_reg_block];local int unsigned regs[uvm_reg];local int unsigned vregs[uvm_vreg];local int unsigned mems[uvm_mem];local bit maps[uvm_reg_map];// Variable: default_path// Default access path for the registers and memories in this block.uvm_path_e default_path = UVM_DEFAULT_PATH;local string default_hdl_path = "RTL";local uvm_reg_backdoor backdoor;local uvm_object_string_pool #(uvm_queue #(string)) hdl_paths_pool;local string root_hdl_paths[string];local bit locked;local int has_cover;local int cover_on;local string fname;local int lineno;local static int id;//----------------------// Group: Initialization//----------------------// Function: new//// Create a new instance and type-specific configuration//// Creates an instance of a block abstraction class with the specified// name.//// ~has_coverage~ specifies which functional coverage models are present in// the extension of the block abstraction class.// Multiple functional coverage models may be specified by adding their// symbolic names, as defined by the <uvm_coverage_model_e> type.//extern function new(string name="", int has_coverage=UVM_NO_COVERAGE);// Function: configure//// Instance-specific configuration//// Specify the parent block of this block.// A block without parent is a root block.//// If the block file corresponds to a hierarchical RTL structure,// its contribution to the HDL path is specified as the ~hdl_path~.// Otherwise, the block does not correspond to a hierarchical RTL// structure (e.g. it is physically flattened) and does not contribute// to the hierarchical HDL path of any contained registers or memories.//extern function void configure(uvm_reg_block parent=null,string hdl_path="");// Function: create_map//// Create an address map in this block//// Create an address map with the specified ~name~, then// configures it with the following properties.//// base_addr - the base address for the map. All registers, memories,// and sub-blocks within the map will be at offsets to this// address//// n_bytes - the byte-width of the bus on which this map is used//// endian - the endian format. See <uvm_endianness_e> for possible// values//// byte_addressing - specifies whether consecutive addresses refer are 1 byte// apart (TRUE) or ~n_bytes~ apart (FALSE). Default is TRUE.////| APB = create_map("APB", 0, 1, UVM_LITTLE_ENDIAN, 1);//extern virtual function uvm_reg_map create_map(string name,uvm_reg_addr_t base_addr,int unsigned n_bytes,uvm_endianness_e endian,bit byte_addressing = 1);// Function: check_data_width//// Check that the specified data width (in bits) is less than// or equal to the value of `UVM_REG_DATA_WIDTH//// This method is designed to be called by a static initializer////| class my_blk extends uvm_reg_block;//| local static bit m_data_width = check_data_width(356);//| ...//| endclass//extern protected static function bit check_data_width(int unsigned width);// Function: set_default_map//// Defines the default address map//// Set the specified address map as the <default_map> for this// block. The address map must be a map of this address block.//extern function void set_default_map (uvm_reg_map map);// Variable: default_map//// Default address map//// Default address map for this block, to be used when no// address map is specified for a register operation and that// register is accessible from more than one address map.//// It is also the implicit address map for a block with a single,// unnamed address map because it has only one physical interface.//uvm_reg_map default_map;extern function uvm_reg_map get_default_map ();extern virtual function void set_parent(uvm_reg_block parent);/*local*/ extern function void add_block (uvm_reg_block blk);/*local*/ extern function void add_map (uvm_reg_map map);/*local*/ extern function void add_reg (uvm_reg rg);/*local*/ extern function void add_vreg (uvm_vreg vreg);/*local*/ extern function void add_mem (uvm_mem mem);// Function: lock_model//// Lock a model and build the address map.//// Recursively lock an entire register model// and build the address maps to enable the// <uvm_reg_map::get_reg_by_offset()> and// <uvm_reg_map::get_mem_by_offset()> methods.//// Once locked, no further structural changes,// such as adding registers or memories,// can be made.//// It is not possible to unlock a model.//extern virtual function void lock_model();// Function: is_locked//// Return TRUE if the model is locked.//extern function bit is_locked();//---------------------// Group: Introspection//---------------------// Function: get_name//// Get the simple name//// Return the simple object name of this block.//// Function: get_full_name//// Get the hierarchical name//// Return the hierarchal name of this block.// The base of the hierarchical name is the root block.//extern virtual function string get_full_name();// Function: get_parent//// Get the parent block//// If this a top-level block, returns ~null~.//extern virtual function uvm_reg_block get_parent();// Function: get_root_blocks//// Get the all root blocks//// Returns an array of all root blocks in the simulation.//extern static function void get_root_blocks(ref uvm_reg_block blks[$]);// Function: find_blocks//// Find the blocks whose hierarchical names match the// specified ~name~ glob.// If a ~root~ block is specified, the name of the blocks are// relative to that block, otherwise they are absolute.//// Returns the number of blocks found.//extern static function int find_blocks(input string name,ref uvm_reg_block blks[$],input uvm_reg_block root = null,input uvm_object accessor = null);// Function: find_block//// Find the first block whose hierarchical names match the// specified ~name~ glob.// If a ~root~ block is specified, the name of the blocks are// relative to that block, otherwise they are absolute.//// Returns the first block found or ~null~ otherwise.// A warning is issued if more than one block is found.//extern static function uvm_reg_block find_block(input string name,input uvm_reg_block root = null,input uvm_object accessor = null);// Function: get_blocks//// Get the sub-blocks//// Get the blocks instantiated in this blocks.// If ~hier~ is TRUE, recursively includes any sub-blocks.//extern virtual function void get_blocks (ref uvm_reg_block blks[$],input uvm_hier_e hier=UVM_HIER);// Function: get_maps//// Get the address maps//// Get the address maps instantiated in this block.//extern virtual function void get_maps (ref uvm_reg_map maps[$]);// Function: get_registers//// Get the registers//// Get the registers instantiated in this block.// If ~hier~ is TRUE, recursively includes the registers// in the sub-blocks.//// Note that registers may be located in different and/or multiple// address maps. To get the registers in a specific address map,// use the <uvm_reg_map::get_registers()> method.//extern virtual function void get_registers (ref uvm_reg regs[$],input uvm_hier_e hier=UVM_HIER);// Function: get_fields//// Get the fields//// Get the fields in the registers instantiated in this block.// If ~hier~ is TRUE, recursively includes the fields of the registers// in the sub-blocks.//extern virtual function void get_fields (ref uvm_reg_field fields[$],input uvm_hier_e hier=UVM_HIER);// Function: get_memories//// Get the memories//// Get the memories instantiated in this block.// If ~hier~ is TRUE, recursively includes the memories// in the sub-blocks.//// Note that memories may be located in different and/or multiple// address maps. To get the memories in a specific address map,// use the <uvm_reg_map::get_memories()> method.//extern virtual function void get_memories (ref uvm_mem mems[$],input uvm_hier_e hier=UVM_HIER);// Function: get_virtual_registers//// Get the virtual registers//// Get the virtual registers instantiated in this block.// If ~hier~ is TRUE, recursively includes the virtual registers// in the sub-blocks.//extern virtual function void get_virtual_registers(ref uvm_vreg regs[$],input uvm_hier_e hier=UVM_HIER);// Function: get_virtual_fields//// Get the virtual fields//// Get the virtual fields from the virtual registers instantiated// in this block.// If ~hier~ is TRUE, recursively includes the virtual fields// in the virtual registers in the sub-blocks.//extern virtual function void get_virtual_fields (ref uvm_vreg_field fields[$],input uvm_hier_e hier=UVM_HIER);// Function: get_block_by_name//// Finds a sub-block with the specified simple name.//// The name is the simple name of the block, not a hierarchical name.// relative to this block.// If no block with that name is found in this block, the sub-blocks// are searched for a block of that name and the first one to be found// is returned.//// If no blocks are found, returns ~null~.//extern virtual function uvm_reg_block get_block_by_name (string name);// Function: get_map_by_name//// Finds an address map with the specified simple name.//// The name is the simple name of the address map, not a hierarchical name.// relative to this block.// If no map with that name is found in this block, the sub-blocks// are searched for a map of that name and the first one to be found// is returned.//// If no address maps are found, returns ~null~.//extern virtual function uvm_reg_map get_map_by_name (string name);// Function: get_reg_by_name//// Finds a register with the specified simple name.//// The name is the simple name of the register, not a hierarchical name.// relative to this block.// If no register with that name is found in this block, the sub-blocks// are searched for a register of that name and the first one to be found// is returned.//// If no registers are found, returns ~null~.//extern virtual function uvm_reg get_reg_by_name (string name);// Function: get_field_by_name//// Finds a field with the specified simple name.//// The name is the simple name of the field, not a hierarchical name.// relative to this block.// If no field with that name is found in this block, the sub-blocks// are searched for a field of that name and the first one to be found// is returned.//// If no fields are found, returns ~null~.//extern virtual function uvm_reg_field get_field_by_name (string name);// Function: get_mem_by_name//// Finds a memory with the specified simple name.//// The name is the simple name of the memory, not a hierarchical name.// relative to this block.// If no memory with that name is found in this block, the sub-blocks// are searched for a memory of that name and the first one to be found// is returned.//// If no memories are found, returns ~null~.//extern virtual function uvm_mem get_mem_by_name (string name);// Function: get_vreg_by_name//// Finds a virtual register with the specified simple name.//// The name is the simple name of the virtual register,// not a hierarchical name.// relative to this block.// If no virtual register with that name is found in this block,// the sub-blocks are searched for a virtual register of that name// and the first one to be found is returned.//// If no virtual registers are found, returns ~null~.//extern virtual function uvm_vreg get_vreg_by_name (string name);// Function: get_vfield_by_name//// Finds a virtual field with the specified simple name.//// The name is the simple name of the virtual field,// not a hierarchical name.// relative to this block.// If no virtual field with that name is found in this block,// the sub-blocks are searched for a virtual field of that name// and the first one to be found is returned.//// If no virtual fields are found, returns ~null~.//extern virtual function uvm_vreg_field get_vfield_by_name (string name);//----------------// 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 block 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// block 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 block has coverage model(s)//// Returns TRUE if the block 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 block and all blocks, registers, fields and memories within it.// The functional coverage measurement is turned on for every// coverage model specified using <uvm_coverage_model_e> symbolic// identifiers.// 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 various abstraction classes,// then enabled during construction.// See the <uvm_reg_block::has_coverage()> method to identify// the available functional coverage models.//extern virtual function uvm_reg_cvr_t set_coverage(uvm_reg_cvr_t is_on);// Function: get_coverage//// Check if coverage measurement is on.//// Returns TRUE if measurement for all of the specified functional// coverage models are currently on.// Multiple functional coverage models can be specified by adding the// functional coverage model identifiers.//// See <uvm_reg_block::set_coverage()> for more details.//extern virtual function bit get_coverage(uvm_reg_cvr_t is_on = UVM_CVR_ALL);// Function: sample//// Functional coverage measurement method//// This method is invoked by the block abstraction class// whenever an address within one of its address map// is successfully read or written.// The specified offset is the offset within the block,// 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// Function: sample_values//// Functional coverage measurement method for field values//// This method is invoked by the user// or by the <uvm_reg_block::sample_values()> method of the parent block// to trigger the sampling// of the current field values in the// block-level functional coverage model.// It recursively invokes the <uvm_reg_block::sample_values()>// and <uvm_reg::sample_values()> methods// in the blocks and registers in this block.//// This method may be extended by the// abstraction class generator to perform the required sampling// in any provided field-value functional coverage model.// If this method is extended, it MUST call super.sample_values().//extern virtual function void sample_values();/*local*/ extern function void XsampleX(uvm_reg_addr_t addr,bit is_read,uvm_reg_map map);//--------------// Group: Access//--------------// Function: get_default_path//// Default access path//// Returns the default access path for this block.//extern virtual function uvm_path_e get_default_path();// Function: reset//// Reset the mirror for this block.//// Sets the mirror value of all registers in the block and sub-blocks// to the reset value corresponding to the specified reset event.// See <uvm_reg_field::reset()> for more details.// Does not actually set the value of the registers in the design,// only the values mirrored in their corresponding mirror.//extern virtual function void reset(string kind = "HARD");// Function: needs_update//// Check if DUT registers need to be written//// If a mirror value has been modified in the abstraction model// without actually updating the actual register// (either through randomization or via the <uvm_reg::set()> method,// the mirror and state of the registers are outdated.// The corresponding registers in the DUT need to be updated.//// This method returns TRUE if the state of at least one register in// the block or sub-blocks needs to be updated to match the mirrored// values.// The mirror values, or actual content of registers, are not modified.// For additional information, see <uvm_reg_block::update()> method.//extern virtual function bit needs_update();// Task: update//// Batch update of register.//// Using the minimum number of write operations, updates the registers// in the design to match the mirrored values in this block and sub-blocks.// The update can be performed using the physical// interfaces (front-door access) or back-door accesses.// This method performs the reverse operation of <uvm_reg_block::mirror()>.//extern virtual task update(output uvm_status_e status,input uvm_path_e path = UVM_DEFAULT_PATH,input uvm_sequence_base parent = null,input int prior = -1,input uvm_object extension = null,input string fname = "",input int lineno = 0);// Task: mirror//// Update the mirrored values//// Read all of the registers in this block and sub-blocks and update their// mirror values to match their corresponding values in the design.// The mirroring can be performed using the physical interfaces// (front-door access) or back-door accesses.// If the ~check~ argument is specified as <UVM_CHECK>,// an error message is issued if the current mirrored value// does not match the actual value in the design.// This method performs the reverse operation of <uvm_reg_block::update()>.//extern virtual task mirror(output uvm_status_e status,input uvm_check_e check = UVM_NO_CHECK,input uvm_path_e path = UVM_DEFAULT_PATH,input uvm_sequence_base parent = null,input int prior = -1,input uvm_object extension = null,input string fname = "",input int lineno = 0);// Task: write_reg_by_name//// Write the named register//// Equivalent to <get_reg_by_name()> followed by <uvm_reg::write()>//extern virtual task write_reg_by_name(output uvm_status_e status,input string name,input uvm_reg_data_t data,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_reg_by_name//// Read the named register//// Equivalent to <get_reg_by_name()> followed by <uvm_reg::read()>//extern virtual task read_reg_by_name(output uvm_status_e status,input string name,output uvm_reg_data_t data,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: write_mem_by_name//// Write the named memory//// Equivalent to <get_mem_by_name()> followed by <uvm_mem::write()>//extern virtual task write_mem_by_name(output uvm_status_e status,input string name,input uvm_reg_addr_t offset,input uvm_reg_data_t data,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_mem_by_name//// Read the named memory//// Equivalent to <get_mem_by_name()> followed by <uvm_mem::read()>//extern virtual task read_mem_by_name(output uvm_status_e status,input string name,input uvm_reg_addr_t offset,output uvm_reg_data_t data,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);extern virtual task readmemh(string filename);extern virtual task writememh(string filename);//----------------// Group: Backdoor//----------------// Function: get_backdoor//// Get the user-defined backdoor for all registers in this block//// Return the user-defined backdoor for all register in this// block and all sub-blocks -- unless overridden by a backdoor set// in a lower-level block or in the register itself.//// If ~inherited~ is TRUE, returns the backdoor of the parent block// if none have been specified for this block.//extern function uvm_reg_backdoor get_backdoor(bit inherited = 1);// Function: set_backdoor//// Set the user-defined backdoor for all registers in this block//// Defines the backdoor mechanism for all registers instantiated// in this block and sub-blocks, unless overridden by a definition// in a lower-level block or register.//extern function void set_backdoor (uvm_reg_backdoor bkdr,string fname = "",int lineno = 0);// Function: clear_hdl_path//// Delete HDL paths//// Remove any previously specified HDL path to the block 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 block instance for the specified// design abstraction. This method may be called more than once for the// same design abstraction if the block is physically duplicated// in the design abstraction//extern function void add_hdl_path (string path, string kind = "RTL");// Function: has_hdl_path//// Check if a HDL path is specified//// Returns TRUE if the block instance has a HDL path defined for the// specified design abstraction. If no design abstraction is specified,// uses the default design abstraction specified for this block or// the nearest block ancestor with a specified default design abstraction.//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 block instance.// Returns only the component of the HDL paths that corresponds to// the block, not a full hierarchical path//// If no design abstraction is specified, the default design abstraction// for this block is used.//extern function void get_hdl_path (ref string 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 block instance.// There may be more than one path returned even// if only one path was defined for the block instance, if any of the// parent components have more than one path defined for the same design// abstraction//// If no design abstraction 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 string paths[$],input string kind = "",string separator = ".");// Function: set_default_hdl_path//// Set the default design abstraction//// Set the default design abstraction for this block instance.//extern function void set_default_hdl_path (string kind);// Function: get_default_hdl_path//// Get the default design abstraction//// Returns the default design abstraction for this block instance.// If a default design abstraction has not been explicitly set for this// block instance, returns the default design abstraction for the// nearest block ancestor.// Returns "" if no default design abstraction has been specified.//extern function string get_default_hdl_path ();// Function: set_hdl_path_root//// Specify a root HDL path//// Set the specified path as the absolute HDL path to the block instance// for the specified design abstraction.// This absolute root path is prepended to all hierarchical paths// under this block. The HDL path of any ancestor block is ignored.// This method overrides any incremental path for the// same design abstraction specified using <add_hdl_path>.//extern function void set_hdl_path_root (string path, string kind = "RTL");// Function: is_hdl_path_root//// Check if this block has an absolute path//// Returns TRUE if an absolute HDL path to the block instance// for the specified design abstraction has been defined.// If no design abstraction is specified, the default design abstraction// for this block is used.//extern function bit is_hdl_path_root (string kind = "");extern virtual function void do_print (uvm_printer printer);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);extern virtual function string convert2string ();extern virtual function uvm_object clone();extern local function void Xinit_address_mapsX();endclass: uvm_reg_block//------------------------------------------------------------------------//---------------// Initialization//---------------// check_data_widthfunction bit uvm_reg_block::check_data_width(int unsigned width);if (width <= $bits(uvm_reg_data_t)) return 1;`uvm_fatal("RegModel", $sformatf("Register model requires that UVM_REG_DATA_WIDTH be defined as %0d or greater. Currently defined as %0d", width, `UVM_REG_DATA_WIDTH))return 0;endfunction// newfunction uvm_reg_block::new(string name="", int has_coverage=UVM_NO_COVERAGE);super.new(name);hdl_paths_pool = new("hdl_paths");this.has_cover = has_coverage;// Root block until registered with a parentm_roots[this] = 0;endfunction: new// configurefunction void uvm_reg_block::configure(uvm_reg_block parent=null, string hdl_path="");this.parent = parent;if (parent != null)this.parent.add_block(this);add_hdl_path(hdl_path);uvm_resource_db#(uvm_reg_block)::set("uvm_reg::*", get_full_name(), this);endfunction// add_blockfunction void uvm_reg_block::add_block (uvm_reg_block blk);if (this.is_locked()) begin`uvm_error("RegModel", "Cannot add subblock to locked block model");return;endif (this.blks.exists(blk)) begin`uvm_error("RegModel", {"Subblock '",blk.get_name(),"' has already been registered with block '",get_name(),"'"})return;endblks[blk] = id++;if (m_roots.exists(blk)) m_roots.delete(blk);endfunction// add_regfunction void uvm_reg_block::add_reg(uvm_reg rg);if (this.is_locked()) begin`uvm_error("RegModel", "Cannot add register to locked block model");return;endif (this.regs.exists(rg)) begin`uvm_error("RegModel", {"Register '",rg.get_name(),"' has already been registered with block '",get_name(),"'"})return;endregs[rg] = id++;endfunction: add_reg// add_vregfunction void uvm_reg_block::add_vreg(uvm_vreg vreg);if (this.is_locked()) begin`uvm_error("RegModel", "Cannot add virtual register to locked block model");return;endif (this.vregs.exists(vreg)) begin`uvm_error("RegModel", {"Virtual register '",vreg.get_name(),"' has already been registered with block '",get_name(),"'"})return;endvregs[vreg] = id++;endfunction: add_vreg// add_memfunction void uvm_reg_block::add_mem(uvm_mem mem);if (this.is_locked()) begin`uvm_error("RegModel", "Cannot add memory to locked block model");return;endif (this.mems.exists(mem)) begin`uvm_error("RegModel", {"Memory '",mem.get_name(),"' has already been registered with block '",get_name(),"'"})return;endmems[mem] = id++;endfunction: add_mem// set_parentfunction void uvm_reg_block::set_parent(uvm_reg_block parent);if (this != parent)this.parent = parent;endfunction// is_lockedfunction bit uvm_reg_block::is_locked();return this.locked;endfunction: is_locked// lock_modelfunction void uvm_reg_block::lock_model();if (is_locked())return;locked = 1;foreach (regs[rg_]) beginuvm_reg rg = rg_;rg.Xlock_modelX();endforeach (mems[mem_]) beginuvm_mem mem = mem_;mem.Xlock_modelX();endforeach (blks[blk_]) beginuvm_reg_block blk=blk_;blk.lock_model();endif (this.parent == null) beginint max_size = uvm_reg::get_max_size();if (uvm_reg_field::get_max_size() > max_size)max_size = uvm_reg_field::get_max_size();if (uvm_mem::get_max_size() > max_size)max_size = uvm_mem::get_max_size();if (max_size > `UVM_REG_DATA_WIDTH) begin`uvm_fatal("RegModel", $sformatf("Register model requires that UVM_REG_DATA_WIDTH be defined as %0d or greater. Currently defined as %0d", max_size, `UVM_REG_DATA_WIDTH))endXinit_address_mapsX();// Check that root register models have unique names// Has this name has been checked before?if (m_roots[this] != 1) beginint n;foreach (m_roots[_blk]) beginuvm_reg_block blk = _blk;if (blk.get_name() == get_name()) beginm_roots[blk] = 1;n++;endendif (n > 1) begin`uvm_error("UVM/REG/DUPLROOT",$sformatf("There are %0d root register models named \"%s\". The names of the root register models have to be unique",n, get_name()))endendendendfunction: lock_model//--------------------------// Get Hierarchical Elements//--------------------------function string uvm_reg_block::get_full_name();if (parent == null)return get_name();return {parent.get_full_name(), ".", get_name()};endfunction: get_full_name// get_fieldsfunction void uvm_reg_block::get_fields(ref uvm_reg_field fields[$],input uvm_hier_e hier=UVM_HIER);foreach (regs[rg_]) beginuvm_reg rg = rg_;rg.get_fields(fields);endif (hier == UVM_HIER)foreach (blks[blk_])beginuvm_reg_block blk = blk_;blk.get_fields(fields);endendfunction: get_fields// get_virtual_fieldsfunction void uvm_reg_block::get_virtual_fields(ref uvm_vreg_field fields[$],input uvm_hier_e hier=UVM_HIER);foreach (vregs[vreg_]) beginuvm_vreg vreg = vreg_;vreg.get_fields(fields);endif (hier == UVM_HIER)foreach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.get_virtual_fields(fields);endendfunction: get_virtual_fields// get_registersfunction void uvm_reg_block::get_registers(ref uvm_reg regs[$],input uvm_hier_e hier=UVM_HIER);foreach (this.regs[rg])regs.push_back(rg);if (hier == UVM_HIER)foreach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.get_registers(regs);endendfunction: get_registers// get_virtual_registersfunction void uvm_reg_block::get_virtual_registers(ref uvm_vreg regs[$],input uvm_hier_e hier=UVM_HIER);foreach (vregs[rg])regs.push_back(rg);if (hier == UVM_HIER)foreach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.get_virtual_registers(regs);endendfunction: get_virtual_registers// get_memoriesfunction void uvm_reg_block::get_memories(ref uvm_mem mems[$],input uvm_hier_e hier=UVM_HIER);foreach (this.mems[mem_]) beginuvm_mem mem = mem_;mems.push_back(mem);endif (hier == UVM_HIER)foreach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.get_memories(mems);endendfunction: get_memories// get_blocksfunction void uvm_reg_block::get_blocks(ref uvm_reg_block blks[$],input uvm_hier_e hier=UVM_HIER);foreach (this.blks[blk_]) beginuvm_reg_block blk = blk_;blks.push_back(blk);if (hier == UVM_HIER)blk.get_blocks(blks);endendfunction: get_blocks// get_root_blocksfunction void uvm_reg_block::get_root_blocks(ref uvm_reg_block blks[$]);foreach (m_roots[blk]) beginblks.push_back(blk);endendfunction: get_root_blocks// find_blocksfunction int uvm_reg_block::find_blocks(input string name,ref uvm_reg_block blks[$],input uvm_reg_block root = null,input uvm_object accessor = null);uvm_resource_pool rpl = uvm_resource_pool::get();uvm_resource_types::rsrc_q_t rs;blks.delete();if (root != null) name = {root.get_full_name(), ".", name};rs = rpl.lookup_regex(name, "uvm_reg::");for (int i = 0; i < rs.size(); i++) beginuvm_resource#(uvm_reg_block) blk;if (!$cast(blk, rs.get(i))) continue;blks.push_back(blk.read(accessor));endreturn blks.size();endfunction// find_blocksfunction uvm_reg_block uvm_reg_block::find_block(input string name,input uvm_reg_block root = null,input uvm_object accessor = null);uvm_reg_block blks[$];if (!find_blocks(name, blks, root, accessor))return null;if (blks.size() > 1) begin`uvm_warning("MRTH1BLK",{"More than one block matched the name \"", name, "\"."})endreturn blks[0];endfunction// get_mapsfunction void uvm_reg_block::get_maps(ref uvm_reg_map maps[$]);foreach (this.maps[map])maps.push_back(map);endfunction// get_parentfunction uvm_reg_block uvm_reg_block::get_parent();get_parent = this.parent;endfunction: get_parent//------------// Get-By-Name//------------// get_block_by_namefunction uvm_reg_block uvm_reg_block::get_block_by_name(string name);if (get_name() == name)return this;foreach (blks[blk_]) beginuvm_reg_block blk = blk_;if (blk.get_name() == name)return blk;endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_reg_block subblks[$];blk_.get_blocks(subblks, UVM_HIER);foreach (subblks[j])if (subblks[j].get_name() == name)return subblks[j];end`uvm_warning("RegModel", {"Unable to locate block '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_block_by_name// get_reg_by_namefunction uvm_reg uvm_reg_block::get_reg_by_name(string name);foreach (regs[rg_]) beginuvm_reg rg = rg_;if (rg.get_name() == name)return rg;endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_reg subregs[$];blk_.get_registers(subregs, UVM_HIER);foreach (subregs[j])if (subregs[j].get_name() == name)return subregs[j];end`uvm_warning("RegModel", {"Unable to locate register '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_reg_by_name// get_vreg_by_namefunction uvm_vreg uvm_reg_block::get_vreg_by_name(string name);foreach (vregs[rg_]) beginuvm_vreg rg = rg_;if (rg.get_name() == name)return rg;endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_vreg subvregs[$];blk_.get_virtual_registers(subvregs, UVM_HIER);foreach (subvregs[j])if (subvregs[j].get_name() == name)return subvregs[j];end`uvm_warning("RegModel", {"Unable to locate virtual register '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_vreg_by_name// get_mem_by_namefunction uvm_mem uvm_reg_block::get_mem_by_name(string name);foreach (mems[mem_]) beginuvm_mem mem = mem_;if (mem.get_name() == name)return mem;endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_mem submems[$];blk_.get_memories(submems, UVM_HIER);foreach (submems[j])if (submems[j].get_name() == name)return submems[j];end`uvm_warning("RegModel", {"Unable to locate memory '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_mem_by_name// get_field_by_namefunction uvm_reg_field uvm_reg_block::get_field_by_name(string name);foreach (regs[rg_]) beginuvm_reg rg = rg_;uvm_reg_field fields[$];rg.get_fields(fields);foreach (fields[i])if (fields[i].get_name() == name)return fields[i];endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_reg subregs[$];blk_.get_registers(subregs, UVM_HIER);foreach (subregs[j]) beginuvm_reg_field fields[$];subregs[j].get_fields(fields);foreach (fields[i])if (fields[i].get_name() == name)return fields[i];endend`uvm_warning("RegModel", {"Unable to locate field '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_field_by_name// get_vfield_by_namefunction uvm_vreg_field uvm_reg_block::get_vfield_by_name(string name);foreach (vregs[rg_]) beginuvm_vreg rg =rg_;uvm_vreg_field fields[$];rg.get_fields(fields);foreach (fields[i])if (fields[i].get_name() == name)return fields[i];endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;uvm_vreg subvregs[$];blk_.get_virtual_registers(subvregs, UVM_HIER);foreach (subvregs[j]) beginuvm_vreg_field fields[$];subvregs[j].get_fields(fields);foreach (fields[i])if (fields[i].get_name() == name)return fields[i];endend`uvm_warning("RegModel", {"Unable to locate virtual field '",name,"' in block '",get_full_name(),"'"})return null;endfunction: get_vfield_by_name//-------------// Coverage API//-------------// set_coveragefunction uvm_reg_cvr_t uvm_reg_block::set_coverage(uvm_reg_cvr_t is_on);this.cover_on = this.has_cover & is_on;foreach (regs[rg_]) beginuvm_reg rg = rg_;void'(rg.set_coverage(is_on));endforeach (mems[mem_]) beginuvm_mem mem = mem_;void'(mem.set_coverage(is_on));endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;void'(blk.set_coverage(is_on));endreturn this.cover_on;endfunction: set_coverage// sample_valuesfunction void uvm_reg_block::sample_values();foreach (regs[rg_]) beginuvm_reg rg = rg_;rg.sample_values();endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.sample_values();endendfunction// XsampleXfunction void uvm_reg_block::XsampleX(uvm_reg_addr_t addr,bit is_read,uvm_reg_map map);sample(addr, is_read, map);if (parent != null) begin// ToDo: Call XsampleX in the parent block// with the offset and map within that block's contextendendfunctionfunction uvm_reg_cvr_t uvm_reg_block::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_coveragefunction void uvm_reg_block::add_coverage(uvm_reg_cvr_t models);this.has_cover |= models;endfunction: add_coverage// has_coveragefunction bit uvm_reg_block::has_coverage(uvm_reg_cvr_t models);return ((this.has_cover & models) == models);endfunction: has_coverage// get_coveragefunction bit uvm_reg_block::get_coverage(uvm_reg_cvr_t is_on = UVM_CVR_ALL);if (this.has_coverage(is_on) == 0) return 0;return ((this.cover_on & is_on) == is_on);endfunction: get_coverage//----------------// Run-Time Access//----------------// resetfunction void uvm_reg_block::reset(string kind = "HARD");foreach (regs[rg_]) beginuvm_reg rg = rg_;rg.reset(kind);endforeach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.reset(kind);endendfunction// needs_updatefunction bit uvm_reg_block::needs_update();needs_update = 0;foreach (regs[rg_]) beginuvm_reg rg = rg_;if (rg.needs_update())return 1;endforeach (blks[blk_]) beginuvm_reg_block blk =blk_;if (blk.needs_update())return 1;endendfunction: needs_update// updatetask uvm_reg_block::update(output uvm_status_e status,input uvm_path_e path = UVM_DEFAULT_PATH,input uvm_sequence_base parent = null,input int prior = -1,input uvm_object extension = null,input string fname = "",input int lineno = 0);status = UVM_IS_OK;if (!needs_update()) begin`uvm_info("RegModel", $sformatf("%s:%0d - RegModel block %s does not need updating",fname, lineno, this.get_name()), UVM_HIGH);return;end`uvm_info("RegModel", $sformatf("%s:%0d - Updating model block %s with %s path",fname, lineno, this.get_name(), path.name ), UVM_HIGH);foreach (regs[rg_]) beginuvm_reg rg = rg_;if (rg.needs_update()) beginrg.update(status, path, null, parent, prior, extension);if (status != UVM_IS_OK && status != UVM_HAS_X) begin;`uvm_error("RegModel", $sformatf("Register \"%s\" could not be updated",rg.get_full_name()));return;endendendforeach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.update(status,path,parent,prior,extension,fname,lineno);endendtask: update// mirrortask uvm_reg_block::mirror(output uvm_status_e status,input uvm_check_e check = UVM_NO_CHECK,input uvm_path_e path = UVM_DEFAULT_PATH,input uvm_sequence_base parent = null,input int prior = -1,input uvm_object extension = null,input string fname = "",input int lineno = 0);uvm_status_e final_status = UVM_IS_OK;foreach (regs[rg_]) beginuvm_reg rg = rg_;rg.mirror(status, check, path, null,parent, prior, extension, fname, lineno);if (status != UVM_IS_OK && status != UVM_HAS_X) begin;final_status = status;endendforeach (blks[blk_]) beginuvm_reg_block blk = blk_;blk.mirror(status, check, path, parent, prior, extension, fname, lineno);if (status != UVM_IS_OK && status != UVM_HAS_X) begin;final_status = status;endendendtask: mirror// write_reg_by_nametask uvm_reg_block::write_reg_by_name(output uvm_status_e status,input string name,input uvm_reg_data_t data,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 rg;this.fname = fname;this.lineno = lineno;status = UVM_NOT_OK;rg = this.get_reg_by_name(name);if (rg != null)rg.write(status, data, path, map, parent, prior, extension);endtask: write_reg_by_name// read_reg_by_nametask uvm_reg_block::read_reg_by_name(output uvm_status_e status,input string name,output uvm_reg_data_t data,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 rg;this.fname = fname;this.lineno = lineno;status = UVM_NOT_OK;rg = this.get_reg_by_name(name);if (rg != null)rg.read(status, data, path, map, parent, prior, extension);endtask: read_reg_by_name// write_mem_by_nametask uvm_reg_block::write_mem_by_name(output uvm_status_e status,input string name,input uvm_reg_addr_t offset,input uvm_reg_data_t data,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_mem mem;this.fname = fname;this.lineno = lineno;status = UVM_NOT_OK;mem = get_mem_by_name(name);if (mem != null)mem.write(status, offset, data, path, map, parent, prior, extension);endtask: write_mem_by_name// read_mem_by_nametask uvm_reg_block::read_mem_by_name(output uvm_status_e status,input string name,input uvm_reg_addr_t offset,output uvm_reg_data_t data,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_mem mem;this.fname = fname;this.lineno = lineno;status = UVM_NOT_OK;mem = get_mem_by_name(name);if (mem != null)mem.read(status, offset, data, path, map, parent, prior, extension);endtask: read_mem_by_name// readmemhtask uvm_reg_block::readmemh(string filename);// TODOendtask: readmemh// writememhtask uvm_reg_block::writememh(string filename);// TODOendtask: writememh//---------------// Map Management//---------------// create_mapfunction uvm_reg_map uvm_reg_block::create_map(string name,uvm_reg_addr_t base_addr,int unsigned n_bytes,uvm_endianness_e endian,bit byte_addressing=1);uvm_reg_map map;if (this.locked) begin`uvm_error("RegModel", "Cannot add map to locked model");return null;endmap = uvm_reg_map::type_id::create(name,,this.get_full_name());map.configure(this,base_addr,n_bytes,endian,byte_addressing);this.maps[map] = 1;if (maps.num() == 1)default_map = map;return map;endfunction// add_mapfunction void uvm_reg_block::add_map(uvm_reg_map map);if (this.locked) begin`uvm_error("RegModel", "Cannot add map to locked model");return;endif (this.maps.exists(map)) begin`uvm_error("RegModel", {"Map '",map.get_name(),"' already exists in '",get_full_name(),"'"})return;endthis.maps[map] = 1;if (maps.num() == 1)default_map = map;endfunction: add_map// get_map_by_namefunction uvm_reg_map uvm_reg_block::get_map_by_name(string name);uvm_reg_map maps[$];this.get_maps(maps);foreach (maps[i])if (maps[i].get_name() == name)return maps[i];foreach (maps[i]) beginuvm_reg_map submaps[$];maps[i].get_submaps(submaps, UVM_HIER);foreach (submaps[j])if (submaps[j].get_name() == name)return submaps[j];end`uvm_warning("RegModel", {"Map with name '",name,"' does not exist in block"})return null;endfunction// set_default_mapfunction void uvm_reg_block::set_default_map(uvm_reg_map map);if (!maps.exists(map))`uvm_warning("RegModel", {"Map '",map.get_full_name(),"' does not exist in block"})default_map = map;endfunction// get_default_mapfunction uvm_reg_map uvm_reg_block::get_default_map();return default_map;endfunction// get_default_pathfunction uvm_path_e uvm_reg_block::get_default_path();if (this.default_path != UVM_DEFAULT_PATH)return this.default_path;if (this.parent != null)return this.parent.get_default_path();return UVM_FRONTDOOR;endfunction// Xinit_address_mapsXfunction void uvm_reg_block::Xinit_address_mapsX();foreach (maps[map_]) beginuvm_reg_map map = map_;map.Xinit_address_mapX();end//map.Xverify_map_configX();endfunction//----------------// Group- Backdoor//----------------// set_backdoorfunction void uvm_reg_block::set_backdoor(uvm_reg_backdoor bkdr,string fname = "",int lineno = 0);bkdr.fname = fname;bkdr.lineno = lineno;if (this.backdoor != null &&this.backdoor.has_update_threads()) begin`uvm_warning("RegModel", "Previous register backdoor still has update threads running. Backdoors with active mirroring should only be set before simulation starts.");endthis.backdoor = bkdr;endfunction: set_backdoor// get_backdoorfunction uvm_reg_backdoor uvm_reg_block::get_backdoor(bit inherited = 1);if (backdoor == null && inherited) beginuvm_reg_block blk = get_parent();while (blk != null) beginuvm_reg_backdoor bkdr = blk.get_backdoor();if (bkdr != null)return bkdr;blk = blk.get_parent();endendreturn this.backdoor;endfunction: get_backdoor// clear_hdl_pathfunction void uvm_reg_block::clear_hdl_path(string kind = "RTL");if (kind == "ALL") beginhdl_paths_pool = new("hdl_paths");return;endif (kind == "")kind = get_default_hdl_path();if (!hdl_paths_pool.exists(kind)) begin`uvm_warning("RegModel",{"Unknown HDL Abstraction '",kind,"'"})return;endhdl_paths_pool.delete(kind);endfunction// add_hdl_pathfunction void uvm_reg_block::add_hdl_path(string path, string kind = "RTL");uvm_queue #(string) paths;paths = hdl_paths_pool.get(kind);paths.push_back(path);endfunction// has_hdl_pathfunction bit uvm_reg_block::has_hdl_path(string kind = "");if (kind == "") beginkind = get_default_hdl_path();endreturn hdl_paths_pool.exists(kind);endfunction// get_hdl_pathfunction void uvm_reg_block::get_hdl_path(ref string paths[$], input string kind = "");uvm_queue #(string) hdl_paths;if (kind == "")kind = get_default_hdl_path();if (!has_hdl_path(kind)) begin`uvm_error("RegModel",{"Block does not have hdl path defined for abstraction '",kind,"'"})return;endhdl_paths = hdl_paths_pool.get(kind);for (int i=0; i<hdl_paths.size();i++)paths.push_back(hdl_paths.get(i));endfunction// get_full_hdl_pathfunction void uvm_reg_block::get_full_hdl_path(ref string paths[$],input string kind = "",string separator = ".");if (kind == "")kind = get_default_hdl_path();paths.delete();if (is_hdl_path_root(kind)) beginif (root_hdl_paths[kind] != "")paths.push_back(root_hdl_paths[kind]);return;endif (!has_hdl_path(kind)) begin`uvm_error("RegModel",{"Block does not have hdl path defined for abstraction '",kind,"'"})return;endbeginuvm_queue #(string) hdl_paths = hdl_paths_pool.get(kind);string parent_paths[$];if (parent != null)parent.get_full_hdl_path(parent_paths, kind, separator);for (int i=0; i<hdl_paths.size();i++) beginstring hdl_path = hdl_paths.get(i);if (parent_paths.size() == 0) beginif (hdl_path != "")paths.push_back(hdl_path);continue;endforeach (parent_paths[j]) beginif (hdl_path == "")paths.push_back(parent_paths[j]);elsepaths.push_back({ parent_paths[j], separator, hdl_path });endendendendfunction// get_default_hdl_pathfunction string uvm_reg_block::get_default_hdl_path();if (default_hdl_path == "" && parent != null)return parent.get_default_hdl_path();return default_hdl_path;endfunction// set_default_hdl_pathfunction void uvm_reg_block::set_default_hdl_path(string kind);if (kind == "") beginif (parent == null) begin`uvm_error("RegModel",{"Block has no parent. ","Must specify a valid HDL abstraction (kind)"})endkind = parent.get_default_hdl_path();enddefault_hdl_path = kind;endfunction// set_hdl_path_rootfunction void uvm_reg_block::set_hdl_path_root (string path, string kind = "RTL");if (kind == "")kind = get_default_hdl_path();root_hdl_paths[kind] = path;endfunction// is_hdl_path_rootfunction bit uvm_reg_block::is_hdl_path_root (string kind = "");if (kind == "")kind = get_default_hdl_path();return root_hdl_paths.exists(kind);endfunction//----------------------------------// Group- Basic Object Operations//----------------------------------// do_printfunction void uvm_reg_block::do_print (uvm_printer printer);super.do_print(printer);foreach(blks[i]) beginuvm_reg_block b = i;uvm_object obj = b;printer.print_object(obj.get_name(), obj);endforeach(regs[i]) beginuvm_reg r = i;uvm_object obj = r;printer.print_object(obj.get_name(), obj);endforeach(vregs[i]) beginuvm_vreg r = i;uvm_object obj = r;printer.print_object(obj.get_name(), obj);endforeach(mems[i]) beginuvm_mem m = i;uvm_object obj = m;printer.print_object(obj.get_name(), obj);endforeach(maps[i]) beginuvm_reg_map m = i;uvm_object obj = m;printer.print_object(obj.get_name(), obj);endendfunction// clonefunction uvm_object uvm_reg_block::clone();`uvm_fatal("RegModel","RegModel blocks cannot be cloned")return null;endfunction// do_copyfunction void uvm_reg_block::do_copy(uvm_object rhs);`uvm_fatal("RegModel","RegModel blocks cannot be copied")endfunction// do_comparefunction bit uvm_reg_block::do_compare (uvm_object rhs,uvm_comparer comparer);`uvm_warning("RegModel","RegModel blocks cannot be compared")return 0;endfunction// do_packfunction void uvm_reg_block::do_pack (uvm_packer packer);`uvm_warning("RegModel","RegModel blocks cannot be packed")endfunction// do_unpackfunction void uvm_reg_block::do_unpack (uvm_packer packer);`uvm_warning("RegModel","RegModel blocks cannot be unpacked")endfunction// convert2stringfunction string uvm_reg_block::convert2string();string image;string maps[];string blk_maps[];bit single_map;uvm_endianness_e endian;string prefix = " ";`ifdef TODOsingle_map = 1;if (map == "") beginthis.get_maps(maps);if (maps.size() > 1) single_map = 0;endif (single_map) begin$sformat(image, "%sBlock %s", prefix, this.get_full_name());if (map != "")$sformat(image, "%s.%s", image, map);endian = this.get_endian(map);$sformat(image, "%s -- %0d bytes (%s)", image,this.get_n_bytes(map), endian.name());foreach (blks[i]) beginstring img;img = blks[i].convert2string({prefix, " "}, blk_maps[i]);image = {image, "\n", img};endendelse begin$sformat(image, "%Block %s", prefix, this.get_full_name());foreach (maps[i]) beginstring img;endian = this.get_endian(maps[i]);$sformat(img, "%s Map \"%s\" -- %0d bytes (%s)",prefix, maps[i],this.get_n_bytes(maps[i]), endian.name());image = {image, "\n", img};this.get_blocks(blks, blk_maps, maps[i]);foreach (blks[j]) beginimg = blks[j].convert2string({prefix, " "},blk_maps[j]);image = {image, "\n", img};endthis.get_subsys(sys, blk_maps, maps[i]);foreach (sys[j]) beginimg = sys[j].convert2string({prefix, " "},blk_maps[j]);image = {image, "\n", img};endendend`endifreturn image;endfunction: convert2string
