From 61f2b0221f74df4faf8994c55c80e0b882c8d9b1 Mon Sep 17 00:00:00 2001 From: Krzysztof Boronski Date: Thu, 26 Oct 2023 14:43:23 +0200 Subject: [PATCH] Callback test, various iprovements Signed-off-by: Krzysztof Boronski --- test_regress/t/t_uvm/base/uvm_callback.svh | 1294 ++++++++ test_regress/t/t_uvm/base/uvm_domain.svh | 228 ++ test_regress/t/t_uvm/base/uvm_object.svh | 16 + .../t/t_uvm/base/uvm_object_globals.svh | 46 + test_regress/t/t_uvm/base/uvm_phase.svh | 944 ++++++ test_regress/t/t_uvm/base/uvm_pool.svh | 341 +++ test_regress/t/t_uvm/base/uvm_queue.svh | 21 +- test_regress/t/t_uvm/base/uvm_root.svh | 2 +- .../t/t_uvm/macros/uvm_callback_defines.svh | 314 ++ .../t/t_uvm/macros/uvm_object_defines.svh | 2598 +++++++++++++++++ test_regress/t/t_uvm/uvmt_logs.svh | 37 + test_regress/t/t_uvm/uvmt_unit.svh | 15 +- test_regress/t/t_uvm_queue.v | 8 +- 13 files changed, 5840 insertions(+), 24 deletions(-) create mode 100644 test_regress/t/t_uvm/base/uvm_callback.svh create mode 100644 test_regress/t/t_uvm/base/uvm_domain.svh create mode 100644 test_regress/t/t_uvm/base/uvm_object_globals.svh create mode 100644 test_regress/t/t_uvm/base/uvm_phase.svh create mode 100644 test_regress/t/t_uvm/base/uvm_pool.svh create mode 100644 test_regress/t/t_uvm/macros/uvm_callback_defines.svh create mode 100644 test_regress/t/t_uvm/macros/uvm_object_defines.svh diff --git a/test_regress/t/t_uvm/base/uvm_callback.svh b/test_regress/t/t_uvm/base/uvm_callback.svh new file mode 100644 index 00000000000..8b3405b3732 --- /dev/null +++ b/test_regress/t/t_uvm/base/uvm_callback.svh @@ -0,0 +1,1294 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//---------------------------------------------------------------------- +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2007-2011 Mentor Graphics Corporation +// Copyright 2010 AMD +// Copyright 2012-2018 NVIDIA Corporation +// Copyright 2014 Semifore +// Copyright 2012 Accellera Systems Initiative +// Copyright 2010-2014 Synopsys, 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. +//---------------------------------------------------------------------- + +//UVM `include "uvm_macros.svh" + +//------------------------------------------------------------------------------ +// Title: Callbacks Classes +// +// This section defines the classes used for callback registration, management, +// and user-defined callbacks. +//------------------------------------------------------------------------------ + +//-!!!- NOTICE -------------------------------------------------------------!!!- +// This is a non-production-ready modified version of UVM intended for coverage +// testing purpouses +//-!!!----------------------------------------------------------------------!!!- + +typedef class uvm_root; +typedef class uvm_callback; +typedef class uvm_callbacks_base; + +// UVM ! +typedef enum {UVM_APPEND, UVM_PREPEND} uvm_apprepend; +// UVM + +//------------------------------------------------------------------------------ +// +// Class - uvm_typeid_base +// +//------------------------------------------------------------------------------ +// +// Simple typeid interface. Need this to set up the base-super mapping. +// This is similar to the factory, but much simpler. The idea of this +// interface is that each object type T has a typeid that can be +// used for mapping type relationships. This is not a user visible class. + +class uvm_typeid_base; + static string typename; + static uvm_callbacks_base typeid_map[uvm_typeid_base]; + static uvm_typeid_base type_map[uvm_callbacks_base]; +endclass + + + +//------------------------------------------------------------------------------ +// +// Class - uvm_typeid#(T) +// +//------------------------------------------------------------------------------ + +class uvm_typeid#(type T=uvm_object) extends uvm_typeid_base; + static uvm_typeid#(T) m_b_inst; + static function uvm_typeid#(T) get(); + if(m_b_inst == null) + m_b_inst = new; + return m_b_inst; + endfunction +endclass + +//------------------------------------------------------------------------------ +// Class - uvm_callbacks_base +// +// Base class singleton that holds generic queues for all instance +// specific objects. This is an internal class. This class contains a +// global pool that has all of the instance specific callback queues in it. +// All of the typewide callback queues live in the derivative class +// uvm_typed_callbacks#(T). This is not a user visible class. +// +// This class holds the class inheritance hierarchy information +// (super types and derivative types). +// +// Note, all derivative uvm_callbacks#() class singletons access this +// global m_pool object in order to get access to their specific +// instance queue. +//------------------------------------------------------------------------------ + +class uvm_callbacks_base extends uvm_object; + + typedef uvm_callbacks_base this_type; + + /*protected*/ static bit m_tracing = 1; + static this_type m_b_inst; + + static uvm_pool#(uvm_object,uvm_queue#(uvm_callback)) m_pool; + + static function this_type m_initialize(); + if(m_b_inst == null) begin + m_b_inst = new; + m_pool = new; + end + return m_b_inst; + endfunction + + //Type checking interface + this_type m_this_type[$]; //one to many T->T/CB + uvm_typeid_base m_super_type; //one to one relation + uvm_typeid_base m_derived_types[$]; //one to many relation + + virtual function bit m_am_i_a(uvm_object obj); + return 0; + endfunction + + virtual function bit m_is_for_me(uvm_callback cb); + return 0; + endfunction + + virtual function bit m_is_registered(uvm_object obj, uvm_callback cb); + return 0; + endfunction + + virtual function uvm_queue#(uvm_callback) m_get_tw_cb_q(uvm_object obj); + return null; + endfunction + + virtual function void m_add_tw_cbs(uvm_callback cb, uvm_apprepend ordering); + endfunction + + virtual function bit m_delete_tw_cbs(uvm_callback cb); + return 0; + endfunction + + //Check registration. To test registration, start at this class and + //work down the class hierarchy. If any class returns true then + //the pair is legal. + function bit check_registration(uvm_object obj, uvm_callback cb); + this_type dt; + + if (m_is_registered(obj,cb)) + return 1; + + // Need to look at all possible T/CB pairs of this type + foreach(m_this_type[i]) + if(m_b_inst != m_this_type[i] && m_this_type[i].m_is_registered(obj,cb)) + return 1; + + if(obj == null) begin + foreach(m_derived_types[i]) begin + dt = uvm_typeid_base::typeid_map[m_derived_types[i] ]; + if(dt != null && dt.check_registration(null,cb)) + return 1; + end + end + + return 0; + endfunction + +endclass + + + +//------------------------------------------------------------------------------ +// +// Class - uvm_typed_callbacks#(T) +// +//------------------------------------------------------------------------------ +// +// Another internal class. This contains the queue of typewide +// callbacks. It also contains some of the public interface methods, +// but those methods are accessed via the uvm_callbacks#() class +// so they are documented in that class even though the implementation +// is in this class. +// +// The , , and methods are implemented in this class. + +class uvm_typed_callbacks#(type T=uvm_object) extends uvm_callbacks_base; + + static uvm_queue#(uvm_callback) m_tw_cb_q; + static string m_typename; + + typedef uvm_typed_callbacks#(T) this_type; + typedef uvm_callbacks_base super_type; + + //The actual global object from the derivative class. Note that this is + //just a reference to the object that is generated in the derived class. + static this_type m_t_inst; + + // UVM ! + static function void uvmt_drop_globals(); + m_tw_cb_q.delete(); + m_t_inst = null; + endfunction + // UVM ! + + static function this_type m_initialize(); + if(m_t_inst == null) begin + void'(super_type::m_initialize()); + m_t_inst = new; + m_t_inst.m_tw_cb_q = new("typewide_queue"); + end + return m_t_inst; + endfunction + + //Type checking interface: is given ~obj~ of type T? + virtual function bit m_am_i_a(uvm_object obj); +`ifdef VERILATOR // https://github.com/verilator/verilator/issues/2412 + T casted_obj; + if (obj == null) + return 1; + return($cast(casted_obj,obj)); +`else // Functionally equivelent original code, included here for comparison + T this_type; + if (obj == null) + return 1; + return($cast(this_type,obj)); +`endif + endfunction + + //Getting the typewide queue + virtual function uvm_queue#(uvm_callback) m_get_tw_cb_q(uvm_object obj); + if(m_am_i_a(obj)) begin + foreach(m_derived_types[i]) begin + super_type dt; + dt = uvm_typeid_base::typeid_map[m_derived_types[i] ]; + if(dt != null && dt != this) begin + m_get_tw_cb_q = dt.m_get_tw_cb_q(obj); + if(m_get_tw_cb_q != null) + return m_get_tw_cb_q; + end + end + return m_t_inst.m_tw_cb_q; + end + else + return null; + endfunction + + static function int m_cb_find(uvm_queue#(uvm_callback) q, uvm_callback cb); + for(int i=0; i str.len() ? max_cb_name : str.len(); + str = "(*)"; + max_inst_name = max_inst_name > str.len() ? max_inst_name : str.len(); + end + + if(obj ==null) begin + if(m_t_inst.m_pool.first(bobj)) begin + do + if($cast(me,bobj)) break; + while(m_t_inst.m_pool.next(bobj)); + end + if(me != null || m_t_inst.m_tw_cb_q.size()) begin + qs.push_back($sformatf("Registered callbacks for all instances of %s\n", tname)); + qs.push_back("---------------------------------------------------------------\n"); + end + if(me != null) begin + do begin + if($cast(me,bobj)) begin + q = m_t_inst.m_pool.get(bobj); + if (q==null) begin + q=new; + m_t_inst.m_pool.add(bobj,q); + end + for(int i=0; i str.len() ? max_cb_name : str.len(); + str = bobj.get_full_name(); + max_inst_name = max_inst_name > str.len() ? max_inst_name : str.len(); + end + end + end while (m_t_inst.m_pool.next(bobj)); + end + else begin + qs.push_back($sformatf("No callbacks registered for any instances of type %s\n", tname)); + end + end + else begin + if(m_t_inst.m_pool.exists(bobj) || m_t_inst.m_tw_cb_q.size()) begin + qs.push_back($sformatf("Registered callbacks for instance %s of %s\n", obj.get_full_name(), tname)); + qs.push_back("---------------------------------------------------------------\n"); + end + if(m_t_inst.m_pool.exists(bobj)) begin + q = m_t_inst.m_pool.get(bobj); + if(q==null) begin + q=new; + m_t_inst.m_pool.add(bobj,q); + end + for(int i=0; i str.len() ? max_cb_name : str.len(); + str = bobj.get_full_name(); + max_inst_name = max_inst_name > str.len() ? max_inst_name : str.len(); + end + end + end + if(!cbq.size()) begin + if(obj == null) str = "*"; + else str = obj.get_full_name(); + qs.push_back($sformatf("No callbacks registered for instance %s of type %s\n", str, tname)); + end + + foreach (cbq[i]) begin + qs.push_back($sformatf("%s %s %s on %s %s\n", cbq[i], blanks.substr(0,max_cb_name-cbq[i].len()-1), inst_q[i], blanks.substr(0,max_inst_name - inst_q[i].len()-1), mode_q[i])); + end +//UVM `uvm_info("UVM/CB/DISPLAY",`UVM_STRING_QUEUE_STREAMING_PACK(qs),UVM_NONE) + + m_tracing = 1; //allow tracing to be resumed + endfunction + +endclass + + + +//------------------------------------------------------------------------------ +// +// CLASS -- NODOCS -- uvm_callbacks #(T,CB) +// +// The ~uvm_callbacks~ class provides a base class for implementing callbacks, +// which are typically used to modify or augment component behavior without +// changing the component class. To work effectively, the developer of the +// component class defines a set of "hook" methods that enable users to +// customize certain behaviors of the component in a manner that is controlled +// by the component developer. The integrity of the component's overall behavior +// is intact, while still allowing certain customizable actions by the user. +// +// To enable compile-time type-safety, the class is parameterized on both the +// user-defined callback interface implementation as well as the object type +// associated with the callback. The object type-callback type pair are +// associated together using the <`uvm_register_cb> macro to define +// a valid pairing; valid pairings are checked when a user attempts to add +// a callback to an object. +// +// To provide the most flexibility for end-user customization and reuse, it +// is recommended that the component developer also define a corresponding set +// of virtual method hooks in the component itself. This affords users the ability +// to customize via inheritance/factory overrides as well as callback object +// registration. The implementation of each virtual method would provide the +// default traversal algorithm for the particular callback being called. Being +// virtual, users can define subtypes that override the default algorithm, +// perform tasks before and/or after calling super. to execute any +// registered callbacks, or to not call the base implementation, effectively +// disabling that particular hook. A demonstration of this methodology is +// provided in an example included in the kit. +//------------------------------------------------------------------------------ + +// Class: uvm_callbacks#(T, CB) +// Implementation of uvm_callbacks#(T,CB) class, as defined in +// section 10.7.2.1. +// +// | class uvm_callbacks #(type T=uvm_object, type CB=uvm_callback) +// + +// @uvm-ieee 1800.2-2017 auto 10.7.2.1 +class uvm_callbacks #(type T=uvm_object, type CB=uvm_callback) + extends uvm_typed_callbacks#(T); + + // Parameter -- NODOCS -- T + // + // This type parameter specifies the base object type with which the + // callback objects will be registered. This object must be + // a derivative of ~uvm_object~. + + // Parameter -- NODOCS -- CB + // + // This type parameter specifies the base callback type that will be + // managed by this callback class. The callback type is typically a + // interface class, which defines one or more virtual method prototypes + // that users can override in subtypes. This type must be a derivative + // of . + + typedef uvm_typed_callbacks#(T) super_type; + typedef uvm_callbacks#(T,CB) this_type; + + + // Singleton instance is used for type checking + local static this_type m_inst; + + // typeinfo + static uvm_typeid_base m_typeid; + static uvm_typeid_base m_cb_typeid; + + static string m_typename; + static string m_cb_typename; + static uvm_callbacks#(T,uvm_callback) m_base_inst; + + bit m_registered; + + // UVM ! + static function void uvmt_drop_globals(); + m_tw_cb_q.delete(); + m_t_inst = null; + m_inst = null; + endfunction + // UVM ! + + // get + // --- + + static function this_type get(); + + if (m_inst == null) begin + uvm_typeid_base cb_base_type; + + void'(super_type::m_initialize()); + + cb_base_type = uvm_typeid#(uvm_callback)::get(); + m_cb_typeid = uvm_typeid#(CB)::get(); + m_typeid = uvm_typeid#(T)::get(); + + m_inst = new; + + if (cb_base_type == m_cb_typeid) begin + $cast(m_base_inst, m_inst); + // The base inst in the super class gets set to this base inst + m_t_inst = m_base_inst; + uvm_typeid_base::typeid_map[m_typeid] = m_inst; + uvm_typeid_base::type_map[m_b_inst] = m_typeid; + end + else begin + m_base_inst = uvm_callbacks#(T,uvm_callback)::get(); + m_base_inst.m_this_type.push_back(m_inst); + end + + if (m_inst == null) + `uvm_fatal("CB/INTERNAL","get(): m_inst is null") + end + + return m_inst; + endfunction + + + + // m_register_pair + // ------------- + // Register valid callback type + + static function bit m_register_pair(string tname="", cbname=""); + this_type inst = get(); + + m_typename = tname; + super_type::m_typename = tname; + m_typeid.typename = tname; + + m_cb_typename = cbname; + m_cb_typeid.typename = cbname; + + inst.m_registered = 1; + + return 1; + endfunction + + virtual function bit m_is_registered(uvm_object obj, uvm_callback cb); + if(m_is_for_me(cb) && m_am_i_a(obj)) begin + return m_registered; + end + endfunction + + //Does type check to see if the callback is valid for this type + virtual function bit m_is_for_me(uvm_callback cb); + CB this_cb; + return($cast(this_cb,cb)); + endfunction + + // Group -- NODOCS -- Add/delete interface + + // Function -- NODOCS -- add + // + // Registers the given callback object, ~cb~, with the given + // ~obj~ handle. The ~obj~ handle can be ~null~, which allows + // registration of callbacks without an object context. If + // ~ordering~ is UVM_APPEND (default), the callback will be executed + // after previously added callbacks, else the callback + // will be executed ahead of previously added callbacks. The ~cb~ + // is the callback handle; it must be non-~null~, and if the callback + // has already been added to the object instance then a warning is + // issued. Note that the CB parameter is optional. For example, the + // following are equivalent: + // + //| uvm_callbacks#(my_comp)::add(comp_a, cb); + //| uvm_callbacks#(my_comp, my_callback)::add(comp_a,cb); + + // UVM ~ + // @uvm-ieee 1800.2-2017 auto 10.7.2.3.1 + static function void add(T obj, uvm_callback cb, uvm_apprepend ordering=UVM_APPEND); + uvm_queue#(uvm_callback) q; + string nm,tnm; + + void'(get()); + + if (cb==null) begin + if (obj==null) + nm = "(*)"; + else + nm = obj.get_full_name(); + + if (m_base_inst.m_typename!="") + tnm = m_base_inst.m_typename; + else if (obj != null) + tnm = obj.get_type_name(); + else + tnm = "uvm_object"; + + uvm_report_error("CBUNREG", + {"Null callback object cannot be registered with object ", + nm, " (", tnm, ")"}, UVM_NONE); + return; + end + + if (!m_base_inst.check_registration(obj,cb)) begin + + if (obj==null) + nm = "(*)"; + else + nm = obj.get_full_name(); + + if (m_base_inst.m_typename!="") + tnm = m_base_inst.m_typename; + else if(obj != null) + tnm = obj.get_type_name(); + else + tnm = "uvm_object"; + + uvm_report_warning("CBUNREG", + {"Callback ", cb.get_name(), " cannot be registered with object ", + nm, " because callback type ", cb.get_type_name(), + " is not registered with object type ", tnm }, UVM_NONE); + end + + if(obj == null) begin + + if (m_cb_find(m_t_inst.m_tw_cb_q,cb) != -1) begin + + if (m_base_inst.m_typename!="") + tnm = m_base_inst.m_typename; + else tnm = "uvm_object"; + + uvm_report_warning("CBPREG", + {"Callback object ", cb.get_name(), + " is already registered with type ", tnm }, UVM_NONE); + end + else begin + `uvm_cb_trace_noobj(cb,$sformatf("Add (%s) typewide callback %0s for type %s", + ordering.name(), cb.get_name(), m_base_inst.m_typename)) + m_t_inst.m_add_tw_cbs(cb,ordering); + end + end + + else begin + + `uvm_cb_trace_noobj(cb,$sformatf("Add (%s) callback %0s to object %0s ", + ordering.name(), cb.get_name(), obj.get_full_name())) + + q = m_base_inst.m_pool.get(obj); + + if (q==null) begin + q=new; + m_base_inst.m_pool.add(obj,q); + end + + if(q.size() == 0) begin + // Need to make sure that registered report catchers are added. This + // way users don't need to set up uvm_report_object as a super type. +//UVM uvm_report_object o; +//UVM +//UVM if($cast(o,obj)) begin +//UVM uvm_queue#(uvm_callback) qr; +//UVM void'(uvm_callbacks#(uvm_report_object, uvm_callback)::get()); +//UVM qr = uvm_callbacks#(uvm_report_object,uvm_callback)::m_t_inst.m_tw_cb_q; +//UVM for(int i=0; i the CB parameter is optional. ~root~ specifies the location in + // the component hierarchy to start the search for ~name~. See + // for more details on searching by name. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.3.2 +//UVM static function void add_by_name(string name, +//UVM uvm_callback cb, +//UVM uvm_component root, +//UVM uvm_apprepend ordering=UVM_APPEND); +//UVM uvm_component cq[$]; +//UVM uvm_root top; +//UVM uvm_coreservice_t cs; +//UVM T t; +//UVM void'(get()); +//UVM cs = uvm_coreservice_t::get(); +//UVM top = cs.get_root(); +//UVM +//UVM if(cb==null) begin +//UVM uvm_report_error("CBUNREG", { "Null callback object cannot be registered with object(s) ", +//UVM name }, UVM_NONE); +//UVM return; +//UVM end +//UVM `uvm_cb_trace_noobj(cb,$sformatf("Add (%s) callback %0s by name to object(s) %0s ", +//UVM ordering.name(), cb.get_name(), name)) +//UVM top.find_all(name,cq,root); +//UVM if(cq.size() == 0) begin +//UVM uvm_report_warning("CBNOMTC", { "add_by_name failed to find any components matching the name ", +//UVM name, ", callback ", cb.get_name(), " will not be registered." }, UVM_NONE); +//UVM end +//UVM foreach(cq[i]) begin +//UVM if($cast(t,cq[i])) begin +//UVM add(t,cb,ordering); +//UVM end +//UVM end +//UVM endfunction + + + // Function -- NODOCS -- delete + // + // Deletes the given callback object, ~cb~, from the queue associated with + // the given ~obj~ handle. The ~obj~ handle can be ~null~, which allows + // de-registration of callbacks without an object context. + // The ~cb~ is the callback handle; it must be non-~null~, and if the callback + // has already been removed from the object instance then a warning is + // issued. Note that the CB parameter is optional. For example, the + // following are equivalent: + // + //| uvm_callbacks#(my_comp)::delete(comp_a, cb); + //| uvm_callbacks#(my_comp, my_callback)::delete(comp_a,cb); + + // @uvm-ieee 1800.2-2017 auto 10.7.2.3.3 + static function void delete(T obj, uvm_callback cb); + uvm_object b_obj = obj; + uvm_queue#(uvm_callback) q; + bit found; + int pos; + void'(get()); + + if(obj == null) begin + `uvm_cb_trace_noobj(cb,$sformatf("Delete typewide callback %0s for type %s", + cb.get_name(), m_base_inst.m_typename)) + found = m_t_inst.m_delete_tw_cbs(cb); + end + else begin + `uvm_cb_trace_noobj(cb,$sformatf("Delete callback %0s from object %0s ", + cb.get_name(), obj.get_full_name())) + q = m_base_inst.m_pool.get(b_obj); + pos = m_cb_find(q,cb); + if(pos != -1) begin + q.delete(pos); + found = 1; + end + end + if(!found) begin + string nm; + if(obj==null) nm = "(*)"; else nm = obj.get_full_name(); + uvm_report_warning("CBUNREG", { "Callback ", cb.get_name(), " cannot be removed from object ", + nm, " because it is not currently registered to that object." }, UVM_NONE); + end + endfunction + + + // Function -- NODOCS -- delete_by_name + // + // Removes the given callback object, ~cb~, associated with one or more + // uvm_component callback queues. As with the CB parameter is + // optional. ~root~ specifies the location in the component hierarchy to start + // the search for ~name~. See for more details on searching + // by name. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.3.4 +//UVM static function void delete_by_name(string name, uvm_callback cb, +//UVM uvm_component root); +//UVM uvm_component cq[$]; +//UVM uvm_root top; +//UVM T t; +//UVM uvm_coreservice_t cs; +//UVM void'(get()); +//UVM cs = uvm_coreservice_t::get(); +//UVM top = cs.get_root(); +//UVM +//UVM `uvm_cb_trace_noobj(cb,$sformatf("Delete callback %0s by name from object(s) %0s ", +//UVM cb.get_name(), name)) +//UVM top.find_all(name,cq,root); +//UVM if(cq.size() == 0) begin +//UVM uvm_report_warning("CBNOMTC", { "delete_by_name failed to find any components matching the name ", +//UVM name, ", callback ", cb.get_name(), " will not be unregistered." }, UVM_NONE); +//UVM end +//UVM foreach(cq[i]) begin +//UVM if($cast(t,cq[i])) begin +//UVM delete(t,cb); +//UVM end +//UVM end +//UVM endfunction + + //-------------------------- + // Group -- NODOCS -- Iterator Interface + //-------------------------- + // + // This set of functions provide an iterator interface for callback queues. A facade + // class, is also available, and is the generally preferred way to + // iterate over callback queues. + + static function void m_get_q (ref uvm_queue #(uvm_callback) q, input T obj); + if(!m_base_inst.m_pool.exists(obj)) begin //no instance specific + q = (obj == null) ? m_t_inst.m_tw_cb_q : m_t_inst.m_get_tw_cb_q(obj); + end + else begin + q = m_base_inst.m_pool.get(obj); + if(q==null) begin + q=new; + m_base_inst.m_pool.add(obj,q); + end + end + endfunction + + + // Function -- NODOCS -- get_first + // + // Returns the first enabled callback of type CB which resides in the queue for ~obj~. + // If ~obj~ is ~null~ then the typewide queue for T is searched. ~itr~ is the iterator; + // it will be updated with a value that can be supplied to to get the next + // callback object. + // + // If the queue is empty then ~null~ is returned. + // + // The iterator class may be used as an alternative, simplified, + // iterator interface. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.4.1 + static function CB get_first (ref int itr, input T obj); + uvm_queue#(uvm_callback) q; + CB cb; + void'(get()); + m_get_q(q,obj); + for(itr = 0; itr to get the previous + // callback object. + // + // If the queue is empty then ~null~ is returned. + // + // The iterator class may be used as an alternative, simplified, + // iterator interface. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.4.2 + static function CB get_last (ref int itr, input T obj); + uvm_queue#(uvm_callback) q; + CB cb; + void'(get()); + m_get_q(q,obj); + for(itr = q.size()-1; itr>=0; --itr) + if ($cast(cb, q.get(itr)) && cb.callback_mode()) + return cb; + return null; + endfunction + + + // Function -- NODOCS -- get_next + // + // Returns the next enabled callback of type CB which resides in the queue for ~obj~, + // using ~itr~ as the starting point. If ~obj~ is ~null~ then the typewide queue for T + // is searched. ~itr~ is the iterator; it will be updated with a value that can be + // supplied to to get the next callback object. + // + // If no more callbacks exist in the queue, then ~null~ is returned. will + // continue to return ~null~ in this case until or has been used to reset + // the iterator. + // + // The iterator class may be used as an alternative, simplified, + // iterator interface. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.4.3 + static function CB get_next (ref int itr, input T obj); + uvm_queue#(uvm_callback) q; + CB cb; + void'(get()); + m_get_q(q,obj); + for(itr = itr+1; itr to get the previous callback object. + // + // If no more callbacks exist in the queue, then ~null~ is returned. will + // continue to return ~null~ in this case until or has been used to reset + // the iterator. + // + // The iterator class may be used as an alternative, simplified, + // iterator interface. + + // @uvm-ieee 1800.2-2017 auto 10.7.2.4.4 + static function CB get_prev (ref int itr, input T obj); + uvm_queue#(uvm_callback) q; + CB cb; + void'(get()); + m_get_q(q,obj); + for(itr = itr-1; itr>= 0; --itr) + if($cast(cb, q.get(itr)) && cb.callback_mode()) + return cb; + return null; + endfunction + + + // Function: get_all + // Populates the end of the ~all_callbacks~ queue with the list of all registered callbacks + // for ~obj~ (whether they are enabled or disabled). + // + // If ~obj~ is ~null~, then ~all_callbacks~ shall be populated with all registered typewide + // callbacks. If ~obj~ is not ~null~, then ~all_callbacks~ shall be populated with both + // the typewide and instance callbacks (if any) registered for ~obj~. + // + // NOTE: This API contradicts the definition provided in section 10.7.2.5 of the P1800.2-2017 + // LRM. See DEVIATIONS.md for additional details. + // + //| static function void get_all( ref CB all_callbacks[$], input T obj=null ); + // + // @uvm-contrib This API is being considered for potential contribution to 1800.2 + + // @uvm-ieee 1800.2-2017 auto 10.7.2.5 + static function void get_all ( ref CB all_callbacks[$], input T obj=null ); + uvm_queue#(uvm_callback) q; + CB cb; + CB callbacks_to_append[$]; + CB unique_callbacks_to_append[$]; + + void'( get() ); + + if ((obj == null) || (!m_pool.exists(obj))) begin + // Only typewide callbacks exist + for (int qi=0; qi and +// <`uvm_do_callbacks_exit_on> provide a simple method for iterating +// callbacks and executing the callback methods. +//------------------------------------------------------------------------------ + +// @uvm-ieee 1800.2-2017 auto D.1.1 +class uvm_callback_iter#(type T = uvm_object, type CB = uvm_callback); + + local int m_i; + local T m_obj; + local CB m_cb; + + // Function -- NODOCS -- new + // + // Creates a new callback iterator object. It is required that the object + // context be provided. + + // @uvm-ieee 1800.2-2017 auto D.1.2.1 + function new(T obj); + m_obj = obj; + endfunction + + // Function -- NODOCS -- first + // + // Returns the first valid (enabled) callback of the callback type (or + // a derivative) that is in the queue of the context object. If the + // queue is empty then ~null~ is returned. + + // @uvm-ieee 1800.2-2017 auto D.1.2.2 + function CB first(); + m_cb = uvm_callbacks#(T,CB)::get_first(m_i, m_obj); + return m_cb; + endfunction + + // Function -- NODOCS -- last + // + // Returns the last valid (enabled) callback of the callback type (or + // a derivative) that is in the queue of the context object. If the + // queue is empty then ~null~ is returned. + + // @uvm-ieee 1800.2-2017 auto D.1.2.3 + function CB last(); + m_cb = uvm_callbacks#(T,CB)::get_last(m_i, m_obj); + return m_cb; + endfunction + + // Function -- NODOCS -- next + // + // Returns the next valid (enabled) callback of the callback type (or + // a derivative) that is in the queue of the context object. If there + // are no more valid callbacks in the queue, then ~null~ is returned. + + // @uvm-ieee 1800.2-2017 auto D.1.2.4 + function CB next(); + m_cb = uvm_callbacks#(T,CB)::get_next(m_i, m_obj); + return m_cb; + endfunction + + // Function -- NODOCS -- prev + // + // Returns the previous valid (enabled) callback of the callback type (or + // a derivative) that is in the queue of the context object. If there + // are no more valid callbacks in the queue, then ~null~ is returned. + + // @uvm-ieee 1800.2-2017 auto D.1.2.5 + function CB prev(); + m_cb = uvm_callbacks#(T,CB)::get_prev(m_i, m_obj); + return m_cb; + endfunction + + // Function -- NODOCS -- get_cb + // + // Returns the last callback accessed via a first() or next() + // call. + + // @uvm-ieee 1800.2-2017 auto D.1.2.6 + function CB get_cb(); + return m_cb; + endfunction + +/**** + function void trace(uvm_object obj = null); + if (m_cb != null && T::cbs::get_debug_flags() & UVM_CALLBACK_TRACE) begin + uvm_report_object reporter = null; + string who = "Executing "; + void'($cast(reporter, obj)); + if (reporter == null) void'($cast(reporter, m_obj)); + if (reporter == null) reporter = uvm_top; + if (obj != null) who = {obj.get_full_name(), " is executing "}; + else if (m_obj != null) who = {m_obj.get_full_name(), " is executing "}; + reporter.uvm_report_info("CLLBK_TRC", {who, "callback ", m_cb.get_name()}, UVM_LOW); + end + endfunction +****/ +endclass + + + +//------------------------------------------------------------------------------ +// CLASS -- NODOCS -- uvm_callback +// +// The ~uvm_callback~ class is the base class for user-defined callback classes. +// Typically, the component developer defines an application-specific callback +// class that extends from this class. In it, he defines one or more virtual +// methods, called a ~callback interface~, that represent the hooks available +// for user override. +// +// Methods intended for optional override should not be declared ~pure.~ Usually, +// all the callback methods are defined with empty implementations so users have +// the option of overriding any or all of them. +// +// The prototypes for each hook method are completely application specific with +// no restrictions. +//------------------------------------------------------------------------------ + +//-!!!- NOTICE -------------------------------------------------------------!!!- +// This is a non-production-ready modified version of UVM intended for coverage +// testing purpouses +//-!!!----------------------------------------------------------------------!!!- + +// Status: Partial implementation + +`include "macros/uvm_object_defines.svh" + +// UVM ~ +// @uvm-ieee 1800.2-2017 auto 10.7.1.1 +class uvm_callback extends uvm_object; + protected bit m_enabled = 1; + + `uvm_object_utils(uvm_callback) + + // Function -- NODOCS -- new + // + // Creates a new uvm_callback object, giving it an optional ~name~. + + // @uvm-ieee 1800.2-2017 auto 10.7.1.2.1 + function new(string name="uvm_callback"); + super.new(name); + endfunction + + + // Function -- NODOCS -- callback_mode + // + // Enable/disable callbacks (modeled like rand_mode and constraint_mode). + + // @uvm-ieee 1800.2-2017 auto 10.7.1.2.2 + function bit callback_mode(int on=-1); +//UVM if(on == 0 || on == 1) begin +//UVM `uvm_cb_trace_noobj(this,$sformatf("Setting callback mode for %s to %s", +//UVM get_name(), ((on==1) ? "ENABLED":"DISABLED"))) +//UVM end +//UVM else begin +//UVM `uvm_cb_trace_noobj(this,$sformatf("Callback mode for %s is %s", +//UVM get_name(), ((m_enabled==1) ? "ENABLED":"DISABLED"))) +//UVM end + callback_mode = m_enabled; + if(on==0) m_enabled=0; + if(on==1) m_enabled=1; + endfunction + + + // Function -- NODOCS -- is_enabled + // + // Returns 1 if the callback is enabled, 0 otherwise. + + // @uvm-ieee 1800.2-2017 auto 10.7.1.2.3 + function bit is_enabled(); + return callback_mode(); + endfunction + +endclass diff --git a/test_regress/t/t_uvm/base/uvm_domain.svh b/test_regress/t/t_uvm/base/uvm_domain.svh new file mode 100644 index 00000000000..d894177f546 --- /dev/null +++ b/test_regress/t/t_uvm/base/uvm_domain.svh @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//---------------------------------------------------------------------- +// Copyright 2007-2018 Mentor Graphics Corporation +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2011 AMD +// Copyright 2015-2018 NVIDIA Corporation +// Copyright 2012 Accellera Systems Initiative +// 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. +//---------------------------------------------------------------------- + +//-!!!- NOTICE -------------------------------------------------------------!!!- +// This is a non-production-ready modified version of UVM intended for coverage +// testing purpouses +//-!!!----------------------------------------------------------------------!!!- + +//UVM typedef class uvm_build_phase; +//UVM typedef class uvm_connect_phase; +//UVM typedef class uvm_end_of_elaboration_phase; +//UVM typedef class uvm_start_of_simulation_phase; +//UVM typedef class uvm_run_phase; +//UVM typedef class uvm_extract_phase; +//UVM typedef class uvm_check_phase; +//UVM typedef class uvm_report_phase; +//UVM typedef class uvm_final_phase; +//UVM +//UVM typedef class uvm_pre_reset_phase; +//UVM typedef class uvm_reset_phase; +//UVM typedef class uvm_post_reset_phase; +//UVM typedef class uvm_pre_configure_phase; +//UVM typedef class uvm_configure_phase; +//UVM typedef class uvm_post_configure_phase; +//UVM typedef class uvm_pre_main_phase; +//UVM typedef class uvm_main_phase; +//UVM typedef class uvm_post_main_phase; +//UVM typedef class uvm_pre_shutdown_phase; +//UVM typedef class uvm_shutdown_phase; +//UVM typedef class uvm_post_shutdown_phase; +//UVM +//UVM uvm_phase build_ph; +//UVM uvm_phase connect_ph; +//UVM uvm_phase end_of_elaboration_ph; +//UVM uvm_phase start_of_simulation_ph; +//UVM uvm_phase run_ph; +//UVM uvm_phase extract_ph; +//UVM uvm_phase check_ph; +//UVM uvm_phase report_ph; + +//------------------------------------------------------------------------------ +// +// Class -- NODOCS -- uvm_domain +// +//------------------------------------------------------------------------------ +// +// Phasing schedule node representing an independent branch of the schedule. +// Handle used to assign domains to components or hierarchies in the testbench +// + +// @uvm-ieee 1800.2-2017 auto 9.4.1 +class uvm_domain extends uvm_phase; + + static local uvm_domain m_uvm_domain; // run-time phases + static local uvm_domain m_domains[string]; + static local uvm_phase m_uvm_schedule; + +//UVM + static function uvmt_drop_globals(); + m_uvm_domain = null; + m_domains.delete(); + m_uvm_schedule = null; + endfunction +//UVM + + // @uvm-ieee 1800.2-2017 auto 9.4.2.2 + static function void get_domains(output uvm_domain domains[string]); + domains = m_domains; + endfunction + + + // Function -- NODOCS -- get_uvm_schedule + // + // Get the "UVM" schedule, which consists of the run-time phases that + // all components execute when participating in the "UVM" domain. + // + static function uvm_phase get_uvm_schedule(); + void'(get_uvm_domain()); + return m_uvm_schedule; + endfunction + + + // Function -- NODOCS -- get_common_domain + // + // Get the "common" domain, which consists of the common phases that + // all components execute in sync with each other. Phases in the "common" + // domain are build, connect, end_of_elaboration, start_of_simulation, run, + // extract, check, report, and final. + // + static function uvm_domain get_common_domain(); + + uvm_domain domain; + + if(m_domains.exists("common")) + domain = m_domains["common"]; + + if (domain != null) + return domain; + + domain = new("common"); +//UVM domain.add(uvm_build_phase::get()); +//UVM domain.add(uvm_connect_phase::get()); +//UVM domain.add(uvm_end_of_elaboration_phase::get()); +//UVM domain.add(uvm_start_of_simulation_phase::get()); +//UVM domain.add(uvm_run_phase::get()); +//UVM domain.add(uvm_extract_phase::get()); +//UVM domain.add(uvm_check_phase::get()); +//UVM domain.add(uvm_report_phase::get()); +//UVM domain.add(uvm_final_phase::get()); +//UVM +//UVM // for backward compatibility, make common phases visible; +//UVM // same as uvm__phase::get(). +//UVM build_ph = domain.find(uvm_build_phase::get()); +//UVM connect_ph = domain.find(uvm_connect_phase::get()); +//UVM end_of_elaboration_ph = domain.find(uvm_end_of_elaboration_phase::get()); +//UVM start_of_simulation_ph = domain.find(uvm_start_of_simulation_phase::get()); +//UVM run_ph = domain.find(uvm_run_phase::get()); +//UVM extract_ph = domain.find(uvm_extract_phase::get()); +//UVM check_ph = domain.find(uvm_check_phase::get()); +//UVM report_ph = domain.find(uvm_report_phase::get()); + + domain = get_uvm_domain(); +//UVM m_domains["common"].add(domain, +//UVM .with_phase(m_domains["common"].find(uvm_run_phase::get()))); +// Temporarily remove default run phase +//UVM + + return m_domains["common"]; + + endfunction + + + + // @uvm-ieee 1800.2-2017 auto 9.4.2.3 + static function void add_uvm_phases(uvm_phase schedule); +//UVM + $display("[uvm]: WARNING: add_uvm_phases is a stub"); +//UVM +//UVM schedule.add(uvm_pre_reset_phase::get()); +//UVM schedule.add(uvm_reset_phase::get()); +//UVM schedule.add(uvm_post_reset_phase::get()); +//UVM schedule.add(uvm_pre_configure_phase::get()); +//UVM schedule.add(uvm_configure_phase::get()); +//UVM schedule.add(uvm_post_configure_phase::get()); +//UVM schedule.add(uvm_pre_main_phase::get()); +//UVM schedule.add(uvm_main_phase::get()); +//UVM schedule.add(uvm_post_main_phase::get()); +//UVM schedule.add(uvm_pre_shutdown_phase::get()); +//UVM schedule.add(uvm_shutdown_phase::get()); +//UVM schedule.add(uvm_post_shutdown_phase::get()); + + endfunction + + + // Function -- NODOCS -- get_uvm_domain + // + // Get a handle to the singleton ~uvm~ domain + // + static function uvm_domain get_uvm_domain(); + + if (m_uvm_domain == null) begin + m_uvm_domain = new("uvm"); + m_uvm_schedule = new("uvm_sched", UVM_PHASE_SCHEDULE); + add_uvm_phases(m_uvm_schedule); +//UVM m_uvm_domain.add(m_uvm_schedule); + end + return m_uvm_domain; + endfunction + + + + // @uvm-ieee 1800.2-2017 auto 9.4.2.1 + function new(string name); + super.new(name,UVM_PHASE_DOMAIN); + if (m_domains.exists(name)) + `uvm_error("UNIQDOMNAM", $sformatf("Domain created with non-unique name '%s'", name)) + m_domains[name] = this; + endfunction + + + // @uvm-ieee 1800.2-2017 auto 9.4.2.4 + function void jump(uvm_phase phase); + uvm_phase phases[$]; + + m_get_transitive_children(phases); + + phases = phases.find(item) with (item.get_state() inside {[UVM_PHASE_STARTED:UVM_PHASE_CLEANUP]}); + + foreach(phases[idx]) + if(phases[idx].is_before(phase) || phases[idx].is_after(phase)) + phases[idx].jump(phase); + + endfunction + +// jump_all +// -------- + static function void jump_all(uvm_phase phase); + uvm_domain domains[string]; + + uvm_domain::get_domains(domains); + + foreach(domains[idx]) + domains[idx].jump(phase); + + endfunction +endclass diff --git a/test_regress/t/t_uvm/base/uvm_object.svh b/test_regress/t/t_uvm/base/uvm_object.svh index 790811df58a..4f8db825581 100644 --- a/test_regress/t/t_uvm/base/uvm_object.svh +++ b/test_regress/t/t_uvm/base/uvm_object.svh @@ -35,6 +35,9 @@ // Status: MOCK +// UVM MOCK +class uvm_copier; endclass + class uvm_object; local string m_leaf_name; local int m_inst_id; @@ -46,6 +49,9 @@ class uvm_object; extern function int get_inst_id(); virtual function string get_type_name (); return ""; endfunction + + extern virtual function void do_copy (uvm_object rhs); + extern virtual function string get_full_name (); endclass // UVM 1:1* @@ -69,3 +75,13 @@ endfunction function int uvm_object::get_inst_id(); return m_inst_id; endfunction + +// UVM 1:1 +function void uvm_object::do_copy (uvm_object rhs); + return; +endfunction + +// UVM 1:1 +function string uvm_object::get_full_name (); + return get_name(); +endfunction diff --git a/test_regress/t/t_uvm/base/uvm_object_globals.svh b/test_regress/t/t_uvm/base/uvm_object_globals.svh new file mode 100644 index 00000000000..6d0fa347dab --- /dev/null +++ b/test_regress/t/t_uvm/base/uvm_object_globals.svh @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//------------------------------------------------------------------------------ +// Copyright 2007-2011 Mentor Graphics Corporation +// Copyright 2017 Intel Corporation +// Copyright 2010 Synopsys, Inc. +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2010 AMD +// Copyright 2015-2018 NVIDIA 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. +//------------------------------------------------------------------------------ + +typedef enum { UVM_PHASE_UNINITIALIZED = 0, + UVM_PHASE_DORMANT = 1, + UVM_PHASE_SCHEDULED = 2, + UVM_PHASE_SYNCING = 4, + UVM_PHASE_STARTED = 8, + UVM_PHASE_EXECUTING = 16, + UVM_PHASE_READY_TO_END = 32, + UVM_PHASE_ENDED = 64, + UVM_PHASE_CLEANUP = 128, + UVM_PHASE_DONE = 256, + UVM_PHASE_JUMPING = 512 + } uvm_phase_state; + +typedef enum { UVM_PHASE_IMP, + UVM_PHASE_NODE, + UVM_PHASE_TERMINAL, + UVM_PHASE_SCHEDULE, + UVM_PHASE_DOMAIN, + UVM_PHASE_GLOBAL +} uvm_phase_type; diff --git a/test_regress/t/t_uvm/base/uvm_phase.svh b/test_regress/t/t_uvm/base/uvm_phase.svh new file mode 100644 index 00000000000..334ac529983 --- /dev/null +++ b/test_regress/t/t_uvm/base/uvm_phase.svh @@ -0,0 +1,944 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//---------------------------------------------------------------------- +// Copyright 2007-2014 Mentor Graphics Corporation +// Copyright 2014 Semifore +// Copyright 2010-2014 Synopsys, Inc. +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2011-2012 AMD +// Copyright 2013-2018 NVIDIA Corporation +// Copyright 2012-2017 Cisco 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. +//---------------------------------------------------------------------- + +//-!!!- NOTICE -------------------------------------------------------------!!!- +// This is a non-production-ready modified version of UVM intended for coverage +// testing purpouses +//-!!!----------------------------------------------------------------------!!!- + +// Status: Partial +// * State + +`ifdef UVM_ENABLE_DEPRECATED_API + typedef class uvm_test_done_objection; +`endif + +typedef class uvm_sequencer_base; + +typedef class uvm_domain; +typedef class uvm_task_phase; + +typedef class uvm_phase_cb; + +typedef uvm_callbacks#(uvm_phase, uvm_phase_cb) uvm_phase_cb_pool /* @uvm-ieee 1800.2-2017 auto D.4.1*/ ; + +// UVM ~ +// @uvm-ieee 1800.2-2017 auto 9.3.1.2 +class uvm_phase extends uvm_object; + + //`uvm_object_utils(uvm_phase) + + //UVM `uvm_register_cb(uvm_phase, uvm_phase_cb) + + + //-------------------- + // Group -- NODOCS -- Construction + //-------------------- + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.1 + extern function new(string name="uvm_phase", + uvm_phase_type phase_type=UVM_PHASE_SCHEDULE, + uvm_phase parent=null); + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.2 + extern function uvm_phase_type get_phase_type(); + + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.3 + extern virtual function void set_max_ready_to_end_iterations(int max); + + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.4 + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.6 + extern virtual function int get_max_ready_to_end_iterations(); + + // @uvm-ieee 1800.2-2017 auto 9.3.1.3.5 + extern static function void set_default_max_ready_to_end_iterations(int max); + + extern static function int get_default_max_ready_to_end_iterations(); + + //------------- + // Group -- NODOCS -- State + //------------- + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.1 + extern function uvm_phase_state get_state(); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.2 + extern function int get_run_count(); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.3 + extern function uvm_phase find_by_name(string name, bit stay_in_scope=1); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.4 + extern function uvm_phase find(uvm_phase phase, bit stay_in_scope=1); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.5 + extern function bit is(uvm_phase phase); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.6 + extern function bit is_before(uvm_phase phase); + + + + // @uvm-ieee 1800.2-2017 auto 9.3.1.4.7 + extern function bit is_after(uvm_phase phase); + + //-------------------------- + // Internal - Implementation + //-------------------------- + + // Implementation - Construction + //------------------------------ + protected uvm_phase_type m_phase_type; + protected uvm_phase m_parent; // our 'schedule' node [or points 'up' one level] + uvm_phase m_imp; // phase imp to call when we execute this node + + // Implementation - State + //----------------------- + local uvm_phase_state m_state; + local int m_run_count; // num times this phase has executed + local process m_phase_proc; + local static int m_default_max_ready_to_end_iters = 20; // 20 is the initial value defined by 1800.2-2017 9.3.1.3.5 +`ifndef UVM_ENABLE_DEPRECATED_API + local +`endif + int max_ready_to_end_iters = get_default_max_ready_to_end_iterations(); + int m_num_procs_not_yet_returned; + extern function uvm_phase m_find_predecessor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null); + extern function uvm_phase m_find_successor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null); + extern function uvm_phase m_find_predecessor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null); + extern function uvm_phase m_find_successor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null); + extern function void m_print_successors(); + + // Implementation - Callbacks + //--------------------------- + // Provide the required component traversal behavior. Called by execute() +//UVM virtual function void traverse(uvm_component comp, +//UVM uvm_phase phase, +//UVM uvm_phase_state state); +//UVM endfunction +//UVM // Provide the required per-component execution flow. Called by traverse() +//UVM virtual function void execute(uvm_component comp, +//UVM uvm_phase phase); +//UVM endfunction + + // Implementation - Schedule + //-------------------------- + protected bit m_predecessors[uvm_phase]; + protected bit m_successors[uvm_phase]; + protected uvm_phase m_end_node; + // Track the currently executing real task phases (used for debug) + static protected bit m_executing_phases[uvm_phase]; +//UVM function uvm_phase get_begin_node(); if (m_imp != null) return this; return null; endfunction +//UVM function uvm_phase get_end_node(); return m_end_node; endfunction + + // Implementation - Synchronization + //--------------------------------- + local uvm_phase m_sync[$]; // schedule instance to which we are synced + +//UVM `ifdef UVM_ENABLE_DEPRECATED_API +//UVM // In order to avoid raciness during static initialization, +//UVM // the creation of the "phase done" objection has been +//UVM // delayed until the first call to get_objection(), and all +//UVM // internal APIs have been updated to call get_objection() instead +//UVM // of referring to phase_done directly. +//UVM // +//UVM // So as to avoid potential null handle dereferences in user code +//UVM // which was accessing the phase_done variable directly, the variable +//UVM // was renamed, and made local. This takes a difficult to debug +//UVM // run-time error, and converts it into an easy to catch compile-time +//UVM // error. +//UVM // +//UVM // Code which is broken due to the protection of phase_done should be +//UVM // refactored to use the get_objection() method. Note that this also +//UVM // opens the door to virtual get_objection() code, as described in +//UVM // https://accellera.mantishub.io/view.php?id=6260 +//UVM uvm_objection phase_done; +//UVM `else // !`ifdef UVM_ENABLE_DEPRECATED_API +//UVM local uvm_objection phase_done; +//UVM `endif + + local int unsigned m_ready_to_end_count; + +//UVM function int unsigned get_ready_to_end_count(); +//UVM return m_ready_to_end_count; +//UVM endfunction +//UVM +//UVM extern local function void get_predecessors_for_successors(output bit pred_of_succ[uvm_phase]); +//UVM extern local task m_wait_for_pred(); + + // Implementation - Jumping + //------------------------- +//UVM local bit m_jump_bkwd; +//UVM local bit m_jump_fwd; +//UVM local uvm_phase m_jump_phase; +//UVM local bit m_premature_end; +//UVM extern function void clear(uvm_phase_state state = UVM_PHASE_DORMANT); +//UVM extern function void clear_successors( +//UVM uvm_phase_state state = UVM_PHASE_DORMANT, +//UVM uvm_phase end_state=null); + + // Implementation - Overall Control + //--------------------------------- + local static mailbox #(uvm_phase) m_phase_hopper = new(); + +//UVM extern static task m_run_phases(); +//UVM extern local task execute_phase(); +//UVM extern local function void m_terminate_phase(); +//UVM extern local function void m_print_termination_state(); +//UVM extern local task wait_for_self_and_siblings_to_drop(); +//UVM extern function void kill(); +//UVM extern function void kill_successors(); + + // TBD add more useful debug + //--------------------------------- + protected static bit m_phase_trace; + local static bit m_use_ovm_run_semantic; + + +//UVM function string convert2string(); +//UVM //return $sformatf("PHASE %s = %p",get_name(),this); +//UVM string s; +//UVM s = $sformatf("phase: %s parent=%s pred=%s succ=%s",get_name(), +//UVM (m_parent==null) ? "null" : get_schedule_name(), +//UVM m_aa2string(m_predecessors), +//UVM m_aa2string(m_successors)); +//UVM return s; +//UVM endfunction +//UVM +//UVM local function string m_aa2string(bit aa[uvm_phase]); // TBD tidy +//UVM string s; +//UVM int i; +//UVM s = "'{ "; +//UVM foreach (aa[ph]) begin +//UVM uvm_phase n = ph; +//UVM s = {s, (n == null) ? "null" : n.get_name(), +//UVM (i == aa.num()-1) ? "" : ", "}; +//UVM i++; +//UVM end +//UVM s = {s, " }"}; +//UVM return s; +//UVM endfunction + + function bit is_domain(); + return (m_phase_type == UVM_PHASE_DOMAIN); + endfunction + + virtual function void m_get_transitive_children(ref uvm_phase phases[$]); + foreach (m_successors[succ]) + begin + phases.push_back(succ); + succ.m_get_transitive_children(phases); + end + endfunction + + +//UVM // @uvm-ieee 1800.2-2017 auto 9.3.1.7.1 +//UVM function uvm_objection get_objection(); +//UVM uvm_phase imp; +//UVM uvm_task_phase tp; +//UVM imp = get_imp(); +//UVM // Only nodes with a non-null uvm_task_phase imp have objections +//UVM if ((get_phase_type() != UVM_PHASE_NODE) || (imp == null) || !$cast(tp, imp)) begin +//UVM return null; +//UVM end +//UVM if (phase_done == null) begin +//UVM `ifdef UVM_ENABLE_DEPRECATED_API +//UVM if (get_name() == "run") begin +//UVM phase_done = uvm_test_done_objection::get(); +//UVM end +//UVM else begin +//UVM `ifdef VERILATOR +//UVM phase_done = uvm_objection::type_id_create({get_name(), "_objection"}); +//UVM `else +//UVM phase_done = uvm_objection::type_id::create({get_name(), "_objection"}); +//UVM `endif +//UVM end +//UVM `else // !UVM_ENABLE_DEPRECATED_API +//UVM `ifdef VERILATOR +//UVM phase_done = uvm_objection::type_id_create({get_name(), "_objection"}); +//UVM `else +//UVM phase_done = uvm_objection::type_id::create({get_name(), "_objection"}); +//UVM `endif +//UVM `endif // UVM_ENABLE_DEPRECATED_API +//UVM end +//UVM +//UVM return phase_done; +//UVM endfunction // get_objection + + // UVM ! + extern function uvm_domain get_domain(); + extern function uvm_phase get_schedule(bit hier = 0); + extern function void jump(uvm_phase phase); + extern function void set_jump_phase(uvm_phase phase) ; + extern function void end_prematurely() ; + + local bit m_jump_bkwd; + local bit m_jump_fwd; + local uvm_phase m_jump_phase; + local bit m_premature_end; + + extern function void add(uvm_phase phase, + uvm_phase with_phase=null, + uvm_phase after_phase=null, + uvm_phase before_phase=null, + uvm_phase start_with_phase=null, + uvm_phase end_with_phase=null + ); +endclass + +// UVM 1:1 +class uvm_phase_state_change extends uvm_object; + + `uvm_object_utils(uvm_phase_state_change) + + // Implementation -- do not use directly + /* local */ uvm_phase m_phase;/* */ + /* local */ uvm_phase_state m_prev_state; + /* local */ uvm_phase m_jump_to; + + function new(string name = "uvm_phase_state_change"); + super.new(name); + endfunction + + + + // @uvm-ieee 1800.2-2017 auto 9.3.2.2.1 + virtual function uvm_phase_state get_state(); + return m_phase.get_state(); + endfunction + + + // @uvm-ieee 1800.2-2017 auto 9.3.2.2.2 + virtual function uvm_phase_state get_prev_state(); + return m_prev_state; + endfunction + + + // @uvm-ieee 1800.2-2017 auto 9.3.2.2.3 + function uvm_phase jump_to(); + return m_jump_to; + endfunction + +endclass + +// UVM 1:1 +class uvm_phase_cb extends uvm_callback; + + + // @uvm-ieee 1800.2-2017 auto 9.3.3.2.1 + function new(string name="unnamed-uvm_phase_cb"); + super.new(name); + endfunction : new + + + // @uvm-ieee 1800.2-2017 auto 9.3.3.2.2 + virtual function void phase_state_change(uvm_phase phase, + uvm_phase_state_change change); + endfunction +endclass + +//------------------------------------------------------------------------------ +// IMPLEMENTATION +//------------------------------------------------------------------------------ + +// UVM ~ +function uvm_phase::new(string name="uvm_phase", + uvm_phase_type phase_type=UVM_PHASE_SCHEDULE, + uvm_phase parent=null); + super.new(name); + m_phase_type = phase_type; + + // The common domain is the only thing that initializes m_state. All + // other states are initialized by being 'added' to a schedule. + if ((name == "common") && + (phase_type == UVM_PHASE_DOMAIN)) + m_state = UVM_PHASE_DORMANT; + + m_run_count = 0; + m_parent = parent; + + //UVM begin + //UVM uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst(); + //UVM string val; + //UVM if (clp.get_arg_value("+UVM_PHASE_TRACE", val)) + //UVM m_phase_trace = 1; + //UVM else + //UVM m_phase_trace = 0; + //UVM if (clp.get_arg_value("+UVM_USE_OVM_RUN_SEMANTIC", val)) + //UVM m_use_ovm_run_semantic = 1; + //UVM else + //UVM m_use_ovm_run_semantic = 0; + //UVM end + m_phase_trace = 0; + m_use_ovm_run_semantic = 0; + //UVM + + + + if (parent == null && (phase_type == UVM_PHASE_SCHEDULE || + phase_type == UVM_PHASE_DOMAIN )) begin + //m_parent = this; + m_end_node = new({name,"_end"}, UVM_PHASE_TERMINAL, this); + this.m_successors[m_end_node] = 1; + m_end_node.m_predecessors[this] = 1; + end + +endfunction + +// UVM 1:1 +function uvm_phase_type uvm_phase::get_phase_type(); + return m_phase_type; +endfunction + +// UVM 1:1 +function void uvm_phase::set_max_ready_to_end_iterations(int max); + max_ready_to_end_iters = max; +endfunction + +// UVM 1:1 +function int uvm_phase::get_max_ready_to_end_iterations(); + return max_ready_to_end_iters; +endfunction + +// UVM 1:1 +function void uvm_phase::set_default_max_ready_to_end_iterations(int max); + m_default_max_ready_to_end_iters = max; +endfunction + +// UVM 1:1 +function int uvm_phase::get_default_max_ready_to_end_iterations(); + return m_default_max_ready_to_end_iters; +endfunction + +// UVM 1:1 +function uvm_phase_state uvm_phase::get_state(); + return m_state; +endfunction + +// UVM 1:1 +function int uvm_phase::get_run_count(); + return m_run_count; +endfunction + +// UVM 1:1 +function void uvm_phase::m_print_successors(); + uvm_phase found; + static string spaces = " "; + static int level; + if (m_phase_type == UVM_PHASE_DOMAIN) + level = 0; + `uvm_info("UVM/PHASE/SUCC",$sformatf("%s%s (%s) id=%0d",spaces.substr(0,level*2),get_name(), m_phase_type.name(),get_inst_id()),UVM_NONE) + level++; + foreach (m_successors[succ]) begin + succ.m_print_successors(); + end + level--; +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::m_find_predecessor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null); + uvm_phase found; + //$display(" FIND PRED node '",phase.get_name(),"' (id=",$sformatf("%0d",phase.get_inst_id()),") - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")"); + if (phase == null) begin + return null ; + end + if (phase == m_imp || phase == this) + return this; + foreach (m_predecessors[pred]) begin + uvm_phase orig; + orig = (orig_phase==null) ? this : orig_phase; + if (!stay_in_scope || + (pred.get_schedule() == orig.get_schedule()) || + (pred.get_domain() == orig.get_domain())) begin + found = pred.m_find_predecessor(phase,stay_in_scope,orig); + if (found != null) + return found; + end + end + return null; +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::m_find_predecessor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null); + uvm_phase found; + //$display(" FIND PRED node '",name,"' - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")"); + if (get_name() == name) + return this; + foreach (m_predecessors[pred]) begin + uvm_phase orig; + orig = (orig_phase==null) ? this : orig_phase; + if (!stay_in_scope || + (pred.get_schedule() == orig.get_schedule()) || + (pred.get_domain() == orig.get_domain())) begin + found = pred.m_find_predecessor_by_name(name,stay_in_scope,orig); + if (found != null) + return found; + end + end + return null; +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::m_find_successor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null); + uvm_phase found; + //$display(" FIND SUCC node '",phase.get_name(),"' (id=",$sformatf("%0d",phase.get_inst_id()),") - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")"); + if (phase == null) begin + return null ; + end + if (phase == m_imp || phase == this) begin + return this; + end + foreach (m_successors[succ]) begin + uvm_phase orig; + orig = (orig_phase==null) ? this : orig_phase; + if (!stay_in_scope || + (succ.get_schedule() == orig.get_schedule()) || + (succ.get_domain() == orig.get_domain())) begin + found = succ.m_find_successor(phase,stay_in_scope,orig); + if (found != null) begin + return found; + end + end + end + return null; +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::m_find_successor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null); + uvm_phase found; + //$display(" FIND SUCC node '",name,"' - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")"); + if (get_name() == name) + return this; + foreach (m_successors[succ]) begin + uvm_phase orig; + orig = (orig_phase==null) ? this : orig_phase; + if (!stay_in_scope || + (succ.get_schedule() == orig.get_schedule()) || + (succ.get_domain() == orig.get_domain())) begin + found = succ.m_find_successor_by_name(name,stay_in_scope,orig); + if (found != null) + return found; + end + end + return null; +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::find(uvm_phase phase, bit stay_in_scope=1); + // TBD full search + //$display({"\nFIND node '",phase.get_name(),"' within ",get_name()," (scope ",m_phase_type.name(),")", (stay_in_scope) ? " staying within scope" : ""}); + if (phase == m_imp || phase == this) + return phase; + find = m_find_predecessor(phase,stay_in_scope,this); + if (find == null) + find = m_find_successor(phase,stay_in_scope,this); +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::find_by_name(string name, bit stay_in_scope=1); + // TBD full search + //$display({"\nFIND node named '",name,"' within ",get_name()," (scope ",m_phase_type.name(),")", (stay_in_scope) ? " staying within scope" : ""}); + if (get_name() == name) + return this; + find_by_name = m_find_predecessor_by_name(name,stay_in_scope,this); + if (find_by_name == null) + find_by_name = m_find_successor_by_name(name,stay_in_scope,this); +endfunction + +// UVM 1:1 +function bit uvm_phase::is(uvm_phase phase); + return (m_imp == phase || this == phase); +endfunction + +// UVM 1:1 +function bit uvm_phase::is_before(uvm_phase phase); + //$display("this=%s is before phase=%s?",get_name(),phase.get_name()); + // TODO: add support for 'stay_in_scope=1' functionality + return (!is(phase) && m_find_successor(phase,0,this) != null); +endfunction + +// UVM 1:1 +function bit uvm_phase::is_after(uvm_phase phase); + //$display("this=%s is after phase=%s?",get_name(),phase.get_name()); + // TODO: add support for 'stay_in_scope=1' functionality + return (!is(phase) && m_find_predecessor(phase,0,this) != null); +endfunction + +// UVM 1:1 +function uvm_domain uvm_phase::get_domain(); + uvm_phase phase; + phase = this; + while (phase != null && phase.m_phase_type != UVM_PHASE_DOMAIN) + phase = phase.m_parent; + if (phase == null) // no parent domain + return null; + if(!$cast(get_domain,phase)) + `uvm_fatal("PH/INTERNAL", "get_domain: m_phase_type is DOMAIN but $cast to uvm_domain fails") +endfunction + +// UVM 1:1 +function uvm_phase uvm_phase::get_schedule(bit hier=0); + uvm_phase sched; + sched = this; + if (hier) + while (sched.m_parent != null && (sched.m_parent.get_phase_type() == UVM_PHASE_SCHEDULE)) + sched = sched.m_parent; + if (sched.m_phase_type == UVM_PHASE_SCHEDULE) + return sched; + if (sched.m_phase_type == UVM_PHASE_NODE) + if (m_parent != null && m_parent.m_phase_type != UVM_PHASE_DOMAIN) + return m_parent; + return null; +endfunction + +// UVM 1:1 +function void uvm_phase::end_prematurely() ; + m_premature_end = 1 ; +endfunction + +// UVM 1:1 +function void uvm_phase::jump(uvm_phase phase); + set_jump_phase(phase) ; + end_prematurely() ; +endfunction + +// UVM 1:1 +function void uvm_phase::set_jump_phase(uvm_phase phase) ; + uvm_phase d; + + if ((m_state < UVM_PHASE_STARTED) || + (m_state > UVM_PHASE_ENDED) ) + begin + `uvm_error("JMPPHIDL", { "Attempting to jump from phase \"", + get_name(), "\" which is not currently active (current state is ", + m_state.name(), "). The jump will not happen until the phase becomes ", + "active."}) + end + + + + // A jump can be either forward or backwards in the phase graph. + // If the specified phase (name) is found in the set of predecessors + // then we are jumping backwards. If, on the other hand, the phase is in the set + // of successors then we are jumping forwards. If neither, then we + // have an error. + // + // If the phase is non-existant and thus we don't know where to jump + // we have a situation where the only thing to do is to uvm_report_fatal + // and terminate_phase. By calling this function the intent was to + // jump to some other phase. So, continuing in the current phase doesn't + // make any sense. And we don't have a valid phase to jump to. So we're done. + + d = m_find_predecessor(phase,0); + if (d == null) begin + d = m_find_successor(phase,0); + if (d == null) begin + string msg; + $sformat(msg,{"phase %s is neither a predecessor or successor of ", + "phase %s or is non-existant, so we cannot jump to it. ", + "Phase control flow is now undefined so the simulation ", + "must terminate"}, phase.get_name(), get_name()); + `uvm_fatal("PH_BADJUMP", msg) + end + else begin + m_jump_fwd = 1; + `uvm_info("PH_JUMPF",$sformatf("jumping forward to phase %s", phase.get_name()), + UVM_DEBUG) + end + end + else begin + m_jump_bkwd = 1; + `uvm_info("PH_JUMPB",$sformatf("jumping backward to phase %s", phase.get_name()), + UVM_DEBUG) + end + + m_jump_phase = d; +endfunction + +// UVM 1:1 +function void uvm_phase::add(uvm_phase phase, + uvm_phase with_phase=null, + uvm_phase after_phase=null, + uvm_phase before_phase=null, + uvm_phase start_with_phase=null, + uvm_phase end_with_phase=null + ); + uvm_phase new_node, begin_node, end_node, tmp_node; + uvm_phase_state_change state_chg; + + if (phase == null) + `uvm_fatal("PH/NULL", "add: phase argument is null") + + if (with_phase != null && with_phase.get_phase_type() == UVM_PHASE_IMP) begin + string nm = with_phase.get_name(); + with_phase = find(with_phase); + if (with_phase == null) + `uvm_fatal("PH_BAD_ADD", + {"cannot find with_phase '",nm,"' within node '",get_name(),"'"}) + end + + if (before_phase != null && before_phase.get_phase_type() == UVM_PHASE_IMP) begin + string nm = before_phase.get_name(); + before_phase = find(before_phase); + if (before_phase == null) + `uvm_fatal("PH_BAD_ADD", + {"cannot find before_phase '",nm,"' within node '",get_name(),"'"}) + end + + if (after_phase != null && after_phase.get_phase_type() == UVM_PHASE_IMP) begin + string nm = after_phase.get_name(); + after_phase = find(after_phase); + if (after_phase == null) + `uvm_fatal("PH_BAD_ADD", + {"cannot find after_phase '",nm,"' within node '",get_name(),"'"}) + end + + if (start_with_phase != null && start_with_phase.get_phase_type() == UVM_PHASE_IMP) begin + string nm = start_with_phase.get_name(); + start_with_phase = find(start_with_phase); + if (start_with_phase == null) + `uvm_fatal("PH_BAD_ADD", + {"cannot find start_with_phase '",nm,"' within node '",get_name(),"'"}) + end + + if (end_with_phase != null && end_with_phase.get_phase_type() == UVM_PHASE_IMP) begin + string nm = end_with_phase.get_name(); + end_with_phase = find(end_with_phase); + if (end_with_phase == null) + `uvm_fatal("PH_BAD_ADD", + {"cannot find end_with_phase '",nm,"' within node '",get_name(),"'"}) + end + + if (((with_phase != null) + (after_phase != null) + (start_with_phase != null)) > 1) + `uvm_fatal("PH_BAD_ADD", + "only one of with_phase/after_phase/start_with_phase may be specified as they all specify predecessor") + + if (((with_phase != null) + (before_phase != null) + (end_with_phase != null)) > 1) + `uvm_fatal("PH_BAD_ADD", + "only one of with_phase/before_phase/end_with_phase may be specified as they all specify successor") + + if (before_phase == this || + after_phase == m_end_node || + with_phase == m_end_node || + start_with_phase == m_end_node || + end_with_phase == m_end_node) + `uvm_fatal("PH_BAD_ADD", + "cannot add before begin node, after end node, or with end nodes") + + if (before_phase != null && after_phase != null) begin + if (!after_phase.is_before(before_phase)) begin + `uvm_fatal("PH_BAD_ADD",{"Phase '",before_phase.get_name(), + "' is not before phase '",after_phase.get_name(),"'"}) + end + end + + if (before_phase != null && start_with_phase != null) begin + if (!start_with_phase.is_before(before_phase)) begin + `uvm_fatal("PH_BAD_ADD",{"Phase '",before_phase.get_name(), + "' is not before phase '",start_with_phase.get_name(),"'"}) + end + end + + if (end_with_phase != null && after_phase != null) begin + if (!after_phase.is_before(end_with_phase)) begin + `uvm_fatal("PH_BAD_ADD",{"Phase '",end_with_phase.get_name(), + "' is not before phase '",after_phase.get_name(),"'"}) + end + end + + // If we are inserting a new "leaf node" + if (phase.get_phase_type() == UVM_PHASE_IMP) begin +//UVM uvm_task_phase tp; + new_node = new(phase.get_name(),UVM_PHASE_NODE,this); + new_node.m_imp = phase; + begin_node = new_node; + end_node = new_node; + + end + // We are inserting an existing schedule + else begin + begin_node = phase; + end_node = phase.m_end_node; + phase.m_parent = this; + end + + // If 'with_phase' is us, then insert node in parallel + /* + if (with_phase == this) begin + after_phase = this; + before_phase = m_end_node; + end + */ + + // If no before/after/with specified, insert at end of this schedule + if (with_phase==null && after_phase==null && before_phase==null && + start_with_phase==null && end_with_phase==null) begin + before_phase = m_end_node; + end + + + if (m_phase_trace) begin + uvm_phase_type typ = phase.get_phase_type(); + `uvm_info("PH/TRC/ADD_PH", + {get_name()," (",m_phase_type.name(),") ADD_PHASE: phase=",phase.get_full_name()," (", + typ.name(),", inst_id=",$sformatf("%0d",phase.get_inst_id()),")", + " with_phase=", (with_phase == null) ? "null" : with_phase.get_name(), + " start_with_phase=", (start_with_phase == null) ? "null" : start_with_phase.get_name(), + " end_with_phase=", (end_with_phase == null) ? "null" : end_with_phase.get_name(), + " after_phase=", (after_phase == null) ? "null" : after_phase.get_name(), + " before_phase=", (before_phase == null) ? "null" : before_phase.get_name(), + " new_node=", (new_node == null) ? "null" : {new_node.get_name(), + " inst_id=", + $sformatf("%0d",new_node.get_inst_id())}, + " begin_node=", (begin_node == null) ? "null" : begin_node.get_name(), + " end_node=", (end_node == null) ? "null" : end_node.get_name()},UVM_DEBUG) + end + + + // + // INSERT IN PARALLEL WITH 'WITH' PHASE + if (with_phase != null) begin + // all pre-existing predecessors to with_phase are predecessors to the new phase + begin_node.m_predecessors = with_phase.m_predecessors; + foreach (with_phase.m_predecessors[pred]) pred.m_successors[begin_node] = 1; + // all pre-existing successors to with_phase are successors to this phase + end_node.m_successors = with_phase.m_successors; + foreach (with_phase.m_successors[succ]) succ.m_predecessors[end_node] = 1; + end + + if (start_with_phase != null) begin + // all pre-existing predecessors to start_with_phase are predecessors to the new phase + begin_node.m_predecessors = start_with_phase.m_predecessors; + foreach (start_with_phase.m_predecessors[pred]) begin + pred.m_successors[begin_node] = 1; + end + // if not otherwise specified, successors for the new phase are the successors to the end of this schedule + if (before_phase == null && end_with_phase == null) begin + end_node.m_successors = m_end_node.m_successors ; + foreach (m_end_node.m_successors[succ]) begin + succ.m_predecessors[end_node] = 1; + end + end + end + + if (end_with_phase != null) begin + // all pre-existing successors to end_with_phase are successors to the new phase + end_node.m_successors = end_with_phase.m_successors; + foreach (end_with_phase.m_successors[succ]) begin + succ.m_predecessors[end_node] = 1; + end + // if not otherwise specified, predecessors for the new phase are the predecessors to the start of this schedule + if (after_phase == null && start_with_phase == null) begin + begin_node.m_predecessors = this.m_predecessors ; + foreach (this.m_predecessors[pred]) begin + pred.m_successors[begin_node] = 1; + end + end + end + + // INSERT BEFORE PHASE + if (before_phase != null) begin + // unless predecessors to this phase are otherwise specified, + // pre-existing predecessors to before_phase move to be predecessors to the new phase + if (after_phase == null && start_with_phase == null) begin + foreach (before_phase.m_predecessors[pred]) begin + pred.m_successors.delete(before_phase); + pred.m_successors[begin_node] = 1; + end + begin_node.m_predecessors = before_phase.m_predecessors; + before_phase.m_predecessors.delete(); + end + // there is a special case if before and after used to be adjacent; + // the new phase goes in-between them + else if (before_phase.m_predecessors.exists(after_phase)) begin + before_phase.m_predecessors.delete(after_phase); + end + + // before_phase is now the sole successor of this phase + before_phase.m_predecessors[end_node] = 1; + end_node.m_successors.delete() ; + end_node.m_successors[before_phase] = 1; + + end + + + // INSERT AFTER PHASE + if (after_phase != null) begin + // unless successors to this phase are otherwise specified, + // pre-existing successors to after_phase are now successors to this phase + if (before_phase == null && end_with_phase == null) begin + foreach (after_phase.m_successors[succ]) begin + succ.m_predecessors.delete(after_phase); + succ.m_predecessors[end_node] = 1; + end + end_node.m_successors = after_phase.m_successors; + after_phase.m_successors.delete(); + end + // there is a special case if before and after used to be adjacent; + // the new phase goes in-between them + else if (after_phase.m_successors.exists(before_phase)) begin + after_phase.m_successors.delete(before_phase); + end + + // after_phase is the sole predecessor of this phase + after_phase.m_successors[begin_node] = 1; + begin_node.m_predecessors.delete(); + begin_node.m_predecessors[after_phase] = 1; + end + + + + // Transition nodes to DORMANT state + if (new_node == null) + tmp_node = phase; + else + tmp_node = new_node; + +//UVM `ifdef VERILATOR +//UVM state_chg = uvm_phase_state_change::type_id_create(tmp_node.get_name()); +//UVM `else + state_chg = uvm_phase_state_change::type_id::create(tmp_node.get_name()); +//UVM `endif + state_chg.m_phase = tmp_node; + state_chg.m_jump_to = null; + state_chg.m_prev_state = tmp_node.m_state; + tmp_node.m_state = UVM_PHASE_DORMANT; + `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(tmp_node, state_chg)) +endfunction diff --git a/test_regress/t/t_uvm/base/uvm_pool.svh b/test_regress/t/t_uvm/base/uvm_pool.svh new file mode 100644 index 00000000000..ec687c966e2 --- /dev/null +++ b/test_regress/t/t_uvm/base/uvm_pool.svh @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//------------------------------------------------------------------------------ +// Copyright 2007-2014 Mentor Graphics Corporation +// Copyright 2010-2014 Synopsys, Inc. +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2011 AMD +// Copyright 2014-2018 NVIDIA 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 -- NODOCS -- Pool Classes +// This section defines the class and derivative. + +//------------------------------------------------------------------------------ +// +// CLASS -- NODOCS -- uvm_pool #(KEY,T) +// +//------------------------------------------------------------------------------ +// Implements a class-based dynamic associative array. Allows sparse arrays to +// be allocated on demand, and passed and stored by reference. +//------------------------------------------------------------------------------ + +//UVM ~ +// @uvm-ieee 1800.2-2017 auto 11.2.1 +class uvm_pool #(type KEY=int, T=uvm_void) extends uvm_object; + + typedef uvm_pool #(KEY,T) this_type; + + static protected this_type m_global_pool; + protected T pool[KEY]; + +//UVM `uvm_object_param_utils(uvm_pool #(KEY,T)) +//UVM `uvm_type_name_decl("uvm_pool") + + // Function -- NODOCS -- new + // + // Creates a new pool with the given ~name~. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.1 + function new (string name=""); + super.new(name); + endfunction + + + // Function -- NODOCS -- get_global_pool + // + // Returns the singleton global pool for the item type, T. + // + // This allows items to be shared amongst components throughout the + // verification environment. + + static function this_type get_global_pool (); + if (m_global_pool==null) + m_global_pool = new("pool"); + return m_global_pool; + endfunction + + + // Function -- NODOCS -- get_global + // + // Returns the specified item instance from the global item pool. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.3 + static function T get_global (KEY key); + this_type gpool; + gpool = get_global_pool(); + return gpool.get(key); + endfunction + + + // Function -- NODOCS -- get + // + // Returns the item with the given ~key~. + // + // If no item exists by that key, a new item is created with that key + // and returned. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.4 + virtual function T get (KEY key); + if (!pool.exists(key)) begin + T default_value; + pool[key] = default_value; + end + return pool[key]; + endfunction + + + // Function -- NODOCS -- add + // + // Adds the given (~key~, ~item~) pair to the pool. If an item already + // exists at the given ~key~ it is overwritten with the new ~item~. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.5 + virtual function void add (KEY key, T item); + pool[key] = item; + endfunction + + + // Function -- NODOCS -- num + // + // Returns the number of uniquely keyed items stored in the pool. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.6 + virtual function int num (); + return pool.num(); + endfunction + + + // Function -- NODOCS -- delete + // + // Removes the item with the given ~key~ from the pool. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.7 + virtual function void delete (KEY key); + if (!exists(key)) begin + uvm_report_warning("POOLDEL", + $sformatf("delete: pool key doesn't exist. Ignoring delete request")); + return; + end + pool.delete(key); + endfunction + + + // Function -- NODOCS -- exists + // + // Returns 1 if an item with the given ~key~ exists in the pool, + // 0 otherwise. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.8 + virtual function int exists (KEY key); + return pool.exists(key); + endfunction + + + // Function -- NODOCS -- first + // + // Returns the key of the first item stored in the pool. + // + // If the pool is empty, then ~key~ is unchanged and 0 is returned. + // + // If the pool is not empty, then ~key~ is key of the first item + // and 1 is returned. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.9 + virtual function int first (ref KEY key); + return pool.first(key); + endfunction + + + // Function -- NODOCS -- last + // + // Returns the key of the last item stored in the pool. + // + // If the pool is empty, then 0 is returned and ~key~ is unchanged. + // + // If the pool is not empty, then ~key~ is set to the last key in + // the pool and 1 is returned. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.10 + virtual function int last (ref KEY key); + return pool.last(key); + endfunction + + + // Function -- NODOCS -- next + // + // Returns the key of the next item in the pool. + // + // If the input ~key~ is the last key in the pool, then ~key~ is + // left unchanged and 0 is returned. + // + // If a next key is found, then ~key~ is updated with that key + // and 1 is returned. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.11 + virtual function int next (ref KEY key); + return pool.next(key); + endfunction + + + // Function -- NODOCS -- prev + // + // Returns the key of the previous item in the pool. + // + // If the input ~key~ is the first key in the pool, then ~key~ is + // left unchanged and 0 is returned. + // + // If a previous key is found, then ~key~ is updated with that key + // and 1 is returned. + + // @uvm-ieee 1800.2-2017 auto 11.2.2.12 + virtual function int prev (ref KEY key); + return pool.prev(key); + endfunction + + virtual function void do_copy (uvm_object rhs); + this_type p; + KEY key; + super.do_copy(rhs); + if (rhs==null || !$cast(p, rhs)) + return; + pool = p.pool; + endfunction + +//UVM virtual function void do_print (uvm_printer printer); +//UVM string v; +//UVM int cnt; +//UVM string item; +//UVM KEY key; +//UVM printer.print_array_header("pool",pool.num(),"aa_object_string"); +//UVM if (pool.first(key)) +//UVM do begin +//UVM item.itoa(cnt); +//UVM item = {"[-key",item,"--]"}; +//UVM $swrite(v,pool[key]); +//UVM printer.print_generic(item,"",-1,v,"["); +//UVM end +//UVM while (pool.next(key)); +//UVM printer.print_array_footer(); +//UVM endfunction + +endclass + + +//------------------------------------------------------------------------------ +// +// CLASS -- NODOCS -- uvm_object_string_pool #(T) +// +//------------------------------------------------------------------------------ +// This provides a specialization of the generic class for +// an associative array of -based objects indexed by string. +// Specializations of this class include the ~uvm_event_pool~ (a +// uvm_object_string_pool storing ~uvm_event#(uvm_object)~) and +// ~uvm_barrier_pool~ (a uvm_obejct_string_pool storing ). +//------------------------------------------------------------------------------ + +// UVM ~ +class uvm_object_string_pool #(type T=uvm_object) extends uvm_pool #(string,T); + + typedef uvm_object_string_pool #(T) this_type; + static protected this_type m_global_pool; + +//UVM `uvm_object_param_utils(uvm_object_string_pool#(T)) +//UVM `uvm_type_name_decl("uvm_obj_str_pool") + + // Function -- NODOCS -- new + // + // Creates a new pool with the given ~name~. + + function new (string name=""); + super.new(name); + endfunction + + // Function -- NODOCS -- get_global_pool + // + // Returns the singleton global pool for the item type, T. + // + // This allows items to be shared amongst components throughout the + // verification environment. + + static function this_type get_global_pool (); + if (m_global_pool==null) + m_global_pool = new("global_pool"); + return m_global_pool; + endfunction + + + // Function -- NODOCS -- get_global + // + // Returns the specified item instance from the global item pool. + + static function T get_global (string key); + this_type gpool; + gpool = get_global_pool(); + return gpool.get(key); + endfunction + + + // Function -- NODOCS -- get + // + // Returns the object item at the given string ~key~. + // + // If no item exists by the given ~key~, a new item is created for that key + // and returned. + + virtual function T get (string key); + if (!pool.exists(key)) + pool[key] = new (key); + return pool[key]; + endfunction + + + // Function -- NODOCS -- delete + // + // Removes the item with the given string ~key~ from the pool. + + virtual function void delete (string key); + if (!exists(key)) begin + uvm_report_warning("POOLDEL", + $sformatf("delete: key '%s' doesn't exist", key)); + return; + end + pool.delete(key); + endfunction + + + // Function- do_print + +//UVM virtual function void do_print (uvm_printer printer); +//UVM string key; +//UVM printer.print_array_header("pool",pool.num(),"aa_object_string"); +//UVM if (pool.first(key)) +//UVM do +//UVM printer.print_object({"[",key,"]"}, pool[key],"["); +//UVM while (pool.next(key)); +//UVM printer.print_array_footer(); +//UVM endfunction + +endclass + + +typedef class uvm_barrier; +typedef class uvm_event; + +//UVM typedef uvm_object_string_pool #(uvm_barrier) uvm_barrier_pool /* @uvm-ieee 1800.2-2017 auto 10.4.2.1*/ ; +//UVM typedef uvm_object_string_pool #(uvm_event#(uvm_object)) uvm_event_pool /* @uvm-ieee 1800.2-2017 auto 10.4.1.1*/ ; diff --git a/test_regress/t/t_uvm/base/uvm_queue.svh b/test_regress/t/t_uvm/base/uvm_queue.svh index fff35d1778a..f88af82dc39 100644 --- a/test_regress/t/t_uvm/base/uvm_queue.svh +++ b/test_regress/t/t_uvm/base/uvm_queue.svh @@ -107,12 +107,9 @@ class uvm_queue #(type T=int) extends uvm_object; virtual function T get (int index); T default_value; if (index >= size() || index < 0) begin -//UVM uvm_report_warning("QUEUEGET", -//UVM $sformatf("get: given index out of range for queue of size %0d. Ignoring get request",size())); -//UVM return default_value; - $display("get: given index out of range for queue of size %0d. Ignoring get request",size()); + uvm_report_warning("QUEUEGET", + $sformatf("get: given index out of range for queue of size %0d. Ignoring get request",size())); return default_value; -//UVM end return queue[index]; endfunction @@ -135,10 +132,8 @@ class uvm_queue #(type T=int) extends uvm_object; // @uvm-ieee 1800.2-2017 auto 11.3.2.6 virtual function void insert (int index, T item); if (index >= size() || index < 0) begin -//UVM uvm_report_warning("QUEUEINS", -//UVM $sformatf("insert: given index out of range for queue of size %0d. Ignoring insert request",size())); - $display("insert: given index out of range for queue of size %0d. Ignoring insert request", size()); -//UVM + uvm_report_warning("QUEUEINS", + $sformatf("insert: given index out of range for queue of size %0d. Ignoring insert request",size())); return; end queue.insert(index,item); @@ -153,11 +148,9 @@ class uvm_queue #(type T=int) extends uvm_object; // @uvm-ieee 1800.2-2017 auto 11.3.2.7 virtual function void delete (int index=-1); if (index >= size() || index < -1) begin -//UVM uvm_report_warning("QUEUEDEL", -//UVM $sformatf("delete: given index out of range for queue of size %0d. Ignoring delete request",size())); -//UVM return; - $display("delete: given index out of range for queue of size %0d. Ignoring delete request",size()); -//UVM + uvm_report_warning("QUEUEDEL", + $sformatf("delete: given index out of range for queue of size %0d. Ignoring delete request",size())); + return; end if (index == -1) queue.delete(); diff --git a/test_regress/t/t_uvm/base/uvm_root.svh b/test_regress/t/t_uvm/base/uvm_root.svh index 991bb735404..b5c879525e8 100644 --- a/test_regress/t/t_uvm/base/uvm_root.svh +++ b/test_regress/t/t_uvm/base/uvm_root.svh @@ -62,7 +62,7 @@ function uvm_root::new(); end m_inst = this; `ifdef UVM_ENABLE_DEPRECATED_API - uvm_top = this; + uvm_top = this; `endif //UVM clp = uvm_cmdline_processor::get_inst(); diff --git a/test_regress/t/t_uvm/macros/uvm_callback_defines.svh b/test_regress/t/t_uvm/macros/uvm_callback_defines.svh new file mode 100644 index 00000000000..40bfebf97df --- /dev/null +++ b/test_regress/t/t_uvm/macros/uvm_callback_defines.svh @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//----------------------------------------------------------------------------- +// Copyright 2007-2012 Mentor Graphics Corporation +// Copyright 2010-2011 Synopsys, Inc. +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2015 NVIDIA 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. +//----------------------------------------------------------------------------- + +`ifndef UVM_CB_MACROS_SVH +`define UVM_CB_MACROS_SVH + + +//----------------------------------------------------------------------------- +// Title -- NODOCS -- Callback Macros +// +// These macros are used to register and execute callbacks extending +// from ~uvm_callbacks~. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_register_cb +// +//| `uvm_register_cb(T,CB) +// +// Registers the given ~CB~ callback type with the given ~T~ object type. If +// a type-callback pair is not registered then a warning is issued if an +// attempt is made to use the pair (add, delete, etc.). +// +// The registration will typically occur in the component that executes the +// given type of callback. For instance: +// +//| virtual class mycb extends uvm_callback; +//| virtual function void doit(); +//| endclass +//| +//| class my_comp extends uvm_component; +//| `uvm_register_cb(my_comp,mycb) +//| ... +//| task run_phase(uvm_phase phase); +//| ... +//| `uvm_do_callbacks(my_comp, mycb, doit()) +//| endtask +//| endclass +//----------------------------------------------------------------------------- + +// @uvm-ieee 1800.2-2017 auto B.4.1 +`define uvm_register_cb(T,CB) \ +///UVM static local bit m_register_cb_``CB = uvm_callbacks#(T,CB)::m_register_pair(`"T`",`"CB`"); \ + static local bit m_register_cb_``CB = uvm_callbacks#(T,CB)::m_register_pair(`"T`",`"CB`"); \ + static function void uvmt_drop_and_reregister_cb(); \ + uvm_callbacks#(T,CB)::uvmt_drop_globals(); \ + m_register_cb_``CB = uvm_callbacks#(T,CB)::m_register_pair(`"T`",`"CB`"); \ + endfunction +//UVM + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_set_super_type +// +//| `uvm_set_super_type(T,ST) +// +// Defines the super type of ~T~ to be ~ST~. This allows for derived class +// objects to inherit typewide callbacks that are registered with the base +// class. +// +// The registration will typically occur in the component that executes the +// given type of callback. For instance: +// +//| virtual class mycb extend uvm_callback; +//| virtual function void doit(); +//| endclass +//| +//| class my_comp extends uvm_component; +//| `uvm_register_cb(my_comp,mycb) +//| ... +//| task run_phase(uvm_phase phase); +//| ... +//| `uvm_do_callbacks(my_comp, mycb, doit()) +//| endtask +//| endclass +//| +//| class my_derived_comp extends my_comp; +//| `uvm_set_super_type(my_derived_comp,my_comp) +//| ... +//| task run_phase(uvm_phase phase); +//| ... +//| `uvm_do_callbacks(my_comp, mycb, doit()) +//| endtask +//| endclass +//----------------------------------------------------------------------------- + +// @uvm-ieee 1800.2-2017 auto B.4.2 +`define uvm_set_super_type(T,ST) \ + static local bit m_register_``T``ST = uvm_derived_callbacks#(T,ST)::register_super_type(`"T`",`"ST`"); + + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_do_callbacks +// +//| `uvm_do_callbacks(T,CB,METHOD) +// +// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with +// the calling object (i.e. ~this~ object), which is or is based on type ~T~. +// +// This macro executes all of the callbacks associated with the calling +// object (i.e. ~this~ object). The macro takes three arguments: +// +// - CB is the class type of the callback objects to execute. The class +// type must have a function signature that matches the METHOD argument. +// +// - T is the type associated with the callback. Typically, an instance +// of type T is passed as one the arguments in the ~METHOD~ call. +// +// - METHOD is the method call to invoke, with all required arguments as +// if they were invoked directly. +// +// For example, given the following callback class definition: +// +//| virtual class mycb extends uvm_cb; +//| pure function void my_function (mycomp comp, int addr, int data); +//| endclass +// +// A component would invoke the macro as +// +//| task mycomp::run_phase(uvm_phase phase); +//| int curr_addr, curr_data; +//| ... +//| `uvm_do_callbacks(mycb, mycomp, my_function(this, curr_addr, curr_data)) +//| ... +//| endtask +//----------------------------------------------------------------------------- + + +// @uvm-ieee 1800.2-2017 auto B.4.3 +`define uvm_do_callbacks(T,CB,METHOD) \ + `uvm_do_obj_callbacks(T,CB,this,METHOD) + + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_do_obj_callbacks +// +//| `uvm_do_obj_callbacks(T,CB,OBJ,METHOD) +// +// Calls the given ~METHOD~ of all callbacks based on type ~CB~ registered with +// the given object, ~OBJ~, which is or is based on type ~T~. +// +// This macro is identical to <`uvm_do_callbacks> macro, +// but it has an additional ~OBJ~ argument to allow the specification of an +// external object to associate the callback with. For example, if the +// callbacks are being applied in a sequence, ~OBJ~ could be specified +// as the associated sequencer or parent sequence. +// +//| ... +//| `uvm_do_callbacks(mycb, mycomp, seqr, my_function(seqr, curr_addr, curr_data)) +//| ... +//----------------------------------------------------------------------------- + +// @uvm-ieee 1800.2-2017 auto B.4.4 +`define uvm_do_obj_callbacks(T,CB,OBJ,METHOD) \ + begin \ + uvm_callback_iter#(T,CB) iter = new(OBJ); \ + CB cb = iter.first(); \ + while(cb != null) begin \ + `uvm_cb_trace_noobj(cb,$sformatf(`"Executing callback method 'METHOD' for callback %s (CB) from %s (T)`",cb.get_name(), OBJ.get_full_name())) \ + cb.METHOD; \ + cb = iter.next(); \ + end \ + end + + + + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_do_callbacks_exit_on +// +//| `uvm_do_callbacks_exit_on(T,CB,METHOD,VAL) +// +// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with +// the calling object (i.e. ~this~ object), which is or is based on type ~T~, +// returning upon the first callback returning the bit value given by ~VAL~. +// +// This macro executes all of the callbacks associated with the calling +// object (i.e. ~this~ object). The macro takes three arguments: +// +// - CB is the class type of the callback objects to execute. The class +// type must have a function signature that matches the METHOD argument. +// +// - T is the type associated with the callback. Typically, an instance +// of type T is passed as one the arguments in the ~METHOD~ call. +// +// - METHOD is the method call to invoke, with all required arguments as +// if they were invoked directly. +// +// - VAL, if 1, says return upon the first callback invocation that +// returns 1. If 0, says return upon the first callback invocation that +// returns 0. +// +// For example, given the following callback class definition: +// +//| virtual class mycb extends uvm_cb; +//| pure function bit drop_trans (mycomp comp, my_trans trans); +//| endclass +// +// A component would invoke the macro as +// +//| task mycomp::run_phase(uvm_phase phase); +//| my_trans trans; +//| forever begin +//| get_port.get(trans); +//| if(do_callbacks(trans) == 0) +//| uvm_report_info("DROPPED",{"trans dropped: %s",trans.convert2string()}); +//| else +//| // execute transaction +//| end +//| endtask +//| function bit do_callbacks(my_trans); +//| // Returns 0 if drop happens and 1 otherwise +//| `uvm_do_callbacks_exit_on(mycomp, mycb, extobj, drop_trans(this,trans), 1) +//| endfunction +// +// Because this macro calls ~return~, its use is restricted to implementations +// of functions that return a ~bit~ value, as in the above example. +// +//----------------------------------------------------------------------------- + + +// @uvm-ieee 1800.2-2017 auto B.4.5 +`define uvm_do_callbacks_exit_on(T,CB,METHOD,VAL) \ + `uvm_do_obj_callbacks_exit_on(T,CB,this,METHOD,VAL) \ + + +//----------------------------------------------------------------------------- +// MACRO -- NODOCS -- `uvm_do_obj_callbacks_exit_on +// +//| `uvm_do_obj_callbacks_exit_on(T,CB,OBJ,METHOD,VAL) +// +// Calls the given ~METHOD~ of all callbacks of type ~CB~ registered with +// the given object ~OBJ~, which must be or be based on type ~T~, and returns +// upon the first callback that returns the bit value given by ~VAL~. It is +// exactly the same as the <`uvm_do_callbacks_exit_on> but has a specific +// object instance (instead of the implicit this instance) as the third +// argument. +// +//| ... +//| // Exit if a callback returns a 1 +//| `uvm_do_callbacks_exit_on(mycomp, mycb, seqr, drop_trans(seqr,trans), 1) +//| ... +// +// Because this macro calls ~return~, its use is restricted to implementations +// of functions that return a ~bit~ value, as in the above example. +//----------------------------------------------------------------------------- + +// @uvm-ieee 1800.2-2017 auto B.4.6 +`define uvm_do_obj_callbacks_exit_on(T,CB,OBJ,METHOD,VAL) \ + begin \ + uvm_callback_iter#(T,CB) iter = new(OBJ); \ + CB cb = iter.first(); \ + while(cb != null) begin \ + if (cb.METHOD == VAL) begin \ + `uvm_cb_trace_noobj(cb,$sformatf(`"Executed callback method 'METHOD' for callback %s (CB) from %s (T) : returned value VAL (other callbacks will be ignored)`",cb.get_name(), OBJ.get_full_name())) \ + return VAL; \ + end \ + `uvm_cb_trace_noobj(cb,$sformatf(`"Executed callback method 'METHOD' for callback %s (CB) from %s (T) : did not return value VAL`",cb.get_name(), OBJ.get_full_name())) \ + cb = iter.next(); \ + end \ + return 1-VAL; \ + end + + +// The +define+UVM_CB_TRACE_ON setting will instrument the uvm library to emit +// messages with message id UVMCB_TRC and UVM_NONE verbosity +// notifing add,delete and execution of uvm callbacks. The instrumentation is off by default. + +`ifdef UVM_CB_TRACE_ON + +`define uvm_cb_trace(OBJ,CB,OPER) \ + begin \ + string msg; \ + msg = (OBJ == null) ? "null" : $sformatf("%s (%s@%0d)", \ + OBJ.get_full_name(), OBJ.get_type_name(), OBJ.get_inst_id()); \ + `uvm_info("UVMCB_TRC", $sformatf("%s: callback %s (%s@%0d) : to object %s", \ + OPER, CB.get_name(), CB.get_type_name(), CB.get_inst_id(), msg), UVM_NONE) \ + end + +`define uvm_cb_trace_noobj(CB,OPER) \ + begin \ + if(uvm_callbacks_base::m_tracing) \ + `uvm_info("UVMCB_TRC", $sformatf("%s : callback %s (%s@%0d)" , \ + OPER, CB.get_name(), CB.get_type_name(), CB.get_inst_id()), UVM_NONE) \ + end +`else + +`define uvm_cb_trace_noobj(CB,OPER) /* null */ +`define uvm_cb_trace(OBJ,CB,OPER) /* null */ + +`endif + + +`endif diff --git a/test_regress/t/t_uvm/macros/uvm_object_defines.svh b/test_regress/t/t_uvm/macros/uvm_object_defines.svh new file mode 100644 index 00000000000..c3246343220 --- /dev/null +++ b/test_regress/t/t_uvm/macros/uvm_object_defines.svh @@ -0,0 +1,2598 @@ +// SPDX-License-Identifier: Apache-2.0 +// +//------------------------------------------------------------------------------ +// Copyright 2012 Aldec +// Copyright 2007-2012 Mentor Graphics Corporation +// Copyright 2018 Qualcomm, Inc. +// Copyright 2014 Intel Corporation +// Copyright 2010-2013 Synopsys, Inc. +// Copyright 2007-2018 Cadence Design Systems, Inc. +// Copyright 2012 AMD +// Copyright 2012-2018 NVIDIA Corporation +// Copyright 2012-2018 Cisco Systems, Inc. +// Copyright 2012 Accellera Systems Initiative +// 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. +//------------------------------------------------------------------------------ + +`ifndef UVM_OBJECT_DEFINES_SVH +`define UVM_OBJECT_DEFINES_SVH + +`ifdef UVM_EMPTY_MACROS + +`define uvm_field_utils_begin(T) +`define uvm_field_utils_end +`define uvm_object_utils(T) +`define uvm_object_param_utils(T) +`define uvm_object_utils_begin(T) +`define uvm_object_param_utils_begin(T) +`define uvm_object_abstract_utils(T) +`define uvm_object_abstract_param_utils(T) +`define uvm_object_abstract_utils_begin(T) +`define uvm_object_abstract_param_utils_begin(T) +`define uvm_object_abstract_utils_end +`define uvm_component_utils(T) +`define uvm_component_param_utils(T) +`define uvm_component_utils_begin(T) +`define uvm_component_param_utils_begin(T) +`define uvm_component_abstract_utils(T) +`define uvm_component_abstract_param_utils(T) +`define uvm_component_abstract_utils_begin(T) +`define uvm_component_abstract_param_utils_begin(T) +`define uvm_component_utils_end +`define uvm_field_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_real(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_enum(T,ARG,FLAG=UVM_DEFAULT) +`define uvm_field_object(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_event(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_array_enum(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_array_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_sarray_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_sarray_enum(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_array_object(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_sarray_object(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_array_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_sarray_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_queue_enum(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_queue_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_queue_object(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_queue_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_string_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_object_string(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_int_unsigned(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_integer(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_integer_unsigned(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_byte(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_byte_unsigned(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_shortint(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_shortint_unsigned(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_longint(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_longint_unsigned(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_int_key(KEY, ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_string_int(ARG,FLAG=UVM_DEFAULT) +`define uvm_field_aa_object_int(ARG,FLAG=UVM_DEFAULT) + +`else + +//------------------------------------------------------------------------------ +// +// Title -- NODOCS -- Utility and Field Macros for Components and Objects +// +// Group -- NODOCS -- Utility Macros +// +// The ~utils~ macros define the infrastructure needed to enable the +// object/component for correct factory operation. See <`uvm_object_utils> and +// <`uvm_component_utils> for details. +// +// A ~utils~ macro should be used inside ~every~ user-defined class that extends +// directly or indirectly, including and +// . +// +// Below is an example usage of the ~utils~ macro for a user-defined object. +// +//| class mydata extends uvm_object; +//| +//| `uvm_object_utils(mydata) +//| +//| // declare data properties +//| +//| function new(string name="mydata_inst"); +//| super.new(name); +//| endfunction +//| +//| endclass +// +// Below is an example usage of a ~utils~ macro for a user-defined component. +// +//| class my_comp extends uvm_component; +//| +//| `uvm_component_utils(my_comp) +//| +//| // declare data properties +//| +//| function new(string name, uvm_component parent=null); +//| super.new(name,parent); +//| endfunction +//| +//| endclass +// +//------------------------------------------------------------------------------ + + +// Define - UVM_FIELD_FLAG_SIZE +// +// The macro defines the number of bits in uvm_field_flag_t. It may be defined by the user but it +// must be at least as large as parameter UVM_FIELD_FLAG_RESERVED_BITS. +// +`ifndef UVM_FIELD_FLAG_SIZE + // @uvm-ieee 1800.2-2017 auto B.6.1 + `define UVM_FIELD_FLAG_SIZE UVM_FIELD_FLAG_RESERVED_BITS +`endif + + +// Definitions for the user to use inside their derived data class declarations. + +// MACRO -- NODOCS -- `uvm_field_utils_begin + +// MACRO -- NODOCS -- `uvm_field_utils_end +// +// These macros form a block in which `uvm_field_* macros can be placed. +// Used as +// +//| `uvm_field_utils_begin(TYPE) +//| `uvm_field_* macros here +//| `uvm_field_utils_end +// +// +// These macros do ~not~ perform factory registration nor implement the +// ~get_type_name~ and ~create~ methods. Use this form when you need custom +// implementations of these two methods, or when you are setting up field macros +// for an abstract class (i.e. virtual class). + +// Implementation Note: The `uvm_field_utils_begin macro creates a new local +// function "__m_uvm_execute_field_op", which has a similar signature to +// , but the arguments are named differently so as to prevent +// potential collisions with field names. For example, if the user had a +// field named "op", then that could collide with the "op" argument of the +// method. + +// @uvm-ieee 1800.2-2017 auto B.2.1.1 +`define uvm_field_utils_begin(T) \ +function void do_execute_op( uvm_field_op op ); \ + super.do_execute_op(op); \ + __m_uvm_execute_field_op(op); \ +endfunction : do_execute_op \ +local function void __m_uvm_execute_field_op( uvm_field_op __local_op__ ); \ + uvm_field_flag_t local_op_type__; /* Used to avoid re-querying */ \ + T local_rhs__; /* Used for $casting copy and compare */ \ + uvm_resource_base local_rsrc__; /* Used for UVM_SET ops */ \ + string local_rsrc_name__; \ + uvm_object local_obj__; /* Used when trying to read uvm_object resources */ \ + bit local_success__; /* Used when trying to read resources */ \ + typedef T __local_type__; /* Used for referring to type T in field macros */ \ + int local_size__; /* Used when unpacking size values */ \ + /* All possible policy classes */ \ + /* Using the same name as the do_* methods, allows macro reuse */ \ + uvm_printer __local_printer__; \ + uvm_comparer __local_comparer__; \ + uvm_recorder __local_recorder__; \ + uvm_packer __local_packer__; \ + uvm_copier __local_copier__; \ + void'($cast(local_rhs__, __local_op__.get_rhs())); \ + if (($cast(local_rsrc__, __local_op__.get_rhs())) && \ + (local_rsrc__ != null)) \ + local_rsrc_name__ = local_rsrc__.get_name(); \ + local_op_type__ = __local_op__.get_op_type(); \ + case (local_op_type__) \ + UVM_PRINT: begin \ + $cast(__local_printer__, __local_op__.get_policy()); \ + end \ + UVM_COMPARE: begin \ + if (local_rhs__ == null) return; \ + $cast(__local_comparer__, __local_op__.get_policy()); \ + end \ + UVM_RECORD: begin \ + $cast(__local_recorder__, __local_op__.get_policy()); \ + end \ + UVM_PACK, UVM_UNPACK: begin \ + $cast(__local_packer__, __local_op__.get_policy()); \ + end \ + UVM_COPY: begin \ + if (local_rhs__ == null) return; \ + $cast(__local_copier__, __local_op__.get_policy()); \ + end \ + UVM_SET: begin \ + if (local_rsrc__ == null) return; \ + end \ + default: \ + return; /* unknown op, just return */ \ + endcase \ + +// @uvm-ieee 1800.2-2017 auto B.2.1.1 +`define uvm_field_utils_end \ +endfunction : __m_uvm_execute_field_op + + +// MACRO -- NODOCS -- `uvm_object_utils + +// MACRO -- NODOCS -- `uvm_object_param_utils + +// MACRO -- NODOCS -- `uvm_object_utils_begin + +// MACRO -- NODOCS -- `uvm_object_param_utils_begin + +// MACRO -- NODOCS -- `uvm_object_utils_end +// +// -based class declarations may contain one of the above forms of +// utility macros. +// +// For simple objects with no field macros, use +// +//| `uvm_object_utils(TYPE) +// +// For simple objects with field macros, use +// +//| `uvm_object_utils_begin(TYPE) +//| `uvm_field_* macro invocations here +//| `uvm_object_utils_end +// +// For parameterized objects with no field macros, use +// +//| `uvm_object_param_utils(TYPE) +// +// For parameterized objects, with field macros, use +// +//| `uvm_object_param_utils_begin(TYPE) +//| `uvm_field_* macro invocations here +//| `uvm_object_utils_end +// +// Simple (non-parameterized) objects use the uvm_object_utils* versions, which +// do the following: +// +// o Implements get_type_name, which returns TYPE as a string +// +// o Implements create, which allocates an object of type TYPE by calling its +// constructor with no arguments. TYPE's constructor, if defined, must have +// default values on all it arguments. +// +// o Registers the TYPE with the factory, using the string TYPE as the factory +// lookup string for the type. +// +// o Implements the static get_type() method which returns a factory +// proxy object for the type. +// +// o Implements the virtual get_object_type() method which works just like the +// static get_type() method, but operates on an already allocated object. +// +// Parameterized classes must use the uvm_object_param_utils* versions. They +// differ from <`uvm_object_utils> only in that they do not supply a type name +// when registering the object with the factory. As such, name-based lookup with +// the factory for parameterized classes is not possible. +// +// The macros with _begin suffixes are the same as the non-suffixed versions +// except that they also start a block in which `uvm_field_* macros can be +// placed. The block must be terminated by `uvm_object_utils_end. +// + +// @uvm-ieee 1800.2-2017 auto 14.4.2 +// @uvm-ieee 1800.2-2017 auto B.2.1 +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_utils(T) \ +//UVM `m_uvm_object_registry_internal(T,T) \ + `m_uvm_object_create_func(T) \ + `uvm_type_name_decl(`"T`") + +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_param_utils(T) \ + `m_uvm_object_registry_param(T) \ + `m_uvm_object_create_func(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_utils_begin(T) \ + `uvm_object_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_param_utils_begin(T) \ + `uvm_object_param_utils(T) \ + `uvm_field_utils_begin(T) + +`define uvm_object_abstract_utils(T) \ + `m_uvm_object_abstract_registry_internal(T,T) \ + `uvm_type_name_decl(`"T`") + +`define uvm_object_abstract_param_utils(T) \ + `m_uvm_object_abstract_registry_param(T) + +`define uvm_object_abstract_utils_begin(T) \ + `uvm_object_abstract_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_abstract_param_utils_begin(T) \ + `uvm_object_abstract_param_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.2 +`define uvm_object_utils_end \ + `uvm_field_utils_end + +// MACRO -- NODOCS -- `uvm_component_utils + +// MACRO -- NODOCS -- `uvm_component_param_utils + +// MACRO -- NODOCS -- `uvm_component_utils_begin + +// MACRO -- NODOCS -- `uvm_component_param_utils_begin + +// MACRO -- NODOCS -- `uvm_component_end +// +// uvm_component-based class declarations may contain one of the above forms of +// utility macros. +// +// For simple components with no field macros, use +// +//| `uvm_component_utils(TYPE) +// +// For simple components with field macros, use +// +//| `uvm_component_utils_begin(TYPE) +//| `uvm_field_* macro invocations here +//| `uvm_component_utils_end +// +// For parameterized components with no field macros, use +// +//| `uvm_component_param_utils(TYPE) +// +// For parameterized components with field macros, use +// +//| `uvm_component_param_utils_begin(TYPE) +//| `uvm_field_* macro invocations here +//| `uvm_component_utils_end +// +// Simple (non-parameterized) components must use the uvm_components_utils* +// versions, which do the following: +// +// o Implements get_type_name, which returns TYPE as a string. +// +// o Implements create, which allocates a component of type TYPE using a two +// argument constructor. TYPE's constructor must have a name and a parent +// argument. +// +// o Registers the TYPE with the factory, using the string TYPE as the factory +// lookup string for the type. +// +// o Implements the static get_type() method which returns a factory +// proxy object for the type. +// +// o Implements the virtual get_object_type() method which works just like the +// static get_type() method, but operates on an already allocated object. +// +// Parameterized classes must use the uvm_object_param_utils* versions. They +// differ from `uvm_object_utils only in that they do not supply a type name +// when registering the object with the factory. As such, name-based lookup with +// the factory for parameterized classes is not possible. +// +// The macros with _begin suffixes are the same as the non-suffixed versions +// except that they also start a block in which `uvm_field_* macros can be +// placed. The block must be terminated by `uvm_component_utils_end. +// + +// @uvm-ieee 1800.2-2017 auto B.2.1 +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_utils(T) \ + `m_uvm_component_registry_internal(T,T) \ + `uvm_type_name_decl(`"T`") \ + +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_param_utils(T) \ + `m_uvm_component_registry_param(T) \ + + +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_utils_begin(T) \ + `uvm_component_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_param_utils_begin(T) \ + `uvm_component_param_utils(T) \ + `uvm_field_utils_begin(T) + +`define uvm_component_abstract_utils(T) \ + `m_uvm_component_abstract_registry_internal(T,T) \ + `uvm_type_name_decl(`"T`") \ + +`define uvm_component_abstract_param_utils(T) \ + `m_uvm_component_abstract_registry_param(T) \ + + +`define uvm_component_abstract_utils_begin(T) \ + `uvm_component_abstract_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_abstract_param_utils_begin(T) \ + `uvm_component_abstract_param_utils(T) \ + `uvm_field_utils_begin(T) + +// @uvm-ieee 1800.2-2017 auto B.2.1.3 +`define uvm_component_utils_end \ + `uvm_field_utils_end + + +// MACRO -- NODOCS -- `uvm_object_registry +// +// Register a uvm_object-based class with the factory +// +//| `uvm_object_registry(T,S) +// +// Registers a uvm_object-based class ~T~ and lookup +// string ~S~ with the factory. ~S~ typically is the +// name of the class in quotes. The <`uvm_object_utils> +// family of macros uses this macro. + +// @uvm-ieee 1800.2-2017 auto B.2.1.4 + +`ifdef VERILATOR +`define uvm_object_registry(T,S) \ + typedef uvm_object_registry#(T,S) type_id; \ + static function T type_id_create (string name="", \ + uvm_component parent=null, \ + string contxt=""); \ + return type_id::create(name, parent, contxt); \ + endfunction \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`else +`define uvm_object_registry(T,S) \ + typedef uvm_object_registry#(T,S) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`endif + +// MACRO -- NODOCS -- `uvm_component_registry +// +// Registers a uvm_component-based class with the factory +// +//| `uvm_component_registry(T,S) +// +// Registers a uvm_component-based class ~T~ and lookup +// string ~S~ with the factory. ~S~ typically is the +// name of the class in quotes. The <`uvm_object_utils> +// family of macros uses this macro. + +// @uvm-ieee 1800.2-2017 auto B.2.1.5 +`ifdef VERILATOR +`define uvm_component_registry(T,S) \ + typedef uvm_component_registry #(T,S) type_id; \ + static function T type_id_create (string name="", \ + uvm_component parent=null, \ + string contxt=""); \ + return type_id::create(name, parent, contxt); \ + endfunction \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`else +`define uvm_component_registry(T,S) \ + typedef uvm_component_registry #(T,S) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`endif + +`define uvm_declare_type_alias(TYPE,NAME,SFX=) \ + static bit m__alias_declared``SFX = TYPE::type_id::set_type_alias(NAME); + + +// uvm_new_func +// ------------ + +`define uvm_new_func \ + function new (string name, uvm_component parent); \ + super.new(name, parent); \ + endfunction + + +//----------------------------------------------------------------------------- +// INTERNAL MACROS - in support of *_utils macros -- do not use directly +//----------------------------------------------------------------------------- + +// m_uvm_object_create_func +// ------------------------ + +`define m_uvm_object_create_func(T) \ + function uvm_object create (string name=""); \ + T tmp; \ + if (name=="") tmp = new(); \ + else tmp = new(name); \ + return tmp; \ + endfunction + +// Macro --NODOCS-- uvm_type_name_decl(TNAME_STRING) +// Potentially public macro for Mantis 5003. +// +// This macro creates a statically accessible +// ~type_name~, and implements the virtual +// method. +// +// *Note:* When running with <`UVM_ENABLE_DEPRECATED_API>, +// the ~type_name~ member is declared as: +//| const static string type_name = TNAME_STRING; +// This is unsafe, as static initialization can cause races +// to occur. When running without <`UVM_ENABLE_DEPRECATED_API>, +// the implementation is an static initialization safe function: +//| static function string type_name(); +//| return TNAME_STRING; +//| endfunction : type_name +// +`ifdef UVM_ENABLE_DEPRECATED_API + `define uvm_type_name_decl(TNAME_STRING) \ + const static string type_name = TNAME_STRING; \ + virtual function string get_type_name(); \ + return TNAME_STRING; \ + endfunction : get_type_name +`else + `define uvm_type_name_decl(TNAME_STRING) \ + static function string type_name(); \ + return TNAME_STRING; \ + endfunction : type_name \ + virtual function string get_type_name(); \ + return TNAME_STRING; \ + endfunction : get_type_name +`endif // !`ifdef UVM_ENABLE_DEPRECATED_API + + +// m_uvm_object_registry_internal +// ------------------------------ + +//This is needed due to an issue in of passing down strings +//created by args to lower level macros. +`ifdef VERILATOR +`define m_uvm_object_registry_internal(T,S) \ + typedef uvm_object_registry#(T,`"S`") type_id; \ + static function T type_id_create (string name="", \ + uvm_component parent=null, \ + string contxt=""); \ + return type_id::create(name, parent, contxt); \ + endfunction \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`else +`define m_uvm_object_registry_internal(T,S) \ + typedef uvm_object_registry#(T,`"S`") type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`endif + +// m_uvm_object_registry_param +// --------------------------- + +`ifdef VERILATOR +`define m_uvm_object_registry_param(T) \ + typedef uvm_object_registry #(T) type_id; \ + static function T type_id_create (string name="", \ + uvm_component parent=null, \ + string contxt=""); \ + return type_id::create(name, parent, contxt); \ + endfunction \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`else +`define m_uvm_object_registry_param(T) \ + typedef uvm_object_registry #(T) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction +`endif + +// m_uvm_object_abstract_registry_internal +// --------------------------------------- + +//This is needed due to an issue in of passing down strings +//created by args to lower level macros. +`define m_uvm_object_abstract_registry_internal(T,S) \ + typedef uvm_abstract_object_registry#(T,`"S`") type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + + +// m_uvm_object_abstract_registry_param +// ------------------------------------ + +`define m_uvm_object_abstract_registry_param(T) \ + typedef uvm_abstract_object_registry #(T) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + + +// m_uvm_component_registry_internal +// --------------------------------- + +//This is needed due to an issue in of passing down strings +//created by args to lower level macros. +`define m_uvm_component_registry_internal(T,S) \ + typedef uvm_component_registry #(T,`"S`") type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + +// versions of the uvm_component_registry macros to be used with +// parameterized classes + +// m_uvm_component_registry_param +// ------------------------------ + +`define m_uvm_component_registry_param(T) \ + typedef uvm_component_registry #(T) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + +// m_uvm_component_abstract_registry_internal +// ------------------------------------------ + +//This is needed due to an issue in of passing down strings +//created by args to lower level macros. +`define m_uvm_component_abstract_registry_internal(T,S) \ + typedef uvm_abstract_component_registry #(T,`"S`") type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + +// versions of the uvm_component_abstract_registry macros to be used with +// parameterized classes + +// m_uvm_component_abstract_registry_param +// --------------------------------------- + +`define m_uvm_component_abstract_registry_param(T) \ + typedef uvm_abstract_component_registry #(T) type_id; \ + static function type_id get_type(); \ + return type_id::get(); \ + endfunction \ + virtual function uvm_object_wrapper get_object_type(); \ + return type_id::get(); \ + endfunction + + + +//------------------------------------------------------------------------------ +// +// Group -- NODOCS -- Field Macros +// +// The `uvm_field_* macros are invoked inside of the `uvm_*_utils_begin and +// `uvm_*_utils_end macro blocks to form "automatic" implementations of the +// core data methods: copy, compare, pack, unpack, record, print, and sprint. +// +// By using the macros, you do not have to implement any of the do_* methods +// inherited from . However, be aware that the field macros expand +// into general inline code that is not as run-time efficient nor as flexible +// as direct implementations of the do_* methods. +// +// Below is an example usage of the field macros for a sequence item. +// +//| class my_trans extends uvm_sequence_item; +//| +//| cmd_t cmd; +//| int addr; +//| int data[$]; +//| my_ext ext; +//| string str; +//| +//| `uvm_object_utils_begin(my_trans) +//| `uvm_field_enum (cmd_t, cmd, UVM_ALL_ON) +//| `uvm_field_int (addr, UVM_ALL_ON) +//| `uvm_field_queue_int(data, UVM_ALL_ON) +//| `uvm_field_object (ext, UVM_ALL_ON) +//| `uvm_field_string (str, UVM_ALL_ON) +//| `uvm_object_utils_end +//| +//| function new(string name="mydata_inst"); +//| super.new(name); +//| endfunction +//| +//| endclass +// +// Below is an example usage of the field macros for a component. +// +//| class my_comp extends uvm_component; +//| +//| my_comp_cfg cfg; +//| +//| `uvm_component_utils_begin(my_comp) +//| `uvm_field_object (cfg, UVM_ALL_ON) +//| `uvm_object_utils_end +//| +//| function new(string name="my_comp_inst", uvm_component parent=null); +//| super.new(name); +//| endfunction +//| +//| endclass +// +// Each `uvm_field_* macro is named according to the particular data type it +// handles: integrals, strings, objects, queues, etc., and each has at least two +// arguments: ~ARG~ and ~FLAG~. +// +// ARG - is the instance name of the variable, whose type must be compatible with +// the macro being invoked. In the example, class variable ~addr~ is an integral type, +// so we use the ~`uvm_field_int~ macro. +// +// FLAG - if set to ~UVM_ALL_ON~, as in the example, the ARG variable will be +// included in all data methods. If FLAG is set to something other than +// ~UVM_ALL_ON~ or ~UVM_DEFAULT~, it specifies which data method implementations will +// ~not~ include the given variable. Thus, if ~FLAG~ is specified as ~NO_COMPARE~, +// the ARG variable will not affect comparison operations, but it will be +// included in everything else. +// +// All possible values for ~FLAG~ are listed and described below. Multiple flag +// values can be bitwise OR'ed together (in most cases they may be added together +// as well, but care must be taken when using the + operator to ensure that the +// same bit is not added more than once). +// +// UVM_ALL_ON - Set all operations on. +// UVM_DEFAULT - This is the recommended set of flags to pass +// to the field macros. Currently, it enables +// all of the operations, making it functionally +// identical to ~UVM_ALL_ON~. In the future +// however, additional flags could be added with +// a recommended default value of ~off~. +// +// UVM_NOCOPY - Do not copy this field. +// UVM_NOCOMPARE - Do not compare this field. +// UVM_NOPRINT - Do not print this field. +// UVM_NOPACK - Do not pack or unpack this field. +// +// UVM_REFERENCE - For object types, operate only on the handle (e.g. no deep copy) +// +// UVM_PHYSICAL - Treat as a physical field. Use physical setting in +// policy class for this field. +// UVM_ABSTRACT - Treat as an abstract field. Use the abstract setting +// in the policy class for this field. +// UVM_READONLY - Do not allow setting of this field from the set_*_local +// methods or during operation. +// +// +// A radix for printing and recording can be specified by OR'ing one of the +// following constants in the ~FLAG~ argument +// +// UVM_BIN - Print / record the field in binary (base-2). +// UVM_DEC - Print / record the field in decimal (base-10). +// UVM_UNSIGNED - Print / record the field in unsigned decimal (base-10). +// UVM_OCT - Print / record the field in octal (base-8). +// UVM_HEX - Print / record the field in hexadecimal (base-16). +// UVM_STRING - Print / record the field in string format. +// UVM_TIME - Print / record the field in time format. +// +// Radix settings for integral types. Hex is the default radix if none is +// specified. +// +// A UVM component should ~not~ be specified using the `uvm_field_object macro +// unless its flag includes UVM_REFERENCE. Otherwise, the field macro will +// implement deep copy, which is an illegal operation for uvm_components. +// You will get a FATAL error if you tried to copy or clone an object containing +// a component handle that was registered with a field macro without the +// UVM_REFERENCE flag. You will also get duplicate entries when printing +// component topology, as this functionality is already provided by UVM. +//------------------------------------------------------------------------------ + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_* macros +// +// Macros that implement data operations for scalar properties. +// +//----------------------------------------------------------------------------- + +// The m_uvm_* macros are implementation artifacts. They are not intended to be +// directly used by the user. + +`define m_uvm_field_radix(FLAG) uvm_radix_enum'((FLAG)&(UVM_RADIX)) + +`define m_uvm_field_recursion(FLAG) uvm_recursion_policy_enum'((FLAG)&(UVM_RECURSION)) + +`define m_uvm_field_begin(ARG, FLAG) \ + begin \ + case (local_op_type__) + +`define m_uvm_field_end(ARG) \ + endcase \ + end + + +`define m_uvm_field_op_begin(OP, FLAG) \ +UVM_``OP: \ + if (!((FLAG)&UVM_NO``OP)) begin + +`define m_uvm_field_op_end(OP) \ + end + +// MACRO -- NODOCS -- `uvm_field_int +// +// Implements the data operations for any packed integral property. +// +//| `uvm_field_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is an integral property of the class, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.1 +`define uvm_field_int(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_int(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_int(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_int(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_int(`"ARG`", \ + ARG, \ + $bits(ARG), \ + `m_uvm_field_radix(FLAG), \ + __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_int(ARG, $bits(ARG), `m_uvm_field_radix(FLAG),,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + ARG, \ + this) \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_object +// +// Implements the data operations for a -based property. +// +//| `uvm_field_object(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is an object property of the class, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.2 +`define uvm_field_object(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + `uvm_copy_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_copier__) \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_pack_object(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_unpack_object(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + __local_recorder__.record_object(`"ARG`", ARG); \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_object(ARG, `m_uvm_field_recursion(FLAG),__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + uvm_object, \ + local_obj__, \ + this) \ + if (local_success__) begin \ + if (local_obj__ == null) begin \ + ARG = null; \ + end else if (!$cast(ARG, local_obj__)) begin \ + `uvm_warning("UVM/FIELDS/OBJ_TYPE", $sformatf("Can't set field '%s' on '%s' with '%s' type", \ + `"ARG`", \ + this.get_full_name(), \ + local_obj__.get_type_name())) \ + end \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_string +// +// Implements the data operations for a string property. +// +//| `uvm_field_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a string property of the class, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.3 +`define uvm_field_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_string(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_string(`"ARG`", ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + __local_printer__.print_string(`"ARG`", ARG); \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + string, \ + ARG, \ + this) \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_enum +// +// Implements the data operations for an enumerated property. +// +//| `uvm_field_enum(T,ARG,FLAG=UVM_DEFAULT) +// +// ~T~ is an enumerated _type_, ~ARG~ is an instance of that type, and +// ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.4 +`define uvm_field_enum(T,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_enum(ARG, local_rhs__.ARG, T, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_enum(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_enum(ARG, T, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_enum(`"ARG`", ARG, T, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + if (`m_uvm_field_radix(FLAG) inside {UVM_NORADIX, UVM_ENUM, UVM_STRING}) \ + `uvm_print_enum(T, ARG,__local_printer__) \ + else \ + `uvm_print_int(ARG, $bits(ARG), `m_uvm_field_radix(FLAG),T,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_enum_read(local_success__, \ + local_rsrc__, \ + T, \ + ARG, \ + this) \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_real +// +// Implements the data operations for any real property. +// +//| `uvm_field_real(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is an real property of the class, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.5 +`define uvm_field_real(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_real(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_real(`"ARG`", ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + __local_printer__.print_real(`"ARG`", ARG); \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_real_read(local_success__, \ + local_rsrc__, \ + ARG, \ + this) \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_event +// +// Implements the data operations for an event property. +// +//| `uvm_field_event(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is an event property of the class, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.1.6 +`define uvm_field_event(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `m_uvm_compare_begin(ARG, local_rhs__.ARG, __local_comparer__) \ + __local_comparer__.print_msg({`"ARG`", " event miscompare"}); \ + `m_uvm_compare_end \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + __local_printer__.print_generic(`"ARG`", "event", -1, ""); \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_sarray_* macros +// +// Macros that implement data operations for one-dimensional static array +// properties. +//----------------------------------------------------------------------------- + +// MACRO -- NODOCS -- `uvm_field_sarray_int +// +// Implements the data operations for a one-dimensional static array of +// integrals. +// +//| `uvm_field_sarray_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional static array of integrals, and ~FLAG~ +// is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.2.1 +`define uvm_field_sarray_int(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_sarray_int(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_sarray(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_sarray(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_int(ARG, `m_uvm_field_radix(FLAG), __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_sarray_int(ARG, \ + `m_uvm_field_radix(FLAG),, \ + __local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if ((local_index__ >= $size(ARG)) || (local_index__ < 0)) begin \ + `uvm_warning("UVM/FIELDS/SARRAY_IDX", $sformatf("Index '%d' is not valid for static array '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + $size(ARG))) \ + end \ + else begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_sarray_object +// +// Implements the data operations for a one-dimensional static array of +// -based objects. +// +//| `uvm_field_sarray_object(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional static array of -based objects, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.2.2 +`define uvm_field_sarray_object(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + foreach(ARG[i]) begin \ + `uvm_copy_object(ARG[i], local_rhs__.ARG[i], `m_uvm_field_recursion(FLAG), __local_copier__) \ + end \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_sarray_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + foreach(ARG[i]) \ + `uvm_pack_object(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + foreach(ARG[i]) \ + `uvm_unpack_object(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_object(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_sarray_object(ARG, `m_uvm_field_recursion(FLAG), __local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if ((local_index__ >= $size(ARG)) || (local_index__ < 0)) begin \ + `uvm_warning("UVM/FIELDS/SARRAY_IDX", $sformatf("Index '%d' is not valid for static array '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + $size(ARG))) \ + end \ + else begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + uvm_object, \ + local_obj__, \ + this) \ + if (local_success__) begin \ + if (local_obj__ == null) begin \ + ARG[local_index__] = null; \ + end else if (!$cast(ARG[local_index__], local_obj__)) begin \ + `uvm_warning("UVM/FIELDS/OBJ_TYPE", $sformatf("Can't set field '%s[%d]' on '%s' with '%s' type", \ + `"ARG`", \ + local_index__, \ + this.get_full_name(), \ + local_obj__.get_type_name())) \ + end \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_sarray_string +// +// Implements the data operations for a one-dimensional static array of +// strings. +// +//| `uvm_field_sarray_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional static array of strings, and ~FLAG~ is a bitwise +// OR of one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.2.3 +`define uvm_field_sarray_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_sarray_string(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + foreach(ARG[i]) \ + `uvm_pack_string(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + foreach(ARG[i]) \ + `uvm_unpack_string(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_string(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_sarray_string(ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if ((local_index__ >= $size(ARG)) || (local_index__ < 0)) begin \ + `uvm_warning("UVM/FIELDS/SARRAY_IDX", $sformatf("Index '%d' is not valid for static array '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + $size(ARG))) \ + end \ + else begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + string, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_sarray_enum +// +// Implements the data operations for a one-dimensional static array of +// enums. +// +//| `uvm_field_sarray_enum(T,ARG,FLAG=UVM_DEFAULT) +// +// ~T~ is a one-dimensional dynamic array of enums _type_, ~ARG~ is an +// instance of that type, and ~FLAG~ is a bitwise OR of one or more flag +// settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.2.4 +`define uvm_field_sarray_enum(T,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_sarray_enum(ARG, local_rhs__.ARG, T, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + foreach (ARG[i]) \ + `uvm_pack_enumN(ARG[i], $bits(T), __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + foreach (ARG[i]) \ + `uvm_unpack_enumN(ARG[i], $bits(T), T, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_enum(ARG, T, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_sarray_enum(T, ARG ,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if ((local_index__ >= $size(ARG)) || (local_index__ < 0)) begin \ + `uvm_warning("UVM/FIELDS/SARRAY_IDX", $sformatf("Index '%d' is not valid for static array '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + $size(ARG))) \ + end \ + else begin \ + `uvm_resource_enum_read(local_success__, \ + local_rsrc__, \ + T, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_array_* macros +// +// Macros that implement data operations for one-dimensional dynamic array +// properties. +// +// Implementation note: +// lines flagged with empty multi-line comments, /**/, are not needed or need +// to be different for fixed arrays, which cannot be resized. Fixed arrays +// do not need to pack/unpack their size either, because their size is known; +// wouldn't hurt though if it allowed code consolidation. Unpacking would +// necessarily be different. */ +// +//----------------------------------------------------------------------------- + + +// m_uvm_QUEUE_resize +// ------------------ + +`define m_uvm_queue_resize(ARG, SZ) \ + if (ARG.size() > SZ) \ + ARG = ARG[0:SZ-1]; \ + else \ + while (ARG.size() < SZ) ARG.push_back(ARG[SZ]); + +// m_uvm_da_resize +// ------------------ + +`define m_uvm_da_resize(ARG, SZ) \ + if (ARG.size() != SZ) ARG = new[SZ](ARG); + + +// m_uvm_field_qda_int +// ------------------- + +`define m_uvm_field_qda_int(TYPE,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_qda_int(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_``TYPE``(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_``TYPE``(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_int(ARG, `m_uvm_field_radix(FLAG), __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_qda_int(TYPE, ARG, `m_uvm_field_radix(FLAG),,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + local_size__, \ + this) \ + if (local_success__) \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if (local_index__ < 0) begin \ + `uvm_warning("UVM/FIELDS/QDA_IDX", $sformatf("Index '%0d' is not valid for field '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + ARG.size() ) ) \ + end \ + else begin \ + bit tmp_stream__[]; \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + { << bit { tmp_stream__ }}, \ + this) \ + if (local_success__) begin \ + if (local_index__ >= ARG.size()) \ + `m_uvm_``TYPE``_resize(ARG, local_index__ + 1) \ + tmp_stream__ = new[$bits(ARG[local_index__])] (tmp_stream__); \ + ARG[local_index__] = { << bit { tmp_stream__ }}; \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_array_int +// +// Implements the data operations for a one-dimensional dynamic array of +// integrals. +// +//| `uvm_field_array_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional dynamic array of integrals, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.3.1 +`define uvm_field_array_int(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_int(da,ARG,FLAG) + +`define m_uvm_field_qda_object(TYPE,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + if ((`m_uvm_field_recursion(FLAG) == UVM_REFERENCE) || !local_rhs__.ARG.size()) \ + ARG = local_rhs__.ARG; \ + else begin \ + `m_uvm_``TYPE``_resize(ARG, local_rhs__.ARG.size()) \ + foreach (ARG[i]) \ + `uvm_copy_object(ARG[i], local_rhs__.ARG[i], `m_uvm_field_recursion(FLAG), __local_copier__) \ + end \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_qda_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + __local_packer__.pack_field_int(ARG.size(), 32); \ + foreach (ARG[i]) \ + `uvm_pack_object(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + local_size__ = __local_packer__.unpack_field_int(32); \ + `m_uvm_``TYPE``_resize(ARG, local_size__); \ + foreach (ARG[i]) \ + `uvm_unpack_object(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_object(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_qda_object(TYPE, ARG, `m_uvm_field_recursion(FLAG),__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + local_size__, \ + this) \ + if (local_success__) \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if (local_index__ < 0) begin \ + `uvm_warning("UVM/FIELDS/QDA_IDX", $sformatf("Index '%0d' is not valid for field '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + ARG.size() ) ) \ + end \ + else begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + uvm_object, \ + local_obj__, \ + this) \ + if (local_success__) begin \ + if (local_index__ >= ARG.size()) \ + `m_uvm_``TYPE``_resize(ARG, local_index__ + 1) \ + if (local_obj__ == null) begin \ + ARG[local_index__] = null; \ + end else if (!$cast(ARG[local_index__], local_obj__)) begin \ + `uvm_error("UVM/FIELDS/QDA_OBJ_TYPE", \ + $sformatf("Can't set field '%s[%0d]' on '%s' with '%s' type", \ + `"ARG`", \ + local_index__, \ + this.get_full_name(), \ + local_obj__.get_type_name())) \ + end \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_array_object +// +// Implements the data operations for a one-dimensional dynamic array +// of -based objects. +// +//| `uvm_field_array_object(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional dynamic array of -based objects, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.3.2 +`define uvm_field_array_object(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_object(da,ARG,FLAG) + + + +// MACRO -- NODOCS -- `uvm_field_array_string +// +// Implements the data operations for a one-dimensional dynamic array +// of strings. +// +//| `uvm_field_array_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional dynamic array of strings, and ~FLAG~ is a bitwise +// OR of one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.3.3 +`define uvm_field_array_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_string(da,ARG,FLAG) + +`define m_uvm_field_qda_string(TYPE,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_qda_string(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + __local_packer__.pack_field_int(ARG.size(), 32); \ + foreach (ARG[i]) \ + `uvm_pack_string(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + local_size__ = __local_packer__.unpack_field_int(32); \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + foreach (ARG[i]) \ + `uvm_unpack_string(ARG[i], __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_string(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_qda_string(TYPE, ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + local_size__, \ + this) \ + if (local_success__) \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if (local_index__ < 0) begin \ + `uvm_warning("UVM/FIELDS/QDA_IDX", $sformatf("Index '%0d' is not valid for field '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + ARG.size() ) ) \ + end \ + else begin \ + string tmp_string__; \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + string, \ + tmp_string__, \ + this) \ + if (local_success__) begin \ + if (local_index__ >= ARG.size()) \ + `m_uvm_``TYPE``_resize(ARG, local_index__ + 1) \ + ARG[local_index__] = tmp_string__; \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_array_enum +// +// Implements the data operations for a one-dimensional dynamic array of +// enums. +// +//| `uvm_field_array_enum(T,ARG,FLAG=UVM_DEFAULT) +// +// ~T~ is a one-dimensional dynamic array of enums _type_, +// ~ARG~ is an instance of that type, and ~FLAG~ is a bitwise OR of +// one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.3.4 +`define uvm_field_array_enum(T,ARG,FLAG=UVM_DEFAULT) \ + `m_field_qda_enum(da,T,ARG,FLAG) + +`define m_field_qda_enum(TYPE,T,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_qda_enum(ARG, local_rhs__.ARG, T, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + __local_packer__.pack_field_int(ARG.size(), 32); \ + foreach (ARG[i]) \ + `uvm_pack_enumN(ARG[i], $bits(T), __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + local_size__ = __local_packer__.unpack_field_int(32); \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + foreach (ARG[i]) \ + `uvm_unpack_enumN(ARG[i], $bits(T), T, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_enum(ARG, T, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_qda_enum(TYPE, T, ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + local_size__, \ + this) \ + if (local_success__) \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if (local_index__ < 0) begin \ + `uvm_warning("UVM/FIELDS/QDA_IDX", $sformatf("Index '%0d' is not valid for field '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + ARG.size() ) ) \ + end \ + else begin \ + T tmp_enum__; \ + `uvm_resource_enum_read(local_success__, \ + local_rsrc__, \ + T, \ + tmp_enum__, \ + this) \ + if (local_success__) begin \ + if (local_index__ >= ARG.size()) \ + `m_uvm_``TYPE``_resize(ARG, local_index__ + 1) \ + ARG[local_index__] = tmp_enum__; \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_queue_* macros +// +// Macros that implement data operations for dynamic queues. +// +//----------------------------------------------------------------------------- + +// MACRO -- NODOCS -- `uvm_field_queue_int +// +// Implements the data operations for a queue of integrals. +// +//| `uvm_field_queue_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional queue of integrals, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.4.1 +`define uvm_field_queue_int(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_int(queue,ARG,FLAG) + +// MACRO -- NODOCS -- `uvm_field_queue_object +// +// Implements the data operations for a queue of -based objects. +// +//| `uvm_field_queue_object(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional queue of -based objects, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described in +// above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.4.2 +`define uvm_field_queue_object(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_object(queue,ARG,FLAG) + + +// MACRO -- NODOCS -- `uvm_field_queue_string +// +// Implements the data operations for a queue of strings. +// +//| `uvm_field_queue_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is a one-dimensional queue of strings, and ~FLAG~ is a bitwise +// OR of one or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.4.3 +`define uvm_field_queue_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_string(queue,ARG,FLAG) + + +// MACRO -- NODOCS -- `uvm_field_queue_enum +// +// Implements the data operations for a one-dimensional queue of enums. +// +//| `uvm_field_queue_enum(T,ARG,FLAG=UVM_DEFAULT) +// +// ~T~ is a queue of enums _type_, ~ARG~ is an instance of that type, +// and ~FLAG~ is a bitwise OR of one or more flag settings as described +// in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.4.4 +`define uvm_field_queue_enum(T,ARG,FLAG=UVM_DEFAULT) \ + `m_field_qda_enum(queue,T,ARG,FLAG) + + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_aa_*_string macros +// +// Macros that implement data operations for associative arrays indexed +// by ~string~. +// +//----------------------------------------------------------------------------- + +// MACRO -- NODOCS -- `uvm_field_aa_int_string +// +// Implements the data operations for an associative array of integrals indexed +// by ~string~. +// +//| `uvm_field_aa_int_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with string key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.5.1 +`define uvm_field_aa_int_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_int_string(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_aa_int_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_aa_int_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_int_string(ARG, `m_uvm_field_radix(FLAG), int, __local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/AA_SIZE", $sformatf("Associative array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + `uvm_resource_builtin_int_read(local_success__, \ + local_rsrc__, \ + ARG[local_index__], \ + this) \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_aa_object_string +// +// Implements the data operations for an associative array of -based +// objects indexed by ~string~. +// +//| `uvm_field_aa_object_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of objects +// with string key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.5.2 +`define uvm_field_aa_object_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + `uvm_copy_aa_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_copier__) \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_object_string(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_pack_aa_object_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_unpack_aa_object_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_object_string(ARG, `m_uvm_field_recursion(FLAG),__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/AA_SIZE", $sformatf("Associative array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + uvm_object, \ + local_obj__, \ + this) \ + if (local_success__) begin \ + if (local_obj__ == null) begin \ + ARG[local_index__] = null; \ + end else if (!$cast(ARG[local_index__], local_obj__)) begin \ + `uvm_warning("UVM/FIELDS/OBJ_TYPE", $sformatf("Can't set field '%s[%s]' on '%s' with '%s' type", \ + `"ARG`", \ + local_index__, \ + this.get_full_name(), \ + local_obj__.get_type_name())) \ + end \ + end \ + /* TODO if(local_success__ && printing matches) */ \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_aa_string_string +// +// Implements the data operations for an associative array of strings indexed +// by ~string~. +// +//| `uvm_field_aa_string_string(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of strings +// with string key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.5.3 +`define uvm_field_aa_string_string(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_string_string(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_aa_string_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_aa_string_string(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_string_string(ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/AA_SIZE", $sformatf("Associative array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + string, \ + ARG[local_index__], \ + this) \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +//----------------------------------------------------------------------------- +// Group -- NODOCS -- `uvm_field_aa_*_int macros +// +// Macros that implement data operations for associative arrays indexed by an +// integral type. +// +//----------------------------------------------------------------------------- + +// MACRO -- NODOCS -- `uvm_field_aa_object_int +// +// Implements the data operations for an associative array of -based +// objects indexed by the ~int~ data type. +// +//| `uvm_field_aa_object_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of objects +// with ~int~ key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.1 +`define uvm_field_aa_object_int(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_object_key(int, ARG, FLAG) + +// Not LRM, but supports packing + configuration +`define uvm_field_aa_object_key(KEY, ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + `uvm_copy_aa_object(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_copier__) \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_object_int(ARG, local_rhs__.ARG, `m_uvm_field_recursion(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_pack_aa_object_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + if (`m_uvm_field_recursion(FLAG) != UVM_REFERENCE) \ + `uvm_unpack_aa_object_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_object_int(ARG, `m_uvm_field_recursion(FLAG), KEY,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + KEY local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + uvm_object, \ + local_obj__, \ + this) \ + if (local_success__) begin \ + if (local_obj__ == null) begin \ + ARG[local_index__] = null; \ + end else if (!$cast(ARG[local_index__], local_obj__)) begin \ + `uvm_warning("UVM/FIELDS/OBJ_TYPE", $sformatf("Can't set field '%s[%d]' on '%s' with '%s' type", \ + `"ARG`", \ + local_index__, \ + this.get_full_name(), \ + local_obj__.get_type_name())) \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// Not LRM, oversight? +`define uvm_field_aa_string_int(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_string_key(int, ARG, FLAG) + +// Not LRM, but supports packing + configuration +`define uvm_field_aa_string_key(KEY, ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_string_int(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_aa_string_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_aa_string_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + /* TODO */ \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + KEY local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + `uvm_resource_read(local_success__, \ + local_rsrc__, \ + string, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// MACRO -- NODOCS -- `uvm_field_aa_int_int +// +// Implements the data operations for an associative array of integral +// types indexed by the ~int~ data type. +// +//| `uvm_field_aa_int_int(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~int~ key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.2 +`define uvm_field_aa_int_int(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(int, ARG, FLAG) \ + + +// MACRO -- NODOCS -- `uvm_field_aa_int_int_unsigned +// +// Implements the data operations for an associative array of integral +// types indexed by the ~int unsigned~ data type. +// +//| `uvm_field_aa_int_int_unsigned(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~int unsigned~ key, and ~FLAG~ is a bitwise OR of one or more flag +// settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.3 +`define uvm_field_aa_int_int_unsigned(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(int unsigned, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_integer +// +// Implements the data operations for an associative array of integral +// types indexed by the ~integer~ data type. +// +//| `uvm_field_aa_int_integer(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~integer~ key, and ~FLAG~ is a bitwise OR of one or more flag settings +// as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.4 +`define uvm_field_aa_int_integer(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(integer, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_integer_unsigned +// +// Implements the data operations for an associative array of integral +// types indexed by the ~integer unsigned~ data type. +// +//| `uvm_field_aa_int_integer_unsigned(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~integer unsigned~ key, and ~FLAG~ is a bitwise OR of one or more +// flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.5 +`define uvm_field_aa_int_integer_unsigned(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(integer unsigned, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_byte +// +// Implements the data operations for an associative array of integral +// types indexed by the ~byte~ data type. +// +//| `uvm_field_aa_int_byte(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~byte~ key, and ~FLAG~ is a bitwise OR of one or more flag settings as +// described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.6 +`define uvm_field_aa_int_byte(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(byte, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_byte_unsigned +// +// Implements the data operations for an associative array of integral +// types indexed by the ~byte unsigned~ data type. +// +//| `uvm_field_aa_int_byte_unsigned(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~byte unsigned~ key, and ~FLAG~ is a bitwise OR of one or more flag +// settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.7 +`define uvm_field_aa_int_byte_unsigned(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(byte unsigned, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_shortint +// +// Implements the data operations for an associative array of integral +// types indexed by the ~shortint~ data type. +// +//| `uvm_field_aa_int_shortint(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~shortint~ key, and ~FLAG~ is a bitwise OR of one or more flag +// settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.8 +`define uvm_field_aa_int_shortint(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(shortint, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_shortint_unsigned +// +// Implements the data operations for an associative array of integral +// types indexed by the ~shortint unsigned~ data type. +// +//| `uvm_field_aa_int_shortint_unsigned(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~shortint unsigned~ key, and ~FLAG~ is a bitwise OR of one or more +// flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.9 +`define uvm_field_aa_int_shortint_unsigned(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(shortint unsigned, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_longint +// +// Implements the data operations for an associative array of integral +// types indexed by the ~longint~ data type. +// +//| `uvm_field_aa_int_longint(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~longint~ key, and ~FLAG~ is a bitwise OR of one or more flag settings +// as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.10 +`define uvm_field_aa_int_longint(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(longint, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_longint_unsigned +// +// Implements the data operations for an associative array of integral +// types indexed by the ~longint unsigned~ data type. +// +//| `uvm_field_aa_int_longint_unsigned(ARG,FLAG=UVM_DEFAULT) +// +// ~ARG~ is the name of a property that is an associative array of integrals +// with ~longint unsigned~ key, and ~FLAG~ is a bitwise OR of one or more +// flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.11 +`define uvm_field_aa_int_longint_unsigned(ARG,FLAG=UVM_DEFAULT) \ + `uvm_field_aa_int_key(longint unsigned, ARG, FLAG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_key +// +// Implements the data operations for an associative array of integral +// types indexed by any integral key data type. +// +//| `uvm_field_aa_int_key(KEY,ARG,FLAG=UVM_DEFAULT) +// +// ~KEY~ is the data type of the integral key, ~ARG~ is the name of a property +// that is an associative array of integrals, and ~FLAG~ is a bitwise OR of one +// or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.12 +`define uvm_field_aa_int_key(KEY, ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_int_int(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_aa_int_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_aa_int_intN(ARG, $bits(KEY), __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_int_int(ARG, `m_uvm_field_radix(FLAG), , KEY,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/AA_SIZE", $sformatf("Associative array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + KEY local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + `uvm_resource_int_read(local_success__, \ + local_rsrc__, \ + KEY, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + + +// MACRO -- NODOCS -- `uvm_field_aa_int_enumkey +// +// Implements the data operations for an associative array of integral +// types indexed by any enumeration key data type. +// +//| `uvm_field_aa_int_enumkey(KEY, ARG,FLAG=UVM_DEFAULT) +// +// ~KEY~ is the enumeration type of the key, ~ARG~ is the name of a property +// that is an associative array of integrals, and ~FLAG~ is a bitwise OR of one +// or more flag settings as described in above. + +// @uvm-ieee 1800.2-2017 auto B.2.2.6.13 +`define uvm_field_aa_int_enumkey(KEY, ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG, FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_aa_int_int(ARG, local_rhs__.ARG, `m_uvm_field_radix(FLAG), __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_aa_int_enum(ARG, KEY, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_aa_int_enum(ARG, KEY, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_aa_int_enum(KEY, ARG, `m_uvm_field_radix(FLAG),,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/AA_SIZE", $sformatf("Associative array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + KEY local_index__; \ + bit[$bits(KEY)-1:0] local_bit_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_bit_index__); \ + if (local_code__ > 0) begin \ + local_index__ = KEY'(local_bit_index__); \ + `uvm_resource_int_read(local_success__, \ + local_rsrc__, \ + KEY, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +//-- Field Macros for arrays of real (Non-LRM enhancement) +`define uvm_field_sarray_real(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_sarray_real(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_sarray_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_sarray_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_real(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_sarray_real(ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_warning("UVM/FIELDS/SARRAY_SIZE", $sformatf("Static array '%s.%s' cannot be resized via configuration.", get_full_name(), `"ARG`") ) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if ((local_index__ >= $size(ARG)) || (local_index__ < 0)) begin \ + `uvm_warning("UVM/FIELDS/SARRAY_IDX", $sformatf("Index '%d' is not valid for static array '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + $size(ARG))) \ + end \ + else begin \ + `uvm_resource_real_read(local_success__, \ + local_rsrc__, \ + ARG[local_index__], \ + this) \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +// m_uvm_field_qda_real +// ------------------- + +`define m_uvm_field_qda_real(TYPE,ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_begin(ARG,FLAG) \ + `m_uvm_field_op_begin(COPY,FLAG) \ + ARG = local_rhs__.ARG; \ + `m_uvm_field_op_end(COPY) \ + `m_uvm_field_op_begin(COMPARE,FLAG) \ + `uvm_compare_qda_real(ARG, local_rhs__.ARG, __local_comparer__) \ + `m_uvm_field_op_end(COMPARE) \ + `m_uvm_field_op_begin(PACK,FLAG) \ + `uvm_pack_``TYPE``_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(PACK) \ + `m_uvm_field_op_begin(UNPACK,FLAG) \ + `uvm_unpack_``TYPE``_real(ARG, __local_packer__) \ + `m_uvm_field_op_end(UNPACK) \ + `m_uvm_field_op_begin(RECORD,FLAG) \ + `uvm_record_qda_real(ARG, __local_recorder__) \ + `m_uvm_field_op_end(RECORD) \ + `m_uvm_field_op_begin(PRINT,FLAG) \ + `uvm_print_qda_real(TYPE, ARG,__local_printer__) \ + `m_uvm_field_op_end(PRINT) \ + `m_uvm_field_op_begin(SET,FLAG) \ + if(local_rsrc_name__ == `"ARG`") begin \ + `uvm_resource_real_read(local_success__, \ + local_rsrc__, \ + local_size__, \ + this) \ + if (local_success__) \ + `m_uvm_``TYPE``_resize(ARG, local_size__) \ + end \ + else begin \ + string local_name__ = {`"ARG`", "["}; \ + if (local_rsrc_name__.len() && \ + local_rsrc_name__[local_rsrc_name__.len()-1] == "]" && \ + local_rsrc_name__.substr(0, local_name__.len()-1) == local_name__) begin \ + string local_index_str__ = local_rsrc_name__.substr(local_name__.len(), \ + local_rsrc_name__.len()-2); \ + int local_index__; \ + /* TODO: Non-decimal indexes */ \ + int local_code__ = $sscanf(local_index_str__, "%d", local_index__); \ + if (local_code__ > 0) begin \ + if (local_index__ < 0) begin \ + `uvm_warning("UVM/FIELDS/QDA_IDX", $sformatf("Index '%0d' is not valid for field '%s.%s' of size '%0d'", \ + local_index__, \ + get_full_name(), \ + `"ARG`", \ + ARG.size() ) ) \ + end \ + else begin \ + real tmp_real__; \ + `uvm_resource_real_read(local_success__, \ + local_rsrc__, \ + tmp_real__, \ + this) \ + if (local_success__) begin \ + if (local_index__ >= ARG.size()) \ + `m_uvm_``TYPE``_resize(ARG, local_index__ + 1) \ + ARG[local_index__] = tmp_real__; \ + end \ + end \ + end \ + end \ + end \ + `m_uvm_field_op_end(SET) \ + `m_uvm_field_end(ARG) + +`define uvm_field_array_real(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_real(da,ARG,FLAG) + +`define uvm_field_queue_real(ARG,FLAG=UVM_DEFAULT) \ + `m_uvm_field_qda_real(queue,ARG,FLAG) + +`endif // !`ifdef UVM_EMPTY_MACROS + +`endif // UVM_OBJECT_DEFINES_SVH diff --git a/test_regress/t/t_uvm/uvmt_logs.svh b/test_regress/t/t_uvm/uvmt_logs.svh index 6fef15f42ed..7205d1805c2 100644 --- a/test_regress/t/t_uvm/uvmt_logs.svh +++ b/test_regress/t/t_uvm/uvmt_logs.svh @@ -49,3 +49,40 @@ typedef enum bit [1:0] { function static int uvm_report_enabled(int a, int b, string c); return 1'b1; endfunction + +function void uvm_report_fatal(string id, + string message, + int verbosity = UVM_NONE, + string filename = "", + int line = 0, + string context_name = "", + bit report_enabled_checked = 0); + $display("(mock) {UVM} FATAL ERROR: [%s] %s ", id, message); + if (filename != "") + $display("(mock) ^ at %s:%0d ", filename, line); + $stop(); +endfunction + +function void uvm_report_error(string id, + string message, + int verbosity = UVM_NONE, + string filename = "", + int line = 0, + string context_name = "", + bit report_enabled_checked = 0); + $display("(mock) {UVM} ERROR: [%s] %s ", id, message); + if (filename != "") + $display("(mock) ^ at %s:%0d ", filename, line); +endfunction + +function void uvm_report_warning(string id, + string message, + int verbosity = UVM_MEDIUM, + string filename = "", + int line = 0, + string context_name = "", + bit report_enabled_checked = 0); + $display("(mock) {UVM} WARNING: [%s] %s ", id, message); + if (filename != "") + $display("(mock) ^ at %s:%0d ", filename, line); +endfunction diff --git a/test_regress/t/t_uvm/uvmt_unit.svh b/test_regress/t/t_uvm/uvmt_unit.svh index f1feb292b90..b895e19167d 100644 --- a/test_regress/t/t_uvm/uvmt_unit.svh +++ b/test_regress/t/t_uvm/uvmt_unit.svh @@ -58,7 +58,8 @@ package uvmt; typedef enum bit [1:0] { S_PASS, S_FAIL, - S_UNTESTED + S_UNTESTED, + S_DISABLED } feature_status_t; typedef struct { @@ -72,6 +73,7 @@ package uvmt; S_PASS: return "PASS"; S_FAIL: return "FAIL"; S_UNTESTED: return "UNTESTED"; + S_DISABLED: return "DISABLED"; default: return ""; endcase endfunction @@ -89,8 +91,8 @@ package uvmt; m_status = S_UNTESTED; endfunction - function void add_feature(string name); - m_features[name] = S_UNTESTED; + function void add_feature(string name, feature_status_t status = S_UNTESTED); + m_features_initials[name] = status; endfunction function void m_fail_feature(test_failure_t failure); @@ -115,6 +117,7 @@ package uvmt; string m_name; feature_status_t m_features[string]; + feature_status_t m_features_initials[string]; feature_status_t m_status; test_failure_t m_failures[$]; uvm_test_base m_tests[$]; @@ -125,12 +128,13 @@ package uvmt; task run(); int feature_count, features_passed, features_failed; - feature_count = m_features.size(); + feature_count = m_features_initials.size(); features_passed = 0; features_failed = 0; m_failures.delete(); - foreach (m_features[feature]) m_features[feature] = S_UNTESTED; + foreach (m_features_initials[feature]) + m_features[feature] = m_features_initials[feature]; foreach (m_tests[i]) begin uvm_test_base test = m_tests[i]; @@ -184,4 +188,3 @@ package uvmt; endtask endclass endpackage - diff --git a/test_regress/t/t_uvm_queue.v b/test_regress/t/t_uvm_queue.v index 9176a06cb32..8ac3b4794f1 100644 --- a/test_regress/t/t_uvm_queue.v +++ b/test_regress/t/t_uvm_queue.v @@ -4,9 +4,11 @@ // any use, without warranty, 2023 by Antmicro Ltd. // SPDX-License-Identifier: CC0-1.0 -`include "t_uvm/uvmt_unit.svh" -`include "t_uvm/base/uvm_object.svh" -`include "t_uvm/base/uvm_queue.svh" +`include "uvmt_unit.svh" +`include "uvmt_logs.svh" + +`include "base/uvm_object.svh" +`include "base/uvm_queue.svh" typedef uvm_queue #(string) strq_t; typedef uvm_queue #(int) intq_t;