Source code for uvm.reg.uvm_reg_item

#//
#//--------------------------------------------------------------
#//    Copyright 2004-2009 Synopsys, Inc.
#//    Copyright 2010 Mentor Graphics Corporation
#//    Copyright 2019-2020 Tuomas Poikela
#//    All Rights Reserved Worldwide
#//
#//    Licensed under the Apache License, Version 2.0 (the
#//    "License"); you may not use this file except in
#//    compliance with the License.  You may obtain a copy of
#//    the License at
#//
#//        http://www.apache.org/licenses/LICENSE-2.0
#//
#//    Unless required by applicable law or agreed to in
#//    writing, software distributed under the License is
#//    distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
#//    CONDITIONS OF ANY KIND, either express or implied.  See
#//    the License for the specific language governing
#//    permissions and limitations under the License.
#//--------------------------------------------------------------
"""
Title: Generic Register Operation Descriptors

This section defines the abstract register transaction item. It also defines
a descriptor for a physical bus operation that is used by <uvm_reg_adapter>
subtypes to convert from a protocol-specific address/data/rw operation to
a bus-independent, canonical r/w operation.
"""


from ..seq.uvm_sequence_item import UVMSequenceItem
from ..macros.uvm_object_defines import uvm_object_utils
from ..macros.uvm_message_defines import uvm_error, uvm_fatal
from .uvm_reg_model import (UVM_READ, UVM_NOT_OK, UVM_MEM, UVM_FRONTDOOR,
    UVM_ACCESS_NAMES, UVM_ELEMENT_KIND_NAMES)
from ..base.uvm_object_globals import UVM_HIGH, UVM_INFO
from ..base.sv import sv
from ..base.uvm_globals import uvm_report_enabled
from typing import TypeVar, List

_T0 = TypeVar('_T0')


[docs]class UVMRegItem(UVMSequenceItem): """ CLASS: UVMRegItem Defines an abstract register transaction item. No bus-specific information is present, although a handle to a `UVMRegMap` is provided in case a user wishes to implement a custom address translation algorithm. """ # constraint max_values { value.size() > 0 && value.size() < 1000; } """ :cvar uvm_elem_kind_e element_kind: Kind of element being accessed: REG, MEM, or FIELD. See <uvm_elem_kind_e>. :cvar rand uvm_reg_addr_t offset: For memory accesses, the offset address. For bursts, the ~starting~ offset address. :cvar uvm_status_e status: The result of the transaction: IS_OK, HAS_X, or ERROR. See <uvm_status_e>. :cvar uvm_reg_map local_map: The local map used to obtain addresses. Users may customize address-translation using this map. Access to the sequencer and bus adapter can be obtained by getting this map's root map, then calling `UVMRegMap.get_sequencer` and `UVMRegMap.get_adapter`. :cvar rand uvm_sequence_base parent: The sequence from which the operation originated. :cvar int prior = -1: The priority requested of this transfer, as defined by `UVMSequenceBase.start_item`. :cvar rand uvm_object extension: Handle to optional user data, as conveyed in the call to `UVMReg.write()`, `UVMReg.read()`, `UVMReg.mirror()`, or `UVMReg.update()` used to trigger the operation. :cvar str bd_kind: If path is UVM_BACKDOOR, this member specifies the abstraction kind for the backdoor access, e.g. "RTL" or "GATES". :cvar str fname: The file name from where this transaction originated, if provided at the call site. :cvar int lineno: The file name from where this transaction originated, if provided at the call site. :cvar List[int] value: The value to write to, or after completion, the value read from the DUT. Burst operations use the <values> property. """ def __init__(self, name="") -> None: """ Create a new instance of this type, giving it the optional `name`. Args: name (str): Name of the instance """ UVMSequenceItem.__init__(self, name) self.value: List[int] = [0] # rand uvm_reg_data_t value[] # // Variable: path # // # // The path being used: <UVM_FRONTDOOR> or <UVM_BACKDOOR>. # // # uvm_path_e path self.path = UVM_FRONTDOOR self.status = 0 self.fname = "" self.lineno = 0 self.bd_kind = "" self.prior = -1 self.extension = None self.parent = None self.offset = 0 # // Variable: kind # // # // Kind of access: READ or WRITE. # // # rand uvm_access_e kind self.kind = UVM_READ # // Variable: element # // # // A handle to the RegModel model element associated with this transaction. # // Use <element_kind> to determine the type to cast to: <uvm_reg>, # // <uvm_mem>, or <uvm_reg_field>. # // self.element = None self.element_kind = -1 # // Variable: map # // # // The original map specified for the operation. The actual <map> # // used may differ when a test or sequence written at the block # // level is reused at the system level. # // self.map = None self.local_map = None
[docs] def convert2string(self) -> str: """ Function: convert2string Returns a string showing the contents of this transaction. Returns: str: Reg item as string. """ value_s = "" ele_name = "null" if self.element is not None: ele_name = self.element.get_full_name() kind_str = UVM_ACCESS_NAMES[self.kind] element_kind_str = UVM_ELEMENT_KIND_NAMES[self.element_kind] s = ("kind=" + kind_str + " ele_kind=" + element_kind_str + " ele_name=" + ele_name) if (len(self.value) > 1 and uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")): value_s = "'{" for i in range(len(self.value)): value_s = value_s + sv.sformatf("%0h,", self.value[i]) value_s = value_s[:-1] + "}" else: value_s = sv.sformatf("%0h", self.value[0]) s = s + " value=" + value_s if self.element_kind == UVM_MEM: s = s + sv.sformatf(" offset=%0h", self.offset) map_name = "null" if self.map is not None: map_name = self.map.get_full_name() s = s + " map=" + map_name + " path=" + str(self.path) s = s + " status=" + str(self.status) return s
[docs] def do_copy(self, rhs) -> None: """ Function: do_copy Copy the ~rhs~ object into this object. The ~rhs~ object must derive from `UVMRegItem`. """ if rhs is None: uvm_fatal("REG/NULL","do_copy: rhs argument is null") arr_rhs_ = [] if not sv.cast(arr_rhs_, rhs, UVMRegItem): uvm_error("WRONG_TYPE","Provided rhs is not of type uvm_reg_item") return rhs_ = arr_rhs_[0] super().copy(rhs) self.element_kind = rhs_.element_kind self.element = rhs_.element self.kind = rhs_.kind self.value = rhs_.value self.offset = rhs_.offset self.status = rhs_.status self.local_map = rhs_.local_map self.map = rhs_.map self.path = rhs_.path self.extension = rhs_.extension self.bd_kind = rhs_.bd_kind self.parent = rhs_.parent self.prior = rhs_.prior self.fname = rhs_.fname self.lineno = rhs_.lineno
uvm_object_utils(UVMRegItem)
[docs]class UVMRegBusOp(): """ CLASS: UVMRegBusOp Class that defines a generic bus transaction for register and memory accesses, having ~kind~ (read or write), ~address~, ~data~, and ~byte enable~ information. If the bus is narrower than the register or memory location being accessed, there will be multiple of these bus operations for every abstract `UVMRegItem` transaction. In this case, ~data~ represents the portion of <uvm_reg_item::value> being transferred during this bus cycle. If the bus is wide enough to perform the register or memory operation in a single cycle, ~data~ will be the same as <uvm_reg_item::value>. """ #typedef struct { # # // Variable: kind # // # // Kind of access: READ or WRITE. # // # uvm_access_e kind # # # // Variable: addr # // # // The bus address. # // # uvm_reg_addr_t addr # # # // Variable: data # // # // The data to write. If the bus width is smaller than the register or # // memory width, ~data~ represents only the portion of ~value~ that is # // being transferred this bus cycle. # // # uvm_reg_data_t data # # # // Variable: n_bits # // # // The number of bits of <uvm_reg_item::value> being transferred by # // this transaction. # # int n_bits # # /* # constraint valid_n_bits { # n_bits > 0 # n_bits <= `UVM_REG_DATA_WIDTH # } # */ # # # // Variable: byte_en # // # // Enables for the byte lanes on the bus. Meaningful only when the # // bus supports byte enables and the operation originates from a field # // write/read. # // # uvm_reg_byte_en_t byte_en # # # // Variable: status # // # // The result of the transaction: UVM_IS_OK, UVM_HAS_X, UVM_NOT_OK. # // See <uvm_status_e>. # // # uvm_status_e status # #} uvm_reg_bus_op def __init__(self) -> None: """ Constructor """ self.kind = UVM_READ self.addr = 0 self.data = 0 self.n_bits = 0 self.byte_en = 0x0 self.status = UVM_NOT_OK