ovm_component.sv

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