<> <> <> DIRECTORY Check, <> Globals, <> HashTable, IO, Model, <> Printout, Rope; CheckImpl: CEDAR PROGRAM IMPORTS <> Globals, <> HashTable, IO, <> Printout EXPORTS Check = BEGIN OPEN Check; <> msgLimit: INT _ 100; <> normalLow: REAL _ 3.8; normalHigh: REAL _ 4.2; passLow: REAL _ 7.8; passHigh: REAL _ 8.2; <> <> <> <> <> <> cmdTable: ARRAY[0..3] OF Rope.ROPE _ [ "normalhigh", "normallow", "passhigh", "passlow" ]; <> msg1, msg2, msg3, msg4, msg5, msg6, skipped: INT; IntRec: TYPE = RECORD[val: INT]; CheckCmd: PUBLIC Globals.CmdProc ~ { CheckProc: HashTable.EachPairAction = BEGIN p: Globals.Pointer; f: Globals.Fet; node: Globals.Node _ NARROW[value]; drives, driven: BOOLEAN _ FALSE; <<1. Make sure the node has transistors attached.>> IF node.firstPointer = NIL THEN BEGIN msg1 _ msg1 + 1; IF msg1 <= msgLimit THEN IO.PutF[Globals.StdOut, "Node %s doesn't connect to any transistors.\n", IO.rope[Printout.NodeRope[node, globalVars]]] ELSE skipped _ skipped + 1; IF msg1 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; RETURN; END; <> FOR p _ node.firstPointer, p.next UNTIL p = NIL DO f _ p.fet; IF f.source = node THEN BEGIN IF f.flowFromDrain THEN driven _ TRUE; IF f.flowFromSource THEN drives _ TRUE; END; IF f.drain = node THEN BEGIN IF f.flowFromSource THEN driven _ TRUE; IF f.flowFromDrain THEN drives _ TRUE; END; IF f.gate = node THEN BEGIN drives _ TRUE; <<4. If transistor can't flow at all, error.>> IF NOT (f.flowFromSource OR f.flowFromDrain) THEN BEGIN msg4 _ msg4 + 1; IF msg4 <= msgLimit THEN BEGIN IO.PutF[Globals.StdOut, "No flow through FET: %s\n", IO.rope[Printout.FetRope[f, globalVars]]]; IF msg4 = 1 THEN IO.PutRope[Globals.StdOut, " Maybe you haven't marked all the inputs and outputs?\n"]; END ELSE skipped _ skipped + 1; IF msg4 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; END; <<5. If transistor is bidirectional but has no flow indicator,>> <> IF f.flowFromSource AND f.flowFromDrain AND f.firstFlow = NIL THEN BEGIN msg5 _ msg5 + 1; IF msg5 <= msgLimit THEN BEGIN IO.PutF[Globals.StdOut, "Bidirectional FET: %s\n", IO.rope[Printout.FetRope[f, globalVars]]]; IF msg5 = 1 THEN IO.PutRope[Globals.StdOut, " Maybe you should label flow?\n"]; END ELSE skipped _ skipped + 1; IF msg5 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; END; <<6. If transistor connects Vdd and Ground, error.>> IF (f.drain = globalVars.VddNode AND f.source = globalVars.GroundNode) OR (f.source = globalVars.VddNode AND f.drain = globalVars.GroundNode) THEN BEGIN msg6 _ msg6 + 1; IF msg6 <= msgLimit THEN IO.PutF[Globals.StdOut, "FET between Vdd and Ground: %s\n", IO.rope[Printout.FetRope[f, globalVars]]] ELSE skipped _ skipped + 1; IF msg6 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; END; END; ENDLOOP; <<3 & 4. Make sure that the node can drive and be driven.>> IF NOT (node.output OR drives) THEN BEGIN msg3 _ msg3 + 1; IF msg3 <= msgLimit THEN BEGIN IO.PutF[Globals.StdOut, "Node doesn't drive anything: %s.\n", IO.rope[Printout.NodeRope[node, globalVars]]]; IF msg3 = 1 THEN IO.PutRope[Globals.StdOut, " Maybe you haven't marked all the inputs and outputs?\n"]; END ELSE skipped _ skipped + 1; IF msg3 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; END; IF NOT (node.input OR driven) THEN BEGIN msg2 _ msg2 + 1; IF msg2 <= msgLimit THEN BEGIN IO.PutF[Globals.StdOut, "Node isn't driven: %s.\n", IO.rope[Printout.NodeRope[node, globalVars]]]; IF msg2 = 1 THEN IO.PutRope[Globals.StdOut, " Maybe you haven't marked all the inputs and outputs?\n"]; END ELSE skipped _ skipped + 1; IF msg2 = msgLimit THEN IO.PutRope[Globals.StdOut, " No more of these messages will be printed.\n"]; END; END; msg1 _ 0; msg2 _ 0; msg3 _ 0; msg4 _ 0; msg5 _ 0; msg6 _ 0; skipped _ 0; <> [] _ HashTable.Pairs[globalVars.nodeTable, CheckProc] }; <> <> <> <> <> <> <<>> <> <> <> <> <> <> <> <<>> <> <> <> <<>> <> <> <> <> <> <> <> <<>> <> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<[ok, val] _ Parse.Real[args];>> <> <> <> <> <> <> <