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