00001 // $Id: a00223.html,v 1.1 2009/01/07 19:29:53 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 `include "base/ovm_component.svh" 00023 `include "base/ovm_root.svh" 00024 00025 ovm_component ovm_top_levels[$]; // don't use 00026 00027 00028 //------------------------------------------------------------------------------ 00029 // 00030 // CLASS: ovm_component 00031 // 00032 //------------------------------------------------------------------------------ 00033 00034 // new 00035 // --- 00036 00037 function ovm_component::new (string name, ovm_component parent); 00038 string error_str; 00039 00040 super.new(name); 00041 00042 // If ovm_top, reset name to "" so it doesn't show in full paths then return 00043 if (parent==null && name == "__top__") begin 00044 set_name(""); 00045 return; 00046 end 00047 00048 // Check that we're not in or past end_of_elaboration 00049 if (end_of_elaboration_ph.is_in_progress() || 00050 end_of_elaboration_ph.is_done() ) begin 00051 ovm_phase curr_phase; 00052 curr_phase = ovm_top.get_current_phase(); 00053 ovm_report_fatal("ILLCRT", {"It is illegal to create a component once", 00054 " phasing reaches end_of_elaboration. The current phase is ", 00055 curr_phase.get_name()}); 00056 end 00057 00058 if (name == "") begin 00059 name.itoa(m_inst_count); 00060 name = {"COMP_", name}; 00061 end 00062 00063 if (parent == null) 00064 parent = ovm_top; 00065 00066 ovm_report_info("NEWCOMP",$psprintf("this=%0s, parent=%0s, name=%s", 00067 this.get_full_name(),parent.get_full_name(),name),OVM_MEDIUM+1); 00068 00069 if (parent.has_child(name) && this != parent.get_child(name)) begin 00070 if (parent == ovm_top) begin 00071 error_str = {"Name '",name,"' is not unique to other top-level ", 00072 "instances. If parent is a module, build a unique name by combining the ", 00073 "the module name and component name: $psprintf(\"\%m.\%s\",\"",name,"\")."}; 00074 ovm_report_fatal("CLDEXT",error_str); 00075 end 00076 else 00077 ovm_report_fatal("CLDEXT", 00078 $psprintf("Cannot set '%s' as a child of '%s', %s", 00079 name, parent.get_full_name(), 00080 "which already has a child by that name.")); 00081 return; 00082 end 00083 00084 m_parent = parent; 00085 00086 set_name(name); 00087 00088 if (!m_parent.m_add_child(this)) 00089 m_parent = null; 00090 00091 event_pool = new("event_pool"); 00092 00093 00094 // Now that inst name is established, reseed (if use_ovm_seeding is set) 00095 reseed(); 00096 00097 // Do local configuration settings (URM backward compatibility) 00098 void'(get_config_int("recording_detail", recording_detail)); 00099 00100 // Deprecated container of top-levels (replaced by ovm_top) 00101 if (parent == ovm_top) 00102 ovm_top_levels.push_back(this); 00103 00104 set_report_verbosity_level(ovm_top.get_report_verbosity_level()); 00105 00106 endfunction 00107 00108 00109 // m_add_child 00110 // ----------- 00111 00112 function bit ovm_component::m_add_child(ovm_component child); 00113 00114 if (m_children.exists(child.get_name()) && 00115 m_children[child.get_name()] != child) begin 00116 ovm_report_warning("BDCLD", 00117 $psprintf("A child with the name '%0s' (type=%0s) already exists.", 00118 child.get_name(), m_children[child.get_name()].get_type_name())); 00119 return 0; 00120 end 00121 00122 foreach (m_children[c]) 00123 if (child == m_children[c]) begin 00124 ovm_report_warning("BDCHLD", 00125 $psprintf("A child with the name '%0s' %0s %0s'", 00126 child.get_name(), 00127 "already exists in parent under name '", 00128 m_children[c].get_name())); 00129 return 0; 00130 end 00131 00132 m_children[child.get_name()] = child; 00133 return 1; 00134 endfunction 00135 00136 00137 //------------------------------------------------------------------------------ 00138 // 00139 // Hierarchy Methods 00140 // 00141 //------------------------------------------------------------------------------ 00142 00143 00144 // get_first_child 00145 // --------------- 00146 00147 function int ovm_component::get_first_child(ref string name); 00148 return m_children.first(name); 00149 endfunction 00150 00151 00152 // get_next_child 00153 // -------------- 00154 00155 function int ovm_component::get_next_child(ref string name); 00156 return m_children.next(name); 00157 endfunction 00158 00159 00160 // get_child 00161 // --------- 00162 00163 function ovm_component ovm_component::get_child(string name); 00164 return m_children[name]; 00165 endfunction 00166 00167 00168 // has_child 00169 // --------- 00170 00171 function int ovm_component::has_child(string name); 00172 return m_children.exists(name); 00173 endfunction 00174 00175 00176 // get_num_children 00177 // ---------------- 00178 00179 function int ovm_component::get_num_children(); 00180 return m_children.num(); 00181 endfunction 00182 00183 00184 // get_full_name 00185 // ------------- 00186 00187 function string ovm_component::get_full_name (); 00188 // Note: Implementation choice to construct full name once since the 00189 // full name may be used often for lookups. 00190 if(m_name == "") 00191 return get_name(); 00192 else 00193 return m_name; 00194 endfunction 00195 00196 00197 // get_parent 00198 // ---------- 00199 00200 function ovm_component ovm_component::get_parent (); 00201 return m_parent; 00202 endfunction 00203 00204 00205 // set_name 00206 // -------- 00207 00208 function void ovm_component::set_name (string name); 00209 00210 super.set_name(name); 00211 m_set_full_name(); 00212 00213 endfunction 00214 00215 00216 00217 // m_set_full_name 00218 // --------------- 00219 00220 function void ovm_component::m_set_full_name(); 00221 if (m_parent == ovm_top || m_parent==null) 00222 m_name = get_name(); 00223 else 00224 m_name = {m_parent.get_full_name(), ".", get_name()}; 00225 00226 foreach (m_children[c]) begin 00227 ovm_component tmp; 00228 tmp = m_children[c]; 00229 tmp.m_set_full_name(); 00230 end 00231 00232 endfunction 00233 00234 00235 // lookup 00236 // ------ 00237 00238 function ovm_component ovm_component::lookup( string name ); 00239 00240 string leaf , remainder; 00241 ovm_component comp; 00242 00243 comp = this; 00244 00245 m_extract_name(name, leaf, remainder); 00246 00247 if (leaf == "") begin 00248 comp = ovm_top; // absolute lookup 00249 m_extract_name(remainder, leaf, remainder); 00250 end 00251 00252 if (!comp.has_child(leaf)) begin 00253 ovm_report_warning("Lookup Error", 00254 $psprintf("Cannot find child %0s",leaf)); 00255 return null; 00256 end 00257 00258 if( remainder != "" ) 00259 return comp.m_children[leaf].lookup(remainder); 00260 00261 return comp.m_children[leaf]; 00262 00263 endfunction 00264 00265 00266 // m_extract_name 00267 // -------------- 00268 00269 function void ovm_component::m_extract_name(input string name , 00270 output string leaf , 00271 output string remainder ); 00272 int i , len; 00273 string extract_str; 00274 len = name.len(); 00275 00276 for( i = 0; i < name.len(); i++ ) begin 00277 if( name[i] == "." ) begin 00278 break; 00279 end 00280 end 00281 00282 if( i == len ) begin 00283 leaf = name; 00284 remainder = ""; 00285 return; 00286 end 00287 00288 leaf = name.substr( 0 , i - 1 ); 00289 remainder = name.substr( i + 1 , len - 1 ); 00290 00291 return; 00292 endfunction 00293 00294 00295 // flush 00296 // ----- 00297 00298 function void ovm_component::flush(); 00299 return; 00300 endfunction 00301 00302 00303 // do_flush (flush_hier?) 00304 // -------- 00305 00306 function void ovm_component::do_flush(); 00307 foreach( m_children[s] ) 00308 m_children[s].do_flush(); 00309 flush(); 00310 endfunction 00311 00312 00313 //------------------------------------------------------------------------------ 00314 // 00315 // Factory Methods 00316 // 00317 //------------------------------------------------------------------------------ 00318 00319 // create 00320 // ------ 00321 00322 function ovm_object ovm_component::create (string name =""); 00323 ovm_report_error("ILLCRT", 00324 "create cannot be called on a ovm_component. Use create_component instead."); 00325 return null; 00326 endfunction 00327 00328 00329 // clone 00330 // ------ 00331 00332 function ovm_object ovm_component::clone (); 00333 ovm_report_error("ILLCLN","clone cannot be called on a ovm_component. "); 00334 return null; 00335 endfunction 00336 00337 00338 // print_override_info 00339 // ------------------- 00340 00341 function void ovm_component::print_override_info (string requested_type_name, 00342 string name=""); 00343 factory.debug_create_by_name(requested_type_name, get_full_name(), name); 00344 endfunction 00345 00346 00347 // create_component 00348 // ---------------- 00349 00350 function ovm_component ovm_component::create_component (string requested_type_name, 00351 string name); 00352 return factory.create_component_by_name(requested_type_name, get_full_name(), 00353 name, this); 00354 endfunction 00355 00356 00357 // create_object 00358 // ------------- 00359 00360 function ovm_object ovm_component::create_object (string requested_type_name, 00361 string name=""); 00362 return factory.create_object_by_name(requested_type_name, 00363 get_full_name(), name); 00364 endfunction 00365 00366 00367 // set_type_override (static) 00368 // ----------------- 00369 00370 function void ovm_component::set_type_override (string original_type_name, 00371 string override_type_name, 00372 bit replace=1); 00373 factory.set_type_override_by_name(original_type_name, 00374 override_type_name, replace); 00375 endfunction 00376 00377 00378 // set_type_override_by_type (static) 00379 // ------------------------- 00380 00381 function void ovm_component::set_type_override_by_type (ovm_object_wrapper original_type, 00382 ovm_object_wrapper override_type, 00383 bit replace=1); 00384 factory.set_type_override_by_type(original_type, override_type, replace); 00385 endfunction 00386 00387 00388 // set_inst_override 00389 // ----------------- 00390 00391 function void ovm_component::set_inst_override (string relative_inst_path, 00392 string original_type_name, 00393 string override_type_name); 00394 string full_inst_path; 00395 00396 if (relative_inst_path == "") 00397 full_inst_path = get_full_name(); 00398 else 00399 full_inst_path = {get_full_name(), ".", relative_inst_path}; 00400 00401 factory.set_inst_override_by_name( 00402 original_type_name, 00403 override_type_name, 00404 full_inst_path); 00405 endfunction 00406 00407 00408 // set_inst_override_by_type 00409 // ------------------------- 00410 00411 function void ovm_component::set_inst_override_by_type (string relative_inst_path, 00412 ovm_object_wrapper original_type, 00413 ovm_object_wrapper override_type); 00414 string full_inst_path; 00415 00416 if (relative_inst_path == "") 00417 full_inst_path = get_full_name(); 00418 else 00419 full_inst_path = {get_full_name(), ".", relative_inst_path}; 00420 00421 factory.set_inst_override_by_type(original_type, override_type, full_inst_path); 00422 00423 endfunction 00424 00425 //------------------------------------------------------------------------------ 00426 // 00427 // Hierarchical report configuration interface 00428 // 00429 //------------------------------------------------------------------------------ 00430 00431 // set_report_severity_action_hier 00432 // ------------------------------- 00433 00434 function void ovm_component::set_report_severity_action_hier( ovm_severity severity, 00435 ovm_action action); 00436 set_report_severity_action(severity, action); 00437 foreach( m_children[c] ) 00438 m_children[c].set_report_severity_action_hier(severity, action); 00439 endfunction 00440 00441 00442 // set_report_id_action_hier 00443 // ------------------------- 00444 00445 function void ovm_component::set_report_id_action_hier( string id, ovm_action action); 00446 set_report_id_action(id, action); 00447 foreach( m_children[c] ) 00448 m_children[c].set_report_id_action_hier(id, action); 00449 endfunction 00450 00451 00452 // set_report_severity_id_action_hier 00453 // ---------------------------------- 00454 00455 function void ovm_component::set_report_severity_id_action_hier( ovm_severity severity, 00456 string id, 00457 ovm_action action); 00458 set_report_severity_id_action(severity, id, action); 00459 foreach( m_children[c] ) 00460 m_children[c].set_report_severity_id_action_hier(severity, id, action); 00461 endfunction 00462 00463 00464 // set_report_severity_file_hier 00465 // ----------------------------- 00466 00467 function void ovm_component::set_report_severity_file_hier( ovm_severity severity, 00468 OVM_FILE file); 00469 set_report_severity_file(severity, file); 00470 foreach( m_children[c] ) 00471 m_children[c].set_report_severity_file_hier(severity, file); 00472 endfunction 00473 00474 00475 // set_report_default_file_hier 00476 // ---------------------------- 00477 00478 function void ovm_component::set_report_default_file_hier( OVM_FILE file); 00479 set_report_default_file(file); 00480 foreach( m_children[c] ) 00481 m_children[c].set_report_default_file_hier(file); 00482 endfunction 00483 00484 00485 // set_report_id_file_hier 00486 // ----------------------- 00487 00488 function void ovm_component::set_report_id_file_hier( string id, OVM_FILE file); 00489 set_report_id_file(id, file); 00490 foreach( m_children[c] ) 00491 m_children[c].set_report_id_file_hier(id, file); 00492 endfunction 00493 00494 00495 // set_report_severity_id_file_hier 00496 // -------------------------------- 00497 00498 function void ovm_component::set_report_severity_id_file_hier ( ovm_severity severity, 00499 string id, 00500 OVM_FILE file); 00501 set_report_severity_id_file(severity, id, file); 00502 foreach( m_children[c] ) 00503 m_children[c].set_report_severity_id_file_hier(severity, id, file); 00504 endfunction 00505 00506 00507 // set_report_verbosity_level_hier 00508 // ------------------------------- 00509 00510 function void ovm_component::set_report_verbosity_level_hier(int verbosity); 00511 set_report_verbosity_level(verbosity); 00512 foreach( m_children[c] ) 00513 m_children[c].set_report_verbosity_level_hier(verbosity); 00514 endfunction 00515 00516 00517 //------------------------------------------------------------------------------ 00518 // 00519 // Phase interface 00520 // 00521 //------------------------------------------------------------------------------ 00522 00523 00524 // do_func_phase 00525 // ------------- 00526 00527 function void ovm_component::do_func_phase (ovm_phase phase); 00528 // If in build_ph, don't build if already done 00529 m_curr_phase = phase; 00530 if (!(phase == build_ph && m_build_done)) 00531 phase.call_func(this); 00532 endfunction 00533 00534 00535 // do_task_phase 00536 // ------------- 00537 00538 task ovm_component::do_task_phase (ovm_phase phase); 00539 00540 m_curr_phase = phase; 00541 `ifndef INCA 00542 00543 //fork 00544 //begin 00545 m_phase_process = process::self(); 00546 phase.call_task(this); 00547 @m_kill_request; 00548 //end 00549 //join 00550 00551 `else 00552 // don't use fine grained process control 00553 fork begin // isolate inner fork so can safely kill via disable fork 00554 fork : task_phase 00555 // process 1 - call task; if returns, keep alive until kill request 00556 begin 00557 phase.call_task(this); 00558 @m_kill_request; 00559 end 00560 // process 2 - any kill request will preempt process 1 00561 @m_kill_request; 00562 join_any 00563 disable fork; 00564 end 00565 join 00566 `endif 00567 00568 endtask 00569 00570 00571 // do_kill_all 00572 // ----------- 00573 00574 function void ovm_component::do_kill_all(); 00575 foreach(m_children[c]) 00576 m_children[c].do_kill_all(); 00577 kill(); 00578 endfunction 00579 00580 00581 00582 // kill 00583 // ---- 00584 00585 function void ovm_component::kill(); 00586 `ifndef INCA 00587 if (m_phase_process != null) begin 00588 m_phase_process.kill; 00589 m_phase_process = null; 00590 end 00591 `else 00592 ->m_kill_request; 00593 `endif 00594 endfunction 00595 00596 00597 // suspend 00598 // ------- 00599 00600 task ovm_component::suspend(); 00601 `ifndef INCA 00602 if(m_phase_process != null) 00603 m_phase_process.suspend; 00604 `else 00605 ovm_report_error("UNIMP", "suspend not implemented"); 00606 `endif 00607 endtask 00608 00609 00610 // resume 00611 // ------ 00612 00613 task ovm_component::resume(); 00614 `ifndef INCA 00615 if(m_phase_process!=null) 00616 m_phase_process.resume; 00617 `else 00618 ovm_report_error("UNIMP", "resume not implemented"); 00619 `endif 00620 endtask 00621 00622 00623 // restart 00624 // ------- 00625 00626 task ovm_component::restart(); 00627 ovm_report_warning("UNIMP", 00628 $psprintf("%0s: restart not implemented",this.get_name())); 00629 endtask 00630 00631 00632 // status 00633 //------- 00634 00635 function string ovm_component::status(); 00636 00637 `ifndef INCA 00638 process::state ps; 00639 00640 if(m_phase_process == null) 00641 return "<unknown>"; 00642 00643 ps = m_phase_process.status(); 00644 00645 return ps.name(); 00646 `else 00647 ovm_report_error("UNIMP", "status not implemented"); 00648 `endif 00649 00650 endfunction 00651 00652 00653 // build 00654 // ----- 00655 00656 function void ovm_component::build(); 00657 m_build_done = 1; 00658 apply_config_settings(print_config_matches); 00659 endfunction 00660 00661 00662 // connect 00663 // ------- 00664 00665 function void ovm_component::connect(); 00666 return; 00667 endfunction 00668 00669 00670 // start_of_simulation 00671 // ------------------- 00672 00673 function void ovm_component::start_of_simulation(); 00674 return; 00675 endfunction 00676 00677 00678 // end_of_elaboration 00679 // ------------------ 00680 00681 function void ovm_component::end_of_elaboration(); 00682 return; 00683 endfunction 00684 00685 00686 // run 00687 // --- 00688 00689 task ovm_component::run(); 00690 return; 00691 endtask 00692 00693 00694 // extract 00695 // ------- 00696 00697 function void ovm_component::extract(); 00698 return; 00699 endfunction 00700 00701 00702 // check 00703 // ----- 00704 00705 function void ovm_component::check(); 00706 return; 00707 endfunction 00708 00709 00710 // report 00711 // ------ 00712 00713 function void ovm_component::report(); 00714 return; 00715 endfunction 00716 00717 00718 // stop 00719 // ---- 00720 00721 task ovm_component::stop(string ph_name); 00722 return; 00723 endtask 00724 00725 00726 // resolve_bindings 00727 // ---------------- 00728 00729 function void ovm_component::resolve_bindings(); 00730 return; 00731 endfunction 00732 00733 00734 // do_resolve_bindings 00735 // ------------------- 00736 00737 function void ovm_component::do_resolve_bindings(); 00738 foreach( m_children[s] ) 00739 m_children[s].do_resolve_bindings(); 00740 resolve_bindings(); 00741 endfunction 00742 00743 00744 00745 //------------------------------------------------------------------------------ 00746 // 00747 // Recording interface 00748 // 00749 //------------------------------------------------------------------------------ 00750 00751 // accept_tr 00752 // --------- 00753 00754 function void ovm_component::accept_tr (ovm_transaction tr, 00755 time accept_time=0); 00756 ovm_event e; 00757 tr.accept_tr(accept_time); 00758 do_accept_tr(tr); 00759 e = event_pool.get("accept_tr"); 00760 if(e!=null) 00761 e.trigger(); 00762 endfunction 00763 00764 // begin_tr 00765 // -------- 00766 00767 function integer ovm_component::begin_tr (ovm_transaction tr, 00768 string stream_name ="main", 00769 string label="", 00770 string desc="", 00771 time begin_time=0); 00772 return m_begin_tr(tr, 0, 0, stream_name, label, desc, begin_time); 00773 endfunction 00774 00775 // begin_child_tr 00776 // -------------- 00777 00778 function integer ovm_component::begin_child_tr (ovm_transaction tr, 00779 integer parent_handle=0, 00780 string stream_name="main", 00781 string label="", 00782 string desc="", 00783 time begin_time=0); 00784 return m_begin_tr(tr, parent_handle, 1, stream_name, label, desc, begin_time); 00785 endfunction 00786 00787 // m_begin_tr 00788 // ---------- 00789 00790 function integer ovm_component::m_begin_tr (ovm_transaction tr, 00791 integer parent_handle=0, 00792 bit has_parent=0, 00793 string stream_name="main", 00794 string label="", 00795 string desc="", 00796 time begin_time=0); 00797 ovm_event e; 00798 integer stream_h; 00799 integer tr_h; 00800 integer link_tr_h; 00801 string name; 00802 00803 tr_h = 0; 00804 if(has_parent) 00805 link_tr_h = tr.begin_child_tr(begin_time, parent_handle); 00806 else 00807 link_tr_h = tr.begin_tr(begin_time); 00808 00809 if (tr.get_name() != "") 00810 name = tr.get_name(); 00811 else 00812 name = tr.get_type_name(); 00813 00814 if(stream_name == "") stream_name="main"; 00815 00816 if (recording_detail != OVM_NONE) begin 00817 00818 if(m_stream_handle.exists(stream_name)) 00819 stream_h = m_stream_handle[stream_name]; 00820 00821 if (ovm_check_handle_kind("Fiber", stream_h) != 1) 00822 begin 00823 stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name()); 00824 m_stream_handle[stream_name] = stream_h; 00825 end 00826 00827 if(has_parent == 0) 00828 tr_h = ovm_begin_transaction("Begin_No_Parent, Link", 00829 stream_h, 00830 name, 00831 label, 00832 desc, 00833 begin_time); 00834 else begin 00835 tr_h = ovm_begin_transaction("Begin_End, Link", 00836 stream_h, 00837 name, 00838 label, 00839 desc, 00840 begin_time); 00841 if(parent_handle!=0) 00842 ovm_link_transaction(parent_handle, tr_h, "child"); 00843 end 00844 00845 m_tr_h[tr] = tr_h; 00846 00847 if (ovm_check_handle_kind("Transaction", link_tr_h) == 1) 00848 ovm_link_transaction(tr_h,link_tr_h); 00849 00850 do_begin_tr(tr,stream_name,tr_h); 00851 00852 e = event_pool.get("begin_tr"); 00853 if (e!=null) 00854 e.trigger(tr); 00855 00856 end 00857 00858 return tr_h; 00859 00860 endfunction 00861 00862 00863 // end_tr 00864 // ------ 00865 00866 function void ovm_component::end_tr (ovm_transaction tr, 00867 time end_time=0, 00868 bit free_handle=1); 00869 ovm_event e; 00870 integer tr_h; 00871 tr_h = 0; 00872 00873 tr.end_tr(end_time,free_handle); 00874 00875 if (recording_detail != OVM_NONE) begin 00876 00877 if (m_tr_h.exists(tr)) begin 00878 00879 tr_h = m_tr_h[tr]; 00880 00881 do_end_tr(tr, tr_h); // callback 00882 00883 m_tr_h.delete(tr); 00884 00885 if (ovm_check_handle_kind("Transaction", tr_h) == 1) begin 00886 00887 ovm_default_recorder.tr_handle = tr_h; 00888 tr.record(ovm_default_recorder); 00889 00890 ovm_end_transaction(tr_h,end_time); 00891 00892 if (free_handle) 00893 ovm_free_transaction_handle(tr_h); 00894 00895 end 00896 end 00897 else begin 00898 do_end_tr(tr, tr_h); // callback 00899 end 00900 00901 00902 e = event_pool.get("end_tr"); 00903 if(e!=null) 00904 e.trigger(); 00905 end 00906 00907 endfunction 00908 00909 // record_error_tr 00910 // --------------- 00911 00912 function integer ovm_component::record_error_tr (string stream_name="main", 00913 ovm_object info=null, 00914 string label="error_tr", 00915 string desc="", 00916 time error_time=0, 00917 bit keep_active=0); 00918 string etype; 00919 integer stream_h; 00920 00921 if(keep_active) etype = "Error, Link"; 00922 else etype = "Error"; 00923 00924 if(error_time == 0) error_time = $time; 00925 00926 stream_h = m_stream_handle[stream_name]; 00927 if (ovm_check_handle_kind("Fiber", stream_h) != 1) begin 00928 stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name()); 00929 m_stream_handle[stream_name] = stream_h; 00930 end 00931 00932 record_error_tr = ovm_begin_transaction(etype, stream_h, label, 00933 label, desc, error_time); 00934 if(info!=null) begin 00935 ovm_default_recorder.tr_handle = record_error_tr; 00936 info.record(ovm_default_recorder); 00937 end 00938 00939 ovm_end_transaction(record_error_tr,error_time); 00940 endfunction 00941 00942 00943 // record_event_tr 00944 // --------------- 00945 00946 function integer ovm_component::record_event_tr (string stream_name="main", 00947 ovm_object info=null, 00948 string label="event_tr", 00949 string desc="", 00950 time event_time=0, 00951 bit keep_active=0); 00952 string etype; 00953 integer stream_h; 00954 00955 if(keep_active) etype = "Event, Link"; 00956 else etype = "Event"; 00957 00958 if(event_time == 0) event_time = $time; 00959 00960 stream_h = m_stream_handle[stream_name]; 00961 if (ovm_check_handle_kind("Fiber", stream_h) != 1) begin 00962 stream_h = ovm_create_fiber(stream_name, "TVM", get_full_name()); 00963 m_stream_handle[stream_name] = stream_h; 00964 end 00965 00966 record_event_tr = ovm_begin_transaction(etype, stream_h, label, 00967 label, desc, event_time); 00968 if(info!=null) begin 00969 ovm_default_recorder.tr_handle = record_event_tr; 00970 info.record(ovm_default_recorder); 00971 end 00972 00973 ovm_end_transaction(record_event_tr,event_time); 00974 endfunction 00975 00976 // do_accept_tr 00977 // ------------ 00978 00979 function void ovm_component::do_accept_tr (ovm_transaction tr); 00980 return; 00981 endfunction 00982 00983 00984 // do_begin_tr 00985 // ----------- 00986 00987 function void ovm_component::do_begin_tr (ovm_transaction tr, 00988 string stream_name, 00989 integer tr_handle); 00990 return; 00991 endfunction 00992 00993 00994 // do_end_tr 00995 // --------- 00996 00997 function void ovm_component::do_end_tr (ovm_transaction tr, 00998 integer tr_handle); 00999 return; 01000 endfunction 01001 01002 01003 //------------------------------------------------------------------------------ 01004 // 01005 // Configuration interface 01006 // 01007 //------------------------------------------------------------------------------ 01008 01009 01010 // set_config_int 01011 // -------------- 01012 01013 function void ovm_component::set_config_int (string inst_name, 01014 string field_name, 01015 ovm_bitstream_t value); 01016 ovm_int_config_setting cfg; 01017 cfg = new({get_full_name(), ".", inst_name}, field_name, 01018 value, get_full_name()); 01019 m_configuration_table.push_front(cfg); 01020 endfunction 01021 01022 01023 // set_config_string 01024 // ----------------- 01025 01026 function void ovm_component::set_config_string (string inst_name, 01027 string field_name, 01028 string value); 01029 ovm_string_config_setting cfg; 01030 cfg = new({get_full_name(), ".", inst_name}, field_name, 01031 value, get_full_name()); 01032 m_configuration_table.push_front(cfg); 01033 endfunction 01034 01035 01036 // set_config_object 01037 // ----------------- 01038 01039 function void ovm_component::set_config_object (string inst_name, 01040 string field_name, 01041 ovm_object value, 01042 bit clone=1); 01043 ovm_object_config_setting cfg; 01044 if(clone && (value != null)) begin 01045 ovm_object tmp; 01046 tmp = value.clone(); 01047 01048 // If create not implemented, or clone is attempted on objects that 01049 // do not t allow cloning (e.g. components) clone will return null. 01050 if(tmp == null) begin 01051 ovm_component comp; 01052 if ($cast(comp,value)) begin 01053 ovm_report_error("INVCLNC", {"Clone failed during set_config_object ", 01054 "with an object that is an ovm_component. Components cannot be cloned."}); 01055 return; 01056 end 01057 else begin 01058 ovm_report_warning("INVCLN", {"Clone failed during set_config_object, ", 01059 "the original reference will be used for configuration. Check that ", 01060 "the create method for the object type is defined properly."}); 01061 end 01062 end 01063 else 01064 value = tmp; 01065 end 01066 01067 cfg = new({get_full_name(), ".", inst_name}, field_name, 01068 value, get_full_name(), clone); 01069 m_configuration_table.push_front(cfg); 01070 01071 endfunction 01072 01073 01074 // MACROS: (used in get_config_* method implementations) 01075 // ------- 01076 01077 `define OVM_LOCAL_SCOPE_STACK(STACK, START) \ 01078 begin \ 01079 ovm_component oc; \ 01080 oc = START; \ 01081 if(oc!=null) begin \ 01082 do begin \ 01083 STACK.push_front(oc.m_parent); \ 01084 oc = oc.m_parent; \ 01085 end while(oc); \ 01086 end \ 01087 else \ 01088 STACK.push_front(null); \ 01089 end 01090 01091 `define OVM_APPLY_CONFIG_SETTING(STACK, CFG) \ 01092 foreach(STACK[s]) begin \ 01093 comp = STACK[s]; \ 01094 if(rtn) break; \ 01095 if(comp==null) begin \ 01096 for(int i=0; i<global_configuration_table.size(); ++i) begin \ 01097 if(global_configuration_table[i].component_match(this) && \ 01098 global_configuration_table[i].field_match(field_name)) \ 01099 begin \ 01100 if($cast(CFG, global_configuration_table[i])) begin \ 01101 if(print_config_matches) \ 01102 global_configuration_table[i].print_match(this,null,field_name);\ 01103 value = CFG.value; \ 01104 rtn = 1; \ 01105 break; \ 01106 end \ 01107 end \ 01108 end \ 01109 end \ 01110 else begin \ 01111 for(int i = 0; i<comp.m_configuration_table.size(); ++i) begin \ 01112 if(comp.m_configuration_table[i].component_match(this) && \ 01113 comp.m_configuration_table[i].field_match(field_name)) \ 01114 begin \ 01115 if($cast(CFG, comp.m_configuration_table[i])) begin \ 01116 if(print_config_matches) \ 01117 comp.m_configuration_table[i].print_match(this,comp,field_name);\ 01118 value = CFG.value; \ 01119 rtn = 1; \ 01120 break; \ 01121 end \ 01122 end \ 01123 end \ 01124 end \ 01125 end 01126 01127 01128 // get_config_int 01129 // -------------- 01130 01131 function bit ovm_component::get_config_int (string field_name, 01132 inout ovm_bitstream_t value); 01133 ovm_component stack[$]; 01134 ovm_component comp; 01135 ovm_int_config_setting cfg; 01136 bit rtn; rtn = 0; 01137 `OVM_LOCAL_SCOPE_STACK(stack, this) 01138 `OVM_APPLY_CONFIG_SETTING(stack, cfg) 01139 return rtn; 01140 endfunction 01141 01142 01143 // get_config_string 01144 // ----------------- 01145 01146 function bit ovm_component::get_config_string (string field_name, 01147 inout string value); 01148 ovm_component stack[$]; 01149 ovm_component comp; 01150 ovm_string_config_setting cfg; 01151 bit rtn; rtn = 0; 01152 `OVM_LOCAL_SCOPE_STACK(stack, this) 01153 `OVM_APPLY_CONFIG_SETTING(stack, cfg) 01154 return rtn; 01155 endfunction 01156 01157 01158 // get_config_object 01159 // ----------------- 01160 01161 function bit ovm_component::get_config_object (string field_name, 01162 inout ovm_object value, 01163 input bit clone=1); 01164 ovm_component stack[$]; 01165 ovm_component comp; 01166 ovm_object_config_setting cfg; 01167 bit rtn; rtn = 0; 01168 `OVM_LOCAL_SCOPE_STACK(stack, this) 01169 `OVM_APPLY_CONFIG_SETTING(stack, cfg) 01170 if(rtn && clone && (value != null)) begin 01171 ovm_object tmp; 01172 tmp = value.clone(); 01173 if(tmp != null) 01174 tmp = value; 01175 end 01176 return rtn; 01177 endfunction 01178 01179 01180 // apply_config_settings 01181 // --------------------- 01182 01183 function void ovm_component::apply_config_settings (bit verbose=0); 01184 ovm_component stack[$]; 01185 ovm_config_setting cfg; 01186 ovm_int_config_setting cfg_int; 01187 ovm_string_config_setting cfg_str; 01188 ovm_object_config_setting cfg_obj; 01189 ovm_component comp; 01190 string match_str; 01191 string matched=""; 01192 bit has_match=0; 01193 `OVM_LOCAL_SCOPE_STACK(stack, this) 01194 //apply any override that matches this component. Go bottom up and then back 01195 //to front so the last override in the global scope has precedence to the 01196 //first override in the parent scope. 01197 if (verbose) begin 01198 match_str = {"Auto-configuration matches for component ", 01199 this.get_full_name()," (",get_type_name(),"). Last entry for a given field takes precedence.\n\n", 01200 " Config set from Instance Path Field name Type Value\n", 01201 " ------------------------------------------------------------------------------\n"}; 01202 end 01203 for(int i=stack.size()-1; i>=0; --i) begin 01204 comp = stack[i]; 01205 if(comp!=null) begin 01206 for(int j=comp.m_configuration_table.size()-1; j>=0; --j) begin 01207 cfg = comp.m_configuration_table[j]; 01208 matched = cfg.matches_string(this,comp); 01209 if(matched != "") begin 01210 if($cast(cfg_int, cfg)) 01211 set_int_local(cfg_int.field, cfg_int.value); 01212 else if($cast(cfg_str, cfg)) 01213 set_string_local(cfg_str.field, cfg_str.value); 01214 else if($cast(cfg_obj, cfg)) begin 01215 set_object_local(cfg_obj.field, cfg_obj.value, cfg_obj.clone); 01216 matched = {matched, " clone=",(cfg_obj.clone==1)?"1":"0"}; 01217 end 01218 match_str = {match_str, " ", matched,"\n"}; 01219 has_match = 1; 01220 end 01221 end 01222 end 01223 else begin 01224 for(int j=global_configuration_table.size()-1; j>=0; --j) begin 01225 //not sure why I need this cast. Seems like a bug 01226 $cast(cfg, global_configuration_table[j]); 01227 matched = cfg.matches_string(this,comp); 01228 if(matched != "") begin 01229 if($cast(cfg_int, cfg)) 01230 set_int_local(cfg_int.field, cfg_int.value); 01231 else if($cast(cfg_str, cfg)) 01232 set_string_local(cfg_str.field, cfg_str.value); 01233 else if($cast(cfg_obj, cfg)) begin 01234 set_object_local(cfg_obj.field, cfg_obj.value, cfg_obj.clone); 01235 matched = {matched, " clone=",(cfg_obj.clone==1)?"1":"0"}; 01236 end 01237 match_str = {match_str, " ", matched,"\n"}; 01238 has_match = 1; 01239 end 01240 end 01241 end 01242 end 01243 01244 if (verbose && has_match) 01245 ovm_report_info("auto-configuration", {match_str,"\n"}); 01246 01247 endfunction 01248 01249 01250 // print_config_settings 01251 // --------------------- 01252 01253 function void ovm_component::print_config_settings (string field="", 01254 ovm_component comp=null, 01255 bit recurse=0); 01256 static int depth; 01257 ovm_component stack[$]; 01258 ovm_component cc; 01259 string all_matches; 01260 string v,r; 01261 all_matches = ""; 01262 01263 if(comp==null) 01264 comp = this; 01265 01266 `OVM_LOCAL_SCOPE_STACK(stack, comp) 01267 cc = comp; 01268 01269 $swrite(v, "%s", cc.get_full_name()); 01270 while(v.len()<17) v = {v," "}; 01271 foreach(stack[s]) begin 01272 comp = stack[s]; 01273 if(comp==null) begin 01274 for(int i=0; i<global_configuration_table.size(); ++i) begin 01275 r = global_configuration_table[i].matches_string(cc, null); 01276 if(r != "") 01277 all_matches = {all_matches, v, r, "\n"}; 01278 end 01279 end 01280 else begin 01281 for(int i=0; i<comp.m_configuration_table.size(); ++i) begin 01282 r = comp.m_configuration_table[i].matches_string(cc, comp); 01283 if(r != "") 01284 all_matches = {all_matches, v, r, "\n"}; 01285 end 01286 end 01287 end 01288 01289 // Note: should use ovm_printer for formatting 01290 if(((all_matches != "") || (recurse == 1)) && depth == 0) begin 01291 $display("Configuration settings for component %s (recurse = %0d)", 01292 cc.get_full_name(), recurse); 01293 $display("Set to Set from Component match Field name Type Value"); 01294 $display("-------------------------------------------------------------------------------"); 01295 end 01296 if(all_matches == "") 01297 $display("%s NONE", v); 01298 else 01299 $write("%s", all_matches); 01300 01301 if(recurse) begin 01302 depth++; 01303 if(cc.m_children.first(v)) 01304 do this.print_config_settings(field, cc.m_children[v], recurse); 01305 while(cc.m_children.next(v)); 01306 depth--; 01307 end 01308 endfunction 01309 01310 01311 //------------------------------------------------------------------------------ 01312 // 01313 // DEPRECATED - DO NOT USE 01314 // 01315 //------------------------------------------------------------------------------ 01316 01317 // global_stop_request (static, deprecated) 01318 // ------------------- 01319 01320 function void ovm_component::global_stop_request(); 01321 ovm_root top; 01322 top = ovm_root::get(); 01323 top.stop_request(); 01324 endfunction 01325 01326 01327 // post_new (deprecated) 01328 // -------- 01329 01330 function void ovm_component::post_new(); 01331 return; 01332 endfunction 01333 01334 01335 // export_connections (deprecated) 01336 // ------------------ 01337 01338 function void ovm_component::export_connections(); 01339 return; 01340 endfunction 01341 01342 01343 // import_connections (deprecated) 01344 // ------------------ 01345 01346 function void ovm_component::import_connections(); 01347 return; 01348 endfunction 01349 01350 01351 // configure (deprecated) 01352 // --------- 01353 01354 function void ovm_component::configure(); 01355 return; 01356 endfunction 01357 01358 01359 // pre_run (deprecated) 01360 // ------- 01361 01362 function void ovm_component::pre_run(); 01363 return; 01364 endfunction 01365 01366 01367 // find_component (deprecated) 01368 // -------------- 01369 01370 function ovm_component ovm_component::find_component (string comp_match); 01371 static bit issued=0; 01372 if (!issued) begin 01373 issued=1; 01374 ovm_top.ovm_report_warning("deprecated", 01375 {"ovm_component::find_component() is deprecated and replaced by ", 01376 "ovm_top.find()"}); 01377 end 01378 return ovm_top.find(comp_match); 01379 endfunction 01380 01381 01382 // find_components (deprecated) 01383 // --------------- 01384 01385 function void ovm_component::find_components (string comp_match, 01386 ref ovm_component comps[$]); 01387 static bit issued=0; 01388 if (!issued) begin 01389 issued=1; 01390 ovm_top.ovm_report_warning("deprecated", 01391 {"ovm_component::find_components() is deprecated and replaced by ", 01392 "ovm_top.find_all()"}); 01393 end 01394 ovm_top.find_all(comp_match,comps); 01395 endfunction 01396 01397 01398 // get_component (deprecated) 01399 // ------------- 01400 01401 function ovm_component ovm_component::get_component (int ele); 01402 ovm_component m__comps[$]; 01403 static bit issued=0; 01404 if (!issued) begin 01405 issued=1; 01406 ovm_top.ovm_report_warning("deprecated", 01407 {"ovm_component::get_component() is an internal method that has been ", 01408 "deprecated. ovm_top's find, find_all, and ovm_component's lookup ", 01409 "method provide similar functionality."}); 01410 end 01411 if (m__comps.size()==0) 01412 ovm_top.find_all("*",m__comps); 01413 if (ele < m__comps.size()) 01414 return m__comps[ele]; 01415 return null; 01416 endfunction 01417 01418 01419 // get_num_components (deprecated) 01420 // ------------------ 01421 01422 function int ovm_component::get_num_components (); 01423 ovm_component m__comps[$]; 01424 static bit issued=0; 01425 if (!issued) begin 01426 issued=1; 01427 ovm_top.ovm_report_warning("deprecated", 01428 {"ovm_component::get_num_components() is an internal method that has ", 01429 "been deprecated. The number of components in the testbench can be ", 01430 "obtained using the ovm_top.find_all() method."}); 01431 end 01432 while (m__comps.size()!=0) 01433 m__comps.delete(0); 01434 ovm_top.find_all("*",m__comps); 01435 get_num_components = m__comps.size(); 01436 endfunction 01437
![]() 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:17 2009 |