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 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 Version: 1.4.6 Mon Sep 29 14:20:12 2008 |