// //-------------------------------------------------------------- // 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 abtract register transaction item. It also defines // a descriptor for a physical bus operation that is used by // 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 is provided in case a user // wishes to implement a custom address translation algorithm. //------------------------------------------------------------------------------ class 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 element_kind; // Variable: element // // A handle to the RegModel model element associated with this transaction. // Use to determine the type to cast to: , // , or . // 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 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 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 and // . // uvm_reg_map local_map; // Variable: map // // The original map specified for the operation. The actual // 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: or . // 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 // . // 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 new(string name=""); super.new(name); value = new[1]; endfunction // Function: convert2string // // Returns a string showing the contents of this transaction. // virtual function string 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 . // virtual function void 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 // transaction. In this case, ~data~ represents the portion // of 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 . //------------------------------------------------------------------------------ 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 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 status; } uvm_reg_bus_op;