use of gov.sandia.n2a.backend.internal.InstanceTemporaries in project n2a by frothga.
the class XyceBackend method generateNetlist.
public void generateNetlist(MNode job, Simulator simulator, BufferedWriter writer) throws Exception {
Population toplevel = (Population) simulator.wrapper.valuesObject[0];
XyceRenderer renderer = new XyceRenderer(simulator);
// Header
writer.append(toplevel.equations.name + "\n");
writer.append("\n");
writer.append("* seed: " + job.get("seed") + "\n");
writer.append(".tran 0 " + job.get("duration") + "\n");
MNode integrator = job.child("integrator");
if (integrator != null) {
String method = integrator.get();
if (!method.isEmpty()) {
writer.append(".options timeint method=" + method + "\n");
}
// TODO: add other integrator options
}
// Equations
for (Instance i : simulator) {
if (i == simulator.wrapper)
continue;
writer.append("\n");
writer.append("* " + i + "\n");
renderer.pi = i;
renderer.exceptions = null;
XyceBackendData bed = (XyceBackendData) i.equations.backendData;
if (bed.deviceSymbol != null) {
writer.append(bed.deviceSymbol.getDefinition(renderer));
}
InstanceTemporaries temp = new InstanceTemporaries(i, simulator, bed.internal);
for (final Variable v : i.equations.variables) {
// Compute variable v
// TODO: how to switch between multiple conditions that can be true during normal operation? IE: how to make Xyce code conditional?
// Perhaps gate each condition (through a transistor?) and sum them at a single node.
// e can be null
EquationEntry e = v.select(temp);
Symbol def = bed.equationSymbols.get(e);
if (def == null)
continue;
writer.append(def.getDefinition(renderer));
// Trace
class TraceFinder implements Visitor {
List<Operator> traces = new ArrayList<Operator>();
public boolean visit(Operator op) {
if (op instanceof Output) {
traces.add(((Output) op).operands[1]);
return false;
}
return true;
}
}
TraceFinder traceFinder = new TraceFinder();
e.expression.visit(traceFinder);
for (Operator trace : traceFinder.traces) {
// We don't know if contents is .func, expression or a node, so always wrap in braces.
writer.append(".print tran {");
if (trace instanceof AccessVariable) {
AccessVariable av = (AccessVariable) trace;
writer.append(renderer.change(av.reference));
} else // trace is an expression
{
if (// this trace wraps the entire equation
e.expression instanceof Output && ((Output) e.expression).operands[1] == trace) {
// simply print the LHS variable, similar to the AccessVariable case above
writer.append(renderer.change(v.reference));
} else {
// arbitrary expression
writer.append(renderer.change(trace));
}
}
// one .print line per variable
writer.append("}\n");
}
}
}
// Trailer
writer.append(".end\n");
}
use of gov.sandia.n2a.backend.internal.InstanceTemporaries in project n2a by frothga.
the class Delay method eval.
public Type eval(Instance context) {
Type tempValue = operands[0].eval(context);
Simulator simulator = Simulator.instance.get();
if (simulator == null)
return tempValue;
// Zero delay, which generally introduces one cycle of delay in an expression like: A = delay(B)
if (operands.length < 2)
return tempValue;
double value = ((Scalar) tempValue).value;
double delay = ((Scalar) operands[1].eval(context)).value;
// Unpack the main instance data, to access buffer.
Instance wrapped = ((InstanceTemporaries) context).wrapped;
DelayBuffer buffer = (DelayBuffer) wrapped.valuesObject[index];
if (buffer == null) {
wrapped.valuesObject[index] = buffer = new DelayBuffer();
if (operands.length > 2)
buffer.value = ((Scalar) operands[2].eval(context)).value;
else
buffer.value = 0;
}
buffer.step(simulator.currentEvent.t, delay, value);
return new Scalar(buffer.value);
}
use of gov.sandia.n2a.backend.internal.InstanceTemporaries in project n2a by frothga.
the class XyceBackend method generateNetlist.
public void generateNetlist(MNode job, Simulator simulator, FileWriter writer) throws Exception {
Population toplevel = (Population) simulator.wrapper.valuesObject[0];
XyceRenderer renderer = new XyceRenderer(simulator);
// Header
writer.append(toplevel.equations.name + "\n");
writer.append("\n");
writer.append("* seed: " + job.get("$metadata", "seed") + "\n");
writer.append(".tran 0 " + job.get("$metadata", "duration") + "\n");
// Equations
for (Instance i : simulator) {
if (i == simulator.wrapper)
continue;
writer.append("\n");
writer.append("* " + i + "\n");
renderer.pi = i;
renderer.exceptions = null;
XyceBackendData bed = (XyceBackendData) i.equations.backendData;
if (bed.deviceSymbol != null) {
writer.append(bed.deviceSymbol.getDefinition(renderer));
}
InstanceTemporaries temp = new InstanceTemporaries(i, simulator, false, bed.internal);
for (final Variable v : i.equations.variables) {
// Compute variable v
// TODO: how to switch between multiple conditions that can be true during normal operation? IE: how to make Xyce code conditional?
// Perhaps gate each condition (through a transistor?) and sum them at a single node.
// e can be null
EquationEntry e = v.select(temp);
Symbol def = bed.equationSymbols.get(e);
if (def == null)
continue;
writer.append(def.getDefinition(renderer));
// Trace
class TraceFinder extends Visitor {
List<Operator> traces = new ArrayList<Operator>();
public boolean visit(Operator op) {
if (op instanceof Output) {
traces.add(((Output) op).operands[0]);
return false;
}
return true;
}
}
TraceFinder traceFinder = new TraceFinder();
e.expression.visit(traceFinder);
for (Operator trace : traceFinder.traces) {
// We don't know if contents is .func, expression or a node, so always wrap in braces.
writer.append(".print tran {");
if (trace instanceof AccessVariable) {
AccessVariable av = (AccessVariable) trace;
writer.append(renderer.change(av.reference));
} else // trace is an expression
{
if (// this trace wraps the entire equation
e.expression instanceof Output && ((Output) e.expression).operands[0] == trace) {
// simply print the LHS variable, similar to the AccessVariable case above
writer.append(renderer.change(v.reference));
} else {
// arbitrary expression
writer.append(renderer.change(trace));
}
}
// one .print line per variable
writer.append("}\n");
}
}
}
// Trailer
writer.append(".end\n");
}
Aggregations