URL
https://opencores.org/ocsvn/uart2bus_testbench/uart2bus_testbench/trunk
Subversion Repositories uart2bus_testbench
[/] [uart2bus_testbench/] [trunk/] [tb/] [uvm_src/] [base/] [uvm_task_phase.svh] - Rev 16
Compare with Previous | Blame | View Log
////----------------------------------------------------------------------// Copyright 2007-2011 Mentor Graphics Corporation// Copyright 2007-2010 Cadence Design Systems, Inc.// Copyright 2010 Synopsys, Inc.// Copyright 2013 NVIDIA Corporation// All Rights Reserved Worldwide//// Licensed under the Apache License, Version 2.0 (the// "License"); you may not use this file except in// compliance with the License. You may obtain a copy of// the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in// writing, software distributed under the License is// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR// CONDITIONS OF ANY KIND, either express or implied. See// the License for the specific language governing// permissions and limitations under the License.//----------------------------------------------------------------------//------------------------------------------------------------------------------//// Class: uvm_task_phase////------------------------------------------------------------------------------// Base class for all task phases.// It forks a call to <uvm_phase::exec_task()>// for each component in the hierarchy.//// The completion of the task does not imply, nor is it required for,// the end of phase. Once the phase completes, any remaining forked// <uvm_phase::exec_task()> threads are forcibly and immediately killed.//// By default, the way for a task phase to extend over time is if there is// at least one component that raises an objection.//| class my_comp extends uvm_component;//| task main_phase(uvm_phase phase);//| phase.raise_objection(this, "Applying stimulus")//| ...//| phase.drop_objection(this, "Applied enough stimulus")//| endtask//| endclass////// There is however one scenario wherein time advances within a task-based phase// without any objections to the phase being raised. If two (or more) phases// share a common successor, such as the <uvm_run_phase> and the// <uvm_post_shutdown_phase> sharing the <uvm_extract_phase> as a successor,// then phase advancement is delayed until all predecessors of the common// successor are ready to proceed. Because of this, it is possible for time to// advance between <uvm_component::phase_started> and <uvm_component::phase_ended>// of a task phase without any participants in the phase raising an objection.//virtual class uvm_task_phase extends uvm_phase;// Function: new//// Create a new instance of a task-based phase//function new(string name);super.new(name,UVM_PHASE_IMP);endfunction// Function: traverse//// Traverses the component tree in bottom-up order, calling <execute> for// each component. The actual order for task-based phases doesn't really// matter, as each component task is executed in a separate process whose// starting order is not deterministic.//virtual function void traverse(uvm_component comp,uvm_phase phase,uvm_phase_state state);phase.m_num_procs_not_yet_returned = 0;m_traverse(comp, phase, state);endfunctionfunction void m_traverse(uvm_component comp,uvm_phase phase,uvm_phase_state state);string name;uvm_domain phase_domain =phase.get_domain();uvm_domain comp_domain = comp.get_domain();uvm_sequencer_base seqr;if (comp.get_first_child(name))dom_traverse(comp.get_child(name), phase, state);while(comp.get_next_child(name));if (m_phase_trace)`uvm_info("PH_TRACE",$sformatf("topdown-phase phase=%s state=%s comp=%s comp.domain=%s phase.domain=%s",phase.get_name(), state.name(), comp.get_full_name(),comp_domain.get_name(),phase_domain.get_name()),UVM_DEBUG)if (phase_domain == uvm_domain::get_common_domain() ||phase_domain == comp_domain) begincase (state)UVM_PHASE_STARTED: begincomp.m_current_phase = phase;comp.m_apply_verbosity_settings(phase);comp.phase_started(phase);if ($cast(seqr, comp))seqr.start_phase_sequence(phase);endUVM_PHASE_EXECUTING: beginuvm_phase ph = this;if (comp.m_phase_imps.exists(this))ph = comp.m_phase_imps[this];ph.execute(comp, phase);endUVM_PHASE_READY_TO_END: begincomp.phase_ready_to_end(phase);endUVM_PHASE_ENDED: beginif ($cast(seqr, comp))seqr.stop_phase_sequence(phase);comp.phase_ended(phase);comp.m_current_phase = null;enddefault:`uvm_fatal("PH_BADEXEC","task phase traverse internal error")endcaseendendfunction// Function: execute//// Fork the task-based phase ~phase~ for the component ~comp~.//virtual function void execute(uvm_component comp,uvm_phase phase);forkbeginprocess proc;// reseed this process for random stabilityproc = process::self();proc.srandom(uvm_create_random_seed(phase.get_type_name(), comp.get_full_name()));phase.m_num_procs_not_yet_returned++;exec_task(comp,phase);phase.m_num_procs_not_yet_returned--;endjoin_noneendfunctionendclass
