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 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 Version: 1.5.5 Wed Jan 7 19:27:17 2009 |