DIRECTORY Atom USING [GetPName], CD USING [Design, lambda, Layer, LayerKey, Technology], CDMenus USING [CreateEntry], CDProperties USING [GetProp], CDSequencer USING [Command, ImplementCommand], IO USING [atom, char, int, Put, PutF, rope, RopeFromROS, ROS, STREAM], Rope USING [Cat, FromRefText, ROPE], SXAtoms USING [spinifex], SX USING [BoxMapProc, Constraint, ConstraintArray, ConstraintIndex, excludeIndex, GeometricRule, MapRec, maxConstraints, nodeIndex, spaceIndex, SpinifexLayerIndex, techCIndexBase, TechHandle, violateIndex], TerminalIO USING [WriteRope]; SXShowRulesImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDMenus, CDProperties, CDSequencer, IO, Rope, SXAtoms, TerminalIO = BEGIN TriggerMap: TYPE = PACKED ARRAY SX.ConstraintIndex OF BOOLEAN; Write: PROCEDURE [data: REF] = BEGIN WITH data SELECT FROM rope: Rope.ROPE => TerminalIO.WriteRope [rope]; stream: IO.STREAM => TerminalIO.WriteRope [IO.RopeFromROS[stream]]; text: REF TEXT => TerminalIO.WriteRope [Rope.FromRefText[text]]; ENDCASE => ERROR; END; -- Write RegisterCommand: PROCEDURE ~ { id: ATOM ~ $showRules; CDSequencer.ImplementCommand [a: id, p: WriteTechHandle, queue: doQueue]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Show Rules", key: id]; TerminalIO.WriteRope ["Spinifex utility showing design rules loaded.\n"] }; -- end RegisterCommand WriteTechHandle: PROCEDURE [comm: CDSequencer.Command] ~ { design: CD.Design ~ comm.design; technologyHandle: REF SX.TechHandle; technologyHandle _ NARROW [CDProperties.GetProp [from: design.technology, prop: SXAtoms.spinifex]]; IF (technologyHandle = NIL) THEN { TerminalIO.WriteRope ["The input focus is not on a design with a Spinifex technology.\n"]; ERROR ABORTED }; Write [Rope.Cat ["\n***** The technology of the design ", design.name, " is ", design.technology.name, ".\n"]]; WriteLayers [th: technologyHandle]; WriteRules [th: technologyHandle]; WriteConstraints [design: design, th: technologyHandle]; WriteConstraintResolution [th: technologyHandle]; Write ["Done\n"] }; -- end WriteTechHandle WriteLayers: PROCEDURE [th: REF SX.TechHandle] ~ { info: IO.STREAM ~ IO.ROS []; IO.PutF [stream: info, format: "It uses %g Spinifex layers.\nLayer number and name, Thyme name, and bloat factor:\n", v1: IO.int[th.numSpinifexLayers]]; FOR layer: SX.SpinifexLayerIndex IN [0.. th.numSpinifexLayers) DO IO.PutF [stream: info, format: "%3g %-15g %-5g %5g \n", v1: IO.int[layer], v2: IO.atom[th.spinifexLayerNames[layer].layerId], v3: IO.rope[th.spinifexLayerNames[layer].thymeName], v4: IO.int[th.layerInterestBloat[layer]]] ENDLOOP; Write [info] }; -- end WriteLayers WriteRules: PROCEDURE [th: REF SX.TechHandle] = BEGIN Write ["\n***** Design rules:\n[So how does checking work? The four quads around a corner are mapped through trigger1 to TRUE/FALSE value for each quadrant. The TRUE area represents 'stuff' and if it forms a convex or concave corner a check is made of size extent into the corresponding 'non-stuff' in the FALSE region. To do a width check we map space to TRUE and the material being width checked to FALSE, thus an appropriate check is generated extending into the material. The check fails if anything in the check region maps through trigger2 to TRUE. If okIfConnected is TRUE then the violation is overidden if trigger1 and trigger2 circuit nodes and are the same. The trigger tables must be hand generated by the tech dependent client and are therefore error prone.]\n"]; FOR layer: SX.SpinifexLayerIndex IN [0.. th.numSpinifexLayers) DO Write [Rope.Cat["List of rules for layer ", Atom.GetPName[th.spinifexLayerNames[layer].layerId], ":\n"]]; IF th.rules[layer] = NIL THEN Write ["none"]; FOR rules: LIST OF REF SX.GeometricRule _ th.rules[layer], rules.rest WHILE rules # NIL DO info: IO.STREAM ~ IO.ROS []; IO.PutF [stream: info, format: "%g; %3g  extent. May %gbe connected.\n", v1: IO.rope[rules.first.message], v2: IO.int[rules.first.extent / CD.lambda], v3: IO.rope[IF rules.first.okIfConnected THEN "" ELSE "not "]]; Write [info]; WriteTriggers [trigger1: rules.first.trigger1, trigger2: rules.first.trigger2, constraints: th.constraintResolutions[layer]^[0]] ENDLOOP; Write ["\n"]; ENDLOOP; END; -- WriteRules WriteTriggers: PROCEDURE [trigger1, trigger2: TriggerMap, constraints: SX.ConstraintArray] = BEGIN SpecificConstraints: TYPE = [SX.techCIndexBase .. SX.maxConstraints) _ SpecificConstraints.FIRST; BEGIN -- trigger 1 info: IO.STREAM ~ IO.ROS []; info.Put [IO.rope[" Trigger 1: "]]; FOR i: SX.ConstraintIndex IN SX.ConstraintIndex DO IO.PutF [stream: info, format: "%2g", v1: IO.char[IF trigger1[i] THEN 'T ELSE 'F]]; ENDLOOP; info.Put [IO.rope["\n"]]; IF trigger1[SX.nodeIndex] THEN info.Put [IO.rope[" Will DRC areas for node regions.\n"]]; IF trigger1[SX.spaceIndex] THEN info.Put [IO.rope[" Will DRC areas for space regions if there are no tiles in the CIF quad tree.\n"]]; IF trigger1[SX.excludeIndex] THEN info.Put [IO.rope[" Will DRC areas for regions excluded by opaque cells.\n"]]; IF trigger1[SX.violateIndex] THEN info.Put [IO.rope[" Will DRC areas for opaque cell exclusion region violations.\n"]]; FOR i: SpecificConstraints IN SpecificConstraints DO IF trigger1[i] THEN BEGIN IF constraints[i] = NIL THEN IO.PutF [stream: info, format: " ***** CONSTRAINT %g NOT INITIALIZED *****\n", v1: IO.int[i]] ELSE IO.PutF [stream: info, format: " Will DRC area for constraint %g.\n", v1: IO.atom[constraints[i].name]] END; ENDLOOP; Write [info] END; -- trigger 1 BEGIN -- trigger 2 info: IO.STREAM ~ IO.ROS []; info.Put [IO.rope[" Trigger 2: "]]; FOR i: SX.ConstraintIndex IN SX.ConstraintIndex DO IO.PutF [stream: info, format: "%2g", v1: IO.char[IF trigger2[i] THEN 'T ELSE 'F]]; ENDLOOP; info.Put [IO.rope["\n"]]; IF trigger2[SX.nodeIndex] THEN info.Put [IO.rope[" Rule is violated if there is a node.\n"]]; IF trigger2[SX.spaceIndex] THEN info.Put [IO.rope[" Rule is violated if there are no tiles in the CIF quad tree.\n"]]; IF trigger2[SX.excludeIndex] THEN info.Put [IO.rope[" Rule is violated if there is stuff in a region excluded by opaque cells.\n"]]; IF trigger2[SX.violateIndex] THEN info.Put [IO.rope[" Rule is violated if there is a violation in a region excluded by opaque cells.\n"]]; FOR i: SpecificConstraints IN SpecificConstraints DO IF trigger2[i] THEN BEGIN IF constraints[i] = NIL THEN IO.PutF [stream: info, format: " ***** CONSTRAINT %g NOT INITIALIZED *****\n", v1: IO.int[i]] ELSE IO.PutF [stream: info, format: " Rule is violated if there is constraint %g.\n", v1: IO.atom[constraints[i].name]] END; ENDLOOP; Write [info] END -- trigger 2 END; -- WriteTriggers WriteConstraints: PROCEDURE [design: CD.Design, th: REF SX.TechHandle] = BEGIN Write ["\n***** Constraints\n[Note that the constraints are determined during the mapping from ChipNDale to Spinifex layers]:\n"]; FOR level: LIST OF CD.Layer _ design.technology.usedLayers, level.rest WHILE level # NIL DO info: IO.STREAM ~ IO.ROS []; layer: CD.Layer _ level.first; IO.PutF [stream: info, format: "List of constraints for ChipNDale layer %2g [%g]:\n", v1: IO.int[layer], v2: IO.atom[CD.LayerKey[layer]]]; Write [info]; IF th.cdLayerMapping[layer] = NIL THEN Write ["*** none ***"]; FOR map: LIST OF SX.MapRec _ th.cdLayerMapping[layer], map.rest WHILE map # NIL DO info1: IO.STREAM ~ IO.ROS []; IO.PutF [stream: info1, format: "For Spinifex layer %g; bloat factor: %g;\n", v1: IO.atom[th.spinifexLayerNames[map.first.spinifexLayer].layerId], v2: IO.int[map.first.bloatFactor]]; WITH map.first.value SELECT FROM c: REF SX.Constraint => BEGIN IO.PutF [stream: info1, format: "The regions represent a constraint on other material in this layer.\nConstraint name: %g; index into the constraint array: %g.\n", v1: IO.atom[c.name], v2: IO.int[c.index]]; IF c.hasCorrespondingNode THEN IO.PutF [stream: info1, format: "Connectivity affects the rule and there is a corresponding layer which has the nodes associated with these regions.\n"]; IO.PutF [stream: info1, format: "Node values are attached to constraints looking at layer %g.\n", v1: IO.atom[th.spinifexLayerNames[c.correspondingNodeLayer].layerId]]; END; p: REF SX.BoxMapProc => IO.PutF [stream: info1, format: "A procedural escape for more complex rectangle mapping is used for this ChipNDale layer.\n"]; ENDCASE => IO.PutF [stream: info1, format: "No constraint from this ChipNDale layer; the regions represent conductive material on this layer and a new Spinifex node is created.\n"]; IO.PutF [stream: info1, format: "\n"]; Write [info1]; ENDLOOP; Write [".\n"]; ENDLOOP; END; -- WriteConstraints WriteConstraintResolution: PROCEDURE [th: REF SX.TechHandle] = BEGIN Write ["\n***** Constraint resolution tables:\n"]; FOR i: SX.SpinifexLayerIndex IN SX.SpinifexLayerIndex DO IF th.constraintResolutions[i] # NIL THEN BEGIN info: IO.STREAM ~ IO.ROS []; IO.PutF [stream: info, format: "Constraint resolution table for Spinifex layer %g:\n", v1: IO.atom[th.spinifexLayerNames[i].layerId]]; FOR j: SX.ConstraintIndex IN SX.ConstraintIndex DO IO.PutF [stream: info, format: "constraint index %g: ", v1: IO.int[j]]; FOR k: SX.ConstraintIndex IN SX.ConstraintIndex DO IF th.constraintResolutions[i][j][k] # NIL THEN BEGIN IO.PutF [stream: info, format: "%g: %g[%g], ", v1: IO.int[k], v2: IO.atom[th.constraintResolutions[i][j][k].name], v3: IO.int[th.constraintResolutions[i][j][k].index]]; END; ENDLOOP; IO.PutF [stream: info, format: "\n"]; ENDLOOP; Write [info]; Write ["\n"] END; ENDLOOP; END; -- WriteConstraintResolution RegisterCommand [] END. °SXShowRulesImpl.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Last edited by Giordano Beretta, May 7, 1985 11:11:40 am PDT Writes the data (a rope or a stream) to the output. Writes the list of geometric rules for each layer. Called in "WriteRules". Tries to tell the consequences of the rules. Writes the list of constraints for each layer. Writes the constraint resolution table for each Spinifex layer. Κ ˜™Jšœ Οmœ1™šŸœž œžœ˜J™3Kšž˜šžœžœž˜Lšœ žœ ˜/Lšœžœžœžœ˜CLšœžœžœ2˜@Lšžœžœ˜—KšžœΟc˜ —šŸœž œ˜Lšœžœ˜KšœI˜ILšœG˜GLšœH˜HLšœ ˜—šŸœž œ ˜:Lšœžœ˜ Lšœžœ˜$KšœžœJ˜cšžœžœžœ˜"LšœZ˜ZLšžœž˜ L˜—Lšœo˜oLšœ#˜#Lšœ"˜"Lšœ8˜8Lšœ1˜1L˜Lšœ Οe˜—šŸ œž œžœ˜2Jš œžœžœžœžœ˜K•StartOfExpansion―[stream: STREAM, format: ROPE _ NIL, v1: IO.Value _ [null[]], v2: IO.Value _ [null[]], v3: IO.Value _ [null[]], v4: IO.Value _ [null[]], v5: IO.Value _ [null[]]]šžœ–˜˜šžœžœž˜ALš žœ:žœžœ1žœ3žœ#˜άLšž˜—Lšœ ˜ Lšœ ‘˜—šŸ œž œžœ˜/J™2Kšž˜L–[]šœ˜šžœžœžœž˜ALšœi˜iLšžœžœžœ˜-šžœžœžœžœžœ-žœ žœž˜ZLš œžœžœžœžœ˜Lšžœ'Οgœ%žœ žœžœžœžœžœžœ ˜ΨLšœ ˜ Lšœ€˜€Lšžœ˜—Lšœ ˜ Lšžœ˜—Kšžœ  ˜—šŸ œž œ/žœ˜\JšœD™DKšž˜Lš œžœžœžœ'žœ˜ašžœ  ˜Lš œžœžœžœžœ˜Kšœ žœ˜%š žœžœžœžœž˜2Lš žœ(žœžœ žœžœ˜SLšžœ˜—Lšœ žœ ˜šžœ žœ ž˜Lšœ žœ2˜>—šžœ žœ ž˜Lšœ žœ^˜j—šžœ žœž˜!Lšœ žœF˜R—šžœ žœž˜!Lšœ žœM˜Y—šžœžœž˜4šžœ ž˜Lšž˜Lš žœžœžœžœSžœ˜|LšžœžœLžœ˜pLšžœ˜—Lšžœ˜—Lšœ ˜ Lšžœ  ˜—šžœ  ˜Lš œžœžœžœžœ˜Lšœ žœ˜%š žœžœžœžœž˜2Lš žœ(žœžœ žœžœ˜SLšžœ˜—Lšœ žœ ˜šžœ žœ ž˜Lšœ žœ6˜B—šžœ žœ ž˜Lšœ žœN˜Z—šžœ žœž˜!Lšœ žœZ˜f—šžœ žœž˜!Lšœ žœ`˜l—šžœžœž˜4šžœ ž˜Lšž˜Lš žœžœžœžœSžœ˜|LšžœžœWžœ˜{Lšžœ˜—Lšžœ˜—Lšœ ˜ Lšžœ  ˜—Kšžœ ˜—šŸœž œ žœ žœ˜HJšœ.™.Kšž˜L–[]šœ‚˜‚š žœžœžœžœ2žœ žœž˜[Lš œžœžœžœžœ˜Lšœžœ˜LšžœXžœžœžœ˜ŠLšœ ˜ Lšžœžœžœ˜>š žœžœžœ0žœžœž˜RLš œžœžœžœžœ˜LšžœPžœCžœ˜Άšžœžœž˜ šœžœ˜Jšž˜Lšžœ¦žœžœ˜ΞLšžœžœžœ—˜ΈLšžœdžœ@˜¨Lšžœ˜—Lšœžœžœ|˜–Lšžœžœ¨˜΅—Lšžœ3˜5Lšžœ˜—Lšœ˜Lšžœ˜—Kšžœ ‘˜—šŸœž œžœ˜>J™?Kšž˜Lšœ2˜2šžœžœž˜8šžœžœž˜)Lšž˜Lš œžœžœžœžœ˜LšžœYžœ*˜‡šžœžœž˜2Lšžœ:žœ ˜Gšžœžœž˜2šžœ%žœž˜/Lšž˜Lšžœ1žœ žœ3žœ/˜¨Lšžœ˜—Jšžœ˜—Jšžœ#˜%Lšžœ˜—Lšœ˜Lšžœ˜—Lšžœ˜—Kšžœ ˜!—Kšœ˜Kšžœ˜—…—%,0ά