VMM - (expanded) std_lib/vmm_channel.sv

Expanded versions of source files are the output of the preprocessor. Lines subject to conditional compilation are not shown and all compiler pragmas have been stripped. Macros have been completely expanded.

std_lib/vmm_channel.sv unexpanded source

00001: // 
00002: // -------------------------------------------------------------
00003: //    Copyright 2004-2008 Synopsys, 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: 
00022: 
00023: // ToDo: Fill level based on bytes
00024:    
00025: function vmm_channel::new(string       name,
00026:                           string       inst,
00027:                           int unsigned full,
00028:                           int unsigned empty,
00029:                           bit          fill_as_bytes);
00033: 
00034:    if (this.one_log) begin
00035:       if (this.shared_log == null) begin
00036:          this.shared_log = new("VMM Channel", "[shared]");
00037:       end
00038:       this.log = shared_log;
00039:    end else this.log = new(name, inst);
00040: 
00041:    this.notify = new(this.log);
00042:    this.notify.configure(FULL,  vmm_notify::ON_OFF);
00043:    this.notify.configure(EMPTY, vmm_notify::ON_OFF);
00044:    this.notify.configure(PUT);
00045:    this.notify.configure(GOT);
00046:    this.notify.configure(PEEKED);
00047:    this.notify.configure(ACTIVATED);
00048:    this.notify.configure(ACT_STARTED);
00049:    this.notify.configure(ACT_COMPLETED);
00050:    this.notify.configure(ACT_REMOVED);
00051:    this.notify.configure(LOCKED);
00052:    this.notify.configure(UNLOCKED);
00053: 
00054:    if (full <= 0) full = 1;
00055:    if (empty < 0 || empty > full) empty = full;
00056: 
00057:    this.full = full;
00058:    this.empty = empty;
00059:    this.is_sunk  = 0;
00060: 
00061:    this.active = null;
00062:    this.active_status = INACTIVE;
00063:    this.tee_on = 0;
00064:    this.downstream = null;
00065:    this.locks  = 2'b00;
00066: 
00067:    this.full_chan = 0;
00068:    this.notify.indicate(EMPTY);
00069: 
00070:    this.iterator = 0;
00071: 
00072:    //
00073:    // Thread to manage connection requests
00074:    //
00075:    fork: connection_requests
00076:       while (1)
00077:       begin : new_while_loop
00078:          vmm_data data = null;
00079: 
00080:          // Broken connection?
00081:          if (this.downstream != null)
00082:          begin
00083:             if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV))
00084:             begin
00085:                string txt;
00086:                txt = {"Channel connection established: ",
00087:                       this.log.get_name(),
00088:                       "(", this.log.get_instance(), ") -> ",
00089:                       this.downstream.log.get_name(),
00090:                       "(", this.downstream.log.get_instance(), ")"};
00091:        
00092:                this.log.text(txt);
00093:                this.log.end_msg();
00094:             end // if debug level
00095:      
00096:             // Fork the data mover thread
00097:             fork
00098:                while (1)
00099:                begin : inner_while_loop
00100:                   // Simple blocking interface
00101:                   data = null;
00102:                   this.peek(data);
00103:                   this.downstream.put(data);
00104:                   this.get(data);
00105:                end // inner_while_loop
00106:             join_none
00107:          end // if downstream != null
00108:      
00109:          // Wait for new connection requests
00110:          @this.new_connection;
00111:          
00112:          // Stop the data mover thread
00113:          disable fork;
00114:         
00115:          // Remove any datum that was forwarded
00116:          // to the downstream channel but not removed
00117:          // from this channel because of the blocking
00118:          // model. Otherwise, the same datum will be
00119:          // obtained from this channel twice.
00120:          if (data != null) this.get(data);
00121:      end // while (1)
00122:    join_none // connection_requests
00123: endfunction : new
00124: 
00125: 
00126: function void vmm_channel::reconfigure(int   full,
00127:                                        int   empty,
00128:                                        logic fill_as_bytes);
00129:    if (full < 0) full = this.full;
00130:    if (full == 0) full = 1;
00131:    if (empty < 0) empty = this.empty;
00132: 
00133:    if (full < empty)
00134:    begin
00135:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("Cannot reconfigure channel with FULL < EMPTY")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00136:       return;
00137:    end
00138: 
00139:    this.full = full;
00140:    this.empty = empty;
00141: 
00142:    if (this.level() >= this.full)
00143:    begin 
00144:       this.full_chan = 1;
00145:       this.notify.indicate(FULL);
00146:       this.notify.reset(EMPTY);
00147:    end
00148:    else if (this.level() <= this.empty)
00149:    begin
00150:       this.full_chan = 0;
00151:       -> this.item_taken;
00152:       this.notify.indicate(EMPTY);
00153:       this.notify.reset(FULL);
00154:    end
00155:    else
00156:    begin
00157:       this.full_chan = 0;
00158:       -> this.item_taken;
00159:       this.notify.reset(EMPTY);
00160:       this.notify.reset(FULL);
00161:    end
00162: endfunction: reconfigure
00163: 
00164: 
00165: function int unsigned vmm_channel::full_level();
00166:    full_level = this.full;
00167: endfunction: full_level
00168: 
00169: 
00170: function int unsigned vmm_channel::empty_level();
00171:    empty_level = this.empty;
00172: endfunction: empty_level
00173: 
00174: 
00175: function int unsigned vmm_channel::level();
00176:    level = this.data.size() + ((this.active == null) ? 0 : 1);
00177: endfunction: level
00178: 
00179: 
00180: function int unsigned vmm_channel::size();
00181:    size = this.data.size() + ((this.active == null) ? 0 : 1);
00182: endfunction : size
00183: 
00184: 
00185: function bit vmm_channel::is_full();
00186:    is_full = full_chan;
00187: endfunction : is_full
00188: 
00189: 
00190: function void vmm_channel::flush();
00191:    vmm_data obj;
00192:    if (this.downstream != null)
00193:       this.downstream.flush();
00194: 
00201:    // This works in VCS 2008.03
00202:    this.data = '{};
00203:    this.tee_data = '{};
00205:    full_chan = 0;
00206:    this.active = null;
00207:    this.active_status = INACTIVE ;
00208:    -> this.item_taken;
00209:    this.notify.reset(FULL);
00210:    this.notify.indicate(EMPTY);
00211: endfunction: flush
00212: 
00213: 
00214: function void vmm_channel::sink();
00215:    this.flush();
00216:    this.is_sunk = 1;
00217: endfunction: sink
00218: 
00219: 
00220: function void vmm_channel::flow();
00221:    this.is_sunk = 0;
00222: endfunction: flow
00223: 
00224: 
00225: function void vmm_channel::reset();
00226:    this.flush();
00227: endfunction: reset
00228: 
00229: 
00230: function void vmm_channel::lock(bit [1:0] who);
00231:    this.locks |= who;
00232:    this.notify.indicate(LOCKED);
00233: endfunction: lock
00234: 
00235: 
00236: function void vmm_channel::unlock(bit [1:0] who);
00237:    this.locks &= ~who;
00238:    this.notify.indicate(UNLOCKED);
00239:    // May cause a consumer or producer to unblock
00240:    -> this.item_taken;
00241:    -> this.item_added;
00242: endfunction: unlock
00243: 
00244: 
00245: function bit vmm_channel::is_locked(bit [1:0] who);
00246:    is_locked = (this.locks & who) ? 1 : 0;
00247: endfunction: is_locked
00248: 
00249: 
00250: function void vmm_channel::display(string prefix);
00251:    $display(this.psdisplay(prefix));
00252: endfunction: display
00253: 
00254: 
00255: function string vmm_channel::psdisplay(string prefix);
00256:    $sformat(psdisplay, "%sChannel %s(%s): Level = %0d of %0d (empty=%0d)",
00257:             prefix, this.log.get_name(), this.log.get_instance(),
00258:             this.level(), this.full, this.empty);
00259:    case (this.locks) 
00260:       SOURCE+SINK : psdisplay = {psdisplay, " [src+snk locked]"};
00261:       SOURCE:       psdisplay = {psdisplay, " [src locked]"};
00262:       SINK:         psdisplay = {psdisplay, " [snk locked]"};
00263:    endcase
00264:    if (this.is_sunk) psdisplay = {psdisplay, " (sunk)"};
00265: 
00266:    foreach(this.data[i]) begin
00267:       $sformat(psdisplay, "%s\n%s", psdisplay, this.data[i].psdisplay($psprintf("%s   [%0d] ",
00268:                                                                                     prefix, i)));
00269:    end
00270: endfunction: psdisplay
00271: 
00272: 
00274: task vmm_channel::put(vmm_data obj,
00275:                       int offset);
00276:    if (obj == null)
00277:    begin
00278:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("Attempted to put null instance into channel")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00279:       return;
00280:    end // if obj == null
00281: 
00282:    this.block_producer();
00283:    this.sneak(obj, offset);
00284:    this.block_producer();
00285: endtask: put
00287: 
00288: function void vmm_channel::sneak(vmm_data obj,
00289:                                  int offset);
00290:    string txt;
00291: 
00292:    if (obj == null)
00293:    begin
00294:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("Attempted to sneak null instance into channel")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00295:       return;
00296:    end // obj == null
00297: 
00298:    if (this.is_sunk) return;
00299: 
00300:    if (offset == -1 || (offset == 0 && this.data.size() == 0))
00301:    begin
00302:       this.data.push_back(obj);
00303:    end
00304:    else
00305:    begin
00306:       int idx = this.index(offset);
00307:       if (idx < 0) return;
00308: 
00309:       this.data.insert(offset, obj);
00310:    end // if offset
00311: 
00312:    if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00313:    begin
00314:      $sformat(txt, "New instance added to channel @%0d (level %0d of %0d/%0d)\n%s",
00315:               offset, this.level(), this.full, this.empty,
00316:               obj.psdisplay("    "));
00317:       this.log.text(txt);
00318:       this.log.end_msg();
00319:    end // if dbg
00320: 
00321:    this.notify.indicate(PUT, obj);
00322: 
00323:    if (this.level() >= this.full)
00324:    begin
00325:       this.full_chan = 1;
00326:       this.notify.indicate(FULL);
00327:    end
00328: 
00329:    if (this.level() > this.empty)
00330:    begin
00331:       this.notify.reset(EMPTY);
00332:    end
00333: 
00334:    -> this.item_added;
00335: endfunction: sneak
00336: 
00337: 
00338: function vmm_data vmm_channel::unput(int offset);
00339:    if (this.size() == 0)
00340:    begin
00341:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 
     :       void'(this.log.text("Cannot unput from an empty channel")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00342:       return null;
00343:    end // if size == 0
00344: 
00345:    if (offset == -1)
00346:    begin
00347:      unput = this.data.pop_back();
00348:    end
00349:    else
00350:    begin
00351:      int idx = this.index(offset);
00352:      if (idx < 0)
00353:      begin
00354:         unput = null;
00355:      end
00356:      else
00357:      begin
00358:         unput = this.data[idx];
00359:         this.data.delete(idx);
00360:      end
00361:    end // if offset != -1
00362: 
00363:    if (unput != null) begin
00364:       this.notify.indicate(GOT, unput);
00365:       if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00366:       begin
00367:          string txt;
00368:          $sformat(txt, "Instance unput from channel @%0d (level %0d of %0d/%0d)\n%s", 
00369:                   offset, this.level(), this.full, this.empty,
00370:                   unput.psdisplay("    "));
00371:          this.log.text(txt);
00372:          this.log.end_msg();
00373:       end // if dbg_lvl
00374:    end
00375: 
00376:    this.unblock_producer();
00377: endfunction: unput
00378: 
00379: 
00380: task vmm_channel::get1(output vmm_data obj,
00381:                        input  int      offset);
00382:    if (offset == 0)
00383:    begin
00384:       obj = this.data.pop_front();
00385:    end
00386:    else
00387:    begin
00388:       int idx = this.index(offset);
00389:       if (idx < 0)
00390:       begin
00391:          obj = null;
00392:       end
00393:       else 
00394:       begin
00395:          obj = this.data[idx];
00396:          this.data.delete(idx);
00397:       end // else if idx < 0
00398:     end // else if offset
00399: 
00400:    if (obj != null)
00401:    begin
00402:       this.notify.indicate(GOT, obj);
00403:       if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00404:       begin
00405:          string txt;
00406:          $sformat(txt, "New instance removed from channel @%0d (level %0d of %0d/%0d)\n%s", 
00407:                   offset, this.level(), this.full, this.empty,
00408:                   obj.psdisplay("    "));
00409:          this.log.text(txt);
00410:          this.log.end_msg();
00411:       end // if dbg_lvl
00412: 
00413:       if (this.tee_on)
00414:       begin
00415:          this.tee_data.push_back(obj);
00416:          -> this.teed;
00417:       end // tee_on
00418: 
00443:    end // if obj != null
00444: endtask: get1
00445: 
00446: 
00447: task vmm_channel::get(output vmm_data obj,
00448:                       input  int      offset);
00449:    this.block_consumer();
00450:    this.get1(obj, offset);
00451:    this.unblock_producer();
00452: endtask: get
00453: 
00454: task vmm_channel::peek(output vmm_data obj,
00455:                        input  int      offset);
00456:    string txt;
00457:    int    idx;
00458: 
00459:    this.block_consumer();
00460: 
00461:    idx = this.index(offset);
00462:    if (idx < 0)
00463:    begin
00464:       obj = null;
00465:    end
00466:    else
00467:    begin
00468:       obj = this.data[idx];
00469:    end
00470: 
00471:    if (obj != null)
00472:    begin
00473:       this.notify.indicate(PEEKED, obj);
00474:       if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00475:       begin
00476:          $sformat(txt, "New instance peeked from channel @%0d (level %0d of %0d/%0d)\n%s",
00477:                   offset, this.level(), this.full, this.empty,
00478:                   obj.psdisplay("    "));
00479:          this.log.text(txt);
00480:          this.log.end_msg();
00481:       end // if dbg_lvl
00482:    end // obj != null
00483: 
00484:    this.unblock_producer();
00485: endtask: peek
00486: 
00487: 
00488: task vmm_channel::activate(output vmm_data obj,
00489:                            input  int      offset);
00490:    string txt;
00491: 
00492:    // Empty the active slot
00493:    if (active != null) 
00494:        this.remove();
00495:  
00496:    while (this.size() == 0) 
00497:       @this.item_added;
00498: 
00499:    if (offset == 0)
00500:    begin
00501:       obj = this.data.pop_front();
00502:    end
00503:    else
00504:    begin
00505:       int idx = this.index(offset);
00506:       if (idx < 0)
00507:       begin
00508:         obj = null;
00509:       end
00510:       else
00511:       begin
00512:         obj = this.data[idx];
00513:         this.data.delete(idx);
00514:       end
00515:    end // else if offset == 0
00516: 
00517: 
00518:    if (obj != null)
00519:    begin
00520:       this.active = obj;
00521:       this.active_status = PENDING ;
00522:       this.notify.indicate(ACTIVATED, obj);
00523:       this.notify.indicate(PEEKED, obj);
00524: 
00525:       if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00526:       begin
00527:          $sformat(txt, "New instance activated from channel @%0d (level %0d of %0d/%0d)\n%s",
00528:                   offset, this.level(), this.full, this.empty,
00529:                   obj.psdisplay("    "));
00530:          this.log.text(txt);
00531:          this.log.end_msg();
00532:       end // if dbg_lvl
00533: 
00534:       if (this.tee_on)
00535:       begin
00536:          this.tee_data.push_back(obj);
00537:          -> this.teed;
00538:       end
00539:    end // if obj != null
00540: endtask: activate
00541: 
00542: 
00543: function vmm_data vmm_channel::active_slot();
00544:    active_slot = this.active;
00545: endfunction: active_slot
00546: 
00547: 
00548: function vmm_data vmm_channel::start();
00549:    if (this.active == null)
00550:    begin
00551:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("Cannot start() without prior activate()")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00552:       return null;
00553:    end // if active == null
00554: 
00555:    if (this.active_status == STARTED)
00556:    begin
00557:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text("Active slot already start()'ed")); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00558:    end // if STARTED
00559: 
00560:    this.active_status = STARTED;
00561:    this.notify.indicate(ACT_STARTED, this.active);
00562:    this.active.notify.indicate(vmm_data::STARTED);
00563:    start = this.active;
00564: endfunction: start
00565: 
00566: 
00567: function vmm_data vmm_channel::complete(vmm_data status);
00568:    if (this.active == null)
00569:    begin
00570:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("Cannot complete() without prior activate()")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00571:       return null;
00572:    end
00573:    if (this.active_status != STARTED)
00574:    begin
00575:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text("complete() called without start()")); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00576:    end
00577: 
00578:    this.active_status = COMPLETED;
00579:    this.notify.indicate(ACT_COMPLETED, this.active);
00580:    this.active.notify.indicate(vmm_data::ENDED, status);
00581:    complete = this.active;
00582: endfunction: complete
00583: 
00584: 
00585: function vmm_data vmm_channel::remove();
00586:    if (this.active == null)
00587:    begin
00588:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("Cannot remove() without prior activate()")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00589:       return null;
00590:    end
00591: 
00592:    // OK to remove if not started or completed   
00593:    if (this.active_status == STARTED)
00594:    begin
00595:       
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text("remove() called without complete()")); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00596:    end
00597: 
00598:    this.notify.indicate(ACT_REMOVED, this.active);
00599:    this.notify.indicate(GOT, this.active);
00600:    if (this.active_status != COMPLETED)
00601:    begin
00602:       this.active.notify.indicate(vmm_data::ENDED);
00603:    end
00604:    this.active_status = INACTIVE;
00605:    remove = this.active;
00606:    this.active = null;
00607: 
00608:    this.unblock_producer();
00609: endfunction: remove
00610: 
00611: 
00612: function vmm_channel::active_status_e vmm_channel::status();
00613:    status = this.active_status;
00614: endfunction: status
00615: 
00616: 
00617: function bit vmm_channel::tee_mode(bit is_on);
00618:    string txt;
00619:    if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV))
00620:    begin
00621:       $sformat(txt, "tee branch turned %0s", (is_on) ? "ON" : "OFF");
00622:       this.log.text(txt);
00623:       this.log.end_msg();
00624:    end
00625: 
00626:    tee_mode = this.tee_on;
00627:    this.tee_on = is_on;
00628: endfunction: tee_mode
00629: 
00630: 
00631: task vmm_channel::tee(output vmm_data obj);
00632:    string txt;
00633:    while (this.tee_data.size() == 0) 
00634:       @this.teed;
00635: 
00636:    obj = this.tee_data.pop_front();
00637: 
00638:    if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV))
00639:    begin
00640:       $sformat(txt, "New instance teed from channel (level %0d of %0d/%0d)\n%s",
00641:                   this.level(), this.full, this.empty,
00642:                   obj.psdisplay("    "));
00643:       this.log.text(txt);
00644:       this.log.end_msg();
00645:    end
00646: endtask: tee
00647: 
00648: 
00649: function void vmm_channel::connect(vmm_channel downstream);
00650:    // Do not disrupt an already-established connection
00651:    if (this.downstream == downstream) return;
00652: 
00653:    // Indicate a new connection
00654:    this.downstream = downstream;
00655:    -> this.new_connection;
00656: endfunction: connect
00657: 
00658: 
00659: function vmm_data vmm_channel::for_each(bit reset);
00660:    if (reset) this.iterator = 0;
00661:    else this.iterator++;
00662: 
00663:    if (this.iterator >= this.data.size()) for_each = null;
00664:    else for_each = this.data[this.iterator];
00665: endfunction: for_each
00666: 
00667: 
00668: function int unsigned vmm_channel::for_each_offset();
00669:    for_each_offset = this.iterator;
00670: endfunction: for_each_offset
00671: 
00672: 
00673: function bit vmm_channel::record(string filename);
00674:    if (filename == "")
00675:    begin
00676:       return 1;
00677:    end
00678: 
00679:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 
     :       void'(this.log.text("vmm_channel::record() not implemented yet")); 
     :       this.log.end_msg(); 
     :    end 
     : while(0);
00680:    record = 0;
00681: endfunction: record
00682: 
00683: 
00684: task vmm_channel::playback(output bit      success,
00685:                            input  string   filename,
00686:                            input  vmm_data loader,
00687:                            input  bit      metered);
00688:    
     : do 
     :    if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin 
     :       void'(this.log.text("vmm_channel::playback() not implemented yet")); 
     :       this.log.end_msg(); 
     :    end 
     : while (0);
00689:    success = 0;
00690: endtask: playback
00691: 
00692: 
00693: function int vmm_channel::index(int offset);
00694:    string txt;
00695:    index = offset;
00696:    if (offset < 0) index += this.data.size() + offset + 1;
00697:    if (index < 0 || index >= this.data.size())
00698:    begin
00699:       if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV))
00700:       begin
00701:          $sformat(txt, "Invalid offset %0d specified. Not in {0:%0d}.\n",
00702:                   offset, this.data.size()-1);
00703:          this.log.text(txt);
00704:          this.log.end_msg();
00705:       end
00706:       index = -1;
00707:    end
00708: endfunction: index
00709: 
00710: 
00712: task vmm_channel::block_producer();
00713:    while (this.full_chan || this.is_locked(SOURCE)) 
00714:       @this.item_taken;
00715: endtask : block_producer
00716: 
00717: 
00718: task vmm_channel::block_consumer();
00719:    while (this.size() == 0 || this.is_locked(SINK)) 
00720:       @this.item_added;
00721: endtask: block_consumer
00723: 
00724: 
00725: function void vmm_channel::unblock_producer();
00726:    if (this.level() <= this.empty)
00727:    begin
00728:       this.full_chan = 0;
00729:       this.notify.indicate(EMPTY);
00730:    end
00731: 
00732:    if (this.level() < this.full)
00733:    begin
00734:       this.notify.reset(FULL);
00735:    end
00736: 
00737:    -> this.item_taken;
00738: endfunction: unblock_producer
00739: 
00740: 
00741: 
00742: 
00743: 
00744: 
00780: