DIRECTORY Asserting, CD, CDApplications, CDCells, CDDirectory, CDOps, CDSequencer, CDViewer, Graphs, IO, MessageWindow, Real, Rope, RoseCreate, RoseDisplayInsides, RoseTypes, SXHighlightNode; RoseHighlightInCD: CEDAR PROGRAM IMPORTS Asserting, CDApplications, CDCells, CDDirectory, CDOps, CDSequencer, CDViewer, IO, MessageWindow, Real, Rope, RoseCreate, SXHighlightNode EXPORTS RoseDisplayInsides =BEGIN OPEN RoseTypes; Complain: ERROR [msg: ROPE] = CODE; Transform: TYPE = RECORD [dxdx, dxdy, dx, dydx, dydy, dy: REAL]; layerTableSize: NAT = 5; layerTable: ARRAY [0 .. layerTableSize) OF RECORD [strKey: ATOM, cdLayer: CD.Layer] = [ [$nDiffusion, 7--ndif--], [$pDiffusion, 12--pdif--], [$Poly, 6--pol--], [$Metal, 8--met--], [$Metal2, 15--met2--] ]; HighlightNode: PUBLIC PROC [link: Graphs.Link, data: REF ANY] --Graphs.LinkConsumerProc-- = { ENABLE Complain => {MessageWindow.Append[msg, TRUE]; MessageWindow.Blink[]; CONTINUE}; WITH link.otherSide.rep SELECT FROM ne: RoseDisplayInsides.NodeElt => Highlight[ne.node]; ENDCASE => Complain["Can only highlight a Node"]; }; Highlighting: TYPE = REF HighlightingRep; HighlightingRep: TYPE = RECORD [ node: Node, cdDesign: CD.Design, loc: CD.DesignPosition _ [0, 0], cdLayer: CD.Layer _ CD.backGround ]; hl: Highlighting; Doit: PROC [CDSequencer.Command] = { ENABLE Complain => {MessageWindow.Append[msg, TRUE]; MessageWindow.Blink[]; CONTINUE}; PushTo[hl.cdDesign, hl.node.cellIn.parent]; SXHighlightNode.HighlightNode[design: hl.cdDesign, pos: hl.loc, lev: hl.cdLayer]; }; Highlight: PROC [node: Node] = { sim: Simulation _ node.strIn.sim; designName: ROPE _ NARROW[Asserting.FnVal[$DesignName, node.other]]; hl _ NEW [HighlightingRep _ [node: node, cdDesign: CDViewer.FindDesign[designName]]]; IF hl.cdDesign = NIL THEN Complain[IO.PutFR["No such design as %g", IO.refAny[designName]]]; [hl.loc, hl.cdLayer] _ UpLoc[node, 1]; IF node.cellIn = NIL THEN ERROR; IF node.cellIn.parent = NIL THEN Complain["Too shallow"]; CDSequencer.ExecuteProc[design: hl.cdDesign, proc: Doit]; }; UpLoc: PROC [node: Node, levels: INT] RETURNS [loc: CD.DesignPosition, lev: CD.Layer] = { locHint: LORA _ Asserting.FnVals[$locHint, node.other]; layerAtom: ATOM; cell: Cell; IF locHint = NIL THEN Complain["No location hint"]; loc.x _ Real.RoundLI[ToReal[locHint.first]*CD.lambda]; loc.y _ Real.RoundLI[ToReal[locHint.rest.first]*CD.lambda]; layerAtom _ NARROW[locHint.rest.rest.first]; FOR i: INT IN [0 .. layerTableSize) DO IF layerTable[i].strKey = layerAtom THEN {lev _ layerTable[i].cdLayer; EXIT}; REPEAT FINISHED => Complain[IO.PutFR["Layer %g unrecognized", IO.atom[layerAtom]]]; ENDLOOP; cell _ node.cellIn; FOR i: INT IN [1 .. levels] DO ct: CellType _ cell.type; toParent: Transform _ GetInstanceTransform[cell]; loc _ TransformPos[toParent, loc]; cell _ cell.parent; ENDLOOP; cell _ cell; }; GetInstanceTransform: PROC [cell: Cell] RETURNS [it: Transform] = { t6: LORA _ Asserting.FnVals[$t6, cell.other]; IF t6 = NIL THEN Complain[IO.PutFR["No instance transform for %g", IO.rope[RoseCreate.LongCellName[cell]]]]; it.dxdx _ ToReal[t6.first]; it.dxdy _ ToReal[t6.rest.first]; it.dx _ ToReal[t6.rest.rest.first]*CD.lambda; it.dydx _ ToReal[t6.rest.rest.rest.first]; it.dydy _ ToReal[t6.rest.rest.rest.rest.first]; it.dy _ ToReal[t6.rest.rest.rest.rest.rest.first]*CD.lambda; }; GetInstanceBounds: PROC [cell: Cell] RETURNS [bounds: CD.Rect] = { typeBounds: CD.Rect; it: Transform _ GetInstanceTransform[cell]; bb: LORA _ Asserting.FnVals[$bb, cell.type.other]; IF bb = NIL THEN Complain[IO.PutFR["No bounding box for %g", IO.rope[cell.type.name]]]; typeBounds.x1 _ Real.RoundLI[ToReal[bb.first]*CD.lambda]; typeBounds.y1 _ Real.RoundLI[ToReal[bb.rest.first]*CD.lambda]; typeBounds.x2 _ Real.RoundLI[ToReal[bb.rest.rest.first]*CD.lambda]; typeBounds.y2 _ Real.RoundLI[ToReal[bb.rest.rest.rest.first]*CD.lambda]; bounds _ TransformRect[it, typeBounds]; }; ToInt: PROC [ra: REF ANY] RETURNS [i: INT] = { WITH ra SELECT FROM ri: REF INT => i _ ri^; ENDCASE => Complain[IO.PutFR["Not INT: %g", IO.refAny[ra]]]; }; ToReal: PROC [ra: REF ANY] RETURNS [r: REAL] = { WITH ra SELECT FROM ri: REF INT => r _ ri^; rr: REF REAL => r _ rr^; ENDCASE => Complain[IO.PutFR["Not REAL: %g", IO.refAny[ra]]]; }; TransformPos: PROC [t: Transform, p: CD.Position] RETURNS [tp: CD.Position] = { tp.x _ Real.RoundLI[t.dxdx*p.x + t.dxdy*p.y + t.dx]; tp.y _ Real.RoundLI[t.dydx*p.x + t.dydy*p.y + t.dy]; }; TransformRect: PROC [t: Transform, r: CD.Rect] RETURNS [tr: CD.Rect] = { Maxin: PROC [x, y: CD.Number] = { p: CD.Position _ TransformPos[t, [x, y]]; tr.x1 _ MIN[tr.x1, p.x]; tr.y1 _ MIN[tr.y1, p.y]; tr.x2 _ MAX[tr.x2, p.x]; tr.y2 _ MAX[tr.y2, p.y]; }; [[tr.x1, tr.y1]] _ [[tr.x2, tr.y2]] _ TransformPos[t, [r.x1, r.y1]]; Maxin[r.x1, r.y2]; Maxin[r.x2, r.y1]; Maxin[r.x2, r.y2]; }; CellList: TYPE = LIST OF Cell; PushTo: PROC [design: CD.Design, cell: Cell] = { path: CellList _ NIL; AtTop: PROC RETURNS [atTop: BOOL] = {atTop _ Rope.Equal[CDDirectory.Name[design.actual.first.dummyCell.ob], path.first.type.name]}; IF NOT InCD[cell] THEN ERROR; FOR cur: Cell _ cell, cur.parent WHILE InCD[cur] DO path _ CONS[cur, path]; ENDLOOP; WHILE design.actual.rest # NIL AND NOT AtTop[] DO IF NOT CDCells.PopFromCell[design] THEN Complain["Couldn't pop"]; ENDLOOP; IF NOT AtTop[] THEN Complain[IO.PutFR["Couldn't pop to %g", IO.rope[RoseCreate.LongCellName[path.first]]]]; FOR path _ path, path.rest WHILE path.rest # NIL DO PushStep[design, path.first, path.rest.first]; ENDLOOP; cell _ cell; }; InCD: PROC [cell: Cell] RETURNS [in: BOOL] = {in _ Asserting.FnVals[$scale, cell.type.other] # NIL}; PushStep: PROC [design: CD.Design, parent, child: Cell] = { childBounds: CD.Rect _ GetInstanceBounds[child]; count: INT _ 0; FOR al: CD.ApplicationList _ CDOps.AppList[design], al.rest WHILE al # NIL DO this: BOOL _ CDApplications.ARectI[al.first] = childBounds; IF this THEN count _ count + 1; al.first.selected _ FALSE; ENDLOOP; IF count # 1 THEN Complain[IO.PutFR["%g child (named %g, at %g) of %g", IO.rope[IF count = 0 THEN "Couldn't find any" ELSE "Found more than one"], IO.refAny[child.name], IO.rope[FmtRect[childBounds]], IO.rope[RoseCreate.LongCellName[parent]]]]; IF NOT CDCells.PushInCellSelected[design] THEN Complain[IO.PutFR["Couldn't push into %g", IO.rope[RoseCreate.LongCellName[child]]]]; }; FmtRect: PROC [r: CD.Rect] RETURNS [rope: ROPE] = { rope _ IO.PutFR["[%g, %g, %g, %g]", IO.int[r.x1], IO.int[r.y1], IO.int[r.x2], IO.int[r.y2]]; }; END. jRoseHighlightInCD.mesa Last Edited by: Spreitzer, July 2, 1985 6:07:07 pm PDT Pop tward path.first Κέ– "cedar" style˜Icode™K™6K˜KšΟk œ œNœX˜ΏK˜šΠbxœœ˜ KšœPœ8˜‘Kšœ˜K˜Kšœœœ ˜K˜Kšœ œœœ˜#K˜Kšœ œœ"œ˜@K˜Kšœœ˜K˜š œ œœœ œ œ ˜WKšœΟcœ˜KšœŸœ˜Kšœ Ÿœ˜Kšœ Ÿœ˜Kšœ Ÿœ˜K˜—K˜š Οn œœœœœŸœ˜]Kšœ(œœ˜Všœœ˜#Kšœ5˜5Kšœ*˜1—K˜—K˜Kšœœœ˜)šœœœ˜ K˜ Kšœ œ˜Kšœœ˜ Kšœ œ œ ˜!K˜—K˜Kšœ˜K˜š œœ˜$Kšœ(œœ˜VKšœ+˜+KšœQ˜QKšœ˜—K˜š  œœ˜ K˜!Kšœ œœ+˜DKšœœM˜UKš œœœ œœ˜\Kšœ&˜&Kšœœœœ˜ Kšœœœ˜9Kšœ9˜9K˜—K˜š  œœœœœœ ˜YKšœ œ*˜7Kšœ œ˜K˜ Kšœ œœ˜3Kšœ+œ ˜6Kšœ0œ ˜;Kšœ œ˜,šœœœ˜&Kšœ"œœ˜Mš˜Kšœ œ œ˜L—Kšœ˜—K˜šœœœ˜K˜K˜1K˜"K˜Kšœ˜—K˜ K˜—K˜š œœœ˜CKšœœ%˜-Kš œœœ œ'œ'˜lK˜K˜ Kšœ#œ˜-Kšœ*˜*K˜/Kšœ2œ˜Kšœ8œ ˜CKšœ=œ ˜HKšœ'˜'K˜—K˜š  œœœœœœ˜.šœœ˜Kšœœœ ˜Kšœ œœ˜<—K˜—K˜š  œœœœœœ˜0šœœ˜Kšœœœ ˜Kšœœœ ˜Kšœ œœ˜=—K˜—K˜š   œœœ œœ˜OK˜4K˜4K˜—K˜š   œœœœœ ˜Hš œœœ ˜!Kšœœ$˜)Kšœœ ˜Kšœœ ˜Kšœœ ˜Kšœœ ˜K˜—KšœD˜DK˜K˜K˜K˜—K˜Kšœ œœœ˜K˜š œœ œ˜0Kšœœ˜š œœœ œ˜#Kšœ_˜_—Kšœœ œœ˜šœœ ˜3Kšœœ ˜Kšœ˜—K™š œœœœ ˜1Kšœœœ˜AKšœ˜—Kš œœ œ œœ-˜kšœœ œ˜3K˜.Kšœ˜—K˜ K˜—K˜š œœœœ˜,Kšœ2œ˜7—K˜š œœ œ!˜;Kšœ œ!˜0Kšœœ˜š œœ2œœ˜MKšœœ1˜;Kšœœ˜Kšœœ˜Kšœ˜—Kšœ œ œ+œœ œœœœœ)˜τKš œœ$œ œ œ(˜„K˜—K˜š  œœœœœ˜3Kš œœœ œ œ œ ˜\K˜—K˜Kšœ˜——…—f!­