VMM OpenSource - sv/sb/vmm_sb_ds_stream_iter.sv

sv/sb/vmm_sb_ds_stream_iter.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 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