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