DIRECTORY Build, Globals, IO, Model, Parse, Printout, Rope; PrintoutImpl: CEDAR PROGRAM IMPORTS Build, Globals, IO, Model, Rope, Parse EXPORTS Printout = BEGIN OPEN Printout; Units: PUBLIC REAL _ 2.0; threshold: REAL; nDups: INT; FetRope: PUBLIC PROC[fet: Globals.Fet, globalVars: Globals.GlobalVars] RETURNS [rope: Rope.ROPE] = BEGIN rope _ IO.PutFR["g=%s, s=%s, d=%s", IO.rope[Build.RopeFromNode[fet.gate, globalVars]], IO.rope[Build.RopeFromNode[fet.source, globalVars]], IO.rope[Build.RopeFromNode[fet.drain, globalVars]]]; RETURN [rope]; END; NodeRope: PUBLIC PROC[node: Globals.Node, globalVars: Globals.GlobalVars] RETURNS [rope: Rope.ROPE] = BEGIN x,y: REAL; p: Globals.Pointer; terminal: Rope.ROPE; f: Globals.Fet; p _ node.firstPointer; IF p = NIL THEN BEGIN RETURN [Build.RopeFromNode[node, globalVars]]; END ELSE BEGIN FOR i:INT IN [0..10) DO f _ p.fet; IF node = f.gate THEN EXIT; IF p.next = NIL THEN EXIT; p _ p.next; ENDLOOP; x _ f.x/Units; y _ f.y/Units; IF node = f.gate THEN terminal _ "gate" ELSE IF node = f.drain THEN terminal _ "drain" ELSE IF node = f.source THEN terminal _ "source" ELSE BEGIN IO.PutF[Globals.StdOut, "Crystal bug: node %s doesn't connect right!\n", IO.rope[Build.RopeFromNode[node, globalVars]]]; RETURN ["??"]; END; rope _ IO.PutFR["%s (see %s at %f,%f)", IO.rope[Build.RopeFromNode[node, globalVars]], IO.rope[terminal], IO.real[x], IO.real[y]]; RETURN [rope]; END; END; PrintCap: PUBLIC Globals.CmdProc = BEGIN ParseOK: BOOLEAN; node: Globals.Node; nDups _ 0; threshold _ 0.0; WHILE args # NIL DO IF Rope.Fetch[args.rope, 0] # '- THEN EXIT; IF Rope.Length[args.rope] # 2 THEN BEGIN IO.PutF[Globals.StdOut, "Bad switch: %s\n", IO.rope[args.rope]]; args _ args.next; LOOP; END; SELECT Rope.Fetch[args.rope, 1] FROM 't => BEGIN [ParseOK, threshold] _ Parse.Real[args.next]; IF ParseOK THEN args _ args.next ELSE IO.PutF[Globals.StdOut, "No threshold value given, using 0.\n"]; END; ENDCASE => IO.PutF[Globals.StdOut, "Bad switch: %s\n", IO.rope[args.rope]]; args _ args.next; ENDLOOP; nDups _ 0; WHILE args # NIL DO node _ Build.NodeFromRope[args.rope, globalVars]; IO.PutF[Globals.StdOut, "%.3f pf capacitance at %s.\n", IO.real[node.cap], IO.rope[NodeRope[node, globalVars]]]; args _ args.next; ENDLOOP; IF nDups > 0 THEN IO.PutF[Globals.StdOut, "%d duplicates not printed.\n", IO.int[nDups]]; END; PrintRes: PUBLIC Globals.CmdProc = BEGIN ParseOK: BOOLEAN; node: Globals.Node; nDups _ 0; threshold _ 0.0; WHILE args # NIL DO IF Rope.Fetch[args.rope, 0] # '- THEN EXIT; IF Rope.Length[args.rope] # 2 THEN BEGIN IO.PutF[Globals.StdOut, "Bad switch: %s\n", IO.rope[args.rope]]; args _ args.next; LOOP; END; SELECT Rope.Fetch[args.rope, 1] FROM 't => BEGIN [ParseOK, threshold] _ Parse.Real[args.next]; IF ParseOK THEN args _ args.next ELSE IO.PutF[Globals.StdOut, "No threshold value given, using 0.\n"]; END; ENDCASE => IO.PutF[Globals.StdOut, "Bad switch: %s\n", IO.rope[args.rope]]; args _ args.next; ENDLOOP; nDups _ 0; WHILE args # NIL DO node _ Build.NodeFromRope[args.rope, globalVars]; IO.PutF[Globals.StdOut, "%.3f ohms resistance at %s.\n", IO.real[node.res], IO.rope[NodeRope[node, globalVars]]]; args _ args.next; ENDLOOP; IF nDups > 0 THEN IO.PutF[Globals.StdOut, "%d duplicates not printed.\n", IO.int[nDups]]; END; PrintFets: PUBLIC Globals.CmdProc = BEGIN WHILE args # NIL DO FetProc[Build.NodeFromRope[args.rope, globalVars], globalVars]; args _ args.next; ENDLOOP; END; FetProc: PROC[node: Globals.Node, globalVars: Globals.GlobalVars] = BEGIN pointer: Globals.Pointer; fet: Globals.Fet; fp: Globals.FlowPtr; FOR pointer _ node.firstPointer, pointer.next UNTIL pointer = NIL DO fet _ pointer.fet; IF fet.gate = node THEN BEGIN IO.PutF[Globals.StdOut, "%s, type=%s, aspect=%.3f, area=%.3f\n", IO.rope[FetRope[fet, globalVars]], IO.rope[Model.TypeTable[fet.type].name], IO.real[fet.aspect], IO.real[fet.area/(Units*Units)]]; IO.PutRope[Globals.StdOut, " Flags:"]; IF fet.flowFromSource THEN IO.PutRope[Globals.StdOut, " fromSource"]; IF fet.flowFromDrain THEN IO.PutRope[Globals.StdOut, " fromDrain"]; IF fet.forcedOn THEN IO.PutRope[Globals.StdOut, " forcedOn"]; IF fet.forcedOff THEN IO.PutRope[Globals.StdOut, " forcedOff"]; IF fet.on0 THEN IO.PutRope[Globals.StdOut, " on0"]; IF fet.on1 THEN IO.PutRope[Globals.StdOut, " on1"]; IF fet.onAlways THEN IO.PutRope[Globals.StdOut, " onAlways"]; IF fet.noSourceInfo THEN IO.PutRope[Globals.StdOut, " noSourceInfo"]; IF fet.noDrainInfo THEN IO.PutRope[Globals.StdOut, " noDrainInfo"]; IF fet.firstFlow # NIL THEN IO.PutRope[Globals.StdOut, " Flow:"]; FOR fp _ fet.firstFlow, fp.next UNTIL fp = NIL DO IF fp.source THEN IO.PutF[Globals.StdOut, " s=%s", IO.rope[fp.flow.name]]; IF fp.drain THEN IO.PutF[Globals.StdOut, " d=%s", IO.rope[fp.flow.name]]; ENDLOOP; IO.PutRope[Globals.StdOut, "\n"]; END; ENDLOOP; END; PrintNodes: PUBLIC Globals.CmdProc = BEGIN WHILE args # NIL DO NodeProc[Build.NodeFromRope[args.rope, globalVars], globalVars]; args _ args.next; ENDLOOP; END; NodeProc: PROC[node: Globals.Node, globalVars: Globals.GlobalVars] = BEGIN IO.PutF[Globals.StdOut, "%s:", IO.rope[Build.RopeFromNode[node, globalVars]]]; IF node.always0 THEN IO.PutRope[Globals.StdOut, " always 0"]; IF node.always1 THEN IO.PutRope[Globals.StdOut, " always 1"]; IF node.input THEN IO.PutRope[Globals.StdOut, " input"]; IF node.output THEN IO.PutRope[Globals.StdOut, " output"]; IF node.precharged THEN IO.PutRope[Globals.StdOut, " precharged"]; IF node.bus THEN IO.PutRope[Globals.StdOut, " bus"]; IF node.dynamic THEN IO.PutRope[Globals.StdOut, " dynamic"]; IF node.inPath THEN IO.PutRope[Globals.StdOut, " inPath"]; IF node.ratioError THEN IO.PutRope[Globals.StdOut, " ratioError"]; IF node.watched THEN IO.PutRope[Globals.StdOut, " watched"]; IO.PutF[Globals.StdOut, " capacitance = %.5f, resistance = %.1f,", IO.real[node.cap], IO.real[node.res]]; IO.PutF[Globals.StdOut, " rise time = %.1f, fall time = %.1f\n", IO.real[node.hiTime], IO.real[node.loTime]]; END; END. ΞFILE: PrintoutImpl.mesa Last edited by Ousterhout, August 30, 1983 1:40 pm Christian LeCocq December 19, 1986 2:02:15 pm PST The following variables are used to communicate between command-level routines and enumeration action routines. dupTable: Hash.Table; The only tricky thing about this routine is that nodes don't contain (x,y) locations. I've found that the best way to identify a node is with a transistor gate. So, this procedure checks the first few transistors attached to the node to see if there's a gate available for use as a reference point. dupTable _ Hash.NewTable[]; Read off switches, if there are any. Read off nodes. For each node, look it up in the node table and print out its capacitance if it's greater than threshold. IF args = NIL THEN Hash.Enumerate[table: globalVars.nodeTable, pattern: "*", proc: capProc, errorStream: Globals.StdOut] ELSE Hash.Enumerate[table: globalVars.nodeTable, pattern: args.rope, proc: capProc, errorStream: Globals.StdOut]; CapProc: PROC[node: Globals.Node] = BEGIN valRope: Rope.ROPE; IF node = NIL THEN RETURN; IF node.cap >= threshold THEN BEGIN valRope _ IO.PutFR["%.3f", IO.real[node.cap]]; entry _ Hash.Find[dupTable, valRope]; IF (entry.clientData # $Duplicate) OR Globals.DupsOK THEN BEGIN entry.clientData _ $Duplicate; IO.PutF[Globals.StdOut, "%s pf capacitance at %s.\n", IO.rope[valRope], IO.rope[NodeRope[node]]]; END ELSE nDups _ nDups + 1; END; END; dupTable _ Hash.NewTable[]; Read off switches, if there are any. Read off nodes. For each node, look it up in the node table and print out its resistance if it's greater than threshold. IF args = NIL THEN Hash.Enumerate[table: globalVars.nodeTable, pattern: "*", proc: resProc, errorStream: Globals.StdOut] ELSE Hash.Enumerate[table: globalVars.nodeTable, pattern: args.rope, proc: resProc, errorStream: Globals.StdOut]; ResProc: PROC[node: Globals.Node] = BEGIN valRope: Rope.ROPE; IF node = NIL THEN RETURN; IF node.res >= threshold THEN BEGIN valRope _ IO.PutFR["%.1f", IO.real[node.res]]; entry _ Hash.Find[dupTable, valRope]; IF (entry.clientData # $Duplicate) OR Globals.DupsOK THEN BEGIN entry.clientData _ $Duplicate; IO.PutF[Globals.StdOut, "%s ohms resistance at %s.\n", IO.rope[valRope], IO.rope[NodeRope[node]]]; END ELSE nDups _ nDups + 1; END; END; IF args = NIL THEN Hash.Enumerate[table: globalVars.nodeTable, pattern: "*", proc: fetProc, errorStream: Globals.StdOut] ELSE Hash.Enumerate[table: globalVars.nodeTable, pattern: args.rope, proc: fetProc, errorStream: Globals.StdOut]; IF args = NIL THEN Hash.Enumerate[table: globalVars.nodeTable, pattern: "*", proc: nodeProc, errorStream: Globals.StdOut] ELSE Hash.Enumerate[table: globalVars.nodeTable, pattern: args.rope, proc: nodeProc, errorStream: Globals.StdOut]; Κ œ˜Jšœ™šœ2™2Icode™1—J˜šΟk ˜ J˜J˜Jšœ˜J˜J˜J˜ J˜—J˜JšΟn œœ˜š˜J˜J˜Jšœ˜J˜J˜J˜—Jšœ ˜Jš˜Jšœ ˜J˜Jšžœœœ˜J˜Jšœo™oJ˜J™Jšœ œ˜Jšœœ˜ J˜J˜Jš žœœœ3œ œ˜b˜Jš˜šœœ˜#Jšœ0˜2Jšœ2˜4Jšœ2˜4—Jšœ˜Jšœ˜—J˜J˜Jš žœœœ5œ œ˜e˜Jš˜Jšœœ˜ J˜Jšœœ˜J˜J˜Jšœ¬™¬J˜J˜šœœ˜Jš˜Jšœ(˜.Jš˜—š˜Jš˜šœœœ ˜J˜ Jšœœœ˜Jšœ œœœ˜J˜ Jšœ˜—J˜J˜Jšœœ˜'Jšœœœ˜.Jšœœœ˜0š˜Jš˜JšœFœ-˜xJšœ˜Jšœ˜—šœœ˜'Jšœ,˜.Jšœ˜Jšœ ˜ Jšœ ˜ —Jšœ˜Jšœ˜—Jšœ˜—J˜J˜Jšžœœ˜"˜Jš˜Jšžœœ˜J˜J™J˜J˜ J˜J˜Jšœ$™$J˜šœœ˜Jšœœœ˜+šœ˜"Jš˜Jšœ*œ˜@J˜Jšœ˜Jšœ˜—šœ˜$˜Jš˜J˜-Jšœ œ˜ Jšœœ>˜EJšœ˜—Jšœœ*œ˜K—J˜Jšœ˜—J˜Jšœz™zJ˜J˜ šœœ™Jšœe™e—š™Jšœœ˜Jšœl™lJšœ1˜1Jšœ5œœ#˜pJ˜Jšœ˜—šœ ˜Jšœ6œ ˜G—Jšœ˜J˜—šžœœ™#Jš™Jšœœ™Jšœœœœ™šœ ™#šœ œœ™.J™%šœ!œ ™?™šœ3™5Jšœ™Jšœ™—Jš™——Jšœ™Jšœ™——Jšœ™—J˜J˜Jšžœœ˜"˜Jš˜Jšžœœ˜J˜J™Jšœ˜J˜ J˜J˜Jšœ$™$J˜šœœ˜Jšœœœ˜+šœ˜"Jš˜Jšœ*œ˜@J˜Jšœ˜Jšœ˜—šœ˜$˜Jš˜J˜-Jšœ œ˜ Jšœœ>˜EJšœ˜—Jšœœ*œ˜K—J˜Jšœ˜—J˜JšœF™FJšœ2™2J˜J˜ šœœ™Jšœe™e—Jš™šœœ˜Jšœ1˜1Jšœ6œœ#˜qJšœl™lJ˜Jšœ˜—šœ ˜Jšœ6œ ˜G—Jšœ˜J˜—šžœœ™#Jš™Jšœœ™Jšœœœœ™šœ™Jš™Jšœ œœ™.J™%šœ!œ™9Jš™J™Jšœ4œœ™bJš™—Jšœ™Jšœ™—Jšœ™—J˜J˜šž œœ˜#Jš˜šœœœI™[Jšœ™—Jš™šœœ˜Jšœl™lJšœ?˜?J˜Jšœ˜—Jšœ˜—J˜šžœœ6˜CJš˜J˜J˜J˜J˜šœ+œ œ˜DJ˜šœ˜Jš˜šœ>˜@Jšœ ˜"Jšœ&˜(Jšœ˜Jšœ˜!—Jšœ'˜)Jšœœœ(˜EJšœœœ'˜CJšœœœ&˜=Jšœœœ'˜?Jšœ œœ!˜3Jšœ œœ!˜3Jšœœœ&˜=Jšœœœ*˜EJšœœœ)˜CJšœœœœ#˜Ašœœœ˜1Jšœ œœœ˜JJšœ œœœ˜IJšœ˜—Jšœ˜!Jšœ˜—Jšœ˜—Jšœ˜—J˜J˜šž œœ˜$Jš˜Jšœœœg™yJš™šœœ˜Jšœm™mJšœ@˜@J˜Jšœ˜—Jšœ˜—J˜šžœœ6˜DJš˜Jšœœ-˜NJšœœœ&˜=Jšœœœ&˜=Jšœ œœ#˜8Jšœ œœ$˜:Jšœœœ(˜BJšœ œœ!˜4Jšœœœ%˜