<> <> <> <> <> <> <> DIRECTORY CD, CDBasics, CDInstances USING [NewInst], CDOps USING [LayerRope], CDProperties USING [GetProp], CDRects USING [CreateBareRect], CDViewer USING [ViewerList, ViewersOf], CDViewHighlight USING [ShowInstance], CStitching, Properties USING [GetProp], RefTab USING [EachPairAction, Pairs], Rope USING [Cat], SX, SXAccessInternal, SXAtoms USING [SignalName, spinifex], SXHighlightNode, SXQuadTree USING [Dimension, Enumerate, PerRectProc], TerminalIO USING [PutRope, PutRopes]; SXHighlightNodeImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDInstances, CDOps, CDProperties, CDRects, CDViewer, CDViewHighlight, CStitching, Properties, 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.NewInst [ ob: CDRects.CreateBareRect [CDBasics.SizeOfRect[rect], CD.shadeLayer], trans: [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.GetLogicalCell[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.PutRope [Rope.Cat[" ", CDOps.LayerRope[lev], " is not conducting\n"]]; RETURN } ENDLOOP; }; ENDCASE => TerminalIO.PutRope ["technology does not support Spinifex\n"]; END; -- HighlightNode GoForIt: PROC [sd: REF SearchData, design: CD.Design, pos: CD.Position] = BEGIN AddSplodge: CStitching.TileProc = BEGIN <<[tile: TilePtr, data: REF ANY] >> rect: CD.Rect = CDBasics.MapRect[tile.Area, sd.rootTrans]; IncludeHighLight [design, rect]; END; dr: CD.DrawRef = CD.CreateDrawRef [[]]; nodeGeom: CStitching.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.pushTrans _ sd.rootTrans _ design.actual.first.mightReplace.trans }; dr.interestClip _ CDBasics.Extend [CDBasics.ToRect[pos, pos], 1]; <> CD.DrawOb[dr, design.actual.first.dummyCell.ob]; IF sd.node = NIL THEN { TerminalIO.PutRope [Rope.Cat[ " Failed to find geometry on layer \"", CDOps.LayerRope[sd.layer], "\" at indicated point.\n"]]; RETURN }; <> [sd.node, sd.applChain] _ sd.rootCir.FindRootNode[sd.node, sd.applChain]; WITH Properties.GetProp [sd.node.properties, SXAtoms.SignalName] SELECT FROM sig: REF SX.SignalName => { TerminalIO.PutRope [Rope.Cat [" Highlighting: ", sig.name,".\n"]] }; ENDCASE => { TerminalIO.PutRope [" Highlighting node.\n"] }; IF sd.applChain#NIL THEN -- Node appeared on some subcircuit, rather than root. sd.cir _ SXAccessInternal.GetLogicalCell[sd.applChain.first.ob].circuit ELSE sd.cir _ sd.rootCir; <> nodeGeom _ CStitching.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, pushTrans: CD.Transformation _ [], rootTrans: CD.Transformation _ [] ]; CompensateDummyCell: CD.DrawProc = BEGIN data: REF SearchData = NARROW [pr.devicePrivate]; oldClip: CD.Rect = pr.interestClip; pr.drawChild _ SearchChild; <> pr.interestClip _ CDBasics.DeMapRect[itemInWorld: oldClip, cellInWorld: data.pushTrans]; trans _ CDBasics.DecomposeTransform [itemInWorld: trans, cellInWorld: data.pushTrans]; <> SearchChild [pr, ob, trans, NIL]; pr.interestClip _ oldClip; pr.drawChild _ CompensateDummyCell END; -- CompensateDummyCell SearchChild: CD.DrawProc = BEGIN sx: REF SX.LogicalCell = SXAccessInternal.GetLogicalCell[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.rootTrans _ CDBasics.ComposeTransform[itemInCell: trans, cellInWorld: data.pushTrans]; }; pr.interestClip _ CDBasics.DeMapRect [ itemInWorld: oldClip, cellInWorld: trans]; IF cir # NIL THEN { FOR aList: CD.InstanceList _ cir.subcircuits, aList.rest WHILE aList # NIL DO appl _ aList.first; IF appl.trans=trans AND appl.ob=ob THEN EXIT; REPEAT FINISHED => {ERROR}; ENDLOOP; data.applChain _ CONS [appl, data.applChain]; }; CD.DrawOb[pr, ob]; 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.GetLogicalCell [ob]; IF sx#NIL AND sx.analysisState=notYetDone AND data.cir#NIL THEN { TerminalIO.PutRopes[" ", CD.Describe[ob, NIL, NIL], " has not been extracted\n"]; ERROR ABORTED }; CD.DrawOb[pr, ob, trans, readOnlyInstProps]; } 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.PutRope [" 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: CStitching.Tesselation] = BEGIN Compose: PROC [trans: CD.Transformation, applChain: LIST OF CD.Instance] RETURNS [comb: CD.Transformation] = BEGIN IF applChain.rest # NIL THEN { [comb] _ Compose [trans, applChain.rest]; comb _ CDBasics.ComposeTransform[itemInCell: applChain.first.trans, cellInWorld: trans]; } ELSE { comb _ CDBasics.ComposeTransform[itemInCell: applChain.first.trans, cellInWorld: trans]; } END; -- Compose PerCell: PROC [circuit: REF SX.Circuit, node: REF SX.CircuitNode, trans: CD.Transformation] = BEGIN PaintNode: SXQuadTree.PerRectProc = BEGIN <> IF r.nodeInformation=data THEN { newR: CD.Rect = CDBasics.MapRect [ itemInCell: SXQuadTree.Dimension [r], cellInWorld: trans]; 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.GetLogicalCell[applChain.first.ob].circuit; subnode: REF SX.CircuitNode = NARROW [key]; subTrans: CD.Transformation _ Compose [trans, applChain]; PerCell [subCircuit, subnode, subTrans]; } 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 trans: CD.Transformation _ []; ac: LIST OF CD.Instance = data.applChain; -- list of cells down to the node. IF ac#NIL THEN [trans] _ Compose [trans, ac]; PerCell [data.cir, data.node, trans] END; -- Paint END. <<>> <> <> <> <> <> <> <> <> <> <> <> <<>> <<>>