ovm_event.sv

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

Intelligent Design Verification
Intelligent Design Verification
Project: OVM, Revision: 1.1.0
Copyright (c) 2008 Intelligent Design Verification.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included here:
http://www.intelligentdv.com/licenses/fdl.txt
doxygen
Doxygen Version: 1.4.6
Mon Sep 29 14:20:12 2008
Find a documentation bug? Report bugs to: bugs.intelligentdv.com Project: DoxygenFilterSV