Expanded versions of source files are the output of the preprocessor. Lines subject to
conditional compilation are not shown and all compiler pragmas have been stripped. Macros
have been completely expanded.
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:
00024: `define VMM_SB_DS_SV
00025:
00026: typedef class vmm_sb_ds_iter;
00027: typedef class vmm_sb_ds_stream_iter;
00028:
00029:
00030: //
00031: // The packet queues, one for each inp->exp stream pair
00032: //
00033: // (Undocumented)
00034: //
00035: class vmm_sb_ds_pkt_stream;
00036: vmm_data pkts[$];
00037:
00038: int n_inserted = 0;
00039: int n_matched = 0;
00040: int n_mismatched = 0;
00041: int n_dropped = 0;
00042: int n_not_found = 0;
00043: endclass
00044:
00045:
00046: //
00047: // Packet queues for one expected stream, one per input stream
00048: //
00049: // (Undocumented)
00050: //
00051: class vmm_sb_ds_exp_streams;
00052: vmm_sb_ds_pkt_stream pkt_streams[int];
00053: endclass
00054:
00055:
00056: //
00057: // Top-Level Data-stream scoreboard class
00058: //
00059: typedef class vmm_sb_ds_callbacks;
00060: class vmm_sb_ds;
00061:
00062: /*local*/ vmm_sb_ds_exp_streams Xexp_streamsX[int];
00063: /*local*/ string Xinp_stream_descsX[int];
00064: /*local*/ string Xexp_stream_descsX[int];
00065: /*local*/ bit Xdefine_stream_calledX = 0;
00066: /*local*/ bit Xparallel_streamsX = 0;
00067:
00068: local int n_not_found = 0;
00069: local bit orphaned = 0;
00070: local int n_orphaned = 0;
00071: local bit insert_recursed = 0;
00072:
00073: local vmm_sb_ds_callbacks callbacks[$];
00074:
00075: vmm_log log;
00076: vmm_notify notify;
00077:
00078: typedef enum {EITHER, INPUT, EXPECT} kind_e;
00079:
00080: typedef enum {INSERTED = 999_000, EMPTY, MATCHED, MISMATCHED,
00081: DROPPED, NOT_FOUND, ORPHANED} notifications_e;
00082:
00083: extern function new(string name);
00084:
00085: extern virtual function int stream_id(vmm_data pkt,
00086: vmm_sb_ds::kind_e kind = EITHER);
00087:
00088: extern function void define_stream(int stream_id,
00089: string descr = "",
00090: vmm_sb_ds::kind_e kind = EITHER);
00091:
00092: extern virtual function bit insert(vmm_data pkt,
00093: vmm_sb_ds::kind_e kind = INPUT,
00094: int exp_stream_id = -1,
00095: int inp_stream_id = -1);
00096: extern virtual function bit remove(vmm_data pkt,
00097: vmm_sb_ds::kind_e kind = INPUT,
00098: int exp_stream_id = -1,
00099: int inp_stream_id = -1);
00100:
00101: extern virtual function bit transform(input vmm_data in_pkt,
00102: output vmm_data out_pkts[]);
00103:
00104: extern virtual function bit match(vmm_data actual,
00105: vmm_data expected);
00106: extern virtual function bit quick_compare(vmm_data actual,
00107: vmm_data expected);
00108: extern virtual function bit compare(vmm_data actual,
00109: vmm_data expected);
00110:
00111:
00112: typedef enum {IN_ORDER, WITH_LOSSES, OUT_ORDER} ordering_e;
00113:
00114: extern virtual function vmm_data expect_in_order(vmm_data pkt,
00115: int exp_stream_id = -1,
00116: int inp_stream_id = -1,
00117: bit silent = 0);
00118: extern virtual function bit expect_with_losses(input vmm_data pkt,
00119: output vmm_data matched,
00120: output vmm_data lost[],
00121: input int exp_stream_id = -1,
00122: input int inp_stream_id = -1,
00123: input bit silent = 0);
00124: extern virtual function vmm_data expect_out_of_order(vmm_data pkt,
00125: int exp_stream_id = -1,
00126: int inp_stream_id = -1,
00127: bit silent = 0);
00128:
00129: extern virtual function void flush();
00130:
00131: extern function vmm_sb_ds_iter new_sb_iter(int exp_stream_id = -1,
00132: int inp_stream_id = -1);
00133: extern function vmm_sb_ds_stream_iter new_stream_iter(int exp_stream_id = -1,
00134: int inp_stream_id = -1);
00135:
00136: extern function void prepend_callback(vmm_sb_ds_callbacks cb);
00137: extern function void append_callback(vmm_sb_ds_callbacks cb);
00138: extern function void unregister_callback(vmm_sb_ds_callbacks cb);
00139:
00140: extern function int get_n_inserted(int exp_stream_id = -1,
00141: int inp_stream_id = -1);
00142: extern function int get_n_pending(int exp_stream_id = -1,
00143: int inp_stream_id = -1);
00144: extern function int get_n_matched(int exp_stream_id = -1,
00145: int inp_stream_id = -1);
00146: extern function int get_n_mismatched(int exp_stream_id = -1,
00147: int inp_stream_id = -1);
00148: extern function int get_n_dropped(int exp_stream_id = -1,
00149: int inp_stream_id = -1);
00150: extern function int get_n_not_found(int exp_stream_id = -1,
00151: int inp_stream_id = -1);
00152: extern function int get_n_orphaned(int exp_stream_id = -1,
00153: int inp_stream_id = -1);
00154:
00155: extern virtual function void report(int exp_stream_id = -1,
00156: int inp_stream_id = -1);
00157: extern virtual function void describe();
00158: extern virtual function void display(string prefix = "");
00159:
00160: endclass
00161:
00162:
00163: //
00164: // Callback facade class
00165: //
00166: class vmm_sb_ds_callbacks;
00167:
00168: virtual function void pre_insert(input vmm_sb_ds sb,
00169: input vmm_data pkt,
00170: input vmm_sb_ds::kind_e kind,
00171: ref int exp_stream_id,
00172: ref int inp_stream_id,
00173: ref bit drop);
00174: endfunction: pre_insert
00175:
00176: virtual function void post_insert(vmm_sb_ds sb,
00177: vmm_data pkt,
00178: int exp_stream_id,
00179: int inp_stream_id);
00180: endfunction: post_insert
00181:
00182: virtual function void matched(input vmm_sb_ds sb,
00183: input vmm_data pkt,
00184: input int exp_stream_id,
00185: input int inp_stream_id,
00186: ref int count);
00187: endfunction: matched
00188:
00189: virtual function void mismatched(input vmm_sb_ds sb,
00190: input vmm_data pkt,
00191: input int exp_stream_id,
00192: input int inp_stream_id,
00193: ref int count);
00194: endfunction: mismatched
00195:
00196: virtual function void dropped(input vmm_sb_ds sb,
00197: input vmm_data pkts[],
00198: input int exp_stream_id,
00199: input int inp_stream_id,
00200: ref int count);
00201: endfunction: dropped
00202:
00203: virtual function void not_found(input vmm_sb_ds sb,
00204: input vmm_data pkt,
00205: input int exp_stream_id,
00206: input int inp_stream_id,
00207: ref int count);
00208: endfunction: not_found
00209:
00210: virtual function void orphaned(input vmm_sb_ds sb,
00211: input vmm_data pkts[],
00212: input int exp_stream_id,
00213: input int inp_stream_id,
00214: ref int count);
00215: endfunction: orphaned
00216:
00217: endclass
00218:
00219:
00220: //
00221: // Status descriptor for notifications
00222: //
00223: class vmm_sb_ds_pkts extends vmm_data;
00224: vmm_data pkts[];
00225: vmm_sb_ds::kind_e kind;
00226: int inp_stream_id;
00227: int exp_stream_id;
00228:
00229: /*local*/ function new(vmm_data pkt,
00230: vmm_sb_ds::kind_e kind,
00231: int exp_stream_id,
00232: int inp_stream_id);
00233: super.new(null);
00234:
00235: if (pkt != null) begin
00236: this.pkts = new [1];
00237: this.pkts[0] = pkt;
00238: end
00239: this.kind = kind;
00240: this.inp_stream_id = inp_stream_id;
00241: this.exp_stream_id = exp_stream_id;
00242: endfunction
00243: endclass
00244:
00245:
00246: //
00247: // Scoreboard iterator
00248: //
00249: class vmm_sb_ds_iter;
00250:
00251: local vmm_sb_ds sb;
00252: local int exp_str_id;
00253: local int inp_str_id;
00254:
00255: local int exp_str_idx;
00256: local vmm_sb_ds_exp_streams exp_str;
00257: local int pkt_str_idx;
00258: local vmm_sb_ds_pkt_stream pkt_str;
00259:
00260: local bit is_valid;
00261:
00262: vmm_sb_ds_stream_iter stream_iter;
00263:
00264: /*local*/ extern function new(vmm_sb_ds sb,
00265: int exp_stream_id,
00266: int inp_stream_id);
00267:
00268: extern function bit first();
00269: extern function bit is_ok();
00270: extern function bit next();
00271: extern function bit last();
00272: extern function bit prev();
00273: extern function int length();
00274: extern function int pos();
00275:
00276: extern function int inp_stream_id();
00277: extern function int exp_stream_id();
00278: extern function string describe();
00279:
00280: extern function int get_n_inserted();
00281: extern function int get_n_pending();
00282: extern function int get_n_matched();
00283: extern function int get_n_mismatched();
00284: extern function int get_n_dropped();
00285: extern function int get_n_not_found();
00286: extern function int get_n_orphaned();
00287:
00288: extern function int incr_n_inserted(int delta);
00289: extern function int incr_n_pending(int delta);
00290: extern function int incr_n_matched(int delta);
00291: extern function int incr_n_mismatched(int delta);
00292: extern function int incr_n_dropped(int delta);
00293: extern function int incr_n_not_found(int delta);
00294: extern function int incr_n_orphaned(int delta);
00295:
00296: extern function vmm_sb_ds_iter copy();
00297: extern function vmm_sb_ds_stream_iter new_stream_iter();
00298:
00299: extern function int delete();
00300:
00301: extern function void display(string prefix = "");
00302:
00303: /*local*/ extern function vmm_sb_ds_pkt_stream Xget_pkt_streamX();
00304:
00305: extern local function bit next_exp_str();
00306: extern local function bit next_pkt_str();
00307: extern local function bit prev_exp_str();
00308: extern local function bit prev_pkt_str();
00309: endclass: vmm_sb_ds_iter
00310:
00311:
00312: function vmm_sb_ds::new(string name);
00313: this.log = new("Data Stream Scoreboard", name);
00314: this.notify = new(this.log);
00315:
00316: void'(this.notify.configure(INSERTED, vmm_notify::ONE_SHOT));
00317: void'(this.notify.configure(EMPTY, vmm_notify::ON_OFF));
00318: void'(this.notify.configure(MATCHED, vmm_notify::ONE_SHOT));
00319: void'(this.notify.configure(MISMATCHED, vmm_notify::ONE_SHOT));
00320: void'(this.notify.configure(DROPPED, vmm_notify::ONE_SHOT));
00321: void'(this.notify.configure(NOT_FOUND, vmm_notify::ONE_SHOT));
00322: void'(this.notify.configure(ORPHANED, vmm_notify::ONE_SHOT));
00323:
00324: this.notify.indicate(EMPTY);
00325:
00326: begin
00327: vmm_opts opts = new;
00328: if (opts.get_bit("sb_trace", "VMM Scoreboard trace ON")) begin
00329: this.log.set_verbosity(vmm_log::TRACE_SEV);
00330: end
00331: if (opts.get_bit("sb_debug", "VMM Scoreboard debug ON")) begin
00332: this.log.set_verbosity(vmm_log::DEBUG_SEV);
00333: end
00334: end
00335: endfunction: new
00336:
00337:
00338: function int vmm_sb_ds::stream_id(vmm_data pkt,
00339: vmm_sb_ds::kind_e kind = EITHER);
00340: return 0;
00341: endfunction: stream_id
00342:
00343:
00344: function void vmm_sb_ds::define_stream(int stream_id,
00345: string descr = "",
00346: vmm_sb_ds::kind_e kind = EITHER);
00347: if (stream_id < 0) begin
00348:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::define_stream called with negative stream_id"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00349: return;
00350: end
00351:
00352: case (kind)
00353: EITHER: begin
00354: if (this.Xdefine_stream_calledX && !this.Xparallel_streamsX) begin
00355:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::define_stream: Attempting to define a mix of EITHER and INPUT/EXPECT streams"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00356: end
00357: else begin
00358: this.Xinp_stream_descsX[stream_id] = descr;
00359: this.Xexp_stream_descsX[stream_id] = descr;
00360: this.Xparallel_streamsX = 1;
00361: end
00362: end
00363:
00364: INPUT: begin
00365: if (this.Xdefine_stream_calledX && this.Xparallel_streamsX) begin
00366:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::define_stream: Attempting to define a mix of EITHER and INPUT/EXPECT streams"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00367: end
00368: else begin
00369: this.Xinp_stream_descsX[stream_id] = descr;
00370: end
00371: end
00372:
00373: EXPECT: begin
00374: if (this.Xdefine_stream_calledX && this.Xparallel_streamsX) begin
00375:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::define_stream: Attempting to define a mix of EITHER and INPUT/EXPECT streams"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00376: end
00377: else begin
00378: this.Xexp_stream_descsX[stream_id] = descr;
00379: end
00380: end
00381: endcase
00382:
00383: this.Xdefine_stream_calledX = 1;
00384:
00385: endfunction: define_stream
00386:
00387:
00388: function bit vmm_sb_ds::insert(vmm_data pkt,
00389: vmm_sb_ds::kind_e kind = INPUT,
00390: int exp_stream_id = -1,
00391: int inp_stream_id = -1);
00392: vmm_sb_ds_exp_streams exp_streams;
00393: vmm_sb_ds_pkt_stream pkt_stream;
00394: bit drop;
00395:
00396: if (kind == EITHER) begin
00397:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::insert called with EITHER packet kind"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00398: return 0;
00399: end
00400:
00401: drop = 0;
00402:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.pre_insert(this, pkt, kind,
: exp_stream_id, inp_stream_id, drop);
: end while (0);
00405: if (drop) return 1;
00406:
00407: if (inp_stream_id < 0) begin
00408: inp_stream_id = this.stream_id(pkt, INPUT);
00409: end
00410: if (this.Xdefine_stream_calledX) begin
00411: if (!Xinp_stream_descsX.exists(inp_stream_id)) begin
00412:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::insert called with undefined input stream #%0d",
: inp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00414: return 0;
00415: end
00416: end
00417:
00418: if (kind == INPUT) begin
00419: vmm_data out_pkts[];
00420:
00421:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Inserting INPUT packet in stream #%0d",
: inp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00423:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00424:
00425: void'(this.transform(pkt, out_pkts));
00426: this.insert_recursed = 1;
00427: foreach (out_pkts[i]) begin
00428: void'(this.insert(out_pkts[i], EXPECT, exp_stream_id, inp_stream_id));
00429: end
00430: this.insert_recursed = 0;
00431:
00432: begin
00433: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id);
00434: status.pkts = new [out_pkts.size()] (out_pkts);
00435: this.notify.indicate(INSERTED, status);
00436: end
00437:
00438: return 1;
00439: end
00440:
00441: // Must be an EXPECT packet
00442: if (exp_stream_id < 0) begin
00443: exp_stream_id = this.stream_id(pkt, EXPECT);
00444: end
00445:
00446: if (this.Xdefine_stream_calledX) begin
00447: if (!Xexp_stream_descsX.exists(exp_stream_id)) begin
00448:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::insert called with undefined expected stream #%0d",
: exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00450: return 0;
00451: end
00452: end
00453:
00454:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Inserting EXPECT packet in stream #%0d->#%0d",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00456:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00457:
00458: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin
00459: exp_streams = new();
00460: this.Xexp_streamsX[exp_stream_id] = exp_streams;
00461: end
00462: else
00463: exp_streams = this.Xexp_streamsX[exp_stream_id];
00464:
00465: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin
00466: pkt_stream = new();
00467: exp_streams.pkt_streams[inp_stream_id] = pkt_stream;
00468: end
00469: else
00470: pkt_stream = exp_streams.pkt_streams[inp_stream_id];
00471:
00472: pkt_stream.pkts.push_back(pkt);
00473: this.notify.reset(EMPTY);
00474:
00475: pkt_stream.n_inserted++;
00476: if (!this.insert_recursed) begin
00477: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00478: this.notify.indicate(INSERTED, status);
00479: end
00480:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.post_insert(this, pkt, exp_stream_id, inp_stream_id);
: end while (0);
00482:
00483: return 1;
00484: endfunction: insert
00485:
00486:
00487: function bit vmm_sb_ds::remove(vmm_data pkt,
00488: vmm_sb_ds::kind_e kind = INPUT,
00489: int exp_stream_id = -1,
00490: int inp_stream_id = -1);
00491:
00492: vmm_sb_ds_exp_streams exp_streams;
00493: vmm_sb_ds_pkt_stream pkt_stream;
00494:
00495: if (kind == EITHER) begin
00496:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::remove called with EITHER packet kind"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00497: return 0;
00498: end
00499:
00500: if (inp_stream_id < 0) begin
00501: inp_stream_id = this.stream_id(pkt, INPUT);
00502: end
00503: if (this.Xdefine_stream_calledX) begin
00504: if (!Xinp_stream_descsX.exists(inp_stream_id)) begin
00505:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::remove called with undefined input stream #%0d",
: inp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00507: return 0;
00508: end
00509: end
00510:
00511: if (kind == INPUT) begin
00512: vmm_data out_pkts[];
00513: bit rc = 1;
00514:
00515:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Deleting INPUT packet from stream #%0d",
: inp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00517:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00518:
00519: void'(this.transform(pkt, out_pkts));
00520: foreach (out_pkts[i]) begin
00521: rc |= this.remove(out_pkts[i], EXPECT, inp_stream_id, exp_stream_id);
00522: end
00523:
00524: return rc;
00525: end
00526:
00527: // Must be an EXPECT packet
00528: if (exp_stream_id < 0) begin
00529: exp_stream_id = this.stream_id(pkt, EXPECT);
00530: end
00531:
00532: if (this.Xdefine_stream_calledX) begin
00533: if (!Xexp_stream_descsX.exists(exp_stream_id)) begin
00534:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::remove called with undefined expected stream #%0d",
: exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00536: return 0;
00537: end
00538: end
00539:
00540:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Deleting EXPECT packet from stream #%0d->#%0d",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00542:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00543:
00544: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin
00545:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::remove: Cannot find packet to remove: expected stream #%0d does not exist",
: exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00547: return 0;
00548: end
00549: exp_streams = this.Xexp_streamsX[exp_stream_id];
00550:
00551: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin
00552:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("vmm_sb_ds::remove: Cannot find packet to remove: stream #%0d->#%0d does not exist.",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00554: return 0;
00555: end
00556: pkt_stream = exp_streams.pkt_streams[inp_stream_id];
00557:
00558: foreach (pkt_stream.pkts[i]) begin
00559: if (this.compare(pkt, pkt_stream.pkts[i])) begin
00560: pkt_stream.pkts.delete(i);
00561: if (pkt_stream.pkts.size() == 0) begin
00562: // The entire scoreboard might be empty!
00563: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY);
00564: end
00565: return 1;
00566: end
00567: end
00568:
00569:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("vmm_sb_ds::remove: Cannot find packet to remove"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00570:
00571: return 0;
00572: endfunction: remove
00573:
00574:
00575: function bit vmm_sb_ds::transform(input vmm_data in_pkt,
00576: output vmm_data out_pkts[]);
00577: out_pkts = new [1];
00578: out_pkts[0] = in_pkt;
00579:
00580: return 1;
00581: endfunction: transform
00582:
00583:
00584: function bit vmm_sb_ds::match(vmm_data actual,
00585: vmm_data expected);
00586: return this.quick_compare(actual, expected);
00587: endfunction: match
00588:
00589:
00590: function bit vmm_sb_ds::quick_compare(vmm_data actual,
00591: vmm_data expected);
00592: return 1;
00593: endfunction: quick_compare
00594:
00595:
00596: function bit vmm_sb_ds::compare(vmm_data actual,
00597: vmm_data expected);
00598:
00599: string diff;
00600: if (this.quick_compare(actual, expected)) begin
00601: return actual.compare(expected, diff);
00602: end
00603:
00604: endfunction: compare
00605:
00606:
00607: function vmm_data vmm_sb_ds::expect_in_order(vmm_data pkt,
00608: int exp_stream_id = -1,
00609: int inp_stream_id = -1,
00610: bit silent = 0);
00611:
00612: vmm_sb_ds_exp_streams exp_streams;
00613: vmm_sb_ds_pkt_stream pkt_stream;
00614:
00615: if (exp_stream_id < 0) begin
00616: exp_stream_id = this.stream_id(pkt, EXPECT);
00617: end
00618: if (inp_stream_id < 0) begin
00619: inp_stream_id = this.stream_id(pkt, INPUT);
00620: end
00621:
00622:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Expecting in-order packet on stream #%0d->#%0d",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00624:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00625:
00626: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin
00627: // Not found because the output stream does not exist!
00628: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00629: int n = 1;
00630:
00631: this.notify.indicate(NOT_FOUND, status);
00632:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00634:
00635: if (!silent) begin
00636: this.n_not_found += n;
00637:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("In-order packet was not found: EXPECT stream #%0d does not exist.", exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00638: end
00639: return null;
00640: end
00641: exp_streams = this.Xexp_streamsX[exp_stream_id];
00642:
00643: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin
00644: // Not found because the input stream does not exist!
00645: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00646: int n = 1;
00647:
00648: this.notify.indicate(NOT_FOUND, status);
00649:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00651:
00652: if (!silent) begin
00653: this.n_not_found += n;
00654:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("In-order packet was not found: stream #%0d->#%0d does not exist.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00655: end
00656: return null;
00657: end
00658: pkt_stream = exp_streams.pkt_streams[inp_stream_id];
00659:
00660: if (pkt_stream.pkts.size() == 0) begin
00661: // Not found because the packet stream is empty!
00662: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00663: int n = 1;
00664:
00665: this.notify.indicate(NOT_FOUND, status);
00666:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00668:
00669: if (!silent) begin
00670: pkt_stream.n_not_found += n;
00671:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("In-order packet was not found: stream %0d->%0d is empty.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00672: end
00673: return null;
00674: end
00675:
00676: if (!this.compare(pkt, pkt_stream.pkts[0])) begin
00677: // Not found because the packet does not match
00678: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00679: int n = 1;
00680:
00681: this.notify.indicate(NOT_FOUND, status);
00682:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00684:
00685: if (!silent) begin
00686: pkt_stream.n_not_found += n;
00687:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("In-order packet was not expected:\n%s\n%s.", pkt.psdisplay(" Actual: "), pkt_stream.pkts[0].psdisplay(" Expect: "))));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00688: end
00689:
00690: // Remove the packet
00691: void'(pkt_stream.pkts.pop_front());
00692: if (pkt_stream.pkts.size() == 0) begin
00693: // The entire scoreboard might be empty!
00694: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY);
00695: end
00696:
00697: return null;
00698: end
00699:
00700: // Found!
00701: begin
00702: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00703: int n = 1;
00704:
00705: this.notify.indicate(MATCHED, status);
00706:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.matched(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00708: if (!silent) pkt_stream.n_matched += n;
00709: end
00710:
00711: pkt = pkt_stream.pkts.pop_front();
00712: if (pkt_stream.pkts.size() == 0) begin
00713: // The entire scoreboard might be empty!
00714: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY);
00715: end
00716:
00717: return pkt;
00718:
00719: endfunction: expect_in_order
00720:
00721:
00722: function bit vmm_sb_ds::expect_with_losses(input vmm_data pkt,
00723: output vmm_data matched,
00724: output vmm_data lost[],
00725: input int exp_stream_id = -1,
00726: input int inp_stream_id = -1,
00727: input bit silent = 0);
00728:
00729: vmm_sb_ds_exp_streams exp_streams;
00730: vmm_sb_ds_pkt_stream pkt_stream;
00731: int match_idx;
00732:
00733: matched = null;
00734: lost = new [0];
00735:
00736: if (inp_stream_id < 0) begin
00737: inp_stream_id = this.stream_id(pkt, INPUT);
00738: end
00739: if (exp_stream_id < 0) begin
00740: exp_stream_id = this.stream_id(pkt, EXPECT);
00741: end
00742:
00743:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Looking for packet on stream #%0d->#%0d",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00745:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00746:
00747: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin
00748: // Not found because the output stream does not exist!
00749: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00750: int n = 1;
00751:
00752: this.notify.indicate(NOT_FOUND, status);
00753:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00755:
00756: if (!silent) begin
00757: this.n_not_found += n;
00758:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("With-loss packet was not found: EXPECT stream #%0d does not exist.", exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00759: end
00760: return 0;
00761: end
00762: exp_streams = this.Xexp_streamsX[exp_stream_id];
00763:
00764: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin
00765: // Not found because the input stream does not exist!
00766: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00767: int n = 1;
00768:
00769: this.notify.indicate(NOT_FOUND, status);
00770:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00772:
00773: if (!silent) begin
00774: this.n_not_found += n;
00775:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("With-loss packet was not found: Stream #%0d->%0d does not exist.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00776: end
00777: return 0;
00778: end
00779: pkt_stream = exp_streams.pkt_streams[inp_stream_id];
00780:
00781: if (pkt_stream.pkts.size() == 0) begin
00782: // Not found because the packet stream is empty!
00783: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00784: int n = 1;
00785:
00786: this.notify.indicate(NOT_FOUND, status);
00787:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00789:
00790: if (!silent) begin
00791: pkt_stream.n_not_found += n;
00792:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("With-loss packet was not found: Stream #%0d->%0d is empty.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00793: end
00794: return 0;
00795: end
00796:
00797: foreach (pkt_stream.pkts[i]) begin
00798: if (this.match(pkt, pkt_stream.pkts[i])) begin
00799: // We have a match!
00800: matched = pkt_stream.pkts[i];
00801: match_idx = i;
00802: break;
00803: end
00804: end
00805: if (matched == null) begin
00806: // Not found because no packet matched
00807: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00808: int n = 1;
00809:
00810: this.notify.indicate(NOT_FOUND, status);
00811:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00813:
00814: if (!silent) begin
00815: this.n_not_found += n;
00816:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text({"With-loss packet was not matched:\n",
: pkt.psdisplay(" ")}));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00818: end
00819: return 0;
00820: end
00821:
00822:
00823: // Everything between the matching packet and the head
00824: // of the packet stream is assumed to have been lost
00825: if (match_idx > 0) begin
00826: lost = new [match_idx];
00827: foreach (lost[i]) begin
00828: lost[i] = pkt_stream.pkts[i];
00829: end
00830:
00831: begin
00832: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id);
00833: int n = lost.size();
00834:
00835: status.pkts = new [lost.size()] (lost);
00836: this.notify.indicate(DROPPED, status);
00837:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.dropped(this, status.pkts, exp_stream_id, inp_stream_id, n);
: end while (0);
00839: if (!silent) pkt_stream.n_dropped += n;
00840: end
00841: end
00842: repeat (match_idx + 1) void'(pkt_stream.pkts.pop_front());
00843: if (pkt_stream.pkts.size() == 0) begin
00844: // The entire scoreboard might be empty!
00845: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY);
00846: end
00847:
00848: if (!this.compare(pkt, matched)) begin
00849: // Mis-match!
00850:
00851:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV, "", -1)) begin
: void'(this.log.text($psprintf("packet mismatched expected packet in stream #%0d->#%0d\n%s\n%s",
: inp_stream_id, exp_stream_id,
: pkt.psdisplay(" Actual:"),
: matched.psdisplay(" Msmtch:"))));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00855:
00856: begin
00857: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id);
00858: int n = 1;
00859:
00860: status.pkts = new [2];
00861: status.pkts[0] = pkt;
00862: status.pkts[1] = matched;
00863:
00864: this.notify.indicate(MISMATCHED, status);
00865:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.mismatched(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00867: if (!silent) pkt_stream.n_mismatched += n;
00868: end
00869:
00870: if (!silent) begin
00871:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("With-loss packet was not found")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00872: end
00873: return 0;
00874: end
00875:
00876: begin
00877: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00878: int n = 1;
00879:
00880: this.notify.indicate(MATCHED, status);
00881:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.matched(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00883: if (!silent) pkt_stream.n_matched += n;
00884: end
00885:
00886: return 1;
00887: endfunction: expect_with_losses
00888:
00889:
00890: function vmm_data vmm_sb_ds::expect_out_of_order(vmm_data pkt,
00891: int exp_stream_id = -1,
00892: int inp_stream_id = -1,
00893: bit silent = 0);
00894: vmm_sb_ds_exp_streams exp_streams;
00895: vmm_sb_ds_pkt_stream pkt_stream;
00896: int match_idx;
00897:
00898: if (inp_stream_id < 0) begin
00899: inp_stream_id = this.stream_id(pkt, INPUT);
00900: end
00901: if (exp_stream_id < 0) begin
00902: exp_stream_id = this.stream_id(pkt, EXPECT);
00903: end
00904:
00905:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Looking for out-of-order packet on stream #%0d->#%0d",
: inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00907:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV, "", -1)) begin
: void'(this.log.text(pkt.psdisplay(" ")));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00908:
00909: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin
00910: // Not found because the output stream does not exist!
00911: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00912: int n = 1;
00913:
00914: this.notify.indicate(NOT_FOUND, status);
00915:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00917:
00918: if (!silent) begin
00919: this.n_not_found += n;
00920:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Out-of-order packet was not found: EXPECT stream #%0d does not exist.", exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00921: end
00922: return null;
00923: end
00924: exp_streams = this.Xexp_streamsX[exp_stream_id];
00925:
00926: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin
00927: // Not found because the input stream does not exist!
00928: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00929: int n = 1;
00930:
00931: this.notify.indicate(NOT_FOUND, status);
00932:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00934:
00935: if (!silent) begin
00936: this.n_not_found += n;
00937:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Out-of-order packet was not found: stream %0d->%0d does not exist.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00938: end
00939: return null;
00940: end
00941: pkt_stream = exp_streams.pkt_streams[inp_stream_id];
00942:
00943: if (pkt_stream.pkts.size() == 0) begin
00944: // Not found because the packet stream is empty!
00945: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00946: int n = 1;
00947:
00948: this.notify.indicate(NOT_FOUND, status);
00949:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00951:
00952: if (!silent) begin
00953: pkt_stream.n_not_found += n;
00954:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text($psprintf("Out-of-order packet was not found: stream %0d->%0d is empty.", inp_stream_id, exp_stream_id)));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00955: end
00956: return null;
00957: end
00958:
00959: foreach (pkt_stream.pkts[i]) begin
00960: if (this.compare(pkt, pkt_stream.pkts[i])) begin
00961: // We have a match!
00962: begin
00963: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00964: int n = 1;
00965:
00966: this.notify.indicate(MATCHED, status);
00967:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.matched(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00969: if (!silent) pkt_stream.n_matched += n;
00970: end
00971:
00972: pkt = pkt_stream.pkts[i];
00973: pkt_stream.pkts.delete(i);
00974: if (pkt_stream.pkts.size() == 0) begin
00975: // The entire scoreboard might be empty!
00976: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY);
00977: end
00978: return pkt;
00979: end
00980: end
00981:
00982: begin
00983: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id);
00984: int n = 1;
00985:
00986: this.notify.indicate(NOT_FOUND, status);
00987:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.not_found(this, pkt, exp_stream_id, inp_stream_id, n);
: end while (0);
00989: if (!silent) pkt_stream.n_not_found += n;
00990: end
00991:
00992: if (!silent) begin
00993:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Out-of-order packet was not found"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00994: end
00995: return null;
00996: endfunction: expect_out_of_order
00997:
00998:
00999: function void vmm_sb_ds::flush();
01000: this.Xinp_stream_descsX.delete();
01001: this.Xexp_stream_descsX.delete();
01002: this.Xexp_streamsX.delete();
01003: this.Xdefine_stream_calledX = 0;
01004:
01005: this.n_not_found = 0;
01006: this.orphaned = 0;
01007: this.insert_recursed = 0;
01008:
01009: this.notify.indicate(EMPTY);
01010: endfunction: flush
01011:
01012:
01013: function vmm_sb_ds_iter vmm_sb_ds::new_sb_iter(int exp_stream_id = -1,
01014: int inp_stream_id = -1);
01015:
01016: vmm_sb_ds_iter iter = new(this, exp_stream_id, inp_stream_id);
01017:
01018: return iter;
01019: endfunction: new_sb_iter
01020:
01021: function vmm_sb_ds_stream_iter vmm_sb_ds::new_stream_iter(int exp_stream_id = -1,
01022: int inp_stream_id = -1);
01023:
01024: vmm_sb_ds_stream_iter iter = new(this, null, exp_stream_id, inp_stream_id);
01025: return iter;
01026: endfunction: new_stream_iter
01027:
01028:
01029: function void vmm_sb_ds::prepend_callback(vmm_sb_ds_callbacks cb);
01030: if (cb == null) begin
01031:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Attempting to prepend a NULL callback extension"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01032: return;
01033: end
01034:
01035: foreach(this.callbacks[i]) begin
01036: if (this.callbacks[i] == cb) begin
01037:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text("Callback has already been registered"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01038: return;
01039: end
01040: end
01041: //Prepend new callback
01042: this.callbacks.push_front(cb);
01043: endfunction: prepend_callback
01044:
01045:
01046: function void vmm_sb_ds::append_callback(vmm_sb_ds_callbacks cb);
01047: if (cb == null) begin
01048:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Attempting to append a NULL callback extension"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
01049: return;
01050: end
01051:
01052: foreach(this.callbacks[i]) begin
01053: if (this.callbacks[i] == cb) begin
01054:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text("Callback has already been registered"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01055: return;
01056: end
01057: end
01058: //Append new callback
01059: this.callbacks.push_back(cb);
01060: endfunction: append_callback
01061:
01062:
01063: function void vmm_sb_ds::unregister_callback(vmm_sb_ds_callbacks cb);
01064: foreach(this.callbacks[i]) begin
01065: if (this.callbacks[i] == cb) begin
01066: // Unregister it
01067: this.callbacks.delete(i);
01068: return;
01069: end
01070: end
01071:
01072:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text("Callback was not registered"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while(0);
01073: endfunction: unregister_callback
01074:
01075:
01076: function int vmm_sb_ds::get_n_inserted(int exp_stream_id = -1,
01077: int inp_stream_id = -1);
01078: int n = 0;
01079:
01080: vmm_sb_ds_iter iter;
01081: iter = new (this, exp_stream_id, inp_stream_id);
01082: while (iter.next()) begin
01083: vmm_sb_ds_pkt_stream pkt_str;
01084: pkt_str = iter.Xget_pkt_streamX();
01085: n += pkt_str.n_inserted;
01086: end
01087:
01088: return n;
01089: endfunction: get_n_inserted
01090:
01091:
01092: function int vmm_sb_ds::get_n_pending(int exp_stream_id = -1,
01093: int inp_stream_id = -1);
01094: int n = 0;
01095:
01096: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01097: while (iter.next()) begin
01098: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX();
01099: n += pkt_str.pkts.size();
01100: end
01101:
01102: return n;
01103: endfunction: get_n_pending
01104:
01105:
01106: function int vmm_sb_ds::get_n_matched(int exp_stream_id = -1,
01107: int inp_stream_id = -1);
01108: int n = 0;
01109:
01110: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01111: while (iter.next()) begin
01112: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX();
01113: n += pkt_str.n_matched;
01114: end
01115:
01116: return n;
01117: endfunction: get_n_matched
01118:
01119:
01120: function int vmm_sb_ds::get_n_mismatched(int exp_stream_id = -1,
01121: int inp_stream_id = -1);
01122: int n = 0;
01123:
01124: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01125: while (iter.next()) begin
01126: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX();
01127: n += pkt_str.n_mismatched;
01128: end
01129:
01130: return n;
01131: endfunction: get_n_mismatched
01132:
01133:
01134: function int vmm_sb_ds::get_n_dropped(int exp_stream_id = -1,
01135: int inp_stream_id = -1);
01136: int n = 0;
01137:
01138: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01139: while (iter.next()) begin
01140: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX();
01141: n += pkt_str.n_dropped;
01142: end
01143:
01144: return n;
01145: endfunction: get_n_dropped
01146:
01147:
01148: function int vmm_sb_ds::get_n_not_found(int exp_stream_id = -1,
01149: int inp_stream_id = -1);
01150: int n = 0;
01151:
01152:
01153: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01154:
01155: while (iter.next()) begin
01156: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX();
01157: n += pkt_str.n_not_found;
01158: end
01159:
01160: if (exp_stream_id < 0 || inp_stream_id < 0) n += this.n_not_found;
01161:
01162: return n;
01163: endfunction: get_n_not_found
01164:
01165:
01166: function int vmm_sb_ds::get_n_orphaned(int exp_stream_id = -1,
01167: int inp_stream_id = -1);
01168:
01169: if (!this.orphaned) begin
01170: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01171: vmm_data pkts[$];
01172: while (iter.next()) begin
01173: vmm_sb_ds_pkt_stream pkt_stream = iter.Xget_pkt_streamX();
01174:
01175: // Not yet supported in SP1
01176: // pkts = '{pkts, pkt_stream.pkts};
01177: foreach (pkt_stream.pkts[i]) pkts.push_back(pkt_stream.pkts[i]);
01178: end
01179:
01180: if (pkts.size() > 0) begin
01181: vmm_sb_ds_pkts status = new(null, EXPECT, -1, -1);
01182: int n = pkts.size();
01183:
01184: status.pkts = new [pkts.size()];
01185: foreach (pkts[i]) status.pkts[i] = pkts[i];
01186: this.notify.indicate(ORPHANED, status);
01187:
:
: do foreach (this.callbacks[vmm_i]) begin
: vmm_sb_ds_callbacks cb;
: if (!$cast(cb, this.callbacks[vmm_i])) continue;
:
: cb.orphaned(this, status.pkts,
: exp_stream_id, inp_stream_id, n);
: end while (0);
01190: this.n_orphaned = n;
01191: end
01192:
01193: this.orphaned = 1;
01194: end
01195:
01196: return this.n_orphaned;
01197: endfunction: get_n_orphaned
01198:
01199:
01200: function void vmm_sb_ds::report(int exp_stream_id = -1,
01201: int inp_stream_id = -1);
01202: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id);
01203:
01204: string s = this.log.get_instance();
01205: if (s.len() < 30) s = {s, {(30 - s.len()){" "}}};
01206: else if (s.len() > 30) s = s.substr(0, 29);
01207:
01208: $write("+--------------------------------+------+------+------+------+------+------+\n");
01209: $write("| %s |%s|%s|%s|%s|%s|%s|\n", s,
01210: "Insert", "Matchd", "MsMtch", "Droppd", "NotFnd", "Orphan");
01211: $write("+--------------------------------+------+------+------+------+------+------+\n");
01212:
01213: while (iter.next()) begin
01214: s = iter.describe();
01215: if (s.len() < 30) s = {s, {(30 - s.len()){" "}}};
01216: else if (s.len() > 30) s = s.substr(0, 29);
01217: $write("| %s | %04d | %04d | %04d | %04d | %04d | %04d |\n", s,
01218: iter.get_n_inserted(), iter.get_n_matched(),
01219: iter.get_n_mismatched(), iter.get_n_dropped(),
01220: iter.get_n_not_found(), iter.get_n_orphaned());
01221: end
01222: $write("+--------------------------------+------+------+------+------+------+------+\n");
01223: $write("| TOTAL | %04d | %04d | %04d | %04d | %04d | %04d |\n",
01224: this.get_n_inserted(exp_stream_id, inp_stream_id),
01225: this.get_n_matched(exp_stream_id, inp_stream_id),
01226: this.get_n_mismatched(exp_stream_id, inp_stream_id),
01227: this.get_n_dropped(exp_stream_id, inp_stream_id),
01228: this.get_n_not_found(exp_stream_id, inp_stream_id),
01229: this.get_n_orphaned(exp_stream_id, inp_stream_id));
01230: $write("+--------------------------------+------+------+------+------+------+------+\n\n");
01231: endfunction: report
01232:
01233:
01234: function void vmm_sb_ds::describe();
01235: vmm_sb_ds_iter iter = this.new_sb_iter();
01236:
01237: $write("Streams in Data Stream Scoreboard \"%s\":\n",
01238: this.log.get_instance());
01239:
01240: while (iter.next()) begin
01241: $write(" %s\n", iter.describe());
01242: end
01243: endfunction: describe
01244:
01245:
01246: function void vmm_sb_ds::display(string prefix = "");
01247: $write("%sContent of Data Stream Scoreboard \"%s\":\n", prefix,
01248: this.log.get_instance());
01249:
01250: if (this.Xparallel_streamsX) begin
01251: foreach (this.Xexp_streamsX[k]) begin
01252: vmm_sb_ds_exp_streams exp_str = this.Xexp_streamsX[k];
01253: vmm_sb_ds_pkt_stream pkt_str = exp_str.pkt_streams[k];
01254:
01255: if (pkt_str == null) continue;
01256:
01257: $write("%s Stream #%0d", prefix, k);
01258: if (this.Xexp_stream_descsX.exists(k)) begin
01259: $write(" (%s)", this.Xexp_stream_descsX[k]);
01260: end
01261: $write(":\n");
01262:
01263: foreach (pkt_str.pkts[i]) begin
01264: pkt_str.pkts[i].display({prefix, " "});
01265: end
01266: end
01267:
01268: return;
01269: end
01270:
01271: foreach (this.Xexp_streamsX[k]) begin
01272: vmm_sb_ds_exp_streams exp_str = this.Xexp_streamsX[k];
01273:
01274: $write("%s To stream #%0d", prefix, k);
01275: if (this.Xexp_stream_descsX.exists(k)) begin
01276: $write(" (%s)", this.Xexp_stream_descsX[k]);
01277: end
01278: $write(":\n");
01279: foreach (exp_str.pkt_streams[j]) begin
01280: vmm_sb_ds_pkt_stream pkt_str = exp_str.pkt_streams[j];
01281:
01282: $write("%s From stream #%0d", prefix, j);
01283: if (this.Xinp_stream_descsX.exists(j)) begin
01284: $write(" (%s)", this.Xinp_stream_descsX[j]);
01285: end
01286: $write(":\n");
01287: foreach (pkt_str.pkts[i]) begin
01288: pkt_str.pkts[i].display({prefix, " "});
01289: end
01290: end
01291: end
01292: endfunction: display
01293:
01294: