ovm_phases.sv

Go to the documentation of this file.
00001 // $Id: a00253.html,v 1.1 2009/01/07 19:30:00 alex.marin Exp $
00002 //------------------------------------------------------------------------------
00003 //   Copyright 2007-2008 Mentor Graphics Corporation
00004 //   Copyright 2007-2008 Cadence Design Systems, Inc.
00005 //   All Rights Reserved Worldwide
00006 //
00007 //   Licensed under the Apache License, Version 2.0 (the
00008 //   "License"); you may not use this file except in
00009 //   compliance with the License.  You may obtain a copy of
00010 //   the License at
00011 //
00012 //       http://www.apache.org/licenses/LICENSE-2.0
00013 //
00014 //   Unless required by applicable law or agreed to in
00015 //   writing, software distributed under the License is
00016 //   distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00017 //   CONDITIONS OF ANY KIND, either express or implied.  See
00018 //   the License for the specific language governing
00019 //   permissions and limitations under the License.
00020 //------------------------------------------------------------------------------
00021 
00022 `ifndef OVM_PHASES_SVH
00023 `define OVM_PHASES_SVH
00024 
00025 typedef class ovm_component;
00026 
00027 //------------------------------------------------------------------------------
00028 //
00029 // Class: ovm_phase
00030 //
00031 //------------------------------------------------------------------------------
00032 // This class is a base class for a phase callback. All predefined OVM phases
00033 // and any user-defined phases alike use ovm_phase. To define a new phase:
00034 //
00035 // (1)  derive a subclass of ovm_phase that implements (overrides) either the
00036 //      call_task  or call_func method, depending on whether the new phase is
00037 //      to be time-consuming or not.  When calling super.new, your subclass must
00038 //      provide the name of phase (typically the name of the callback method),
00039 //      whether the method is to be called top-down or bottom-up, and whether
00040 //      the method is task or a function. For example, given a component type,
00041 //      my_comp, you can define a my_task phase for that component as follows:
00042 //
00043 //        class my_comp extends ovm_component;
00044 //          ...
00045 //          virtual my_task();  return; endtask // make virtual
00046 //          ...
00047 //        endclass
00048 //
00049 //        class my_task_phase extends ovm_phase;
00050 //          function new();
00051 //            super.new("my_task",1,1);
00052 //          endfunction
00053 //          task call_task(ovm_component parent);
00054 //             my_comp_type my_comp;
00055 //             if ($cast(my_comp,parent))
00056 //               my_comp.my_task_phase()
00057 //          endtask
00058 //        endclass
00059 //      
00060 //      Tip: The above can be defined via a convenient macro invocation:
00061 //
00062 //           `ovm_phase_task_topdown_decl(my_task)
00063 //
00064 // (2)  Create a global (or package-scope) instance of your phase object:
00065 //
00066 //        my_task_phase my_task_ph = new();
00067 //
00068 // (3)  Register the phase with the OVM's phase controller, ovm_top. For
00069 //      example, to register the my_task_phase as a phase for all my_comp-
00070 //      based components:
00071 //        
00072 //        ovm_top.insert_phase(my_task_ph, run_ph);
00073 //
00074 //      It should be global in nature so that it is universally available 
00075 //      to any process for getting or waiting on phase state.
00076 //
00077 // That's it! The ovm_top phase controller will now call my_comp-based components'
00078 // my_task phase callbacks in top-down order after completion of the run phase.
00079 //
00080 //
00081 // Type information methods:
00082 //
00083 //   The methods get_name, is_task, and is_top_down provide information about
00084 //   the phase's type.
00085 // 
00086 // Event & status methods:
00087 //
00088 //   The ovm_phase class defines an event interface that allows processes to
00089 //   wait until the phase begins or ends and to determine whether the phase is
00090 //   currently active (is_in_progress) or has completed (is_done). The reset
00091 //   method clears the phase state.
00092 //
00093 //------------------------------------------------------------------------------
00094 
00095 
00096 virtual class ovm_phase;
00097 
00098   local  string  m_name;
00099   local  bit     m_is_top_down;
00100   local  bit     m_is_task;
00101 
00102   local  event   m_start_event;
00103   local  bit     m_is_started=0;
00104   local  event   m_done_event;
00105   local  bit     m_is_done=0;
00106   local  bit     m_executed[int];
00107 
00108   local  ovm_phase m_aliases[$];
00109   local  ovm_phase m_insertion_phase;
00110 
00111   function new (string name, bit is_top_down, bit is_task);
00112     m_name = name;
00113     m_is_top_down = is_top_down;
00114     m_is_task     = is_task;
00115   endfunction
00116 
00117   //
00118   // Info interface
00119   //
00120   function string get_name       (); return m_name;        endfunction
00121   function bit    is_task        (); return m_is_task;     endfunction
00122   function bit    is_top_down    (); return m_is_top_down; endfunction
00123 
00124   virtual function string get_type_name();
00125     return "ovm_phase";
00126   endfunction
00127 
00128   //
00129   // Event & Status interface
00130   //
00131   task            wait_start     (); @m_start_event;       endtask
00132   task            wait_done      (); @m_done_event;        endtask
00133 
00134   function bit    is_in_progress (); return m_is_started;  endfunction
00135   function bit    is_done        (); return m_is_done;     endfunction
00136 
00137   function void   reset          (); m_is_done=0;
00138                                      m_is_started=0;       
00139                                      m_executed.delete();
00140                                      foreach(m_aliases[i]) 
00141                                        m_aliases[i].reset(); endfunction
00142 
00143   //
00144   // Virtual methods call_task/call_func: subclasses must define only one
00145   //
00146   virtual task call_task (ovm_component parent);
00147      foreach(m_aliases[i]) m_aliases[i].call_task(parent);
00148      return;
00149   endtask
00150 
00151   virtual function void call_func (ovm_component parent);
00152      foreach(m_aliases[i]) m_aliases[i].call_func(parent);
00153     return;
00154   endfunction
00155 
00156   // psuedo-private methods; do not call directly
00157 
00158   function void m_set_is_started(bit val);
00159     foreach(m_aliases[i]) m_aliases[i].m_set_is_started(val);
00160     m_is_started=val;
00161   endfunction
00162 
00163   function void m_set_in_progress();
00164     foreach(m_aliases[i]) m_aliases[i].m_set_in_progress();
00165     m_set_is_started(1);
00166     ->m_start_event;
00167   endfunction
00168 
00169   function void m_set_done();
00170     foreach(m_aliases[i]) m_aliases[i].m_set_done();
00171     m_is_done=1;
00172     m_set_is_started(0);
00173     ->m_done_event;
00174   endfunction
00175 
00176   function void set_insertion_phase(ovm_phase phase);
00177     if(m_insertion_phase != null) begin
00178       ovm_report_warning("INSPHS", "Cannot set the insertion phase for a phase that has already been set");
00179       return;
00180     end
00181     m_insertion_phase = phase;
00182   endfunction
00183 
00184   function ovm_phase get_insertion_phase();
00185     return m_insertion_phase;
00186   endfunction
00187 
00188   function bit has_executed(ovm_component comp);
00189     if(m_executed.exists(comp.get_inst_id())) return 1;
00190     foreach(m_aliases[i])
00191       if(m_aliases[i].has_executed(comp)) return 1;
00192     return 0;
00193   endfunction
00194 
00195   function void set_executed(ovm_component comp);
00196     m_executed[comp.get_inst_id()] = 1;
00197   endfunction
00198 
00199   function void add_alias(ovm_phase the_alias, exist_ph);
00200     ovm_phase insertion_phase;
00201     string    alias_nm, insrt_nm, alias_insrt_nm;
00202     //if the alias is null then return
00203     if(the_alias == null) return;
00204     if(the_alias == this && m_insertion_phase == exist_ph) return;
00205 
00206     alias_nm = the_alias.get_name();
00207 
00208     //This warning can't happen from ovm_root, but in theory a user could create
00209     //their own phase controller in which case, aliasing different names is probably
00210     //not desireable.
00211     if(alias_nm != get_name()) begin
00212       ovm_report_warning("PHSALS", {
00213         "Phases ", get_name(), " and ", alias_nm, 
00214         " are being aliased, but have different phase names"});
00215     end
00216 
00217     //verify that the aliased phase has the same semantics as the
00218     //master phase.
00219     if(m_is_task != the_alias.is_task()) begin
00220       ovm_report_fatal("PHSALS", {
00221         "Phases ", get_name(), " and ", alias_nm, 
00222         " are being aliased, but one is a function phase and one is a task phase"});
00223       return;
00224     end
00225     if(m_is_top_down != the_alias.is_top_down()) begin
00226       ovm_report_fatal("PHSALS", {
00227         "Phases ", get_name(), " and ", alias_nm, 
00228         " are being aliased, but one is top-down and the other is bottom-up"});
00229       return;
00230     end
00231     if(exist_ph != null)
00232        alias_insrt_nm = exist_ph.get_name();
00233     else
00234        alias_insrt_nm = "the topmost phase";
00235     if(m_insertion_phase != null)
00236        insrt_nm = m_insertion_phase.get_name();
00237     else
00238        insrt_nm = "the topmost phase";
00239     if(insrt_nm != alias_insrt_nm) begin
00240       ovm_report_fatal("PHSALS", {
00241         "Phases ", get_name(), " and ", alias_nm, 
00242         " are being aliased, they have different insertion phase, \"",
00243         insrt_nm, "\" versus \"", alias_insrt_nm, "\""}); 
00244       return;
00245     end
00246 
00247     //for existing aliases, we needed to verify the insertion phase
00248     //which is why we wait to the end before we exit.
00249     foreach(m_aliases[i]) if (the_alias == m_aliases[i]) return;
00250     if(the_alias == this) return;
00251 
00252     the_alias.set_insertion_phase(exist_ph);
00253     m_aliases.push_back(the_alias);
00254   endfunction
00255 endclass
00256 
00257 
00258 `endif // OVM_PHASES_SVH

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 2.0.1
Copyright (c) 2008 Intelligent Design Verification.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included here:
http://www.intelligentdv.com/licenses/fdl.txt
doxygen
Doxygen Version: 1.5.5
Wed Jan 7 19:27:18 2009
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV