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 `ifdef VCS2006_06
00023 // Work-around for NYI feature in VCS2006.06
00024 // but IEEE 1800-2009 compliant
00025 `define vmm_delQ(_q) _q.delete()
00026 `else
00027 // Works in VCS2008.03 or later
00028 // IEEE 1800-2005 compliant
00029 `define vmm_delQ(_q) _q = '{}
00030 `endif
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