00001 // $Id: ovm__root_8svh-source.html,v 1.1 2008/10/07 21:54:19 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_ROOT_SVH 00023 `define OVM_ROOT_SVH 00024 00025 `define OVM_DEFAULT_TIMEOUT 9200s 00026 00027 //------------------------------------------------------------------------------ 00028 // 00029 // CLASS: ovm_root (phase controller) 00030 // 00031 //------------------------------------------------------------------------------ 00032 // The OVM environment contains a single instance of ovm_root, called ovm_top. 00033 // The ovm_top serves as THE top-level component for all components. A component 00034 // becomes a child of ovm_top when its 'parent' constructor argument is null. 00035 // 00036 // run_test 00037 // Phases all components through all registered phases. If the optional 00038 // test_name argument is provided, or if a command-line plusarg, +OVM_TESTNAME, 00039 // is found, the specified test is created prior to phasing. The test may 00040 // contain new verification components or the entire testbench, in which case 00041 // the test and testbench can be chosen from the command line without forcing 00042 // recompilation. If the global (package) variable, finish_on_completion, is 00043 // set, $finish is called after phasing completes. 00044 // 00045 // insert_phase 00046 // This method is used to register phases with ovm_root. The new phase (1st 00047 // argument) is inserted _after_ the phase given by the 2nd argument. If the 00048 // 2nd argument is null, the new phase becomes the first phase. 00049 // 00050 // run_global_phase 00051 // Note: all phasing should be started via run_test. This method is used to 00052 // run up to and through the phase given by the 1st argument. If null, then 00053 // all remaining phases will be run, effectively completing simulation. 00054 // 00055 // stop_request 00056 // Calling this function triggers the process of shutting down the currently 00057 // running task-based phase. This process involves calling all components' 00058 // stop tasks for those components whose enable_stop_interrupt bit is set. 00059 // Once all stop tasks return, or once the optional global_stop_timeout 00060 // expires, all components' kill method is called, effectively ending the 00061 // current phase. The ovm_top will then begin execution of the next phase, 00062 // if any. 00063 // 00064 // find / find_all 00065 // Returns the component handle (find) or list of components handles (find_all) 00066 // matching a given string. The string may contain the wildcards, * and ?. 00067 // Strings beginning with '.' are absolute path names. If optional comp arg 00068 // provided, search begins from that component down (default=all components). 00069 // 00070 // time phase_timeout / stop_timeout 00071 // These set watchdog timers for task-based phases and stop tasks. Their 00072 // default value is set to the maximum time. A timeout at this value usually 00073 // indicates a problem with your testbench. You should lower the timeout to 00074 // prevent "never-ending" simulations. Setting the value to 0 turns off the 00075 // timer. 00076 // 00077 // enable_print_topology 00078 // If set, the topology is printed just after the end_of_elaboration phase. 00079 // 00080 // finish_on_completion 00081 // If set, run_test will issue a $finish after all phases are executed. 00082 //------------------------------------------------------------------------------ 00083 00084 00085 class ovm_root extends ovm_component; 00086 00087 extern static function ovm_root get(); 00088 00089 extern virtual task run_test (string test_name=""); 00090 00091 extern task run_global_phase (ovm_phase phase=null); 00092 00093 extern function void stop_request (); 00094 00095 extern function void insert_phase (ovm_phase new_phase, 00096 ovm_phase exist_phase); 00097 extern function 00098 ovm_component find (string comp_match); 00099 extern function void find_all (string comp_match, 00100 ref ovm_component comps[$], 00101 input ovm_component comp=null); 00102 00103 extern function ovm_phase get_current_phase (); 00104 extern function ovm_phase get_phase_by_name (string name); 00105 00106 virtual function string get_type_name(); return "ovm_root"; endfunction 00107 00108 time phase_timeout = 0; 00109 time stop_timeout = 0; 00110 bit enable_print_topology = 0; 00111 bit finish_on_completion = 1; 00112 00113 00114 // PRIVATE members 00115 00116 extern `_protected function new (); 00117 00118 extern local task m_do_phase_all (ovm_component comp, ovm_phase phase); 00119 extern local task m_stop_process (); 00120 extern local task m_stop_request (time timeout=0); 00121 extern local task m_do_stop_all (ovm_component comp); 00122 extern local function void m_reset_phase(ovm_component comp, 00123 ovm_phase phase=null); 00124 00125 local ovm_phase m_phase_q[ovm_phase]; 00126 local ovm_phase m_first_phase = null; 00127 local ovm_phase m_last_phase = null; 00128 local event m_stop_request_e; 00129 00130 ovm_phase m_curr_phase = null; 00131 static local ovm_root m_inst; 00132 00133 /*** DEPRECATED - Do not use in new code. Convert code when appropriate ***/ 00134 extern function void print_unit_list (ovm_component comp=null); 00135 extern function void print_unit (string name, ovm_printer printer=null); 00136 extern function void print_units (ovm_printer printer=null); 00137 extern function void print_topology (ovm_printer printer=null); 00138 00139 endclass 00140 00141 // ovm_enable_print_topology (global, deprecated) 00142 // ------------------------- 00143 00144 bit ovm_enable_print_topology = 0; 00145 00146 // our singleton top-level; it is initialized upon first call to ovm_root::get 00147 00148 `const ovm_root ovm_top = ovm_root::get(); 00149 00150 00151 // run_test 00152 // -------- 00153 00154 task run_test (string test_name=""); 00155 ovm_root top; 00156 top = ovm_root::get(); 00157 top.run_test(test_name); 00158 endtask 00159 00160 00161 // global_stop_request 00162 // ------------------- 00163 00164 function void global_stop_request(); 00165 ovm_root top; 00166 top = ovm_root::get(); 00167 top.stop_request(); 00168 endfunction 00169 00170 00171 // set_global_timeout 00172 // ------------------ 00173 00174 function void set_global_timeout(time timeout); 00175 ovm_root top; 00176 top = ovm_root::get(); 00177 top.phase_timeout = timeout; 00178 endfunction 00179 00180 00181 // set_global_stop_timeout 00182 // ----------------------- 00183 00184 function void set_global_stop_timeout(time timeout); 00185 ovm_root top; 00186 top = ovm_root::get(); 00187 top.stop_timeout = timeout; 00188 endfunction 00189 00190 00191 // ovm_find_component (deprecated) 00192 // ------------------ 00193 00194 function ovm_component ovm_find_component (string comp_name); 00195 ovm_root top; 00196 top = ovm_root::get(); 00197 return top.find(comp_name); 00198 endfunction 00199 00200 00201 // ovm_print_topology (deprecated) 00202 // ------------------ 00203 00204 function void ovm_print_topology(ovm_printer printer=null); 00205 ovm_report_handler::ovm_report_deprecated("ovm_print_topology()"); 00206 ovm_top.print_topology(printer); 00207 endfunction 00208 00209 00210 00211 //----------------------------------------------------------------------------- 00212 // 00213 // IMPLEMENTATION 00214 // 00215 //----------------------------------------------------------------------------- 00216 00217 // get 00218 // --- 00219 00220 function ovm_root ovm_root::get(); 00221 if (m_inst == null) 00222 m_inst = new(); 00223 return m_inst; 00224 endfunction 00225 00226 00227 // new 00228 // --- 00229 00230 function ovm_root::new(); 00231 super.new("__top__", null); 00232 report_header(); 00233 print_enabled=0; 00234 endfunction 00235 00236 00237 00238 //------------------------------------------------------------------------------ 00239 // Primary Simulation Entry Points 00240 //------------------------------------------------------------------------------ 00241 00242 ovm_component ovm_test_top; // deprecated; do not use 00243 00244 // run_test 00245 // -------- 00246 00247 task ovm_root::run_test(string test_name=""); 00248 00249 ovm_factory factory = ovm_factory::get(); 00250 bit testname_plusarg; 00251 string msg; 00252 00253 testname_plusarg = 0; 00254 00255 // plusarg overrides argument 00256 if ($value$plusargs("OVM_TESTNAME=%s", test_name)) 00257 testname_plusarg = 1; 00258 00259 if ($value$plusargs("TESTNAME=%s", test_name)) begin 00260 ovm_report_warning("DPRFT", 00261 "+TESTNAME is deprecated. Use +OVM_TESTNAME instead."); 00262 testname_plusarg = 1; 00263 end 00264 00265 // if test now defined, create it using common factory 00266 if (test_name != "") begin 00267 if(m_children.exists("ovm_test_top")) begin 00268 ovm_report_fatal("TTINST", 00269 "An ovm_test_top already exists via a previous call to run_test"); 00270 #0; // forces shutdown because $finish is forked 00271 end 00272 $cast(ovm_test_top, factory.create_component_by_name(test_name, 00273 "ovm_test_top", "ovm_test_top", null)); 00274 00275 assert_test_not_found : assert(ovm_test_top != null) else begin 00276 msg = testname_plusarg ? "command line (+OVM_TESTNAME=": "call to run_test("; 00277 ovm_report_fatal("INVTST", 00278 {"Requested test from ",msg, test_name, ") not found." }); 00279 $fatal; 00280 end 00281 end 00282 00283 if (m_children.num() == 0) begin 00284 ovm_report_fatal("NOCOMP", 00285 {"No components instantiated. You must instantiate", 00286 " at least one component before calling run_test. To run", 00287 " a test, use +OVM_TESTNAME or supply the test name in", 00288 " the argument to run_test(). Exiting simulation."}); 00289 return; 00290 end 00291 00292 ovm_report_info("RNTST", {"Running test ",test_name, "..."}, OVM_LOW); 00293 00294 fork 00295 // isolated from calling process 00296 run_global_phase(); 00297 join 00298 00299 report_summarize(); 00300 00301 if (finish_on_completion) begin 00302 // forking allows current delta to complete 00303 fork 00304 $finish; 00305 join_none 00306 end 00307 00308 endtask 00309 00310 00311 // m_reset_phase 00312 // ------------- 00313 00314 function void ovm_root::m_reset_phase(ovm_component comp, ovm_phase phase=null); 00315 string name; 00316 00317 if (comp.get_first_child(name)) 00318 do 00319 this.m_reset_phase(comp.get_child(name)); 00320 while (comp.get_next_child(name)); 00321 00322 comp.m_curr_phase=phase; 00323 00324 endfunction 00325 00326 //------------------------------------------------------------------------------ 00327 // Phase control 00328 //------------------------------------------------------------------------------ 00329 00330 // run_global_phase 00331 // ---------------- 00332 00333 task ovm_root::run_global_phase(ovm_phase phase=null); 00334 00335 time timeout; 00336 00337 if (m_curr_phase != null) begin 00338 ovm_report_fatal("PHSSTR", "Global phasing has already started."); 00339 #0; // forces shutdown because $finish is forked 00340 return; 00341 end 00342 00343 // If we weren't given a specific phase, run through them all. 00344 00345 if (phase == null) begin 00346 phase = m_last_phase; 00347 end 00348 00349 if (!m_phase_q.exists(phase)) begin 00350 ovm_report_fatal("PHNTFD", {"Phase %0s not registered.",phase.get_name()}); 00351 return; 00352 end 00353 00354 if (m_curr_phase == phase || phase.is_done()) begin 00355 ovm_report_warning("PHDONE", $psprintf( 00356 "Phase '%0s' already executed. Current phase is '%0s'.", 00357 phase.get_name(), m_curr_phase.get_name())); 00358 return; 00359 end 00360 00361 // MAIN LOOP: Executes all phases from the current phase 00362 // through the phase given in the argument. 00363 while (m_curr_phase != phase) begin 00364 00365 if (m_curr_phase == null) 00366 m_curr_phase = m_first_phase; 00367 else 00368 m_curr_phase = m_phase_q[m_curr_phase]; 00369 00370 // Trigger phase's in_progress event. 00371 // The #0 allows any waiting processes to resume before we continue. 00372 m_curr_phase.m_set_in_progress(); 00373 #0; 00374 00375 ovm_report_info("STARTPH", 00376 $psprintf("STARTING PHASE %0s",m_curr_phase.get_name()),int'(OVM_FULL)+1); 00377 00378 // TASK-based phase 00379 if (m_curr_phase.is_task()) begin 00380 00381 event wait_forever; 00382 00383 timeout = (phase_timeout==0) ? `OVM_DEFAULT_TIMEOUT - $time : 00384 phase_timeout; 00385 00386 `ifdef INCA 00387 00388 // IUS does not support disabling named fork blocks, so we isolate the 00389 // inner fork block so we can kill it using disable fork 00390 fork // guard process 00391 begin 00392 00393 fork 00394 00395 // Start an independent process that kills the phase, else the killing 00396 // stops prematurely at the component that issued the request. 00397 m_stop_process(); 00398 00399 begin // guard process 00400 fork 00401 begin 00402 #0; // ensures stop_process active before potential stop_request 00403 m_do_phase_all(this,m_curr_phase); 00404 @wait_forever; // wait for stop or timeout 00405 end 00406 begin 00407 #timeout ovm_report_error("TIMOUT", 00408 $psprintf("Watchdog timeout of '%0t' expired.", timeout)); 00409 end 00410 join_any 00411 disable fork; 00412 end // end guard process 00413 00414 join_any 00415 disable fork; 00416 00417 end 00418 join // end guard process 00419 00420 `else // QUESTA 00421 00422 fork : task_based_phase 00423 m_stop_process(); 00424 begin 00425 m_do_phase_all(this,m_curr_phase); 00426 wait fork; 00427 end 00428 #timeout ovm_report_error("TIMOUT", 00429 $psprintf("Watchdog timeout of '%0x' expired.", timeout)); 00430 join_any 00431 disable task_based_phase; 00432 00433 `endif // INCA-QUESTA 00434 00435 end // if (is_task) 00436 00437 // FUNCTION-based phase 00438 else begin 00439 m_do_phase_all(this,m_curr_phase); 00440 end 00441 00442 ovm_report_info("ENDPH", 00443 $psprintf("ENDING PHASE %0s",m_curr_phase.get_name()),int'(OVM_FULL)+1); 00444 00445 // Trigger phase's done event. 00446 // The #0 allows any waiting processes to resume before we continue. 00447 m_curr_phase.m_set_done(); 00448 #0; 00449 00450 // If error occurred during elaboration, exit with FATAL. 00451 if (m_curr_phase == end_of_elaboration_ph) begin 00452 ovm_report_server srvr; 00453 srvr = get_report_server(); 00454 if(srvr.get_severity_count(OVM_ERROR) > 0) begin 00455 ovm_report_fatal("ovm", "elaboration errors"); 00456 #0; // $finish is called in a forked process in ovm_report_object::die. 00457 // this forces that process to start, preventing us from continuing 00458 end 00459 00460 if (enable_print_topology || ovm_enable_print_topology) 00461 print_topology(); 00462 end 00463 00464 // if next phase is end_of_elab, the resolve all connections 00465 if (m_phase_q[m_curr_phase] == end_of_elaboration_ph) 00466 do_resolve_bindings(); 00467 00468 end 00469 00470 endtask 00471 00472 00473 // m_do_phase_all 00474 // -------------- 00475 00476 task ovm_root::m_do_phase_all (ovm_component comp, ovm_phase phase); 00477 00478 // run_global_phase calls this private task for each phase in consecutive 00479 // order. If the phase is a function, then all components' functions are 00480 // called sequentially in top-down or bottom-up order. If the phase is a 00481 // task, all components' do_task_phase tasks are forked and we return 00482 // with no waiting. The caller can subsequently call 'wait fork' to wait 00483 // for the forked tasks to complete. 00484 00485 ovm_phase curr_phase; 00486 bit done[string]; 00487 00488 curr_phase = comp.m_curr_phase; 00489 00490 // This while loop is needed in case new componenents are created 00491 // several phases into a simulation. 00492 00493 while (curr_phase != phase) begin 00494 00495 ovm_phase ph; 00496 done.delete(); 00497 00498 if (curr_phase == null) 00499 curr_phase = m_first_phase; 00500 else 00501 curr_phase = m_phase_q[curr_phase]; 00502 00503 // bottom-up 00504 if (!curr_phase.is_top_down()) begin 00505 string name; 00506 if (comp.get_first_child(name)) begin 00507 do begin 00508 m_do_phase_all(comp.get_child(name),curr_phase); 00509 done[name] = 1; 00510 end 00511 while (comp.get_next_child(name)); 00512 end 00513 end 00514 00515 ovm_report_info("COMPPH", $psprintf("*** comp %0s (%0s) curr_phase is %0s", 00516 comp.get_full_name(),comp.get_type_name(),curr_phase.get_name()),int'(OVM_FULL)+1); 00517 00518 if (curr_phase.is_task()) begin 00519 // We fork here to ensure that do_task_phase, a user-overridable task, 00520 // does not inadvertently block this process 00521 fork 00522 comp.do_task_phase(curr_phase); 00523 join_none 00524 end 00525 else 00526 comp.do_func_phase(curr_phase); 00527 00528 // bottom-up 2nd pass: phase newly created components, if any 00529 if (!curr_phase.is_top_down()) begin 00530 00531 while (comp.get_num_children() != done.num()) begin 00532 string name; 00533 if (comp.get_first_child(name)) begin 00534 do begin 00535 if (!done.exists(name)) begin 00536 m_do_phase_all(comp.get_child(name),curr_phase); 00537 done[name] = 1; 00538 end 00539 end 00540 while (comp.get_next_child(name)); 00541 end 00542 end 00543 end 00544 00545 // top-down 00546 else begin 00547 string name; 00548 if (comp.get_first_child(name)) 00549 do begin 00550 m_do_phase_all(comp.get_child(name),curr_phase); 00551 end 00552 while (comp.get_next_child(name)); 00553 end 00554 00555 end 00556 endtask 00557 00558 00559 // get_current_phase 00560 // ----------------- 00561 00562 function ovm_phase ovm_root::get_current_phase(); 00563 return m_curr_phase; 00564 endfunction 00565 00566 00567 //------------------------------------------------------------------------------ 00568 // Stopping 00569 //------------------------------------------------------------------------------ 00570 00571 // stop_request 00572 // ------------ 00573 00574 function void ovm_root::stop_request(); 00575 ->m_stop_request_e; 00576 endfunction 00577 00578 00579 // m_stop_process 00580 // -------------- 00581 00582 task ovm_root::m_stop_process(); 00583 @m_stop_request_e; 00584 m_stop_request(stop_timeout); 00585 endtask 00586 00587 00588 // m_stop_request 00589 // -------------- 00590 00591 task ovm_root::m_stop_request(time timeout=0); 00592 00593 if (timeout == 0) 00594 timeout = `OVM_DEFAULT_TIMEOUT - $time; 00595 00596 // stop request valid for running task-based phases only 00597 if (m_curr_phase == null || !m_curr_phase.is_task()) begin 00598 ovm_report_warning("STPNA", 00599 $psprintf("Stop-request has no effect outside non-time-consuming phases", 00600 "current phase is ",m_curr_phase==null? 00601 "none (not started":m_curr_phase.get_name())); 00602 return; 00603 end 00604 00605 // All stop tasks are forked from a single thread so 'wait fork' 00606 // can be used. We fork the single thread as well so that 'wait fork' 00607 // does not wait for threads previously started by the caller's thread. 00608 00609 // IUS does not support disabling named fork blocks, so we isolate the 00610 // inner fork block so we can kill it using disable fork 00611 `ifdef INCA 00612 00613 fork begin // guard process 00614 fork 00615 begin 00616 m_do_stop_all(this); 00617 wait fork; 00618 end 00619 begin 00620 #timeout ovm_report_warning("STPTO", 00621 $psprintf("Stop-request timeout of %0t expired. Stopping phase '%0s'", 00622 timeout, m_curr_phase.get_name())); 00623 end 00624 join_any 00625 disable fork; 00626 end 00627 join 00628 00629 `else // QUESTA 00630 00631 fork : stop_tasks 00632 begin 00633 m_do_stop_all(this); 00634 wait fork; 00635 end 00636 begin 00637 #timeout ovm_report_warning("STPTO", 00638 $psprintf("Stop-request timeout of %0t expired. Stopping phase '%0s'", 00639 timeout, m_curr_phase.get_name())); 00640 end 00641 join_any 00642 disable stop_tasks; 00643 00644 `endif // INCA 00645 00646 // all stop processes have completed, or a timeout has occured 00647 this.do_kill_all(); 00648 00649 endtask 00650 00651 00652 // m_do_stop_all 00653 // ------------- 00654 00655 task ovm_root::m_do_stop_all(ovm_component comp); 00656 00657 string name; 00658 00659 // we use an external traversal to ensure all forks are 00660 // made from a single threaad. 00661 if (comp.get_first_child(name)) 00662 do begin 00663 m_do_stop_all(comp.get_child(name)); 00664 end 00665 while (comp.get_next_child(name)); 00666 00667 if (comp.enable_stop_interrupt) begin 00668 fork begin 00669 comp.stop(m_curr_phase.get_name()); 00670 end 00671 join_none 00672 end 00673 00674 endtask 00675 00676 00677 //------------------------------------------------------------------------------ 00678 // Phase Insertion 00679 //------------------------------------------------------------------------------ 00680 00681 // insert_phase 00682 // ------------ 00683 00684 function void ovm_root::insert_phase(ovm_phase new_phase, 00685 ovm_phase exist_phase); 00686 ovm_phase exist_ph; 00687 string s; 00688 00689 if (build_ph.is_done()) begin 00690 ovm_report_fatal("PHINST", "Phase insertion after build phase prohibited."); 00691 return; 00692 end 00693 00694 if (exist_phase != null && exist_phase.is_done() || 00695 exist_phase == null && m_curr_phase != null) begin 00696 ovm_report_fatal("PHINST", {"Can not insert a phase at a point that has ", 00697 "already executed. Current phase is '", m_curr_phase.get_name(),"'."}); 00698 return; 00699 end 00700 00701 if (new_phase == null) begin 00702 ovm_report_fatal("PHNULL", "Phase argument is null."); 00703 return; 00704 end 00705 00706 if (exist_phase != null && !m_phase_q.exists(exist_phase)) begin 00707 ovm_report_fatal("PHNTFD", {"Phase '",exist_phase.get_name(), 00708 "' is not registered."}); 00709 return; 00710 end 00711 00712 if (m_phase_q.exists(new_phase)) begin 00713 if ((exist_phase == null && m_first_phase != new_phase) || 00714 (exist_phase != null && m_phase_q[exist_phase] != new_phase)) begin 00715 ovm_report_error("PHDUPL", {"Phase '", new_phase.get_name(), 00716 "' is already registered in a different order."}); 00717 end 00718 return; 00719 end 00720 00721 if (exist_phase == null) begin 00722 m_phase_q[new_phase] = m_first_phase; 00723 m_first_phase = new_phase; 00724 end 00725 else begin 00726 m_phase_q[new_phase] = m_phase_q[exist_phase]; 00727 m_phase_q[exist_phase] = new_phase; 00728 end 00729 00730 if (m_phase_q[new_phase] == null) 00731 m_last_phase = new_phase; 00732 00733 endfunction 00734 00735 00736 // get_phase_by_name 00737 // ----------------- 00738 00739 function ovm_phase ovm_root::get_phase_by_name (string name); 00740 ovm_phase m_ph; 00741 foreach (m_phase_q[ph]) begin 00742 m_ph = ph; 00743 if(m_ph.get_name() == name) 00744 return ph; 00745 end 00746 return null; 00747 endfunction 00748 00749 00750 //------------------------------------------------------------------------------ 00751 // Component Search & Printing 00752 //------------------------------------------------------------------------------ 00753 00754 00755 // find_all 00756 // -------- 00757 00758 function void ovm_root::find_all(string comp_match, ref ovm_component comps[$], 00759 input ovm_component comp=null); 00760 string name; 00761 `ifdef INCA 00762 static ovm_component tmp[$]; //static list to work around ius 6.2 limitation 00763 static bit s_is_child; //starts at 0 for the root call 00764 bit is_child; //automatic variable gets updated immediately on entry 00765 is_child = s_is_child; 00766 `endif 00767 00768 if (comp==null) 00769 comp = this; 00770 00771 if (comp.get_first_child(name)) 00772 do begin 00773 `ifdef INCA 00774 //Indicate that a recursive call is being made. Using a static variable 00775 //since this is a temp workaround and we don't want to effect the 00776 //function prototype. 00777 s_is_child = 1; 00778 this.find_all(comp_match,tmp,comp.get_child(name)); 00779 s_is_child = 0; //reset for a future call. 00780 //Only copy to the component list if this is the top of the stack, 00781 //otherwise an infinite loop will result copying tmp to itself. 00782 if(is_child==0) 00783 while(tmp.size()) comps.push_back(tmp.pop_front()); 00784 `else 00785 this.find_all(comp_match,comps,comp.get_child(name)); 00786 `endif 00787 end 00788 while (comp.get_next_child(name)); 00789 00790 if (ovm_is_match(comp_match, comp.get_full_name()) && 00791 comp.get_name() != "") /* ovm_top */ 00792 comps.push_back(comp); 00793 00794 endfunction 00795 00796 00797 // find 00798 // ---- 00799 00800 function ovm_component ovm_root::find (string comp_match); 00801 `ifdef INCA 00802 static ovm_component comp_list[$]; 00803 comp_list.delete(); 00804 `else 00805 ovm_component comp_list[$]; 00806 `endif 00807 00808 find_all(comp_match,comp_list); 00809 00810 if (comp_list.size() > 1) 00811 ovm_report_warning("MMATCH", 00812 $psprintf("Found %0d components matching '%s'. Returning first match, %0s.", 00813 comp_list.size(),comp_match,comp_list[0].get_full_name())); 00814 00815 if (comp_list.size() == 0) 00816 ovm_report_warning("CMPNFD", 00817 {"Component matching '",comp_match,"' was not found in the list of ovm_components"}); 00818 return comp_list[0]; 00819 endfunction 00820 00821 00822 //------------------------------------------------------------------------------ 00823 // 00824 // REVIEW FOR DEPRECATION OR REMOVAL 00825 // 00826 //------------------------------------------------------------------------------ 00827 00828 // print_unit 00829 // ---------- 00830 00831 function void ovm_root::print_unit (string name, ovm_printer printer=null); 00832 00833 ovm_component comp; 00834 comp = find(name); 00835 if (comp) 00836 comp.print(printer); 00837 endfunction 00838 00839 00840 // print_units 00841 // ----------- 00842 00843 function void ovm_root::print_units (ovm_printer printer=null); 00844 00845 // Can replace implementation with one line, which will produce single table 00846 // this.print(printer); 00847 00848 string s; 00849 00850 if (m_children.num()==0) begin 00851 ovm_report_warning("EMTCOMP", "No OVM components to print."); 00852 return; 00853 end 00854 00855 if (printer==null) 00856 printer = ovm_default_printer; 00857 00858 if (printer.knobs.sprint) 00859 s = printer.m_string; 00860 00861 foreach (m_children[c]) begin 00862 if(m_children[c].print_enabled) begin 00863 printer.print_object("", m_children[c]); 00864 if(printer.knobs.sprint) 00865 s = {s, printer.m_string}; 00866 end 00867 end 00868 00869 printer.m_string = s; 00870 00871 00872 endfunction 00873 00874 00875 // print_unit_list 00876 // --------------- 00877 00878 function void ovm_root::print_unit_list(ovm_component comp=null); 00879 00880 string name; 00881 00882 if (comp==null) begin 00883 comp = this; 00884 if (m_children.num()==0) begin 00885 ovm_report_warning("NOUNIT","No OVM components to print. "); 00886 return; 00887 end 00888 $display("List of ovm components"); 00889 end 00890 else begin 00891 $display("%s (%s)", comp.get_full_name(), comp.get_type_name()); 00892 end 00893 00894 if (comp.get_first_child(name)) 00895 do begin 00896 this.print_unit_list(comp.get_child(name)); 00897 end 00898 while (comp.get_next_child(name)); 00899 00900 endfunction 00901 00902 00903 // print_topology 00904 // -------------- 00905 00906 function void ovm_root::print_topology(ovm_printer printer=null); 00907 ovm_report_info("OVMTOP", "OVM testbench topology:", OVM_LOW); 00908 print_units(printer); 00909 endfunction 00910 00911 00912 `endif //OVM_ROOT_SVH
![]() Intelligent Design Verification Project: OVM, Revision: 1.1.0 |
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.4.6 Mon Sep 29 14:23:30 2008 |