// execute_phase// -------------taskuvm_phase::execute_phase();uvm_task_phasetask_phase;uvm_roottop;uvm_phase_state_changestate_chg;uvm_coreservice_tcs;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) nodesforeach(m_predecessors[pred])wait(pred.m_state==UVM_PHASE_DONE);
// 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/childrentaskuvm_phase::m_run_phases();uvm_roottop;uvm_coreservice_tcs;cs=uvm_coreservice_t::get();top=cs.get_root();// initiate by starting first phase in common domainbeginuvm_phaseph=uvm_domain::get_common_domain();void'(m_phase_hopper.try_put(ph));endforeverbeginuvm_phasephase;m_phase_hopper.get(phase);fork
////// @uvm-contrib For potential contribution to the 1800.2 standardclassuvm_phase_hopperextendsuvm_object;`uvm_object_utils(uvm_phase_hopper)// Function: new// Creates a new uvm_phase_hopper instance with ~name~.//externfunctionnew(stringname="uvm_phase_hopper");// Group: Singleton Accessors// Function: get_global_hopper// Returns the global phase hopper.//// This method is provided as a wrapper function to conveniently retrieve the// phase hopper via the <uvm_coreservice_t::get_phase_hopper> method.externstaticfunctionuvm_phase_hopperget_global_hopper();// Group: Queue API// Function: try_put// Attempts to add a new phase to the hopper.//// If the phase is successfully added to the internal queue, then// <raise_objection> is called for ~phase~, and '1' is returned.// If the phase can not be added to the internal queue, then no // objection is raised and '0' is returned.//// NOTE - By default the internal queue has no maximum depth, and// as such this method shall always succeed.externvirtualfunctionbittry_put(uvm_phasephase);
//// Note that the UVM core state shall transition to UVM_CORE_POST_RUN// when ~run_phases~ returns.externvirtualtaskrun_phases();// Task: process_phase// Processes a phase.//// The process_phase task transitions a phase from the SCHEDULED// to the DONE state. //// It calls the following tasks in order:// - sync_phase// - start_phase// - execute_phase// - end_phase// - cleanup_phase// - finish_phase//
// Task: execute_phase// Performs actions associated with transitioning phase state to the UVM_PHASE_EXECUTING state.externprotectedvirtualtaskexecute_phase(uvm_phasephase);// Task: end_phase// Performs actions associated with transitioning phase state to the UVM_PHASE_ENDED state.externprotectedvirtualtaskend_phase(uvm_phasephase);// Task: cleanup_phase// Performs actions associated with transitioning phase state to the UVM_PHASE_CLEANUP or UVM_PHASE_JUMPING state.externprotectedvirtualtaskcleanup_phase(uvm_phasephase);// Task: finish_phase// Performs actions associated with transitioning phase state to the UVM_PHASE_DONE state.externprotectedvirtualtaskfinish_phase(uvm_phasephase);// Task: wait_for_waiters// Delays execution to allow waiters on phase state changes to react.
//// If ~comp~ is null, then the default implementation shall pass// <uvm_root::get> to the traverse method.externvirtualfunctionvoidtraverse_on(uvm_phaseimp,uvm_componentcomp,uvm_phasenode,uvm_phase_statestate);// Function: execute_on// Calls ~execute~ on ~imp~, passing in ~comp~, and ~node~.//// Similar the ~traverse_on~, the ~execute_on~ function is a hook// that allows the phase hopper to witness, and potentially change// how a phase executes on a component.//// By default, the ~execute_on~ method calls <uvm_phase::execute>// for ~imp~ on ~comp~.externvirtualfunctionvoidexecute_on(uvm_phaseimp,uvm_componentcomp,uvm_phasenode);/// Implementation Artifactslocaluvm_phasem_queue[$];// Internal storagelocaluvm_objectionm_objection;// Tracks when all phases are completeendclass// uvm_phase_hopper/// Implementationfunctionuvm_phase_hopper::new(stringname="uvm_phase_hopper");super.new(name);m_objection=new("phase_hopper_objection");
endtask:start_phase// Inside the executing stagetaskuvm_phase_hopper::execute_phase(uvm_phasephase);uvm_phase_stateprev_state;prev_state=phase.get_state();phase.set_state(UVM_PHASE_EXECUTING);// Only nodes traverse_onif(phase.get_phase_type()!=UVM_PHASE_NODE)beginwait_for_waiters(phase,prev_state);return;endelsebeginuvm_roottop;uvm_phaseimp;uvm_task_phasetask_phase;top=uvm_root::get();imp=phase.get_imp();