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