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 void'(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 void'(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 return "No description";
00204 endfunction: describe
00205
00206
00207 function int vmm_sb_ds_stream_iter::length();
00208 return this.str.pkts.size();
00209 endfunction: length
00210
00211
00212 function vmm_data vmm_sb_ds_stream_iter::data();
00213 if (idx >= this.str.pkts.size()) this.is_valid = 0;
00214 return (this.is_valid) ? this.str.pkts[idx] : null;
00215 endfunction: data
00216
00217
00218 function int vmm_sb_ds_stream_iter::pos();
00219 return idx;
00220 endfunction: pos
00221
00222
00223 function bit vmm_sb_ds_stream_iter::find(vmm_data pkt);
00224 foreach (this.str.pkts[i]) begin
00225 if (this.sb.compare(pkt, this.str.pkts[i])) begin
00226 idx = i;
00227 return 1;
00228 end
00229 end
00230
00231 return 0;
00232 endfunction: find
00233
00234
00235 function void vmm_sb_ds_stream_iter::prepend(vmm_data pkt);
00236 if (this.idx >= this.str.pkts.size()) this.is_valid = 0;
00237 if (!this.is_valid) begin
00238 this.str.pkts.push_front(pkt);
00239 this.idx = -1;
00240 return;
00241 end
00242
00243 this.str.pkts.insert(this.idx, pkt);
00244 this.idx++;
00245
00246 this.sb.notify.reset(vmm_sb_ds::EMPTY);
00247 endfunction: prepend
00248
00249
00250 function void vmm_sb_ds_stream_iter::append(vmm_data pkt);
00251 if (this.idx >= this.str.pkts.size()) this.is_valid = 0;
00252 if (!this.is_valid) begin
00253 this.str.pkts.push_back(pkt);
00254 this.idx = -1;
00255 return;
00256 end
00257
00258 if (this.idx == this.str.pkts.size()-1) begin
00259 this.str.pkts.push_back(pkt);
00260 return;
00261 end
00262 this.str.pkts.insert(this.idx+1, pkt);
00263
00264 this.sb.notify.reset(vmm_sb_ds::EMPTY);
00265 endfunction: append
00266
00267
00268 function vmm_data vmm_sb_ds_stream_iter::delete();
00269 vmm_data pkt;
00270
00271 if (this.idx >= this.str.pkts.size()) this.is_valid = 0;
00272 if (!this.is_valid) begin
00273 this.idx = -1;
00274 return null;
00275 end
00276
00277 pkt = this.str.pkts[this.idx];
00278 this.str.pkts.delete(this.idx);
00279
00280 if (this.str.pkts.size() == 0) begin
00281 // The entire scoreboard might be empty!
00282 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY);
00283 end
00284
00285 return pkt;
00286 endfunction: delete
00287
00288
00289 function int vmm_sb_ds_stream_iter::flush();
00290 int n = this.str.pkts.size();
00291
00292 `ifdef VCS2006_06
00293 // Work-around for NYI feature in VCS2006.06
00294 // but IEEE 1800-2009 compliant
00295 this.str.pkts.delete();
00296 `else
00297 // Works in VCS2008.03 or later
00298 // IEEE 1800-2005 compliant
00299 this.str.pkts = '{};
00300 `endif
00301
00302 // The entire scoreboard might be empty!
00303 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY);
00304
00305 return n;
00306 endfunction: flush
00307
00308
00309 function int vmm_sb_ds_stream_iter::preflush();
00310 int n = 0;
00311
00312 if (this.idx >= this.str.pkts.size()) this.is_valid = 0;
00313 if (!this.is_valid) begin
00314 this.idx = -1;
00315 return -1;
00316 end
00317
00318 n = this.idx;
00319 if (n > 0) begin
00320 this.str.pkts = this.str.pkts[this.idx:$];
00321 this.idx = 0;
00322 end
00323
00324 if (this.str.pkts.size() == 0) begin
00325 // The entire scoreboard might be empty!
00326 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY);
00327 end
00328
00329 return n;
00330 endfunction: preflush
00331
00332
00333 function int vmm_sb_ds_stream_iter::postflush();
00334 int n = 0;
00335
00336 if (this.idx >= this.str.pkts.size()) this.is_valid = 0;
00337 if (!this.is_valid) begin
00338 this.idx = -1;
00339 return -1;
00340 end
00341
00342 n = (this.str.pkts.size()-1) - this.idx;
00343 if (n > 0) begin
00344 this.str.pkts = this.str.pkts[0:this.idx];
00345 end
00346
00347 if (this.str.pkts.size() == 0) begin
00348 // The entire scoreboard might be empty!
00349 if (this.sb.get_n_pending() == 0) this.sb.notify.indicate(vmm_sb_ds::EMPTY);
00350 end
00351
00352 return n;
00353 endfunction: postflush
00354
00355
00356 function vmm_sb_ds_stream_iter vmm_sb_ds_stream_iter::copy();
00357
00358 vmm_sb_ds_stream_iter iter = new(this.sb, this.str,
00359 this.exp_id, this.inp_id);
00360
00361 iter.idx = this.idx;
00362 iter.is_valid = this.is_valid;
00363
00364 return iter;
00365 endfunction: copy