capaEvalFlag ←
SELECT PWCore.GetLayoutAtom[cell]
FROM
$Get, $GetAndFlatten, $GetLibrary => FALSE,
ENDCASE => NOT CheckForProperty[instance, cell, noStrayCapa];
SELECT cell.class
FROM
CoreClasses.recordCellClass => {
rct: CoreClasses.RecordCellType ← NARROW[cell.data];
InsertNonPublicWires[cell.public, rct.internal, flatCell, circuit, wireName, ignoreFlag, capaEvalFlag];
NextCellType[cell, target, flatCell, instance, parent, flatParent, circuit, wireName, ignoreFlag, capaEvalFlag, Flatten]
};
CoreClasses.transistorCellClass => {
directional: BOOLEAN ← CoreProperties.GetCellInstanceProp[instance, oneWay]#NIL OR CoreProperties.GetCellTypeProp[cell, oneWay]#NIL;
transistorLength: INT ← NARROW[CoreProperties.GetCellTypeProp[cell, CoreClasses.lengthProp], REF INT]^;
transistorWidth: INT ← NARROW[CoreProperties.GetCellTypeProp[cell, CoreClasses.widthProp], REF INT]^;
gateWire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[x:wireName, key: cell.public[ORD[CoreClasses.TransistorPort.gate]]].val];
ch1Wire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[x:wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch1]]].val];
ch2Wire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[x:wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch2]]].val];
tran: CoreClasses.Transistor ← NARROW[cell.data];
BuildFet[gateWire, ch1Wire, ch2Wire, tran.type, transistorLength, transistorWidth, directional, circuit];
};
ElectricalCoreClasses.capacitorCellClass => {
gndNode: Node ← Mint.NodeFromRope["public.Gnd", circuit];
n0Wire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[wireName, cell.public[0]].val];
n0Node: Node ← NARROW[RefTab.Fetch[circuit.nodeTable, n0Wire].val];
n1Wire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[wireName, cell.public[1]].val];
n1Node: Node ← NARROW[RefTab.Fetch[circuit.nodeTable, n1Wire].val];
capa: ElectricalCoreClasses.Capacitor ← NARROW[cell.data];
SELECT
TRUE
FROM
n0Node=gndNode => n1Node.cap ← n1Node.cap+capa.value;
n1Node=gndNode => n0Node.cap ← n0Node.cap+capa.value;
ENDCASE => IO.PutF[StdOut, "Capacitor between %g and %g discarded\n", IO.rope[Mint.RopeFromNode[n0Node, circuit]], IO.rope[Mint.RopeFromNode[n0Node, circuit]]];
};
ElectricalCoreClasses.signalGeneratorCellClass => {
nWire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[wireName, cell.public[0]].val];
nNode: Node ← NARROW[RefTab.Fetch[circuit.nodeTable, nWire].val];
sig: ElectricalCoreClasses.SignalGenerator ← NARROW[cell.data];
nNode.input ← TRUE;
SELECT sig.type
FROM
DC => nNode.history ← Schedule.CreateHistory[0.0, sig.onLevel*kilo];
RectWave => {
delay: ps ← sig.tDelay*kilo;
offLevel: mVolt ← sig.offLevel*kilo;
onLevel: mVolt ← sig.onLevel*kilo;
tRise: ps ← sig.tRise*kilo;
tFall: ps ← sig.tFall*kilo;
width: ps ← sig.width*kilo;
period: ps ← sig.period*kilo;
nNode.history ← Schedule.CreateHistory[0.0, offLevel];
THROUGH [0..3]
DO
nNode.history ← Schedule.AddToHistory[nNode.history, delay, offLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+tRise, onLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+width-tFall, onLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+width, offLevel];
delay ← delay+period;
ENDLOOP;
};
OneShot => {
delay: ps ← sig.tDelay*kilo;
offLevel: mVolt ← sig.offLevel*kilo;
onLevel: mVolt ← sig.onLevel*kilo;
tRise: ps ← sig.tRise*kilo;
tFall: ps ← sig.tFall*kilo;
width: ps ← sig.width*kilo;
nNode.history ← Schedule.CreateHistory[0.0, offLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay, offLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+tRise, onLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+width-tFall, onLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+width, offLevel];
};
Step => {
delay: ps ← sig.tDelay*kilo;
offLevel: mVolt ← sig.offLevel*kilo;
onLevel: mVolt ← sig.onLevel*kilo;
tRise: ps ← sig.tRise*kilo;
nNode.history ← Schedule.CreateHistory[0.0, offLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay, offLevel];
nNode.history ← Schedule.AddToHistory[nNode.history, delay+tRise, onLevel];
};
ENDCASE => ERROR;
};
ElectricalCoreClasses.probeCellClass => {
IF
NARROW[cell.data, ElectricalCoreClasses.Probe].type=Voltage
THEN {
nWire: CoreFlat.FlatWire ← NARROW[RefTab.Fetch[wireName, cell.public[0]].val];
nNode: Node ← NARROW[RefTab.Fetch[circuit.nodeTable, nWire].val];
nNode.watched ← TRUE;
}
ELSE IO.PutF[StdOut, "No current probes allowed\n"];
};
ElectricalCoreClasses.panelCellClass => {
panel: ElectricalCoreClasses.Panel ← NARROW[cell.data];
circuit.info.tStart ← panel.tMin;
circuit.info.tStop ← panel.tMax;
};
ENDCASE => {
IF cell.class.recast=NIL THEN IO.PutF[StdOut, "What is a %g ?\n", IO.rope[cell.class.name]]
ELSE NextCellType[cell, target, flatCell, instance, parent, flatParent, circuit, wireName, ignoreFlag, capaEvalFlag, Flatten]
};