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 class vmm_sb_ds_stream_iter; 00024 00025 local vmm_sb_ds sb; 00026 local int exp_id; 00027 local int inp_id; 00028 00029 local vmm_sb_ds_pkt_stream str; 00030 local int idx; 00031 00032 local bit is_valid; 00033 00034 extern /*local*/ function new(vmm_sb_ds sb, 00035 vmm_sb_ds_pkt_stream str, 00036 int exp_id, 00037 int inp_id); 00038 00039 00040 extern function bit first(); 00041 extern function bit is_ok(); 00042 extern function bit next(); 00043 extern function bit last(); 00044 extern function bit prev(); 00045 00046 extern function int inp_stream_id(); 00047 extern function int exp_stream_id(); 00048 extern function string describe(); 00049 extern function int length(); 00050 00051 extern function vmm_data data(); 00052 extern function int pos(); 00053 extern function bit find(vmm_data pkt); 00054 extern function void prepend(vmm_data pkt); 00055 extern function void append(vmm_data pkt); 00056 00057 extern function vmm_data delete(); 00058 extern function int flush(); 00059 extern function int preflush(); 00060 extern function int postflush(); 00061 00062 extern function vmm_sb_ds_stream_iter copy(); 00063 00064 endclass: vmm_sb_ds_stream_iter 00065 00066 00067 function vmm_sb_ds_stream_iter::new(vmm_sb_ds sb, 00068 vmm_sb_ds_pkt_stream str, 00069 int exp_id, 00070 int inp_id); 00071 if (str == null) begin 00072 vmm_sb_ds_exp_streams exp_strs = null; 00073 00074 if (exp_id < 0) begin 00075 if (sb.Xexp_streamsX.num() != 0) begin 00076 `vmm_error(sb.log, "Cannot create stream iterator on unspecified expected stream: More than one stream exists"); 00077 str = null; 00078 end 00079 else begin 00080 sb.Xexp_streamsX.first(exp_id); 00081 exp_strs = sb.Xexp_streamsX[exp_id]; 00082 end 00083 end 00084 else begin 00085 if (!sb.Xexp_streamsX.exists(exp_id)) begin 00086 `vmm_error(sb.log, $psprintf("Cannot create stream iterator on expected stream #%0d: Stream does not exist", exp_id)); 00087 str = null; 00088 end 00089 else begin 00090 exp_strs = sb.Xexp_streamsX[exp_id]; 00091 end 00092 end 00093 00094 if (inp_id < 0 && exp_strs != null) begin 00095 if (exp_strs.pkt_streams.num() != 0) begin 00096 `vmm_error(sb.log, "Cannot create stream iterator on unspecified input stream: More than one stream exists"); 00097 str = null; 00098 end 00099 else begin 00100 exp_strs.pkt_streams.first(inp_id); 00101 str = exp_strs.pkt_streams[inp_id]; 00102 end 00103 end 00104 else begin 00105 if (!exp_strs.pkt_streams.exists(inp_id)) begin 00106 `vmm_error(sb.log, $psprintf("Cannot create stream iterator on input stream #%0d: Stream does not exist", inp_id)); 00107 str = null; 00108 end 00109 else begin 00110 str = exp_strs.pkt_streams[inp_id]; 00111 end 00112 end 00113 end 00114 00115 this.sb = sb; 00116 this.str = str; 00117 this.exp_id = exp_id; 00118 this.inp_id = inp_id; 00119 this.idx = -1; 00120 this.is_valid = 0; 00121 endfunction: new 00122 00123 00124 function bit vmm_sb_ds_stream_iter::first(); 00125 this.is_valid = 0; 00126 return this.next(); 00127 endfunction: first 00128 00129 function bit vmm_sb_ds_stream_iter::is_ok(); 00130 return is_valid ; 00131 endfunction: is_ok 00132 00133 00134 function bit vmm_sb_ds_stream_iter::next(); 00135 if (str.pkts.size() == 0) begin 00136 this.idx = -1; 00137 this.is_valid = 0; 00138 return 0; 00139 end 00140 00141 if (!this.is_valid) begin 00142 this.idx = 0; 00143 this.is_valid = 1; 00144 return 1; 00145 end 00146 00147 idx++; 00148 00149 if (idx < this.str.pkts.size()) begin 00150 return 1; 00151 end 00152 00153 this.idx = -1; 00154 this.is_valid = 0; 00155 00156 return 0; 00157 endfunction: next 00158 00159 00160 function bit vmm_sb_ds_stream_iter::last(); 00161 this.is_valid = 0; 00162 return this.prev(); 00163 endfunction: last 00164 00165 00166 function bit vmm_sb_ds_stream_iter::prev(); 00167 if (str.pkts.size() == 0) begin 00168 this.idx = -1; 00169 this.is_valid = 0; 00170 return 0; 00171 end 00172 00173 if (!this.is_valid) begin 00174 this.idx = this.str.pkts.size() - 1; 00175 this.is_valid = 1; 00176 return 1; 00177 end 00178 00179 idx--; 00180 00181 if (idx >= 0) begin 00182 return 1; 00183 end 00184 00185 this.idx = -1; 00186 this.is_valid = 0; 00187 00188 return 0; 00189 endfunction: prev 00190 00191 00192 function int vmm_sb_ds_stream_iter::inp_stream_id(); 00193 return this.inp_id; 00194 endfunction: inp_stream_id 00195 00196 00197 function int vmm_sb_ds_stream_iter::exp_stream_id(); 00198 return this.exp_id; 00199 endfunction: exp_stream_id 00200 00201 00202 function string vmm_sb_ds_stream_iter::describe(); 00203 endfunction: describe 00204 00205 00206 function int vmm_sb_ds_stream_iter::length(); 00207 return this.str.pkts.size(); 00208 endfunction: length 00209 00210 00211 function vmm_data vmm_sb_ds_stream_iter::data(); 00212 if (idx >= this.str.pkts.size()) this.is_valid = 0; 00213 return (this.is_valid) ? this.str.pkts[idx] : null; 00214 endfunction: data 00215 00216 00217 function int vmm_sb_ds_stream_iter::pos(); 00218 return idx; 00219 endfunction: pos 00220 00221 00222 function bit vmm_sb_ds_stream_iter::find(vmm_data pkt); 00223 foreach (this.str.pkts[i]) begin 00224 if (this.sb.compare(pkt, this.str.pkts[i])) begin 00225 idx = i; 00226 return 1; 00227 end 00228 end 00229 00230 return 0; 00231 endfunction: find 00232 00233 00234 function void vmm_sb_ds_stream_iter::prepend(vmm_data pkt); 00235 if (this.idx >= this.str.pkts.size()) this.is_valid = 0; 00236 if (!this.is_valid) begin 00237 this.str.pkts.push_front(pkt); 00238 this.idx = -1; 00239 return; 00240 end 00241 00242 this.str.pkts.insert(this.idx, pkt); 00243 this.idx++; 00244 00245 this.sb.notify.reset(vmm_sb_ds::EMPTY); 00246 endfunction: prepend 00247 00248 00249 function void vmm_sb_ds_stream_iter::append(vmm_data pkt); 00250 if (this.idx >= this.str.pkts.size()) this.is_valid = 0; 00251 if (!this.is_valid) begin 00252 this.str.pkts.push_back(pkt); 00253 this.idx = -1; 00254 return; 00255 end 00256 00257 if (this.idx == this.str.pkts.size()-1) begin 00258 this.str.pkts.push_back(pkt); 00259 return; 00260 end 00261 this.str.pkts.insert(this.idx+1, pkt); 00262 00263 this.sb.notify.reset(vmm_sb_ds::EMPTY); 00264 endfunction: append 00265 00266 00267 function vmm_data vmm_sb_ds_stream_iter::delete(); 00268 vmm_data pkt; 00269 00270 if (this.idx >= this.str.pkts.size()) this.is_valid = 0; 00271 if (!this.is_valid) begin 00272 this.idx = -1; 00273 return null; 00274 end 00275 00276 pkt = this.str.pkts[this.idx]; 00277 this.str.pkts.delete(this.idx); 00278 00279 if (this.str.pkts.size() == 0) begin 00280 // The entire scoreboard might be empty! 00281 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY); 00282 end 00283 00284 return pkt; 00285 endfunction: delete 00286 00287 00288 function int vmm_sb_ds_stream_iter::flush(); 00289 int n = this.str.pkts.size(); 00290 00291 `ifdef VCS2006_06 00292 // Work-around for NYI feature in VCS2006.06 00293 // *NOT* IEEE compliant :-( 00294 this.str.pkts.delete(); 00295 `else 00296 // Works in VCS2008.03 00297 this.str.pkts = '{}; 00298 `endif 00299 00300 // The entire scoreboard might be empty! 00301 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY); 00302 00303 return n; 00304 endfunction: flush 00305 00306 00307 function int vmm_sb_ds_stream_iter::preflush(); 00308 int n = 0; 00309 00310 if (this.idx >= this.str.pkts.size()) this.is_valid = 0; 00311 if (!this.is_valid) begin 00312 this.idx = -1; 00313 return -1; 00314 end 00315 00316 n = this.idx; 00317 if (n > 0) begin 00318 this.str.pkts = this.str.pkts[this.idx:$]; 00319 this.idx = 0; 00320 end 00321 00322 if (this.str.pkts.size() == 0) begin 00323 // The entire scoreboard might be empty! 00324 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY); 00325 end 00326 00327 return n; 00328 endfunction: preflush 00329 00330 00331 function int vmm_sb_ds_stream_iter::postflush(); 00332 int n = 0; 00333 00334 if (this.idx >= this.str.pkts.size()) this.is_valid = 0; 00335 if (!this.is_valid) begin 00336 this.idx = -1; 00337 return -1; 00338 end 00339 00340 n = (this.str.pkts.size()-1) - this.idx; 00341 if (n > 0) begin 00342 this.str.pkts = this.str.pkts[0:this.idx]; 00343 end 00344 00345 if (this.str.pkts.size() == 0) begin 00346 // The entire scoreboard might be empty! 00347 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY); 00348 end 00349 00350 return n; 00351 endfunction: postflush 00352 00353 00354 function vmm_sb_ds_stream_iter vmm_sb_ds_stream_iter::copy(); 00355 00356 vmm_sb_ds_stream_iter iter = new(this.sb, this.str, 00357 this.exp_id, this.inp_id); 00358 00359 iter.idx = this.idx; 00360 iter.is_valid = this.is_valid; 00361 00362 return iter; 00363 endfunction: copy