Expanded versions of source files are the output of the preprocessor. Lines subject to
conditional compilation are not shown and all compiler pragmas have been stripped. Macros
have been completely expanded.
00001: //
00002: // -------------------------------------------------------------
00003: // Copyright 2004-2008 Synopsys, Inc.
00004: // All Rights Reserved Worldwide
00005: //
00006: // Licensed under the Apache License, Version 2.0 (the
00007: // "License"); you may not use this file except in
00008: // compliance with the License. You may obtain a copy of
00009: // the License at
00010: //
00011: // http://www.apache.org/licenses/LICENSE-2.0
00012: //
00013: // Unless required by applicable law or agreed to in
00014: // writing, software distributed under the License is
00015: // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
00016: // CONDITIONS OF ANY KIND, either express or implied. See
00017: // the License for the specific language governing
00018: // permissions and limitations under the License.
00019: // -------------------------------------------------------------
00020: //
00021:
00022:
00023:
00024: function xvc_xactor::new(string name,
00025: string inst,
00026: int stream_id = -1,
00027: xvc_action_channel action_chan = null,
00028: xvc_action_channel interrupt_chan = null
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
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Attempting to add a NULL action"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: 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
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::WARNING_SEV, "", -1)) begin
: void'(this.log.text("Attempting to add already-known action"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: 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 = SOFT_RST);
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 or later
00121: // IEEE 1800-2005 compliant
00122: this.known_actions = '{};
00124: end
00125: endfunction: reset_xactor
00126:
00127:
00128: function void xvc_xactor::xactor_status(string prefix = "");
00129: super.xactor_status(prefix);
00130:
00131: if (this.interrupt) begin
00132: // Pending interrupt
00133: if (this.interrupted) begin
00134: // Interrupted...
00135: if (this.executing == null) begin
00136:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::ERROR_SEV, "", -1)) begin
: void'(this.log.text("Internal Error: interrupted but not executing"));
: this.log.end_msg();
: end
: /* synopsys translate_on */
: while (0);
00138: end else begin
00139: $display(" Executing interrupt action \"%s\".",
00140: this.executing.get_name());
00141: end
00142: end else begin
00143: $display(" Waiting for action \"%s\" to be interrupted.",
00144: this.executing.get_name());
00145: end
00146: end else begin
00147: if (this.executing == null) begin
00148: $display(" Waiting to execute an action...");
00149: end else begin
00150: $display(" Executing action \"%s\".",
00151: this.executing.get_name());
00152: end
00153: end
00154: endfunction: xactor_status
00155:
00156:
00157: task xvc_xactor::main();
00158: fork
00159: super.main();
00160: this.execute_actions();
00161: this.execute_interruptions();
00162: join_none
00163: endtask: main
00164:
00165:
00166: task xvc_xactor::execute_actions();
00167: xvc_action action;
00168:
00169: while (1) begin
00170: // OK to be interrupted while not executing actions
00171: this.interrupted = 1;
00172: this.wait_if_stopped_or_empty(this.action_chan);
00173: this.action_chan.activate(action);
00174: this.interrupted = 0;
00175:
00176: this.executing = action;
00177: this.wait_if_interrupted();
00178:
00179: this.execute_action(this.action_chan, "action");
00180: end
00181: endtask: execute_actions
00182:
00183:
00184: task xvc_xactor::execute_interruptions();
00185: xvc_action action;
00186:
00187: while (1) begin
00188: this.wait_if_stopped_or_empty(this.interrupt_chan);
00189: this.interrupt_chan.activate(action);
00190:
00191: this.interrupt = 1;
00192: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::DEBUG_SEV)) begin
00193: void'(this.log.text("Requesting action interrupt..."));
00194: this.log.end_msg();
00195: end
00196: wait (this.interrupted);
00197:
00198: if (this.suspended == null) this.suspended = idle;
00199: this.execute_action(this.interrupt_chan, "interrupt action");
00200: if (this.suspended == idle) this.suspended = null;
00201:
00202: if (this.interrupt_chan.level() == 0) begin
00203: this.interrupt = 0;
00204: -> this.rte;
00205: end
00206: end
00207: endtask: execute_interruptions
00208:
00209:
00210: task xvc_xactor::wait_if_interrupted();
00211: if (this.suspended != null) begin
00212: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::WARNING_SEV)) begin
00213: void'(this.log.text("Interrupt actions cannot be interrupted. Ignoring call to xvc_xactor::wait_if_interrupted()"));
00214: this.log.end_msg();
00215: end
00216: return;
00217: end
00218:
00219: // Wait, not only for an interrupt action that is
00220: // requesting execution - but also if there is
00221: // one ready in the interrupt channel to resolve
00222: // race condition between the regular executor and
00223: // the interrupt executor.
00224: if (this.interrupt || this.interrupt_chan.level() > 0) begin
00225: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin
00226: void'(this.log.text($psprintf("Interrupting action \"%s\"...",
00227: this.executing.get_name())));
00228: this.log.end_msg();
00229: end
00230: this.suspended = this.executing;
00231: this.executing = null;
00232: this.interrupted = 1;
00233:
00234: @this.rte;
00235: this.executing = this.suspended;
00236: this.suspended = null;
00237: this.interrupted = 0;
00238: if (this.log.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin
00239: void'(this.log.text($psprintf("Resuming action \"%s\"...",
00240: this.executing.get_name())));
00241: this.log.end_msg();
00242: end
00243: end
00244: endtask: wait_if_interrupted
00245:
00246:
00247: task xvc_xactor::execute_action(xvc_action_channel chan,
00248: string descr);
00249: xvc_action action;
00250: int i;
00251:
00252: action = chan.active_slot();
00253:
00254: if (this.trace.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin
00255: void'(this.trace.text($psprintf("Executing %s \"%s\"...",
00256: descr, action.get_name())));
00257: this.trace.end_msg();
00258: end
00259:
00260: this.executing = action;
00261: this.executing.display({descr,": "});
00262: // Prepend any callback required by the action
00263: foreach (action.callbacks[i]) begin
00264: if (action.callbacks[i] != null) begin
00265: if (i >= this.xactors.size() || this.xactors[i] == null) begin
00266:
: do
: /* synopsys translate_off */
: if (this.log.start_msg(vmm_log::FAILURE_TYP, vmm_log::FATAL_SEV, "", -1)) 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
: /* synopsys translate_on */
: while (0);
00269: continue;
00270: end
00271: this.xactors[i].prepend_callback(action.callbacks[i]);
00272: end
00273: end
00274:
00275: void'(chan.start());
00276: action.execute(this.exec_chan, this);
00277: void'(chan.complete());
00278:
00279: // De-register callbacks
00280: foreach (action.callbacks[i]) begin
00281: if (action.callbacks[i] != null) begin
00282: if (i >= this.xactors.size() || this.xactors[i] == null) continue;
00283: this.xactors[i].unregister_callback(action.callbacks[i]);
00284: end
00285: end
00286:
00287: this.executing = null;
00288:
00289: if (this.trace.start_msg(vmm_log::INTERNAL_TYP, vmm_log::TRACE_SEV)) begin
00290: void'(this.trace.text($psprintf("Completed %s \"%s\"...",
00291: descr, action.get_name())));
00292: this.trace.end_msg();
00293: end
00294:
00295: void'(chan.remove());
00296: endtask: execute_action
00297:
00298:
00299: function void xvc_xactor::save_rng_state();
00300: endfunction: save_rng_state
00301:
00302:
00303: function void xvc_xactor::restore_rng_state();
00304: endfunction: restore_rng_state