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.
std_lib/vmm_notify.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: 00026: class vmm_notification_config; 00027: event the_event; 00028: bit the_event_bit; //for ON_OFF_TRIGGERING (1:ON, 0:OFF) 00029: time stamp; 00030: int n_waiting_for; 00031: event reset; 00032: event abort; 00033: vmm_notification watch; 00034: int unsigned trig_mode; 00035: vmm_data status; 00036: vmm_notify_callbacks cbs[$]; 00040: endclass 00041: 00042: 00043: function vmm_notify::new(vmm_log log); 00047: 00048: this.log = log; 00049: endfunction 00050: 00051: function void vmm_notify::display(string prefix); 00052: $write(this.psdisplay(prefix), "\n"); 00053: endfunction 00054: 00055: function string vmm_notify::psdisplay(string prefix); 00056: int i, ok; 00057: $sformat(psdisplay, "%sConfigured%s: [", 00058: prefix, (log == null) ? "" : $psprintf(" in %s(%s)", 00059: log.get_name(), 00060: log.get_instance())); 00061: for (ok = this.configs.first(i); 00062: ok; 00063: ok = this.configs.next(i)) begin 00064: $sformat(psdisplay, "%0s %0d", psdisplay, i); 00065: end 00066: psdisplay = {psdisplay, "]"}; 00067: endfunction: psdisplay 00068: 00069: 00070: function vmm_notify vmm_notify::copy(vmm_notify to); 00071: int i, ok; 00072: 00073: if (to == null) to = new(this.log); 00074: 00075: to.last_notification_id = this.last_notification_id; 00076: for (ok = this.configs.first(i); ok; 00077: ok = this.configs.next(i)) begin 00078: 00079: vmm_notification_config cfg = new; 00080: 00081: cfg.trig_mode = this.configs[i].trig_mode; 00082: cfg.stamp = 0; 00083: cfg.status = null; 00084: cfg.n_waiting_for = 0; 00085: cfg.watch = null; 00086: to.configs[i] = cfg; 00087: end 00088: 00089: return to; 00090: endfunction : copy 00091: 00092: 00093: function int vmm_notify::configure(int notification_id, 00094: sync_e sync); 00095: 00096: // Warn if an event is being re-configured 00097: if (this.configs.exists(notification_id)) 00098: begin 00099: if (log == null) begin 00100: $write("vmm_notify::WARNING: Reconfiguring notification #%0d...\n", 00101: notification_id); 00102: end 00103: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) 00104: begin 00105: string txt; 00106: $sformat(txt, "Reconfiguring notification #%0d...", notification_id); 00107: void'(this.log.text(txt)); 00108: this.log.end_msg(); 00109: end 00110: end 00111: else if (notification_id > 1_000_000) 00112: begin 00113: // New notification ID > 1,000,000 are reserved 00114: if (log == null) begin 00115: $write("vmm_notify::FATAL: Notification notification IDs > 1,000,000 are reserved\n"); 00116: $finish(); 00117: end 00118: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00119: begin 00120: void'(this.log.text("Notification notification IDs > 1,000,000 are reserved")); 00121: this.log.end_msg(); 00122: end 00123: return -1; 00124: end 00125: 00126: // Automatically generate a unique notification ID if notification ID 00127: // is not positive. 00128: if (notification_id < 0) 00129: begin 00130: last_notification_id++; 00131: notification_id = last_notification_id; 00132: end 00133: configure = notification_id; 00134: 00146: 00147: begin 00148: vmm_notification_config cfg = new; 00149: 00150: cfg.trig_mode = sync; 00151: cfg.stamp = 0; 00152: cfg.status = null; 00153: cfg.n_waiting_for = 0; 00154: cfg.the_event_bit = 0; 00155: 00156: this.configs[notification_id] = cfg; 00157: end 00158: endfunction: configure 00159: 00160: 00161: function int vmm_notify::is_configured(int notification_id); 00162: if (!this.configs.exists(notification_id)) return 0; 00163: 00164: is_configured = this.configs[notification_id].trig_mode; 00165: endfunction: is_configured 00166: 00167: 00168: function bit vmm_notify::is_on(int notification_id); 00169: vmm_notification_config cfg; 00170: 00171: if (!this.configs.exists(notification_id)) 00172: begin 00173: if (this.log == null) begin 00174: $write("vmm_notify::FATAL: Checking undefined notification #%0d\n", 00175: notification_id); 00176: $finish(); 00177: end 00178: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00179: begin 00180: string txt; 00181: $sformat(txt, "Checking undefined notification #%0d", notification_id); 00182: void'(this.log.text(txt)); 00183: this.log.end_msg(); 00184: end 00185: return 0; 00186: end 00187: 00188: cfg = this.configs[notification_id]; 00189: 00190: if (cfg.trig_mode != ON_OFF) begin 00191: if (this.log == null) begin 00192: $write("vmm_notify::WARNING: Cannot check non-ON_OFF notification #%0d\n", 00193: notification_id); 00194: end 00195: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin 00196: string txt; 00197: $sformat(txt, "Cannot check non-ON_OFF notification #%0d", notification_id); 00198: void'(this.log.text(txt)); 00199: this.log.end_msg(); 00200: end 00201: return 0; 00202: end 00203: 00204: is_on = cfg.the_event_bit; 00205: endfunction: is_on 00206: 00207: 00208: task vmm_notify::wait_for(int notification_id); 00209: vmm_notification_config cfg; 00210: 00211: if (!this.configs.exists(notification_id)) 00212: begin 00213: if (this.log == null) begin 00214: $write("vmm_notify::FATAL Waiting for undefined notification #%0d\n", 00215: notification_id); 00216: $finish(); 00217: end 00218: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00219: begin 00220: string txt; 00221: $sformat(txt, "Waiting for undefined notification #%0d", notification_id); 00222: void'(this.log.text(txt)); 00223: this.log.end_msg(); 00224: end 00225: 00226: return; 00227: end 00228: 00229: cfg = this.configs[notification_id]; 00230: 00231: cfg.n_waiting_for++; 00232: case(cfg.trig_mode) 00233: ON_OFF : while (cfg.the_event_bit !== 1) begin 00234: @(cfg.the_event); 00235: end 00236: ONE_SHOT : @(cfg.the_event); 00237: BLAST : wait (cfg.the_event.triggered); 00238: default : begin 00239: if (this.log == null) begin 00240: $write("Invalid notification type\n"); 00241: end else : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin : void'(this.log.text("Invalid notification type")); : this.log.end_msg(); : end : while (0); 00242: end 00243: endcase 00244: if (cfg.n_waiting_for > 0) cfg.n_waiting_for--; 00245: endtask: wait_for 00246: 00247: 00248: task vmm_notify::wait_for_off(int notification_id); 00249: vmm_notification_config cfg; 00250: 00251: if (!this.configs.exists(notification_id)) 00252: begin 00253: if (this.log == null) begin 00254: $write("vmm_notify::FATAL: Waiting for undefined notification #%0d\n", 00255: notification_id); 00256: $finish(); 00257: end 00258: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00259: begin 00260: string txt; 00261: $sformat(txt, "Waiting for undefined notification #%0d", notification_id); 00262: void'(this.log.text(txt)); 00263: this.log.end_msg(); 00264: end 00265: return; 00266: end 00267: 00268: cfg = this.configs[notification_id]; 00269: 00270: cfg.n_waiting_for++; 00271: case(cfg.trig_mode) 00272: ON_OFF : while (cfg.the_event_bit !== 0) begin 00273: @(cfg.the_event); 00274: end 00275: default : begin 00276: if (this.log == null) begin 00277: $write("Cannot use vmm_notify::wait_for_off() on non-ON/OFF notification\n"); 00278: end else : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin : void'(this.log.text("Cannot use vmm_notify::wait_for_off() on non-ON/OFF notification")); : this.log.end_msg(); : end : while (0); 00279: end 00280: endcase 00281: if (cfg.n_waiting_for > 0) cfg.n_waiting_for--; 00282: endtask: wait_for_off 00283: 00284: 00285: function bit vmm_notify::is_waited_for(int notification_id); 00286: vmm_notification_config cfg; 00287: 00288: if (!this.configs.exists(notification_id)) 00289: begin 00290: if (this.log == null) begin 00291: $write("vmm_notify::FATAL: is_waited_for() called for undefined notification #%0d\n", 00292: notification_id); 00293: $finish(); 00294: end 00295: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00296: begin 00297: string txt; 00298: $sformat(txt, "vmm_notify::is_waited_for called for undefined notification #%0d", 00299: notification_id); 00300: void'(this.log.text(txt)); 00301: this.log.end_msg(); 00302: end 00303: 00304: return 0; 00305: end 00306: 00307: cfg = this.configs[notification_id]; 00308: 00309: is_waited_for = (cfg.n_waiting_for > 0); 00310: endfunction: is_waited_for 00311: 00312: 00313: function void vmm_notify::terminated(int notification_id); 00314: vmm_notification_config cfg; 00315: 00316: if (!this.configs.exists(notification_id)) 00317: begin 00318: if (this.log == null) begin 00319: $write("vmm_notify::FATAL: terminated() called for undefined notification #%0d\n", 00320: notification_id); 00321: $finish(); 00322: end 00323: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00324: begin 00325: string txt; 00326: $sformat(txt, "vmm_notify::terminated called for undefined notification #%0d", 00327: notification_id); 00328: void'(this.log.text(txt)); 00329: this.log.end_msg(); 00330: end 00331: return; 00332: end 00333: 00334: cfg = this.configs[notification_id]; 00335: 00336: if (cfg.n_waiting_for > 0) cfg.n_waiting_for--; 00337: endfunction: terminated 00338: 00339: function vmm_data vmm_notify::status(int notification_id); 00340: vmm_notification_config cfg; 00341: 00342: if (!this.configs.exists(notification_id)) 00343: begin 00344: if (this.log == null) begin 00345: $write("vmm_notify::FATAL: Requesting status for undefined notification #%0d\n", 00346: notification_id); 00347: $finish(); 00348: end 00349: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00350: begin 00351: string txt; 00352: $sformat(txt, "Requesting status for undefined notification #%0d", 00353: notification_id); 00354: void'(this.log.text(txt)); 00355: this.log.end_msg(); 00356: end 00357: return null; 00358: end 00359: 00360: cfg = this.configs[notification_id]; 00361: 00362: status = cfg.status; 00363: endfunction: status 00364: 00365: function time vmm_notify::timestamp(int notification_id); 00366: vmm_notification_config cfg; 00367: 00368: if (!this.configs.exists(notification_id)) 00369: begin 00370: if (this.log == null) begin 00371: $write("vmm_notify::FATAL: Requesting timestamp for undefined notification #%0d\n", 00372: notification_id); 00373: $finish(); 00374: end 00375: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00376: begin 00377: string txt; 00378: $sformat(txt, "Requesting timestamp for undefined notification #%0d", 00379: notification_id); 00380: void'(this.log.text(txt)); 00381: this.log.end_msg(); 00382: end 00383: return 0; 00384: end 00385: 00386: cfg = this.configs[notification_id]; 00387: 00388: timestamp = cfg.stamp; 00389: endfunction: timestamp 00390: 00391: function void vmm_notify::indicate(int notification_id, 00392: vmm_data status); 00393: vmm_notification_config cfg; 00394: 00395: if (!this.configs.exists(notification_id)) 00396: begin 00397: if (this.log == null) begin 00398: $write("vmm_notify::FATAL: Indicating undefined notification #%0d\n", 00399: notification_id); 00400: $finish(); 00401: end 00402: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00403: begin 00404: string txt; 00405: $sformat(txt, "Indicating undefined notification #%0d", 00406: notification_id); 00407: void'(this.log.text(txt)); 00408: this.log.end_msg(); 00409: end 00410: return; 00411: end 00412: 00413: cfg = this.configs[notification_id]; 00414: 00415: if (cfg.trig_mode == ON_OFF) cfg.the_event_bit = 1; 00416: -> cfg.the_event; 00417: 00418: cfg.stamp = $realtime(); 00419: cfg.status = status; 00420: 00421: foreach (cfg.cbs[i]) begin 00422: cfg.cbs[i].indicated(status); 00423: end 00424: 00449: endfunction: indicate 00450: 00451: 00452: function void vmm_notify::set_notification(int notification_id, 00453: vmm_notification ntfy); 00454: vmm_notification_config cfg; 00455: 00456: if (!this.configs.exists(notification_id)) 00457: begin 00458: if (this.log == null) begin 00459: $write("vmm_notify::FATAL: Setting notification on undefined notification #%0d\n", 00460: notification_id); 00461: $finish(); 00462: end 00463: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00464: begin 00465: string txt; 00466: $sformat(txt, "Setting notification on undefined notification #%0d", notification_id); 00467: void'(this.log.text(txt)); 00468: this.log.end_msg(); 00469: end 00470: return; 00471: end 00472: 00473: cfg = this.configs[notification_id]; 00474: 00475: // Was there an event before? 00476: if (cfg.watch != null) 00477: begin 00478: // Terminate it 00479: ->cfg.abort; 00480: end 00481: if (ntfy == null) 00482: begin 00483: cfg.watch = null; 00484: return; 00485: end 00486: 00487: // Watch for the specified event 00488: cfg.watch = ntfy; 00489: fork 00490: begin 00491: fork 00492: while (1) 00493: begin 00494: fork 00495: while (1) 00496: begin 00497: vmm_data status; 00498: ntfy.indicate(status); 00499: this.indicate(notification_id, status); 00500: end 00501: 00502: while (cfg.trig_mode == ON_OFF) // persistent? 00503: begin 00504: ntfy.reset(); 00505: cfg.the_event_bit = 0; 00506: -> cfg.the_event; 00507: end 00508: join_none 00509: 00510: @(cfg.reset); 00511: disable fork; 00512: end 00513: join_none 00514: 00515: @(cfg.abort); 00516: disable fork; 00517: end 00518: join_none 00519: endfunction: set_notification 00520: 00521: 00522: function vmm_notification vmm_notify::get_notification(int notification_id); 00523: if (!this.configs.exists(notification_id)) 00524: begin 00525: if (this.log == null) begin 00526: $write("vmm_notify::FATAL: Requesting notification for undefined notification #%0d\n", 00527: notification_id); 00528: $finish(); 00529: end 00530: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00531: begin 00532: string txt; 00533: $sformat(txt, "Requesting notification for undefined notification #%0d", 00534: notification_id); 00535: void'(this.log.text(txt)); 00536: this.log.end_msg(); 00537: end 00538: return null; 00539: end 00540: 00541: get_notification = this.configs[notification_id].watch; 00542: endfunction: get_notification 00543: 00544: 00545: function void vmm_notify::reset(int notification_id, 00546: reset_e rst_typ); 00547: vmm_notification_config cfg; 00548: 00549: if (notification_id < 0) 00550: begin 00551: int i, ok; 00552: 00553: for (ok = this.configs.first(i); ok; ok = this.configs.next(i)) 00554: begin 00555: cfg = this.configs[i]; 00556: 00557: if (cfg.trig_mode == ON_OFF) begin 00558: cfg.the_event_bit = 0; 00559: ->cfg.the_event; 00560: end 00561: 00562: if (cfg.watch != null) 00563: begin 00564: ->cfg.reset; 00565: if (rst_typ == HARD) 00566: begin 00567: ->cfg.abort; 00568: cfg.watch = null; 00569: end 00570: end 00571: 00572: if (rst_typ == HARD) 00573: begin 00574: cfg.stamp = 0; 00575: cfg.status = null; 00576: cfg.n_waiting_for = 0; 00577: end 00578: end 00579: return; 00580: end 00581: 00582: if (!this.configs.exists(notification_id)) 00583: begin 00584: if (this.log == null) begin 00585: $write("vmm_notify::FATAL: Reseting undefined notification #%0d\n", 00586: notification_id); 00587: $finish(); 00588: end 00589: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) 00590: begin 00591: string txt; 00592: $sformat(txt, "Reseting undefined notification #%0d", notification_id); 00593: void'(this.log.text(txt)); 00594: this.log.end_msg(); 00595: end 00596: return; 00597: end 00598: 00599: cfg = this.configs[notification_id]; 00600: ->cfg.the_event; 00601: cfg.the_event_bit = 0; 00602: if (cfg.watch != null) 00603: begin 00604: ->cfg.reset; 00605: if (rst_typ == HARD) 00606: begin 00607: ->cfg.abort; 00608: cfg.watch = null; 00609: end 00610: end 00611: 00612: if (rst_typ == HARD) 00613: begin 00614: cfg.stamp = 0; 00615: cfg.status = null; 00616: cfg.n_waiting_for = 0; 00617: end 00618: endfunction: reset 00619: 00620: 00621: function void vmm_notify::append_callback(int notification_id, 00622: vmm_notify_callbacks cbs); 00623: if (!this.configs.exists(notification_id)) 00624: begin 00625: if (log == null) begin 00626: $write("vmm_notify::ERROR: Unknown notification #%0d to append callback to.\n", 00627: notification_id); 00628: end 00629: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 00630: begin 00631: string txt; 00632: $sformat(txt, "Unkown notification #%0d to append callback to.", 00633: notification_id); 00634: this.log.text(txt); 00635: this.log.end_msg(); 00636: end 00637: return; 00638: end 00639: 00640: // Append new callback 00641: this.configs[notification_id].cbs.push_back(cbs); 00642: 00643: endfunction: append_callback 00644: 00645: 00646: function void vmm_notify::unregister_callback(int notification_id, 00647: vmm_notify_callbacks cbs); 00648: if (!this.configs.exists(notification_id)) 00649: begin 00650: if (log == null) begin 00651: $write("vmm_notify::ERROR: Unknown notification #%0d to remove callback from.\n", 00652: notification_id); 00653: end 00654: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) 00655: begin 00656: string txt; 00657: $sformat(txt, "Unkown notification #%0d to remove callback from.", 00658: notification_id); 00659: this.log.text(txt); 00660: this.log.end_msg(); 00661: end 00662: return; 00663: end 00664: 00665: begin 00666: vmm_notification_config cfg = this.configs[notification_id]; 00667: foreach(cfg.cbs[i]) begin 00668: if (cfg.cbs[i] == cbs) begin 00669: // Unregister it 00670: cfg.cbs.delete(i); 00671: return; 00672: end 00673: end 00674: end 00675: 00676: if (log == null) begin 00677: $write("vmm_notify::WARNING: Callback was not registered with notification #%0d.\n", 00678: notification_id); 00679: end 00680: else if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) 00681: begin 00682: string txt; 00683: $sformat(txt, "Callback was not registered with notification #%0d.", 00684: notification_id); 00685: this.log.text(txt); 00686: this.log.end_msg(); 00687: end 00688: endfunction: unregister_callback 00689: 00690: 00691: 00692: 00693: 00694: