//
//------------------------------------------------------------------------------
// Copyright 2010 Paradigm Works
// Copyright 2007-2017 Mentor Graphics Corporation
// Copyright 2014 Semifore
// Copyright 2018 Intel Corporation
// Copyright 2010-2014 Synopsys, Inc.
// Copyright 2007-2018 Cadence Design Systems, Inc.
// Copyright 2011-2018 AMD
// Copyright 2012-2018 Cisco Systems, Inc.
// Copyright 2013-2018 NVIDIA Corporation
// Copyright 2012 Accellera Systems Initiative
// Copyright 2017-2018 Verific
//   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 class uvm_objection;
typedef class uvm_sequence_base;
typedef class uvm_sequence_item;

//------------------------------------------------------------------------------
//
// CLASS -- NODOCS -- uvm_component
//
// The uvm_component class is the root base class for UVM components. In
// addition to the features inherited from <uvm_object> and <uvm_report_object>,
// uvm_component provides the following interfaces:
//
// Hierarchy - provides methods for searching and traversing the component
//     hierarchy.
//
// Phasing - defines a phased test flow that all components follow, with a
//     group of standard phase methods and an API for custom phases and
//     multiple independent phasing domains to mirror DUT behavior e.g. power
//
// Reporting - provides a convenience interface to the <uvm_report_handler>. All
//     messages, warnings, and errors are processed through this interface.
//
// Transaction recording - provides methods for recording the transactions
//     produced or consumed by the component to a transaction database (vendor
//     specific). 
//
// Factory - provides a convenience interface to the <uvm_factory>. The factory
//     is used to create new components and other objects based on type-wide and
//     instance-specific configuration.
//
// The uvm_component is automatically seeded during construction using UVM
// seeding, if enabled. All other objects must be manually reseeded, if
// appropriate. See <uvm_object::reseed> for more information.
//
//------------------------------------------------------------------------------

// @uvm-ieee 1800.2-2017 auto 13.1.1
virtual class uvm_component extends uvm_report_object;

  // Function -- NODOCS -- new
  //
  // Creates a new component with the given leaf instance ~name~ and handle
  // to its ~parent~.  If the component is a top-level component (i.e. it is
  // created in a static module or interface), ~parent~ should be ~null~.
  //
  // The component will be inserted as a child of the ~parent~ object, if any.
  // If ~parent~ already has a child by the given ~name~, an error is produced.
  //
  // If ~parent~ is ~null~, then the component will become a child of the
  // implicit top-level component, ~uvm_top~.
  //
  // All classes derived from uvm_component must call super.new(name,parent).

  // @uvm-ieee 1800.2-2017 auto 13.1.2.1
  extern function new (string name, uvm_component parent);


  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Hierarchy Interface
  //----------------------------------------------------------------------------
  //
  // These methods provide user access to information about the component
  // hierarchy, i.e., topology.
  // 
  //----------------------------------------------------------------------------

  // Function -- NODOCS -- get_parent
  //
  // Returns a handle to this component's parent, or ~null~ if it has no parent.

  // @uvm-ieee 1800.2-2017 auto 13.1.3.1
  extern virtual function uvm_component get_parent ();


  // Function -- NODOCS -- get_full_name
  //
  // Returns the full hierarchical name of this object. The default
  // implementation concatenates the hierarchical name of the parent, if any,
  // with the leaf name of this object, as given by <uvm_object::get_name>. 

  // @uvm-ieee 1800.2-2017 auto 13.1.3.2
  extern virtual function string get_full_name ();


  // Function -- NODOCS -- get_children
  //
  // This function populates the end of the ~children~ array with the 
  // list of this component's children. 
  //
  //|   uvm_component array[$];
  //|   my_comp.get_children(array);
  //|   foreach(array[i]) 
  //|     do_something(array[i]);

  // @uvm-ieee 1800.2-2017 auto 13.1.3.3
  extern function void get_children(ref uvm_component children[$]);



  // @uvm-ieee 1800.2-2017 auto 13.1.3.4
  extern function uvm_component get_child (string name);


  // @uvm-ieee 1800.2-2017 auto 13.1.3.4
  extern function int get_next_child (ref string name);

  // Function -- NODOCS -- get_first_child
  //
  // These methods are used to iterate through this component's children, if
  // any. For example, given a component with an object handle, ~comp~, the
  // following code calls <uvm_object::print> for each child:
  //
  //|    string name;
  //|    uvm_component child;
  //|    if (comp.get_first_child(name))
  //|      do begin
  //|        child = comp.get_child(name);
  //|        child.print();
  //|      end while (comp.get_next_child(name));

  // @uvm-ieee 1800.2-2017 auto 13.1.3.4
  extern function int get_first_child (ref string name);


  // Function -- NODOCS -- get_num_children
  //
  // Returns the number of this component's children. 

  // @uvm-ieee 1800.2-2017 auto 13.1.3.5
  extern function int get_num_children ();


  // Function -- NODOCS -- has_child
  //
  // Returns 1 if this component has a child with the given ~name~, 0 otherwise.

  // @uvm-ieee 1800.2-2017 auto 13.1.3.6
  extern function int has_child (string name);


  // Function - set_name
  //
  // Renames this component to ~name~ and recalculates all descendants'
  // full names. This is an internal function for now.

  extern virtual function void set_name (string name);

  
  // Function -- NODOCS -- lookup
  //
  // Looks for a component with the given hierarchical ~name~ relative to this
  // component. If the given ~name~ is preceded with a '.' (dot), then the search
  // begins relative to the top level (absolute lookup). The handle of the
  // matching component is returned, else ~null~. The name must not contain
  // wildcards.

  // @uvm-ieee 1800.2-2017 auto 13.1.3.7
  extern function uvm_component lookup (string name);


  // Function -- NODOCS -- get_depth
  //
  // Returns the component's depth from the root level. uvm_top has a
  // depth of 0. The test and any other top level components have a depth
  // of 1, and so on.

  extern function int unsigned get_depth();


  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Phasing Interface
  //----------------------------------------------------------------------------
  //
  // These methods implement an interface which allows all components to step
  // through a standard schedule of phases, or a customized schedule, and
  // also an API to allow independent phase domains which can jump like state
  // machines to reflect behavior e.g. power domains on the DUT in different
  // portions of the testbench. The phase tasks and functions are the phase
  // name with the _phase suffix. For example, the build phase function is
  // <build_phase>.
  //
  // All processes associated with a task-based phase are killed when the phase
  // ends. See <uvm_task_phase> for more details.
  //----------------------------------------------------------------------------


  // Function -- NODOCS -- build_phase
  //
  // The <uvm_build_phase> phase implementation method.
  //
  // Any override should call super.build_phase(phase) to execute the automatic
  // configuration of fields registered in the component by calling 
  // <apply_config_settings>.
  // To turn off automatic configuration for a component, 
  // do not call super.build_phase(phase).
  //
  // This method should never be called directly. 

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.1
  extern virtual function void build_phase(uvm_phase phase);

  // Function -- NODOCS -- connect_phase
  //
  // The <uvm_connect_phase> phase implementation method.
  //
  // This method should never be called directly. 

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.2
  extern virtual function void connect_phase(uvm_phase phase);

  // Function -- NODOCS -- end_of_elaboration_phase
  //
  // The <uvm_end_of_elaboration_phase> phase implementation method.
  //
  // This method should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.3
  extern virtual function void end_of_elaboration_phase(uvm_phase phase);

  // Function -- NODOCS -- start_of_simulation_phase
  //
  // The <uvm_start_of_simulation_phase> phase implementation method.
  //
  // This method should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.4
  extern virtual function void start_of_simulation_phase(uvm_phase phase);

  // Task -- NODOCS -- run_phase
  //
  // The <uvm_run_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // Thus the phase will automatically
  // end once all objections are dropped using ~phase.drop_objection()~.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // The run_phase task should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.5
  extern virtual task run_phase(uvm_phase phase);

  // Task -- NODOCS -- pre_reset_phase
  //
  // The <uvm_pre_reset_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.1
  extern virtual task pre_reset_phase(uvm_phase phase);

  // Task -- NODOCS -- reset_phase
  //
  // The <uvm_reset_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.2
  extern virtual task reset_phase(uvm_phase phase);

  // Task -- NODOCS -- post_reset_phase
  //
  // The <uvm_post_reset_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.3
  extern virtual task post_reset_phase(uvm_phase phase);

  // Task -- NODOCS -- pre_configure_phase
  //
  // The <uvm_pre_configure_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.4
  extern virtual task pre_configure_phase(uvm_phase phase);

  // Task -- NODOCS -- configure_phase
  //
  // The <uvm_configure_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.5
  extern virtual task configure_phase(uvm_phase phase);

  // Task -- NODOCS -- post_configure_phase
  //
  // The <uvm_post_configure_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.6
  extern virtual task post_configure_phase(uvm_phase phase);

  // Task -- NODOCS -- pre_main_phase
  //
  // The <uvm_pre_main_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.7
  extern virtual task pre_main_phase(uvm_phase phase);

  // Task -- NODOCS -- main_phase
  //
  // The <uvm_main_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.8
  extern virtual task main_phase(uvm_phase phase);

  // Task -- NODOCS -- post_main_phase
  //
  // The <uvm_post_main_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.9
  extern virtual task post_main_phase(uvm_phase phase);

  // Task -- NODOCS -- pre_shutdown_phase
  //
  // The <uvm_pre_shutdown_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.10
  extern virtual task pre_shutdown_phase(uvm_phase phase);

  // Task -- NODOCS -- shutdown_phase
  //
  // The <uvm_shutdown_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.11
  extern virtual task shutdown_phase(uvm_phase phase);

  // Task -- NODOCS -- post_shutdown_phase
  //
  // The <uvm_post_shutdown_phase> phase implementation method.
  //
  // This task returning or not does not indicate the end
  // or persistence of this phase.
  // It is necessary to raise an objection
  // using ~phase.raise_objection()~ to cause the phase to persist.
  // Once all components have dropped their respective objection
  // using ~phase.drop_objection()~, or if no components raises an
  // objection, the phase is ended.
  // 
  // Any processes forked by this task continue to run
  // after the task returns,
  // but they will be killed once the phase ends.
  //
  // This method should not be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.2.12
  extern virtual task post_shutdown_phase(uvm_phase phase);

  // Function -- NODOCS -- extract_phase
  //
  // The <uvm_extract_phase> phase implementation method.
  //
  // This method should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.6
  extern virtual function void extract_phase(uvm_phase phase);



  // Function -- NODOCS -- check_phase
  //
  // The <uvm_check_phase> phase implementation method.
  //
  // This method should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.7
  extern virtual function void check_phase(uvm_phase phase);

  // Function -- NODOCS -- report_phase
  //
  // The <uvm_report_phase> phase implementation method.
  //
  // This method should never be called directly.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.8
  extern virtual function void report_phase(uvm_phase phase);

  // Function -- NODOCS -- final_phase
  //
  // The <uvm_final_phase> phase implementation method.
  //
  // This method should never be called directly.
  
  // @uvm-ieee 1800.2-2017 auto 13.1.4.1.9
  extern virtual function void final_phase(uvm_phase phase);

`ifdef UVM_ENABLE_DEPRECATED_API
  // For backward compatibility the base <build_phase> method calls <build>.
  extern virtual function void build();

  // For backward compatibility the base connect_phase method calls connect.
  extern virtual function void connect();

  // For backward compatibility the base <end_of_elaboration_phase> method calls <end_of_elaboration>.
  extern virtual function void end_of_elaboration();
   
  // For backward compatibility the base <start_of_simulation_phase> method calls <start_of_simulation>.
  extern virtual function void start_of_simulation();

  // For backward compatibility the base <run_phase> method calls <run>.
  extern virtual task run();

  // For backward compatibility the base extract_phase method calls extract.
  extern virtual function void extract();

  // For backward compatibility the base check_phase method calls check.
  extern virtual function void check();

  // For backward compatibility the base report_phase method calls report.
  extern virtual function void report();
`endif // UVM_ENABLE_DEPRECATED_API

  // Function -- NODOCS -- phase_started
  //
  // Invoked at the start of each phase. The ~phase~ argument specifies
  // the phase being started. Any threads spawned in this callback are
  // not affected when the phase ends.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.3.1
  extern virtual function void phase_started (uvm_phase phase);

  // Function -- NODOCS -- phase_ready_to_end
  //
  // Invoked when all objections to ending the given ~phase~ and all
  // sibling phases have been dropped, thus indicating that ~phase~ is 
  // ready to begin a clean exit. Sibling phases are any phases that 
  // have a common successor phase in the schedule plus any phases that
  // sync'd to the current phase. Components needing to consume delta
  // cycles or advance time to perform a clean exit from the phase
  // may raise the phase's objection. 
  //
  // |phase.raise_objection(this,"Reason");
  //
  // It is the responsibility of this component to drop the objection 
  // once it is ready for this phase to end (and processes killed).
  // If no objection to the given ~phase~ or sibling phases are raised,
  // then phase_ended() is called after a delta cycle.  If any objection
  // is raised, then when all objections to ending the given ~phase~
  // and siblings are dropped, another iteration of phase_ready_to_end
  // is called.  To prevent endless iterations due to coding error,
  // after 20 iterations, phase_ended() is called regardless of whether
  // previous iteration had any objections raised.
  
  // @uvm-ieee 1800.2-2017 auto 13.1.4.3.2
  extern virtual function void phase_ready_to_end (uvm_phase phase);


  // Function -- NODOCS -- phase_ended
  //
  // Invoked at the end of each phase. The ~phase~ argument specifies
  // the phase that is ending.  Any threads spawned in this callback are
  // not affected when the phase ends.
  
  // @uvm-ieee 1800.2-2017 auto 13.1.4.3.3
  extern virtual function void phase_ended (uvm_phase phase);

  
  //--------------------------------------------------------------------
  // phase / schedule / domain API
  //--------------------------------------------------------------------

  
  // Function -- NODOCS -- set_domain
  //
  // Apply a phase domain to this component and, if ~hier~ is set, 
  // recursively to all its children. 
  //
  // Calls the virtual <define_domain> method, which derived components can
  // override to augment or replace the domain definition of its base class.
  //

  // @uvm-ieee 1800.2-2017 auto 13.1.4.4.1
  extern function void set_domain(uvm_domain domain, int hier=1);


  // Function -- NODOCS -- get_domain
  //
  // Return handle to the phase domain set on this component
  
  // @uvm-ieee 1800.2-2017 auto 13.1.4.4.2
  extern function uvm_domain get_domain();


  // Function -- NODOCS -- define_domain
  //
  // Builds custom phase schedules into the provided ~domain~ handle.
  //
  // This method is called by <set_domain>, which integrators use to specify
  // this component belongs in a domain apart from the default 'uvm' domain.
  //
  // Custom component base classes requiring a custom phasing schedule can
  // augment or replace the domain definition they inherit by overriding
  // their ~defined_domain~. To augment, overrides would call super.define_domain().
  // To replace, overrides would not call super.define_domain().
  // 
  // The default implementation adds a copy of the ~uvm~ phasing schedule to
  // the given ~domain~, if one doesn't already exist, and only if the domain
  // is currently empty.
  //
  // Calling <set_domain>
  // with the default ~uvm~ domain (i.e. <uvm_domain::get_uvm_domain> ) on
  // a component with no ~define_domain~ override effectively reverts the
  // that component to using the default ~uvm~ domain. This may be useful
  // if a branch of the testbench hierarchy defines a custom domain, but
  // some child sub-branch should remain in the default ~uvm~ domain,
  // call <set_domain> with a new domain instance handle with ~hier~ set.
  // Then, in the sub-branch, call <set_domain> with the default ~uvm~ domain handle,
  // obtained via <uvm_domain::get_uvm_domain>.
  //
  // Alternatively, the integrator may define the graph in a new domain externally,
  // then call <set_domain> to apply it to a component.


  // @uvm-ieee 1800.2-2017 auto 13.1.4.4.3
  extern virtual protected function void define_domain(uvm_domain domain);

`ifdef UVM_ENABLE_DEPRECATED_API
  // Function -- NODOCS -- set_phase_imp
  //
  // Override the default implementation for a phase on this component (tree) with a
  // custom one, which must be created as a singleton object extending the default
  // one and implementing required behavior in exec and traverse methods
  //
  // The ~hier~ specifies whether to apply the custom functor to the whole tree or
  // just this component.

  extern function void set_phase_imp(uvm_phase phase, uvm_phase imp, int hier=1);
`endif
  
  // Task -- NODOCS -- suspend
  //
  // Suspend this component.
  //
  // This method must be implemented by the user to suspend the
  // component according to the protocol and functionality it implements.
  // A suspended component can be subsequently resumed using <resume()>. 

  // @uvm-ieee 1800.2-2017 auto 13.1.4.5.1
  extern virtual task suspend ();


  // Task -- NODOCS -- resume
  //
  // Resume this component.
  //
  // This method must be implemented by the user to resume a component
  // that was previously suspended using <suspend()>.
  // Some component may start in the suspended state and
  // may need to be explicitly resumed.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.5.2
  extern virtual task resume ();


  // Function -- NODOCS -- resolve_bindings
  //
  // Processes all port, export, and imp connections. Checks whether each port's
  // min and max connection requirements are met.
  //
  // It is called just before the end_of_elaboration phase.
  //
  // Users should not call directly.

  extern virtual function void resolve_bindings ();

  extern function string massage_scope(string scope);


  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Configuration Interface
  //----------------------------------------------------------------------------
  //
  // Components can be designed to be user-configurable in terms of its
  // topology (the type and number of children it has), mode of operation, and
  // run-time parameters (knobs). The configuration interface accommodates
  // this common need, allowing component composition and state to be modified
  // without having to derive new classes or new class hierarchies for
  // every configuration scenario. 
  //
  //----------------------------------------------------------------------------

`ifdef UVM_ENABLE_DEPRECATED_API
  // Function -- NODOCS -- check_config_usage
  //
  // Check all configuration settings in a components configuration table
  // to determine if the setting has been used, overridden or not used.
  // When ~recurse~ is 1 (default), configuration for this and all child
  // components are recursively checked. This function is automatically
  // called in the check phase, but can be manually called at any time.
  //
  // To get all configuration information prior to the run phase, do something 
  // like this in your top object:
  //|  function void start_of_simulation_phase(uvm_phase phase);
  //|    check_config_usage();
  //|  endfunction

  extern function void check_config_usage (bit recurse=1);
`endif // UVM_ENABLE_DEPRECATED_API

  // Function -- NODOCS -- apply_config_settings
  //
  // Searches for all config settings matching this component's instance path.
  // For each match, the appropriate set_*_local method is called using the
  // matching config setting's field_name and value. Provided the set_*_local
  // method is implemented, the component property associated with the
  // field_name is assigned the given value. 
  //
  // This function is called by <uvm_component::build_phase>.
  //
  // The apply_config_settings method determines all the configuration
  // settings targeting this component and calls the appropriate set_*_local
  // method to set each one. To work, you must override one or more set_*_local
  // methods to accommodate setting of your component's specific properties.
  // Any properties registered with the optional `uvm_*_field macros do not
  // require special handling by the set_*_local methods; the macros provide
  // the set_*_local functionality for you. 
  //
  // If you do not want apply_config_settings to be called for a component,
  // then the build_phase() method should be overloaded and you should not call
  // super.build_phase(phase). Likewise, apply_config_settings can be overloaded to
  // customize automated configuration.
  //
  // When the ~verbose~ bit is set, all overrides are printed as they are
  // applied. If the component's <print_config_matches> property is set, then
  // apply_config_settings is automatically called with ~verbose~ = 1.

  // @uvm-ieee 1800.2-2017 auto 13.1.5.1
  extern virtual function void apply_config_settings (bit verbose = 0);

  // Function -- NODOCS -- use_automatic_config
  //
  // Returns 1 if the component should call <apply_config_settings> in the <build_phase>;
  // otherwise, returns 0.
  //
  // @uvm-ieee 1800.2-2017 auto 13.1.5.2
  extern virtual function bit use_automatic_config();

`ifdef UVM_ENABLE_DEPRECATED_API
  // Function -- NODOCS -- print_config_settings
  //
  // Called without arguments, print_config_settings prints all configuration
  // information for this component, as set by previous calls to <uvm_config_db::set()>.
  // The settings are printing in the order of their precedence.
  // 
  // If ~field~ is specified and non-empty, then only configuration settings
  // matching that field, if any, are printed. The field may not contain
  // wildcards. 
  //
  // If ~comp~ is specified and non-~null~, then the configuration for that
  // component is printed.
  //
  // If ~recurse~ is set, then configuration information for all ~comp~'s
  // children and below are printed as well.
  //
  // This function has been deprecated.  Use print_config instead.

  extern function void print_config_settings (string field="", 
                                              uvm_component comp=null, 
                                              bit recurse=0);
`endif // UVM_ENABLE_DEPRECATED_API
   
  // Function: print_config
  //
  // Print_config prints all configuration information for this
  // component, as set by previous calls to <uvm_config_db::set()> and exports to
  // the resources pool.  The settings are printed in the order of
  // their precedence.
  //
  // If ~recurse~ is set, then configuration information for all
  // children and below are printed as well.
  //
  // if ~audit~ is set then the audit trail for each resource is printed
  // along with the resource name and value
  //
  // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2

  extern function void print_config(bit recurse = 0, bit audit = 0);

  // Function -- NODOCS -- print_config_with_audit
  //
  // Operates the same as print_config except that the audit bit is
  // forced to 1.  This interface makes user code a bit more readable as
  // it avoids multiple arbitrary bit settings in the argument list.
  //
  // If ~recurse~ is set, then configuration information for all
  // children and below are printed as well.

  extern function void print_config_with_audit(bit recurse = 0);

  // Variable: print_config_matches
  //
  // Setting this static variable causes uvm_config_db::get() to print info about
  // matching configuration settings as they are being applied.
  //
  // @uvm-accellera The details of this API are specific to the Accellera implementation, and are not being considered for contribution to 1800.2


  static bit print_config_matches;

  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Objection Interface
  //----------------------------------------------------------------------------
  //
  // These methods provide object level hooks into the <uvm_objection> 
  // mechanism.
  // 
  //----------------------------------------------------------------------------


  // Function -- NODOCS -- raised
  //
  // The ~raised~ callback is called when this or a descendant of this component
  // instance raises the specified ~objection~. The ~source_obj~ is the object
  // that originally raised the objection. 
  // The ~description~ is optionally provided by the ~source_obj~ to give a
  // reason for raising the objection. The ~count~ indicates the number of
  // objections raised by the ~source_obj~.

  // @uvm-ieee 1800.2-2017 auto 13.1.5.4
  virtual function void raised (uvm_objection objection, uvm_object source_obj, 
      string description, int count);
  endfunction


  // Function -- NODOCS -- dropped
  //
  // The ~dropped~ callback is called when this or a descendant of this component
  // instance drops the specified ~objection~. The ~source_obj~ is the object
  // that originally dropped the objection. 
  // The ~description~ is optionally provided by the ~source_obj~ to give a
  // reason for dropping the objection. The ~count~ indicates the number of
  // objections dropped by the ~source_obj~.

  // @uvm-ieee 1800.2-2017 auto 13.1.5.5
  virtual function void dropped (uvm_objection objection, uvm_object source_obj, 
      string description, int count);
  endfunction


  // Task -- NODOCS -- all_dropped
  //
  // The ~all_droppped~ callback is called when all objections have been 
  // dropped by this component and all its descendants.  The ~source_obj~ is the
  // object that dropped the last objection.
  // The ~description~ is optionally provided by the ~source_obj~ to give a
  // reason for raising the objection. The ~count~ indicates the number of
  // objections dropped by the ~source_obj~.

  // @uvm-ieee 1800.2-2017 auto 13.1.5.6
  virtual task all_dropped (uvm_objection objection, uvm_object source_obj, 
      string description, int count);
  endtask


  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Factory Interface
  //----------------------------------------------------------------------------
  //
  // The factory interface provides convenient access to a portion of UVM's
  // <uvm_factory> interface. For creating new objects and components, the
  // preferred method of accessing the factory is via the object or component
  // wrapper (see <uvm_component_registry #(T,Tname)> and
  // <uvm_object_registry #(T,Tname)>). The wrapper also provides functions
  // for setting type and instance overrides.
  //
  //----------------------------------------------------------------------------

  // Function -- NODOCS -- create_component
  //
  // A convenience function for <uvm_factory::create_component_by_name>,
  // this method calls upon the factory to create a new child component
  // whose type corresponds to the preregistered type name, ~requested_type_name~,
  // and instance name, ~name~. This method is equivalent to:
  //
  //|  factory.create_component_by_name(requested_type_name,
  //|                                   get_full_name(), name, this);
  //
  // If the factory determines that a type or instance override exists, the type
  // of the component created may be different than the requested type. See
  // <set_type_override> and <set_inst_override>. See also <uvm_factory> for
  // details on factory operation.

  extern function uvm_component create_component (string requested_type_name, 
                                                  string name);


  // Function -- NODOCS -- create_object
  //
  // A convenience function for <uvm_factory::create_object_by_name>,
  // this method calls upon the factory to create a new object
  // whose type corresponds to the preregistered type name,
  // ~requested_type_name~, and instance name, ~name~. This method is
  // equivalent to:
  //
  //|  factory.create_object_by_name(requested_type_name,
  //|                                get_full_name(), name);
  //
  // If the factory determines that a type or instance override exists, the
  // type of the object created may be different than the requested type.  See
  // <uvm_factory> for details on factory operation.

  extern function uvm_object create_object (string requested_type_name,
                                            string name="");


  // Function -- NODOCS -- set_type_override_by_type
  //
  // A convenience function for <uvm_factory::set_type_override_by_type>, this
  // method registers a factory override for components and objects created at
  // this level of hierarchy or below. This method is equivalent to:
  //
  //|  factory.set_type_override_by_type(original_type, override_type,replace);
  //
  // The ~relative_inst_path~ is relative to this component and may include
  // wildcards. The ~original_type~ represents the type that is being overridden.
  // In subsequent calls to <uvm_factory::create_object_by_type> or
  // <uvm_factory::create_component_by_type>, if the requested_type matches the
  // ~original_type~ and the instance paths match, the factory will produce
  // the ~override_type~. 
  //
  // The original and override type arguments are lightweight proxies to the
  // types they represent. See <set_inst_override_by_type> for information
  // on usage.

  extern static function void set_type_override_by_type
                                             (uvm_object_wrapper original_type, 
                                              uvm_object_wrapper override_type,
                                              bit replace=1);


  // Function -- NODOCS -- set_inst_override_by_type
  //
  // A convenience function for <uvm_factory::set_inst_override_by_type>, this
  // method registers a factory override for components and objects created at
  // this level of hierarchy or below. In typical usage, this method is
  // equivalent to:
  //
  //|  factory.set_inst_override_by_type( original_type,
  //|                                     override_type,
  //|                                     {get_full_name(),".",
  //|                                      relative_inst_path});
  //
  // The ~relative_inst_path~ is relative to this component and may include
  // wildcards. The ~original_type~ represents the type that is being overridden.
  // In subsequent calls to <uvm_factory::create_object_by_type> or
  // <uvm_factory::create_component_by_type>, if the requested_type matches the
  // ~original_type~ and the instance paths match, the factory will produce the
  // ~override_type~. 
  //
  // The original and override types are lightweight proxies to the types they
  // represent. They can be obtained by calling ~type::get_type()~, if
  // implemented by ~type~, or by directly calling ~type::type_id::get()~, where 
  // ~type~ is the user type and ~type_id~ is the name of the typedef to
  // <uvm_object_registry #(T,Tname)> or <uvm_component_registry #(T,Tname)>.
  //
  // If you are employing the `uvm_*_utils macros, the typedef and the get_type
  // method will be implemented for you. For details on the utils macros
  // refer to <Utility and Field Macros for Components and Objects>.
  //
  // The following example shows `uvm_*_utils usage:
  //
  //|  class comp extends uvm_component;
  //|    `uvm_component_utils(comp)
  //|    ...
  //|  endclass
  //|
  //|  class mycomp extends uvm_component;
  //|    `uvm_component_utils(mycomp)
  //|    ...
  //|  endclass
  //|
  //|  class block extends uvm_component;
  //|    `uvm_component_utils(block)
  //|    comp c_inst;
  //|    virtual function void build_phase(uvm_phase phase);
  //|      set_inst_override_by_type("c_inst",comp::get_type(),
  //|                                         mycomp::get_type());
  //|    endfunction
  //|    ...
  //|  endclass

  extern function void set_inst_override_by_type(string relative_inst_path,  
                                                 uvm_object_wrapper original_type,
                                                 uvm_object_wrapper override_type);


  // Function -- NODOCS -- set_type_override
  //
  // A convenience function for <uvm_factory::set_type_override_by_name>,
  // this method configures the factory to create an object of type
  // ~override_type_name~ whenever the factory is asked to produce a type
  // represented by ~original_type_name~.  This method is equivalent to:
  //
  //|  factory.set_type_override_by_name(original_type_name,
  //|                                    override_type_name, replace);
  //
  // The ~original_type_name~ typically refers to a preregistered type in the
  // factory. It may, however, be any arbitrary string. Subsequent calls to
  // create_component or create_object with the same string and matching
  // instance path will produce the type represented by override_type_name.
  // The ~override_type_name~ must refer to a preregistered type in the factory. 

  extern static function void set_type_override(string original_type_name, 
                                                string override_type_name,
                                                bit    replace=1);


  // Function -- NODOCS -- set_inst_override
  //
  // A convenience function for <uvm_factory::set_inst_override_by_name>, this
  // method registers a factory override for components created at this level
  // of hierarchy or below. In typical usage, this method is equivalent to:
  //
  //|  factory.set_inst_override_by_name(original_type_name,
  //|                                    override_type_name,
  //|                                    {get_full_name(),".",
  //|                                     relative_inst_path}
  //|                                     );
  //
  // The ~relative_inst_path~ is relative to this component and may include
  // wildcards. The ~original_type_name~ typically refers to a preregistered type
  // in the factory. It may, however, be any arbitrary string. Subsequent calls
  // to create_component or create_object with the same string and matching
  // instance path will produce the type represented by ~override_type_name~.
  // The ~override_type_name~ must refer to a preregistered type in the factory. 

  extern function void set_inst_override(string relative_inst_path,  
                                         string original_type_name,
                                         string override_type_name);


  // Function -- NODOCS -- print_override_info
  //
  // This factory debug method performs the same lookup process as create_object
  // and create_component, but instead of creating an object, it prints
  // information about what type of object would be created given the
  // provided arguments.

  extern function void print_override_info(string requested_type_name,
                                           string name="");


  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Hierarchical Reporting Interface
  //----------------------------------------------------------------------------
  //
  // This interface provides versions of the set_report_* methods in the
  // <uvm_report_object> base class that are applied recursively to this
  // component and all its children.
  //
  // When a report is issued and its associated action has the LOG bit set, the
  // report will be sent to its associated FILE descriptor.
  //----------------------------------------------------------------------------

  // Function -- NODOCS -- set_report_id_verbosity_hier

  extern function void set_report_id_verbosity_hier (string id,
                                                  int verbosity);

  // Function -- NODOCS -- set_report_severity_id_verbosity_hier
  //
  // These methods recursively associate the specified verbosity with reports of
  // the given ~severity~, ~id~, or ~severity-id~ pair. A verbosity associated
  // with a particular severity-id pair takes precedence over a verbosity
  // associated with id, which takes precedence over a verbosity associated
  // with a severity.
  //
  // For a list of severities and their default verbosities, refer to
  // <uvm_report_handler>.

  extern function void set_report_severity_id_verbosity_hier(uvm_severity severity,
                                                          string id,
                                                          int verbosity);


  // Function -- NODOCS -- set_report_severity_action_hier

  extern function void set_report_severity_action_hier (uvm_severity severity,
                                                        uvm_action action);


  // Function -- NODOCS -- set_report_id_action_hier

  extern function void set_report_id_action_hier (string id,
                                                  uvm_action action);

  // Function -- NODOCS -- set_report_severity_id_action_hier
  //
  // These methods recursively associate the specified action with reports of
  // the given ~severity~, ~id~, or ~severity-id~ pair. An action associated
  // with a particular severity-id pair takes precedence over an action
  // associated with id, which takes precedence over an action associated
  // with a severity.
  //
  // For a list of severities and their default actions, refer to
  // <uvm_report_handler>.

  extern function void set_report_severity_id_action_hier(uvm_severity severity,
                                                          string id,
                                                          uvm_action action);



  // Function -- NODOCS -- set_report_default_file_hier

  extern function void set_report_default_file_hier (UVM_FILE file);

  // Function -- NODOCS -- set_report_severity_file_hier

  extern function void set_report_severity_file_hier (uvm_severity severity,
                                                      UVM_FILE file);

  // Function -- NODOCS -- set_report_id_file_hier

  extern function void set_report_id_file_hier (string id,
                                                UVM_FILE file);

  // Function -- NODOCS -- set_report_severity_id_file_hier
  //
  // These methods recursively associate the specified FILE descriptor with
  // reports of the given ~severity~, ~id~, or ~severity-id~ pair. A FILE
  // associated with a particular severity-id pair takes precedence over a FILE
  // associated with id, which take precedence over an a FILE associated with a
  // severity, which takes precedence over the default FILE descriptor.
  //
  // For a list of severities and other information related to the report
  // mechanism, refer to <uvm_report_handler>.

  extern function void set_report_severity_id_file_hier(uvm_severity severity,
                                                        string id,
                                                        UVM_FILE file);


  // Function -- NODOCS -- set_report_verbosity_level_hier
  //
  // This method recursively sets the maximum verbosity level for reports for
  // this component and all those below it. Any report from this component
  // subtree whose verbosity exceeds this maximum will be ignored.
  // 
  // See <uvm_report_handler> for a list of predefined message verbosity levels
  // and their meaning.

    extern function void set_report_verbosity_level_hier (int verbosity);
 

  // Function -- NODOCS -- pre_abort
  //
  // This callback is executed when the message system is executing a
  // <UVM_EXIT> action. The exit action causes an immediate termination of
  // the simulation, but the pre_abort callback hook gives components an 
  // opportunity to provide additional information to the user before
  // the termination happens. For example, a test may want to executed
  // the report function of a particular component even when an error
  // condition has happened to force a premature termination you would
  // write a function like:
  //
  //| function void mycomponent::pre_abort();
  //|   report();
  //| endfunction
  //
  // The pre_abort() callback hooks are called in a bottom-up fashion.

  // @uvm-ieee 1800.2-2017 auto 13.1.4.6
  virtual function void pre_abort;
  endfunction

  //----------------------------------------------------------------------------
  // Group -- NODOCS -- Recording Interface
  //----------------------------------------------------------------------------
  // These methods comprise the component-based transaction recording
  // interface. The methods can be used to record the transactions that
  // this component "sees", i.e. produces or consumes.
  //
  // The API and implementation are subject to change once a vendor-independent
  // use-model is determined.
  //----------------------------------------------------------------------------

  // Function -- NODOCS -- accept_tr
  //
  // This function marks the acceptance of a transaction, ~tr~, by this
  // component. Specifically, it performs the following actions:
  //
  // - Calls the ~tr~'s <uvm_transaction::accept_tr> method, passing to it the
  //   ~accept_time~ argument.
  //
  // - Calls this component's <do_accept_tr> method to allow for any post-begin
  //   action in derived classes.
  //
  // - Triggers the component's internal accept_tr event. Any processes waiting
  //   on this event will resume in the next delta cycle. 

  // @uvm-ieee 1800.2-2017 auto 13.1.6.1
  extern function void accept_tr (uvm_transaction tr, time accept_time = 0);


  // Function -- NODOCS -- do_accept_tr
  //
  // The <accept_tr> method calls this function to accommodate any user-defined
  // post-accept action. Implementations should call super.do_accept_tr to
  // ensure correct operation.
    
  // @uvm-ieee 1800.2-2017 auto 13.1.6.2
  extern virtual protected function void do_accept_tr (uvm_transaction tr);


  // Function -- NODOCS -- begin_tr
  //
  // This function marks the start of a transaction, ~tr~, by this component.
  // Specifically, it performs the following actions:
  //
  // - Calls ~tr~'s <uvm_transaction::begin_tr> method, passing to it the
  //   ~begin_time~ argument. The ~begin_time~ should be greater than or equal
  //   to the accept time. By default, when ~begin_time~ = 0, the current
  //   simulation time is used.
  //
  //   If recording is enabled (recording_detail != UVM_OFF), then a new
  //   database-transaction is started on the component's transaction stream
  //   given by the stream argument. No transaction properties are recorded at
  //   this time.
  //
  // - Calls the component's <do_begin_tr> method to allow for any post-begin
  //   action in derived classes.
  //
  // - Triggers the component's internal begin_tr event. Any processes waiting
  //   on this event will resume in the next delta cycle. 
  //
  // A handle to the transaction is returned. The meaning of this handle, as
  // well as the interpretation of the arguments ~stream_name~, ~label~, and
  // ~desc~ are vendor specific.

   // @uvm-ieee 1800.2-2017 auto 13.1.6.3
   extern function int begin_tr (uvm_transaction tr,
                                     string stream_name="main",
                                     string label="",
                                     string desc="",
                                     time begin_time=0,
                                     int parent_handle=0);

`ifdef UVM_ENABLE_DEPRECATED_API
  // Function -- NODOCS -- begin_child_tr
  //
  // This function marks the start of a child transaction, ~tr~, by this
  // component. Its operation is identical to that of <begin_tr>, except that
  // an association is made between this transaction and the provided parent
  // transaction. This association is vendor-specific.
  // 
  // This function is deprecated

  extern function int begin_child_tr (uvm_transaction tr,
                                          int parent_handle=0,
                                          string stream_name="main",
                                          string label="",
                                          string desc="",
                                          time begin_time=0);
`endif //UVM_ENABLE_DEPRECATED_API

  // Function -- NODOCS -- do_begin_tr
  //
  // The <begin_tr> and <begin_child_tr> methods call this function to
  // accommodate any user-defined post-begin action. Implementations should call
  // super.do_begin_tr to ensure correct operation.

  extern virtual protected 
    // @uvm-ieee 1800.2-2017 auto 13.1.6.4
    function void do_begin_tr (uvm_transaction tr,
                               string stream_name,
                               int tr_handle);


  // Function -- NODOCS -- end_tr
  //
  // This function marks the end of a transaction, ~tr~, by this component.
  // Specifically, it performs the following actions:
  //
  // - Calls ~tr~'s <uvm_transaction::end_tr> method, passing to it the
  //   ~end_time~ argument. The ~end_time~ must at least be greater than the
  //   begin time. By default, when ~end_time~ = 0, the current simulation time
  //   is used.
  //
  //   The transaction's properties are recorded to the database-transaction on
  //   which it was started, and then the transaction is ended. Only those
  //   properties handled by the transaction's do_record method (and optional
  //   `uvm_*_field macros) are recorded.
  //
  // - Calls the component's <do_end_tr> method to accommodate any post-end
  //   action in derived classes.
  //
  // - Triggers the component's internal end_tr event. Any processes waiting on
  //   this event will resume in the next delta cycle. 
  //
  // The ~free_handle~ bit indicates that this transaction is no longer needed.
  // The implementation of free_handle is vendor-specific.

  // @uvm-ieee 1800.2-2017 auto 13.1.6.5
  extern function void end_tr (uvm_transaction tr,
                               time end_time=0,
                               bit free_handle=1);


  // Function -- NODOCS -- do_end_tr
  //
  // The <end_tr> method calls this function to accommodate any user-defined
  // post-end action. Implementations should call super.do_end_tr to ensure
  // correct operation.

  // @uvm-ieee 1800.2-2017 auto 13.1.6.6
  extern virtual protected function void do_end_tr (uvm_transaction tr,
                                                    int tr_handle);


  // Function -- NODOCS -- record_error_tr
  //
  // This function marks an error transaction by a component. Properties of the
  // given uvm_object, ~info~, as implemented in its <uvm_object::do_record> method,
  // are recorded to the transaction database.
  //
  // An ~error_time~ of 0 indicates to use the current simulation time. The
  // ~keep_active~ bit determines if the handle should remain active. If 0,
  // then a zero-length error transaction is recorded. A handle to the
  // database-transaction is returned. 
  //
  // Interpretation of this handle, as well as the strings ~stream_name~,
  // ~label~, and ~desc~, are vendor-specific.

  // @uvm-ieee 1800.2-2017 auto 13.1.6.7
  extern function int record_error_tr (string stream_name="main",
                                           uvm_object info=null,
                                           string label="error_tr",
                                           string desc="",
                                           time   error_time=0,
                                           bit    keep_active=0);


  // Function -- NODOCS -- record_event_tr
  //
  // This function marks an event transaction by a component. 
  //
  // An ~event_time~ of 0 indicates to use the current simulation time. 
  //
  // A handle to the transaction is returned. The ~keep_active~ bit determines
  // if the handle may be used for other vendor-specific purposes. 
  //
  // The strings for ~stream_name~, ~label~, and ~desc~ are vendor-specific
  // identifiers for the transaction.

  // @uvm-ieee 1800.2-2017 auto 13.1.6.8
  extern function int record_event_tr (string stream_name="main",
                                           uvm_object info=null,
                                           string label="event_tr",
                                           string desc="",
                                           time   event_time=0,
                                           bit    keep_active=0);


  // @uvm-ieee 1800.2-2017 auto 13.1.6.9
  extern virtual function uvm_tr_stream get_tr_stream(string name,
                                                      string stream_type_name="");


  // @uvm-ieee 1800.2-2017 auto 13.1.6.10
  extern virtual function void free_tr_stream(uvm_tr_stream stream);

  // Variable -- NODOCS -- print_enabled
  //
  // This bit determines if this component should automatically be printed as a
  // child of its parent object. 
  // 
  // By default, all children are printed. However, this bit allows a parent
  // component to disable the printing of specific children.

  bit print_enabled = 1;

  // Variable -- NODOCS -- tr_database
  //
  // Specifies the <uvm_tr_database> object to use for <begin_tr>
  // and other methods in the <Recording Interface>.  
  // Default is <uvm_coreservice_t::get_default_tr_database>.
  uvm_tr_database tr_database;
  
  `ifdef UVM_ENABLE_DEPRECATED_API
  extern virtual function uvm_tr_database m_get_tr_database();
  `endif // UVM_ENABLE_DEPRECATED_API
  
  // @uvm-ieee 1800.2-2017 auto 13.1.6.12
  extern virtual function uvm_tr_database get_tr_database();

  // @uvm-ieee 1800.2-2017 auto 13.1.6.11
  extern virtual function void set_tr_database(uvm_tr_database db);


  //----------------------------------------------------------------------------
  //                     PRIVATE or PSUEDO-PRIVATE members
  //                      *** Do not call directly ***
  //         Implementation and even existence are subject to change. 
  //----------------------------------------------------------------------------
  // Most local methods are prefixed with m_, indicating they are not
  // user-level methods. SystemVerilog does not support friend classes,
  // which forces some otherwise internal methods to be exposed (i.e. not
  // be protected via 'local' keyword). These methods are also prefixed
  // with m_ to indicate they are not intended for public use.
  //
  // Internal methods will not be documented, although their implementa-
  // tions are freely available via the open-source license.
  //----------------------------------------------------------------------------

  protected uvm_domain m_domain;    // set_domain stores our domain handle

  /*protected*/ uvm_phase  m_phase_imps[uvm_phase];    // functors to override ovm_root defaults

  //TND review protected, provide read-only accessor.
  uvm_phase            m_current_phase;            // the most recently executed phase
  protected process    m_phase_process;

  /*protected*/ bit  m_build_done;
  /*protected*/ int  m_phasing_active;

`ifdef UVM_ENABLE_DEPRECATED_API
  extern                   function void set_int_local(string field_name, 
                                                       uvm_bitstream_t value,
                                                       bit recurse=1);
`endif // UVM_ENABLE_DEPRECATED_API
  extern                   function void set_local(uvm_resource_base rsrc) ;

  /*protected*/ uvm_component m_parent;
  protected     uvm_component m_children[string];
  protected     uvm_component m_children_by_handle[uvm_component];
  extern protected virtual function bit  m_add_child(uvm_component child);
  extern local     virtual function void m_set_full_name();

  extern                   function void do_resolve_bindings();
  extern                   function void do_flush();

  extern virtual           function void flush ();

  extern local             function void m_extract_name(string name ,
                                                        output string leaf ,
                                                        output string remainder );

  // overridden to disable
  extern virtual function uvm_object create (string name=""); 
  extern virtual function uvm_object clone  ();

  local uvm_tr_stream m_streams[string][string];
  local uvm_recorder m_tr_h[uvm_transaction];
  extern protected function int m_begin_tr (uvm_transaction tr,
                                                int parent_handle=0,
                                                string stream_name="main", string label="",
                                                string desc="", time begin_time=0);

  string m_name;

  typedef uvm_abstract_component_registry#(uvm_component, "uvm_component") type_id;
  `uvm_type_name_decl("uvm_component")

  protected uvm_event_pool event_pool;

  int unsigned recording_detail = UVM_NONE;
  extern         function void   do_print(uvm_printer printer);

  // Internal methods for setting up command line messaging stuff
  extern function void m_set_cl_msg_args;
  extern function void m_set_cl_verb;
  extern function void m_set_cl_action;
  extern function void m_set_cl_sev;
  extern function void m_apply_verbosity_settings(uvm_phase phase);

  // The verbosity settings may have a specific phase to start at. 
  // We will do this work in the phase_started callback. 

  typedef struct {
    string comp;
    string phase;
    time   offset;
    uvm_verbosity verbosity;
    string id;
  } m_verbosity_setting;

  m_verbosity_setting m_verbosity_settings[$];
  static m_verbosity_setting m_time_settings[$];

  // does the pre abort callback hierarchically
  extern /*local*/ function void m_do_pre_abort;

  // produce message for unsupported types from apply_config_settings
  uvm_resource_base m_unsupported_resource_base = null;
  extern function void m_unsupported_set_local(uvm_resource_base rsrc);

typedef struct  {
	string arg;
	string args[$];
	int unsigned used;
} uvm_cmdline_parsed_arg_t;

static uvm_cmdline_parsed_arg_t m_uvm_applied_cl_action[$];
static uvm_cmdline_parsed_arg_t m_uvm_applied_cl_sev[$];

endclass : uvm_component

`include "base/uvm_root.svh"

//------------------------------------------------------------------------------
// IMPLEMENTATION
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// CLASS- uvm_component
//
//------------------------------------------------------------------------------


// new
// ---

function uvm_component::new (string name, uvm_component parent);
  string error_str;
  uvm_root top;
  uvm_coreservice_t cs;

  super.new(name);

  // If uvm_top, reset name to "" so it doesn't show in full paths then return
  if (parent==null && name == "__top__") begin
    set_name(""); // *** VIRTUAL
    return;
  end

  cs = uvm_coreservice_t::get();
  top = cs.get_root();  

  // Check that we're not in or past end_of_elaboration
  begin
    uvm_phase bld;
    uvm_domain common;
    common = uvm_domain::get_common_domain();
    bld = common.find(uvm_build_phase::get());
    if (bld == null)
      uvm_report_fatal("COMP/INTERNAL",
                       "attempt to find build phase object failed",UVM_NONE);
    if (bld.get_state() == UVM_PHASE_DONE) begin
      uvm_report_fatal("ILLCRT", {"It is illegal to create a component ('",
                name,"' under '",
                (parent == null ? top.get_full_name() : parent.get_full_name()),
               "') after the build phase has ended."},
                       UVM_NONE);
    end
  end

  if (name == "") begin
    name.itoa(m_inst_count);
    name = {"COMP_", name};
  end

  if(parent == this) begin
    `uvm_fatal("THISPARENT", "cannot set the parent of a component to itself")
  end

  if (parent == null)
    parent = top;

  if(uvm_report_enabled(UVM_MEDIUM+1, UVM_INFO, "NEWCOMP"))
    `uvm_info("NEWCOMP", {"Creating ",
      (parent==top?"uvm_top":parent.get_full_name()),".",name},UVM_MEDIUM+1)

  if (parent.has_child(name) && this != parent.get_child(name)) begin
    if (parent == top) begin
      error_str = {"Name '",name,"' is not unique to other top-level ",
      "instances. If parent is a module, build a unique name by combining the ",
      "the module name and component name: $sformatf(\"\%m.\%s\",\"",name,"\")."};
      `uvm_fatal("CLDEXT",error_str)
    end
    else
      `uvm_fatal("CLDEXT",
        $sformatf("Cannot set '%s' as a child of '%s', %s",
                  name, parent.get_full_name(),
                  "which already has a child by that name."))
    return;
  end

  m_parent = parent;

  set_name(name); // *** VIRTUAL

  if (!m_parent.m_add_child(this))
    m_parent = null;

  event_pool = new("event_pool");

  m_domain = parent.m_domain;     // by default, inherit domains from parents
  
  // Now that inst name is established, reseed (if use_uvm_seeding is set)
  reseed();

  // Do local configuration settings
  if (!uvm_config_db #(uvm_bitstream_t)::get(this, "", "recording_detail", recording_detail))
        void'(uvm_config_db #(int)::get(this, "", "recording_detail", recording_detail));

  m_rh.set_name(get_full_name());
  set_report_verbosity_level(parent.get_report_verbosity_level());

  m_set_cl_msg_args();

endfunction


// m_add_child
// -----------

function bit uvm_component::m_add_child(uvm_component child);

  if (m_children.exists(child.get_name()) &&
      m_children[child.get_name()] != child) begin
      `uvm_warning("BDCLD",
        $sformatf("A child with the name '%0s' (type=%0s) already exists.",
           child.get_name(), m_children[child.get_name()].get_type_name()))
      return 0;
  end

  if (m_children_by_handle.exists(child)) begin
      `uvm_warning("BDCHLD",
        $sformatf("A child with the name '%0s' %0s %0s'",
                  child.get_name(),
                  "already exists in parent under name '",
                  m_children_by_handle[child].get_name()))
      return 0;
    end

  m_children[child.get_name()] = child;
  m_children_by_handle[child] = child;
  return 1;
endfunction



//------------------------------------------------------------------------------
//
// Hierarchy Methods
// 
//------------------------------------------------------------------------------


// get_children
// ------------

function void uvm_component::get_children(ref uvm_component children[$]);
  foreach(m_children[i]) 
    children.push_back(m_children[i]);
endfunction


// get_first_child
// ---------------

function int uvm_component::get_first_child(ref string name);
  return m_children.first(name);
endfunction


// get_next_child
// --------------

function int uvm_component::get_next_child(ref string name);
  return m_children.next(name);
endfunction


// get_child
// ---------

function uvm_component uvm_component::get_child(string name);
  if (m_children.exists(name))
    return m_children[name];
  `uvm_warning("NOCHILD",{"Component with name '",name,
       "' is not a child of component '",get_full_name(),"'"})
  return null;
endfunction


// has_child
// ---------

function int uvm_component::has_child(string name);
  return m_children.exists(name);
endfunction


// get_num_children
// ----------------

function int uvm_component::get_num_children();
  return m_children.num();
endfunction


// get_full_name
// -------------

function string uvm_component::get_full_name ();
  // Note- Implementation choice to construct full name once since the
  // full name may be used often for lookups.
  if(m_name == "")
    return get_name();
  else
    return m_name;
endfunction


// get_parent
// ----------

function uvm_component uvm_component::get_parent ();
  return  m_parent;
endfunction


// set_name
// --------

function void uvm_component::set_name (string name);
  if(m_name != "") begin
    `uvm_error("INVSTNM", $sformatf("It is illegal to change the name of a component. The component name will not be changed to \"%s\"", name))
    return;
  end
  super.set_name(name);
  m_set_full_name();

endfunction


// m_set_full_name
// ---------------

function void uvm_component::m_set_full_name();
  uvm_root top;
  if ($cast(top, m_parent) || m_parent==null)
    m_name = get_name();
  else 
    m_name = {m_parent.get_full_name(), ".", get_name()};

  foreach (m_children[c]) begin
    uvm_component tmp;
    tmp = m_children[c];
    tmp.m_set_full_name(); 
  end

endfunction


// lookup
// ------

function uvm_component uvm_component::lookup( string name );

  string leaf , remainder;
  uvm_component comp;
  uvm_root top;
  uvm_coreservice_t cs;
  cs = uvm_coreservice_t::get();
  top = cs.get_root();
   
  comp = this;
  
  m_extract_name(name, leaf, remainder);

  if (leaf == "") begin
    comp = top; // absolute lookup
    m_extract_name(remainder, leaf, remainder);
  end
  
  if (!comp.has_child(leaf)) begin
    `uvm_warning("Lookup Error", 
       $sformatf("Cannot find child %0s",leaf))
    return null;
  end

  if( remainder != "" )
    return comp.m_children[leaf].lookup(remainder);

  return comp.m_children[leaf];

endfunction


// get_depth
// ---------

function int unsigned uvm_component::get_depth();
  if(m_name == "") return 0;
  get_depth = 1;
  foreach(m_name[i]) 
    if(m_name[i] == ".") ++get_depth;
endfunction


// m_extract_name
// --------------

function void uvm_component::m_extract_name(input string name ,
                                            output string leaf ,
                                            output string remainder );
  int i , len;
  len = name.len();
  
  for( i = 0; i < name.len(); i++ ) begin  
    if( name[i] == "." ) begin
      break;
    end
  end

  if( i == len ) begin
    leaf = name;
    remainder = "";
    return;
  end

  leaf = name.substr( 0 , i - 1 );
  remainder = name.substr( i + 1 , len - 1 );

  return;
endfunction
  

// flush
// -----

function void uvm_component::flush();
  return;
endfunction


// do_flush  (flush_hier?)
// --------

function void uvm_component::do_flush();
  foreach( m_children[s] )
    m_children[s].do_flush();
  flush();
endfunction
  


//------------------------------------------------------------------------------
//
// Factory Methods
// 
//------------------------------------------------------------------------------


// create
// ------

function uvm_object  uvm_component::create (string name =""); 
  `uvm_error("ILLCRT",
    "create cannot be called on a uvm_component. Use create_component instead.")
  return null;
endfunction


// clone
// ------

function uvm_object  uvm_component::clone ();
  `uvm_error("ILLCLN", $sformatf("Attempting to clone '%s'.  Clone cannot be called on a uvm_component.  The clone target variable will be set to null.", get_full_name()))
  return null;
endfunction


// print_override_info
// -------------------

function void  uvm_component::print_override_info (string requested_type_name, 
                                                   string name="");
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();
  factory.debug_create_by_name(requested_type_name, get_full_name(), name);
endfunction


// create_component
// ----------------

function uvm_component uvm_component::create_component (string requested_type_name,
                                                        string name);
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();
  return factory.create_component_by_name(requested_type_name, get_full_name(),
                                          name, this);
endfunction


// create_object
// -------------

function uvm_object uvm_component::create_object (string requested_type_name,
                                                  string name="");
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();
  return factory.create_object_by_name(requested_type_name,
                                       get_full_name(), name);
endfunction


// set_type_override (static)
// -----------------

function void uvm_component::set_type_override (string original_type_name,
                                                string override_type_name,
                                                bit    replace=1);
   uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
   uvm_factory factory=cs.get_factory();
   factory.set_type_override_by_name(original_type_name,override_type_name, replace);
endfunction 


// set_type_override_by_type (static)
// -------------------------

function void uvm_component::set_type_override_by_type (uvm_object_wrapper original_type,
                                                        uvm_object_wrapper override_type,
                                                        bit    replace=1);
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();
   factory.set_type_override_by_type(original_type, override_type, replace);
endfunction 


// set_inst_override
// -----------------

function void  uvm_component::set_inst_override (string relative_inst_path,  
                                                 string original_type_name,
                                                 string override_type_name);
  string full_inst_path;
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();

  if (relative_inst_path == "")
    full_inst_path = get_full_name();
  else
    full_inst_path = {get_full_name(), ".", relative_inst_path};

  factory.set_inst_override_by_name(
                            original_type_name,
                            override_type_name,
                            full_inst_path);
endfunction 


// set_inst_override_by_type
// -------------------------

function void uvm_component::set_inst_override_by_type (string relative_inst_path,  
                                                        uvm_object_wrapper original_type,
                                                        uvm_object_wrapper override_type);
  string full_inst_path;
  uvm_coreservice_t cs = uvm_coreservice_t::get();                                                     
  uvm_factory factory=cs.get_factory();

  if (relative_inst_path == "")
    full_inst_path = get_full_name();
  else
    full_inst_path = {get_full_name(), ".", relative_inst_path};

  factory.set_inst_override_by_type(original_type, override_type, full_inst_path);

endfunction



//------------------------------------------------------------------------------
//
// Hierarchical report configuration interface
//
//------------------------------------------------------------------------------

// set_report_id_verbosity_hier
// -------------------------

function void uvm_component::set_report_id_verbosity_hier( string id, int verbosity);
  set_report_id_verbosity(id, verbosity);
  foreach( m_children[c] )
    m_children[c].set_report_id_verbosity_hier(id, verbosity);
endfunction


// set_report_severity_id_verbosity_hier
// ----------------------------------

function void uvm_component::set_report_severity_id_verbosity_hier( uvm_severity severity,
                                                                 string id,
                                                                 int verbosity);
  set_report_severity_id_verbosity(severity, id, verbosity);
  foreach( m_children[c] )
    m_children[c].set_report_severity_id_verbosity_hier(severity, id, verbosity);
endfunction


// set_report_severity_action_hier
// -------------------------

function void uvm_component::set_report_severity_action_hier( uvm_severity severity, 
                                                           uvm_action action);
  set_report_severity_action(severity, action);
  foreach( m_children[c] )
    m_children[c].set_report_severity_action_hier(severity, action);
endfunction


// set_report_id_action_hier
// -------------------------

function void uvm_component::set_report_id_action_hier( string id, uvm_action action);
  set_report_id_action(id, action);
  foreach( m_children[c] )
    m_children[c].set_report_id_action_hier(id, action);
endfunction


// set_report_severity_id_action_hier
// ----------------------------------

function void uvm_component::set_report_severity_id_action_hier( uvm_severity severity,
                                                                 string id,
                                                                 uvm_action action);
  set_report_severity_id_action(severity, id, action);
  foreach( m_children[c] )
    m_children[c].set_report_severity_id_action_hier(severity, id, action);
endfunction


// set_report_severity_file_hier
// -----------------------------

function void uvm_component::set_report_severity_file_hier( uvm_severity severity,
                                                            UVM_FILE file);
  set_report_severity_file(severity, file);
  foreach( m_children[c] )
    m_children[c].set_report_severity_file_hier(severity, file);
endfunction


// set_report_default_file_hier
// ----------------------------

function void uvm_component::set_report_default_file_hier( UVM_FILE file);
  set_report_default_file(file);
  foreach( m_children[c] )
    m_children[c].set_report_default_file_hier(file);
endfunction


// set_report_id_file_hier
// -----------------------
  
function void uvm_component::set_report_id_file_hier( string id, UVM_FILE file);
  set_report_id_file(id, file);
  foreach( m_children[c] )
    m_children[c].set_report_id_file_hier(id, file);
endfunction


// set_report_severity_id_file_hier
// --------------------------------

function void uvm_component::set_report_severity_id_file_hier ( uvm_severity severity,
                                                                string id,
                                                                UVM_FILE file);
  set_report_severity_id_file(severity, id, file);
  foreach( m_children[c] )
    m_children[c].set_report_severity_id_file_hier(severity, id, file);
endfunction


// set_report_verbosity_level_hier
// -------------------------------

function void uvm_component::set_report_verbosity_level_hier(int verbosity);
  set_report_verbosity_level(verbosity);
  foreach( m_children[c] )
    m_children[c].set_report_verbosity_level_hier(verbosity);
endfunction  



//------------------------------------------------------------------------------
//
// Phase interface 
//
//------------------------------------------------------------------------------


// phase methods
//--------------
// these are prototypes for the methods to be implemented in user components
// build_phase() has a default implementation, the others have an empty default

`ifdef UVM_ENABLE_DEPRECATED_API
  `define M_UVM_OVM_PHASE_WARN_AND_CALL(NAME) \
    begin \
      static bit warned; \
      if (!warned) \
        `uvm_warning("UVM/DEPRECATED/COMP/OVM_PHASES", {"The library is calling the deprecated uvm_component::", `"NAME`", " method because UVM_ENABLE_DEPRECATED_API is defined.  Usage of this deprecated method by the user may lead to unexpected behavior.  Users should use uvm_component::", `"NAME`", "_phase()."}) \
      warned = 1; \
      NAME(); \
    end
`endif // UVM_ENABLE_DEPRECATED_API

function void uvm_component::build_phase(uvm_phase phase);
  m_build_done = 1;
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(build)
`else // !UVM_ENABLE_DEPRECATED_API
  if (use_automatic_config())
    apply_config_settings(print_config_matches);
`endif // UVM_ENABLED_DEPRECATED_API  
endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
// Backward compatibility build function

function void uvm_component::build();
  m_build_done = 1;
  if (use_automatic_config())
    apply_config_settings(print_config_matches);
endfunction // build
`endif // UVM_ENABLE_DEPRECATED_API

// these phase methods are common to all components in UVM. For backward
// compatibility, they call the old style name (without the _phse)

function void uvm_component::connect_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(connect)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

function void uvm_component::start_of_simulation_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(start_of_simulation)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

function void uvm_component::end_of_elaboration_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(end_of_elaboration)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

task          uvm_component::run_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(run)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endtask

function void uvm_component::extract_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(extract)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

function void uvm_component::check_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(check)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

function void uvm_component::report_phase(uvm_phase phase);
`ifdef UVM_ENABLE_DEPRECATED_API
  `M_UVM_OVM_PHASE_WARN_AND_CALL(report)
`endif // UVM_ENABLE_DEPRECATED_API
  return; 
endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
  `undef M_UVM_OVM_PHASE_WARN_AND_CALL
`endif

function void uvm_component::final_phase(uvm_phase phase);         return; endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
// These are the old style phase names. In order for runtime phase names
// to not conflict with user names, the _phase postfix was added.

function void uvm_component::connect();             return; endfunction
function void uvm_component::start_of_simulation(); return; endfunction
function void uvm_component::end_of_elaboration();  return; endfunction
task          uvm_component::run();                 return; endtask
function void uvm_component::extract();             return; endfunction
function void uvm_component::check();               return; endfunction
function void uvm_component::report();              return; endfunction
`endif // UVM_ENABLE_DEPRECATED_API

// these runtime phase methods are only called if a set_domain() is done

task uvm_component::pre_reset_phase(uvm_phase phase);      return; endtask
task uvm_component::reset_phase(uvm_phase phase);          return; endtask
task uvm_component::post_reset_phase(uvm_phase phase);     return; endtask
task uvm_component::pre_configure_phase(uvm_phase phase);  return; endtask
task uvm_component::configure_phase(uvm_phase phase);      return; endtask
task uvm_component::post_configure_phase(uvm_phase phase); return; endtask
task uvm_component::pre_main_phase(uvm_phase phase);       return; endtask
task uvm_component::main_phase(uvm_phase phase);           return; endtask
task uvm_component::post_main_phase(uvm_phase phase);      return; endtask
task uvm_component::pre_shutdown_phase(uvm_phase phase);   return; endtask
task uvm_component::shutdown_phase(uvm_phase phase);       return; endtask
task uvm_component::post_shutdown_phase(uvm_phase phase);  return; endtask


//------------------------------
// current phase convenience API
//------------------------------


// phase_started
// -------------
// phase_started() and phase_ended() are extra callbacks called at the
// beginning and end of each phase, respectively.  Since they are
// called for all phases the phase is passed in as an argument so the
// extender can decide what to do, if anything, for each phase.

function void uvm_component::phase_started(uvm_phase phase);
endfunction

// phase_ended
// -----------

function void uvm_component::phase_ended(uvm_phase phase);
endfunction


// phase_ready_to_end
// ------------------

function void uvm_component::phase_ready_to_end (uvm_phase phase);
endfunction

//------------------------------
// phase / schedule / domain API
//------------------------------
// methods for VIP creators and integrators to use to set up schedule domains
// - a schedule is a named, organized group of phases for a component base type
// - a domain is a named instance of a schedule in the master phasing schedule


// define_domain
// -------------

function void uvm_component::define_domain(uvm_domain domain);
  uvm_phase schedule;
  //schedule = domain.find(uvm_domain::get_uvm_schedule());
  schedule = domain.find_by_name("uvm_sched");
  if (schedule == null) begin
    uvm_domain common;
    schedule = new("uvm_sched", UVM_PHASE_SCHEDULE);
    uvm_domain::add_uvm_phases(schedule);
    domain.add(schedule);
    common = uvm_domain::get_common_domain();
    if (common.find(domain,0) == null)
      common.add(domain,.with_phase(uvm_run_phase::get()));
  end

endfunction


// set_domain
// ----------
// assigns this component [tree] to a domain. adds required schedules into graph
// If called from build, ~hier~ won't recurse into all chilren (which don't exist yet)
// If we have components inherit their parent's domain by default, then ~hier~
// isn't needed and we need a way to prevent children from inheriting this component's domain

function void uvm_component::set_domain(uvm_domain domain, int hier=1);

  // build and store the custom domain
  m_domain = domain;
  define_domain(domain);
  if (hier)
    foreach (m_children[c])
      m_children[c].set_domain(domain);
endfunction

// get_domain
// ----------
//
function uvm_domain uvm_component::get_domain();
  return m_domain;
endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
// set_phase_imp
// -------------

function void uvm_component::set_phase_imp(uvm_phase phase, uvm_phase imp, int hier=1);
  m_phase_imps[phase] = imp;
  if (hier)
    foreach (m_children[c])
      m_children[c].set_phase_imp(phase,imp,hier);
endfunction
`endif

//--------------------------
// phase runtime control API
//--------------------------

// suspend
// -------

task uvm_component::suspend();
   `uvm_warning("COMP/SPND/UNIMP", "suspend() not implemented")
endtask


// resume
// ------

task uvm_component::resume();
   `uvm_warning("COMP/RSUM/UNIMP", "resume() not implemented")
endtask


// resolve_bindings
// ----------------

function void uvm_component::resolve_bindings();
  return;
endfunction


// do_resolve_bindings
// -------------------

function void uvm_component::do_resolve_bindings();
  foreach( m_children[s] )
    m_children[s].do_resolve_bindings();
  resolve_bindings();
endfunction



//------------------------------------------------------------------------------
//
// Recording interface
//
//------------------------------------------------------------------------------

// accept_tr
// ---------

function void uvm_component::accept_tr (uvm_transaction tr,
                                        time accept_time=0);
  uvm_event#(uvm_object) e;
  
  if(tr == null)
    return;
  
  tr.accept_tr(accept_time);
  do_accept_tr(tr);
  e = event_pool.get("accept_tr");
  if(e!=null) 
    e.trigger();
endfunction

// begin_tr
// --------

function int uvm_component::begin_tr (uvm_transaction tr,
                                          string stream_name="main",
                                          string label="",
                                          string desc="",
                                          time begin_time=0,
                                          int parent_handle=0);
   return m_begin_tr(tr, parent_handle, stream_name, label, desc, begin_time);
endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
// begin_child_tr
// --------------

function int uvm_component::begin_child_tr (uvm_transaction tr,
                                                int parent_handle=0,
                                                string stream_name="main",
                                                string label="",
                                                string desc="",
                                                time begin_time=0);
  static bit have_been_warned;
  if(!have_been_warned) begin
    uvm_report_warning("UVM/DEPRECATED/COMP/BCT", "The deprecated uvm_component::begin_child_tr method has been called.  Attempting to compile without UVM_ENABLE_DEPRECATED_API defined will fail. Use begin_tr instead");
    have_been_warned = 1;
  end
                                                
  return m_begin_tr(tr, parent_handle, stream_name, label, desc, begin_time);
endfunction
`endif // UVM_ENABLE_DEPRECATED_API

`ifdef UVM_ENABLE_DEPRECATED_API     
// m_get_tr_database
// ---------------------
   function uvm_tr_database uvm_component::m_get_tr_database();
     static bit have_been_warned;
     if(!have_been_warned) begin
       `uvm_warning("UVM/DEPRECATED/COMP/M_GET_TR_DB", "uvm_component::m_get_tr_database() is deprecated, use get_tr_database() in its place")
       have_been_warned = 1;
     end
     return get_tr_database();
   endfunction : m_get_tr_database
`endif // UVM_ENABLE_DEPRECATED_API  

// get_tr_database
// ---------------------
   function uvm_tr_database uvm_component::get_tr_database();
     if (tr_database == null) begin
       uvm_coreservice_t cs = uvm_coreservice_t::get();
       tr_database = cs.get_default_tr_database();
     end
     return tr_database;
   endfunction : get_tr_database

// set_tr_database
// ---------------------
   function void uvm_component::set_tr_database(uvm_tr_database db);
      tr_database = db;
   endfunction : set_tr_database
 
   
// get_tr_stream
// ------------
function uvm_tr_stream uvm_component::get_tr_stream( string name,
                                                      string stream_type_name="" );
   uvm_tr_database db = get_tr_database();
   if (!m_streams.exists(name) || !m_streams[name].exists(stream_type_name))
     m_streams[name][stream_type_name] = db.open_stream(name, this.get_full_name(), stream_type_name);
   return m_streams[name][stream_type_name];
endfunction : get_tr_stream

// free_tr_stream
// --------------
function void uvm_component::free_tr_stream(uvm_tr_stream stream);
   // Check the null case...
   if (stream == null)
     return;

   // Then make sure this name/type_name combo exists
   if (!m_streams.exists(stream.get_name()) ||
       !m_streams[stream.get_name()].exists(stream.get_stream_type_name()))
     return;

   // Then make sure this name/type_name combo is THIS stream
   if (m_streams[stream.get_name()][stream.get_stream_type_name()] != stream)
     return;

   // Then delete it from the arrays
   m_streams[stream.get_name()].delete(stream.get_type_name());
   if (m_streams[stream.get_name()].size() == 0)
     m_streams.delete(stream.get_name());

   // Finally, free the stream if necessary
   if (stream.is_open() || stream.is_closed()) begin
      stream.free();
   end
endfunction : free_tr_stream
   
// m_begin_tr
// ----------

function int uvm_component::m_begin_tr (uvm_transaction tr,
                                            int parent_handle=0,
                                            string stream_name="main",
                                            string label="",
                                            string desc="",
                                            time begin_time=0);
   uvm_event#(uvm_object) e;
   string    name;
   string    kind;
   uvm_tr_database db;
   int   handle, link_handle;
   uvm_tr_stream stream;
   uvm_recorder recorder, parent_recorder, link_recorder;

   if (tr == null)
     return 0;

   db = get_tr_database();
   
   if (parent_handle != 0)
     parent_recorder = uvm_recorder::get_recorder_from_handle(parent_handle);
   
   if (parent_recorder == null) begin
      uvm_sequence_item seq;
      if ($cast(seq,tr)) begin
         uvm_sequence_base parent_seq = seq.get_parent_sequence();
         if (parent_seq != null) begin
            parent_recorder = parent_seq.m_tr_recorder;
         end
      end
   end
   
   if(parent_recorder != null) begin
      link_handle = tr.begin_child_tr(begin_time, parent_recorder.get_handle());
   end
   else begin
      link_handle = tr.begin_tr(begin_time);
   end

   if (link_handle != 0)
     link_recorder = uvm_recorder::get_recorder_from_handle(link_handle);

   
   if (tr.get_name() != "")
     name = tr.get_name();
   else
     name = tr.get_type_name();
   
   if (uvm_verbosity'(recording_detail) != UVM_NONE) begin
      if (stream_name == "")
        stream_name = "main";

      stream = get_tr_stream(stream_name, "TVM");

      if (stream != null ) begin
         kind = (parent_recorder == null) ? "Begin_No_Parent, Link" : "Begin_End, Link";
         
         recorder = stream.open_recorder(name, begin_time, kind);

         if (recorder != null) begin
            if (label != "") 
              recorder.record_string("label", label);
            if (desc != "")
              recorder.record_string("desc", desc);
         
            if (parent_recorder != null) begin
               tr_database.establish_link(uvm_parent_child_link::get_link(parent_recorder,
                                                                          recorder));
            end
            
            if (link_recorder != null) begin
               tr_database.establish_link(uvm_related_link::get_link(recorder,
                                                                     link_recorder));
            end
            m_tr_h[tr] = recorder;
         end
      end
      
      handle = (recorder == null) ? 0 : recorder.get_handle();
      do_begin_tr(tr, stream_name, handle); 
      
   end
   
   e = event_pool.get("begin_tr");
   if (e!=null) 
     e.trigger(tr);
   
   return handle;
   
endfunction


// end_tr
// ------

function void uvm_component::end_tr (uvm_transaction tr,
                                     time end_time=0,
                                     bit free_handle=1);
   uvm_event#(uvm_object) e;
   uvm_recorder recorder;

   if (tr == null)
     return;

   tr.end_tr(end_time,free_handle);

   if (uvm_verbosity'(recording_detail) != UVM_NONE) begin

      if (m_tr_h.exists(tr)) begin

         recorder = m_tr_h[tr];

         do_end_tr(tr, recorder.get_handle()); // callback

         m_tr_h.delete(tr);

         tr.record(recorder);

         recorder.close(end_time);

         if (free_handle)
           recorder.free();
            
      end
      else begin
         do_end_tr(tr, 0); // callback
      end
      
   end

   e = event_pool.get("end_tr");
   if(e!=null) 
     e.trigger();

endfunction


// record_error_tr
// ---------------

function int uvm_component::record_error_tr (string stream_name="main",
                                                 uvm_object info=null,
                                                 string label="error_tr",
                                                 string desc="",
                                                 time   error_time=0,
                                                 bit    keep_active=0);
   uvm_recorder recorder;
   string etype;
   uvm_tr_stream stream;
   int handle;
   
   if(keep_active) etype = "Error, Link";
   else etype = "Error";
   
   if(error_time == 0) error_time = $realtime;

   if (stream_name == "")
     stream_name = "main";

   stream = get_tr_stream(stream_name, "TVM");
   
   handle = 0;
   if (stream != null) begin

      recorder = stream.open_recorder(label,
                                    error_time,
                                    etype);

      if (recorder != null) begin
         if (label != "")
           recorder.record_string("label", label);
         if (desc != "")
           recorder.record_string("desc", desc);
         if (info!=null)
           info.record(recorder);

         recorder.close(error_time);

         if (keep_active == 0) begin
            recorder.free();
         end
         else begin
            handle = recorder.get_handle();
         end
      end // if (recorder != null)
   end // if (stream != null)
   
   return handle;
endfunction


// record_event_tr
// ---------------

function int uvm_component::record_event_tr (string stream_name="main",
                                                 uvm_object info=null,
                                                 string label="event_tr",
                                                 string desc="",
                                                 time   event_time=0,
                                                 bit    keep_active=0);
   uvm_recorder recorder;
   string etype;
   int handle;
   uvm_tr_stream stream;
   
  if(keep_active) etype = "Event, Link";
  else etype = "Event";
   
   if(event_time == 0) event_time = $realtime;
   
   if (stream_name == "")
     stream_name = "main";
   
   stream = get_tr_stream(stream_name, "TVM");

   handle = 0;
   if (stream != null) begin
      recorder = stream.open_recorder(label,
                                    event_time,
                                    etype);

      if (recorder != null) begin
         if (label != "")
           recorder.record_string("label", label);
         if (desc != "")
           recorder.record_string("desc", desc);
         if (info!=null)
           info.record(recorder);
                        
         recorder.close(event_time);

         if (keep_active == 0) begin
            recorder.free();
         end
         else begin
            handle = recorder.get_handle();
         end
      end // if (recorder != null)
   end // if (stream != null)

   return handle;
endfunction

// do_accept_tr
// ------------

function void uvm_component::do_accept_tr (uvm_transaction tr);
  return;
endfunction


// do_begin_tr
// -----------

function void uvm_component::do_begin_tr (uvm_transaction tr,
                                          string stream_name,
                                          int tr_handle);
  return;
endfunction


// do_end_tr
// ---------

function void uvm_component::do_end_tr (uvm_transaction tr,
                                        int tr_handle);
  return;
endfunction


//------------------------------------------------------------------------------
//
// Configuration interface
//
//------------------------------------------------------------------------------


function string uvm_component::massage_scope(string scope);

  // uvm_top
  if(scope == "")
    return "^$";

  if(scope == "*")
    return {get_full_name(), ".*"};

  // absolute path to the top-level test
  if(scope == "uvm_test_top")
    return "uvm_test_top";

  // absolute path to uvm_root
  if(scope[0] == ".")
    return {get_full_name(), scope};

  return {get_full_name(), ".", scope};

endfunction


`ifdef UVM_ENABLE_DEPRECATED_API
// check_config_usage
// ------------------

function void uvm_component::check_config_usage ( bit recurse=1 );
  uvm_resource_pool rp = uvm_resource_pool::get();
  uvm_queue#(uvm_resource_base) rq;

  rq = rp.find_unused_resources();

  if(rq.size() == 0)
    return;

  uvm_report_info("CFGNRD"," ::: The following resources have at least one write and no reads :::",UVM_INFO);
  rp.print_resources(rq, 1);
endfunction
`endif // UVM_ENABLE_DEPRECATED_API

// use_automatic_config
// --------------------
function bit uvm_component::use_automatic_config();
  return 1;
endfunction      
   
// apply_config_settings
// ---------------------

function void uvm_component::apply_config_settings (bit verbose=0);

  uvm_resource_pool rp = uvm_resource_pool::get();
  uvm_queue#(uvm_resource_base) rq;
  uvm_resource_base r;

  // The following is VERY expensive. Needs refactoring. Should
  // get config only for the specific field names in 'field_array'.
  // That's because the resource pool is organized first by field name.
  // Can further optimize by encoding the value for each 'field_array' 
  // entry to indicate string, uvm_bitstream_t, or object. That way,
  // we call 'get' for specific fields of specific types rather than
  // the search-and-cast approach here.
  rq = rp.lookup_scope(get_full_name());
  rp.sort_by_precedence(rq);

  // rq is in precedence order now, so we have to go through in reverse
  // order to do the settings.
  for(int i=rq.size()-1; i>=0; --i) begin
    r = rq.get(i);

    if(verbose)
      uvm_report_info("CFGAPL",$sformatf("applying configuration to field %s", r.get_name()),UVM_NONE);

    set_local(r);

  end

endfunction


// print_config
// ------------

function void uvm_component::print_config(bit recurse = 0, audit = 0);

  uvm_resource_pool rp = uvm_resource_pool::get();

  uvm_report_info("CFGPRT","visible resources:",UVM_INFO);
  rp.print_resources(rp.lookup_scope(get_full_name()), audit);

  if(recurse) begin
    uvm_component c;
    foreach(m_children[name]) begin
      c = m_children[name];
      c.print_config(recurse, audit);
    end
  end

endfunction

`ifdef UVM_ENABLE_DEPRECATED_API
// print_config_settings
// ---------------------

function void uvm_component::print_config_settings (string field="",
                                                    uvm_component comp=null,
                                                    bit recurse=0);
  static bit have_been_warned;
  if(!have_been_warned) begin
    uvm_report_warning("UVM/DEPRECATED/COMP/PCS", "The deprecated uvm_component::print_config_settings method has been called.  Attempting to compile without UVM_ENABLE_DEPRECATED_API defined will fail.  Use uvm_component::print_config() instead.");
    have_been_warned = 1;
  end

  print_config(recurse, 1);
endfunction
`endif // UVM_ENABLE_DEPRECATED_API

// print_config_with_audit
// -----------------------

function void uvm_component::print_config_with_audit(bit recurse = 0);
  print_config(recurse, 1);
endfunction


// do_print (override)
// --------

function void uvm_component::do_print(uvm_printer printer);
  super.do_print(printer);

  // It is printed only if its value is other than the default (UVM_NONE)
  if(uvm_verbosity'(recording_detail) != UVM_NONE)
    case (recording_detail)
      UVM_LOW : printer.print_generic("recording_detail", "uvm_verbosity", 
        $bits(recording_detail), "UVM_LOW");
      UVM_MEDIUM : printer.print_generic("recording_detail", "uvm_verbosity", 
        $bits(recording_detail), "UVM_MEDIUM");
      UVM_HIGH : printer.print_generic("recording_detail", "uvm_verbosity", 
        $bits(recording_detail), "UVM_HIGH");
      UVM_FULL : printer.print_generic("recording_detail", "uvm_verbosity", 
        $bits(recording_detail), "UVM_FULL");
      default : printer.print_field_int("recording_detail", recording_detail, 
        $bits(recording_detail), UVM_DEC, , "integral");
    endcase

endfunction


`ifdef UVM_ENABLE_DEPRECATED_API
// set_int_local (override)
// -------------

function void uvm_component::set_int_local (string field_name,
                             uvm_bitstream_t value,
                             bit recurse=1);

  //call the super function to get child recursion and any registered fields
  super.set_int_local(field_name, value, recurse);

  //set the local properties
  if(uvm_is_match(field_name, "recording_detail"))
    recording_detail = value;

endfunction

`endif // UVM_ENABLE_DEPRECATED_API


// set_local (override)
// ---------

function void uvm_component::set_local(uvm_resource_base rsrc) ;

  bit success;

  //set the local properties
  if((rsrc != null) && (rsrc.get_name() == "recording_detail")) begin
    `uvm_resource_builtin_int_read(success,
                                   rsrc,
                                   recording_detail,
                                   this)
  end

  if (!success)
    super.set_local(rsrc);
  
endfunction


// m_unsupported_set_local (override)
// ----------------------

function void uvm_component::m_unsupported_set_local(uvm_resource_base rsrc);

  m_unsupported_resource_base = rsrc;
endfunction


// Internal methods for setting messagin parameters from command line switches

typedef class uvm_cmdline_processor;


// m_set_cl_msg_args
// -----------------

function void uvm_component::m_set_cl_msg_args;
  string s_;
  process p_;
	
  p_=process::self();
  if(p_!=null) 
	  s_=p_.get_randstate();
  else
	  `uvm_warning("UVM","run_test() invoked from a non process context")

  m_set_cl_verb();
  m_set_cl_action();
  m_set_cl_sev();
  
  if(p_!=null) 
	  p_.set_randstate(s_);
endfunction


// m_set_cl_verb
// -------------
function void uvm_component::m_set_cl_verb;
  // _ALL_ can be used for ids
  // +uvm_set_verbosity=<comp>,<id>,<verbosity>,<phase|time>,<offset>
  // +uvm_set_verbosity=uvm_test_top.env0.agent1.*,_ALL_,UVM_FULL,time,800
 
  static string values[$];
  static bit first = 1;
  string args[$];
  uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();
  uvm_root top;
  uvm_coreservice_t cs;
	
  cs = uvm_coreservice_t::get();
  top = cs.get_root();

  if(first) begin
	  string t[$];
	  m_verbosity_setting setting;
      void'(clp.get_arg_values("+uvm_set_verbosity=",values));
      foreach(values[i]) begin
	    args.delete();
    	uvm_split_string(values[i], ",", args);  
	   	if(((args.size() == 4) || (args.size() == 5)) &&  (clp.m_convert_verb(args[2], setting.verbosity) == 1)  )
		   	t.push_back(values[i]);
	   	else
		   	uvm_report_warning("UVM/CMDLINE",$sformatf("argument %s not recognized and therefore dropped",values[i]));
      end
      
	  values=t;
	  first=0;
  end	

  foreach(values[i]) begin
    m_verbosity_setting setting;
    args.delete();
    uvm_split_string(values[i], ",", args);

	begin
      setting.comp = args[0];
      setting.id = args[1];
      void'(clp.m_convert_verb(args[2],setting.verbosity));
      setting.phase = args[3];
      setting.offset = 0;
      if(args.size() == 5) setting.offset = args[4].atoi();
      if((setting.phase == "time") && (this == top)) begin
        m_time_settings.push_back(setting);
      end
  
      if (uvm_is_match(setting.comp, get_full_name()) ) begin
        if((setting.phase == "" || setting.phase == "build" || setting.phase == "time") && 
           (setting.offset == 0) ) 
        begin
          if(setting.id == "_ALL_") 
            set_report_verbosity_level(setting.verbosity);
          else
            set_report_id_verbosity(setting.id, setting.verbosity);
        end
        else begin
          if(setting.phase != "time") begin
            m_verbosity_settings.push_back(setting);
          end
        end
      end
    end
  end
  // do time based settings
  if(this == top) begin
    fork begin
      time last_time = 0;
      if (m_time_settings.size() > 0)
        m_time_settings.sort() with ( item.offset );
      foreach(m_time_settings[i]) begin
        uvm_component comps[$];
        top.find_all(m_time_settings[i].comp,comps);
        #(m_time_settings[i].offset - last_time);
        last_time = m_time_settings[i].offset;
        if(m_time_settings[i].id == "_ALL_") begin
           foreach(comps[j]) begin
             comps[j].set_report_verbosity_level(m_time_settings[i].verbosity);
           end
        end
        else begin
          foreach(comps[j]) begin
            comps[j].set_report_id_verbosity(m_time_settings[i].id, m_time_settings[i].verbosity);
          end
        end
      end
    end join_none // fork begin
  end
endfunction

// m_set_cl_action
// ---------------

function void uvm_component::m_set_cl_action;
  // _ALL_ can be used for ids or severities
  // +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>
  // +uvm_set_action=uvm_test_top.env0.*,_ALL_,UVM_ERROR,UVM_NO_ACTION
	
  static bit initialized = 0;
  uvm_severity sev;
  uvm_action action;
  uvm_cmdline_processor uvm_cmdline_proc = uvm_cmdline_processor::get_inst();

  if(!initialized) begin
	string values[$];
    void'(uvm_cmdline_proc.get_arg_values("+uvm_set_action=",values));
	foreach(values[idx]) begin
		uvm_cmdline_parsed_arg_t t;
		string args[$];
	 	uvm_split_string(values[idx], ",", args);	

		if(args.size() != 4) begin
	   		`uvm_warning("INVLCMDARGS", $sformatf("+uvm_set_action requires 4 arguments, but %0d given for command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args.size(), values[idx]))
	   		continue;
   		end
   		if((args[2] != "_ALL_") && !uvm_string_to_severity(args[2], sev)) begin
	   		`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args[2], values[idx]))
	   		continue;
   		end
   		if(!uvm_string_to_action(args[3], action)) begin
	   		`uvm_warning("INVLCMDARGS", $sformatf("Bad action argument \"%s\" given to command +uvm_set_action=%s, Usage: +uvm_set_action=<comp>,<id>,<severity>,<action[|action]>", args[3], values[idx]))
	   		continue;
   		end
   		t.args=args;   
   		t.arg=values[idx];
   		m_uvm_applied_cl_action.push_back(t);
	end 
	initialized=1;
  end
  
  foreach(m_uvm_applied_cl_action[i]) begin
	string args[$] = m_uvm_applied_cl_action[i].args;

	if (!uvm_is_match(args[0], get_full_name()) ) continue; 
	
	void'(uvm_string_to_severity(args[2], sev));
	void'(uvm_string_to_action(args[3], action));
	
    m_uvm_applied_cl_action[i].used++;
    if(args[1] == "_ALL_") begin
      if(args[2] == "_ALL_") begin
        set_report_severity_action(UVM_INFO, action);
        set_report_severity_action(UVM_WARNING, action);
        set_report_severity_action(UVM_ERROR, action);
        set_report_severity_action(UVM_FATAL, action);
      end
      else begin
        set_report_severity_action(sev, action);
      end
    end
    else begin
      if(args[2] == "_ALL_") begin
        set_report_id_action(args[1], action);
      end
      else begin
        set_report_severity_id_action(sev, args[1], action);
      end
    end
  end

endfunction


// m_set_cl_sev
// ------------

function void uvm_component::m_set_cl_sev;
  // _ALL_ can be used for ids or severities
  //  +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>
  //  +uvm_set_severity=uvm_test_top.env0.*,BAD_CRC,UVM_ERROR,UVM_WARNING

  static bit initialized;
  uvm_severity orig_sev, sev;
  uvm_cmdline_processor uvm_cmdline_proc = uvm_cmdline_processor::get_inst();

  if(!initialized) begin
	string values[$];
    void'(uvm_cmdline_proc.get_arg_values("+uvm_set_severity=",values));
	foreach(values[idx]) begin
		uvm_cmdline_parsed_arg_t t;
		string args[$];
	 	uvm_split_string(values[idx], ",", args);	
	 	if(args.size() != 4) begin
      		`uvm_warning("INVLCMDARGS", $sformatf("+uvm_set_severity requires 4 arguments, but %0d given for command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args.size(), values[idx]))
      		continue;
    	end
    	if(args[2] != "_ALL_" && !uvm_string_to_severity(args[2], orig_sev)) begin
      		`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args[2], values[idx]))
      		continue;
    	end
    	if(!uvm_string_to_severity(args[3], sev)) begin
      		`uvm_warning("INVLCMDARGS", $sformatf("Bad severity argument \"%s\" given to command +uvm_set_severity=%s, Usage: +uvm_set_severity=<comp>,<id>,<orig_severity>,<new_severity>", args[3], values[idx]))
      		continue;
    	end
	 	
	 	t.args=args;
    	t.arg=values[idx];
	 	m_uvm_applied_cl_sev.push_back(t);
	end	
	initialized=1;
  end

  foreach(m_uvm_applied_cl_sev[i]) begin
  	string args[$]=m_uvm_applied_cl_sev[i].args;

    if (!uvm_is_match(args[0], get_full_name()) ) continue; 
	    
	void'(uvm_string_to_severity(args[2], orig_sev));
	void'(uvm_string_to_severity(args[3], sev));   	
    m_uvm_applied_cl_sev[i].used++;
    if(args[1] == "_ALL_" && args[2] == "_ALL_") begin
      set_report_severity_override(UVM_INFO,sev);
      set_report_severity_override(UVM_WARNING,sev);
      set_report_severity_override(UVM_ERROR,sev);
      set_report_severity_override(UVM_FATAL,sev);
    end
    else if(args[1] == "_ALL_") begin
      set_report_severity_override(orig_sev,sev);
    end
    else if(args[2] == "_ALL_") begin
      set_report_severity_id_override(UVM_INFO,args[1],sev);
      set_report_severity_id_override(UVM_WARNING,args[1],sev);
      set_report_severity_id_override(UVM_ERROR,args[1],sev);
      set_report_severity_id_override(UVM_FATAL,args[1],sev);
    end
    else begin
      set_report_severity_id_override(orig_sev,args[1],sev);
    end
  end
endfunction


// m_apply_verbosity_settings
// --------------------------

function void uvm_component::m_apply_verbosity_settings(uvm_phase phase);
  int i;
  while (i < m_verbosity_settings.size()) begin
    if(phase.get_name() == m_verbosity_settings[i].phase) begin
      if( m_verbosity_settings[i].offset == 0 ) begin
          if(m_verbosity_settings[i].id == "_ALL_") 
            set_report_verbosity_level(m_verbosity_settings[i].verbosity);
          else 
            set_report_id_verbosity(m_verbosity_settings[i].id, m_verbosity_settings[i].verbosity);
      end
      else begin
        process p = process::self();
        string p_rand = p.get_randstate();
        fork begin
          m_verbosity_setting setting = m_verbosity_settings[i];
          #setting.offset;
          if(setting.id == "_ALL_") 
            set_report_verbosity_level(setting.verbosity);
          else 
            set_report_id_verbosity(setting.id, setting.verbosity);
        end join_none
        p.set_randstate(p_rand);
      end
      // Remove after use
      m_verbosity_settings.delete(i);
      continue;
    end // if (phase.get_name() == m_verbosity_settings[i].phase)
    i++;
  end // while (i < m_verbosity_settings.size())
endfunction


// m_do_pre_abort
// --------------

function void uvm_component::m_do_pre_abort;
  foreach(m_children[i])
    m_children[i].m_do_pre_abort(); 
  pre_abort(); 
endfunction
