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/xvc_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: 00024: function xvc_xactor::new(string name, 00025: string inst, 00026: int stream_id, 00027: xvc_action_channel action_chan, 00028: xvc_action_channel interrupt_chan 00029: ); 00030: super.new(name, inst, stream_id ); 00031: 00032: this.trace = new({name, " Trace"}, inst); 00033: 00034: if (action_chan == null) begin 00035: action_chan = new({name, "Action Channel"}, inst); 00036: end else action_chan.reconfigure(1, 0); 00037: this.action_chan = action_chan; 00038: this.log.is_above(this.action_chan.log); 00039: 00040: if (interrupt_chan == null) begin 00041: interrupt_chan = new({name, "Interrupt Channel"}, inst, 65535); 00042: end else interrupt_chan.reconfigure(65535, 0); 00043: this.interrupt_chan = interrupt_chan; 00044: this.log.is_above(this.interrupt_chan.log); 00045: 00046: this.interrupt = 0; 00047: this.interrupted = 0; 00048: 00049: this.idle = new("Dummy idle action", this.log); 00050: endfunction: new 00051: 00052: 00053: function void xvc_xactor::add_action(xvc_action action); 00054: int i; 00055: 00056: if (action == null) begin 00057: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Attempting to add a NULL action")); : this.log.end_msg(); : end : while (0); 00058: return; 00059: end 00060: 00061: // Do we already know about this action? 00062: foreach(this.known_actions[i]) begin 00063: if (this.known_actions[i] == action) begin 00064: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV)) begin : void'(this.log.text("Attempting to add already-known action")); : this.log.end_msg(); : end : while(0); 00065: return; 00066: end 00067: end 00068: 00069: this.known_actions.push_back(action); 00070: endfunction: add_action 00071: 00072: 00073: function xvc_action xvc_xactor::parse(string argv[]); 00074: int i; 00075: 00076: parse = null; 00077: 00078: foreach(this.known_actions[i]) begin 00079: parse = this.known_actions[i].parse(argv); 00080: if (parse != null) return parse; 00081: end 00082: 00083: if (this.log.start_msg(vmm_log::FAILURE_TYP, 00084: vmm_log::ERROR_SEV)) begin 00085: string msg = "Unknown action command:"; 00086: foreach (argv[i]) begin 00087: msg = {msg, " ", argv[i]}; 00088: end 00089: void'(this.log.text(msg)); 00090: this.log.end_msg(); 00091: end 00092: endfunction: parse 00093: 00094: 00095: function void xvc_xactor::start_xactor(); 00096: super.start_xactor(); 00097: endfunction: start_xactor 00098: 00099: 00100: function void xvc_xactor::stop_xactor(); 00101: super.stop_xactor(); 00102: endfunction: stop_xactor 00103: 00104: 00105: function void xvc_xactor::reset_xactor(vmm_xactor::reset_e rst_typ); 00106: super.reset_xactor(rst_typ); 00107: 00108: this.action_chan.flush(); 00109: this.interrupt_chan.flush(); 00110: this.executing = null; 00111: this.interrupt = 0; 00112: this.interrupted = 0; 00113: 00114: if (rst_typ > vmm_xactor::HARD_RST) begin 00120: // Works in VCS2008.03 00121: this.known_actions = '{}; 00123: end 00124: endfunction: reset_xactor 00125: 00126: 00127: function void xvc_xactor::xactor_status(string prefix); 00128: super.xactor_status(prefix); 00129: 00130: if (this.interrupt) begin 00131: // Pending interrupt 00132: if (this.interrupted) begin 00133: // Interrupted... 00134: if (this.executing == null) begin 00136: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV)) begin : void'(this.log.text("Internal Error: interrupted but not executing")); : this.log.end_msg(); : end : while (0); 00137: end else begin 00138: $display(" Executing interrupt action \"%s\".", 00139: this.executing.get_name()); 00140: end 00141: end else begin 00142: $display(" Waiting for action \"%s\" to be interrupted.", 00143: this.executing.get_name()); 00144: end 00145: end else begin 00146: if (this.executing == null) begin 00147: $display(" Waiting to execute an action..."); 00148: end else begin 00149: $display(" Executing action \"%s\".", 00150: this.executing.get_name()); 00151: end 00152: end 00153: endfunction: xactor_status 00154: 00155: 00156: task xvc_xactor::main(); 00157: fork 00158: super.main(); 00159: this.execute_actions(); 00160: this.execute_interruptions(); 00161: join_none 00162: endtask: main 00163: 00164: 00165: task xvc_xactor::execute_actions(); 00166: xvc_action action; 00167: 00168: while (1) begin 00169: // OK to be interrupted while not executing actions 00170: this.interrupted = 1; 00171: this.wait_if_stopped_or_empty(this.action_chan); 00172: this.action_chan.activate(action); 00173: this.interrupted = 0; 00174: 00175: this.executing = action; 00176: this.wait_if_interrupted(); 00177: 00178: this.execute_action(this.action_chan, "action"); 00179: end 00180: endtask: execute_actions 00181: 00182: 00183: task xvc_xactor::execute_interruptions(); 00184: xvc_action action; 00185: 00186: while (1) begin 00187: this.wait_if_stopped_or_empty(this.interrupt_chan); 00188: this.interrupt_chan.activate(action); 00189: 00190: this.interrupt = 1; 00191: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV)) begin 00192: void'(this.log.text("Requesting action interrupt...")); 00193: this.log.end_msg(); 00194: end 00195: wait (this.interrupted); 00196: 00197: if (this.suspended == null) this.suspended = idle; 00198: this.execute_action(this.interrupt_chan, "interrupt action"); 00199: if (this.suspended == idle) this.suspended = null; 00200: 00201: if (this.interrupt_chan.level() == 0) begin 00202: this.interrupt = 0; 00203: -> this.rte; 00204: end 00205: end 00206: endtask: execute_interruptions 00207: 00208: 00209: task xvc_xactor::wait_if_interrupted(); 00210: if (this.suspended != null) begin 00211: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::WARNING_SEV)) begin 00212: void'(this.log.text("Interrupt actions cannot be interrupted. Ignoring call to xvc_xactor::wait_if_interrupted()")); 00213: this.log.end_msg(); 00214: end 00215: return; 00216: end 00217: 00218: // Wait, not only for an interrupt action that is 00219: // requesting execution - but also if there is 00220: // one ready in the interrupt channel to resolve 00221: // race condition between the regular executor and 00222: // the interrupt executor. 00223: if (this.interrupt || this.interrupt_chan.level() > 0) begin 00224: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00225: void'(this.log.text($psprintf("Interrupting action \"%s\"...", 00226: this.executing.get_name()))); 00227: this.log.end_msg(); 00228: end 00229: this.suspended = this.executing; 00230: this.executing = null; 00231: this.interrupted = 1; 00232: 00233: @this.rte; 00234: this.executing = this.suspended; 00235: this.suspended = null; 00236: this.interrupted = 0; 00237: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00238: void'(this.log.text($psprintf("Resuming action \"%s\"...", 00239: this.executing.get_name()))); 00240: this.log.end_msg(); 00241: end 00242: end 00243: endtask: wait_if_interrupted 00244: 00245: 00246: task xvc_xactor::execute_action(xvc_action_channel chan, 00247: string descr); 00248: xvc_action action; 00249: int i; 00250: 00251: action = chan.active_slot(); 00252: 00253: if (this.trace.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00254: void'(this.trace.text($psprintf("Executing %s \"%s\"...", 00255: descr, action.get_name()))); 00256: this.trace.end_msg(); 00257: end 00258: 00259: this.executing = action; 00260: this.executing.display({descr,": "}); 00261: // Prepend any callback required by the action 00262: foreach (action.callbacks[i]) begin 00263: if (action.callbacks[i] != null) begin 00264: if (i >= this.xactors.size() || this.xactors[i] == null) begin 00267: : do : if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV)) begin : void'(this.log.text($psprintf("No xvc_xactor::xactors[%0d] to register callback from action \"%s\".", : i, action.get_name()))); : this.log.end_msg(); : end : while (0); 00268: continue; 00269: end 00270: this.xactors[i].prepend_callback(action.callbacks[i]); 00271: end 00272: end 00273: 00274: chan.start(); 00275: action.execute(this.exec_chan, this); 00276: chan.complete(); 00277: 00278: // De-register callbacks 00279: foreach (action.callbacks[i]) begin 00280: if (action.callbacks[i] != null) begin 00281: if (i >= this.xactors.size() || this.xactors[i] == null) continue; 00282: this.xactors[i].unregister_callback(action.callbacks[i]); 00283: end 00284: end 00285: 00286: this.executing = null; 00287: 00288: if (this.trace.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin 00289: void'(this.trace.text($psprintf("Completed %s \"%s\"...", 00290: descr, action.get_name()))); 00291: this.trace.end_msg(); 00292: end 00293: 00294: chan.remove(); 00295: endtask: execute_action 00296: 00297: 00298: function void xvc_xactor::save_rng_state(); 00299: endfunction: save_rng_state 00300: 00301: 00302: function void xvc_xactor::restore_rng_state(); 00303: endfunction: restore_rng_state