ovm_objection.svh

Go to the documentation of this file.
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
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
Doxygen Version: 1.6.3
IDV SV Filter Version: 2.6.3
Sat Jun 19 11:51:28 2010
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV