00001 //---------------------------------------------------------------------- 00002 // Copyright 2007-2009 Mentor Graphics Corp. 00003 // Copyright 2007-2009 Cadence Design Systems, Inc. 00004 // All Rights Reserved Worldwide 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the 00007 // "License"); you may not use this file except in 00008 // compliance with the License. You may obtain a copy of 00009 // the License at 00010 // 00011 // http://www.apache.org/licenses/LICENSE-2.0 00012 // 00013 // Unless required by applicable law or agreed to in 00014 // writing, software distributed under the License is 00015 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00016 // CONDITIONS OF ANY KIND, either express or implied. See 00017 // the License for the specific language governing 00018 // permissions and limitations under the License. 00019 //---------------------------------------------------------------------- 00020 00021 `ifndef OVM_OBJECTION_SVH 00022 `define OVM_OBJECTION_SVH 00023 00024 //Assumes access to ovm via an import of ovm_pkg or `include of ovm.svh 00025 00026 typedef class ovm_objection; 00027 typedef class ovm_sequence_base; 00028 00029 00030 //------------------------------------------------------------------------------ 00031 // 00032 // Class: ovm_objection 00033 // 00034 //------------------------------------------------------------------------------ 00035 // Objections provide a facility for coordinating status information between 00036 // two or more participating components, objects, and even module-based IP. 00037 // In particular, the ~ovm_test_done~ built-in objection provides a means for 00038 // coordinating when to end a test, i.e. when to call <global_stop_request> to 00039 // end the <ovm_component::run> phase. When all participating components have 00040 // dropped their raised objections with ~ovm_test_done~, an implicit call to 00041 // ~global_stop_request~ is issued. 00042 //------------------------------------------------------------------------------ 00043 00044 class ovm_objection extends ovm_report_object; 00045 00046 protected int m_source_count[ovm_object]; 00047 protected int m_total_count [ovm_object]; 00048 protected time m_drain_time [ovm_object]; 00049 protected bit m_draining [ovm_object]; 00050 00051 protected bit m_hier_mode = 1; 00052 00053 ovm_root top = ovm_root::get(); 00054 00055 // Function: new 00056 // 00057 // Creates a new objection instance. 00058 00059 function new(string name=""); 00060 super.new(name); 00061 set_report_verbosity_level(top.get_report_verbosity_level()); 00062 endfunction 00063 00064 00065 // Function- m_report 00066 // 00067 // Internal method for reporting count updates 00068 00069 function void m_report(ovm_object obj, ovm_object source_obj, int count, string action); 00070 // workaround to array lookup in IUS? 00071 int _count = m_source_count.exists(obj) ? m_source_count[obj] : 0; 00072 int _total = m_total_count[obj]; 00073 if (source_obj == obj) 00074 ovm_report_info("OBJTN_CNT", 00075 $sformatf("Object %0s %0s %0d objection(s), count=%0d total=%0d", 00076 obj.get_full_name()==""?"ovm_top":obj.get_full_name(), action, count, _count, _total), OVM_HIGH); 00077 else begin 00078 ovm_report_info("OBJTN_CNT", 00079 $sformatf("Object %0s %0s %0d objection(s) from its total (%s from source object %s), count=%0d total=%0d", 00080 obj.get_full_name()==""?"ovm_top":obj.get_full_name(), action=="raised"?"added":"subtracted", 00081 count, action, source_obj.get_full_name(), _count, _total), OVM_HIGH); 00082 end 00083 endfunction 00084 00085 00086 // Function- m_get_parent 00087 // 00088 // Internal method for getting the parent of the given ~object~. 00089 // The ultimate parent is ovm_top, OVM's implicit top-level component. 00090 00091 function ovm_object m_get_parent(ovm_object obj); 00092 ovm_component comp; 00093 ovm_sequence_base seq; 00094 if ($cast(comp, obj)) begin 00095 obj = comp.get_parent(); 00096 end 00097 else if ($cast(seq, obj)) begin 00098 obj = seq.get_sequencer(); 00099 end 00100 else 00101 obj = top; 00102 if (obj == null) 00103 obj = top; 00104 return obj; 00105 endfunction 00106 00107 00108 // Function- m_propagate 00109 // 00110 // Propagate the objection to the objects parent. If the object is a 00111 // component, the parent is just the hierarchical parent. If the object is 00112 // a sequence, the parent is the parent sequence if one exists, or 00113 // it is the attached sequencer if there is no parent sequence. 00114 // 00115 // obj : the ovm_object on which the objection is being raised or lowered 00116 // source_obj : the root object on which the end user raised/lowered the 00117 // objection (as opposed to an anscestor of the end user object)a 00118 // count : the number of objections associated with the action. 00119 // raise : indicator of whether the objection is being raised or lowered. A 00120 // 1 indicates the objection is being raised. 00121 00122 function void m_propagate (ovm_object obj, ovm_object source_obj, int count, bit raise); 00123 if (obj != null && obj != top) begin 00124 obj = m_get_parent(obj); 00125 if(raise) 00126 m_raise(obj, source_obj, count); 00127 else 00128 m_drop(obj, source_obj, count); 00129 end 00130 endfunction 00131 00132 00133 // Group: Objection Control 00134 00135 // Hierarchical mode only needs to be set for intermediate components, not 00136 // for ovm_root or a leaf component. 00137 function void m_set_hier_mode (ovm_object obj); 00138 ovm_component c; 00139 if((m_hier_mode == 1) || (obj == top)) begin 00140 // Don't set if already set or the object is ovm_top. 00141 return; 00142 end 00143 if($cast(c,obj)) begin 00144 // Don't set if object is a leaf. 00145 if(c.get_num_children() == 0) begin 00146 return; 00147 end 00148 end 00149 else begin 00150 // Don't set if object is a non-component. 00151 return; 00152 end 00153 00154 // restore counts on non-source nodes 00155 m_total_count.delete(); 00156 foreach (m_source_count[obj]) begin 00157 ovm_object theobj = obj; 00158 int count = m_source_count[obj]; 00159 do begin 00160 if (m_total_count.exists(theobj)) 00161 m_total_count[theobj] += count; 00162 else 00163 m_total_count[theobj] = count; 00164 theobj = m_get_parent(theobj); 00165 end 00166 while (theobj != null); 00167 end 00168 00169 m_hier_mode = 1; 00170 endfunction 00171 00172 // Function: raise_objection 00173 // 00174 // Raises the number of objections for the source ~object~ by ~count~, which 00175 // defaults to 1. The ~object~ is usually the ~this~ handle of the caller. 00176 // If ~object~ is not specified or null, the implicit top-level component, 00177 // ~ovm_top~, is chosen. 00178 // 00179 // Rasing an objection causes the following. 00180 // 00181 // - The source and total objection counts for ~object~ are increased by 00182 // ~count~. 00183 // 00184 // - The objection's <raised> virtual method is called, which calls the 00185 // <ovm_component::raised> method for all of the components up the 00186 // hierarchy. 00187 // 00188 00189 function void raise_objection (ovm_object obj=null, int count=1); 00190 m_raise (obj, obj, count); 00191 endfunction 00192 00193 00194 // Function- m_raise 00195 00196 function void m_raise (ovm_object obj, ovm_object source_obj, int count=1); 00197 00198 if (obj == null) 00199 obj = top; 00200 00201 if (m_total_count.exists(obj)) 00202 m_total_count[obj] += count; 00203 else 00204 m_total_count[obj] = count; 00205 00206 if (source_obj==obj) begin 00207 if (m_source_count.exists(obj)) 00208 m_source_count[obj] += count; 00209 else 00210 m_source_count[obj] = count; 00211 source_obj = obj; 00212 end 00213 00214 if (ovm_report_enabled(OVM_FULL,OVM_INFO,"OBJTN_CNT")) 00215 m_report(obj,source_obj,count,"raised"); 00216 00217 raised(obj, source_obj, count); 00218 00219 // If this object is still draining from a previous drop, then 00220 // raise the count and return. Any propagation will be handled 00221 // by the drain process. 00222 if (m_draining.exists(obj)) 00223 return; 00224 00225 if (!m_hier_mode && obj != top) 00226 m_raise(top,source_obj,count); 00227 else if (obj != top) 00228 m_propagate(obj, source_obj, count, 1); 00229 00230 endfunction 00231 00232 00233 // Function: drop_objection 00234 // 00235 // Drops the number of objections for the source ~object~ by ~count~, which 00236 // defaults to 1. The ~object~ is usually the ~this~ handle of the caller. 00237 // If ~object~ is not specified or null, the implicit top-level component, 00238 // ~ovm_top~, is chosen. 00239 // 00240 // Dropping an objection causes the following. 00241 // 00242 // - The source and total objection counts for ~object~ are decreased by 00243 // ~count~. It is an error to drop the objection count for ~object~ below 00244 // zero. 00245 // 00246 // - The objection's <dropped> virtual method is called, which calls the 00247 // <ovm_component::dropped> method for all of the components up the 00248 // hierarchy. 00249 // 00250 // - If the total objection count has not reached zero for ~object~, then 00251 // the drop is propagated up the object hierarchy as with 00252 // <raise_objection>. Then, each object in the hierarchy will have updated 00253 // their ~source~ counts--objections that they originated--and ~total~ 00254 // counts--the total number of objections by them and all their 00255 // descendants. 00256 // 00257 // If the total objection count reaches zero, propagation up the hierarchy 00258 // is deferred until a configurable drain-time has passed and the 00259 // <ovm_component::all_dropped> callback for the current hierarchy level 00260 // has returned. The following process occurs for each instance up 00261 // the hierarchy from the source caller: 00262 // 00263 // A process is forked in a non-blocking fashion, allowing the ~drop~ 00264 // call to return. The forked process then does the following: 00265 // 00266 // - If a drain time was set for the given ~object~, the process waits for 00267 // that amount of time. 00268 // 00269 // - The objection's <all_dropped> virtual method is called, which calls the 00270 // <ovm_component::all_dropped> method (if ~object~ is a component). 00271 // 00272 // - The process then waits for the ~all_dropped~ callback to complete. 00273 // 00274 // - After the drain time has elapsed and all_dropped callback has 00275 // completed, propagation of the dropped objection to the parent proceeds 00276 // as described in <raise_objection>, except as described below. 00277 // 00278 // If a new objection for this ~object~ or any of its descendents is raised 00279 // during the drain time or during execution of the all_dropped callback at 00280 // any point, the hierarchical chain described above is terminated and the 00281 // dropped callback does not go up the hierarchy. The raised objection will 00282 // propagate up the hierarchy, but the number of raised propagated up is 00283 // reduced by the number of drops that were pending waiting for the 00284 // all_dropped/drain time completion. Thus, if exactly one objection 00285 // caused the count to go to zero, and during the drain exactly one new 00286 // objection comes in, no raises or drops are propagted up the hierarchy, 00287 // 00288 // As an optimization, if the ~object~ has no set drain-time and no 00289 // registered callbacks, the forked process can be skipped and propagation 00290 // proceeds immediately to the parent as described. 00291 00292 function void drop_objection (ovm_object obj=null, int count=1); 00293 m_drop (obj, obj, count); 00294 endfunction 00295 00296 00297 // Function- m_drop 00298 00299 function void m_drop (ovm_object obj, ovm_object source_obj, int count=1); 00300 00301 if (obj == null) 00302 obj = top; 00303 00304 if (!m_total_count.exists(obj) || (count > m_total_count[obj])) begin 00305 ovm_report_fatal("OBJTN_ZERO", {"Object \"", obj.get_full_name(), 00306 "\" attempted to drop objection count below zero."}); 00307 return; 00308 end 00309 if ((obj == source_obj) && 00310 (!m_source_count.exists(obj) || (count > m_source_count[obj]))) begin 00311 ovm_report_fatal("OBJTN_ZERO", {"Object \"", obj.get_full_name(), 00312 "\" attempted to drop objection count below zero."}); 00313 return; 00314 end 00315 00316 m_total_count[obj] -= count; 00317 00318 if (source_obj==obj) begin 00319 m_source_count[obj] -= count; 00320 source_obj = obj; 00321 end 00322 00323 if (ovm_report_enabled(OVM_FULL,OVM_INFO,"OBJTN_CNT")) 00324 m_report(obj,source_obj,count,"dropped"); 00325 00326 dropped(obj, source_obj, count); 00327 00328 // if count != 0, no reason to fork 00329 if (m_total_count[obj] != 0) begin 00330 00331 if (!m_hier_mode && obj != top) 00332 m_drop(top,source_obj,count); 00333 else if (obj != top) 00334 this.m_propagate(obj, source_obj, count, 0); 00335 00336 end 00337 else begin 00338 00339 int diff_count; 00340 bit reraise; 00341 00342 m_draining[obj] = 1; 00343 00344 fork begin 00345 00346 if (m_total_count[obj] == 0) begin 00347 fork begin //wrapper thread for disable fork 00348 fork 00349 begin 00350 if (m_drain_time.exists(obj)) 00351 #(m_drain_time[obj]); 00352 00353 all_dropped(obj,source_obj,count); 00354 00355 // wait for all_dropped cbs to complete 00356 wait fork; 00357 end 00358 wait (m_total_count[obj] != 0); 00359 join_any 00360 disable fork; 00361 end join 00362 end 00363 00364 m_draining.delete(obj); 00365 00366 diff_count = m_total_count[obj] - count; 00367 00368 // no propagation if the re-raise cancels the drop 00369 if (diff_count != 0) begin 00370 reraise = diff_count > 0 ? 1 : 0; 00371 00372 if (diff_count < 0) 00373 diff_count = -diff_count; 00374 00375 if (!m_hier_mode && obj != top) begin 00376 if (reraise) 00377 m_raise(top,source_obj,diff_count); 00378 else 00379 m_drop(top,source_obj,diff_count); 00380 end 00381 else 00382 if (obj != top) begin 00383 this.m_propagate(obj, source_obj, diff_count, reraise); 00384 end 00385 end 00386 00387 end 00388 join_none 00389 00390 end 00391 00392 endfunction 00393 00394 00395 // Function: set_drain_time 00396 // 00397 // Sets the drain time on the given ~object~ to ~drain~. 00398 // 00399 // The drain time is the amount of time to wait once all objections have 00400 // been dropped before calling the all_dropped callback and propagating 00401 // the objection to the parent. 00402 // 00403 // If a new objection for this ~object~ or any of its descendents is raised 00404 // during the drain time or during execution of the all_dropped callbacks, 00405 // the drain_time/all_dropped execution is terminated. 00406 00407 function void set_drain_time (ovm_object obj, time drain); 00408 m_drain_time[obj] = drain; 00409 m_set_hier_mode(obj); 00410 endfunction 00411 00412 00413 // Group: Callback Hooks 00414 00415 // Function: raised 00416 // 00417 // Objection callback that is called when a <raise_objection> has reached ~obj~. 00418 // The default implementation calls <ovm_component::raised>. 00419 00420 virtual function void raised (ovm_object obj, ovm_object source_obj, int count); 00421 ovm_component comp; 00422 if ($cast(comp,obj)) 00423 comp.raised(this, source_obj, count); 00424 endfunction 00425 00426 00427 // Function: dropped 00428 // 00429 // Objection callback that is called when a <drop_objection> has reached ~obj~. 00430 // The default implementation calls <ovm_component::dropped>. 00431 00432 virtual function void dropped (ovm_object obj, ovm_object source_obj, int count); 00433 ovm_component comp; 00434 if($cast(comp,obj)) 00435 comp.dropped(this, source_obj, count); 00436 endfunction 00437 00438 00439 // Function: all_dropped 00440 // 00441 // Objection callback that is called when a <drop_objection> has reached ~obj~, 00442 // and the total count for ~obj~ goes to zero. This callback is executed 00443 // after the drain time associated with ~obj~. The default implementation 00444 // calls <ovm_component::all_dropped>. 00445 00446 virtual task all_dropped (ovm_object obj, ovm_object source_obj, int count); 00447 ovm_component comp; 00448 if($cast(comp,obj)) 00449 comp.all_dropped(this, source_obj, count); 00450 endtask 00451 00452 00453 // Group: Objection Status 00454 00455 // Function: get_objection_count 00456 // 00457 // Returns the current number of objections raised by the given ~object~. 00458 00459 function int get_objection_count (ovm_object obj); 00460 if (!m_source_count.exists(obj)) 00461 return 0; 00462 return m_source_count[obj]; 00463 endfunction 00464 00465 00466 // Function: get_objection_total 00467 // 00468 // Returns the current number of objections raised by the given ~object~ 00469 // and all descendants. 00470 00471 function int get_objection_total (ovm_object obj=null); 00472 ovm_component c; 00473 string ch; 00474 00475 if (obj==null) 00476 obj = top; 00477 00478 if (!m_total_count.exists(obj)) 00479 return 0; 00480 if (m_hier_mode) 00481 return m_total_count[obj]; 00482 else begin 00483 if ($cast(c,obj)) begin 00484 get_objection_total = m_source_count[obj]; 00485 if (c.get_first_child(ch)) 00486 do 00487 get_objection_total += get_objection_total(c.get_child(ch)); 00488 while (c.get_next_child(ch)); 00489 end 00490 else begin 00491 return m_total_count[obj]; 00492 end 00493 end 00494 endfunction 00495 00496 00497 // Function: get_drain_time 00498 // 00499 // Returns the current drain time set for the given ~object~ (default: 0 ns). 00500 00501 function time get_drain_time (ovm_object obj); 00502 if (!m_drain_time.exists(obj)) 00503 return 0; 00504 return m_drain_time[obj]; 00505 endfunction 00506 00507 00508 // Function: display_objections 00509 // 00510 // Displays objection information about the given ~object~. If ~object~ is 00511 // not specified or ~null~, the implicit top-level component, <ovm_top>, is 00512 // chosen. The ~show_header~ argument allows control of whether a header is 00513 // output. 00514 00515 protected function string m_display_objections(ovm_object obj=null, bit show_header=1); 00516 00517 static string blank=" "; 00518 00519 string s; 00520 int total; 00521 ovm_object list[string]; 00522 ovm_object curr_obj; 00523 int depth; 00524 string name; 00525 string this_obj_name; 00526 string curr_obj_name; 00527 00528 foreach (m_total_count[o]) begin 00529 ovm_object theobj = o; 00530 if ( m_total_count[o] > 0) 00531 list[theobj.get_full_name()] = theobj; 00532 end 00533 00534 if (obj==null) 00535 obj = top; 00536 00537 total = get_objection_total(obj); 00538 00539 s = $sformatf("The total objection count is %0d\n",total); 00540 00541 if (total == 0) 00542 return s; 00543 00544 s = {s,"---------------------------------------------------------\n"}; 00545 s = {s,"Source Total \n"}; 00546 s = {s,"Count Count Object\n"}; 00547 s = {s,"---------------------------------------------------------\n"}; 00548 00549 00550 this_obj_name = obj.get_full_name(); 00551 curr_obj_name = this_obj_name; 00552 00553 do begin 00554 00555 curr_obj = list[curr_obj_name]; 00556 00557 // determine depth 00558 depth=0; 00559 foreach (curr_obj_name[i]) 00560 if (curr_obj_name[i] == ".") 00561 depth++; 00562 00563 // determine leaf name 00564 name = curr_obj_name; 00565 for (int i=curr_obj_name.len()-1;i >= 0; i--) 00566 if (curr_obj_name[i] == ".") begin 00567 name = curr_obj_name.substr(i+1,curr_obj_name.len()-1); 00568 break; 00569 end 00570 if (curr_obj_name == "") 00571 name = "ovm_top"; 00572 else 00573 depth++; 00574 00575 // print it 00576 s = {s, $sformatf("%-6d %-6d %s%s\n", 00577 m_source_count.exists(curr_obj) ? m_source_count[curr_obj] : 0, 00578 m_total_count.exists(curr_obj) ? m_total_count[curr_obj] : 0, 00579 blank.substr(0,2*depth), name)}; 00580 00581 end while (list.next(curr_obj_name) && 00582 curr_obj_name.substr(0,this_obj_name.len()-1) == this_obj_name); 00583 00584 s = {s,"---------------------------------------------------------\n"}; 00585 00586 return s; 00587 00588 endfunction 00589 00590 00591 function string convert2string(); 00592 return m_display_objections(top,1); 00593 endfunction 00594 00595 function void display_objections(ovm_object obj=null, bit show_header=1); 00596 $display(m_display_objections(obj,show_header)); 00597 endfunction 00598 00599 00600 // Below is all of the basic data stuff that is needed for an ovm_object 00601 // for factory registration, printing, comparing, etc. 00602 00603 typedef ovm_object_registry#(ovm_objection,"ovm_objection") type_id; 00604 static function type_id get_type(); 00605 return type_id::get(); 00606 endfunction 00607 00608 function ovm_object create (string name=""); 00609 ovm_objection tmp = new(name); 00610 return tmp; 00611 endfunction 00612 00613 virtual function string get_type_name (); 00614 return "ovm_objection"; 00615 endfunction 00616 00617 function void do_copy (ovm_object rhs); 00618 ovm_objection _rhs; 00619 $cast(_rhs, rhs); 00620 m_source_count = _rhs.m_source_count; 00621 m_total_count = _rhs.m_total_count; 00622 m_drain_time = _rhs.m_drain_time; 00623 m_draining = _rhs.m_draining; 00624 m_hier_mode = _rhs.m_hier_mode; 00625 endfunction 00626 00627 endclass 00628 00629 00630 00631 //------------------------------------------------------------------------------ 00632 // 00633 // Class: ovm_test_done_objection 00634 // 00635 // Built-in end-of-test coordination 00636 //------------------------------------------------------------------------------ 00637 00638 class ovm_test_done_objection extends ovm_objection; 00639 00640 protected static ovm_test_done_objection m_inst = null; 00641 00642 // local function new(); 00643 function new(string name="ovm_test_done"); 00644 super.new(name); 00645 endfunction 00646 00647 // Function: qualify 00648 // 00649 // Checks that the given ~object~ is derived from either <ovm_component> or 00650 // <ovm_sequence_base>. 00651 00652 virtual function void qualify(ovm_object obj=null, bit is_raise); 00653 ovm_component c; 00654 ovm_sequence_base s; 00655 string nm = is_raise ? "raise_objection" : "drop_objection"; 00656 if(! ($cast(c,obj) || $cast(s,obj))) begin 00657 ovm_report_error("TEST_DONE_NOHIER", {"A non-hierarchical object, '", 00658 obj.get_full_name(), "' (", obj.get_type_name(),") was used in a call ", 00659 "to ovm_test_done.", nm,"(). For this objection, a sequence ", 00660 "or component is required." }); 00661 end 00662 endfunction 00663 00664 00665 // Task: all_dropped 00666 // 00667 // This callback is called when the given ~object's~ objection count reaches 00668 // zero; if the ~object~ is the implicit top-level, <ovm_top> then it means 00669 // there are no more objections raised for the ~ovm_test_done~ objection. 00670 // Thus, after calling <ovm_objection::all_dropped>, this method will call 00671 // <global_stop_request> to stop the current task-based phase (e.g. run). 00672 00673 virtual task all_dropped (ovm_object obj, ovm_object source_obj, int count); 00674 super.all_dropped(obj,source_obj,count); 00675 if (obj == top) begin 00676 if(!top.m_in_stop_request) begin 00677 ovm_report_info("TEST_DONE", {"All end-of-test objections have been ", 00678 "dropped, calling global_stop_request()"}, OVM_LOW); 00679 top.stop_request(); 00680 end 00681 else begin 00682 ovm_report_info("TEST_DONE", {"All end-of-test objections have been ", 00683 "dropped"}, OVM_LOW); 00684 end 00685 end 00686 endtask 00687 00688 00689 // Function: raise_objection 00690 // 00691 // Calls <ovm_objection::raise_objection> after calling <qualify>. 00692 // If the ~object~ is not provided or is ~null~, then the implicit top-level 00693 // component, ~ovm_top~, is chosen. 00694 00695 virtual function void raise_objection (ovm_object obj=null, int count=1); 00696 if(obj==null) 00697 obj=top; 00698 else 00699 qualify(obj, 1); 00700 super.raise_objection(obj,count); 00701 endfunction 00702 00703 00704 // Function: drop 00705 // 00706 // Calls <ovm_objection::drop_objection> after calling <qualify>. 00707 // If the ~object~ is not provided or is ~null~, then the implicit top-level 00708 // component, ~ovm_top~, is chosen. 00709 00710 virtual function void drop_objection (ovm_object obj=null, int count=1); 00711 if(obj==null) 00712 obj=top; 00713 else 00714 qualify(obj, 0); 00715 super.drop_objection(obj,count); 00716 endfunction 00717 00718 // Below is all of the basic data stuff that is needed for an ovm_object 00719 // for factory registration, printing, comparing, etc. 00720 00721 typedef ovm_object_registry#(ovm_test_done_objection,"ovm_test_done") type_id; 00722 static function type_id get_type(); 00723 return type_id::get(); 00724 endfunction 00725 00726 function ovm_object create (string name=""); 00727 ovm_test_done_objection tmp = new(name); 00728 return tmp; 00729 endfunction 00730 00731 virtual function string get_type_name (); 00732 return "ovm_test_done"; 00733 endfunction 00734 00735 static function ovm_test_done_objection get(); 00736 if(m_inst == null) 00737 m_inst = ovm_test_done_objection::type_id::create("ovm_test_done"); 00738 return m_inst; 00739 endfunction 00740 00741 endclass 00742 00743 00744 `endif 00745
![]() Intelligent Design Verification Project: OVM, Revision: 2.1.0 |
Copyright (c) 2008-2010 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.6.3 IDV SV Filter Version: 2.6.3 Sat Jun 19 11:51:28 2010 |