<<>> <> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDCommandOps, CDCommandOpsExtras2, CDHierarchyMarks, CDInstances, CDOps, CDProperties, CDRects, CDSequencer, CDSimpleOps, CDViewer, CDViewHighlight, RuntimeError USING [UNCAUGHT], TerminalIO, ViewerClasses USING [Viewer]; CDHierarchyMarksImpl: CEDAR MONITOR IMPORTS CD, CDInstances, CDBasics, CDCells, CDCommandOps, CDCommandOpsExtras2, CDOps, CDProperties, CDRects, CDSequencer, CDSimpleOps, CDViewer, CDViewHighlight, RuntimeError, TerminalIO EXPORTS CDHierarchyMarks = BEGIN SetHierarchyMarkProc: TYPE = CDHierarchyMarks.SetHierarchyMarkProc; myKey: ATOM _ $CDHierarchyMark; GetHierarchyMark: PUBLIC PROC [design: CD.Design_NIL, ob: CD.Object_NIL] RETURNS [inst: CD.Instance_NIL] = { GetFrom: PROC [x: REF] RETURNS [inst: CD.Instance_NIL] = { WITH CDProperties.GetProp[x, myKey] SELECT FROM i: CD.Instance => RETURN [i]; ENDCASE => NULL; }; IF ob#NIL THEN inst _ GetFrom[ob] ELSE IF design#NIL THEN inst _ GetFrom[design]; }; ReallySetHierarchyMark: PROC [design: CD.Design, ob: CD.Object_NIL, inst: CD.Instance] = { i2: CD.Instance; inst _ CDInstances.Copy[inst]; IF design=NIL THEN { IF ob#NIL THEN CDProperties.PutProp[ob, myKey, inst] } ELSE { IF ob=NIL THEN { CDProperties.PutProp[design, myKey, inst]; <<--put it also to the real top level cell>> FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO IF list.first.mightReplace=NIL THEN CDProperties.PutProp[list.first.dummyCell.ob, myKey, inst] ENDLOOP; } ELSE { <<--put property to both, the mightReplace and the dummyCell, if it should go on either>> FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO IF list.first.dummyCell.ob=ob THEN { CDProperties.PutProp[ob, myKey, inst]; IF list.first.mightReplace=NIL THEN CDProperties.PutProp[design, myKey, inst] ELSE { i2 _ CDInstances.DeComposed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation]; CDProperties.PutProp[list.first.mightReplace.ob, myKey, i2]; }; RETURN; } ENDLOOP; FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO IF list.first.mightReplace#NIL AND list.first.mightReplace.ob=ob THEN { CDProperties.PutProp[ob, myKey, inst]; i2 _ CDInstances.Composed[inst, list.first.mightReplace.location, list.first.mightReplace.ob.size, list.first.mightReplace.orientation]; CDProperties.PutProp[list.first.dummyCell.ob, myKey, i2]; RETURN; } ENDLOOP; <<--an ordinary cell; no pushed in state...>> CDProperties.PutProp[ob, myKey, inst] }; }; }; SetHierarchyMark: PUBLIC PROC [design: CD.Design, ob: CD.Object_NIL, inst: CD.Instance] = { FOR list: LIST OF SetHierarchyMarkProc _ regList, list.rest WHILE list#NIL DO list.first[design, ob, inst ! RuntimeError.UNCAUGHT => CONTINUE]; ENDLOOP; }; regList: LIST OF SetHierarchyMarkProc; RegisterHierarchyMarker: PUBLIC ENTRY PROC [setHierarchyMark: SetHierarchyMarkProc] = { IF setHierarchyMark#NIL THEN { IF regList=NIL THEN regList _ LIST[setHierarchyMark] ELSE FOR list: LIST OF SetHierarchyMarkProc _ regList, list.rest DO IF list.rest=NIL THEN {list.rest _ LIST[setHierarchyMark]; EXIT} ENDLOOP }; }; <<>> <<--########################>> RemDisplayHierachyMarkComm: PROC [comm: CDSequencer.Command] = { viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer#NIL THEN CDViewHighlight.ShowInstance[v: viewer, key: myViewKey] }; PutHierachyMarkComm: PROC [comm: CDSequencer.Command] = { selected: CD.Instance _ CDCommandOps.TheInstance[comm, "place the hierarchy mark"]; IF selected#NIL THEN { IF ~CDCells.IsPushedIn[comm.design] THEN SetHierarchyMark[comm.design, NIL, selected] ELSE SetHierarchyMark[comm.design, comm.design.actual.first.dummyCell.ob, selected]; TDisplayHierarchyMarkComm[comm]; }; }; SelectHierachyMarkComm: PROC [comm: CDSequencer.Command] = { Match: PROC [i1, i2: CD.Instance] RETURNS [BOOL] = INLINE { RETURN [i1.ob=i2.ob AND i1.location=i2.location AND i1.orientation=i2.orientation] }; inst: CD.Instance; TerminalIO.WriteRope["Select hierarchy mark\n"]; IF CDCells.IsPushedIn[comm.design] THEN { mr: CD.Instance _ comm.design.actual.first.mightReplace; inst _ GetHierarchyMark[comm.design, mr.ob]; IF inst#NIL THEN inst _ CDInstances.Composed[inst, mr.location, mr.ob.size, mr.orientation]; } ELSE inst _ GetHierarchyMark[comm.design, NIL]; IF inst=NIL THEN TerminalIO.WriteRope["no hierarchy mark is set\n"] ELSE { CDSimpleOps.DeselectAll[comm.design]; FOR il: CD.InstanceList _ CDOps.InstList[comm.design], il.rest WHILE il#NIL DO IF Match[il.first, inst] THEN { il.first.selected _ TRUE; CDOps.RedrawInstance[comm.design, il.first, FALSE]; }; ENDLOOP; }; }; TDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = { <<--T=>Top>> startInst: CD.Instance _ comm.design.actual.first.mightReplace; IF startInst=NIL THEN startInst _ comm.design.actual.first.dummyCell; DisplayHierarchyMarks[comm.design, LIST[startInst], comm]; }; ADisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = { <<--A=>Selected from top level>> DisplayHierarchyMarks[comm.design, CDOps.InstList[comm.design], comm]; }; SDisplayHierarchyMarkComm: PROC [comm: CDSequencer.Command] = { <<--S=>All from top level>> DisplayHierarchyMarks[comm.design, CDInstances.SplitSelected[CDOps.InstList[comm.design]].selected, comm]; }; myViewKey: ATOM _ NIL; --$CDHierarchyMark; CreateEmptyCell: PROC [] RETURNS [cell: CD.Object] = { cell _ CDCells.CreateEmptyCell[]; CDCells.SetSimplificationTreshhold[cell, 0]; }; MakeMarker: PROC [highlightInst: CD.Instance, mark: CD.Rect, lambda: CD.Number_2] = { mOb: CD.Object _ CreateEmptyCell[]; d: CD.Number _ MAX[lambda, MIN[mark.x2-mark.x1, mark.y2-mark.y1]/20]; lineOb: CD.Object; lineOb _ CDRects.CreateRect[size: [mark.x2-mark.x1+2*d, d], l: CD.shadeLayer]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, -d]]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, mark.y2-mark.y1]]; lineOb _ CDRects.CreateRect[size: [d, mark.y2-mark.y1], l: CD.shadeLayer]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [-d, 0]]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, position: [mark.x2-mark.x1, 0]]; [] _ CDCells.RepositionCell[mOb, NIL]; [] _ CDCells.IncludeOb[cell: highlightInst.ob, ob: mOb, position: CDBasics.BaseOfRect[mark]]; }; foundAndStop: SIGNAL [ig: CD.Instance] = CODE; <<--ig in global design coordinates>> DontDrawRects: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = {}; DrawChild: PROC [inst: CD.Instance, pos: CD.Position, orient: CD.Orientation, pr: REF CD.DrawInformation] = { searchInst: CD.Instance _ NARROW[pr.devicePrivate]; IF searchInst.ob=inst.ob AND searchInst.location=pos AND searchInst.orientation=orient THEN { ig: CD.Instance _ CDInstances.NewInst[inst.ob, pos, orient]; SIGNAL foundAndStop [ig] }; }; DisplayHierarchyMarks: PROC [design: CD.Design, il: CD.InstanceList, viewerHint: REF] = { highlightInst: CD.Instance _ NIL; GoDown: PROC [fromInst: CD.Instance] = { <<--fromInst in global world coordinate system>> foundInst, markInst: CD.Instance _ NIL; multiple: BOOL _ FALSE; IF CDProperties.GetProp[fromInst.ob, $IconFor]#NIL THEN RETURN; markInst _ GetHierarchyMark[design, fromInst.ob]; IF markInst#NIL THEN { pr.devicePrivate _ CDInstances.Composed[markInst, fromInst.location, fromInst.ob.size, fromInst.orientation]; fromInst.ob.class.drawMe[inst: fromInst, pos: fromInst.location, orient: fromInst.orientation, pr: pr ! foundAndStop => { IF foundInst=NIL THEN {foundInst _ ig; RESUME} ELSE {multiple _ TRUE; CONTINUE} } ]; IF foundInst#NIL THEN { IF multiple THEN TerminalIO.WriteRopes["****multiple hierarchymarks in ", CDCommandOps.InstRope[fromInst], "\n"] ELSE { IF highlightInst=NIL THEN highlightInst _ CDInstances.NewInst[CreateEmptyCell[]]; MakeMarker[highlightInst, CDInstances.InstRectI[foundInst], design.technology.lambda]; GoDown[foundInst]; }; }; } }; pr: CD.DrawRef _ CD.CreateDrawRef[inf: [ design: design, drawChild: DrawChild, drawRect: DontDrawRects ]]; FOR list: CD.InstanceList _ il, list.rest WHILE list#NIL DO GoDown[list.first]; IF CDSequencer.Aborted[design] THEN EXIT; ENDLOOP; IF highlightInst=NIL THEN TerminalIO.WriteRope["no hierarchy marks set\n"] ELSE { [] _ CDCells.RepositionCell[highlightInst.ob, NIL]; highlightInst.location _ CDBasics.NegOffset[CD.ClientOrigin[highlightInst.ob]]; }; FOR vL: CDViewer.ViewerList _ CDViewer.ViewersOf[viewerHint], vL.rest WHILE vL#NIL DO CDViewHighlight.ShowInstance[v: vL.first, instOrList: highlightInst, key: myViewKey]; ENDLOOP }; <<>> <<--########################>> [] _ CDProperties.RegisterProperty[myKey, $CDHierarchyMarks]; RegisterHierarchyMarker[ReallySetHierarchyMark]; <<>> <<--########################>> CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Place hierarchy mark", proc: PutHierachyMarkComm, key: $CDHierarchyMarksPut]; CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks top", proc: TDisplayHierarchyMarkComm, key: $CDHierarchyMarksTDisplay]; CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks selected", proc: SDisplayHierarchyMarkComm, key: $CDHierarchyMarksSDisplay]; CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Display hierarchy marks all", proc: ADisplayHierarchyMarkComm, key: $CDHierarchyMarksADisplay]; CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Un-display hierarchy marks", proc: RemDisplayHierachyMarkComm, key: $CDHierarchyMarksUnDisplay]; CDCommandOpsExtras2.RegisterWithMenu[menu: $ProgramMenu, entry: "Select hierarchy mark", proc: SelectHierachyMarkComm, key: $CDHierarchyMarksSelect]; <<--########################>> END.