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

typedef class uvm_test_done_objection;
typedef class uvm_sequencer_base;

typedef class uvm_domain;
typedef class uvm_task_phase;

typedef class uvm_phase_cb;


   
//------------------------------------------------------------------------------
//
// Section: Phasing Definition classes
//
//------------------------------------------------------------------------------
//
// The following class are used to specify a phase and its implied functionality.
//
  
//------------------------------------------------------------------------------
//
// Class: uvm_phase
//
//------------------------------------------------------------------------------
//
// This base class defines everything about a phase: behavior, state, and context.
//
// To define behavior, it is extended by UVM or the user to create singleton
// objects which capture the definition of what the phase does and how it does it.
// These are then cloned to produce multiple nodes which are hooked up in a graph
// structure to provide context: which phases follow which, and to hold the state
// of the phase throughout its lifetime.
// UVM provides default extensions of this class for the standard runtime phases.
// VIP Providers can likewise extend this class to define the phase functor for a
// particular component context as required.
//
// This base class defines everything about a phase: behavior, state, and context.
//
// To define behavior, it is extended by UVM or the user to create singleton
// objects which capture the definition of what the phase does and how it does it.
// These are then cloned to produce multiple nodes which are hooked up in a graph
// structure to provide context: which phases follow which, and to hold the state
// of the phase throughout its lifetime.
// UVM provides default extensions of this class for the standard runtime phases.
// VIP Providers can likewise extend this class to define the phase functor for a
// particular component context as required.
//
// *Phase Definition*
//
// Singleton instances of those extensions are provided as package variables.
// These instances define the attributes of the phase (not what state it is in)
// They are then cloned into schedule nodes which point back to one of these
// implementations, and calls its virtual task or function methods on each
// participating component.
// It is the base class for phase functors, for both predefined and
// user-defined phases. Per-component overrides can use a customized imp.
//
// To create custom phases, do not extend uvm_phase directly: see the
// three predefined extended classes below which encapsulate behavior for
// different phase types: task, bottom-up function and top-down function.
//
// Extend the appropriate one of these to create a uvm_YOURNAME_phase class
// (or YOURPREFIX_NAME_phase class) for each phase, containing the default
// implementation of the new phase, which must be a uvm_component-compatible
// delegate, and which may be a ~null~ implementation. Instantiate a singleton
// instance of that class for your code to use when a phase handle is required.
// If your custom phase depends on methods that are not in uvm_component, but
// are within an extended class, then extend the base YOURPREFIX_NAME_phase
// class with parameterized component class context as required, to create a
// specialized functor which calls your extended component class methods.
// This scheme ensures compile-safety for your extended component classes while
// providing homogeneous base types for APIs and underlying data structures.
//
// *Phase Context*
//
// A schedule is a coherent group of one or mode phase/state nodes linked
// together by a graph structure, allowing arbitrary linear/parallel
// relationships to be specified, and executed by stepping through them in
// the graph order.
// Each schedule node points to a phase and holds the execution state of that
// phase, and has optional links to other nodes for synchronization.
//
// The main operations are: construct, add phases, and instantiate
// hierarchically within another schedule.
//
// Structure is a DAG (Directed Acyclic Graph). Each instance is a node
// connected to others to form the graph. Hierarchy is overlaid with m_parent.
// Each node in the graph has zero or more successors, and zero or more
// predecessors. No nodes are completely isolated from others. Exactly
// one node has zero predecessors. This is the root node. Also the graph
// is acyclic, meaning for all nodes in the graph, by following the forward
// arrows you will never end up back where you started but you will eventually
// reach a node that has no successors.
//
// *Phase State*
//
// A given phase may appear multiple times in the complete phase graph, due
// to the multiple independent domain feature, and the ability for different
// VIP to customize their own phase schedules perhaps reusing existing phases.
// Each node instance in the graph maintains its own state of execution.
//
// *Phase Handle*
//
// Handles of this type uvm_phase are used frequently in the API, both by
// the user, to access phasing-specific API, and also as a parameter to some
// APIs. In many cases, the singleton phase handles can be
// used (eg. <uvm_run_phase::get()>) in APIs. For those APIs that need to look
// up that phase in the graph, this is done automatically.

class uvm_phase extends uvm_object;

  //`uvm_object_utils(uvm_phase)

  `uvm_register_cb(uvm_phase, uvm_phase_cb)


  //--------------------
  // Group: Construction
  //--------------------
  
  // Function: new
  //
  // Create a new phase node, with a name and a note of its type
  //   name   - name of this phase
  //   type   - a value in <uvm_phase_type>
  //
  extern function new(string name="uvm_phase",
                      uvm_phase_type phase_type=UVM_PHASE_SCHEDULE,
                      uvm_phase parent=null);

  // Function: get_phase_type
  //
  // Returns the phase type as defined by <uvm_phase_type>
  //
  extern function uvm_phase_type get_phase_type();


  //-------------
  // Group: State
  //-------------

  // Function: get_state
  //
  // Accessor to return current state of this phase
  //
  extern function uvm_phase_state get_state();


  // Function: get_run_count
  //
  // Accessor to return the integer number of times this phase has executed
  //
  extern function int get_run_count();


  // Function: find_by_name
  //
  // Locate a phase node with the specified ~name~ and return its handle.
  // With ~stay_in_scope~ set, searches only within this phase's schedule or
  // domain.
  //
  extern function uvm_phase find_by_name(string name, bit stay_in_scope=1);


  // Function: find
  //
  // Locate the phase node with the specified ~phase~ IMP and return its handle.
  // With ~stay_in_scope~ set, searches only within this phase's schedule or
  // domain.
  //
  extern function uvm_phase find(uvm_phase phase, bit stay_in_scope=1);


  // Function: is
  //
  // returns 1 if the containing uvm_phase refers to the same phase
  // as the phase argument, 0 otherwise
  //
  extern function bit is(uvm_phase phase);


  // Function: is_before
  //
  // Returns 1 if the containing uvm_phase refers to a phase that is earlier
  // than the phase argument, 0 otherwise
  //
  extern function bit is_before(uvm_phase phase);


  // Function: is_after
  //
  // returns 1 if the containing uvm_phase refers to a phase that is later
  // than the phase argument, 0 otherwise
  //
  extern function bit is_after(uvm_phase phase);


  //-----------------
  // Group: Callbacks
  //-----------------

  // Function: exec_func
  //
  // Implements the functor/delegate functionality for a function phase type
  //   comp  - the component to execute the functionality upon
  //   phase - the phase schedule that originated this phase call
  //
  virtual function void exec_func(uvm_component comp, uvm_phase phase); endfunction


  // Function: exec_task
  //
  // Implements the functor/delegate functionality for a task phase type
  //   comp  - the component to execute the functionality upon
  //   phase - the phase schedule that originated this phase call
  //
  virtual task exec_task(uvm_component comp, uvm_phase phase); endtask



  //----------------
  // Group: Schedule
  //----------------

  // Function: add
  //
  // Build up a schedule structure inserting phase by phase, specifying linkage
  //
  // Phases can be added anywhere, in series or parallel with existing nodes
  //
  //   phase        - handle of singleton derived imp containing actual functor.
  //                  by default the new phase is appended to the schedule
  //   with_phase   - specify to add the new phase in parallel with this one
  //   after_phase  - specify to add the new phase as successor to this one
  //   before_phase - specify to add the new phase as predecessor to this one
  //
  extern function void add(uvm_phase phase,
                           uvm_phase with_phase=null,
                           uvm_phase after_phase=null,
                           uvm_phase before_phase=null);


  // Function: get_parent
  //
  // Returns the parent schedule node, if any, for hierarchical graph traversal
  //
  extern function uvm_phase get_parent();


  // Function: get_full_name
  //
  // Returns the full path from the enclosing domain down to this node.
  // The singleton IMP phases have no hierarchy.
  //
  extern virtual function string get_full_name();


  // Function: get_schedule
  //
  // Returns the topmost parent schedule node, if any, for hierarchical graph traversal
  //
  extern function uvm_phase get_schedule(bit hier = 0);


  // Function: get_schedule_name
  //
  // Returns the schedule name associated with this phase node
  //
  extern function string get_schedule_name(bit hier = 0);


  // Function: get_domain
  //
  // Returns the enclosing domain
  //
  extern function uvm_domain get_domain();


  // Function: get_imp
  //
  // Returns the phase implementation for this this node.
  // Returns ~null~ if this phase type is not a UVM_PHASE_LEAF_NODE.
  //
  extern function uvm_phase get_imp();


  // Function: get_domain_name
  //
  // Returns the domain name associated with this phase node
  //
  extern function string get_domain_name();

  // Function: get_adjacent_predecessor_nodes
  //
  // Provides an array of nodes which are predecessors to
  // ~this~ phase node.  A 'predecessor node' is defined
  // as any phase node which lies prior to ~this~ node in
  // the phase graph, with no nodes between ~this~ node and
  // the predecessor node.
  //
  extern function void get_adjacent_predecessor_nodes(ref uvm_phase pred[]);

  // Function: get_adjacent_successor_nodes
  //
  // Provides an array of nodes which are successors to
  // ~this~ phase node.  A 'successor's node' is defined
  // as any phase node which comes after ~this~ node in
  // the phase graph, with no nodes between ~this~ node
  // and the successor node.
  //
  extern function void get_adjacent_successor_nodes(ref uvm_phase succ[]);

  //-----------------------
  // Group: Phase Done Objection
  //-----------------------
  //
  // Task-based phase nodes within the phasing graph provide a <uvm_objection>
  // based interface for prolonging the execution of the phase.  All other
  // phase types do not contain an objection, and will report a fatal error
  // if the user attempts to ~raise~, ~drop~, or ~get_objection_count~.
   
  // Function- m_report_null_objection
  // Simplifies the reporting of ~null~ objection errors
  extern function void m_report_null_objection(uvm_object obj,
                                               string description,
                                               int count,
                                               string action);
   
  // Function: get_objection
  //
  // Return the <uvm_objection> that gates the termination of the phase.
  //
  function uvm_objection get_objection(); return this.phase_done; endfunction

  // Function: raise_objection
  //
  // Raise an objection to ending this phase
  // Provides components with greater control over the phase flow for
  // processes which are not implicit objectors to the phase.
  //
  //|   while(1) begin
  //|     some_phase.raise_objection(this);
  //|     ...
  //|     some_phase.drop_objection(this);
  //|   end 
  //|   ...
  //
  extern virtual function void raise_objection (uvm_object obj, 
                                                string description="",
                                                int count=1);

  // Function: drop_objection
  //
  // Drop an objection to ending this phase
  //
  // The drop is expected to be matched with an earlier raise.
  //
  extern virtual function void drop_objection (uvm_object obj, 
                                               string description="",
                                               int count=1);


  // Function: get_objection_count
  //
  // Returns the current number of objections to ending this phase raised by the given ~object~.
  //
  extern virtual function int get_objection_count( uvm_object obj=null );
   
  //-----------------------
  // Group: Synchronization
  //-----------------------
  // The functions 'sync' and 'unsync' add soft sync relationships between nodes
  //
  // Summary of usage:
  //| my_phase.sync(.target(domain)
  //|              [,.phase(phase)[,.with_phase(phase)]]);
  //| my_phase.unsync(.target(domain)
  //|                [,.phase(phase)[,.with_phase(phase)]]);
  //
  // Components in different schedule domains can be phased independently or in sync
  // with each other. An API is provided to specify synchronization rules between any
  // two domains. Synchronization can be done at any of three levels:
  //
  // - the domain's whole phase schedule can be synchronized
  // - a phase can be specified, to sync that phase with a matching counterpart
  // - or a more detailed arbitrary synchronization between any two phases
  //
  // Each kind of synchronization causes the same underlying data structures to
  // be managed. Like other APIs, we use the parameter dot-notation to set
  // optional parameters.
  //
  // When a domain is synced with another domain, all of the matching phases in
  // the two domains get a 'with' relationship between them. Likewise, if a domain
  // is unsynched, all of the matching phases that have a 'with' relationship have
  // the dependency removed. It is possible to sync two domains and then just
  // remove a single phase from the dependency relationship by unsyncing just
  // the one phase.


  // Function: sync
  //
  // Synchronize two domains, fully or partially
  //
  //   target       - handle of target domain to synchronize this one to
  //   phase        - optional single phase in this domain to synchronize, 
  //                  otherwise sync all
  //   with_phase   - optional different target-domain phase to synchronize with,
  //                  otherwise use ~phase~ in the target domain
  //
  extern function void sync(uvm_domain target,
                            uvm_phase phase=null,
                            uvm_phase with_phase=null);

  // Function: unsync
  //
  // Remove synchronization between two domains, fully or partially
  //
  //   target       - handle of target domain to remove synchronization from
  //   phase        - optional single phase in this domain to un-synchronize, 
  //                  otherwise unsync all
  //   with_phase   - optional different target-domain phase to un-synchronize with,
  //                  otherwise use ~phase~ in the target domain
  //
  extern function void unsync(uvm_domain target,
                              uvm_phase phase=null,
                              uvm_phase with_phase=null);


  // Function: wait_for_state
  //
  // Wait until this phase compares with the given ~state~ and ~op~ operand.
  // For <UVM_EQ> and <UVM_NE> operands, several <uvm_phase_states> can be
  // supplied by ORing their enum constants, in which case the caller will
  // wait until the phase state is any of (UVM_EQ) or none of (UVM_NE) the
  // provided states.
  //
  // To wait for the phase to be at the started state or after
  //
  //| wait_for_state(UVM_PHASE_STARTED, UVM_GTE);
  //
  // To wait for the phase to be either started or executing
  //
  //| wait_for_state(UVM_PHASE_STARTED | UVM_PHASE_EXECUTING, UVM_EQ);
  //
  extern task wait_for_state(uvm_phase_state state, uvm_wait_op op=UVM_EQ);

   
  //---------------
  // Group: Jumping
  //---------------
  
  // Force phases to jump forward or backward in a schedule
  //
  // A phasing domain can execute a jump from its current phase to any other.
  // A jump passes phasing control in the current domain from the current phase
  // to a target phase. There are two kinds of jump scope:
  //
  // - local jump to another phase within the current schedule, back- or forwards
  // - global jump of all domains together, either to a point in the master
  //   schedule outwith the current schedule, or by calling jump_all()
  //
  // A jump preserves the existing soft synchronization, so the domain that is
  // ahead of schedule relative to another synchronized domain, as a result of
  // a jump in either domain, will await the domain that is behind schedule.
  //
  // *Note*: A jump out of the local schedule causes other schedules that have
  // the jump node in their schedule to jump as well. In some cases, it is
  // desirable to jump to a local phase in the schedule but to have all
  // schedules that share that phase to jump as well. In that situation, the
  // jump_all static function should be used. This function causes all schedules
  // that share a phase to jump to that phase.
 
  // Function: jump
  //
  // Jump to a specified ~phase~. If the destination ~phase~ is within the current 
  // phase schedule, a simple local jump takes place. If the jump-to ~phase~ is
  // outside of the current schedule then the jump affects other schedules which
  // share the phase.
  //
  extern function void jump(uvm_phase phase);

  // Function: set_jump_phase
  //
  // Specify a phase to transition to when phase is complete.
  // Note that this function is part of what jump() does; unlike jump()
  // it does not set the flag to terminate the phase prematurely.
  extern function void set_jump_phase(uvm_phase phase) ;
  
  // Function: end_prematurely
  //
  // Set a flag to cause the phase to end prematurely.  
  // Note that this function is part of what jump() does; unlike jump()
  // it does not set a jump_phase to go to after the phase ends.
  extern function void end_prematurely() ;

  // Function- jump_all
  //
  // Make all schedules jump to a specified ~phase~, even if the jump target is local.
  // The jump happens to all phase schedules that contain the jump-to ~phase~,
  // i.e. a global jump. 
  //
  extern static function void jump_all(uvm_phase phase);


  // Function: get_jump_target
  //
  // Return handle to the target phase of the current jump, or ~null~ if no jump
  // is in progress. Valid for use during the phase_ended() callback
  //
  extern function uvm_phase get_jump_target();


  int unsigned max_ready_to_end_iter = 20;

  //--------------------------
  // Internal - Implementation
  //--------------------------

  // Implementation - Construction
  //------------------------------
  protected uvm_phase_type m_phase_type;
  protected uvm_phase      m_parent;     // our 'schedule' node [or points 'up' one level]
  uvm_phase                m_imp;        // phase imp to call when we execute this node

  // Implementation - State
  //-----------------------
  local uvm_phase_state    m_state;
  local int                m_run_count; // num times this phase has executed
  local process            m_phase_proc;
  int                      m_num_procs_not_yet_returned;
  extern function uvm_phase m_find_predecessor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null);
  extern function uvm_phase m_find_successor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null);
  extern function uvm_phase m_find_predecessor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null);
  extern function uvm_phase m_find_successor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null);
  extern function void m_print_successors();

  // Implementation - Callbacks
  //---------------------------
  // Provide the required component traversal behavior. Called by execute()
  virtual function void traverse(uvm_component comp,
                                 uvm_phase phase,
                                 uvm_phase_state state);
  endfunction
  // Provide the required per-component execution flow. Called by traverse()
  virtual function void execute(uvm_component comp,
                                 uvm_phase phase);
  endfunction

  // Implementation - Schedule
  //--------------------------
  protected bit  m_predecessors[uvm_phase];
  protected bit  m_successors[uvm_phase];
  protected uvm_phase m_end_node;
  // Track the currently executing real task phases (used for debug)
  static protected bit m_executing_phases[uvm_phase];
  function uvm_phase get_begin_node(); if (m_imp != null) return this; return null; endfunction
  function uvm_phase get_end_node();   return m_end_node; endfunction

  // Implementation - Synchronization
  //---------------------------------
  local uvm_phase m_sync[$];  // schedule instance to which we are synced
  uvm_objection phase_done; // phase done objection
  local int unsigned m_ready_to_end_count;

  function int unsigned get_ready_to_end_count();
     return m_ready_to_end_count;
  endfunction

  extern local function void get_predecessors_for_successors(output bit pred_of_succ[uvm_phase]);
  extern local task m_wait_for_pred();

  // Implementation - Jumping
  //-------------------------
  local bit                m_jump_bkwd;
  local bit                m_jump_fwd;
  local uvm_phase          m_jump_phase;
  local bit                m_premature_end;
  extern function void clear(uvm_phase_state state = UVM_PHASE_DORMANT);
  extern function void clear_successors(
                             uvm_phase_state state = UVM_PHASE_DORMANT,
                             uvm_phase end_state=null);

  // Implementation - Overall Control
  //---------------------------------
  local static mailbox #(uvm_phase) m_phase_hopper = new();

  extern static task m_run_phases();
  extern local task  execute_phase();
  extern local function void m_terminate_phase();
  extern local function void m_print_termination_state();
  extern local task wait_for_self_and_siblings_to_drop();
  extern function void kill();
  extern function void kill_successors();

  // TBD add more useful debug
  //---------------------------------
  protected static bit m_phase_trace;
  local static bit m_use_ovm_run_semantic;


  function string convert2string();
  //return $sformatf("PHASE %s = %p",get_name(),this);
  string s;
    s = $sformatf("phase: %s parent=%s  pred=%s  succ=%s",get_name(),
                     (m_parent==null) ? "null" : get_schedule_name(),
                     m_aa2string(m_predecessors),
                     m_aa2string(m_successors));
    return s;
  endfunction

  local function string m_aa2string(bit aa[uvm_phase]); // TBD tidy
    string s;
    int i;
    s = "'{ ";
    foreach (aa[ph]) begin
      uvm_phase n = ph;
      s = {s, (n == null) ? "null" : n.get_name(),
        (i == aa.num()-1) ? "" : ", "};
      i++;
    end
    s = {s, " }"};
    return s;
  endfunction

  function bit is_domain();
    return (m_phase_type == UVM_PHASE_DOMAIN);
  endfunction

  virtual function void m_get_transitive_children(ref uvm_phase phases[$]);
    foreach (m_successors[succ])
    begin
        phases.push_back(succ);
        succ.m_get_transitive_children(phases);
    end
  endfunction
endclass


//------------------------------------------------------------------------------
//
// Class: uvm_phase_state_change
//
//------------------------------------------------------------------------------
//
// Phase state transition descriptor.
// Used to describe the phase transition that caused a
// <uvm_phase_cb::phase_state_changed()> callback to be invoked.
//

class uvm_phase_state_change extends uvm_object;

  `uvm_object_utils(uvm_phase_state_change)

  // Implementation -- do not use directly
  /* local */ uvm_phase       m_phase;
  /* local */ uvm_phase_state m_prev_state;
  /* local */ uvm_phase       m_jump_to;
  
  function new(string name = "uvm_phase_state_change");
    super.new(name);
  endfunction


  // Function: get_state()
  //
  // Returns the state the phase just transitioned to.
  // Functionally equivalent to <uvm_phase::get_state()>.
  //
  virtual function uvm_phase_state get_state();
    return m_phase.get_state();
  endfunction
  
  // Function: get_prev_state()
  //
  // Returns the state the phase just transitioned from.
  //
  virtual function uvm_phase_state get_prev_state();
    return m_prev_state;
  endfunction

  // Function: jump_to()
  //
  // If the current state is ~UVM_PHASE_ENDED~ or ~UVM_PHASE_JUMPING~ because of
  // a phase jump, returns the phase that is the target of jump.
  // Returns ~null~ otherwise.
  //
  function uvm_phase jump_to();
    return m_jump_to;
  endfunction

endclass


//------------------------------------------------------------------------------
//
// Class: uvm_phase_cb
//
//------------------------------------------------------------------------------
//
// This class defines a callback method that is invoked by the phaser
// during the execution of a specific node in the phase graph or all phase nodes.
// User-defined callback extensions can be used to integrate data types that
// are not natively phase-aware with the UVM phasing.
//

class uvm_phase_cb extends uvm_callback;

  // Function: new
  // Constructor
  function new(string name="unnamed-uvm_phase_cb");
     super.new(name);
  endfunction : new
   
  // Function: phase_state_change
  //
  // Called whenever a ~phase~ changes state.
  // The ~change~ descriptor describes the transition that was just completed.
  // The callback method is invoked immediately after the phase state has changed,
  // but before the phase implementation is executed.
  //
  // An extension may interact with the phase,
  // such as raising the phase objection to prolong the phase,
  // in a manner that is consistent with the current phase state.
  //
  // By default, the callback method does nothing.
  // Unless otherwise specified, modifying the  phase transition descriptor has
  // no effect on the phasing schedule or execution.
  //
  virtual function void phase_state_change(uvm_phase phase,
                                           uvm_phase_state_change change);
  endfunction
endclass

//------------------------------------------------------------------------------
//
// Class: uvm_phase_cb_pool
//
//------------------------------------------------------------------------------
//
// Convenience type for the uvm_callbacks#(uvm_phase, uvm_phase_cb) class.
//
typedef uvm_callbacks#(uvm_phase, uvm_phase_cb) uvm_phase_cb_pool;


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

typedef class uvm_cmdline_processor;

`define UVM_PH_TRACE(ID,MSG,PH,VERB) \
   `uvm_info(ID, {$sformatf("Phase '%0s' (id=%0d) ", \
       PH.get_full_name(), PH.get_inst_id()),MSG}, VERB);

//-----------------------------
// Implementation - Construction
//-----------------------------

// new

function uvm_phase::new(string name="uvm_phase",
                        uvm_phase_type phase_type=UVM_PHASE_SCHEDULE,
                        uvm_phase parent=null);
  super.new(name);
  m_phase_type = phase_type;

  // The common domain is the only thing that initializes m_state.  All
  // other states are initialized by being 'added' to a schedule.
  if ((name == "common") &&
      (phase_type == UVM_PHASE_DOMAIN))
    m_state = UVM_PHASE_DORMANT;
   
  m_run_count = 0;
  m_parent = parent;

  begin
    uvm_cmdline_processor clp = uvm_cmdline_processor::get_inst();
    string val;
    if (clp.get_arg_value("+UVM_PHASE_TRACE", val))
      m_phase_trace = 1;
    else
      m_phase_trace = 0;
    if (clp.get_arg_value("+UVM_USE_OVM_RUN_SEMANTIC", val))
      m_use_ovm_run_semantic = 1;
    else
      m_use_ovm_run_semantic = 0;
  end

   
  if (parent == null && (phase_type == UVM_PHASE_SCHEDULE ||
                         phase_type == UVM_PHASE_DOMAIN )) begin
    //m_parent = this;
    m_end_node = new({name,"_end"}, UVM_PHASE_TERMINAL, this);
    this.m_successors[m_end_node] = 1;
    m_end_node.m_predecessors[this] = 1;
  end

endfunction


// add
// ---
// TBD error checks if param nodes are actually in this schedule or not

function void uvm_phase::add(uvm_phase phase,
                             uvm_phase with_phase=null,
                             uvm_phase after_phase=null,
                             uvm_phase before_phase=null);
  uvm_phase new_node, begin_node, end_node, tmp_node;
  uvm_phase_state_change state_chg;

  if (phase == null)
      `uvm_fatal("PH/NULL", "add: phase argument is null")

  if (with_phase != null && with_phase.get_phase_type() == UVM_PHASE_IMP) begin
    string nm = with_phase.get_name();
    with_phase = find(with_phase);
    if (with_phase == null)
      `uvm_fatal("PH_BAD_ADD",
         {"cannot find with_phase '",nm,"' within node '",get_name(),"'"})
  end

  if (before_phase != null && before_phase.get_phase_type() == UVM_PHASE_IMP) begin
    string nm = before_phase.get_name();
    before_phase = find(before_phase);
    if (before_phase == null)
      `uvm_fatal("PH_BAD_ADD",
         {"cannot find before_phase '",nm,"' within node '",get_name(),"'"})
  end

  if (after_phase != null && after_phase.get_phase_type() == UVM_PHASE_IMP) begin
    string nm = after_phase.get_name();
    after_phase = find(after_phase);
    if (after_phase == null)
      `uvm_fatal("PH_BAD_ADD",
         {"cannot find after_phase '",nm,"' within node '",get_name(),"'"})
  end

  if (with_phase != null && (after_phase != null || before_phase != null))
    `uvm_fatal("PH_BAD_ADD",
       "cannot specify both 'with' and 'before/after' phase relationships")

  if (before_phase == this || after_phase == m_end_node || with_phase == m_end_node)
    `uvm_fatal("PH_BAD_ADD",
       "cannot add before begin node, after end node, or with end nodes")

  // If we are inserting a new "leaf node"
  if (phase.get_phase_type() == UVM_PHASE_IMP) begin
    uvm_task_phase tp;
    new_node = new(phase.get_name(),UVM_PHASE_NODE,this);
    new_node.m_imp = phase;
    begin_node = new_node;
    end_node = new_node;

    // The phase_done objection is only required
    // for task-based nodes
    if ($cast(tp, phase)) begin
       if (new_node.get_name() == "run") begin
         new_node.phase_done = uvm_test_done_objection::get();
       end
       else begin
         new_node.phase_done = uvm_objection::type_id::create({phase.get_name(), "_objection"});
       end
    end

  end
  // We are inserting an existing schedule
  else begin
    begin_node = phase;
    end_node   = phase.m_end_node;
    phase.m_parent = this;
  end

  // If 'with_phase' is us, then insert node in parallel
  /*
  if (with_phase == this) begin
    after_phase = this;
    before_phase = m_end_node;
  end
  */

  // If no before/after/with specified, insert at end of this schedule
  if (with_phase == null && after_phase == null && before_phase == null) begin
    before_phase = m_end_node;
  end


  if (m_phase_trace) begin
    uvm_phase_type typ = phase.get_phase_type();
    `uvm_info("PH/TRC/ADD_PH",
      {get_name()," (",m_phase_type.name(),") ADD_PHASE: phase=",phase.get_full_name()," (",
      typ.name(),", inst_id=",$sformatf("%0d",phase.get_inst_id()),")",
      " with_phase=",   (with_phase == null)   ? "null" : with_phase.get_name(), 
      " after_phase=",  (after_phase == null)  ? "null" : after_phase.get_name(),
      " before_phase=", (before_phase == null) ? "null" : before_phase.get_name(), 
      " new_node=",     (new_node == null)     ? "null" : {new_node.get_name(),
                                                           " inst_id=",
                                                           $sformatf("%0d",new_node.get_inst_id())},
      " begin_node=",   (begin_node == null)   ? "null" : begin_node.get_name(),
      " end_node=",     (end_node == null)     ? "null" : end_node.get_name()},UVM_DEBUG)
  end


  // INSERT IN PARALLEL WITH 'WITH' PHASE
  if (with_phase != null) begin
    begin_node.m_predecessors = with_phase.m_predecessors;
    end_node.m_successors = with_phase.m_successors;
    foreach (with_phase.m_predecessors[pred])
      pred.m_successors[begin_node] = 1;
    foreach (with_phase.m_successors[succ])
      succ.m_predecessors[end_node] = 1;
  end
  
  
  // INSERT BEFORE PHASE
  else if (before_phase != null && after_phase == null) begin
    begin_node.m_predecessors = before_phase.m_predecessors;
    end_node.m_successors[before_phase] = 1;
    foreach (before_phase.m_predecessors[pred]) begin
      pred.m_successors.delete(before_phase);
      pred.m_successors[begin_node] = 1;
    end
    before_phase.m_predecessors.delete();
    before_phase.m_predecessors[end_node] = 1;
  end
  

  // INSERT AFTER PHASE
  else if (before_phase == null && after_phase != null) begin
    end_node.m_successors = after_phase.m_successors;
    begin_node.m_predecessors[after_phase] = 1;
    foreach (after_phase.m_successors[succ]) begin
      succ.m_predecessors.delete(after_phase);
      succ.m_predecessors[end_node] = 1;
    end
    after_phase.m_successors.delete();
    after_phase.m_successors[begin_node] = 1;
  end
  

  // IN BETWEEN 'BEFORE' and 'AFTER' PHASES
  else if (before_phase != null && after_phase != null) begin
    if (!after_phase.is_before(before_phase)) begin
      `uvm_fatal("PH_ADD_PHASE",{"Phase '",before_phase.get_name(),
                 "' is not before phase '",after_phase.get_name(),"'"})
    end
    // before and after? add 1 pred and 1 succ
    begin_node.m_predecessors[after_phase] = 1;
    end_node.m_successors[before_phase] = 1;
    after_phase.m_successors[begin_node] = 1;
    before_phase.m_predecessors[end_node] = 1;
    if (after_phase.m_successors.exists(before_phase)) begin
      after_phase.m_successors.delete(before_phase);
      before_phase.m_successors.delete(after_phase);
    end
  end // if (before_phase != null && after_phase != null)

  // Transition nodes to DORMANT state
  if (new_node == null)
    tmp_node = phase;
  else
    tmp_node = new_node;

  state_chg = uvm_phase_state_change::type_id::create(tmp_node.get_name());
  state_chg.m_phase = tmp_node;
  state_chg.m_jump_to = null;
  state_chg.m_prev_state = tmp_node.m_state;
  tmp_node.m_state = UVM_PHASE_DORMANT;
  `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(tmp_node, state_chg)) 
endfunction


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

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


// get_imp
// -------

function uvm_phase uvm_phase::get_imp();
  return m_imp;
endfunction


// get_schedule
// ------------

function uvm_phase uvm_phase::get_schedule(bit hier=0);
  uvm_phase sched;
  sched = this;
  if (hier)
    while (sched.m_parent != null && (sched.m_parent.get_phase_type() == UVM_PHASE_SCHEDULE))
      sched = sched.m_parent;
  if (sched.m_phase_type == UVM_PHASE_SCHEDULE)
    return sched;
  if (sched.m_phase_type == UVM_PHASE_NODE)
    if (m_parent != null && m_parent.m_phase_type != UVM_PHASE_DOMAIN)
      return m_parent;
  return null;
endfunction


// get_domain
// ----------

function uvm_domain uvm_phase::get_domain();
  uvm_phase phase;
  phase = this;
  while (phase != null && phase.m_phase_type != UVM_PHASE_DOMAIN)
    phase = phase.m_parent;
  if (phase == null) // no parent domain 
    return null;
  if(!$cast(get_domain,phase))
      `uvm_fatal("PH/INTERNAL", "get_domain: m_phase_type is DOMAIN but $cast to uvm_domain fails")
endfunction


// get_domain_name
// ---------------
  
function string uvm_phase::get_domain_name();
  uvm_domain domain;
  domain = get_domain();
  if (domain == null)
    return "unknown";
  return domain.get_name();
endfunction


// get_schedule_name
// -----------------
  
function string uvm_phase::get_schedule_name(bit hier=0);
  uvm_phase sched;
  string s;
  sched = get_schedule(hier);
  if (sched == null)
    return "";
  s = sched.get_name();
  while (sched.m_parent != null && sched.m_parent != sched &&
          (sched.m_parent.get_phase_type() == UVM_PHASE_SCHEDULE)) begin
    sched = sched.m_parent;
    s = {sched.get_name(),(s.len()>0?".":""),s};
  end
  return s;
endfunction


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

function string uvm_phase::get_full_name();
  string dom, sch;
  if (m_phase_type == UVM_PHASE_IMP)
    return get_name();
  get_full_name = get_domain_name();
  sch = get_schedule_name();
  if (sch != "")
    get_full_name = {get_full_name, ".", sch};
  if (m_phase_type != UVM_PHASE_DOMAIN && m_phase_type != UVM_PHASE_SCHEDULE)
    get_full_name = {get_full_name, ".", get_name()};
endfunction


// get_phase_type
// --------------

function uvm_phase_type uvm_phase::get_phase_type();
  return m_phase_type;
endfunction


//-----------------------
// Implementation - State
//-----------------------

// get_state
// ---------

function uvm_phase_state uvm_phase::get_state();
  return m_state;
endfunction

// get_run_count
// -------------

function int uvm_phase::get_run_count();
  return m_run_count;
endfunction


// m_print_successors
// ------------------

function void uvm_phase::m_print_successors();
  uvm_phase found;
  static string spaces = "                                                 ";
  static int level;
  if (m_phase_type == UVM_PHASE_DOMAIN)
    level = 0;
  `uvm_info("UVM/PHASE/SUCC",$sformatf("%s%s (%s) id=%0d",spaces.substr(0,level*2),get_name(), m_phase_type.name(),get_inst_id()),UVM_NONE)
  level++;
  foreach (m_successors[succ]) begin
    succ.m_print_successors();
  end
  level--;
endfunction


// m_find_predecessor
// ------------------

function uvm_phase uvm_phase::m_find_predecessor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null);
  uvm_phase found;
  //$display("  FIND PRED node '",phase.get_name(),"' (id=",$sformatf("%0d",phase.get_inst_id()),") - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")");
  if (phase == null) begin
    return null ;
  end
  if (phase == m_imp || phase == this)
    return this;
  foreach (m_predecessors[pred]) begin
    uvm_phase orig;
    orig = (orig_phase==null) ? this : orig_phase;
    if (!stay_in_scope || 
        (pred.get_schedule() == orig.get_schedule()) ||
        (pred.get_domain() == orig.get_domain())) begin
      found = pred.m_find_predecessor(phase,stay_in_scope,orig);
      if (found != null)
        return found;
    end
  end
  return null;
endfunction


// m_find_predecessor_by_name
// --------------------------

function uvm_phase uvm_phase::m_find_predecessor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null);
  uvm_phase found;
  //$display("  FIND PRED node '",name,"' - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")");
  if (get_name() == name)
    return this;
  foreach (m_predecessors[pred]) begin
    uvm_phase orig;
    orig = (orig_phase==null) ? this : orig_phase;
    if (!stay_in_scope || 
        (pred.get_schedule() == orig.get_schedule()) ||
        (pred.get_domain() == orig.get_domain())) begin
      found = pred.m_find_predecessor_by_name(name,stay_in_scope,orig);
      if (found != null)
        return found;
    end
  end
  return null;
endfunction


// m_find_successor
// ----------------

function uvm_phase uvm_phase::m_find_successor(uvm_phase phase, bit stay_in_scope=1, uvm_phase orig_phase=null);
  uvm_phase found;
  //$display("  FIND SUCC node '",phase.get_name(),"' (id=",$sformatf("%0d",phase.get_inst_id()),") - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")");
  if (phase == null) begin
    return null ;
  end
  if (phase == m_imp || phase == this) begin
    return this;
    end
  foreach (m_successors[succ]) begin
    uvm_phase orig;
    orig = (orig_phase==null) ? this : orig_phase;
    if (!stay_in_scope || 
        (succ.get_schedule() == orig.get_schedule()) ||
        (succ.get_domain() == orig.get_domain())) begin
      found = succ.m_find_successor(phase,stay_in_scope,orig);
      if (found != null) begin
        return found;
        end
    end
  end
  return null;
endfunction


// m_find_successor_by_name
// ------------------------

function uvm_phase uvm_phase::m_find_successor_by_name(string name, bit stay_in_scope=1, uvm_phase orig_phase=null);
  uvm_phase found;
  //$display("  FIND SUCC node '",name,"' - checking against ",get_name()," (",m_phase_type.name()," id=",$sformatf("%0d",get_inst_id()),(m_imp==null)?"":{"/",$sformatf("%0d",m_imp.get_inst_id())},")");
  if (get_name() == name)
    return this;
  foreach (m_successors[succ]) begin
    uvm_phase orig;
    orig = (orig_phase==null) ? this : orig_phase;
    if (!stay_in_scope || 
        (succ.get_schedule() == orig.get_schedule()) ||
        (succ.get_domain() == orig.get_domain())) begin
      found = succ.m_find_successor_by_name(name,stay_in_scope,orig);
      if (found != null)
        return found;
    end
  end
  return null;
endfunction


// find
// ----

function uvm_phase uvm_phase::find(uvm_phase phase, bit stay_in_scope=1);
  // TBD full search
  //$display({"\nFIND node '",phase.get_name(),"' within ",get_name()," (scope ",m_phase_type.name(),")", (stay_in_scope) ? " staying within scope" : ""});
  if (phase == m_imp || phase == this)
    return phase;
  find = m_find_predecessor(phase,stay_in_scope,this);
  if (find == null)
    find = m_find_successor(phase,stay_in_scope,this);
endfunction


// find_by_name
// ------------

function uvm_phase uvm_phase::find_by_name(string name, bit stay_in_scope=1);
  // TBD full search
  //$display({"\nFIND node named '",name,"' within ",get_name()," (scope ",m_phase_type.name(),")", (stay_in_scope) ? " staying within scope" : ""});
  if (get_name() == name)
    return this;
  find_by_name = m_find_predecessor_by_name(name,stay_in_scope,this);
  if (find_by_name == null)
    find_by_name = m_find_successor_by_name(name,stay_in_scope,this);
endfunction


// is
// --
  
function bit uvm_phase::is(uvm_phase phase);
  return (m_imp == phase || this == phase); 
endfunction

  
// is_before
// ---------

function bit uvm_phase::is_before(uvm_phase phase);
  //$display("this=%s is before phase=%s?",get_name(),phase.get_name());
  // TODO: add support for 'stay_in_scope=1' functionality
  return (!is(phase) && m_find_successor(phase,0,this) != null);
endfunction


// is_after
// --------
  
function bit uvm_phase::is_after(uvm_phase phase);
  //$display("this=%s is after phase=%s?",get_name(),phase.get_name());
  // TODO: add support for 'stay_in_scope=1' functionality
  return (!is(phase) && m_find_predecessor(phase,0,this) != null);
endfunction


// execute_phase
// -------------

task uvm_phase::execute_phase();

  uvm_task_phase task_phase;
  uvm_root top;
  uvm_phase_state_change state_chg;
  uvm_coreservice_t cs;

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

  // If we got here by jumping forward, we must wait for
  // all its predecessor nodes to be marked DONE.
  // (the next conditional speeds this up)
  // Also, this helps us fast-forward through terminal (end) nodes
  foreach (m_predecessors[pred])
    wait (pred.m_state == UVM_PHASE_DONE);


  // If DONE (by, say, a forward jump), return immed
  if (m_state == UVM_PHASE_DONE)
    return;

  state_chg = uvm_phase_state_change::type_id::create(get_name());
  state_chg.m_phase      = this;
  state_chg.m_jump_to    = null;

  //---------
  // SYNCING:
  //---------
  // Wait for phases with which we have a sync()
  // relationship to be ready. Sync can be 2-way -
  // this additional state avoids deadlock.
  state_chg.m_prev_state = m_state;
  m_state = UVM_PHASE_SYNCING;
  `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))
  #0;
   
  if (m_sync.size()) begin
    
    foreach (m_sync[i]) begin
      wait (m_sync[i].m_state >= UVM_PHASE_SYNCING);
    end
  end

  m_run_count++;


  if (m_phase_trace) begin
    `UVM_PH_TRACE("PH/TRC/STRT","Starting phase",this,UVM_LOW)
  end


  // If we're a schedule or domain, then "fake" execution
  if (m_phase_type != UVM_PHASE_NODE) begin
    state_chg.m_prev_state = m_state;
    m_state = UVM_PHASE_STARTED;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))

    #0;

    state_chg.m_prev_state = m_state;
    m_state = UVM_PHASE_EXECUTING;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))

    #0;
  end


  else begin // PHASE NODE

    //---------
    // STARTED:
    //---------
    state_chg.m_prev_state = m_state;
    m_state = UVM_PHASE_STARTED;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))

    m_imp.traverse(top,this,UVM_PHASE_STARTED);
    m_ready_to_end_count = 0 ; // reset the ready_to_end count when phase starts
    #0; // LET ANY WAITERS WAKE UP


    //if (m_imp.get_phase_type() != UVM_PHASE_TASK) begin
    if (!$cast(task_phase,m_imp)) begin

      //-----------
      // EXECUTING: (function phases)
      //-----------
      state_chg.m_prev_state = m_state;
      m_state = UVM_PHASE_EXECUTING;
      `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))

      #0; // LET ANY WAITERS WAKE UP
      m_imp.traverse(top,this,UVM_PHASE_EXECUTING);

    end
    else begin
        m_executing_phases[this] = 1;

        state_chg.m_prev_state = m_state;
        m_state = UVM_PHASE_EXECUTING;
        `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))

        fork : master_phase_process
          begin
  
            m_phase_proc = process::self();
  
            //-----------
            // EXECUTING: (task phases)
            //-----------
            task_phase.traverse(top,this,UVM_PHASE_EXECUTING);
  
            wait(0); // stay alive for later kill
  
          end
        join_none
  
        uvm_wait_for_nba_region(); //Give sequences, etc. a chance to object
  
        // Now wait for one of three criterion for end-of-phase.
        fork
          begin // guard
          
           fork
             // JUMP
             begin
                wait (m_premature_end);
                `UVM_PH_TRACE("PH/TRC/EXE/JUMP","PHASE EXIT ON JUMP REQUEST",this,UVM_DEBUG)
             end
  
             // WAIT_FOR_ALL_DROPPED
             begin
               bit do_ready_to_end  ; // bit used for ready_to_end iterations
               // OVM semantic: don't end until objection raised or stop request
               if (phase_done.get_objection_total(top) ||
                   m_use_ovm_run_semantic && m_imp.get_name() == "run") begin
                 if (!phase_done.m_top_all_dropped)
                   phase_done.wait_for(UVM_ALL_DROPPED, top);
                 `UVM_PH_TRACE("PH/TRC/EXE/ALLDROP","PHASE EXIT ALL_DROPPED",this,UVM_DEBUG)
               end
               else begin
                  if (m_phase_trace) `UVM_PH_TRACE("PH/TRC/SKIP","No objections raised, skipping phase",this,UVM_LOW)
               end
               
               wait_for_self_and_siblings_to_drop() ;
               do_ready_to_end = 1;
                  
               //--------------
               // READY_TO_END:
               //--------------
 
               while (do_ready_to_end) begin
                 uvm_wait_for_nba_region(); // Let all siblings see no objections before traverse might raise another 
                 `UVM_PH_TRACE("PH_READY_TO_END","PHASE READY TO END",this,UVM_DEBUG)
                 m_ready_to_end_count++;
                 if (m_phase_trace)
                   `UVM_PH_TRACE("PH_READY_TO_END_CB","CALLING READY_TO_END CB",this,UVM_HIGH)
                 state_chg.m_prev_state = m_state;
                 m_state = UVM_PHASE_READY_TO_END;
                 `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))
                 if (m_imp != null)
                   m_imp.traverse(top,this,UVM_PHASE_READY_TO_END);
                  
                 uvm_wait_for_nba_region(); // Give traverse targets a chance to object 

                 wait_for_self_and_siblings_to_drop();
                 do_ready_to_end = (m_state == UVM_PHASE_EXECUTING) && (m_ready_to_end_count < max_ready_to_end_iter) ; //when we don't wait in task above, we drop out of while loop
               end
             end
  
             // TIMEOUT
             begin
               if (this.get_name() == "run") begin
                  if (top.phase_timeout == 0)
                    wait(top.phase_timeout != 0);
                  if (m_phase_trace)
                    `UVM_PH_TRACE("PH/TRC/TO_WAIT", $sformatf("STARTING PHASE TIMEOUT WATCHDOG (timeout == %t)", top.phase_timeout), this, UVM_HIGH)
                  `uvm_delay(top.phase_timeout)
                  if ($time == `UVM_DEFAULT_TIMEOUT) begin
                     if (m_phase_trace)
                       `UVM_PH_TRACE("PH/TRC/TIMEOUT", "PHASE TIMEOUT WATCHDOG EXPIRED", this, UVM_LOW)
                     foreach (m_executing_phases[p]) begin
                        if ((p.phase_done != null) && (p.phase_done.get_objection_total() > 0)) begin
                           if (m_phase_trace)
                             `UVM_PH_TRACE("PH/TRC/TIMEOUT/OBJCTN", 
                                           $sformatf("Phase '%s' has outstanding objections:\n%s", p.get_full_name(), p.phase_done.convert2string()),
                                           this,
                                           UVM_LOW)
                        end
                     end
                        
                     `uvm_fatal("PH_TIMEOUT",
                                $sformatf("Default timeout of %0t hit, indicating a probable testbench issue",
                                          `UVM_DEFAULT_TIMEOUT))
                  end
                  else begin
                     if (m_phase_trace)
                       `UVM_PH_TRACE("PH/TRC/TIMEOUT", "PHASE TIMEOUT WATCHDOG EXPIRED", this, UVM_LOW)
                     foreach (m_executing_phases[p]) begin
                        if ((p.phase_done != null) && (p.phase_done.get_objection_total() > 0)) begin
                           if (m_phase_trace)
                             `UVM_PH_TRACE("PH/TRC/TIMEOUT/OBJCTN", 
                                           $sformatf("Phase '%s' has outstanding objections:\n%s", p.get_full_name(), p.phase_done.convert2string()),
                                           this,
                                           UVM_LOW)
                        end
                     end
                        
                     `uvm_fatal("PH_TIMEOUT",
                                $sformatf("Explicit timeout of %0t hit, indicating a probable testbench issue",
                                          top.phase_timeout))
                  end
                  if (m_phase_trace)
                    `UVM_PH_TRACE("PH/TRC/EXE/3","PHASE EXIT TIMEOUT",this,UVM_DEBUG)
               end // if (this.get_name() == "run")
               else begin
                  wait (0); // never unblock for non-run phase
               end
             end // if (m_phase_trace)

  
           join_any
           disable fork;
        
          end
  
        join // guard

    end

  end

  m_executing_phases.delete(this);

  //---------
  // JUMPING:
  //---------

  // If jump_to() was called then we need to kill all the successor
  // phases which may still be running and then initiate the new
  // phase.  The return is necessary so we don't start new successor
  // phases.  If we are doing a forward jump then we want to set the
  // state of this phase's successors to UVM_PHASE_DONE.  This
  // will let us pretend that all the phases between here and there
  // were executed and completed.  Thus any dependencies will be
  // satisfied preventing deadlocks.
  // GSA TBD insert new jump support

  if (m_phase_type == UVM_PHASE_NODE) begin

    if(m_premature_end) begin
      if(m_jump_phase != null) begin 
        state_chg.m_jump_to = m_jump_phase;
      
        `uvm_info("PH_JUMP",
              $sformatf("phase %s (schedule %s, domain %s) is jumping to phase %s",
               get_name(), get_schedule_name(), get_domain_name(), m_jump_phase.get_name()),
              UVM_MEDIUM);
      end
      else begin
        `uvm_info("PH_JUMP",
              $sformatf("phase %s (schedule %s, domain %s) is ending prematurely",
               get_name(), get_schedule_name(), get_domain_name()),
              UVM_MEDIUM);
      end
  
  
      #0; // LET ANY WAITERS ON READY_TO_END TO WAKE UP
      if (m_phase_trace)
        `UVM_PH_TRACE("PH_END","ENDING PHASE PREMATURELY",this,UVM_HIGH)
    end
    else begin
      // WAIT FOR PREDECESSORS:  // WAIT FOR PREDECESSORS:
      // function phases only
      if (task_phase == null)
        m_wait_for_pred();
    end
  
    //-------
    // ENDED:
    //-------
    // execute 'phase_ended' callbacks
    if (m_phase_trace)
      `UVM_PH_TRACE("PH_END","ENDING PHASE",this,UVM_HIGH)
    state_chg.m_prev_state = m_state;
    m_state = UVM_PHASE_ENDED;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))
    if (m_imp != null)
      m_imp.traverse(top,this,UVM_PHASE_ENDED);
    #0; // LET ANY WAITERS WAKE UP
  
  
    //---------
    // CLEANUP:
    //---------
    // kill this phase's threads
    state_chg.m_prev_state = m_state;
    if(m_premature_end) m_state = UVM_PHASE_JUMPING;
    else m_state = UVM_PHASE_CLEANUP ;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))
    if (m_phase_proc != null) begin
      m_phase_proc.kill();
      m_phase_proc = null;
    end
    #0; // LET ANY WAITERS WAKE UP
    if (phase_done != null)
      phase_done.clear();
  end

  //------
  // DONE:
  //------
  m_premature_end = 0 ;
  if(m_jump_fwd || m_jump_bkwd) begin
    if(m_jump_fwd) begin
      clear_successors(UVM_PHASE_DONE,m_jump_phase);
    end
    m_jump_phase.clear_successors();
  end
  else begin

    if (m_phase_trace)
      `UVM_PH_TRACE("PH/TRC/DONE","Completed phase",this,UVM_LOW)
    state_chg.m_prev_state = m_state;
    m_state = UVM_PHASE_DONE;
    `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(this, state_chg))
    m_phase_proc = null;
    #0; // LET ANY WAITERS WAKE UP
  end
  #0; // LET ANY WAITERS WAKE UP
  if (phase_done != null)
    phase_done.clear();

//-----------
// SCHEDULED:
//-----------
  if(m_jump_fwd || m_jump_bkwd) begin
    void'(m_phase_hopper.try_put(m_jump_phase));
    m_jump_phase = null;
    m_jump_fwd = 0;
    m_jump_bkwd = 0;
  end
  // If more successors, schedule them to run now
  else if (m_successors.size() == 0) begin
    top.m_phase_all_done=1;
  end 
  else begin
    // execute all the successors
    foreach (m_successors[succ]) begin
      if(succ.m_state < UVM_PHASE_SCHEDULED) begin
        state_chg.m_prev_state = succ.m_state;
        state_chg.m_phase = succ;
        succ.m_state = UVM_PHASE_SCHEDULED;
        `uvm_do_callbacks(uvm_phase, uvm_phase_cb, phase_state_change(succ, state_chg))
        #0; // LET ANY WAITERS WAKE UP
        void'(m_phase_hopper.try_put(succ));
        if (m_phase_trace)
          `UVM_PH_TRACE("PH/TRC/SCHEDULED",{"Scheduled from phase ",get_full_name()},succ,UVM_LOW)
      end
    end
  end

endtask

function void uvm_phase::get_adjacent_predecessor_nodes(ref uvm_phase pred[]);
   bit done;
   bit predecessors[uvm_phase];
   int idx;

   // Get all predecessors (including TERMINALS, SCHEDULES, etc.)
   foreach (m_predecessors[p])
     predecessors[p] = 1;

   // Replace any terminal / schedule nodes with their predecessors,
   // recursively.
   do begin
      done = 1;
      foreach (predecessors[p]) begin
         if (p.get_phase_type() != UVM_PHASE_NODE) begin
            predecessors.delete(p);
            foreach (p.m_predecessors[next_p])
              predecessors[next_p] = 1;
            done = 0;
         end
      end
   end while (!done); 

   pred = new [predecessors.size()];
   foreach (predecessors[p]) begin
      pred[idx++] = p;
   end
endfunction : get_adjacent_predecessor_nodes

function void uvm_phase::get_adjacent_successor_nodes(ref uvm_phase succ[]);
   bit done;
   bit successors[uvm_phase];
   int idx;

   // Get all successors (including TERMINALS, SCHEDULES, etc.)
   foreach (m_successors[s])
     successors[s] = 1;

   // Replace any terminal / schedule nodes with their successors,
   // recursively.
   do begin
      done = 1;
      foreach (successors[s]) begin
         if (s.get_phase_type() != UVM_PHASE_NODE) begin
            successors.delete(s);
            foreach (s.m_successors[next_s])
              successors[next_s] = 1;
            done = 0;
         end
      end
   end while (!done); 

   succ = new [successors.size()];
   foreach (successors[s]) begin
      succ[idx++] = s;
   end
endfunction : get_adjacent_successor_nodes

// Internal implementation, more efficient than calling get_predessor_nodes on all
// of the successors returned by get_adjacent_successor_nodes
function void uvm_phase::get_predecessors_for_successors(output bit pred_of_succ[uvm_phase]);
    bit done;
    uvm_phase successors[];

    get_adjacent_successor_nodes(successors);
          
    // get all predecessors to these successors
    foreach (successors[s])
      foreach (successors[s].m_predecessors[pred])
        pred_of_succ[pred] = 1;
    
    // replace any terminal nodes with their predecessors, recursively.
    // we are only interested in "real" phase nodes
    do begin
      done=1;
      foreach (pred_of_succ[pred]) begin
        if (pred.get_phase_type() != UVM_PHASE_NODE) begin
          pred_of_succ.delete(pred); 
          foreach (pred.m_predecessors[next_pred])
            pred_of_succ[next_pred] = 1;
          done =0;
        end
      end
    end while (!done);


    // remove ourselves from the list
    pred_of_succ.delete(this);
endfunction


// m_wait_for_pred
// ---------------

task uvm_phase::m_wait_for_pred();

    bit pred_of_succ[uvm_phase];
    get_predecessors_for_successors(pred_of_succ);

    // wait for predecessors to successors (real phase nodes, not terminals)
    // mostly debug msgs
    foreach (pred_of_succ[sibling]) begin

      if (m_phase_trace) begin
        string s;
        s = $sformatf("Waiting for phase '%s' (%0d) to be READY_TO_END. Current state is %s",
            sibling.get_name(),sibling.get_inst_id(),sibling.m_state.name());
        `UVM_PH_TRACE("PH/TRC/WAIT_PRED_OF_SUCC",s,this,UVM_HIGH)
      end

      sibling.wait_for_state(UVM_PHASE_READY_TO_END, UVM_GTE);

      if (m_phase_trace) begin
        string s;
        s = $sformatf("Phase '%s' (%0d) is now READY_TO_END. Releasing phase",
            sibling.get_name(),sibling.get_inst_id());
        `UVM_PH_TRACE("PH/TRC/WAIT_PRED_OF_SUCC",s,this,UVM_HIGH)
      end

    end

    if (m_phase_trace) begin
      if (pred_of_succ.num()) begin
        string s = "( ";
        foreach (pred_of_succ[pred])
          s = {s, pred.get_full_name()," "};
        s = {s, ")"};
        `UVM_PH_TRACE("PH/TRC/WAIT_PRED_OF_SUCC",
              {"*** All pred to succ ",s," in READY_TO_END state, so ending phase ***"},this,UVM_HIGH)
      end
      else begin
        `UVM_PH_TRACE("PH/TRC/WAIT_PRED_OF_SUCC",
                    "*** No pred to succ other than myself, so ending phase ***",this,UVM_HIGH)
      end
    end

  #0; // LET ANY WAITERS WAKE UP

endtask


//---------------------------------
// Implementation - Synchronization
//---------------------------------

function void uvm_phase::m_report_null_objection(uvm_object obj,
                                               string description,
                                               int count,
                                               string action);
   string m_action;
   string m_addon;
   string m_obj_name = (obj == null) ? "uvm_top" : obj.get_full_name();
   
   if ((action == "raise") || (action == "drop")) begin
      if (count != 1)
        m_action = $sformatf("%s %0d objections", action, count);
      else
        m_action = $sformatf("%s an objection", action); 
   end
   else if (action == "get_objection_count") begin
      m_action = "call get_objection_count";
   end

   if (this.get_phase_type() == UVM_PHASE_IMP) begin
      m_addon = " (This is a UVM_PHASE_IMP, you have to query the schedule to find the UVM_PHASE_NODE)";
   end
   
   `uvm_error("UVM/PH/NULL_OBJECTION",
              $sformatf("'%s' attempted to %s on '%s', however '%s' is not a task-based phase node! %s",
                        m_obj_name,
                        m_action,
                        get_name(),
                        get_name(),
                        m_addon))
endfunction : m_report_null_objection
                        
   
// raise_objection
// ---------------

function void uvm_phase::raise_objection (uvm_object obj, 
                                                   string description="",
                                                   int count=1);
  if (phase_done != null)
    phase_done.raise_objection(obj,description,count);
  else
    m_report_null_objection(obj, description, count, "raise");
endfunction


// drop_objection
// --------------

function void uvm_phase::drop_objection (uvm_object obj, 
                                                  string description="",
                                                  int count=1);
  if (phase_done != null)
    phase_done.drop_objection(obj,description,count);
  else
    m_report_null_objection(obj, description, count, "drop");
endfunction

// get_objection_count
// -------------------

function int uvm_phase::get_objection_count (uvm_object obj=null);
   if (phase_done != null)
     return phase_done.get_objection_count(obj);
   else begin
      m_report_null_objection(obj, "" , 0, "get_objection_count");
      return 0;
   end
endfunction : get_objection_count

// sync
// ----

function void uvm_phase::sync(uvm_domain target,
                              uvm_phase phase=null,
                              uvm_phase with_phase=null);
  if (!this.is_domain()) begin
    `uvm_fatal("PH_BADSYNC","sync() called from a non-domain phase schedule node");
  end
  else if (target == null) begin
    `uvm_fatal("PH_BADSYNC","sync() called with a null target domain");
  end
  else if (!target.is_domain()) begin
    `uvm_fatal("PH_BADSYNC","sync() called with a non-domain phase schedule node as target");
  end
  else if (phase == null && with_phase != null) begin
    `uvm_fatal("PH_BADSYNC","sync() called with null phase and non-null with phase");
  end
  else if (phase == null) begin
    // whole domain sync - traverse this domain schedule from begin to end node and sync each node
    int visited[uvm_phase];
    uvm_phase queue[$];
    queue.push_back(this);
    visited[this] = 1;
    while (queue.size()) begin
      uvm_phase node;
      node = queue.pop_front();
      if (node.m_imp != null) begin
        sync(target, node.m_imp);
      end
      foreach (node.m_successors[succ]) begin
        if (!visited.exists(succ)) begin
          queue.push_back(succ);
          visited[succ] = 1;
        end
      end
    end
  end else begin
    // single phase sync
    // this is a 2-way ('with') sync and we check first in case it is already there
    uvm_phase from_node, to_node;
    int found_to[$], found_from[$];
    if(with_phase == null) with_phase = phase;
    from_node = find(phase);
    to_node = target.find(with_phase);
    if(from_node == null || to_node == null) return;
    found_to = from_node.m_sync.find_index(node) with (node == to_node);
    found_from = to_node.m_sync.find_index(node) with (node == from_node);
    if (found_to.size() == 0) from_node.m_sync.push_back(to_node);
    if (found_from.size() == 0) to_node.m_sync.push_back(from_node);
  end
endfunction


// unsync
// ------

function void uvm_phase::unsync(uvm_domain target,
                                uvm_phase phase=null,
                                uvm_phase with_phase=null);
  if (!this.is_domain()) begin
    `uvm_fatal("PH_BADSYNC","unsync() called from a non-domain phase schedule node");
  end else if (target == null) begin
    `uvm_fatal("PH_BADSYNC","unsync() called with a null target domain");
  end else if (!target.is_domain()) begin
    `uvm_fatal("PH_BADSYNC","unsync() called with a non-domain phase schedule node as target");
  end else if (phase == null && with_phase != null) begin
    `uvm_fatal("PH_BADSYNC","unsync() called with null phase and non-null with phase");
  end else if (phase == null) begin
    // whole domain unsync - traverse this domain schedule from begin to end node and unsync each node
    int visited[uvm_phase];
    uvm_phase queue[$];
    queue.push_back(this);
    visited[this] = 1;
    while (queue.size()) begin
      uvm_phase node;
      node = queue.pop_front();
      if (node.m_imp != null) unsync(target,node.m_imp);
      foreach (node.m_successors[succ]) begin
        if (!visited.exists(succ)) begin
          queue.push_back(succ);
          visited[succ] = 1;
        end
      end
    end
  end else begin
    // single phase unsync
    // this is a 2-way ('with') sync and we check first in case it is already there
    uvm_phase from_node, to_node;
    int found_to[$], found_from[$];
    if(with_phase == null) with_phase = phase;
    from_node = find(phase);
    to_node = target.find(with_phase);
    if(from_node == null || to_node == null) return;
    found_to = from_node.m_sync.find_index(node) with (node == to_node);
    found_from = to_node.m_sync.find_index(node) with (node == from_node);
    if (found_to.size()) from_node.m_sync.delete(found_to[0]);
    if (found_from.size()) to_node.m_sync.delete(found_from[0]);
  end
endfunction


// wait_for_state
//---------------
  
task uvm_phase::wait_for_state(uvm_phase_state state, uvm_wait_op op=UVM_EQ);
  case (op)
    UVM_EQ:  wait((state&m_state) != 0);
    UVM_NE:  wait((state&m_state) == 0);
    UVM_LT:  wait(m_state <  state);
    UVM_LTE: wait(m_state <= state);
    UVM_GT:  wait(m_state >  state);
    UVM_GTE: wait(m_state >= state);
  endcase
endtask


//-------------------------
// Implementation - Jumping
//-------------------------

// set_jump_phase
// ----
//
// Specify a phase to transition to when phase is complete.

function void uvm_phase::set_jump_phase(uvm_phase phase) ;
  uvm_phase d;

  if ((m_state <  UVM_PHASE_STARTED) ||
      (m_state >  UVM_PHASE_ENDED) )
  begin
   `uvm_error("JMPPHIDL", { "Attempting to jump from phase \"",
      get_name(), "\" which is not currently active (current state is ",
      m_state.name(), "). The jump will not happen until the phase becomes ",
      "active."})
  end



  // A jump can be either forward or backwards in the phase graph.
  // If the specified phase (name) is found in the set of predecessors
  // then we are jumping backwards.  If, on the other hand, the phase is in the set
  // of successors then we are jumping forwards.  If neither, then we
  // have an error.
  //
  // If the phase is non-existant and thus we don't know where to jump
  // we have a situation where the only thing to do is to uvm_report_fatal
  // and terminate_phase.  By calling this function the intent was to
  // jump to some other phase. So, continuing in the current phase doesn't
  // make any sense.  And we don't have a valid phase to jump to.  So we're done.

  d = m_find_predecessor(phase,0);
  if (d == null) begin
    d = m_find_successor(phase,0);
    if (d == null) begin
      string msg;
      $sformat(msg,{"phase %s is neither a predecessor or successor of ",
                    "phase %s or is non-existant, so we cannot jump to it.  ",
                    "Phase control flow is now undefined so the simulation ",
                    "must terminate"}, phase.get_name(), get_name());
      `uvm_fatal("PH_BADJUMP", msg);
    end
    else begin
      m_jump_fwd = 1;
      `uvm_info("PH_JUMPF",$sformatf("jumping forward to phase %s", phase.get_name()),
                UVM_DEBUG);
    end
  end
  else begin
    m_jump_bkwd = 1;
    `uvm_info("PH_JUMPB",$sformatf("jumping backward to phase %s", phase.get_name()),
              UVM_DEBUG);
  end
  
  m_jump_phase = d;
endfunction

// end_prematurely
// ----
//
// Set a flag to cause the phase to end prematurely.  

function void uvm_phase::end_prematurely() ;
   m_premature_end = 1 ;
endfunction

// jump
// ----
//
// Note that this function does not directly alter flow of control.
// That is, the new phase is not initiated in this function.
// Rather, flags are set which execute_phase() uses to determine
// that a jump has been requested and performs the jump.

function void uvm_phase::jump(uvm_phase phase);
   set_jump_phase(phase) ;
   end_prematurely() ;
endfunction


// jump_all
// --------
function void uvm_phase::jump_all(uvm_phase phase);
    `uvm_warning("NOTIMPL","uvm_phase::jump_all is not implemented and has been replaced by uvm_domain::jump_all")
endfunction


// get_jump_target
// ---------------
  
function uvm_phase uvm_phase::get_jump_target();
  return m_jump_phase;
endfunction


// clear
// -----
// for internal graph maintenance after a forward jump
function void uvm_phase::clear(uvm_phase_state state = UVM_PHASE_DORMANT);
  m_state = state;
  m_phase_proc = null;
  if (phase_done != null)
    phase_done.clear(this);
endfunction


// clear_successors
// ----------------
// for internal graph maintenance after a forward jump
// - called only by execute_phase()
// - depth-first traversal of the DAG, calliing clear() on each node
// - do not clear the end phase or beyond 
function void uvm_phase::clear_successors(uvm_phase_state state = UVM_PHASE_DORMANT, 
    uvm_phase end_state=null);
  if(this == end_state) 
    return;
  clear(state);
  foreach(m_successors[succ]) begin
    succ.clear_successors(state, end_state);
  end
endfunction


//---------------------------------
// Implementation - Overall Control
//---------------------------------
// wait_for_self_and_siblings_to_drop
// -----------------------------
// This task loops until this phase instance and all its siblings, either
// sync'd or sharing a common successor, have all objections dropped.
task uvm_phase::wait_for_self_and_siblings_to_drop() ;
  bit need_to_check_all = 1 ;
  uvm_root top;
  uvm_coreservice_t cs;
  bit siblings[uvm_phase];
  
  cs = uvm_coreservice_t::get();
  top = cs.get_root();
  
  get_predecessors_for_successors(siblings);
  foreach (m_sync[i]) begin
    siblings[m_sync[i]] = 1;
  end

  while (need_to_check_all) begin
    need_to_check_all = 0 ; //if all are dropped, we won't need to do this again

    // wait for own objections to drop
    if ((phase_done != null) && (phase_done.get_objection_total(top) != 0)) begin 
      m_state = UVM_PHASE_EXECUTING ;
      phase_done.wait_for(UVM_ALL_DROPPED, top);
      need_to_check_all = 1 ;
    end

    // now wait for siblings to drop
    foreach(siblings[sib]) begin
      sib.wait_for_state(UVM_PHASE_EXECUTING, UVM_GTE); // sibling must be at least executing 
      if ((sib.phase_done != null) && (sib.phase_done.get_objection_total(top) != 0)) begin
        m_state = UVM_PHASE_EXECUTING ;
        sib.phase_done.wait_for(UVM_ALL_DROPPED, top); // sibling must drop any objection
        need_to_check_all = 1 ;
      end
    end
  end
endtask

// kill
// ----

function void uvm_phase::kill();

  `uvm_info("PH_KILL", {"killing phase '", get_name(),"'"}, UVM_DEBUG);

  if (m_phase_proc != null) begin
    m_phase_proc.kill();
    m_phase_proc = null;
  end

endfunction


// kill_successors
// ---------------

// Using a depth-first traversal, kill all the successor phases of the
// current phase.
function void uvm_phase::kill_successors();
  foreach (m_successors[succ])
    succ.kill_successors();
  kill();
endfunction


// m_run_phases
// ------------

// This task contains the top-level process that owns all the phase
// processes.  By hosting the phase processes here we avoid problems
// associated with phase processes related as parents/children
task uvm_phase::m_run_phases();
  uvm_root top;
  uvm_coreservice_t cs;
  cs = uvm_coreservice_t::get();
  top = cs.get_root();

  // initiate by starting first phase in common domain
  begin
    uvm_phase ph = uvm_domain::get_common_domain();
    void'(m_phase_hopper.try_put(ph));
  end

  forever begin
    uvm_phase phase;
    m_phase_hopper.get(phase);
    fork
      begin
        phase.execute_phase();
      end
    join_none
    #0;  // let the process start running
  end
endtask


// terminate_phase
// ---------------

function void uvm_phase::m_terminate_phase();
  if (phase_done != null)
    phase_done.clear(this);
endfunction


// print_termination_state
// -----------------------

function void uvm_phase::m_print_termination_state();
  uvm_root top;
  uvm_coreservice_t cs;
  cs = uvm_coreservice_t::get();
  top = cs.get_root();
  if (phase_done != null) begin
    `uvm_info("PH_TERMSTATE",
              $sformatf("phase %s outstanding objections = %0d",
                        get_name(), phase_done.get_objection_total(top)),
              UVM_DEBUG)
  end
  else begin
    `uvm_info("PH_TERMSTATE",
              $sformatf("phase %s has no outstanding objections",
                        get_name()),
              UVM_DEBUG)
  end
endfunction



