VMM OpenSource - sv/std_lib/vmm_atomic_gen.sv

sv/std_lib/vmm_atomic_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 
00023 `define vmm_atomic_gen_(class)           class``_atomic_gen
00024 `define vmm_atomic_gen_callbacks_(class) class``_atomic_gen_callbacks
00025 
00026 
00027 `define vmm_atomic_gen(class_name, text) \
00028 `vmm_atomic_gen_using(class_name, class_name``_channel, text)
00029 
00030 `define vmm_atomic_gen_using(class_name, channel_name, text) \
00031  \
00032 typedef class `vmm_atomic_gen_(class_name); \
00033 class `vmm_atomic_gen_callbacks_(class_name) extends vmm_xactor_callbacks; \
00034    virtual task post_inst_gen(`vmm_atomic_gen_(class_name) gen, \
00035                               class_name                   obj, \
00036                               ref bit                      drop); \
00037    endtask \
00038 endclass \
00039  \
00040  \
00041 class `vmm_atomic_gen_(class_name) extends `VMM_XACTOR; \
00042  \
00043    int unsigned stop_after_n_insts; \
00044  \
00045    typedef enum int {GENERATED, \
00046                      DONE} symbols_e; \
00047  \
00048  \
00049    class_name randomized_obj; \
00050  \
00051    channel_name out_chan; \
00052  \
00053    local int scenario_count; \
00054    local int obj_count; \
00055  \
00056    virtual function string psdisplay(string prefix = ""); \
00057       psdisplay = super.psdisplay(prefix); \
00058       $sformat(psdisplay, "%s [stops after #insts %0d>%0d]", \
00059                psdisplay, this.obj_count, this.stop_after_n_insts); \
00060       $sformat(psdisplay, "%s\n%sOutChan: %s(%s) [level=%0d of %0d]", \
00061                psdisplay, prefix, this.out_chan.log.get_name(), \
00062                this.out_chan.log.get_instance(), this.out_chan.level(), \
00063                this.out_chan.full_level()); \
00064       if (this.randomized_obj != null) begin \
00065          prefix = {prefix, "Factory: "}; \
00066          psdisplay = {psdisplay, "\n", \
00067                       this.randomized_obj.psdisplay(prefix)}; \
00068       end \
00069       return psdisplay; \
00070    endfunction: psdisplay \
00071  \
00072    function new(string       inst, \
00073                 int          stream_id = -1, \
00074                 channel_name out_chan  = null `VMM_XACTOR_NEW_ARGS); \
00075       super.new({text, " Atomic Generator"}, inst, stream_id `VMM_XACTOR_NEW_CALL); \
00076  \
00077       if (out_chan == null) begin \
00078          out_chan = new({text, " Atomic Generator output channel"}, \
00079                          inst); \
00080          `VMM_OBJECT_SET_PARENT(out_chan, this) \
00081       end \
00082       this.out_chan = out_chan; \
00083       this.out_chan.set_producer(this); \
00084       this.log.is_above(this.out_chan.log); \
00085  \
00086       this.scenario_count = 0; \
00087       this.obj_count = 0; \
00088       this.stop_after_n_insts = 0; \
00089  \
00090       void'(this.notify.configure(GENERATED, vmm_notify::ONE_SHOT)); \
00091       void'(this.notify.configure(DONE, vmm_notify::ON_OFF)); \
00092  \
00093       this.randomized_obj = new; \
00094       `VMM_OBJECT_SET_PARENT(this.randomized_obj, this) \
00095    endfunction: new \
00096  \
00097    virtual task inject(class_name obj, \
00098                        ref bit    dropped); \
00099       dropped = 0; \
00100  \
00101       `vmm_callback(`vmm_atomic_gen_callbacks_(class_name), \
00102                     post_inst_gen(this, obj, dropped)); \
00103  \
00104       if (!dropped) begin \
00105          this.obj_count++; \
00106          this.notify.indicate(GENERATED, obj); \
00107          this.out_chan.put(obj); \
00108       end \
00109    endtask: inject \
00110  \
00111    virtual function void reset_xactor(vmm_xactor::reset_e rst_typ = SOFT_RST); \
00112       super.reset_xactor(rst_typ); \
00113  \
00114       this.out_chan.flush(); \
00115       this.scenario_count = 0; \
00116       this.obj_count = 0; \
00117  \
00118       if (rst_typ >= FIRM_RST) begin \
00119          this.notify.reset( , vmm_notify::HARD); \
00120       end \
00121  \
00122       if (rst_typ >= HARD_RST) begin \
00123          this.stop_after_n_insts = 0; \
00124          this.randomized_obj     = new; \
00125       end \
00126    endfunction: reset_xactor \
00127  \
00128    virtual protected task main(); \
00129       bit dropped; \
00130  \
00131       fork \
00132          super.main(); \
00133       join_none \
00134  \
00135       while (this.stop_after_n_insts <= 0 || \
00136              this.obj_count < this.stop_after_n_insts) begin \
00137  \
00138          this.wait_if_stopped(); \
00139  \
00140          this.randomized_obj.stream_id   = this.stream_id; \
00141          this.randomized_obj.scenario_id = this.scenario_count; \
00142          this.randomized_obj.data_id     = this.obj_count; \
00143  \
00144          if (!this.randomized_obj.randomize()) begin \
00145             `vmm_fatal(this.log, "Cannot randomize atomic instance"); \
00146             continue; \
00147          end \
00148  \
00149          begin \
00150             class_name obj; \
00151  \
00152             $cast(obj, this.randomized_obj.copy()); \
00153             `VMM_OBJECT_SET_PARENT(obj, this) \
00154             this.inject(obj, dropped); \
00155          end \
00156       end \
00157  \
00158       this.notify.indicate(DONE); \
00159       this.notify.indicate(XACTOR_STOPPED); \
00160       this.notify.indicate(XACTOR_IDLE); \
00161       this.notify.reset(XACTOR_BUSY); \
00162       this.scenario_count++; \
00163    endtask: main \
00164  \
00165 endclass