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.
sb/vmm_sb_ds.sv unexpanded 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: 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[*]; 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[*]; 00063: /*local*/ string Xinp_stream_descsX[*]; 00064: /*local*/ string Xexp_stream_descsX[*]; 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: this.notify.configure(INSERTED, vmm_notify::ONE_SHOT); 00317: this.notify.configure(EMPTY, vmm_notify::ON_OFF); 00318: this.notify.configure(MATCHED, vmm_notify::ONE_SHOT); 00319: this.notify.configure(MISMATCHED, vmm_notify::ONE_SHOT); 00320: this.notify.configure(DROPPED, vmm_notify::ONE_SHOT); 00321: this.notify.configure(NOT_FOUND, vmm_notify::ONE_SHOT); 00322: this.notify.configure(ORPHANED, vmm_notify::ONE_SHOT); 00323: 00324: this.notify.indicate(EMPTY); 00325: endfunction: new 00326: 00327: 00328: function int vmm_sb_ds::stream_id(vmm_data pkt, 00329: vmm_sb_ds::kind_e kind); 00330: return 0; 00331: endfunction: stream_id 00332: 00333: 00334: function void vmm_sb_ds::define_stream(int stream_id, 00335: string descr, 00336: vmm_sb_ds::kind_e kind); 00337: if (stream_id < 0) begin 00338: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("vmm_sb_ds::define_stream() called with negative stream_id")); : this.log.end_msg(); : end : while (0); 00339: return; 00340: end 00341: 00342: case (kind) 00343: EITHER: begin 00344: if (this.Xdefine_stream_calledX && !this.Xparallel_streamsX) begin 00345: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00346: end 00347: else begin 00348: this.Xinp_stream_descsX[stream_id] = descr; 00349: this.Xexp_stream_descsX[stream_id] = descr; 00350: this.Xparallel_streamsX = 1; 00351: end 00352: end 00353: 00354: INPUT: begin 00355: if (this.Xdefine_stream_calledX && this.Xparallel_streamsX) begin 00356: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00357: end 00358: else begin 00359: this.Xinp_stream_descsX[stream_id] = descr; 00360: end 00361: end 00362: 00363: EXPECT: begin 00364: if (this.Xdefine_stream_calledX && this.Xparallel_streamsX) begin 00365: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00366: end 00367: else begin 00368: this.Xexp_stream_descsX[stream_id] = descr; 00369: end 00370: end 00371: endcase 00372: 00373: this.Xdefine_stream_calledX = 1; 00374: 00375: endfunction: define_stream 00376: 00377: 00378: function bit vmm_sb_ds::insert(vmm_data pkt, 00379: vmm_sb_ds::kind_e kind, 00380: int exp_stream_id, 00381: int inp_stream_id); 00382: vmm_sb_ds_exp_streams exp_streams; 00383: vmm_sb_ds_pkt_stream pkt_stream; 00384: bit drop; 00385: 00386: if (kind == EITHER) begin 00387: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("vmm_sb_ds::insert() called with EITHER packet kind")); : this.log.end_msg(); : end : while (0); 00388: return 0; 00389: end 00390: 00391: drop = 0; 00394: : : 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); 00395: if (drop) return 1; 00396: 00397: if (inp_stream_id < 0) begin 00398: inp_stream_id = this.stream_id(pkt, INPUT); 00399: end 00400: if (this.Xdefine_stream_calledX) begin 00401: if (!Xinp_stream_descsX.exists(inp_stream_id)) begin 00403: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("vmm_sb_ds::insert() called with undefined input stream #%0d", : inp_stream_id))); : this.log.end_msg(); : end : while (0); 00404: return 0; 00405: end 00406: end 00407: 00408: if (kind == INPUT) begin 00409: vmm_data out_pkts[]; 00410: 00412: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV)) begin : void'(this.log.text($psprintf("Inserting INPUT packet in stream #%0d", : inp_stream_id))); : this.log.end_msg(); : end : while (0); 00413: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00414: 00415: this.transform(pkt, out_pkts); 00416: this.insert_recursed = 1; 00417: foreach (out_pkts[i]) begin 00418: this.insert(out_pkts[i], EXPECT, exp_stream_id, inp_stream_id); 00419: end 00420: this.insert_recursed = 0; 00421: 00422: begin 00423: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id); 00424: status.pkts = new [out_pkts.size()] (out_pkts); 00425: this.notify.indicate(INSERTED, status); 00426: end 00427: 00428: return 1; 00429: end 00430: 00431: // Must be an EXPECT packet 00432: if (exp_stream_id < 0) begin 00433: exp_stream_id = this.stream_id(pkt, EXPECT); 00434: end 00435: 00436: if (this.Xdefine_stream_calledX) begin 00437: if (!Xexp_stream_descsX.exists(exp_stream_id)) begin 00439: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("vmm_sb_ds::insert() called with undefined expected stream #%0d", : exp_stream_id))); : this.log.end_msg(); : end : while (0); 00440: return 0; 00441: end 00442: end 00443: 00445: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV)) begin : void'(this.log.text($psprintf("Inserting EXPECT packet in stream #%0d->#%0d", : inp_stream_id, exp_stream_id))); : this.log.end_msg(); : end : while (0); 00446: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00447: 00448: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin 00449: exp_streams = new(); 00450: this.Xexp_streamsX[exp_stream_id] = exp_streams; 00451: end 00452: else 00453: exp_streams = this.Xexp_streamsX[exp_stream_id]; 00454: 00455: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin 00456: pkt_stream = new(); 00457: exp_streams.pkt_streams[inp_stream_id] = pkt_stream; 00458: end 00459: else 00460: pkt_stream = exp_streams.pkt_streams[inp_stream_id]; 00461: 00462: pkt_stream.pkts.push_back(pkt); 00463: this.notify.reset(EMPTY); 00464: 00465: pkt_stream.n_inserted++; 00466: if (!this.insert_recursed) begin 00467: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00468: this.notify.indicate(INSERTED, status); 00469: end 00471: : : 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); 00472: 00473: return 1; 00474: endfunction: insert 00475: 00476: 00477: function bit vmm_sb_ds::remove(vmm_data pkt, 00478: vmm_sb_ds::kind_e kind, 00479: int exp_stream_id, 00480: int inp_stream_id); 00481: 00482: vmm_sb_ds_exp_streams exp_streams; 00483: vmm_sb_ds_pkt_stream pkt_stream; 00484: 00485: if (kind == EITHER) begin 00486: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("vmm_sb_ds::remove() called with EITHER packet kind")); : this.log.end_msg(); : end : while (0); 00487: return 0; 00488: end 00489: 00490: if (inp_stream_id < 0) begin 00491: inp_stream_id = this.stream_id(pkt, INPUT); 00492: end 00493: if (this.Xdefine_stream_calledX) begin 00494: if (!Xinp_stream_descsX.exists(inp_stream_id)) begin 00496: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("vmm_sb_ds::remove() called with undefined input stream #%0d", : inp_stream_id))); : this.log.end_msg(); : end : while (0); 00497: return 0; 00498: end 00499: end 00500: 00501: if (kind == INPUT) begin 00502: vmm_data out_pkts[]; 00503: bit rc = 1; 00504: 00506: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Deleting INPUT packet from stream #%0d", : inp_stream_id))); : this.log.end_msg(); : end : while (0); 00507: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00508: 00509: this.transform(pkt, out_pkts); 00510: foreach (out_pkts[i]) begin 00511: rc |= this.remove(out_pkts[i], EXPECT, inp_stream_id, exp_stream_id); 00512: end 00513: 00514: return rc; 00515: end 00516: 00517: // Must be an EXPECT packet 00518: if (exp_stream_id < 0) begin 00519: exp_stream_id = this.stream_id(pkt, EXPECT); 00520: end 00521: 00522: if (this.Xdefine_stream_calledX) begin 00523: if (!Xexp_stream_descsX.exists(exp_stream_id)) begin 00525: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("vmm_sb_ds::remove() called with undefined expected stream #%0d", : exp_stream_id))); : this.log.end_msg(); : end : while (0); 00526: return 0; 00527: end 00528: end 00529: 00531: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) begin : void'(this.log.text($psprintf("Deleting EXPECT packet from stream #%0d->#%0d", : inp_stream_id, exp_stream_id))); : this.log.end_msg(); : end : while (0); 00532: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00533: 00534: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin 00536: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00537: return 0; 00538: end 00539: exp_streams = this.Xexp_streamsX[exp_stream_id]; 00540: 00541: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin 00543: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00544: return 0; 00545: end 00546: pkt_stream = exp_streams.pkt_streams[inp_stream_id]; 00547: 00548: foreach (pkt_stream.pkts[i]) begin 00549: if (this.compare(pkt, pkt_stream.pkts[i])) begin 00550: pkt_stream.pkts.delete(i); 00551: if (pkt_stream.pkts.size() == 0) begin 00552: // The entire scoreboard might be empty! 00553: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY); 00554: end 00555: return 1; 00556: end 00557: end 00558: 00559: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("vmm_sb_ds::remove(): Cannot find packet to remove")); : this.log.end_msg(); : end : while (0); 00560: 00561: return 0; 00562: endfunction: remove 00563: 00564: 00565: function bit vmm_sb_ds::transform(input vmm_data in_pkt, 00566: output vmm_data out_pkts[]); 00567: out_pkts = new [1]; 00568: out_pkts[0] = in_pkt; 00569: 00570: return 1; 00571: endfunction: transform 00572: 00573: 00574: function bit vmm_sb_ds::match(vmm_data actual, 00575: vmm_data expected); 00576: return this.quick_compare(actual, expected); 00577: endfunction: match 00578: 00579: 00580: function bit vmm_sb_ds::quick_compare(vmm_data actual, 00581: vmm_data expected); 00582: return 1; 00583: endfunction: quick_compare 00584: 00585: 00586: function bit vmm_sb_ds::compare(vmm_data actual, 00587: vmm_data expected); 00588: 00589: string diff; 00590: if (this.quick_compare(actual, expected)) begin 00591: return actual.compare(expected, diff); 00592: end 00593: 00594: endfunction: compare 00595: 00596: 00597: function vmm_data vmm_sb_ds::expect_in_order(vmm_data pkt, 00598: int exp_stream_id, 00599: int inp_stream_id, 00600: bit silent); 00601: 00602: vmm_sb_ds_exp_streams exp_streams; 00603: vmm_sb_ds_pkt_stream pkt_stream; 00604: 00605: if (exp_stream_id < 0) begin 00606: exp_stream_id = this.stream_id(pkt, EXPECT); 00607: end 00608: if (inp_stream_id < 0) begin 00609: inp_stream_id = this.stream_id(pkt, INPUT); 00610: end 00611: 00613: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV)) 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 : while (0); 00614: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00615: 00616: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin 00617: // Not found because the output stream does not exist! 00618: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00619: int n = 1; 00620: 00621: this.notify.indicate(NOT_FOUND, status); 00623: : : 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); 00624: 00625: if (!silent) begin 00626: this.n_not_found += n; 00627: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00628: end 00629: return null; 00630: end 00631: exp_streams = this.Xexp_streamsX[exp_stream_id]; 00632: 00633: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin 00634: // Not found because the input stream does not exist! 00635: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00636: int n = 1; 00637: 00638: this.notify.indicate(NOT_FOUND, status); 00640: : : 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); 00641: 00642: if (!silent) begin 00643: this.n_not_found += n; 00644: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00645: end 00646: return null; 00647: end 00648: pkt_stream = exp_streams.pkt_streams[inp_stream_id]; 00649: 00650: if (pkt_stream.pkts.size() == 0) begin 00651: // Not found because the packet stream is empty! 00652: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00653: int n = 1; 00654: 00655: this.notify.indicate(NOT_FOUND, status); 00657: : : 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); 00658: 00659: if (!silent) begin 00660: pkt_stream.n_not_found += n; 00661: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00662: end 00663: return null; 00664: end 00665: 00666: if (!this.compare(pkt, pkt_stream.pkts[0])) begin 00667: // Not found because the packet does not match 00668: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00669: int n = 1; 00670: 00671: this.notify.indicate(NOT_FOUND, status); 00673: : : 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); 00674: 00675: if (!silent) begin 00676: pkt_stream.n_not_found += n; 00677: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00678: end 00679: 00680: // Remove the packet 00681: pkt_stream.pkts.pop_front(); 00682: if (pkt_stream.pkts.size() == 0) begin 00683: // The entire scoreboard might be empty! 00684: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY); 00685: end 00686: 00687: return null; 00688: end 00689: 00690: // Found! 00691: begin 00692: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00693: int n = 1; 00694: 00695: this.notify.indicate(MATCHED, status); 00697: : : 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); 00698: if (!silent) pkt_stream.n_matched += n; 00699: end 00700: 00701: pkt = pkt_stream.pkts.pop_front(); 00702: if (pkt_stream.pkts.size() == 0) begin 00703: // The entire scoreboard might be empty! 00704: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY); 00705: end 00706: 00707: return pkt; 00708: 00709: endfunction: expect_in_order 00710: 00711: 00712: function bit vmm_sb_ds::expect_with_losses(input vmm_data pkt, 00713: output vmm_data matched, 00714: output vmm_data lost[], 00715: input int exp_stream_id, 00716: input int inp_stream_id, 00717: input bit silent); 00718: 00719: vmm_sb_ds_exp_streams exp_streams; 00720: vmm_sb_ds_pkt_stream pkt_stream; 00721: int match_idx; 00722: 00723: matched = null; 00724: lost = new [0]; 00725: 00726: if (inp_stream_id < 0) begin 00727: inp_stream_id = this.stream_id(pkt, INPUT); 00728: end 00729: if (exp_stream_id < 0) begin 00730: exp_stream_id = this.stream_id(pkt, EXPECT); 00731: end 00732: 00734: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV)) begin : void'(this.log.text($psprintf("Looking for packet on stream #%0d->#%0d", : inp_stream_id, exp_stream_id))); : this.log.end_msg(); : end : while (0); 00735: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00736: 00737: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin 00738: // Not found because the output stream does not exist! 00739: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00740: int n = 1; 00741: 00742: this.notify.indicate(NOT_FOUND, status); 00744: : : 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); 00745: 00746: if (!silent) begin 00747: this.n_not_found += n; 00748: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00749: end 00750: return 0; 00751: end 00752: exp_streams = this.Xexp_streamsX[exp_stream_id]; 00753: 00754: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin 00755: // Not found because the input stream does not exist! 00756: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00757: int n = 1; 00758: 00759: this.notify.indicate(NOT_FOUND, status); 00761: : : 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); 00762: 00763: if (!silent) begin 00764: this.n_not_found += n; 00765: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00766: end 00767: return 0; 00768: end 00769: pkt_stream = exp_streams.pkt_streams[inp_stream_id]; 00770: 00771: if (pkt_stream.pkts.size() == 0) begin 00772: // Not found because the packet stream is empty! 00773: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00774: int n = 1; 00775: 00776: this.notify.indicate(NOT_FOUND, status); 00778: : : 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); 00779: 00780: if (!silent) begin 00781: pkt_stream.n_not_found += n; 00782: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00783: end 00784: return 0; 00785: end 00786: 00787: foreach (pkt_stream.pkts[i]) begin 00788: if (this.match(pkt, pkt_stream.pkts[i])) begin 00789: // We have a match! 00790: matched = pkt_stream.pkts[i]; 00791: match_idx = i; 00792: break; 00793: end 00794: end 00795: if (matched == null) begin 00796: // Not found because no packet matched 00797: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00798: int n = 1; 00799: 00800: this.notify.indicate(NOT_FOUND, status); 00802: : : 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); 00803: 00804: if (!silent) begin 00805: this.n_not_found += n; 00807: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text({"With-loss packet was not matched:\n", : pkt.psdisplay(" ")})); : this.log.end_msg(); : end : while (0); 00808: end 00809: return 0; 00810: end 00811: 00812: 00813: // Everything between the matching packet and the head 00814: // of the packet stream is assumed to have been lost 00815: if (match_idx > 0) begin 00816: lost = new [match_idx]; 00817: foreach (lost[i]) begin 00818: lost[i] = pkt_stream.pkts[i]; 00819: end 00820: 00821: begin 00822: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id); 00823: int n = lost.size(); 00824: 00825: status.pkts = new [lost.size()] (lost); 00826: this.notify.indicate(DROPPED, status); 00828: : : 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); 00829: if (!silent) pkt_stream.n_dropped += n; 00830: end 00831: end 00832: repeat (match_idx + 1) pkt_stream.pkts.pop_front(); 00833: if (pkt_stream.pkts.size() == 0) begin 00834: // The entire scoreboard might be empty! 00835: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY); 00836: end 00837: 00838: if (!this.compare(pkt, matched)) begin 00839: // Mis-match! 00840: 00844: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::TRACE_SEV)) 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 : while (0); 00845: 00846: begin 00847: vmm_sb_ds_pkts status = new(null, EXPECT, exp_stream_id, inp_stream_id); 00848: int n = 1; 00849: 00850: status.pkts = new [2]; 00851: status.pkts[0] = pkt; 00852: status.pkts[1] = matched; 00853: 00854: this.notify.indicate(MISMATCHED, status); 00856: : : 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); 00857: if (!silent) pkt_stream.n_mismatched += n; 00858: end 00859: 00860: if (!silent) begin 00861: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text($psprintf("With-loss packet was not found"))); : this.log.end_msg(); : end : while (0); 00862: end 00863: return 0; 00864: end 00865: 00866: begin 00867: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00868: int n = 1; 00869: 00870: this.notify.indicate(MATCHED, status); 00872: : : 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); 00873: if (!silent) pkt_stream.n_matched += n; 00874: end 00875: 00876: return 1; 00877: endfunction: expect_with_losses 00878: 00879: 00880: function vmm_data vmm_sb_ds::expect_out_of_order(vmm_data pkt, 00881: int exp_stream_id, 00882: int inp_stream_id, 00883: bit silent); 00884: vmm_sb_ds_exp_streams exp_streams; 00885: vmm_sb_ds_pkt_stream pkt_stream; 00886: int match_idx; 00887: 00888: if (inp_stream_id < 0) begin 00889: inp_stream_id = this.stream_id(pkt, INPUT); 00890: end 00891: if (exp_stream_id < 0) begin 00892: exp_stream_id = this.stream_id(pkt, EXPECT); 00893: end 00894: 00896: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::DEBUG_SEV)) 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 : while (0); 00897: : do : if (this.log.start_msg(vmm_log::DEBUG_TYP, vmm_log::VERBOSE_SEV)) begin : void'(this.log.text(pkt.psdisplay(" "))); : this.log.end_msg(); : end : while (0); 00898: 00899: if (!this.Xexp_streamsX.exists(exp_stream_id)) begin 00900: // Not found because the output stream does not exist! 00901: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00902: int n = 1; 00903: 00904: this.notify.indicate(NOT_FOUND, status); 00906: : : 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); 00907: 00908: if (!silent) begin 00909: this.n_not_found += n; 00910: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00911: end 00912: return null; 00913: end 00914: exp_streams = this.Xexp_streamsX[exp_stream_id]; 00915: 00916: if (!exp_streams.pkt_streams.exists(inp_stream_id)) begin 00917: // Not found because the input stream does not exist! 00918: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00919: int n = 1; 00920: 00921: this.notify.indicate(NOT_FOUND, status); 00923: : : 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); 00924: 00925: if (!silent) begin 00926: this.n_not_found += n; 00927: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00928: end 00929: return null; 00930: end 00931: pkt_stream = exp_streams.pkt_streams[inp_stream_id]; 00932: 00933: if (pkt_stream.pkts.size() == 0) begin 00934: // Not found because the packet stream is empty! 00935: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00936: int n = 1; 00937: 00938: this.notify.indicate(NOT_FOUND, status); 00940: : : 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); 00941: 00942: if (!silent) begin 00943: pkt_stream.n_not_found += n; 00944: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 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 : while (0); 00945: end 00946: return null; 00947: end 00948: 00949: foreach (pkt_stream.pkts[i]) begin 00950: if (this.compare(pkt, pkt_stream.pkts[i])) begin 00951: // We have a match! 00952: begin 00953: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00954: int n = 1; 00955: 00956: this.notify.indicate(MATCHED, status); 00958: : : 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); 00959: if (!silent) pkt_stream.n_matched += n; 00960: end 00961: 00962: pkt = pkt_stream.pkts[i]; 00963: pkt_stream.pkts.delete(i); 00964: if (pkt_stream.pkts.size() == 0) begin 00965: // The entire scoreboard might be empty! 00966: if (this.get_n_pending() == 0) this.notify.indicate(EMPTY); 00967: end 00968: return pkt; 00969: end 00970: end 00971: 00972: begin 00973: vmm_sb_ds_pkts status = new(pkt, EXPECT, exp_stream_id, inp_stream_id); 00974: int n = 1; 00975: 00976: this.notify.indicate(NOT_FOUND, status); 00978: : : 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); 00979: if (!silent) pkt_stream.n_not_found += n; 00980: end 00981: 00982: if (!silent) begin 00983: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Out-of-order packet was not found")); : this.log.end_msg(); : end : while (0); 00984: end 00985: return null; 00986: endfunction: expect_out_of_order 00987: 00988: 00989: function void vmm_sb_ds::flush(); 00990: this.Xinp_stream_descsX.delete(); 00991: this.Xexp_stream_descsX.delete(); 00992: this.Xexp_streamsX.delete(); 00993: this.Xdefine_stream_calledX = 0; 00994: 00995: this.n_not_found = 0; 00996: this.orphaned = 0; 00997: this.insert_recursed = 0; 00998: 00999: this.notify.indicate(EMPTY); 01000: endfunction: flush 01001: 01002: 01003: function vmm_sb_ds_iter vmm_sb_ds::new_sb_iter(int exp_stream_id, 01004: int inp_stream_id); 01005: 01006: vmm_sb_ds_iter iter = new(this, exp_stream_id, inp_stream_id); 01007: 01008: return iter; 01009: endfunction: new_sb_iter 01010: 01011: function vmm_sb_ds_stream_iter vmm_sb_ds::new_stream_iter(int exp_stream_id, 01012: int inp_stream_id); 01013: 01014: vmm_sb_ds_stream_iter iter = new(this, null, exp_stream_id, inp_stream_id); 01015: return iter; 01016: endfunction: new_stream_iter 01017: 01018: 01019: function void vmm_sb_ds::prepend_callback(vmm_sb_ds_callbacks cb); 01020: if (cb == null) begin 01021: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Attempting to prepend a NULL callback extension")); : this.log.end_msg(); : end : while (0); 01022: return; 01023: end 01024: 01025: foreach(this.callbacks[i]) begin 01026: if (this.callbacks[i] == cb) begin 01027: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("Callback has already been registered")); : this.log.end_msg(); : end : while(0); 01028: return; 01029: end 01030: end 01031: //Prepend new callback 01032: this.callbacks.push_front(cb); 01033: endfunction: prepend_callback 01034: 01035: 01036: function void vmm_sb_ds::append_callback(vmm_sb_ds_callbacks cb); 01037: if (cb == null) begin 01038: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Attempting to append a NULL callback extension")); : this.log.end_msg(); : end : while (0); 01039: return; 01040: end 01041: 01042: foreach(this.callbacks[i]) begin 01043: if (this.callbacks[i] == cb) begin 01044: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("Callback has already been registered")); : this.log.end_msg(); : end : while(0); 01045: return; 01046: end 01047: end 01048: //Append new callback 01049: this.callbacks.push_back(cb); 01050: endfunction: append_callback 01051: 01052: 01053: function void vmm_sb_ds::unregister_callback(vmm_sb_ds_callbacks cb); 01054: foreach(this.callbacks[i]) begin 01055: if (this.callbacks[i] == cb) begin 01056: // Unregister it 01057: this.callbacks.delete(i); 01058: return; 01059: end 01060: end 01061: 01062: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("Callback was not registered")); : this.log.end_msg(); : end : while(0); 01063: endfunction: unregister_callback 01064: 01065: 01066: function int vmm_sb_ds::get_n_inserted(int exp_stream_id, 01067: int inp_stream_id); 01068: int n = 0; 01069: 01070: vmm_sb_ds_iter iter; 01071: iter = new (this, exp_stream_id, inp_stream_id); 01072: while (iter.next()) begin 01073: vmm_sb_ds_pkt_stream pkt_str; 01074: pkt_str = iter.Xget_pkt_streamX(); 01075: n += pkt_str.n_inserted; 01076: end 01077: 01078: return n; 01079: endfunction: get_n_inserted 01080: 01081: 01082: function int vmm_sb_ds::get_n_pending(int exp_stream_id, 01083: int inp_stream_id); 01084: int n = 0; 01085: 01086: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01087: while (iter.next()) begin 01088: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX(); 01089: n += pkt_str.pkts.size(); 01090: end 01091: 01092: return n; 01093: endfunction: get_n_pending 01094: 01095: 01096: function int vmm_sb_ds::get_n_matched(int exp_stream_id, 01097: int inp_stream_id); 01098: int n = 0; 01099: 01100: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01101: while (iter.next()) begin 01102: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX(); 01103: n += pkt_str.n_matched; 01104: end 01105: 01106: return n; 01107: endfunction: get_n_matched 01108: 01109: 01110: function int vmm_sb_ds::get_n_mismatched(int exp_stream_id, 01111: int inp_stream_id); 01112: int n = 0; 01113: 01114: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01115: while (iter.next()) begin 01116: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX(); 01117: n += pkt_str.n_mismatched; 01118: end 01119: 01120: return n; 01121: endfunction: get_n_mismatched 01122: 01123: 01124: function int vmm_sb_ds::get_n_dropped(int exp_stream_id, 01125: int inp_stream_id); 01126: int n = 0; 01127: 01128: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01129: while (iter.next()) begin 01130: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX(); 01131: n += pkt_str.n_dropped; 01132: end 01133: 01134: return n; 01135: endfunction: get_n_dropped 01136: 01137: 01138: function int vmm_sb_ds::get_n_not_found(int exp_stream_id, 01139: int inp_stream_id); 01140: int n = 0; 01141: 01142: 01143: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01144: 01145: while (iter.next()) begin 01146: vmm_sb_ds_pkt_stream pkt_str = iter.Xget_pkt_streamX(); 01147: n += pkt_str.n_not_found; 01148: end 01149: 01150: if (exp_stream_id < 0 || inp_stream_id < 0) n += this.n_not_found; 01151: 01152: return n; 01153: endfunction: get_n_not_found 01154: 01155: 01156: function int vmm_sb_ds::get_n_orphaned(int exp_stream_id, 01157: int inp_stream_id); 01158: 01159: if (!this.orphaned) begin 01160: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01161: vmm_data pkts[$]; 01162: while (iter.next()) begin 01163: vmm_sb_ds_pkt_stream pkt_stream = iter.Xget_pkt_streamX(); 01164: 01165: // Not yet supported in SP1 01166: // pkts = '{pkts, pkt_stream.pkts}; 01167: foreach (pkt_stream.pkts[i]) pkts.push_back(pkt_stream.pkts[i]); 01168: end 01169: 01170: if (pkts.size() > 0) begin 01171: vmm_sb_ds_pkts status = new(null, EXPECT, -1, -1); 01172: int n = pkts.size(); 01173: 01174: status.pkts = new [pkts.size()]; 01175: foreach (pkts[i]) status.pkts[i] = pkts[i]; 01176: this.notify.indicate(ORPHANED, status); 01179: : : 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); 01180: this.n_orphaned = n; 01181: end 01182: 01183: this.orphaned = 1; 01184: end 01185: 01186: return this.n_orphaned; 01187: endfunction: get_n_orphaned 01188: 01189: 01190: function void vmm_sb_ds::report(int exp_stream_id, 01191: int inp_stream_id); 01192: vmm_sb_ds_iter iter = new (this, exp_stream_id, inp_stream_id); 01193: 01194: string s = this.log.get_instance(); 01195: if (s.len() < 30) s = {s, {(30 - s.len()){" "}}}; 01196: else if (s.len() > 30) s = s.substr(0, 29); 01197: 01198: $write("+--------------------------------+------+------+------+------+------+------+\n"); 01199: $write("| %s |%s|%s|%s|%s|%s|%s|\n", s, 01200: "Insert", "Matchd", "MsMtch", "Droppd", "NotFnd", "Orphan"); 01201: $write("+--------------------------------+------+------+------+------+------+------+\n"); 01202: 01203: while (iter.next()) begin 01204: s = iter.describe(); 01205: if (s.len() < 30) s = {s, {(30 - s.len()){" "}}}; 01206: else if (s.len() > 30) s = s.substr(0, 29); 01207: $write("| %s | %04d | %04d | %04d | %04d | %04d | %04d |\n", s, 01208: iter.get_n_inserted(), iter.get_n_matched(), 01209: iter.get_n_mismatched(), iter.get_n_dropped(), 01210: iter.get_n_not_found(), iter.get_n_orphaned()); 01211: end 01212: $write("+--------------------------------+------+------+------+------+------+------+\n"); 01213: $write("| TOTAL | %04d | %04d | %04d | %04d | %04d | %04d |\n", 01214: this.get_n_inserted(exp_stream_id, inp_stream_id), 01215: this.get_n_matched(exp_stream_id, inp_stream_id), 01216: this.get_n_mismatched(exp_stream_id, inp_stream_id), 01217: this.get_n_dropped(exp_stream_id, inp_stream_id), 01218: this.get_n_not_found(exp_stream_id, inp_stream_id), 01219: this.get_n_orphaned(exp_stream_id, inp_stream_id)); 01220: $write("+--------------------------------+------+------+------+------+------+------+\n\n"); 01221: endfunction: report 01222: 01223: 01224: function void vmm_sb_ds::describe(); 01225: vmm_sb_ds_iter iter = this.new_sb_iter(); 01226: 01227: $write("Streams in Data Stream Scoreboard \"%s\":\n", 01228: this.log.get_instance()); 01229: 01230: while (iter.next()) begin 01231: $write(" %s\n", iter.describe()); 01232: end 01233: endfunction: describe 01234: 01235: 01236: function void vmm_sb_ds::display(string prefix); 01237: $write("%sContent of Data Stream Scoreboard \"%s\":\n", prefix, 01238: this.log.get_instance()); 01239: 01240: if (this.Xparallel_streamsX) begin 01241: foreach (this.Xexp_streamsX[k]) begin 01242: vmm_sb_ds_exp_streams exp_str = this.Xexp_streamsX[k]; 01243: vmm_sb_ds_pkt_stream pkt_str = exp_str.pkt_streams[k]; 01244: 01245: if (pkt_str == null) continue; 01246: 01247: $write("%s Stream #%0d", prefix, k); 01248: if (this.Xexp_stream_descsX.exists(k)) begin 01249: $write(" (%s)", this.Xexp_stream_descsX[k]); 01250: end 01251: $write(":\n"); 01252: 01253: foreach (pkt_str.pkts[i]) begin 01254: pkt_str.pkts[i].display({prefix, " "}); 01255: end 01256: end 01257: 01258: return; 01259: end 01260: 01261: foreach (this.Xexp_streamsX[k]) begin 01262: vmm_sb_ds_exp_streams exp_str = this.Xexp_streamsX[k]; 01263: 01264: $write("%s To stream #%0d", prefix, k); 01265: if (this.Xexp_stream_descsX.exists(k)) begin 01266: $write(" (%s)", this.Xexp_stream_descsX[k]); 01267: end 01268: $write(":\n"); 01269: foreach (exp_str.pkt_streams[j]) begin 01270: vmm_sb_ds_pkt_stream pkt_str = exp_str.pkt_streams[j]; 01271: 01272: $write("%s From stream #%0d", prefix, j); 01273: if (this.Xinp_stream_descsX.exists(j)) begin 01274: $write(" (%s)", this.Xinp_stream_descsX[j]); 01275: end 01276: $write(":\n"); 01277: foreach (pkt_str.pkts[i]) begin 01278: pkt_str.pkts[i].display({prefix, " "}); 01279: end 01280: end 01281: end 01282: endfunction: display 01283: 01284: