DIRECTORY Atom USING [GetPropFromList], CD USING [CreateDrawRef, Design, DrawProc, DrawRectProc, DrawRef, highLightShade, Instance, InstanceList, Layer, Orientation, original, Position, Rect], CDBasics USING [BaseOfRect, Extend, SizeOfRect, ToRect, universe], CDDirectory USING [Name], CDInstances USING [NewInstance], CDOps USING [LayerName], CDOrient USING [ComposeOrient, DecomposeOrient, DeMapRect, MapRect, RectAt], CDProperties USING [GetProp], CDRects USING [CreateBareRect], CDViewer USING [ViewerList, ViewersOf], CDViewHighlight USING [ShowInstance], CornerStitching, RefTab USING [EachPairAction, Pairs], Rope USING [Cat], SX, SXAccessInternal, SXAtoms USING [SignalName, spinifex], SXHighlightNode, SXQuadTree USING [Dimension, Enumerate, PerRectProc], TerminalIO USING [WriteRope]; SXHighlightNodeImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDDirectory, CDInstances, CDOps, CDOrient, CDProperties, CDRects, CDViewer, CDViewHighlight, CornerStitching, RefTab, Rope, SX, SXAccessInternal, SXAtoms, SXQuadTree, TerminalIO EXPORTS SXHighlightNode = BEGIN RemoveHighlightNode: PUBLIC PROC [design: CD.Design] = BEGIN vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; FOR list: CDViewer.ViewerList _ vl, list.rest WHILE list#NIL DO CDViewHighlight.ShowInstance[list.first, NIL, TRUE, $SX]; ENDLOOP; END; -- RemoveHighlightNode IncludeHighLight: PROC [design: CD.Design, rect: CD.Rect] = BEGIN vl: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; app: CD.Instance = CDInstances.NewInstance[ ob: CDRects.CreateBareRect[CDBasics.SizeOfRect[rect], CD.highLightShade], location: CDBasics.BaseOfRect[rect] ]; FOR list: CDViewer.ViewerList _ vl, list.rest WHILE list#NIL DO CDViewHighlight.ShowInstance[list.first, app, FALSE, $SX]; ENDLOOP; END; -- IncludeHighLight HighlightNode: PUBLIC PROC [design: CD.Design, pos: CD.Position, lev: CD.Layer] = BEGIN WITH CDProperties.GetProp[design.technology, SXAtoms.spinifex] SELECT FROM tpOK: REF SX.TechHandle => { FOR mapList: LIST OF SX.MapRec _ tpOK.cdLayerMapping[lev], mapList.rest WHILE mapList#NIL DO IF mapList.first.value = NIL THEN { rootCir: REF SX.Circuit = SXAccessInternal.GetSXData[design.actual.first.dummyCell.ob].circuit; data: REF SearchData _ NEW[SearchData _ [ layer: lev, nodeLayer: mapList.first.spinifexLayer, tech: tpOK, rootCir: rootCir, cir: rootCir ]]; GoForIt[data, design, pos]; RETURN }; REPEAT FINISHED => { TerminalIO.WriteRope[Rope.Cat[" ", CDOps.LayerName[lev], " is not conducting\n"]]; RETURN } ENDLOOP; }; ENDCASE => TerminalIO.WriteRope["technology does not support spinifex\n"]; END; -- HighlightNode GoForIt: PROC [sd: REF SearchData, design: CD.Design, pos: CD.Position] = BEGIN AddSplodge: CornerStitching.PerTileProc = BEGIN rect: CD.Rect = CDOrient.MapRect[tile.Area, sd.rootSize, sd.rootOrient, sd.rootPos]; IncludeHighLight[design, rect]; END; dr: CD.DrawRef = CD.CreateDrawRef[design]; nodeGeom: REF CornerStitching.Tesselation; RemoveHighlightNode[design]; dr.drawChild _ CompensateDummyCell; -- Used for outermost cell only, dr.drawChild set to SearchChild for recursive calls inside CompensateDummyCell. dr.drawRect _ CheckRect; dr.devicePrivate _ sd; IF design.actual.first.mightReplace#NIL THEN { sd.rootSize _ sd.pushSize _ design.actual.first.mightReplace.ob.size; sd.rootPos _ sd.pushPos _ design.actual.first.mightReplace.location; sd.rootOrient _ sd.pushOrient _ design.actual.first.mightReplace.orientation }; dr.interestClip _ CDBasics.Extend[CDBasics.ToRect[pos, pos], 1]; design.actual.first.dummyCell.ob.class.drawMe[design.actual.first.dummyCell, [0,0], CD.original, dr]; IF sd.node = NIL THEN { TerminalIO.WriteRope[ Rope.Cat[ " Failed to find geometry on layer: \"", CDOps.LayerName[sd.layer], "\" at indicated point.\n"]]; RETURN }; [sd.node, sd.applChain] _ sd.rootCir.FindRootNode[sd.node, sd.applChain]; WITH sd.node.properties.GetPropFromList[SXAtoms.SignalName] SELECT FROM sig: REF SX.SignalName => { TerminalIO.WriteRope[Rope.Cat[" Highlighting: ", sig.name,".\n"]] }; ENDCASE => { TerminalIO.WriteRope[" Highlighting node.\n"] }; IF sd.applChain#NIL THEN -- Node appeared on some subcircuit, rather than root. sd.cir _ SXAccessInternal.GetSXData[sd.applChain.first.ob].circuit ELSE sd.cir _ sd.rootCir; nodeGeom _ CornerStitching.NewTesselation[]; Paint[sd, nodeGeom]; [] _ nodeGeom.EnumerateArea[CDBasics.universe, AddSplodge]; END; -- GoForIt SearchData: TYPE = RECORD [ layer: CD.Layer, nodeLayer: SX.SpinifexLayerIndex, tech: REF SX.TechHandle, rootCir: REF SX.Circuit, -- Highest Spinifex SX.Circuit found in application chain. cir: REF SX.Circuit, node: REF SX.CircuitNode _ NIL, applChain: LIST OF CD.Instance _ NIL, pushSize: CD.Position _ [0,0], pushPos: CD.Position _ [0,0], pushOrient: CD.Orientation _ CD.original, rootSize: CD.Position _ [0,0], rootPos: CD.Position _ [0,0], rootOrient: CD.Orientation _ CD.original ]; CompensateDummyCell: CD.DrawProc = BEGIN data: REF SearchData = NARROW[pr.devicePrivate]; oldClip: CD.Rect = pr.interestClip; pr.drawChild _ SearchChild; pr.interestClip _ CDOrient.DeMapRect[itemInWorld: oldClip, cellSize: data.pushSize, cellInstOrient: data.pushOrient, cellInstPos: data.pushPos]; pos _ CDBasics.BaseOfRect[CDOrient.DeMapRect[ CDOrient.RectAt[pos: pos, size: inst.ob.size, orient: orient], data.pushSize, data.pushOrient, data.pushPos ]]; orient _ CDOrient.DecomposeOrient[orient, data.pushOrient]; SearchChild[inst, pos, orient, pr]; pr.interestClip _ oldClip; pr.drawChild _ CompensateDummyCell END; -- CompensateDummyCell SearchChild: CD.DrawProc = BEGIN sx: REF SX.LogicalCell = SXAccessInternal.GetSXData[inst.ob]; IF sx#NIL AND sx.circuit#NIL AND sx.analysisState=useCircuit THEN { subcircuit: REF SX.Circuit _ sx.circuit; data: REF SearchData = NARROW[pr.devicePrivate]; oldClip: CD.Rect = pr.interestClip; cir: REF SX.Circuit = data.cir; root: REF SX.Circuit = data.rootCir; appl: CD.Instance; oldChain: LIST OF CD.Instance = data.applChain; data.cir _ subcircuit; IF data.rootCir = NIL THEN { data.rootCir _ subcircuit; data.rootSize _ inst.ob.size; data.rootPos _ CDBasics.BaseOfRect[CDOrient.MapRect[ CDOrient.RectAt[pos: pos, size: data.rootSize, orient: orient], data.pushSize, data.pushOrient, data.pushPos ]]; data.rootOrient _ CDOrient.ComposeOrient[orient, data.pushOrient] }; pr.interestClip _ CDOrient.DeMapRect[ itemInWorld: oldClip, cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos ]; IF cir # NIL THEN { FOR aList: CD.InstanceList _ cir.subcircuits, aList.rest WHILE aList # NIL DO appl _ aList.first; IF appl.location=pos AND appl.orientation=orient AND appl.ob=inst.ob THEN EXIT; REPEAT FINISHED => { ERROR }; ENDLOOP; data.applChain _ CONS[appl, data.applChain]; }; inst.ob.class.drawMe[inst, [0,0], CD.original, pr]; IF cir # NIL THEN data.cir _ cir; IF pr.stopFlag^ = FALSE THEN { data.applChain _ oldChain; data.rootCir _ root }; pr.interestClip _ oldClip } ELSE { data: REF SearchData = NARROW[pr.devicePrivate]; sx: REF SX.LogicalCell = SXAccessInternal.GetSXData[inst.ob]; IF sx#NIL AND sx.analysisState=notYetDone AND data.cir#NIL THEN { TerminalIO.WriteRope[Rope.Cat[" ", CDDirectory.Name[inst.ob], " has not been extracted\n"]]; ERROR ABORTED }; inst.ob.class.drawMe[inst, pos, orient, pr] } END; -- SearchChild CheckRect: CD.DrawRectProc = BEGIN IF l = NARROW[pr.devicePrivate, REF SearchData].layer THEN { SearchNode: SXQuadTree.PerRectProc = BEGIN WITH r.nodeInformation SELECT FROM n: REF SX.CircuitNode => sData.node _ n; -- XXX FIX HERE, pr.stopFlag should be set only if node is found. ENDCASE; pr.stopFlag^ _ TRUE END; -- SearchNode sData: REF SearchData = NARROW[pr.devicePrivate]; IF sData.cir = NIL THEN { TerminalIO.WriteRope[" design has not been analyzed.\n"]; ERROR ABORTED }; SXQuadTree.Enumerate [quadTree: sData.cir.spinifexLayers[sData.nodeLayer], clipRect: pr.interestClip, PerRect: SearchNode] } END; -- CheckRect Paint: PROC [data: REF SearchData, protoPaint: REF CornerStitching.Tesselation] = BEGIN Compose: PROC [pos: CD.Position, orient: CD.Orientation, size: CD.Position, applChain: LIST OF CD.Instance] RETURNS [combPos: CD.Position, combOrient: CD.Orientation] = BEGIN IF applChain.rest # NIL THEN { [pos, orient] _ Compose[pos, orient, applChain.rest.first.ob.size, applChain.rest]; combPos _ CDBasics.BaseOfRect[CDOrient.MapRect[ CDOrient.RectAt[ pos: applChain.first.location, size: applChain.first.ob.size, orient: applChain.first.orientation ], applChain.rest.first.ob.size, orient, pos ]]; combOrient _ CDOrient.ComposeOrient[applChain.first.orientation, orient] } ELSE { combPos _ CDBasics.BaseOfRect[CDOrient.MapRect[ CDOrient.RectAt[ pos: applChain.first.location, size: applChain.first.ob.size, orient: applChain.first.orientation ], size, orient, pos ]]; combOrient _ CDOrient.ComposeOrient[applChain.first.orientation, orient] } END; -- Compose PerCell: PROC [circuit: REF SX.Circuit, node: REF SX.CircuitNode, pos: CD.Position, orient: CD.Orientation, size: CD.Position] = BEGIN PaintNode: SXQuadTree.PerRectProc = -- PROC [r: REF Rectangle, data: REF ANY] -- BEGIN IF r.nodeInformation=data THEN { newR: CD.Rect = CDOrient.MapRect[ itemInCell: SXQuadTree.Dimension [r], cellSize: size, cellInstOrient: orient, cellInstPos: pos ]; protoPaint.ChangeRect[newR, SXAtoms.spinifex] } END; -- PaintNode SearchForPortConnection: RefTab.EachPairAction = BEGIN FOR ml: SX.MergeRecList _ NARROW[val], ml.rest WHILE ml # NIL DO IF ml.first.becomes = node THEN { applChain: LIST OF CD.Instance = ml.first.applChain; subCircuit: REF SX.Circuit = SXAccessInternal.GetSXData[applChain.first.ob].circuit; subnode: REF SX.CircuitNode = NARROW[key]; subPos: CD.Position; subOrient: CD.Orientation; [subPos, subOrient] _ Compose[pos, orient, size, applChain]; PerCell[subCircuit, subnode, subPos, subOrient, applChain.first.ob.size]; } ENDLOOP; RETURN [FALSE] END; -- SearchForPortConnection FOR layer: SX.SpinifexLayerIndex IN [0..data.tech.numSpinifexLayers) DO SXQuadTree.Enumerate [quadTree: circuit.spinifexLayers[layer], clipRect: CDBasics.universe, PerRect: PaintNode, data: node] ENDLOOP; IF circuit.mergeDirectory#NIL THEN [] _ circuit.mergeDirectory.Pairs[SearchForPortConnection] END; -- PerCell pos: CD.Position _ [0,0]; orient: CD.Orientation _ CD.original; ac: LIST OF CD.Instance = data.applChain; -- list of cells down to the node. IF ac#NIL THEN [pos, orient] _ Compose[pos, orient, [0,0], ac]; PerCell[data.cir, data.node, pos, orient, IF ac = NIL THEN [0,0] ELSE ac.first.ob.size] END; -- Paint END. ΠSXHighlightNodeImpl.mesa Copyright c 1984, 1985 by Xerox Corporation. All rights reserved. Written by: Mark Shand, August 8, 1984 11:39:46 am PDT Last Edited by: Shand, September 3, 1984 5:51:16 am PDT Last Edited by: Jacobi, July 25, 1985 3:22:38 pm PDT Last edited by: gbb July 26, 1985 1:37:51 pm PDT IncludeHighLight: PROC [design: CD.Design, rect: CD.Rect] = BEGIN app: CD.Instance = CDInstances.NewInstance[ ob: CDRects.CreateBareRect[CDBasics.SizeOfRect[rect], CD.highLightShade], location: CDBasics.BaseOfRect[rect] ]; CDOps.IncludeInstance[design, app]; CDProperties.PutPropOnInstance[app, $highLightNode, $highLightNode]; END; -- IncludeHighLight RemoveHighlightNode: PUBLIC PROC [design: CD.Design] = BEGIN IsHighLight: PROC [app: CD.Instance] RETURNS [BOOL] = INLINE BEGIN RETURN [app=NIL OR CDProperties.GetPropFromInstance[app, $highLightNode]=$highLightNode ] END; al: CD.InstanceList _ CONS[NEW[CD.InstanceRep], CDOps.InstList[design]]; list: CD.InstanceList _ al; WHILE list.rest#NIL DO IF IsHighLight[list.rest.first] THEN { CDOps.DelayedRedraw[design, CDInstances.InstRectO[list.rest.first]]; list.rest _ list.rest.rest } ELSE list _ list.rest ENDLOOP; CDOps.SetInstList[design, al.rest]; END; -- RemoveHighlightNode OK if NIL! --[tile: TilePtr, data: REF ANY] -- -- find the node we wish to highlight. -- find the highest layer node to which the node we wish to highlight is merged. -- find all rectangles connected to the high-layer node. -- add rectangles to the currently pushed ChipNDale cell which cover all the rectangles in the highlighted node. -- PROC [aptr: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] -- For outermost cell transforms must be precompensated for transform compositions which occur in DrawMe. In subcells such precompensation is not required. -- Now really start searching. --PROC [aptr: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] --This object is a logical subcircuit. --PROC[r: Rect, l: Layer, pr: DrawRef] -- --PROC[r: REF Rectangle, data: REF ANY] -- --PROC[key: RefTab.Key, val: RefTab.Val] RETURNS [quit: BOOLEAN] -- Edited on March 4, 1985 4:23:17 pm PST, by Jacobi removing errors reprogrammed, without using drawprocs Edited on March 5, 1985 8:59:52 am PST, by Jacobi made readable Edited on April 8, 1985 2:51:21 pm PST, by Jacobi use of SXAccessInternal instead of properties; SpinifexCellPredicate removed Edited on May 6, 1985 11:26:55 am PDT, by Beretta Converted to ChipNDale CD20 Edited on July 25, 1985 3:20:45 pm PDT, by Jacobi Use of CDViewHighlight instead of changing the design I don't like the loop over all viewers, but I don't want to change the interface and can't know which is the right viewer... Κj˜code™Kšœ Οmœ7™BK™6K™7K™4K™0—šΟk ˜ Jšœžœ˜Kšžœ˜˜Jšœ žœ4˜BJšœ žœ˜Kšœ žœ˜ Kšœžœ ˜Jšœ žœ>˜LKšœ žœ ˜Jšœžœ˜Jšœ žœ˜'Jšœ%˜%Jšœ˜Jšœžœ˜&Jšœžœ˜Jšœ˜J˜Jšœžœ˜%Jšœ˜Kšœ žœ%˜5Jšœ žœ ˜—code2šΟbœžœž˜"Iunitšžœžœˆžœ3˜ΝMšžœ˜—Mšž˜šΟnœžœ žœžœ™;Kšž™šœžœ$™+Kšœ6žœ™IKšœ$™$Kšœ™—Kšœ#™#KšœD™DKšžœΟc™—š œž œ žœ ™6Jšž™š   œžœžœ žœžœ™5Jšžœž™ šžœžœžœ™JšœD™DJ™—Jšžœ™—Mš œžœžœžœžœ'™HJšœžœ™šžœ žœž™šžœžœ™&JšœD™DJšœ™J™—Jšžœ™Jšžœ™—Jšœ#™#Kšžœ‘™—š œžœžœ žœ ˜6Jšž˜Kšœ5˜5šžœ+žœžœž˜?Kšœ)žœžœ˜9Kšžœ˜—Kšžœ‘˜—š œžœ žœžœ˜;Kšž˜Kšœ5˜5šœžœ$˜+Kšœ6žœ˜IKšœ$˜$Kšœ˜—šžœ+žœžœž˜?Kšœ.žœ˜:Kšžœ˜—Kšžœ‘˜—š   œžœžœ žœžœžœ ˜QKšž˜šžœ;žœž˜Jšœžœžœ˜š žœ žœžœžœ1žœ žœž˜\šžœžœžœ˜#šœ žœžœP˜_Kšœžœ™ —šœžœžœ˜)Kšœ ˜ Kšœ(˜(Kšœ ˜ Kšœ˜Kšœ ˜ Kšœ˜—Kšœ˜Kšž˜K˜—šžœžœ˜KšœR˜RKšž˜K˜—Kšžœ˜—K˜—KšžœC˜J—Kšžœ‘˜—š  œžœžœžœžœ ˜IJšž˜šŸ œ ˜*Kš‘#œ™$Kšž˜KšœžœL˜TKšœ˜Kšžœ˜—Mšœžœ žœ˜*Kšœ žœ˜*Kšœ˜Kšœ$‘!œ ‘œ ‘œ‘˜”Kšœ˜Kšœ˜šžœ"žœžœ˜.KšœE˜EKšœD˜DKšœL˜LK˜—Kšœ@˜@Mšœ&™&JšœTžœ˜ešžœ žœžœ˜Jšœ˜Jšž˜J˜—MšœP™PKšœI˜Išžœ8žœž˜Gšœžœžœ˜KšœA˜AK˜—šžœ˜ Kšœ-˜-Kšœ˜——šžœžœžœ‘8˜QKšœB˜B—šž˜Kšœ˜—Mšœ8™8Jšœ,˜,Jšœ˜J˜Kšœp™pKšœ;˜;Kšžœ‘ ˜—šœ žœžœ˜Kšœžœ˜Kšœ!˜!Kšœžœ˜Kšœ žœ ‘;˜TKšœžœ ˜Kšœžœžœ˜Kš œ žœžœžœ žœ˜%Kšœ žœ˜Kšœ žœ˜Kšœ žœžœ ˜)Kšœ žœ˜Kšœ žœ˜Kšœ žœžœ ˜(K˜—šŸœžœ ˜"Kšœb™bKšž˜Kšœžœžœ˜0Kšœ žœ˜#Kšœ˜K™œKšœ˜šœ-˜-Kšœ?˜?Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—Kšœ;˜;K™Kšœ#˜#Kšœ˜Kšœ"˜"Kšžœ‘˜—š Ÿœžœ ˜Kšœa™aKšž˜Kšœžœžœ3˜=š žœžœžœ žœžœžœ˜CK™&Kšœ žœžœ˜(Kšœžœžœ˜0Kšœ žœ˜#Kšœžœžœ˜Kšœžœžœ˜$Kšœžœ ˜Kšœ žœžœžœ˜/Kšœ˜šžœžœžœ˜Kšœ˜Kšœ˜šœ4˜4Kšœ@˜@Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—KšœA˜AK˜—šœ%˜%Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—šžœžœžœ˜š žœžœ,žœ žœž˜MKšœ˜Kš žœžœžœžœžœ˜Ošžœžœ˜Kšž˜K˜—Kšžœ˜—Kšœžœ˜,Kšœ˜—Kšœ"žœ˜3Kšžœžœžœ˜!šžœžœžœ˜Kšœ˜Kšœ˜K˜—Kšœ˜Kšœ˜—šžœ˜Kšœžœžœ˜0Kšœžœžœ3˜=š žœžœžœžœ žœžœ˜AKšœ]˜]Kšžœž˜ K˜—Kšœ+˜+K˜—Kšžœ‘˜—šŸ œžœ˜Jšœ*™*Jšž˜šžœžœžœžœ˜<šŸ œ˜%Kšœ+™+Kšž˜šžœžœž˜"Kšœžœžœ ‘A˜jKšžœ˜—Kšœž˜Kšžœ‘ ˜—Mšœžœžœ˜1šžœ žœžœ˜Kšœ9˜9Kšžœž˜ Kšœ˜—Kšœz˜zK˜—Jšžœ‘ ˜—š œžœžœžœ˜QJšž˜š œžœžœžœžœžœžœžœ žœ žœžœ˜¨Kšž˜šžœžœžœ˜KšœS˜Sšœ/˜/šœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜—Kšœ˜Kšœ˜Kšœ˜Kšœ˜—KšœH˜HK˜—šžœ˜šœ/˜/šœ˜Kšœ˜Kšœ˜Kšœ#˜#Kšœ˜—Kšœ˜Kšœ˜Kšœ˜Kšœ˜—KšœH˜HKšœ˜—Kšžœ‘ ˜—š œžœ žœžœžœžœžœžœ ˜€Jšž˜šŸ œ‘,œ˜QKšž˜šžœžœ˜ šœžœ˜!Kšœ%˜%Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ-˜-K˜—Kšžœ‘ ˜—šŸœΠck˜1KšœD™DKšž˜š žœžœžœžœžœž˜@šžœžœ˜!Kšœ žœžœžœ˜4Kšœ žœžœC˜UKšœ žœžœžœ˜*Kšœžœ ˜Kšœ žœ ˜Kšœ<˜