CoreThymeImpl:
CEDAR
PROGRAM
IMPORTS Convert, CoreOps, CoreClasses, CoreProperties, HashTable, NewCoreClasses, Rope, SinixOps, Sisyph, spGlobals, TerminalIO, TiogaFileOps, ViewerTools
EXPORTS CoreThyme =
BEGIN OPEN CoreThyme;
TNode: TYPE = TiogaFileOps.Ref;
WireFilterProc: TYPE = PROC [wire: Wire] RETURNS [BOOL];
wId, cId, iId: INT ← 0; -- Used in naming unnamed wires, cells and instances
isPublic: ATOM ← CoreProperties.RegisterProperty[$CoreThymeIsPublic, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]];
pathNameProp: ATOM ← CoreProperties.RegisterProperty[$CoreThymePathName, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]];
probeWireProp: ATOM ← CoreProperties.RegisterProperty[$CoreThymeProbeWire, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]];
savedNameProp: ATOM ← CoreProperties.RegisterProperty[$CoreThymeSavedName, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]];
savedNameValidProp: ATOM ← CoreProperties.RegisterProperty[$CoreThymeSavedNameValid, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]];
Internal Procs
PutHeader:
PROC [outputFile:
ROPE, root: TNode] =
BEGIN
node: TNode;
TiogaFileOps.SetStyle[root, "Cedar"];
node ← TiogaFileOps.InsertAsLastChild[root];
TiogaFileOps.SetContents[node, Rope.Cat["-- ", outputFile]];
[] ← TiogaFileOps.InsertAsLastChild[root];
END;
PutTopLevelCircuit:
PROC [cellType: CellType, root: TNode] =
BEGIN
tNode: TNode ← TiogaFileOps.InsertAsLastChild[root];
tSubNode: TNode;
plotSpec, initSpec: ROPE;
resultList: LIST OF CellInstance;
thymePanelCT: CellType;
thymePanel: NewCoreClasses.ThymePanel;
IF cellType.class#CoreClasses.recordCellClass THEN ERROR;
TiogaFileOps.SetContents[tNode, "CIRCUIT[Lambda ← 1, TDegC ← 25] = {"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "Vdd: Node;"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "! /DATools/DATools6.1/Thyme/SignalGenerators"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "! /DATools/DATools6.1/Thyme/BSIM"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "powerSupply: voltage[Vdd, Gnd] = 5.0;"];
[resultList, thymePanelCT] ← PutRecordCellType[cellType, root, TRUE];
IF thymePanelCT=
NIL
THEN {TerminalIO.PutRope["** Error: Sorry, no ThymePanel in cell\n"]; RETURN};
thymePanel ← NARROW[thymePanelCT.data, NewCoreClasses.ThymePanel];
Put Init Specs
FOR l:
LIST
OF CellInstance ← resultList, l.rest
WHILE l#
NIL
DO
inst: CellInstance ← l.first;
instType: CellType ← RecastIcon[inst.type];
IF instType.class=NewCoreClasses.initCellClass
THEN {
init: NewCoreClasses.Init ← NARROW[instType.data];
pathName: ROPE ← NARROW[CoreProperties.GetCellInstanceProp[inst, pathNameProp]];
SELECT init.type
FROM
Voltage => initSpec ← Rope.Cat[
Rope.Cat["IC[", NewCoreClasses.RopeFromns[init.time]],
", Vdd← 5.0",
Rope.Cat[", ", pathName],
Rope.Cat["← ", Convert.RopeFromReal[init.value], "];"]];
Current => ERROR; -- No Init Current for the moment
ENDCASE => ERROR;
tNode ← TiogaFileOps.InsertAsLastChild[root];
TiogaFileOps.SetContents[tNode, initSpec];
};
ENDLOOP;
Put Plot Specs
tNode ← TiogaFileOps.InsertAsLastChild[root];
plotSpec ← Rope.Cat[
Rope.Cat["Plot[\"", thymePanel.title, "\", "],
Rope.Cat[":", NewCoreClasses.RopeFromns[thymePanel.tScale], ", "],
Rope.Cat[Convert.RopeFromReal[thymePanel.yMin], ", "],
Rope.Cat[Convert.RopeFromReal[thymePanel.yMax], ", "],
Rope.Cat["powerSupply^: ", NewCoreClasses.RopeFrommA[thymePanel.iScale]]];
FOR l:
LIST
OF CellInstance ← resultList, l.rest
WHILE l#
NIL
DO
inst: CellInstance ← l.first;
instType: CellType ← RecastIcon[inst.type];
IF instType.class=NewCoreClasses.probeCellClass
THEN {
probe: NewCoreClasses.Probe ← NARROW[instType.data];
pathName: ROPE ← NARROW[CoreProperties.GetCellInstanceProp[inst, pathNameProp]];
SELECT probe.type
FROM
Voltage => plotSpec ← Rope.Cat[plotSpec, ", ", pathName, ": ", Convert.RopeFromReal[probe.scale]];
Current => plotSpec ← Rope.Cat[plotSpec, ", ", pathName, "^: ", NewCoreClasses.RopeFrommA[probe.scale]];
ENDCASE => ERROR;
};
ENDLOOP;
plotSpec ← Rope.Cat[plotSpec, "];"];
TiogaFileOps.SetContents[tNode, plotSpec];
Put Run Specs
tNode ← TiogaFileOps.InsertAsLastChild[root];
TiogaFileOps.SetContents[tNode, Rope.Cat["Run[",
Rope.Cat["tMin ← ", NewCoreClasses.RopeFromns[thymePanel.tMin], ", "],
Rope.Cat["tMax ← ", NewCoreClasses.RopeFromns[thymePanel.tMax], "];"]
]];
END;
RestoreSavedNames:
PROC [cellType: CellType] =
BEGIN
IF CoreProperties.GetCellTypeProp[cellType, savedNameValidProp]#
NIL
THEN {
oName: ROPE ← NARROW[CoreProperties.GetCellTypeProp[cellType, savedNameProp]];
[] ← CoreOps.SetCellTypeName[cellType, oName];
CoreProperties.PutCellTypeProp[cellType, savedNameProp, NIL];
CoreProperties.PutCellTypeProp[cellType, savedNameValidProp, NIL];
}
ELSE RETURN;
IF cellType.class=CoreClasses.recordCellClass
THEN {
recordCT: CoreClasses.RecordCellType ← NARROW[cellType.data];
RestoreWireName: CoreOps.EachWireProc = {
IF CoreProperties.GetWireProp[wire, savedNameValidProp]#
NIL
THEN {
oName: ROPE ← NARROW[CoreProperties.GetWireProp[wire, savedNameProp]];
[] ← CoreOps.SetShortWireName[wire, oName];
CoreProperties.PutWireProp[wire, savedNameProp, NIL];
CoreProperties.PutWireProp[wire, savedNameValidProp, NIL];
};
};
[] ← CoreOps.VisitWire[recordCT.internal, RestoreWireName];
CoreOps.FlushNameCaches[recordCT.internal];
CoreOps.FlushNameCaches[cellType.public];
FOR i:
NAT
IN [0..recordCT.size)
DO
inst: CellInstance ← recordCT.instances[i];
instType: CellType ← RecastIcon[inst.type];
IF CoreProperties.GetCellInstanceProp[inst, savedNameValidProp]#
NIL
THEN {
oName: ROPE ← NARROW[CoreProperties.GetCellInstanceProp[inst, savedNameProp]];
[] ← CoreClasses.SetCellInstanceName[inst, oName];
CoreProperties.PutCellInstanceProp[inst, savedNameProp, NIL];
CoreProperties.PutCellInstanceProp[inst, savedNameValidProp, NIL];
};
RestoreSavedNames[instType];
ENDLOOP;
};
END;
WireToAtomicWires:
PROC [wire: Wire, unique:
BOOL ←
TRUE]
RETURNS [wires: Wires] =
BEGIN
AddToWires:
PROC [subWire: Wire] = {
IF unique
THEN
FOR l: Wires ← wires, l.rest
WHILE l#
NIL
DO
IF l.first=subWire THEN RETURN;
ENDLOOP;
wires ← CONS[subWire, wires];
};
wires ← NIL;
IF wire.size=0 THEN AddToWires[wire] ELSE CoreOps.VisitRootAtomics[wire, AddToWires];
wires ← CoreOps.Reverse[wires]
END;
Filter:
PROC [in: Wires, filter: WireFilterProc]
RETURNS [out: Wires] =
BEGIN
out ← NIL;
FOR l: Wires ← in, l.rest
WHILE l#
NIL
DO
IF ~filter[l.first] THEN out ← CONS[l.first, out]
ENDLOOP;
out ← CoreOps.Reverse[out];
END;
IsPublic: WireFilterProc =
BEGIN
RETURN [CoreProperties.GetWireProp[wire, isPublic]#NIL]
END;
IsVddOrGnd: WireFilterProc =
BEGIN
name: ROPE ← CoreOps.GetShortWireName[wire];
RETURN [Rope.Equal[name, "Vdd"] OR Rope.Equal[name, "Gnd"]];
END;
WiresToRope:
PROC [root: Wire, wires: Wires]
RETURNS [rope:
ROPE] =
BEGIN
separator: ROPE ← ", ";
rope ← NIL;
FOR l: Wires ← wires, l.rest
WHILE l#
NIL
DO
rope ← Rope.Cat[rope, separator, CoreOps.GetFullWireName[root, l.first]]
ENDLOOP;
IF rope#NIL THEN rope ← Rope.Substr[rope, Rope.Length[separator], Rope.Length[rope]];
rope ← Rope.Translate[base: rope, translator: NameTranslator];
END;
ActualsToRope:
PROC [public, internal: Wire, wires: Wires, topLevel:
BOOL]
RETURNS [rope:
ROPE] =
BEGIN
separator: ROPE ← ", ";
rope ← NIL;
FOR l: Wires ← wires, l.rest
WHILE l#
NIL
DO
rope ← Rope.Cat[rope, separator, CoreOps.GetFullWireName[IF IsPublic[l.first]AND~topLevel THEN public ELSE internal, l.first]]
ENDLOOP;
IF rope#NIL THEN rope ← Rope.Substr[rope, Rope.Length[separator], Rope.Length[rope]];
rope ← Rope.Translate[base: rope, translator: NameTranslator];
END;
NameTranslator: Rope.TranslatorType =
BEGIN
SELECT old
FROM
'* => new ← 'X;
'. => new ← 'x;
ENDCASE => new ← old;
END;
EnsureWireName:
PROC [wire: Wire]
RETURNS [name:
ROPE] =
BEGIN
name ← CoreOps.GetShortWireName[wire];
IF CoreProperties.GetWireProp[wire, savedNameValidProp]#NIL THEN RETURN;
CoreProperties.PutWireProp[wire, savedNameProp, name];
CoreProperties.PutWireProp[wire, savedNameValidProp, savedNameValidProp];
IF name=
NIL
THEN {name ← Rope.Cat["Node", Convert.RopeFromInt[wId]]; wId ← wId+1}
ELSE name ← Rope.Translate[base: name, translator: NameTranslator];
[] ← CoreOps.SetShortWireName[wire, name];
END;
EnsureCellTypeName:
PROC [cellType: CellType]
RETURNS [name:
ROPE] =
BEGIN
name ← CoreOps.GetCellTypeName[cellType];
IF CoreProperties.GetCellTypeProp[cellType, savedNameValidProp]#NIL THEN RETURN;
CoreProperties.PutCellTypeProp[cellType, savedNameProp, name];
CoreProperties.PutCellTypeProp[cellType, savedNameValidProp, savedNameValidProp];
IF name=
NIL
THEN name ← Rope.Cat["Cell", Convert.RopeFromInt[cId]]
ELSE name ← Rope.Cat[Rope.Translate[base: name, translator: NameTranslator], Convert.RopeFromInt[cId]];
cId ← cId+1;
[] ← CoreOps.SetCellTypeName[cellType, name];
END;
EnsureInstName:
PROC [inst: CellInstance]
RETURNS [name:
ROPE] =
BEGIN
name ← CoreClasses.GetCellInstanceName[inst];
IF CoreProperties.GetCellInstanceProp[inst, savedNameValidProp]#NIL THEN RETURN;
CoreProperties.PutCellInstanceProp[inst, savedNameProp, name];
CoreProperties.PutCellInstanceProp[inst, savedNameValidProp, savedNameValidProp];
IF name=
NIL
THEN {name ← Rope.Cat["Inst", Convert.RopeFromInt[iId]]; iId ← iId+1}
ELSE name ← Rope.Translate[base: name, translator: NameTranslator];
[] ← CoreClasses.SetCellInstanceName[inst, name];
END;
RecastIcon:
PROC [ct: CellType]
RETURNS [result: CellType] =
BEGIN
result ← ct;
WHILE SinixOps.IsIcon[Sisyph.mode.decoration, result]
DO
result ← CoreOps.Recast[result];
ENDLOOP;
END;
Root is tioga node into which the recordCell definition will be inserted as a child
PutRecordCellType:
PROC [cellType: CellType, root: TNode, topLevel:
BOOL]
RETURNS [resultList:
LIST
OF CellInstance ←
NIL, thymePanel: CellType ←
NIL] =
BEGIN
tNode, subTNode: TNode;
tNodeContents, subTNodeContents: ROPE;
recordCT: CoreClasses.RecordCellType ← NARROW[cellType.data];
subCellTypeTab: HashTable.Table ← HashTable.Create[];
cellTypeName: ROPE ← EnsureCellTypeName[cellType];
EnsureInternalNames: CoreOps.EachWireProc = {
IF wire#recordCT.internal THEN [] ← EnsureWireName[wire]
};
MarkPublicWire: CoreOps.EachWireProc = {
[] ← CoreProperties.PutWireProp[wire, isPublic, isPublic]
};
Ensure names on internal, mark public, and delete fullname caches
[] ← CoreOps.VisitWire[recordCT.internal, EnsureInternalNames];
[] ← CoreOps.VisitWire[cellType.public, MarkPublicWire];
CoreOps.FlushNameCaches[recordCT.internal];
CoreOps.FlushNameCaches[cellType.public];
Put circuit header if needed
tNode ← TiogaFileOps.InsertAsLastChild[root];
IF ~topLevel
THEN {
tNodeContents ← Rope.Cat[
cellTypeName,
": CIRCUIT[",
WiresToRope[cellType.public, WireToAtomicWires[cellType.public]],
"] = {"
];
TiogaFileOps.SetContents[tNode, tNodeContents];
};
If top-level then put internal nodes except Vdd&Gnd else put internal minus public
IF topLevel
THEN subTNodeContents ← WiresToRope[recordCT.internal, Filter[WireToAtomicWires[recordCT.internal], IsVddOrGnd]]
ELSE subTNodeContents ← WiresToRope[recordCT.internal, Filter[WireToAtomicWires[recordCT.internal], IsPublic]];
IF subTNodeContents#
NIL
AND ~Rope.Equal[subTNodeContents, ""]
THEN {
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, Rope.Cat[subTNodeContents, ": Node;"]]
};
Now put the instances
FOR i:
NAT
IN [0..recordCT.size)
DO
inst: CellInstance ← recordCT.instances[i];
instType: CellType ← RecastIcon[inst.type];
SELECT instType.class
FROM
CoreClasses.recordCellClass => {
instName: ROPE ← EnsureInstName[inst];
found: BOOL;
value: HashTable.Value;
subCellTypeResultList: LIST OF CellInstance;
Put the definition if it isn't there already
[found, value] ← HashTable.Fetch[subCellTypeTab, instType];
IF found
THEN subCellTypeResultList ← NARROW[value, LIST OF CellInstance]
ELSE {
subCellTypeResultList ← PutRecordCellType[instType, tNode, FALSE].resultList;
[] ← HashTable.Insert[subCellTypeTab, instType, subCellTypeResultList]};
Put the instance
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
subTNodeContents ← Rope.Cat[
Rope.Cat[instName, ": ", EnsureCellTypeName[instType]],
"[",
ActualsToRope[cellType.public, recordCT.internal, WireToAtomicWires[inst.actual, FALSE], topLevel],
"];"];
TiogaFileOps.SetContents[subTNode, subTNodeContents];
Put the results in subCellTypeResultList onto resultList
FOR l:
LIST
OF CellInstance ← subCellTypeResultList, l.rest
WHILE l#
NIL
DO
subCellInst: CellInstance ← CopyCellInstance[l.first];
pathName: ROPE ← NARROW[CoreProperties.GetCellInstanceProp[subCellInst, pathNameProp]];
voltageProbeOnPublicWire: BOOL ← FALSE;
subCellInstType: CellType ← RecastIcon[subCellInst.type];
Compute the new path name if its a voltage probe on a public wire; this new path name will be the path name of the actual
IF subCellInstType.class=NewCoreClasses.probeCellClass
THEN {
probe: NewCoreClasses.Probe ← NARROW[subCellInstType.data];
IF probe.type=Voltage
THEN {
probeWire: Wire ← NARROW[CoreProperties.GetCellInstanceProp[subCellInst, probeWireProp]];
ForEachBinding: CoreOps.EachWirePairProc = {
IF publicWire=probeWire
THEN {
voltageProbeOnPublicWire ← TRUE;
pathName ← WiresToRope[recordCT.internal, WireToAtomicWires[actualWire]];
CoreProperties.PutCellInstanceProp[subCellInst, probeWireProp, actualWire];
};
};
[] ← CoreOps.VisitBinding[inst.actual, instType.public, ForEachBinding]
};
};
IF ~voltageProbeOnPublicWire THEN pathName ← Rope.Cat[instName, "/", pathName];
[] ← CoreProperties.PutCellInstanceProp[subCellInst, pathNameProp, pathName];
resultList ← CONS[subCellInst, resultList];
ENDLOOP;
};
CoreClasses.transistorCellClass =>
PutTransistorInstance[recordCT.internal, inst, instType, tNode];
NewCoreClasses.resistorCellClass =>
PutResistorInstance[recordCT.internal, inst, instType, tNode];
NewCoreClasses.inductorCellClass =>
PutInductorInstance[recordCT.internal, inst, instType, tNode];
NewCoreClasses.capacitorCellClass =>
PutCapacitorInstance[recordCT.internal, inst, instType, tNode];
NewCoreClasses.signalGeneratorCellClass =>
PutSignalGeneratorInstance[recordCT.internal, inst, instType, tNode];
NewCoreClasses.probeCellClass => {
probe: NewCoreClasses.Probe ← NARROW[instType.data];
SELECT probe.type
FROM
Voltage => {
[] ← CoreProperties.PutCellInstanceProp[inst, pathNameProp, WiresToRope[recordCT.internal, WireToAtomicWires[inst.actual]]];
[] ← CoreProperties.PutCellInstanceProp[inst, probeWireProp, inst.actual.elements[0]];
};
Current => {
useResistor: BOOL ← probe.resistance>0.001;
instName: ROPE ← EnsureInstName[inst];
[] ← CoreProperties.PutCellInstanceProp[inst, pathNameProp, instName];
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
subTNodeContents ← Rope.Cat[
Rope.Cat[instName, IF useResistor THEN ": Resistor[" ELSE ": Voltage["],
ActualsToRope[cellType.public, recordCT.internal, WireToAtomicWires[inst.actual, FALSE], topLevel],
"] = ",
IF useResistor THEN NewCoreClasses.RopeFromKOhms[probe.resistance] ELSE NewCoreClasses.RopeFromVolts[0.0],
";"];
TiogaFileOps.SetContents[subTNode, subTNodeContents];
};
ENDCASE => ERROR;
resultList ← CONS[inst, resultList];
};
NewCoreClasses.initCellClass => {
init: NewCoreClasses.Init ← NARROW[instType.data];
SELECT init.type
FROM
Voltage => [] ← CoreProperties.PutCellInstanceProp[inst, pathNameProp, WiresToRope[recordCT.internal, WireToAtomicWires[inst.actual]]];
Current => ERROR;
ENDCASE => ERROR;
resultList ← CONS[inst, resultList];
};
NewCoreClasses.thymePanelCellClass => thymePanel ← instType;
ENDCASE => ERROR;
ENDLOOP;
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, "};"];
END;
PutTransistorInstance:
PROC [rootWire: Wire, inst: CellInstance, instType: CellType, rootTNode: TNode] =
BEGIN
tNode: TNode;
tNodeContents: ROPE;
transistor: CoreClasses.Transistor ← NARROW[instType.data];
instName: ROPE ← EnsureInstName[inst];
tNode ← TiogaFileOps.InsertAsLastChild[rootTNode];
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": "],
SELECT transistor.type
FROM
nE => "ETran",
pE => "CTran"
ENDCASE => ERROR,
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], " | "],
Rope.Cat["L ← ", Convert.RopeFromInt[transistor.length], ", "],
Rope.Cat["W ← ", Convert.RopeFromInt[transistor.width], ", sdExtend ← 6];"]
];
TiogaFileOps.SetContents[tNode, tNodeContents];
END;
PutResistorInstance:
PROC [rootWire: Wire, inst: CellInstance, instType: CellType, rootTNode: TNode] =
BEGIN
tNode: TNode;
tNodeContents: ROPE;
resistor: NewCoreClasses.Resistor ← NARROW[instType.data];
instName: ROPE ← EnsureInstName[inst];
tNode ← TiogaFileOps.InsertAsLastChild[rootTNode];
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": Resistor"],
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], "] = "],
Rope.Cat[NewCoreClasses.RopeFromKOhms[resistor.value], ";"]
];
TiogaFileOps.SetContents[tNode, tNodeContents];
END;
PutInductorInstance:
PROC [rootWire: Wire, inst: CellInstance, instType: CellType, rootTNode: TNode] =
BEGIN
tNode: TNode;
tNodeContents: ROPE;
inductor: NewCoreClasses.Inductor ← NARROW[instType.data];
instName: ROPE ← EnsureInstName[inst];
tNode ← TiogaFileOps.InsertAsLastChild[rootTNode];
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": Inductor"],
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], "] = "],
Rope.Cat[NewCoreClasses.RopeFromuH[inductor.value], ";"]
];
TiogaFileOps.SetContents[tNode, tNodeContents];
END;
PutCapacitorInstance:
PROC [rootWire: Wire, inst: CellInstance, instType: CellType, rootTNode: TNode] =
BEGIN
tNode: TNode;
tNodeContents: ROPE;
capacitor: NewCoreClasses.Capacitor ← NARROW[instType.data];
instName: ROPE ← EnsureInstName[inst];
tNode ← TiogaFileOps.InsertAsLastChild[rootTNode];
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": Capacitor"],
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], "] = "],
Rope.Cat[NewCoreClasses.RopeFrompF[capacitor.value], ";"]
];
TiogaFileOps.SetContents[tNode, tNodeContents];
END;
PutSignalGeneratorInstance:
PROC [rootWire: Wire, inst: CellInstance, instType: CellType, rootTNode: TNode] =
BEGIN
tNode: TNode;
tNodeContents: ROPE;
signalGenerator: NewCoreClasses.SignalGenerator ← NARROW[instType.data];
instName: ROPE ← EnsureInstName[inst];
tNode ← TiogaFileOps.InsertAsLastChild[rootTNode];
SELECT signalGenerator.type
FROM
RectWave => {
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": RectWave"],
Rope.Cat[
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], " | "],
Rope.Cat["OnLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.onLevel], ", "],
Rope.Cat["OffLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.offLevel], ", "],
Rope.Cat["period ← ", NewCoreClasses.RopeFromns[signalGenerator.period], ", "],
Rope.Cat["width ← ", NewCoreClasses.RopeFromns[signalGenerator.width], ", "]],
Rope.Cat[
Rope.Cat["tRise ← ", NewCoreClasses.RopeFromns[signalGenerator.tRise], ", "],
Rope.Cat["tFall ← ", NewCoreClasses.RopeFromns[signalGenerator.tFall], ", "],
Rope.Cat["tDelay ← ", NewCoreClasses.RopeFromns[signalGenerator.tDelay], "];"]]
];
};
OneShot => {
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": OneShot"],
Rope.Cat[
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], " | "],
Rope.Cat["OnLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.onLevel], ", "],
Rope.Cat["OffLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.offLevel], ", "],
Rope.Cat["width ← ", NewCoreClasses.RopeFromns[signalGenerator.width], ", "]],
Rope.Cat[
Rope.Cat["tRise ← ", NewCoreClasses.RopeFromns[signalGenerator.tRise], ", "],
Rope.Cat["tFall ← ", NewCoreClasses.RopeFromns[signalGenerator.tFall], ", "],
Rope.Cat["tDelay ← ", NewCoreClasses.RopeFromns[signalGenerator.tDelay], "];"]]
];
};
Step => {
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": Step"],
Rope.Cat[
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], " | "],
Rope.Cat["OnLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.onLevel], ", "],
Rope.Cat["OffLevel ← ", NewCoreClasses.RopeFromVolts[signalGenerator.offLevel], ", "]],
Rope.Cat[
Rope.Cat["tRise ← ", NewCoreClasses.RopeFromns[signalGenerator.tRise], ", "],
Rope.Cat["tDelay ← ", NewCoreClasses.RopeFromns[signalGenerator.tDelay], "];"]]
];
};
DC => {
tNodeContents ← Rope.Cat[
Rope.Cat[instName, ": Voltage"],
Rope.Cat["[", WiresToRope[rootWire, WireToAtomicWires[inst.actual]], ", Gnd] = "],
Rope.Cat[NewCoreClasses.RopeFromVolts[signalGenerator.onLevel], ";"]
];
};
ENDCASE => ERROR;
TiogaFileOps.SetContents[tNode, tNodeContents];
END;
CopyCellInstance:
PROC [inst: CellInstance]
RETURNS [copy: CellInstance] =
BEGIN
ForEachProp:
PROC [a:
ATOM, v:
REF
ANY] = {
copy.properties ← CoreProperties.PutProp[copy.properties, a, v]
};
copy ← NEW [CoreClasses.CellInstanceRec];
copy.actual ← inst.actual;
copy.type ← inst.type;
copy.properties ← NIL;
CoreProperties.Enumerate[inst.properties, ForEachProp]
END;
END.