VMM OpenSource - sv/std_lib/vmm_scenario_gen.sv

sv/std_lib/vmm_scenario_gen.sv expanded 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 `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