VMM OpenSource - (expanded) sv/std_lib/vmm_scenario_gen.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.

sv/std_lib/vmm_scenario_gen.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: 
00027:    // Works in VCS2008.03 or later
00028:    // IEEE 1800-2005 compliant
00029:    `define vmm_delQ(_q) _q = '{}
     : 
00031: 
00032: `define vmm_scenario_(class)                class``_scenario
     : 
00033: `define vmm_scenario_valid_(class)          class``_scenario_valid
     : 
00034: `define vmm_inject_item_scenario_(class)    class``_inject_item_scenario
     : 
00035: `define vmm_atomic_scenario_(class)         class``_atomic_scenario
     : 
00036: `define vmm_scenario_election_(class)       class``_scenario_election
     : 
00037: `define vmm_scenario_election_valid_(class) class``_scenario_election_valid
     : 
00038: `define vmm_scenario_gen_(class)            class``_scenario_gen
     : 
00039: `define vmm_scenario_gen_callbacks_(class)  class``_scenario_gen_callbacks
     : 
00040: 
00041: `define vmm_scenario_gen(class_name, text) \
00042: `vmm_scenario_gen_using(class_name, class_name``_channel, text)
     : 
00043: 
00044: `define vmm_scenario_gen_using(class_name, channel_name, text) \
00045:  \
00046: class `vmm_scenario_(class_name) extends `VMM_SCENARIO; \
00047:  \
00048:    static `VMM_LOG log; \
00049:  \
00050:    rand class_name items[]; \
00051:         class_name using; \
00052:  \
00053:    virtual function string psdisplay(string prefix = ""); \
00054:       psdisplay = super.psdisplay(prefix); \
00055:       foreach (this.items[i]) begin \
00056:          string pfx; \
00057:          if (this.items[i] == null) continue; \
00058:          $sformat(pfx, "%s  Item[%0d]: ", prefix, i); \
00059:          psdisplay = {psdisplay, "\n", this.items[i].psdisplay(pfx)}; \
00060:       end \
00061:       if (this.using != null) begin \
00062:          psdisplay = {psdisplay, "\n", this.using.psdisplay({prefix, "  Using: "})}; \
00063:       end \
00064:       return psdisplay; \
00065:    endfunction \
00066:  \
00067:    constraint `vmm_scenario_valid_(class_name) { \
00068:       items.size() == length; \
00069:  \
00070:       solve length before items.size() `VMM_SOLVE_BEFORE_OPT; \
00071:    } \
00072:  \
00073:    function new(`VMM_SCENARIO_NEW_ARGS); \
00074:       super.new(this.log `VMM_SCENARIO_NEW_CALL); \
00075:       if (this.log == null) begin \
00076:          this.log = new({text, " Scenario"}, "Class"); \
00077:          this.notify.log = this.log; \
00078:       end \
00079:  \
00080:       using = null; \
00081:    endfunction: new \
00082:  \
00083:    function void allocate_scenario(class_name using = null); \
00084:       this.items = new [this.get_max_length()]; \
00085:       foreach (this.items[i]) begin \
00086:          if (using == null) this.items[i] = new; \
00087:          else $cast(this.items[i], using.copy()); \
00088:          `VMM_OBJECT_SET_PARENT(this.items[i], this) \
00089:  \
00090:          this.items[i].stream_id   = this.stream_id; \
00091:          this.items[i].scenario_id = this.scenario_id; \
00092:          this.items[i].data_id     = i; \
00093:       end \
00094:    endfunction: allocate_scenario \
00095:  \
00096:    function void fill_scenario(class_name using = null); \
00097:       int i; \
00098:  \
00099:       if (this.items.size() < this.get_max_length()) begin \
00100:          this.items = new [this.get_max_length()] (this.items); \
00101:       end \
00102:       foreach (this.items[i]) begin \
00103:          if (this.items[i] != null) continue; \
00104:  \
00105:          if (using == null) this.items[i] = new; \
00106:          else $cast(this.items[i], using.copy()); \
00107:          `VMM_OBJECT_SET_PARENT(this.items[i], this) \
00108:  \
00109:          this.items[i].stream_id   = this.stream_id; \
00110:          this.items[i].scenario_id = this.scenario_id; \
00111:          this.items[i].data_id     = i; \
00112:       end \
00113:    endfunction: fill_scenario \
00114:  \
00115:    function void pre_randomize(); \
00116:       this.fill_scenario(this.using); \
00117:    endfunction: pre_randomize \
00118:  \
00119:    virtual task apply(channel_name     channel, \
00120:                       ref int unsigned n_insts); \
00121:       int i; \
00122:  \
00123:       for (i = 0; i < this.length; i++) begin \
00124:          class_name item; \
00125:          $cast(item, this.items[i].copy()); \
00126: `ifndef VMM_GRAB_DISABLED \
00127:          channel.put(item,,this); \
00128: `else \
00129:          channel.put(item); \
00130: `endif \
00131:       end \
00132:  \
00133:       n_insts = this.length; \
00134:    endtask: apply \
00135: endclass \
00136:  \
00137:  \
00138: class `vmm_inject_item_scenario_(class_name) extends `vmm_scenario_(class_name); \
00139:  \
00140:    function new(class_name obj `VMM_DATA_NEW_ARGS); \
00141:       super.new(`VMM_DATA_NEW_CALL); \
00142:  \
00143:       this.items    = new [1]; \
00144:       this.items[0] = obj; \
00145:       this.length   = 1; \
00146:       this.repeated = 0; \
00147:    endfunction: new \
00148:  \
00149:    virtual task apply(channel_name     channel, \
00150:                       ref int unsigned n_insts); \
00151: `ifndef VMM_GRAB_DISABLED \
00152:       channel.put(this.items[0],,this); \
00153: `else \
00154:       channel.put(this.items[0]); \
00155: `endif \
00156:       n_insts = 1; \
00157:    endtask: apply \
00158:  \
00159: endclass \
00160:  \
00161:  \
00162: class `vmm_atomic_scenario_(class_name) extends `vmm_scenario_(class_name); \
00163:  \
00164:    int unsigned ATOMIC; \
00165:  \
00166:    constraint atomic_scenario { \
00167:       if (scenario_kind == ATOMIC) { \
00168:          length == 1; \
00169:          repeated == 0; \
00170:       } \
00171:    } \
00172:  \
00173:    function new(`VMM_DATA_NEW_ARGS); \
00174:       super.new(`VMM_DATA_NEW_CALL); \
00175:  \
00176:       this.ATOMIC = this.define_scenario("Atomic", 1); \
00177:  \
00178:       this.scenario_kind   = this.ATOMIC; \
00179:       this.length = 1; \
00180:    endfunction: new \
00181:  \
00182:    virtual function string psdisplay(string prefix = ""); \
00183:       psdisplay = super.psdisplay(prefix); \
00184:    endfunction:psdisplay \
00185:  \
00186:    function void pre_randomize(); \
00187:       super.pre_randomize(); \
00188:    endfunction \
00189:  \
00190:    virtual task apply(channel_name     channel, \
00191:                       ref int unsigned n_insts); \
00192:       super.apply(channel, n_insts); \
00193:    endtask: apply \
00194:  \
00195: endclass \
00196:  \
00197:  \
00198: class `vmm_scenario_election_(class_name); \
00199:    int stream_id; \
00200:    int scenario_id; \
00201:    int unsigned n_scenarios; \
00202:    int unsigned last_selected[$]; \
00203:    int unsigned next_in_set; \
00204:  \
00205:    `vmm_scenario_(class_name) scenario_set[$]; \
00206:  \
00207:    rand int select; \
00208:  \
00209:    constraint `vmm_scenario_election_valid_(class_name) { \
00210:       select >= 0; \
00211:       select < n_scenarios; \
00212:    } \
00213:  \
00214:    constraint round_robin { \
00215:       select == next_in_set; \
00216:    } \
00217:  \
00218: endclass \
00219:  \
00220: typedef class `vmm_scenario_gen_(class_name); \
00221:  \
00222: class `vmm_scenario_gen_callbacks_(class_name) extends vmm_xactor_callbacks; \
00223:    virtual task pre_scenario_randomize(`vmm_scenario_gen_(class_name) gen, \
00224:                                        ref `vmm_scenario_(class_name) scenario); \
00225:    endtask \
00226:  \
00227:    virtual task post_scenario_gen(`vmm_scenario_gen_(class_name) gen, \
00228:                                   `vmm_scenario_(class_name)     scenario, \
00229:                                   ref bit                        dropped); \
00230:    endtask \
00231: endclass \
00232:  \
00233:  \
00234: class `vmm_scenario_gen_(class_name) extends `VMM_XACTOR; \
00235:  \
00236:    int unsigned stop_after_n_insts; \
00237:    int unsigned stop_after_n_scenarios; \
00238:  \
00239:    typedef enum int {GENERATED, \
00240:                      DONE} symbols_e; \
00241:  \
00242:    `vmm_scenario_election_(class_name) select_scenario; \
00243:  \
00244:    `vmm_scenario_(class_name) scenario_set[$]; \
00245:    protected `vmm_scenario_(class_name) scenario_registry[string]; \
00246:  \
00247:    channel_name out_chan; \
00248:  \
00249:    protected int scenario_count; \
00250:    protected int inst_count; \
00251:  \
00252:    virtual function string psdisplay(string prefix = ""); \
00253:       psdisplay = super.psdisplay(prefix); \
00254:       $sformat(psdisplay, "%s [stops after #insts %0d>%0d or #scenarios %0d>%0d]", \
00255:                psdisplay, this.inst_count, this.stop_after_n_insts, \
00256:                this.scenario_count, this.stop_after_n_scenarios); \
00257:       $sformat(psdisplay, "%s\n%sOutChan: %s(%s) [level=%0d of %0d]", \
00258:                psdisplay, prefix, this.out_chan.log.get_name(), \
00259:                this.out_chan.log.get_instance(), this.out_chan.level(), \
00260:                this.out_chan.full_level()); \
00261:       foreach (this.scenario_registry[name]) begin \
00262:          psdisplay = {psdisplay, "\n", \
00263:                       this.scenario_registry[name].psdisplay(prefix)}; \
00264:       end \
00265:       return psdisplay; \
00266:    endfunction: psdisplay \
00267:  \
00268:    function new(string       inst, \
00269:                 int          stream_id = -1, \
00270:                 channel_name out_chan  = null \
00271:                 `VMM_XACTOR_NEW_ARGS); \
00272:       super.new({text, " Scenario Generator"}, inst, stream_id \
00273:                 `VMM_XACTOR_NEW_CALL); \
00274:  \
00275:       if (out_chan == null) begin \
00276:          out_chan = new({text, " Scenario Generator output channel"}, \
00277:                         inst); \
00278:          `VMM_OBJECT_SET_PARENT(out_chan, this) \
00279:       end \
00280:       this.out_chan = out_chan; \
00281:       this.out_chan.set_producer(this); \
00282:       this.log.is_above(this.out_chan.log); \
00283:  \
00284:       this.scenario_count = 0; \
00285:       this.inst_count = 0; \
00286:       this.stop_after_n_insts     = 0; \
00287:       this.stop_after_n_scenarios = 0; \
00288:  \
00289:       this.select_scenario = new; \
00290:       begin \
00291:          `vmm_atomic_scenario_(class_name) sc = new; \
00292:          `VMM_OBJECT_SET_PARENT(sc, this) \
00293:          this.register_scenario("Atomic", sc); \
00294:       end \
00295:  \
00296:       void'(this.notify.configure(GENERATED)); \
00297:       void'(this.notify.configure(DONE, vmm_notify::ON_OFF)); \
00298:    endfunction: new \
00299:  \
00300:    virtual function void register_scenario(string name, \
00301:                                            `vmm_scenario_(class_name) scenario); \
00302:       if(name == "") begin \
00303:          `vmm_error(this.log, `vmm_sformatf("Invalid '%s' string was passed", name)); \
00304:          return; \
00305:       end \
00306: \
00307:       if(this.scenario_registry.exists(name)) begin \
00308:          `vmm_error(this.log, `vmm_sformatf("%s already has an entry in the scenario registry", name)); \
00309:          return; \
00310:       end \
00311: \
00312:       if(scenario == null) begin \
00313:          `vmm_error(this.log, `vmm_sformatf("scenario passed for %s is a null value", name)); \
00314:          return; \
00315:       end \
00316: \
00317:       this.scenario_registry[name] = scenario; \
00318: \
00319:       foreach(this.scenario_set[i]) begin \
00320:          if(this.scenario_set[i] == scenario) \
00321:             return; \
00322:       end \
00323:       this.scenario_set.push_back(scenario); \
00324:    endfunction: register_scenario \
00325: \
00326:    virtual function bit scenario_exists(string name); \
00327:         if(name == "") begin \
00328:             `vmm_error(this.log, `vmm_sformatf("Invalid '%s' string was passed", name)); \
00329:             return 0; \
00330:         end \
00331: \
00332:         if(this.scenario_registry.exists(name)) \
00333:             scenario_exists = 1; \
00334:         else \
00335:             scenario_exists = 0; \
00336:     endfunction: scenario_exists \
00337: \
00338:    virtual function void replace_scenario(string name, \
00339:                                            `vmm_scenario_(class_name) scenario); \
00340:       if(name == "") begin \
00341:          `vmm_error(this.log, `vmm_sformatf("Invalid '%s' string was passed", name)); \
00342:          return; \
00343:       end \
00344: \
00345:       if(scenario == null) begin \
00346:          `vmm_error(this.log, `vmm_sformatf("scenario passed for %s is a null value", name)); \
00347:          return; \
00348:       end \
00349: \
00350:       if(!this.scenario_registry.exists(name)) begin \
00351:          `vmm_error(this.log, `vmm_sformatf("cannot replace a unregistered %s entry [use register_scenario]", name)); \
00352:          return ; \
00353:       end \
00354: \
00355:       foreach(this.scenario_set[i]) begin \
00356:          if(this.scenario_set[i] == this.scenario_registry[name]) begin \
00357:             this.scenario_set.delete(i); \
00358:             break; \
00359:          end \
00360:       end \
00361:       this.scenario_registry[name] = scenario; \
00362:       foreach(this.scenario_set[i]) begin \
00363:           if(this.scenario_set[i] == scenario) \
00364:               return; \
00365:       end \
00366:       this.scenario_set.push_back(scenario); \
00367:    endfunction: replace_scenario \
00368: \
00369:    virtual function void get_all_scenario_names(ref string name[$]); \
00370:       string s; \
00371: \
00372:       if(this.scenario_registry.first(s)) begin \
00373:          do begin \
00374:             name.push_back(s); \
00375:          end while(this.scenario_registry.next(s)); \
00376:       end \
00377:       if(name.size() == 0) begin \
00378:          `vmm_warning(this.log, "There are no entries in the scenario generator registry"); \
00379:       end \
00380:    endfunction: get_all_scenario_names \
00381: \
00382:    virtual function void get_names_by_scenario(`vmm_scenario_(class_name) scenario, \
00383:                                                ref string name[$]); \
00384:       string s; \
00385: \
00386:       if(scenario == null) begin \
00387:          `vmm_error(this.log, `vmm_sformatf("scenario is a null value")); \
00388:          return; \
00389:       end \
00390: \
00391:       if(this.scenario_registry.first(s)) begin \
00392:          do begin \
00393:             if(this.scenario_registry[s] == scenario) \
00394:                name.push_back(s); \
00395:          end while(this.scenario_registry.next(s)); \
00396:       end \
00397:       if(name.size() == 0) begin \
00398:          `vmm_warning(this.log, "There are no entries in the scenario registry"); \
00399:       end \
00400:    endfunction: get_names_by_scenario \
00401: \
00402:    virtual function string get_scenario_name(`vmm_scenario_(class_name) scenario); \
00403:         string s[$]; \
00404: \
00405:         if(scenario == null) begin \
00406:             `vmm_error(this.log, `vmm_sformatf("scenario is a null value")); \
00407:             return ""; \
00408:         end \
00409: \
00410:         this.get_names_by_scenario(scenario, s); \
00411: \
00412:         if(s.size()) \
00413:             get_scenario_name = s[0]; \
00414:         else \
00415:             get_scenario_name = ""; \
00416:    endfunction: get_scenario_name \
00417: \
00418:    virtual function int get_scenario_index(`vmm_scenario_(class_name) scenario); \
00419:        get_scenario_index = -1; \
00420:        foreach(this.scenario_set[i]) begin \
00421:           if(this.scenario_set[i] == scenario) begin \
00422:              return (get_scenario_index = i); \
00423:           end \
00424:        end \
00425:        if(get_scenario_index == -1) begin \
00426:           `vmm_warning(this.log, `vmm_sformatf("Cannot find the index for the scenario")); \
00427:        end \
00428:    endfunction: get_scenario_index \
00429: \
00430:    virtual function bit unregister_scenario(`vmm_scenario_(class_name) scenario); \
00431:       string s; \
00432:       unregister_scenario=0; \
00433: \
00434:       if(scenario == null) begin \
00435:          `vmm_error(this.log, `vmm_sformatf("scenario is a null value")); \
00436:          return 0; \
00437:       end \
00438:       if(this.scenario_registry.first(s)) begin \
00439:          do begin \
00440:             if(this.scenario_registry[s] == scenario) begin \
00441:                this.scenario_registry.delete(s); \
00442:                unregister_scenario=1; \
00443:             end \
00444:          end while(this.scenario_registry.next(s)); \
00445:       end \
00446:       if(unregister_scenario==0) begin \
00447:          `vmm_warning(this.log, "There are no entries in the scenario registry"); \
00448:       end \
00449:       if(unregister_scenario) begin \
00450:          foreach(this.scenario_set[i]) begin \
00451:             if(this.scenario_set[i] == scenario) begin \
00452:                this.scenario_set.delete(i); \
00453:                break; \
00454:             end \
00455:          end \
00456:       end \
00457:    endfunction: unregister_scenario \
00458: \
00459:    virtual function `vmm_scenario_(class_name) unregister_scenario_by_name(string name); \
00460:       if(name == "") begin \
00461:          `vmm_error(this.log, `vmm_sformatf("Invalid '%s' string was passed", name)); \
00462:          return null; \
00463:       end \
00464:       if(!this.scenario_registry.exists(name)) begin \
00465:          `vmm_warning(this.log, `vmm_sformatf("There is no entry for %s in the scenario registry", name)); \
00466:          return null; \
00467:       end \
00468:       else begin \
00469:          unregister_scenario_by_name = this.scenario_registry[name]; \
00470:          foreach(this.scenario_set[i]) begin \
00471:             if(this.scenario_set[i] == this.scenario_registry[name]) begin \
00472:                this.scenario_set.delete(i); \
00473:                break; \
00474:             end \
00475:          end \
00476:          this.scenario_registry.delete(name); \
00477:       end \
00478:    endfunction: unregister_scenario_by_name \
00479: \
00480:    virtual function `vmm_scenario_(class_name) get_scenario(string name); \
00481:       if(name == "") begin \
00482:          `vmm_error(this.log, `vmm_sformatf("Invalid '%s' string was passed", name)); \
00483:          return null; \
00484:       end \
00485:       if(!this.scenario_registry.exists(name)) begin \
00486:          `vmm_error(this.log, `vmm_sformatf("%s does not have an entry in the scenario registry", name)); \
00487:          return null; \
00488:       end \
00489: \
00490:       get_scenario = this.scenario_registry[name]; \
00491:       if(get_scenario == null) \
00492:          `vmm_warning(this.log, `vmm_sformatf("%s has a null scenario associated with it in the scenario registry", name)); \
00493: \
00494:    endfunction: get_scenario \
00495:  \
00496:    function int unsigned get_n_insts(); \
00497:       get_n_insts = this.inst_count; \
00498:    endfunction: get_n_insts \
00499:  \
00500:    function int unsigned get_n_scenarios(); \
00501:       get_n_scenarios = this.scenario_count; \
00502:    endfunction: get_n_scenarios \
00503:  \
00504:    virtual task inject_obj(class_name obj); \
00505:       `vmm_inject_item_scenario_(class_name) scenario = new(obj); \
00506:       this.inject(scenario); \
00507:    endtask: inject_obj \
00508:  \
00509:    virtual task inject(`vmm_scenario_(class_name) scenario); \
00510:       bit drop = 0; \
00511:  \
00512:       scenario.stream_id   = this.stream_id; \
00513:       scenario.scenario_id = this.scenario_count; \
00514:       foreach (scenario.items[i]) begin \
00515:          scenario.items[i].stream_id   = scenario.stream_id; \
00516:          scenario.items[i].scenario_id = scenario.scenario_id; \
00517:          scenario.items[i].data_id     = i; \
00518:       end \
00519:  \
00520:       `vmm_callback(`vmm_scenario_gen_callbacks_(class_name), \
00521:                     post_scenario_gen(this, scenario, drop)); \
00522:  \
00523:       if (!drop) begin \
00524:          this.scenario_count++; \
00525:          this.notify.indicate(GENERATED, scenario); \
00526:  \
00527:          if (scenario.repeated > scenario.repeat_thresh) begin \
00528:             `vmm_warning(this.log, `vmm_sformatf("A scenario will be repeated %0d times...", \
00529:                                                  scenario.repeated)); \
00530:          end \
00531:          repeat (scenario.repeated + 1) begin \
00532:             int unsigned n_insts = 0; \
00533:             scenario.apply(this.out_chan, n_insts); \
00534:             this.inst_count += n_insts; \
00535:          end \
00536:       end \
00537:    endtask: inject \
00538:  \
00539:    virtual function void reset_xactor(vmm_xactor::reset_e rst_typ = SOFT_RST); \
00540:       super.reset_xactor(rst_typ); \
00541:       this.scenario_count = 0; \
00542:       this.inst_count     = 0; \
00543:       this.out_chan.flush(); \
00544:       `vmm_delQ(this.select_scenario.last_selected); \
00545:  \
00546:       if (rst_typ >= FIRM_RST) begin \
00547:          this.notify.reset( , vmm_notify::HARD); \
00548:       end \
00549:  \
00550:       if (rst_typ >= HARD_RST) begin \
00551:          `vmm_atomic_scenario_(class_name) sc = new; \
00552:          `VMM_OBJECT_SET_PARENT(sc, this) \
00553:  \
00554:          this.stop_after_n_insts     = 0; \
00555:          this.stop_after_n_scenarios = 0; \
00556:          this.select_scenario = new; \
00557:          this.scenario_set.push_back(sc); \
00558:       end \
00559:  \
00560:    endfunction: reset_xactor \
00561:  \
00562:    virtual protected task main(); \
00563:       `vmm_scenario_(class_name) the_scenario; \
00564:  \
00565:       fork \
00566:          super.main(); \
00567:       join_none \
00568:  \
00569:       if(this.scenario_set.size() == 0) \
00570:           return; \
00571:  \
00572:       while ((this.stop_after_n_insts <= 0 \
00573:               || this.inst_count < this.stop_after_n_insts) \
00574:              && (this.stop_after_n_scenarios <= 0 \
00575:                  || this.scenario_count < this.stop_after_n_scenarios)) begin \
00576:  \
00577:          this.wait_if_stopped(); \
00578:  \
00579:          this.select_scenario.stream_id    = this.stream_id; \
00580:          this.select_scenario.scenario_id  = this.scenario_count; \
00581:          this.select_scenario.n_scenarios  = this.scenario_set.size(); \
00582:          this.select_scenario.scenario_set = this.scenario_set; \
00583:          if (this.select_scenario.last_selected.size() == 0) \
00584:             this.select_scenario.next_in_set = 0; \
00585:          else \
00586:             this.select_scenario.next_in_set = ((this.select_scenario.last_selected[$] + 1) % this.scenario_set.size()); \
00587:  \
00588:          if (!this.select_scenario.randomize()) begin \
00589:             `vmm_fatal(this.log, "Cannot select scenario descriptor"); \
00590:             continue; \
00591:          end \
00592:  \
00593:          if (this.select_scenario.select < 0 || \
00594:              this.select_scenario.select >= this.scenario_set.size()) begin \
00595:             `vmm_fatal(this.log, `vmm_sformatf("Select scenario #%0d is not within available set (0-%0d)", \
00596:                                                this.select_scenario.select, \
00597:                                                this.scenario_set.size()-1)); \
00598:             continue; \
00599:          end \
00600:  \
00601:          this.select_scenario.last_selected.push_back(this.select_scenario.select); \
00602:          while (this.select_scenario.last_selected.size() > 10) begin \
00603:             void'(this.select_scenario.last_selected.pop_front()); \
00604:          end \
00605:  \
00606:          the_scenario = this.scenario_set[this.select_scenario.select]; \
00607:          if (the_scenario == null) begin \
00608:             `vmm_fatal(this.log, `vmm_sformatf("Selected scenario #%0d does not exist", \
00609:                                                this.select_scenario.select)); \
00610:             continue; \
00611:          end \
00612:  \
00613:          the_scenario.stream_id   = this.stream_id; \
00614:          the_scenario.scenario_id = this.scenario_count; \
00615:          foreach (the_scenario.items[i]) begin \
00616:             if (the_scenario.items[i] == null) continue; \
00617:  \
00618:             the_scenario.items[i].stream_id   = the_scenario.stream_id; \
00619:             the_scenario.items[i].scenario_id = the_scenario.scenario_id; \
00620:             the_scenario.items[i].data_id     = i; \
00621:          end \
00622:  \
00623:          `vmm_callback(`vmm_scenario_gen_callbacks_(class_name), \
00624:                        pre_scenario_randomize(this, the_scenario)); \
00625:          if (the_scenario == null) continue; \
00626:  \
00627:          if (!the_scenario.randomize()) begin \
00628:             `vmm_fatal(this.log, $psprintf("Cannot randomize scenario descriptor #%0d", \
00629:                                            this.select_scenario.select)); \
00630:             continue; \
00631:          end \
00632:  \
00633:          this.inject(the_scenario); \
00634:       end \
00635:  \
00636:       this.notify.indicate(DONE); \
00637:       this.notify.indicate(XACTOR_STOPPED); \
00638:       this.notify.indicate(XACTOR_IDLE); \
00639:       this.notify.reset(XACTOR_BUSY); \
00640:       this.scenario_count++; \
00641:    endtask: main \
00642:   \
00643: endclass
     :