SpiceInputGenImpl.mesa
Christian LeCocq February 13, 1987 12:13:30 pm PST
DIRECTORY
Convert,
Core,
CoreFlat,
CoreOps,
CoreClasses,
HashTable,
ElectricalCoreClasses,
Rope,
SpiceOps,
TerminalIO,
TiogaFileOps;
SpiceInputGenImpl: CEDAR PROGRAM    
IMPORTS
Convert,
CoreFlat,
CoreOps,
CoreClasses,
HashTable,
ElectricalCoreClasses,
Rope,
TerminalIO,
TiogaFileOps
EXPORTS
SpiceOps
= BEGIN
s: TYPE = REAL;
ROPE: TYPE = Rope.ROPE;
TNode: TYPE = TiogaFileOps.Ref;
CellType: TYPE = Core.CellType;
FlatWire: TYPE = CoreFlat.FlatWire;
ConvData: TYPE = REF ConvDataRec;
ConvDataRec: TYPE = RECORD[
rootCell: Core.CellType,
rootNode: TNode,
wTable: HashTable.Table,
nextId: CARD ← 0,
initList: ROPE,
tranList: ROPE,
printList: ROPE
];
FlatCellProc: TYPE = PROC [cell: Core.CellType, target: CoreFlat.FlatCellTypeRec ← CoreFlat.allFlatCells, flatCell: CoreFlat.FlatCellTypeRec ← [], instance: CoreClasses.CellInstance ← NIL, parent: Core.CellType ← NIL, flatParent: CoreFlat.FlatCellTypeRec ← [], data: REF ANYNIL, wireName: HashTable.Table];
constants
lineLength: NAT ← 80;
sep: ROPE ← " ";
infinity: NATLAST[NAT];
femto: REAL ← 1e-15;
pico: REAL ← 1e-12;
nano: REAL ← 1e-9;
micro: REAL ← 1e-6;
mili: REAL ← 1e-3;
kilo: REAL ← 1e3;
mega: REAL ← 1e6;
giga: REAL ← 1e9;
tera: REAL ← 1e12;
gndName: PUBLIC ROPE ← "public.Gnd";
vddName: PUBLIC ROPE ← "public.Vdd";
pModel: PUBLIC ROPE ← "PMOS";
nModel: PUBLIC ROPE ← "NMOS";
diodeModel: PUBLIC ROPE ← "D";
Public Procs
WriteSpiceDeck: PUBLIC PROC [cellType: CellType, outputFile: ROPE ← NIL] = BEGIN
convData: ConvData ← NEW[ConvDataRec];
IF outputFile=NIL THEN IF CoreOps.GetCellTypeName[cellType]=NIL
THEN outputFile ← "///Temp/Spice/Simulation.spice"
ELSE outputFile ← Rope.Cat["///Temp/Spice/", CoreOps.GetCellTypeName[cellType], ".spice"];
convData.rootCell ← cellType;
convData.wTable ← HashTable.Create[equal: CoreFlat.FlatWireEqual, hash: CoreFlat.FlatWireHash];
convData.rootNode ← TiogaFileOps.CreateRoot[];
PutHeader[convData, outputFile];
NetFromCore[convData];
PutEnd[convData, outputFile];
END;
Print Procs
WriteInstance: PROC [convData: ConvData, rope: ROPE] ~ {
tNode: TNode ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
IF Rope.Length[rope]<lineLength THEN TiogaFileOps.SetContents[tNode, rope]
ELSE {
index, index2: INT;
UNTIL index2>lineLength DO
index ← index2;
index2 ← Rope.Index[rope, index+1, sep];
ENDLOOP;
TiogaFileOps.SetContents[tNode, Rope.Substr[rope, 0, index]];
WriteInstance[convData, Rope.Concat["+", Rope.Substr[rope, index+1]]];
};
};
WireId: PROC [convData: ConvData, wire: FlatWire] RETURNS [id: ROPE] ~ {
found: BOOL;
value: HashTable.Value;
[found, value] ← HashTable.Fetch[convData.wTable, wire];
IF found THEN RETURN [NARROW[value, ROPE]];
id ← NextInstanceId[convData];
[] ← HashTable.Insert[convData.wTable, wire, id];
Comment[convData, Rope.Cat[id, ": ", CoreFlat.WirePathRope[convData.rootCell, wire^]]];
};
NextInstanceId: PROC [convData: ConvData] RETURNS [id: ROPE] ~ {
convData.nextId ← convData.nextId+1;
id ← Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE];
id ← Rope.Concat[id, " "];
};
RealToRope: PROC [r: REAL, m: REAL ← 1.0] RETURNS [rope: ROPE] ~ {
c: REAL ← 1.0;
r ← r*m;
IF r=0.0 THEN RETURN["0 "];
FOR x: REALABS[r], x*1000.0 UNTIL x>=1.0 DO
c ← c/1000.0;
ENDLOOP;
FOR x: REALABS[r], x/1000.0 UNTIL x<1000.0 DO
c ← c*1000.0;
ENDLOOP;
rope ← Rope.Concat[Convert.RopeFromReal[r/c], SELECT c FROM
1e12 => "T ",
1e09 => "G ",
1e06 => "MEG ",
1e03 => "K ",
1e00 => " ",
1e-3 => "M ",
1e-6 => "U ",
1e-9 => "N ",
1e-12 => "P ",
1e-15 => "F ",
ENDCASE => ERROR]; -- Value outside of range...
};
Comment: PROC [convData: ConvData, comment: ROPE] ~ {
tNode: TNode ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
TiogaFileOps.SetContents[tNode, Rope.Concat["* ", comment]];
};
Resistor: PROC [convData: ConvData, n1, n2: FlatWire, value: REAL, tc1, tc2: REAL ← 0.0] ~ {
res: ROPE ← Rope.Concat[base: "R", rest: NextInstanceId[convData]];
res ← Rope.Cat[res, WireId[convData, n1], WireId[convData, n2]];
res ← Rope.Concat[res, RealToRope[value, kilo]];
IF tc1#0.0 OR tc2#0.0 THEN res ← Rope.Cat[res, " TC=", RealToRope[tc1], ",", RealToRope[tc2]];
WriteInstance[convData, res];
};
Capacitor: PROC [convData: ConvData, n1, n2: FlatWire, value: REAL, incond: REAL ← 0.0] ~ {
cap: ROPE ← Rope.Concat[base: "C", rest: NextInstanceId[convData]];
cap ← Rope.Cat[cap, WireId[convData, n1], WireId[convData, n2]];
cap ← Rope.Concat[cap, RealToRope[value, pico]];
IF incond#0.0 THEN cap ← Rope.Cat[cap, " IC=", RealToRope[incond]];
WriteInstance[convData, cap]
};
Inductor: PROC [convData: ConvData, n1, n2: FlatWire, value: REAL, incond: REAL ← 0.0] ~ {
ind: ROPE ← Rope.Concat[base: "L", rest: NextInstanceId[convData]];
ind ← Rope.Cat[ind, WireId[convData, n1], WireId[convData, n2]];
ind ← Rope.Concat[ind, RealToRope[value, micro]];
IF incond#0.0 THEN ind ← Rope.Cat[ind, " IC=", RealToRope[incond]];
WriteInstance[convData, ind]
};
CoupledInductors: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, l1, l2: REAL, k: REAL] ~ {
cind: ROPE ← Rope.Concat[base: "K", rest: NextInstanceId[convData]];
Inductor[convData, n0, n1, l1];
cind ← Rope.Cat[cind, "L", Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE], " "];
Inductor[convData, n2, n3, l2];
cind ← Rope.Cat[cind, "L", Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE], " "];
cind ← Rope.Concat[cind, RealToRope[k]];
WriteInstance[convData, cind]
};
LosslessLine: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, z0: REAL, td: REAL] ~ {
lline: ROPE ← Rope.Concat[base: "T", rest: NextInstanceId[convData]];
lline ← Rope.Cat[lline, WireId[convData, n0], WireId[convData, n1]];
lline ← Rope.Cat[lline, WireId[convData, n2], WireId[convData, n3]];
lline ← Rope.Cat[lline, "Z0=", RealToRope[z0, kilo], "TD=", RealToRope[td, nano]];
WriteInstance[convData, lline]
};
Vccs: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, value: REAL] ~ {
lsource: ROPE ← Rope.Concat[base: "G", rest: NextInstanceId[convData]];
lsource ← Rope.Cat[lsource, WireId[convData, n0], WireId[convData, n1]];
lsource ← Rope.Cat[lsource, WireId[convData, n2], WireId[convData, n3]];
lsource ← Rope.Concat[lsource, RealToRope[value]];
WriteInstance[convData, lsource]
};
Vcvs: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, value: REAL] ~ {
lsource: ROPE ← Rope.Concat[base: "E", rest: NextInstanceId[convData]];
lsource ← Rope.Cat[lsource, WireId[convData, n0], WireId[convData, n1]];
lsource ← Rope.Cat[lsource, WireId[convData, n2], WireId[convData, n3]];
lsource ← Rope.Concat[lsource, RealToRope[value]];
WriteInstance[convData, lsource]
};
Cccs: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, value: REAL] ~ {
lsource: ROPE ← Rope.Concat[base: "F", rest: NextInstanceId[convData]];
lsource ← Rope.Cat[lsource, WireId[convData, n0], WireId[convData, n1]];
VSource[convData, n2, n3];
lsource ← Rope.Cat[lsource, "V", Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE], " "];
lsource ← Rope.Concat[lsource, RealToRope[value]];
WriteInstance[convData, lsource]
};
Ccvs: PROC [convData: ConvData, n0, n1, n2, n3: FlatWire, value: REAL] ~ {
lsource: ROPE ← Rope.Concat[base: "H", rest: NextInstanceId[convData]];
lsource ← Rope.Cat[lsource, WireId[convData, n0], WireId[convData, n1]];
VSource[convData, n2, n3];
lsource ← Rope.Cat[lsource, "V", Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE], " "];
lsource ← Rope.Concat[lsource, RealToRope[value]];
WriteInstance[convData, lsource]
};
Diode: PROC [convData: ConvData, n1, n2: FlatWire, model: ROPE, area: REAL] ~ {
diode: ROPE ← Rope.Concat[base: "D", rest: NextInstanceId[convData]];
diode ← Rope.Cat[diode, WireId[convData, n1], WireId[convData, n2]];
diode ← Rope.Concat[diode, model];
diode ← Rope.Concat[diode, RealToRope[area, pico]];
WriteInstance[convData, diode]
};
VSource: PROC [convData: ConvData, n1, n2: FlatWire, dc: REAL ← 0.0] ~ {
vs: ROPE ← Rope.Concat[base: "V", rest: NextInstanceId[convData]];
vs ← Rope.Cat[vs, WireId[convData, n1], WireId[convData, n2]];
IF dc#0.0 THEN vs ← Rope.Cat[vs, " DC ", RealToRope[dc]];
WriteInstance[convData, vs]
};
ISource: PROC [convData: ConvData, n1, n2: FlatWire, ma: REAL ← 0.0] ~ {
is: ROPE ← Rope.Concat[base: "I", rest: NextInstanceId[convData]];
is ← Rope.Cat[is, WireId[convData, n1], WireId[convData, n2]];
IF ma#0.0 THEN is ← Rope.Cat[is, " DC ", RealToRope[ma, mili]];
WriteInstance[convData, is]
};
PulseVS: PROC [convData: ConvData, n1, n2: FlatWire, v1, v2, td, tr, tf, pw, per: REAL ← 0.0] ~ {
vs: ROPE ← Rope.Concat[base: "V", rest: NextInstanceId[convData]];
vs ← Rope.Cat[vs, WireId[convData, n1], WireId[convData, n2]];
vs ← Rope.Cat[vs, "PULSE(", RealToRope[v1], RealToRope[v2]];
vs ← Rope.Cat[vs, RealToRope[td, nano], RealToRope[tr, nano], RealToRope[tf, nano]];
vs ← Rope.Cat[vs, RealToRope[pw, nano], RealToRope[per, nano], ")"];
WriteInstance[convData, vs]
};
MOSFet: PROC [convData: ConvData, gate, drain, source, bulk: FlatWire, model: ROPE, l, w, ad, as: REAL] ~ {
mos: ROPE ← Rope.Concat[base: "M", rest: NextInstanceId[convData]];
mos ← Rope.Cat[mos, WireId[convData, drain], WireId[convData, gate], WireId[convData, source], WireId[convData, bulk]];
mos ← Rope.Concat[mos, model];
mos ← Rope.Cat[mos, " L=", RealToRope[l, micro], " W=", RealToRope[w, micro]];
IF ad#0.0 OR as#0.0 THEN mos ← Rope.Cat[mos, "AD=", RealToRope[ad, pico], " AS=", RealToRope[as, pico]];
WriteInstance[convData, mos]
};
PutHeader: PROC [convData: ConvData, outputFile: ROPE] ~ {
node: TNode;
vddWire, gndWire: FlatWire;
node0: ROPE ← "0 ";
TiogaFileOps.SetStyle[convData.rootNode, "Cedar"];
node ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
Comment[convData, CoreOps.GetCellTypeName[convData.rootCell]];
establish the power through the Circuit, and set Gnd to node # 0
vddWire ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[convData.rootCell, vddName]];
gndWire ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[convData.rootCell, gndName]];
[] ← HashTable.Insert[convData.wTable, gndWire, node0];
VSource[convData, vddWire, gndWire, 5.0];
};
PutEnd: PROC [convData: ConvData, outputFile: ROPE] ~ {
node: TNode;
IF convData.initList#NIL THEN {
node ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
TiogaFileOps.SetContents[node, Rope.Concat[".IC ", convData.initList]];
};
node ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
TiogaFileOps.SetContents[node, Rope.Concat[".PRINT TRAN ", convData.printList]];
node ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
TiogaFileOps.SetContents[node, Rope.Concat[".TRAN ", convData.tranList]];
node ← TiogaFileOps.InsertAsLastChild[convData.rootNode];
TiogaFileOps.SetContents[node, ".END"];
TiogaFileOps.Store[convData.rootNode, outputFile]
};
Input From Core
NextCellType: PROC [cell: Core.CellType, target: CoreFlat.FlatCellTypeRec, flatCell: CoreFlat.FlatCellTypeRec, instance: CoreClasses.CellInstance, parent: Core.CellType, flatParent: CoreFlat.FlatCellTypeRec, data: REF ANY, wireName: HashTable.Table, proc: FlatCellProc] = {
BindCellType: CoreFlat.UnboundFlatCellProc = {
BindPublicToActual: CoreOps.EachWirePairProc = {
PROC [actualWire, publicWire: Wire]
IF publicWire.size=0 THEN {
flatWire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[table: wireName, key: actualWire].value];
[] ← HashTable.Store[table: wireName, key: publicWire, value: flatWire];
};
};
IF CoreOps.VisitBinding[actual: IF instance=NIL OR instance.type#cell THEN previous.public ELSE instance.actual, public: cell.public, eachWirePair: BindPublicToActual] THEN ERROR;
proc[cell, target, flatCell, instance, parent, flatParent, data, wireName];
};
previous: Core.CellType ← cell;
CoreFlat.NextUnboundCellType[cell, target, flatCell, instance, parent, flatParent, data, BindCellType];
};
Flatten: FlatCellProc = {
convData: ConvData ← NARROW[data];
SELECT cell.class FROM
ElectricalCoreClasses.resistorCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1]].value];
res: ElectricalCoreClasses.Resistor ← NARROW[cell.data];
Resistor[convData, n0Wire, n1Wire, res.value];
};
ElectricalCoreClasses.inductorCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1]].value];
ind: ElectricalCoreClasses.Inductor ← NARROW[cell.data];
Inductor[convData, n0Wire, n1Wire, ind.value];
};
ElectricalCoreClasses.capacitorCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1]].value];
capa: ElectricalCoreClasses.Capacitor ← NARROW[cell.data];
Capacitor[convData, n0Wire, n1Wire, capa.value];
};
ElectricalCoreClasses.diodeCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1]].value];
diode: ElectricalCoreClasses.Diode ← NARROW[cell.data];
IF diode.type#Junction THEN TerminalIO.PutRope["***Diode model should be manually edited"];
Diode[convData, n0Wire, n1Wire, diodeModel, diode.area];
};
ElectricalCoreClasses.coupledIndCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][1]].value];
n2Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][0]].value];
n3Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][1]].value];
coupledInd: ElectricalCoreClasses.CoupledInd ← NARROW[cell.data];
CoupledInductors[convData, n0Wire, n1Wire, n2Wire, n3Wire, coupledInd.l1, coupledInd.l2, coupledInd.k];
};
ElectricalCoreClasses.losslessLineCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][1]].value];
n2Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][0]].value];
n3Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][1]].value];
losslessLine: ElectricalCoreClasses.LosslessLine ← NARROW[cell.data];
LosslessLine[convData, n0Wire, n1Wire, n2Wire, n3Wire, losslessLine.z0, losslessLine.td];
};
ElectricalCoreClasses.linearSourceCellClass => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0][1]].value];
n2Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][0]].value];
n3Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1][1]].value];
linearSource: ElectricalCoreClasses.LinearSource ← NARROW[cell.data];
SELECT linearSource.type FROM
VCCS => Vccs[convData, n0Wire, n1Wire, n2Wire, n3Wire, linearSource.value];
VCVS => Vcvs[convData, n0Wire, n1Wire, n2Wire, n3Wire, linearSource.value];
CCCS => Cccs[convData, n0Wire, n1Wire, n2Wire, n3Wire, linearSource.value];
ccvs => Ccvs[convData, n0Wire, n1Wire, n2Wire, n3Wire, linearSource.value];
ENDCASE => ERROR; -- a change in ElectricalCoreClasses ???
};
ElectricalCoreClasses.signalGeneratorCellClass => {
nWire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
gndWire: CoreFlat.FlatWire ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[convData.rootCell, gndName]];
sig: ElectricalCoreClasses.SignalGenerator ← NARROW[cell.data];
SELECT sig.type FROM
DC => VSource[convData, nWire, gndWire, sig.onLevel];
RectWave => PulseVS[convData, nWire, gndWire, sig.offLevel, sig.onLevel, sig.tDelay, sig.tRise, sig.tFall, sig.width-sig.tRise-sig.tFall, sig.period];
OneShot => PulseVS[convData, nWire, gndWire, sig.offLevel, sig.onLevel, sig.tDelay, sig.tRise, sig.tFall, sig.width-sig.tRise-sig.tFall, infinity];
Step => PulseVS[convData, nWire, gndWire, sig.offLevel, sig.onLevel, sig.tDelay, sig.tRise, sig.tFall, infinity, infinity];
ENDCASE => ERROR;
};
ElectricalCoreClasses.probeCellClass => {
SELECT NARROW[cell.data, ElectricalCoreClasses.Probe].type FROM
Voltage => {
nWire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
convData.printList ← Rope.Cat[convData.printList, " V(", WireId[convData, nWire], ")"];
};
Current => {
n0Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
n1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[1]].value];
VSource[convData, n0Wire, n1Wire];
convData.printList ← Rope.Cat[convData.printList, "I(V", Convert.RopeFromCard[from: convData.nextId, showRadix: FALSE], ")"];
};
ENDCASE => ERROR;
};
ElectricalCoreClasses.initCellClass => {
init: ElectricalCoreClasses.Init ← NARROW[cell.data];
SELECT init.type FROM
Voltage => {
nWire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[wireName, cell.public[0]].value];
convData.initList ← Rope.Cat[convData.initList, " V(", WireId[convData, nWire], ")=", RealToRope[init.value]];
};
Current => {
NYI
};
ENDCASE => ERROR;
};
ElectricalCoreClasses.panelCellClass => {
panel: ElectricalCoreClasses.Panel ← NARROW[cell.data];
convData.tranList ← Rope.Cat[RealToRope[panel.tStep, nano], RealToRope[panel.tMax, nano], RealToRope[panel.tMin, nano]];
};
CoreClasses.transistorCellClass => {
gateWire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.gate]]].value];
ch1Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch1]]].value];
ch2Wire: CoreFlat.FlatWire ← NARROW[HashTable.Fetch[table: wireName, key: cell.public[ORD[CoreClasses.TransistorPort.ch2]]].value];
tran: CoreClasses.Transistor ← NARROW[cell.data];
SELECT tran.type FROM
pE => {
vddWire: CoreFlat.FlatWire ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[convData.rootCell, vddName]];
MOSFet[convData, gateWire, ch1Wire, ch2Wire, vddWire, pModel, tran.length, tran.width, 0.0, 0.0]
};
nE => {
gndWire: CoreFlat.FlatWire ← NEW[CoreFlat.FlatWireRec ← CoreFlat.ParseWirePath[convData.rootCell, gndName]];
MOSFet[convData, gateWire, ch1Wire, ch2Wire, gndWire, nModel, tran.length, tran.width, 0.0, 0.0];
};
ENDCASE => ERROR;
};
CoreClasses.recordCellClass => {
MarkAtomicPublic: PROC[wire: Core.Wire] = {
[] ← HashTable.Store[table: publics, key: wire, value: $Public];
};
InsertInternal: PROC[wire: Core.Wire] = {
IF NOT HashTable.Fetch[table: publics, key: wire].found THEN {
InsertWire[wire, flatCell, wireName];
};
};
rct: CoreClasses.RecordCellType;
publics: HashTable.Table ← HashTable.Create[cell.public.size+1];
rct ← NARROW[cell.data];
CoreOps.VisitRootAtomics[root: cell.public, eachWire: MarkAtomicPublic];
CoreOps.VisitRootAtomics[root: rct.internal, eachWire: InsertInternal];
NextCellType[cell, target, flatCell, instance, parent, flatParent, data, wireName, Flatten]
};
ENDCASE => {
IF cell.class.recast=NIL THEN TerminalIO.PutRopes[" What is a ", cell.class.name, "?\n"]
ELSE NextCellType[cell, target, flatCell, instance, parent, flatParent, data, wireName, Flatten]
};
};
InsertWire: PROC [wire: Core.Wire, flatCell: CoreFlat.FlatCellTypeRec, wireName: HashTable.Table, wireRoot: CoreFlat.WireRoot ← internal] = {
flatWire: CoreFlat.FlatWire ← NEW[CoreFlat.FlatWireRec];
flatWire.flatCell ← flatCell;
flatWire.wireRoot ← wireRoot;
flatWire.wire ← wire;
[] ← HashTable.Store[table: wireName, key: wire, value: flatWire];
};
NetFromCore: PUBLIC PROC[convData: ConvData] = {
InsertPublic: PROC[wire: Core.Wire] = {
InsertWire[wire, CoreFlat.rootCellType, wireName, public];
};
wireName: HashTable.Table ← HashTable.Create[];
TerminalIO.PutRopes["\nConverting cell ", CoreOps.GetCellTypeName[convData.rootCell], "... "];
CoreOps.VisitRootAtomics[root: convData.rootCell.public, eachWire: InsertPublic];
Flatten[cell: convData.rootCell, data: convData, wireName: wireName];
TerminalIO.PutRope[" Finished\n"];
};
END.