<<>> <> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDCommandOps, CDHierarchyMarks, CDInstances, CDOps, CDProperties, CDRects, CDSequencer, CDViewer, CDViewHighlight, RuntimeError USING [UNCAUGHT], TerminalIO, ViewerClasses USING [Viewer]; CDHierarchyMarksImpl: CEDAR MONITOR IMPORTS CD, CDInstances, CDBasics, CDCells, CDCommandOps, CDOps, CDProperties, CDRects, CDSequencer, 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] = { <<--inst must be in the coordinate system of ob!>> 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 { <<--put it to the design and to the real top level dummy cell>> CDProperties.PutProp[design, myKey, inst]; CDProperties.PutProp[CDOps.RealTopCell[design], myKey, inst]; } ELSE { <<--put property to both, the mightReplace and the dummyCell, if it should go on either>> CDProperties.PutProp[ob, myKey, inst]; <<--fancy cases when we are pushed in to this cell>> FOR list: LIST OF CD.PushRec _ design.actual, list.rest WHILE list#NIL DO IF list.first.dummyCell.ob=ob THEN { <<--we assume inst to be in design coordinates>> IF list.first.mightReplace=NIL THEN CDProperties.PutProp[design, myKey, inst] ELSE { i2 _ CDInstances.DeComposed[inst, list.first.mightReplace.trans]; CDProperties.PutProp[list.first.mightReplace.ob, myKey, i2]; }; RETURN; }; IF list.first.mightReplace#NIL AND list.first.mightReplace.ob=ob THEN { <<--we assume inst to be in cell coordinates>> i2 _ CDInstances.Composed[inst, list.first.mightReplace.trans]; CDProperties.PutProp[list.first.dummyCell.ob, myKey, i2]; RETURN; }; ENDLOOP; }; }; }; 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 _ CDOps.TheInstance[comm.design, "place the hierarchy mark\n"]; IF selected#NIL THEN { SetHierarchyMark[comm.design, CDOps.PushedTopCell[comm.design], selected]; TDisplayHierarchyMarkComm[comm]; }; }; SelectHierachyMarkComm: PROC [comm: CDSequencer.Command] = { Match: PROC [i1, i2: CD.Instance] RETURNS [BOOL] = INLINE { RETURN [i1.ob=i2.ob AND i1.trans=i2.trans] }; inst: CD.Instance; found: INT _ 0; TerminalIO.PutRope["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.trans]; } ELSE inst _ GetHierarchyMark[comm.design, NIL]; IF inst=NIL THEN TerminalIO.PutRope["no hierarchy mark is set\n"] ELSE { CDOps.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; found _ found+1; CDOps.RedrawInstance[comm.design, il.first, FALSE]; }; ENDLOOP; IF found#1 THEN TerminalIO.PutRope["hierarchy mark not unique\n"] }; }; 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, trans: [[-d, -d]]]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[-d, mark.y2-mark.y1]]]; lineOb _ CDRects.CreateRect[size: [d, mark.y2-mark.y1], l: CD.shadeLayer]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[-d, 0]]]; [] _ CDCells.IncludeOb[cell: mOb, ob: lineOb, trans: [[mark.x2-mark.x1, 0]]]; [] _ CDCells.ResizeCell[NIL, mOb]; [] _ CDCells.IncludeOb[cell: highlightInst.ob, ob: mOb, trans: [CDBasics.BaseOfRect[mark]]]; }; foundAndStop: SIGNAL [ig: CD.Instance] = CODE; <<--ig in global design coordinates>> DontDrawRects: CD.DrawRectProc = {}; DontDrawContext: CD.DrawContextProc = {}; DrawChild: CD.DrawProc = { searchInst: CD.Instance _ NARROW[pr.devicePrivate]; IF searchInst.ob=ob AND searchInst.trans=trans THEN { ig: CD.Instance _ CDInstances.NewInst[ob, trans]; SIGNAL foundAndStop [ig] }; }; DisplayHierarchyMarks: PROC [design: CD.Design, il: CD.InstanceList, viewerHint: REF] = { <<--il in global design coordinate system>> highlightInst: CD.Instance _ NIL; GoDown: PROC [fromInst: CD.Instance] = { <<--fromInst in global design coordinate system>> foundInst: CD.Instance _ NIL; --will be in design coordinate system markInst: CD.Instance _ NIL; --will be in fromInst.ob's coordinate system 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.trans]; --get design coords <<--draw in design coords>> fromInst.ob.class.drawMe[ob: fromInst.ob, trans: fromInst.trans, pr: pr ! foundAndStop => { IF foundInst=NIL THEN {foundInst _ ig; RESUME} ELSE {multiple _ TRUE; CONTINUE} } ]; IF foundInst#NIL THEN { IF multiple THEN TerminalIO.PutRopes["****multiple hierarchymarks in ", CDOps.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, drawContext: DontDrawContext ]]; 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.PutRope["no hierarchy marks set\n"] ELSE { [] _ CDCells.ResizeCell[NIL, 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]; <<>> <<--########################>> CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "place hierarchy mark", proc: PutHierachyMarkComm, key: $CDHierarchyMarksPut]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks top", proc: TDisplayHierarchyMarkComm, key: $CDHierarchyMarksTDisplay]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks selected", proc: SDisplayHierarchyMarkComm, key: $CDHierarchyMarksSDisplay]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "display hierarchy marks all", proc: ADisplayHierarchyMarkComm, key: $CDHierarchyMarksADisplay]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "un-display hierarchy marks", proc: RemDisplayHierachyMarkComm, key: $CDHierarchyMarksUnDisplay]; CDCommandOps.RegisterWithMenu[menu: $ProgramMenu, entry: "select hierarchy mark", proc: SelectHierachyMarkComm, key: $CDHierarchyMarksSelect]; <<--########################>> END.