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 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 Version: 1.5.5 Wed Jan 7 19:27:18 2009 |