JasmineThyme.mesa
Copyright © 1986 by Xerox Corporation. All rights reserved.
Last Edited by: Neil Gunther June 20, 1986 8:17:55 pm PDT
DIRECTORY
Convert,
Core,
CoreClasses,
CoreFlat,
CoreOps,
CoreProperties,
Rope,
spMain,
spGlobals,
SymTab,
TiogaFileOps,
ViewerTools;
JasmineThyme: CEDAR PROGRAM
IMPORTS Convert, CoreClasses, CoreFlat, CoreOps, CoreProperties, Rope, spMain, spGlobals, SymTab, TiogaFileOps, ViewerTools
= BEGIN
TNode: TYPE = TiogaFileOps.Ref;
nodeProp: ATOM = CoreProperties.RegisterProperty[$JasmineNode];
hasNameProp: ATOM = CoreProperties.RegisterProperty[$JasmineNameProp];
CreateThymeFile: PROC [model: SymTab.Ref, outputFile: Core.ROPE] = {
root: TNode ← TiogaFileOps.CreateRoot[];
PrintHeader[outputFile, root];
PrintCircuit[root];
TiogaFileOps.Store[root, outputFile]
};
PrintHeader: PROC [outputFile: Core.ROPE, root: TNode] = {
node: TNode;
TiogaFileOps.SetStyle[root, "Cedar"];
node ← TiogaFileOps.InsertAsLastChild[root];
TiogaFileOps.SetContents[node, Rope.Cat["-- ", outputFile, "; Created by Jasmine."]];
[] ← TiogaFileOps.InsertAsLastChild[root];
};
PrintCircuit: PROC [root: TNode] = {
tNode: TNode ← TiogaFileOps.InsertAsLastChild[root];
tSubNode: TNode;
plotControl: Core.ROPE;
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.0/Thyme/SignalGenerators.thy"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "! /DATools/DATools6.0/Thyme/BSim.thy\n"];
tSubNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[tSubNode, "powerSupply: voltage[Vdd, Gnd] = 5.0;"];
Thyme nodes & instances
PrintInstanceNodes[root, cellType, cellType.public[0]];
Thyme initial conditions
--Optional--
Thyme Plot control
tNode ← TiogaFileOps.InsertAsLastChild[root];
plotControl ← Rope.Cat[
Rope.Cat["PLOT[\"", "Jasmine Test Model", "\", "],
Rope.Cat[":", "1ns", ", "],
Rope.Concat["-3", ", "],
Rope.Concat["8", ", "],
Rope.Concat["myGnd, jn15"]
];
plotControl ← Rope.Concat[plotControl, "];"];
TiogaFileOps.SetContents[tNode, plotControl];
Thyme Run control
tNode ← TiogaFileOps.InsertAsLastChild[root];
TiogaFileOps.SetContents[tNode, Rope.Cat["RUN[",
Rope.Cat["tMin ← ", "0ns", ", "],
Rope.Cat["tMax ← ", "200ns", "];"]
]];
}; --PrintCircuit
PrintInstanceNodes: PROC [tRoot: TNode, cellType: Core.CellType, wire: Core.Wire] = {
RegisterInternalNode: PROC [nodeID: INT] RETURNS [nodeIDName: Core.ROPE] = {
nodeIDName ← Rope.Cat["jn", Convert.RopeFromInt[nodeID], nodeSeparator];
jasmineNodeList ← CONS[nodeIDName, jasmineNodeList];
}; --RegisterInternalNode
RegisterJasmineNode: PROC [jNode: Core.ROPE] = {
nodeIDName ← Rope.Cat[jNode, nodeSeparator];
jasmineNodeList ← CONS[nodeIDName, jasmineNodeList];
}; --RegisterJasmineNode
AccumulateNode: CoreFlat.EachInternalWireProc
--[bindings: HashTable.Table, path: PackedPath, cellType: Core.CellType, wire: Core.Wire]-- = {
jasmineNodeName: Core.ROPENIL;
RegisterJasmineNode[CoreOps.GetShortWireName[wire]];
IF (jasmineNodeName←NARROW[CoreProperties.GetWireProp[from: wire, prop: nodeProp]])#NIL THEN
RegisterJasmineNode[jasmineNodeName];
}; --AccumulateNode
AccumulateInstance: CoreFlat.EachWireInstanceProc
--[bindings: HashTable.Table, path: PackedPath, instance: CoreClasses.CellInstance, wire: Core.Wire] RETURNS [flatten: BOOL ← TRUE]-- = {
NameInstance: PROC[inst: CoreClasses.CellInstance] RETURNS [name: Core.ROPE] = {
name ← CoreClasses.GetCellInstanceName[inst];
IF CoreProperties.GetCellInstanceProp[inst, hasNameProp]#NIL THEN RETURN;
IF name=NIL THEN {
name ← Rope.Cat["Block", Convert.RopeFromInt[instID]];
instID ← instID.SUCC;
};
[] ← CoreClasses.SetCellInstanceName[inst, name];
CoreProperties.PutCellInstanceProp[inst, hasNameProp, hasNameProp];
};
SELECT instance.type.class FROM
CoreClasses.recordCellClass => {
subTNodeInstance ← Rope.Cat[
Rope.Cat[NameInstance[instance], ": ", CoreOps.GetCellTypeName[instance.type]],
"[", CoreOps.GetShortWireName[instance.actual], "];"];
};
CoreClasses.transistorCellClass => {
transistor: CoreClasses.Transistor ← NARROW[instance.type.data];
jasName: Core.ROPENARROW[CoreProperties.GetWireProp[from: wire, prop: nodeProp]];
subTNodeInstance ← Rope.Cat[
Rope.Cat[NameInstance[instance], ": "],
SELECT transistor.type FROM
nE => "ETran",
pE => "CTran"
ENDCASE => ERROR,
Rope.Cat["[", RopeFromWires[wire, WireToAtomicWires[instance.actual]], " | "],
Rope.Cat["L←", Convert.RopeFromInt[transistor.length], ", "],
Rope.Cat["W←", Convert.RopeFromInt[transistor.width], ", sdExtend𡤆];"]
];
};
CoreClasses.transistorCellClass => {
subTNodeInstance ← Rope.Cat[
Rope.Cat[NameInstance[instance], ": Capacitor"],
Rope.Cat["[", RegisterInternalNode[jNodeID], "Gnd", "] = "],
Rope.Cat[Convert.RopeFromReal[5.0], "pF", ";"]
];
};
ENDCASE => ERROR;
jNodeID ← jNodeID.SUCC;
instList ← CONS[subTNodeInstance, instList];
}; --AccumulateInstance
subTNodeInstance, subTNodeWires, subTNodeResistors, nodeIDName, rName: Core.ROPE;
nodeSeparator: Core.ROPE ← ", ";
tNode, subTNode: TNode;
jasmineNodeList, instList: LIST OF Core.ROPENIL;
instID, resID, capID, jNodeID: INT ← 0;
tNode ← TiogaFileOps.InsertAsLastChild[tRoot];
instList ← Reverse[instList];
jasmineNodeList ← Reverse[jasmineNodeList];
FOR jnList: LIST OF Core.ROPE ← jasmineNodeList, jnList.rest UNTIL jnList=NIL DO
subTNodeWires ← Rope.Cat[subTNodeWires, jnList.first];
ENDLOOP;
subTNodeWires← Rope.Substr[base: subTNodeWires, len: (Rope.Length[subTNodeWires]-Rope.Length[nodeSeparator])];
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, Rope.Cat[subTNodeWires, ": Node;"]];
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, "peakCurrent: Current[myGnd, jn15] = 8mA;"];
FOR jnList: LIST OF Core.ROPE ← jasmineNodeList, jnList.rest UNTIL jnList=NIL DO
IF jnList.rest = NIL THEN EXIT;
rName ← Rope.Cat["R", Convert.RopeFromInt[resID]];
subTNodeResistors ← Rope.Cat[
Rope.Cat[rName, ": Resistor"],
Rope.Cat["[", jnList.first, Rope.Substr[base: jnList.rest.first, len: (Rope.Length[jnList.rest.first]-Rope.Length[nodeSeparator])], "] = "],
Rope.Cat[Convert.RopeFromReal[0.02386], "K", ";"]
];
resID ← resID.SUCC;
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, subTNodeResistors];
ENDLOOP;
FOR iList: LIST OF Core.ROPE ← instList, iList.rest UNTIL iList=NIL DO
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, iList.first];
ENDLOOP;
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, Rope.Cat["testSignal: RectWave[", CoreOps.GetShortWireName[wire], " | period�ns, width�ns, tRise𡤁ns, tFall𡤁ns, tDelay𡤄ns];"]
];
subTNode ← TiogaFileOps.InsertAsLastChild[tNode];
TiogaFileOps.SetContents[subTNode, "};\n"];
}; --PrintInstanceNodes
ShowThyme: PROC [workingDir, thyFile: Core.ROPE] = {
thyHandle: spGlobals.Handle ← spGlobals.MakeThymeViewers[workingDir];
ViewerTools.SetContents[thyHandle.input, thyFile];
spMain.NormalRun[thyHandle];
};
Reverse: PROC [ropes: LIST OF Core.ROPE] RETURNS [revRopes: LIST OF Core.ROPENIL] = {
WHILE ropes#NIL DO revRopes ← CONS [ropes.first, revRopes]; ropes ← ropes.rest ENDLOOP;
};
END.