ovm_event.sv

Go to the documentation of this file.
00001 // $Id: a00228.html,v 1.1 2009/01/07 19:29:57 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_event.svh"
00023 
00024 
00025 //------------------------------------------------------------------------------
00026 //
00027 // CLASS: ovm_event_callback
00028 //
00029 //------------------------------------------------------------------------------
00030 
00031 // new
00032 // ---
00033 
00034 function ovm_event_callback::new (string name=""); 
00035   super.new(name);
00036 endfunction
00037 
00038 
00039 // create
00040 // ------
00041 
00042 function ovm_object ovm_event_callback::create (string name="");
00043   ovm_event_callback v;
00044 // Not allowed since ovm_event_callback is abstract 
00045 //  v=new(name);
00046 //  return v;
00047   return null;
00048 endfunction
00049 
00050 
00051 // pre_trigger
00052 // -----------
00053 
00054 function bit ovm_event_callback::pre_trigger(ovm_event e,
00055                                              ovm_object data=null);
00056   // empty by default
00057   return 0;
00058 endfunction
00059 
00060 
00061 // post_trigger
00062 // ------------
00063 
00064 function void ovm_event_callback::post_trigger(ovm_event e,
00065                                                ovm_object data=null);
00066   // empty by default
00067   return;
00068 endfunction
00069 
00070 
00071 //------------------------------------------------------------------------------
00072 //
00073 // CLASS: ovm_event
00074 //
00075 //------------------------------------------------------------------------------
00076 
00077 // new
00078 // ---
00079 
00080 function ovm_event::new (string name=""); 
00081   super.new(name);
00082 endfunction
00083 
00084 
00085 // get_type_name
00086 // -------------
00087 
00088 function string ovm_event::get_type_name ();
00089   return this.type_name;
00090 endfunction
00091 
00092 
00093 // create
00094 // ------
00095 
00096 function ovm_object ovm_event::create (string name=""); 
00097   ovm_event v;
00098   v=new(name);
00099   return v;
00100 endfunction
00101 
00102 
00103 // wait_on
00104 // -------
00105 
00106 task ovm_event::wait_on (bit delta=0);
00107 
00108   if (this.on) begin
00109     if (delta)
00110       #0;
00111     return;
00112   end
00113   this.num_waiters++;
00114   @on; //wait(m_event.triggered); //@on; 'this' not allowed
00115 endtask
00116 
00117 
00118 // wait_off
00119 // --------
00120 
00121 task ovm_event::wait_off (bit delta=0);
00122 
00123   if (!this.on) begin
00124     if (delta)
00125       #0;
00126     return;
00127   end
00128   this.num_waiters++;
00129   @on;
00130 endtask
00131 
00132 
00133 // wait_trigger
00134 // ------------
00135 
00136 task ovm_event::wait_trigger ();
00137   this.num_waiters++;
00138   @m_event;
00139 endtask
00140 
00141 // wait_trigger_data
00142 // -----------------
00143 
00144 task ovm_event::wait_trigger_data (output ovm_object data);
00145   wait_trigger();
00146   data = get_trigger_data();
00147 endtask
00148 
00149 
00150 // wait_ptrigger
00151 // -------------
00152 
00153 task ovm_event::wait_ptrigger ();
00154   if (m_event.triggered)
00155     return;
00156   this.num_waiters++;
00157   @m_event;
00158 endtask
00159 
00160 // wait_ptrigger_data
00161 // -----------------
00162 
00163 task ovm_event::wait_ptrigger_data (output ovm_object data);
00164   wait_ptrigger();
00165   data = get_trigger_data();
00166 endtask
00167 
00168 
00169 // trigger
00170 // -------
00171 
00172 function void ovm_event::trigger (ovm_object data=null);
00173   int skip;
00174   skip=0;
00175   if (this.callbacks.size()) begin
00176     for (int i=0;i<callbacks.size();i++) begin
00177       ovm_event_callback tmp;
00178       tmp=this.callbacks[i];
00179       skip = skip + tmp.pre_trigger(this,data);
00180     end
00181   end
00182   if (skip==0) begin
00183     ->m_event;
00184     if (this.callbacks.size()) begin
00185       for (int i=0;i<this.callbacks.size();i++) begin
00186         ovm_event_callback tmp;
00187         tmp=this.callbacks[i];
00188         tmp.post_trigger(this,data);
00189       end
00190     end
00191     this.num_waiters = 0;
00192     this.on = 1;
00193     this.trigger_time = $time;
00194     this.trigger_data = data;
00195   end
00196   //return 1; no timeout yet, so don't need
00197 endfunction
00198 
00199 
00200 // get_trigger_data
00201 // ----------------
00202 
00203 function ovm_object ovm_event::get_trigger_data ();
00204   return this.trigger_data;
00205 endfunction
00206 
00207 
00208 // get_trigger_time
00209 // ----------------
00210 
00211 function time ovm_event::get_trigger_time ();
00212   return this.trigger_time;
00213 endfunction
00214 
00215 
00216 
00217 /*
00218 // is_triggered
00219 // ------------
00220 
00221 function bit ovm_event::is_triggered ();
00222   // TODO: need independent process to reset this
00223   if ($time == 0)
00224     return 0;
00225   return (this.trigger_time >= $time);
00226 endfunction
00227 
00228 
00229 // is_pending
00230 // ----------
00231 
00232 function void ovm_event::is_pending ();
00233   // TODO: need independent process to reset this
00234   if ($time == 0)
00235     return 0;
00236   return (this.trigger_time <= $time);
00237 endfunction
00238 */
00239 
00240 
00241 // is_on
00242 // -----
00243 
00244 function bit ovm_event::is_on ();
00245   return (this.on == 1);
00246 endfunction
00247 
00248 
00249 // is_off
00250 // ------
00251 
00252 function bit ovm_event::is_off ();
00253   return (this.on == 0);
00254 endfunction
00255 
00256 
00257 // reset
00258 // -----
00259 
00260 function void ovm_event::reset (bit wakeup=0);
00261   event e;
00262   if (wakeup)
00263     ->m_event;
00264   m_event = e;
00265   this.num_waiters = 0;
00266   on = 0;
00267   trigger_time = 0;
00268   trigger_data = null;
00269 endfunction
00270 
00271 
00272 // cancel
00273 // ------
00274 
00275 function void ovm_event::cancel ();
00276   if (this.num_waiters > 0)
00277     this.num_waiters--;
00278 endfunction
00279 
00280 
00281 // get_num_waiters
00282 // ---------------
00283 
00284 function int ovm_event::get_num_waiters ();
00285   return this.num_waiters;
00286 endfunction
00287 
00288 
00289 // add_callback
00290 // ------------
00291 
00292 function void ovm_event::add_callback (ovm_event_callback cb,
00293                                        bit append=1);
00294   for (int i=0;i<callbacks.size();i++) begin
00295     if (cb == callbacks[i]) begin
00296       ovm_report_warning("CBRGED","add_callback: Callback already registered. Ignoring.");
00297       return;
00298     end
00299   end
00300   if (append)
00301     callbacks.push_back(cb);
00302   else
00303     callbacks.push_front(cb);
00304 endfunction
00305 
00306 
00307 // delete_callback
00308 // ---------------
00309 
00310 function void ovm_event::delete_callback (ovm_event_callback cb);
00311   for (int i=0;i<callbacks.size();i++) begin
00312     if (cb == callbacks[i]) begin
00313       callbacks.delete(i);
00314       return;
00315     end
00316   end
00317   ovm_report_warning("CBNTFD", "delete_callback: Callback not found. Ignoring delete request.");
00318 endfunction
00319 
00320 function void ovm_event::do_print (ovm_printer printer);
00321   printer.print_field("num_waiters", num_waiters, $bits(num_waiters), OVM_DEC, ".", "int");
00322   printer.print_field("on", on, $bits(on), OVM_BIN, ".", "bit");
00323   printer.print_time("trigger_time", trigger_time);
00324   printer.print_object("trigger_data", trigger_data);
00325   printer.m_scope.down("callbacks", null);
00326   foreach(callbacks[e]) begin
00327     printer.print_object($psprintf("[%0d]",e), callbacks[e], "[");
00328   end
00329   printer.m_scope.up(null);
00330 endfunction
00331 
00332 function void ovm_event::do_copy (ovm_object rhs);
00333   ovm_event e;
00334   super.do_copy(rhs);
00335   if(!$cast(e, rhs) || (e==null)) return;
00336 
00337   m_event = e.m_event;
00338   num_waiters = e.num_waiters;
00339   on = e.on;
00340   trigger_time = e.trigger_time;
00341   trigger_data = e.trigger_data;
00342   for(int i=0; i<callbacks.size(); ++i) void'(callbacks.pop_front());
00343   for(int i=0; i<e.callbacks.size(); ++i) callbacks.push_back(e.callbacks[i]);
00344 endfunction
00345 
00346 
00347 //------------------------------------------------------------------------------
00348 //
00349 // CLASS: ovm_barrier
00350 //
00351 //------------------------------------------------------------------------------
00352 
00353 // new
00354 // ---
00355 
00356 function ovm_barrier::new (string name="",
00357                            int threshold=0);
00358   ovm_event e;
00359   super.new(name);
00360   e = new({"barrier_",name});
00361   this.threshold = threshold;
00362   this.m_event = e;
00363   this.num_waiters = 0;
00364   this.auto_reset = 1;
00365   this.at_threshold = 0;
00366 endfunction
00367 
00368 
00369 // get_type_name
00370 // -------------
00371 
00372 function string ovm_barrier::get_type_name ();
00373   return type_name;
00374 endfunction
00375 
00376 
00377 // create
00378 // ------
00379 
00380 function ovm_object ovm_barrier::create (string name=""); 
00381   ovm_barrier v;
00382   v=new(name);
00383   return v;
00384 endfunction
00385 
00386 
00387 // wait_for
00388 // --------
00389 
00390 task ovm_barrier::wait_for ();
00391   if (this.at_threshold)
00392     return;
00393 
00394   this.num_waiters++;
00395 
00396   if (reached_threshold()) begin
00397     if (!this.auto_reset)
00398       this.at_threshold=1;
00399     this.m_trigger();
00400     return;
00401   end
00402 
00403   this.m_event.wait_trigger();
00404 endtask
00405  
00406 
00407 // m_trigger (private)
00408 // ---------
00409 
00410 task ovm_barrier::m_trigger ();
00411 
00412   this.m_event.trigger();
00413   this.num_waiters=0;
00414   #0; //this process was last to wait; allow other procs to resume first
00415 
00416 endtask
00417 
00418 
00419 // reset
00420 // -----
00421 
00422 function void ovm_barrier::reset (bit wakeup=1);
00423   this.at_threshold = 0;
00424   if (this.num_waiters) begin
00425     if (wakeup)
00426       this.m_event.trigger();
00427     else
00428       this.m_event.reset();
00429   end
00430   this.num_waiters = 0;
00431 endfunction
00432 
00433 
00434 // cancel
00435 // ------
00436 
00437 function void ovm_barrier::cancel ();
00438   this.m_event.cancel();
00439   this.num_waiters = this.m_event.get_num_waiters();
00440 endfunction
00441 
00442 
00443 // get_threshold
00444 // -------------
00445 
00446 function int ovm_barrier::get_threshold ();
00447   return this.threshold;
00448 endfunction
00449 
00450 
00451 // set_threshold
00452 // ------------
00453 
00454 function void ovm_barrier::set_threshold (int threshold);
00455   this.threshold = threshold;
00456   if (threshold <= num_waiters)
00457     this.reset(1);
00458 endfunction
00459 
00460 
00461 // set_auto_reset
00462 // --------------
00463 
00464 function void ovm_barrier::set_auto_reset (bit value=1);
00465   this.at_threshold = 0;
00466   this.auto_reset = value;
00467 endfunction
00468 
00469 
00470 // reached_threshold
00471 // -----------------
00472 
00473 function bit ovm_barrier::reached_threshold ();
00474   return (this.num_waiters >= this.threshold);
00475 endfunction
00476 
00477 
00478 // get_num_waiters
00479 // ---------------
00480 
00481 function int ovm_barrier::get_num_waiters ();
00482   return this.num_waiters;
00483 endfunction
00484 
00485 function void ovm_barrier::do_print (ovm_printer printer);
00486   printer.print_field("threshold", threshold, $bits(threshold), OVM_DEC, ".", "int");
00487   printer.print_field("num_waiters", num_waiters, $bits(num_waiters), OVM_DEC, ".", "int");
00488   printer.print_field("at_threshold", at_threshold, $bits(at_threshold), OVM_BIN, ".", "bit");
00489   printer.print_field("auto_reset", auto_reset, $bits(auto_reset), OVM_BIN, ".", "bit");
00490 endfunction
00491 
00492 function void ovm_barrier::do_copy (ovm_object rhs);
00493   ovm_barrier b;
00494   super.do_copy(rhs);
00495   if(!$cast(b, rhs) || (b==null)) return;
00496 
00497   threshold = b.threshold;
00498   num_waiters = b.num_waiters;
00499   at_threshold = b.at_threshold;
00500   auto_reset = b.auto_reset;
00501   m_event = b.m_event;
00502 
00503  endfunction  
00504 
00505 //------------------------------------------------------------------------------
00506 //
00507 // CLASS: ovm_event_pool
00508 //
00509 //------------------------------------------------------------------------------
00510 
00511 // new
00512 // ---
00513 
00514 function ovm_event_pool::new (string name=""); 
00515   super.new(name);
00516 endfunction
00517 
00518 
00519 // get_type_name
00520 // -------------
00521 
00522 function string ovm_event_pool::get_type_name ();
00523   return type_name;
00524 endfunction
00525 
00526 
00527 // create
00528 // ------
00529 
00530 function ovm_object ovm_event_pool::create (string name=""); 
00531   ovm_event_pool v;
00532   v=new(name);
00533   return v;
00534 endfunction
00535 
00536 
00537 // get_global_pool (static)
00538 // ---------------
00539 
00540 function ovm_event_pool ovm_event_pool::get_global_pool ();
00541   if (m_global_pool==null) begin
00542     ovm_event_pool pool;
00543     pool = new("pool");
00544     m_global_pool = pool;
00545   end
00546   return m_global_pool;
00547 endfunction
00548 
00549 
00550 // get
00551 // ---
00552 
00553 function ovm_event ovm_event_pool::get (string name);
00554   ovm_event e;
00555   if(this.pool.exists(name)) e = this.pool[name];
00556 
00557   if (e==null) begin
00558      e = new (name);
00559      this.pool[name] = e;
00560   end
00561   return e;
00562 endfunction
00563 
00564 
00565 // num
00566 // ---
00567 
00568 function int ovm_event_pool::num ();
00569   return this.pool.num();
00570 endfunction
00571 
00572 
00573 // delete
00574 // ------
00575 
00576 function void ovm_event_pool::delete (string name);
00577   if (!this.exists(name)) begin
00578     ovm_report_warning("EVNTX", $psprintf("delete: %0s doesn't exist. Ignoring delete request",name));
00579     return;
00580   end
00581   this.pool.delete(name);
00582 endfunction
00583 
00584 
00585 // exists
00586 // ------
00587 
00588 function int ovm_event_pool::exists (string name);
00589   return this.pool.exists(name);
00590 endfunction
00591 
00592 
00593 // first
00594 // -----
00595 
00596 function int ovm_event_pool::first (ref string name);
00597   return this.pool.first(name);
00598 endfunction
00599 
00600 
00601 // last
00602 // ----
00603 
00604 function int ovm_event_pool::last (ref string name);
00605   return this.pool.last(name);
00606 endfunction
00607 
00608 
00609 // next
00610 // ----
00611 
00612 function int ovm_event_pool::next (ref string name);
00613   return this.pool.next(name);
00614 endfunction
00615 
00616 
00617 // prev
00618 // ----
00619 
00620 function int ovm_event_pool::prev (ref string name);
00621   return this.pool.prev(name);
00622 endfunction
00623 
00624 function void ovm_event_pool::do_print (ovm_printer printer);
00625   printer.print_generic("pool", "aa_object_string", pool.num(), "-");
00626   printer.m_scope.down("pool", null);
00627   foreach(pool[e]) begin
00628     printer.print_object(e, pool[e], "[");
00629   end
00630   printer.m_scope.up(null);
00631 
00632 endfunction
00633 
00634 function void ovm_event_pool::do_copy (ovm_object rhs);
00635   ovm_event_pool ep;
00636   string key;
00637   super.do_copy(rhs);
00638 
00639   if (rhs == null) return;
00640   assert($cast(ep, rhs));
00641 
00642   pool.delete();
00643   if(ep.pool.first(key))
00644     do pool[key] = ep.pool[key];
00645     while(ep.pool.next(key));
00646 
00647 endfunction
00648 
00649 
00650 //------------------------------------------------------------------------------
00651 //
00652 // CLASS: ovm_barrier_pool
00653 //
00654 //------------------------------------------------------------------------------
00655 
00656 // new
00657 // ---
00658 
00659 function ovm_barrier_pool::new (string name=""); 
00660   super.new(name);
00661 endfunction
00662 
00663 
00664 // get_type_name
00665 // -------------
00666 
00667 function string ovm_barrier_pool::get_type_name ();
00668   return type_name;
00669 endfunction
00670 
00671 
00672 // create
00673 // ------
00674 
00675 function ovm_object ovm_barrier_pool::create (string name=""); 
00676   ovm_barrier_pool v;
00677   v=new(name);
00678   return v;
00679 endfunction
00680 
00681 
00682 // get_global_pool (static)
00683 // ---------------
00684 
00685 function ovm_barrier_pool ovm_barrier_pool::get_global_pool ();
00686   if (m_global_pool==null) begin
00687     ovm_barrier_pool pool;
00688     pool = new("pool");
00689     m_global_pool = pool;
00690   end
00691   return m_global_pool;
00692 endfunction
00693 
00694 
00695 // get
00696 // ---
00697 
00698 function ovm_barrier ovm_barrier_pool::get (string name);
00699   ovm_barrier b;
00700   if(this.pool.exists(name)) b = this.pool[name];
00701   if (b==null) begin
00702      b = new (name);
00703      this.pool[name] = b;
00704   end
00705   return b;
00706 endfunction
00707 
00708 
00709 // num
00710 // ---
00711 
00712 function int ovm_barrier_pool::num ();
00713   return this.pool.num();
00714 endfunction
00715 
00716 
00717 // delete
00718 // ------
00719 
00720 function void ovm_barrier_pool::delete (string name);
00721   if (!this.exists(name)) begin
00722     ovm_report_warning("BRNTEX", $psprintf("delete: %0s doesn't exist. Ignoring delete request",name));
00723     return;
00724   end
00725   this.pool.delete(name);
00726 endfunction
00727 
00728 
00729 // exists
00730 // ------
00731 
00732 function int ovm_barrier_pool::exists (string name);
00733   return this.pool.exists(name);
00734 endfunction
00735 
00736 
00737 // first
00738 // -----
00739 
00740 function int ovm_barrier_pool::first (ref string name);
00741   return this.pool.first(name);
00742 endfunction
00743 
00744 
00745 // last
00746 // ----
00747 
00748 function int ovm_barrier_pool::last (ref string name);
00749   return this.pool.last(name);
00750 endfunction
00751 
00752 
00753 // next
00754 // ----
00755 
00756 function int ovm_barrier_pool::next (ref string name);
00757   return this.pool.next(name);
00758 endfunction
00759 
00760 
00761 // prev
00762 // ----
00763 
00764 function int ovm_barrier_pool::prev (ref string name);
00765   return this.pool.prev(name);
00766 endfunction
00767 
00768 function void ovm_barrier_pool::do_print (ovm_printer printer);
00769   printer.print_generic("pool", "aa_object_string", pool.num(), "-");
00770   printer.m_scope.down("pool", null);
00771   foreach(pool[e]) begin
00772     printer.print_object(e, pool[e], "[");
00773   end
00774   printer.m_scope.up(null);
00775 
00776 endfunction
00777 
00778 function void ovm_barrier_pool::do_copy (ovm_object rhs);
00779   ovm_barrier_pool bp;
00780   string key;
00781   super.do_copy(rhs);
00782   if(!$cast(bp, rhs) || (bp==null)) return;
00783 
00784   pool.delete();
00785   if(bp.pool.first(key))
00786     do pool[key] = bp.pool[key];
00787     while(bp.pool.next(key));
00788 
00789 endfunction

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