DIRECTORY CommandTool, Convert, CoreOps, CoreClasses, CoreProperties, CoreThyme, HashTable, NewCoreClasses, Rope, SinixOps, Sisyph, spGlobals, TerminalIO, TiogaFileOps, ViewerTools; 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]]]; CreateThymeViewer: PUBLIC PROC [wDir: ROPE] RETURNS [handle: ThymeHandle] = BEGIN handle _ spGlobals.MakeThymeViewers[wDir]; END; SetWorkingDirectory: PUBLIC PROC [wDir: ROPE, handle: ThymeHandle] = BEGIN spGlobals.SetWorkingDirectory[wDir, handle]; END; Translate: PUBLIC PROC [cellType: CellType, outputFile: ROPE] = BEGIN root: TNode; wId _ 0; cId _ 0; iId _ 0; root _ TiogaFileOps.CreateRoot[]; PutHeader[outputFile, root]; PutTopLevelCircuit[cellType, root]; RestoreSavedNames[cellType]; TiogaFileOps.Store[root, outputFile] END; Simulate: PUBLIC PROC [inputFile: ROPE, handle: ThymeHandle] = BEGIN ViewerTools.SetContents[handle.input, inputFile]; spGlobals.NormalRun[handle]; END; 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.WriteRope["** Error: Sorry, no ThymePanel in cell\n"]; RETURN}; thymePanel _ NARROW[thymePanelCT.data, NewCoreClasses.ThymePanel]; 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; 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]; 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; 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] }; [] _ CoreOps.VisitWire[recordCT.internal, EnsureInternalNames]; [] _ CoreOps.VisitWire[cellType.public, MarkPublicWire]; CoreOps.FlushNameCaches[recordCT.internal]; CoreOps.FlushNameCaches[cellType.public]; tNode _ TiogaFileOps.InsertAsLastChild[root]; IF ~topLevel THEN { tNodeContents _ Rope.Cat[ cellTypeName, ": CIRCUIT[", WiresToRope[cellType.public, WireToAtomicWires[cellType.public]], "] = {" ]; TiogaFileOps.SetContents[tNode, tNodeContents]; }; 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;"]] }; 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; [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]}; 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]; 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]; 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. CoreThymeImpl.mesa Written by: Pradeep Sindhu March 27, 1986 3:52:07 pm PST Last Edited by: Bertrand Serlet October 20, 1986 8:53:19 pm PDT Pradeep Sindhu December 8, 1986 11:12:44 pm PST Christian Jacobi, June 11, 1986 4:01:24 pm PDT The implementation is relatively straightforward except for the following point. The translation from Core to Thyme must be done in a way that the Core is not modified. Unfortunately, we need to at least modify names of wires, celltypes, and instances because Core names are not understood by Thyme. Furthermore, this name modification must be done in place (at least for wires) because we want to use Core primitives like GetFullWireNames when naming nodes. The way we handle this problem is to keep the old name around whenever we modify a name, and then to restore the old name after the translation from Core to Thyme is complete. The old name is kept in the property savedNameProp. The procedure that does the name fixup after translation is RestoreSavedNames. The reason we need the savedNameValidProp property is to discriminate between the cases savedNameProp=NIL because the property hasn't yet been put there and savedNameProp=NIL because the savedName is NIL. Public Procs Internal Procs Put Init Specs Put Plot Specs Put Run Specs Root is tioga node into which the recordCell definition will be inserted as a child Ensure names on internal, mark public, and delete fullname caches Put circuit header if needed If top-level then put internal nodes except Vdd&Gnd else put internal minus public Now put the instances Put the definition if it isn't there already Put the instance Put the results in subCellTypeResultList onto resultList 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 Κ¬˜™J™8Icode™™/K™/K™.—K™—šΟk ˜ Kšœ«˜«K˜—šΡbln œœœ˜ Jšœ“˜šJšœ ˜Jšœœ ˜J˜Jšœœ˜Jš œœœœœ˜8J˜JšœœΟc4˜LJšœ œ‡˜•Jšœœ‡˜™Jšœœˆ˜›Jšœœˆ˜›Jšœœ˜₯J˜—Icommentš œ Οe œh œ/  œ8  œ"™Κhead™ š Οnœœœœœ˜QJšœ*˜*Jšœ˜—J˜š ‘œœœœ˜JJšœ,˜,Jšœ˜—J˜J˜š ‘ œœœ"œ˜EJšœ ˜ J˜Jšœ˜Jšœ!˜!J˜J˜#Jšœ˜Jšœ$˜$Jšœ˜—J˜J˜š‘œ œ œ˜EJ˜1Jšœ˜Jšœ˜—J˜—™š‘ œœœ˜8Jšœ ˜ J˜Jšœ%˜%J˜,Jšœ<˜˜Cšœ˜Kšœœœ:˜NKšœ.˜.Kšœ8œ˜=Kšœ=œ˜BK˜—Kšœœ˜ —K˜šœ,œ˜4Kšœ'œ˜=š‘œ˜)šœ6œœ˜BKšœœœ2˜FK˜+Kšœ0œ˜5Kšœ5œ˜:K˜—K˜—Kšœ;˜;K˜+K˜)šœœœ˜#Kšœ+˜+K˜+šœ>œœ˜JKšœœœ:˜NK˜2Kšœ8œ˜=Kšœ=œ˜BK˜—Kšœ˜Kšœ˜—J˜—Kšœ˜—J˜J˜š ‘œœœœœ˜Xš‘ œœ˜$š œœœœœ˜:Kšœœœ˜Kšœ˜—Kšœœ˜K˜—Kšœœ˜ Kšœ œœ,˜UK˜Kšœ˜—K˜š‘œœ%œ˜MKšœœ˜ šœœœ˜(Kšœœœ˜1Kšœ˜—K˜Kšœ˜—K˜š‘œ˜ Kšœ-œ˜7Kšœ˜—K˜š‘ œ˜"Kšœœ"˜,Kšœœ˜˜>Kšœ˜—K˜š ‘ œœ2œœœ˜gKšœ œ˜Kšœœ˜ šœœœ˜+Kš œ9œœ œœ˜~Kšœ˜—KšœœœD˜UKšœ>˜>Kšœ˜—J˜š‘œ˜+šœ˜K˜K˜Kšœ˜—Kšœ˜—K˜K˜š ‘œœœœ˜>Kšœ&˜&Kšœ6œœœ˜HKšœ6˜6KšœI˜Išœ˜ KšœA˜EKšœ?˜C—Kšœ*˜*Kšœ˜—K˜K˜š ‘œœœœ˜JKšœ)˜)Kšœ>œœœ˜PKšœ>˜>KšœQ˜Qšœ˜ Kšœ2˜6Kšœc˜g—K˜ Kšœ-˜-Kšœ˜—K˜K˜š ‘œœœœ˜FKšœ-˜-Kšœ>œœœ˜PKšœ>˜>KšœQ˜Qšœ˜ KšœA˜EKšœ?˜C—K˜1Kšœ˜—K˜š‘ œœœ˜BKšœ ˜ šœ1˜8Kšœ ˜ Kšœ˜—Kšœ˜—J™J™Sš‘œœ-œœœœœœ˜žKšœ˜Kšœ!œ˜&Kšœ'œ˜=Kšœ5˜5Kšœœ ˜2K˜šΟbœ˜-Kšœœ˜8K˜—K˜š’œ˜(Kšœ9˜9K˜—K™K™AK˜?Kšœ8˜8K˜+K˜)K™K™Kšœ-˜-šœ œ˜šœ˜Kšœ ˜ KšœΟsœ˜ KšœA˜AKšœ˜Kšœ˜—Kšœ/˜/K˜—K˜K™Ršœ ˜ Kšœl˜pKšœk˜o—šœœœ#œ˜DKšœ1˜1KšœI˜IK˜—K˜K™šœœœ˜#Kšœ+˜+K˜+šœ˜šœ ˜ Kšœ œ˜&Kšœœ˜ K˜Kšœœœ˜,K˜K™,Kšœ;˜;šœ˜Kšœœœœ˜@šœ˜Kšœ;œ ˜MKšœH˜H——K™K™Kšœ1˜1šœ˜Kšœ7˜7K˜KšœQœ ˜cKšœ˜—Kšœ5˜5K˜K™8š œœœ.œœ˜JKšœ6˜6Kšœ œœ@˜WKšœœœ˜'Kšœ9˜9K˜Kšœy™yšœ5œ˜=Kšœœ˜;šœœ˜KšœœA˜Y˜,šœœ˜Kšœœ˜ KšœI˜IKšœK˜KK˜—K˜—K˜GK˜—K˜—Kšœœ.˜OKšœM˜MKšœ œ˜+Kšœ˜—K˜—šœ"˜"Kšœ@˜@—šœ#˜#Kšœ>˜>—šœ#˜#Kšœ>˜>—šœ$˜$Kšœ?˜?—šœ*˜*KšœE˜E—šœ"˜"Kšœœ˜4šœ ˜šœ ˜ Kšœ|˜|KšœV˜VK˜—˜ Kšœ œ˜+Kšœ œ˜&KšœF˜FKšœ1˜1šœ˜Kšœœ œœ˜HKšœQœ ˜cK˜Kšœ œ0œ#˜jK˜—Kšœ5˜5K˜—Kšœœ˜—Kšœ œ˜$K˜—šœ!˜!Kšœœ˜2šœ ˜Kšœ‡˜‡Kšœ œ˜Kšœœ˜—Kšœ œ˜$K˜—Kšœ<˜