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_xactor.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: 00023: function vmm_xactor::new(string name, 00024: string inst, 00025: int stream_id 00026: ); 00027: 00028: 00032: 00033: this.log = new(name, inst); 00034: this.notify = new(this.log); 00035: this.notify.configure(XACTOR_IDLE, vmm_notify::ON_OFF); 00036: this.notify.configure(XACTOR_BUSY, vmm_notify::ON_OFF); 00037: this.notify.configure(XACTOR_STARTED); 00038: this.notify.configure(XACTOR_STOPPING, vmm_notify::ON_OFF); 00039: this.notify.configure(XACTOR_STOPPED); 00040: this.notify.configure(XACTOR_RESET); 00041: 00042: this.notify.indicate(XACTOR_IDLE); 00043: this.notify.reset(XACTOR_BUSY); 00044: 00045: this.stream_id = stream_id; 00046: 00047: this.start_it = 0; 00048: this.stop_it = 1; 00049: this.n_threads_to_stop = 0; 00050: this.n_threads_stopped = 0; 00051: this.reset_it = 0; 00052: this.resetable = 0; 00053: this.main_running = 0; 00054: 00055: fork 00056: begin 00057: this.save_main_rng_state = 1; 00058: this.restore_main_rng_state = 0; 00059: this.main_rng_state = get_randstate(); 00060: 00061: while (1) begin 00062: this.main_running = 0; 00063: 00064: // wait to start 00065: while (!this.start_it) begin 00066: @ (this.start_it_event); 00067: // Reset has no effect since we are not started yet 00068: this.reset_it = 0; 00069: end 00070: this.start_it = 0; 00071: this.stop_it = 0; 00072: this.n_threads_to_stop = 0; 00073: this.n_threads_stopped = 0; 00074: 00075: // We may be held back by on-going reset operation 00076: fork 00077: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00078: void'(this.log.text("Start delayed by on-going reset activity")); 00079: this.log.end_msg(); 00080: end 00081: join_none 00082: 00083: while (this.reset_pending > 0) begin 00084: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin : void'(this.log.text("Pending resets not currently supported")); : this.log.end_msg(); : end : while (0); 00085: // `wait(@(this.reset_pending)); // Not supported yet. 00086: end 00087: disable fork; 00088: 00089: // 00090: // Fork the main body 00091: // 00092: 00093: if (this.save_main_rng_state) begin 00094: this.main_rng_state = get_randstate(); 00095: end 00096: if (this.restore_main_rng_state) begin 00097: set_randstate(main_rng_state); 00098: end 00099: this.save_main_rng_state = 0; 00100: this.restore_main_rng_state = 0; 00101: 00102: fork 00103: begin 00104: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV )) begin 00105: void'(this.log.text("Started")); 00106: this.log.end_msg(); 00107: end 00108: 00109: this.notify.reset(XACTOR_IDLE); 00110: this.notify.indicate(XACTOR_BUSY); 00111: this.notify.indicate(XACTOR_STARTED); 00112: main(); 00113: end 00114: 00115: begin 00116: // Check that super.main() was called in all 00117: // extensions of this class 00118: #1; 00119: if (!this.main_running) begin 00120: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("Virtual vmm_xactor::main() does not call super.main()")); : this.log.end_msg(); : end : while(0); 00121: end 00122: end 00123: join_none 00124: 00125: // Wait to reset 00126: this.resetable = 1; 00127: do 00128: @ (this.reset_it_event); 00129: while (!this.reset_it); 00130: this.resetable = 0; 00131: this.reset_it = 0; 00132: this.stop_it = 1; 00133: this.n_threads_to_stop = 0; 00134: this.n_threads_stopped = 0; 00135: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00136: void'(this.log.text("Reset")); 00137: this.log.end_msg(); 00138: end 00139: this.notify.reset(XACTOR_BUSY); 00140: this.notify.indicate(XACTOR_IDLE); 00141: this.notify.reset(XACTOR_STOPPING); 00142: this.notify.indicate(XACTOR_STOPPED); 00143: this.notify.indicate(XACTOR_RESET); 00144: disable fork; 00145: // Pending start? 00146: if (this.start_it) begin 00147: ->this.start_it_event; 00148: end 00149: end 00150: end 00151: join_none 00152: endfunction: new 00153: 00154: 00155: function string vmm_xactor::get_name(); 00156: get_name = this.log.get_name(); 00157: endfunction:get_name 00158: 00159: 00160: function string vmm_xactor::get_instance(); 00161: get_instance = this.log.get_instance(); 00162: endfunction: get_instance 00163: 00164: 00165: function void vmm_xactor::start_xactor(); 00166: this.start_it = 1; 00167: -> this.start_it_event; 00168: this.notify.reset(XACTOR_STOPPING); 00169: endfunction: start_xactor 00170: 00171: 00172: function void vmm_xactor::stop_xactor(); 00173: this.stop_it = 1; 00174: this.start_it = 0; 00175: this.notify.indicate(XACTOR_STOPPING); 00176: 00177: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00178: void'(this.log.text("Stop requested")); 00179: this.log.end_msg(); 00180: end 00181: endfunction: stop_xactor 00182: 00183: 00184: function void vmm_xactor::reset_xactor(reset_e rst_typ); 00185: this.reset_it = 1; 00186: -> this.reset_it_event; 00187: this.start_it = 0; 00188: 00189: // Reset notifier & RNG state on FIRM and above 00190: if (rst_typ == FIRM_RST || 00191: rst_typ == HARD_RST) begin 00192: this.notify.reset(-1, vmm_notify::HARD); 00193: this.restore_rng_state(); 00194: end 00195: else begin 00196: this.notify.reset(-1, vmm_notify::SOFT); 00197: end 00198: 00199: // Unregister all callbacks on HARD reset 00200: if (rst_typ == HARD_RST) begin 00206: // Works in VCS2008.03 00207: this.callbacks = '{}; 00209: end 00210: endfunction: reset_xactor 00211: 00212: 00213: function void vmm_xactor::save_rng_state(); 00214: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00215: void'(this.log.text("Saving RNG state information...")); 00216: this.log.end_msg(); 00217: end 00218: 00219: if (!this.stop_it) begin 00220: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("save_rng_state() called while transactor is still running")); : this.log.end_msg(); : end : while(0); 00221: end 00222: this.save_main_rng_state = 1; 00223: endfunction: save_rng_state 00224: 00225: 00226: function void vmm_xactor::restore_rng_state(); 00227: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00228: void'(this.log.text("Restoring RNG state information...")); 00229: this.log.end_msg(); 00230: end 00231: 00232: if (!this.stop_it) begin 00233: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("restore_rng_state() called while transactor is still running")); : this.log.end_msg(); : end : while(0); 00234: end 00235: this.restore_main_rng_state = 1; 00236: endfunction: restore_rng_state 00237: 00238: 00239: function void vmm_xactor::xactor_status(string prefix); 00240: if (this.stop_it) begin 00241: if (this.n_threads_to_stop == 0) begin 00242: : do : if (this.log.start_msg(vmm_log::NOTE_TYP)) begin : void'(this.log.text({prefix, "Transactor is STOPPING (no threads stopped yet)"})); : this.log.end_msg(); : end : while (0); 00243: end 00244: else if (this.n_threads_to_stop < this.n_threads_stopped) begin 00247: : do : if (this.log.start_msg(vmm_log::NOTE_TYP)) begin : void'(this.log.text($psprintf("%sTransactor is STOPPING (%0d out of %0d threads stopped)", : prefix, this.n_threads_stopped, : this.n_threads_to_stop))); : this.log.end_msg(); : end : while (0); 00248: end 00249: else begin 00250: : do : if (this.log.start_msg(vmm_log::NOTE_TYP)) begin : void'(this.log.text({prefix, "Transactor is STOPPED"})); : this.log.end_msg(); : end : while (0); 00251: end 00252: end 00253: else : do : if (this.log.start_msg(vmm_log::NOTE_TYP)) begin : void'(this.log.text({prefix, "Transactor is RUNNING"})); : this.log.end_msg(); : end : while (0); 00254: endfunction: xactor_status 00255: 00256: 00257: task vmm_xactor::main(); 00258: this.main_running = 1; 00259: endtask: main 00260: 00261: 00262: task vmm_xactor::wait_if_stopped(int unsigned n_threads); 00263: if (n_threads == 0) begin 00264: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 00265: void'(this.log.text("Number of threads to stop specified to vmm_xactor::wait_if_stopped() must be greater than 0")); 00266: this.log.end_msg(); 00267: end 00268: n_threads = 1; 00269: end 00270: 00271: if (this.stop_it) begin 00272: if (this.n_threads_to_stop == 0) this.n_threads_to_stop = n_threads; 00273: else if (this.n_threads_to_stop != n_threads) begin 00274: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin 00275: void'(this.log.text("All threads must specify the same number of threads to stop to vmm_xactor::wait_if_stopped()")); 00276: this.log.end_msg(); 00277: end 00278: if (this.n_threads_to_stop < n_threads) this.n_threads_to_stop = n_threads; 00279: end 00280: 00281: this.n_threads_stopped++; 00282: if (this.n_threads_stopped >= this.n_threads_to_stop) begin 00283: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00284: void'(this.log.text("Stopped")); 00285: this.log.end_msg(); 00286: end 00287: 00288: this.notify.reset(XACTOR_BUSY); 00289: this.notify.indicate(XACTOR_IDLE); 00290: this.notify.reset(XACTOR_STOPPING); 00291: this.notify.indicate(XACTOR_STOPPED); 00292: end 00293: 00294: @(this.start_it_event); 00295: this.start_it = 0; 00296: this.stop_it = 0; 00297: this.n_threads_stopped = 0; 00298: this.n_threads_to_stop = 0; 00299: 00300: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00301: void'(this.log.text("Started")); 00302: this.log.end_msg(); 00303: end 00304: this.notify.reset(XACTOR_IDLE); 00305: this.notify.indicate(XACTOR_BUSY); 00306: this.notify.indicate(XACTOR_STARTED); 00307: end 00308: endtask: wait_if_stopped 00309: 00310: 00311: task vmm_xactor::wait_if_stopped_or_empty(vmm_channel chan, 00312: int unsigned n_threads); 00313: this.wait_if_stopped(n_threads); 00314: while (chan.level() == 0) begin 00315: vmm_data data; 00316: 00317: // Indicate IDLE because we are going to block on the channel 00318: this.notify.reset(XACTOR_BUSY); 00319: this.notify.indicate(XACTOR_IDLE); 00320: 00321: chan.peek(data); 00322: this.wait_if_stopped(n_threads); 00323: end 00324: 00325: this.notify.reset(XACTOR_IDLE); 00326: this.notify.indicate(XACTOR_BUSY); 00327: endtask: wait_if_stopped_or_empty 00328: 00329: 00330: function void vmm_xactor::prepend_callback(vmm_xactor_callbacks cb); 00331: if (cb == null) begin 00332: : 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); 00333: return; 00334: end 00335: 00336: foreach(this.callbacks[i]) begin 00337: if (this.callbacks[i] == cb) begin 00338: : 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); 00339: return; 00340: end 00341: end 00342: //Prepend new callback 00343: this.callbacks.push_front(cb); 00344: endfunction: prepend_callback 00345: 00346: 00347: function void vmm_xactor::append_callback(vmm_xactor_callbacks cb); 00348: if (cb == null) begin 00349: : 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); 00350: return; 00351: end 00352: 00353: foreach(this.callbacks[i]) begin 00354: if (this.callbacks[i] == cb) begin 00355: : 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); 00356: return; 00357: end 00358: end 00359: //Append new callback 00360: this.callbacks.push_back(cb); 00361: endfunction: append_callback 00362: 00363: 00364: function void vmm_xactor::unregister_callback(vmm_xactor_callbacks cb); 00365: foreach(this.callbacks[i]) begin 00366: if (this.callbacks[i] == cb) begin 00367: // Unregister it 00368: this.callbacks.delete(i); 00369: return; 00370: end 00371: end 00372: 00373: : 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); 00374: endfunction: unregister_callback 00375: 00376: 00377: 00378: 00379: