//
//--------------------------------------------------------------
// Copyright 2004-2009 Synopsys, Inc.
// Copyright 2010 Mentor Graphics Corporation
// All Rights Reserved Worldwide
//
// Licensed under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in
// compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in
// writing, software distributed under the License is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See
// the License for the specific language governing
// permissions and limitations under the License.
//--------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Title: 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.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// CLASS: uvm_reg_item
//
// Defines an abstract register transaction item. No bus-specific information
// is present, although a handle to a <uvm_reg_map> is provided in case a user
// wishes to implement a custom address translation algorithm.
//------------------------------------------------------------------------------
class [docs]uvm_reg_item extends uvm_sequence_item;
`uvm_object_utils(uvm_reg_item)
// Variable: element_kind
//
// Kind of element being accessed: REG, MEM, or FIELD. See <uvm_elem_kind_e>.
//
uvm_elem_kind_e element_kind;
// 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>.
//
uvm_object element;
// Variable: kind
//
// Kind of access: READ or WRITE.
//
rand uvm_access_e kind;
// Variable: value
//
// The value to write to, or after completion, the value read from the DUT.
// Burst operations use the <values> property.
//
rand uvm_reg_data_t value[];
// TODO: parameterize
constraint max_values { value.size() > 0 && value.size() < 1000; }
// Variable: offset
//
// For memory accesses, the offset address. For bursts,
// the ~starting~ offset address.
//
rand uvm_reg_addr_t offset;
// Variable: status
//
// The result of the transaction: IS_OK, HAS_X, or ERROR.
// See <uvm_status_e>.
//
uvm_status_e status;
// Variable: 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 <uvm_reg_map::get_sequencer> and
// <uvm_reg_map::get_adapter>.
//
uvm_reg_map local_map;
// 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.
//
uvm_reg_map map;
// Variable: path
//
// The path being used: <UVM_FRONTDOOR> or <UVM_BACKDOOR>.
//
uvm_path_e path;
// Variable: parent
//
// The sequence from which the operation originated.
//
rand uvm_sequence_base parent;
// Variable: prior
//
// The priority requested of this transfer, as defined by
// <uvm_sequence_base::start_item>.
//
int prior = -1;
// Variable: extension
//
// Handle to optional user data, as conveyed in the call to
// write(), read(), mirror(), or update() used to trigger the operation.
//
rand uvm_object extension;
// Variable: bd_kind
//
// If path is UVM_BACKDOOR, this member specifies the abstraction
// kind for the backdoor access, e.g. "RTL" or "GATES".
//
string bd_kind;
// Variable: fname
//
// The file name from where this transaction originated, if provided
// at the call site.
//
string fname;
// Variable: lineno
//
// The file name from where this transaction originated, if provided
// at the call site.
//
int lineno;
// Function: new
//
// Create a new instance of this type, giving it the optional ~name~.
//
function [docs]new(string name="");
super.new(name);
value = new[1];
endfunction
// Function: convert2string
//
// Returns a string showing the contents of this transaction.
//
virtual function string [docs]convert2string();
string s,value_s;
s = {"kind=",kind.name(),
" ele_kind=",element_kind.name(),
" ele_name=",element==null?"null":element.get_full_name() };
if (value.size() > 1 && uvm_report_enabled(UVM_HIGH, UVM_INFO, "RegModel")) begin
value_s = "'{";
foreach (value[i])
value_s = {value_s,$sformatf("%0h,",value[i])};
value_s[value_s.len()-1]="}";
end
else
value_s = $sformatf("%0h",value[0]);
s = {s, " value=",value_s};
if (element_kind == UVM_MEM)
s = {s, $sformatf(" offset=%0h",offset)};
s = {s," map=",(map==null?"null":map.get_full_name())," path=",path.name()};
s = {s," status=",status.name()};
return s;
endfunction
// Function: do_copy
//
// Copy the ~rhs~ object into this object. The ~rhs~ object must
// derive from <uvm_reg_item>.
//
virtual function void [docs]do_copy(uvm_object rhs);
uvm_reg_item rhs_;
if (rhs == null)
`uvm_fatal("REG/NULL","do_copy: rhs argument is null")
if (!$cast(rhs_,rhs)) begin
`uvm_error("WRONG_TYPE","Provided rhs is not of type uvm_reg_item")
return;
end
super.copy(rhs);
element_kind = rhs_.element_kind;
element = rhs_.element;
kind = rhs_.kind;
value = rhs_.value;
offset = rhs_.offset;
status = rhs_.status;
local_map = rhs_.local_map;
map = rhs_.map;
path = rhs_.path;
extension = rhs_.extension;
bd_kind = rhs_.bd_kind;
parent = rhs_.parent;
prior = rhs_.prior;
fname = rhs_.fname;
lineno = rhs_.lineno;
endfunction
endclass
//------------------------------------------------------------------------------
//
// CLASS: uvm_reg_bus_op
//
// Struct 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
// <uvm_reg_item> 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;
} [docs]uvm_reg_bus_op;