<> <> <> <> DIRECTORY Atom, CD, CDBasics, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDIO, CDOps, CDPanel, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts, CDValue, CDViewer, IO, ProcessProps, Rope, TiogaMenuOps, TerminalIO, ViewerClasses USING [Viewer], ViewerOps; CDExtraCommands: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDCommandOps, CDDirectory, CDInstances, CDIO, CDLayers, CDOps, CDPanel, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts, CDValue, CDViewer, IO, ProcessProps, TiogaMenuOps, TerminalIO, ViewerOps = BEGIN WithWDir: PROC [wDir: Rope.ROPE, proc: PROC] = { ProcessProps.AddPropList[ propList: Atom.PutPropOnList[NIL, $WorkingDirectory, wDir], inner: proc ]; }; HelpComm: PROC [comm: CDSequencer.Command] = { Do: PROC [] = { v: ViewerClasses.Viewer _ TiogaMenuOps.Open["CDCrib.tioga"]; IF v#NIL THEN ViewerOps.OpenIcon[v]; }; WithWDir[CDIO.GetWorkingDirectory[NIL], Do]; TerminalIO.PutRope["for more documentation, open also\n ChipNDaleIntroduction.tioga\n ChipNDaleDoc.tioga\n ChipNDaleToolsDoc.tioga\n"]; }; CoordinatesCommand: PROC [comm: CDSequencer.Command] = { WriteInLambda: PROC [n: CD.Number] = { TerminalIO.PutRope[CDOps.LambdaRope[n, lambda]] }; lambda: INT _ comm.design.technology.lambda; TerminalIO.PutRope["coordinates [\024]"]; -- \024 prints as greek lambda TerminalIO.PutRope[" down: ("]; WriteInLambda[comm.sPos.x]; TerminalIO.PutRope[","]; WriteInLambda[comm.sPos.y]; TerminalIO.PutRope[") up: ("]; WriteInLambda[comm.pos.x]; TerminalIO.PutRope[","]; WriteInLambda[comm.pos.y]; TerminalIO.PutRope[") dist: ("]; WriteInLambda[comm.pos.x-comm.sPos.x]; TerminalIO.PutRope[","]; WriteInLambda[comm.pos.y-comm.sPos.y]; TerminalIO.PutRope[")\n"]; }; ArrowInformation: PROC [comm: CDSequencer.Command] = { WriteInLambda: PROC [n: CD.Number] = { TerminalIO.PutRope[CDOps.LambdaRope[n, lambda]] }; lambda: INT _ comm.design.technology.lambda; WITH CDValue.Fetch[comm.design, $arrow, design] SELECT FROM rp: REF CD.Position => { TerminalIO.PutRope[" arrow at: ("]; WriteInLambda[rp.x]; TerminalIO.PutRope[","]; WriteInLambda[rp.y]; TerminalIO.PutRope[") up: ("]; WriteInLambda[comm.pos.x]; TerminalIO.PutRope[","]; WriteInLambda[comm.pos.y]; TerminalIO.PutRope[") dist: ("]; WriteInLambda[rp.x-comm.pos.x]; TerminalIO.PutRope[","]; WriteInLambda[rp.y-comm.pos.y]; TerminalIO.PutRope[")\n"]; } ENDCASE => NULL; }; OrientationRope: PROC [orient: CD.Orientation] RETURNS [Rope.ROPE] = { RETURN [SELECT orient FROM original => "original", mirrorX => "mirrorX", rotate90 => "rotate90", rotate90X => "rotate90X", rotate180 => "rotate180", rotate180X => "rotate180X", rotate270 => "rotate270", rotate270X => "rotate270X", ENDCASE => ERROR ] }; StatisticCommand: PROC [comm: CDSequencer.Command] = { lambda: INT _ comm.design.technology.lambda; countTot, countSel, countInvis: INT _ 0; isDesign: BOOL _ FALSE; rect: CD.Rect _ CDBasics.universe; v: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; inst: CD.Instance; TerminalIO.PutRope["statistic "]; IF v#NIL THEN rect _ CDViewer.VisibleRect[v]; IF ~CDBasics.NonEmpty[rect] THEN rect _ CDBasics.universe; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO countTot _ countTot+1; IF l.first.selected THEN { IF ~CDBasics.Intersect[rect, CDInstances.InstRectI[l.first]] THEN countInvis _ countInvis+1; countSel _ countSel+1; inst _ l.first } ENDLOOP; TerminalIO.PutF["%g objects; %g selected\n", IO.int[countTot], IO.int[countSel]]; IF countSel=1 THEN { verbosity: INT _ 5; TerminalIO.PutRope[CDOps.InstRope[inst, comm.design, verbosity]]; IF verbosity>0 THEN { ir: CD.Position _ CD.InterestSize[inst.ob]; <<\024 prints as greek lambda>> TerminalIO.PutF[" at: (%g,%g)\024", [rope[CDOps.LambdaRope[inst.trans.off.x, lambda]]], [rope[CDOps.LambdaRope[inst.trans.off.y, lambda]]] ]; TerminalIO.PutF[" i-size: (%g,%g)\024", [rope[CDOps.LambdaRope[ir.x, lambda]]], [rope[CDOps.LambdaRope[ir.y, lambda]]] ]; WITH inst.ob.specific SELECT FROM tp: CDTexts.TextSpecific => IF tp.cdFont#NIL THEN TerminalIO.PutF[" [Font: %g, scale:%g\024]", [rope[tp.cdFont.supposedName]], [rope[CDOps.LambdaRope[tp.cdFont.scaleI, lambda]]] --need technology for lambda ]; cp: CD.CellSpecific => TerminalIO.PutRope[IF cp.specifiedIr THEN " interest rect explicite" ELSE " interest rect defaulted"]; ENDCASE => NULL; TerminalIO.PutRopes[" orientation: ", OrientationRope[inst.trans.orient]]; IF inst.ob.class.composed AND ~CDDirectory.IsIncluded[comm.design, inst.ob] THEN TerminalIO.PutRope[" not included in directory"] }; TerminalIO.PutRope["\n"]; }; ArrowInformation[comm]; IF countInvis#0 THEN TerminalIO.PutF1[" ** %g invisible selected object(s)\n", [integer[countInvis]]]; }; AddSelectLayer: PROC [comm: CDSequencer.Command] = { n: INT _ 0; layer: CD.Layer _ CDLayers.CurrentLayer[comm.design]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.ob.layer=layer THEN { n _ n+1; IF ~l.first.selected THEN { l.first.selected _ TRUE; CDOps.RedrawInstance[comm.design, l.first, FALSE]; } } ENDLOOP; TerminalIO.PutF["select all %g objects: (%g)\n", [rope[CDOps.LayerRope[layer]]], [integer[n]]]; }; ChangeLayerComm: PROC [comm: CDSequencer.Command] = { n: INT _ 0; layer: CD.Layer _ CDLayers.CurrentLayer[comm.design]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected AND l.first.ob.class.newLayer#NIL THEN { CDOps.RedrawInstance[comm.design, l.first]; IF l.first.ob.class.newLayer[l.first, layer] THEN n _ n+1; CDOps.RedrawInstance[comm.design, l.first, FALSE]; } ENDLOOP; TerminalIO.PutF["changed layer to %g (%g)\n", IO.rope[CDOps.LayerRope[layer]], IO.int[n]]; }; GetWidthLayerCommand: PROC [comm: CDSequencer.Command] = { inst: CD.Instance = CDOps.TheInstance[comm.design, "set default layer and width"]; IF inst#NIL THEN { done: BOOL _ FALSE; layer: CD.Layer = inst.ob.layer; IF CDProperties.GetLayerProp[layer, $DontUse]=NIL THEN IF CDTexts.IsText[inst.ob] OR CD.LayerTechnology[layer]#NIL OR (CD.LayerTechnology[layer]=NIL AND CDLayers.Kind[layer]=paint) THEN { IF layer#CD.undefLayer AND layer#CD.shadeLayer AND layer#CD.backgroundLayer AND layer#CD.backgroundLayer AND layer#CD.outlineLayer AND layer#CD.selectionLayer THEN { sz: CD.Position _ CD.InterestSize[inst.ob]; w: CD.Number _ IF inst.ob.class.wireTyped THEN sz.x ELSE MIN[sz.x, sz.y]; done _ TRUE; CDLayers.SetLayerWidth[comm.design, layer, w]; CDLayers.SetCurrentLayer[comm.design, layer]; TerminalIO.PutF[" %g (%g)\n", [rope[CDOps.LayerRope[layer]]], [rope[CDOps.LambdaRope[w, comm.design.technology.lambda]]] ]; } }; IF ~done THEN TerminalIO.PutRope[" not done\n"]; } }; GetLayerCommand: PROC [comm: CDSequencer.Command] = { inst: CD.Instance = CDOps.TheInstance[comm.design, "set default layer"]; IF inst#NIL THEN { done: BOOL _ FALSE; layer: CD.Layer = inst.ob.layer; IF CDProperties.GetLayerProp[layer, $DontUse]=NIL THEN IF CDTexts.IsText[inst.ob] OR CD.LayerTechnology[layer]#NIL OR (CD.LayerTechnology[layer]=NIL AND CDLayers.Kind[layer]=paint) THEN { IF layer#CD.undefLayer AND layer#CD.shadeLayer AND layer#CD.backgroundLayer AND layer#CD.backgroundLayer AND layer#CD.outlineLayer AND layer#CD.selectionLayer THEN { done _ TRUE; TerminalIO.PutRopes[" ", CDOps.LayerRope[layer], "\n"]; CDLayers.SetCurrentLayer[comm.design, layer]; } }; IF ~done THEN TerminalIO.PutRope[" not done\n"]; } }; GetWidthCommand: PROC [comm: CDSequencer.Command] = { w: CD.Number _ 0; layer: CD.Layer _ CDLayers.CurrentLayer[comm.design]; inst: CD.Instance = CDOps.TheInstance[comm.design, "set default width"]; IF inst#NIL THEN { sz: CD.Position _ CD.InterestSize[inst.ob]; IF inst.ob.class.wireTyped THEN w _ sz.x ELSE w _ MIN[sz.x, sz.y]; }; CDLayers.SetLayerWidth[comm.design, layer, w]; TerminalIO.PutF[" width for %g set to %g\n", [rope[CDOps.LayerRope[layer]]], [rope[CDOps.LambdaRope[w, comm.design.technology.lambda]]] ]; }; IncreaseByWidthComm: PROC [comm: CDSequencer.Command] = { cnt: INT _ 0; TerminalIO.PutRope["increase wire length by width: "]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.selected AND l.first.ob.class.wireTyped AND ~l.first.ob.class.symbolic THEN { oldSize: CD.Position _ CD.InterestSize[l.first.ob]; newSize: CD.Position _ [x: oldSize.x, y: oldSize.y+oldSize.x]; newOb: CD.Object _ CDRects.CreateRect[newSize, l.first.ob.layer]; IF newOb#NIL THEN { CDOps.RedrawInstance[comm.design, l.first, TRUE]; l.first.ob _ newOb; cnt _ cnt+1; <<--this orientation busines makes sure the instance is grown at the top or the right edge>> SELECT l.first.trans.orient FROM original, mirrorX, rotate270, rotate90X => {}; rotate90, rotate270X => l.first.trans.off.x _ l.first.trans.off.x+oldSize.x; rotate180, rotate180X => l.first.trans.off.y _ l.first.trans.off.y+oldSize.x; ENDCASE => {}; CDOps.RedrawInstance[comm.design, l.first]; }; }; ENDLOOP; TerminalIO.PutF1[" %g objects\n", IO.int[cnt]]; }; ShowErrorComm: PROCEDURE [comm: CDSequencer.Command] = { applList: CD.InstanceList = CDOps.InstList[comm.design]; foundSome: BOOL _ FALSE; TerminalIO.PutRope[ "show error "]; FOR a: CD.InstanceList _ applList, a.rest WHILE a#NIL DO IF a.first.ob.layer=CD.errorLayer THEN { inst: CD.Instance = a.first; foundSome _ TRUE; IF ~inst.selected THEN { eRect: CD.Rect = CDInstances.InstRectI[inst]; inst.selected _ TRUE; CDOps.Redraw[comm.design, eRect, FALSE]; TerminalIO.PutRopes[CDOps.InstRope[inst], "\n"]; FOR vl: CDViewer.ViewerList _ CDViewer.ViewersOf[comm], vl.rest WHILE vl#NIL DO CDViewer.ShowAndScale[viewer: vl.first, rect: CDBasics.Extend[eRect, 30*comm.design.technology.lambda] ]; ENDLOOP; CDOps.ReOrderInstance[comm.design, inst]; EXIT } }; REPEAT FINISHED => IF foundSome THEN TerminalIO.PutRope["all errors in this cell are already selected\n"] ELSE TerminalIO.PutRope[ "no errors in this cell\n"] ENDLOOP; }; SelectAllErrorsComm: PROC [comm: CDSequencer.Command] = { cnt: INT _ 0; CDOps.DeselectAll[comm.design]; FOR l: CD.InstanceList _ CDOps.InstList[comm.design], l.rest WHILE l#NIL DO IF l.first.ob.layer=CD.errorLayer THEN { cnt _ cnt+1; l.first.selected _ TRUE; CDOps.RedrawInstance[comm.design, l.first, FALSE] } ENDLOOP; TerminalIO.PutF["%g error(s) selected\n", IO.int[cnt]]; }; MakePinComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; r: CD.Rect = CDBasics.ToRect[comm.pos, comm.sPos]; inst: CD.Instance; layer: CD.Layer _ CDLayers.CurrentLayer[comm.design]; layer _ CDLayers.AbstractToPaint[layer]; TerminalIO.PutRopes["draw Pin (", CDOps.LayerRope[layer], ")\n"]; name _ TerminalIO.RequestRope[" type name of pin: "]; inst _ CDSymbolicObjects.CreateSymInst[denotes: r, layer: layer, name: name]; CDOps.IncludeInstance[comm.design, inst]; }; MakeSegmentComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; r: CD.Rect = CDBasics.ToRect[comm.pos, comm.sPos]; inst: CD.Instance; layer: CD.Layer _ CDLayers.CurrentLayer[comm.design]; TerminalIO.PutRopes["draw Segment (", CDOps.LayerRope[layer], ")\n"]; layer _ CDLayers.AbstractToPaint[layer]; name _ TerminalIO.RequestRope[" type name of segment: "]; inst _ CDSymbolicObjects.CreateSymInst[denotes: [x1: r.x1, x2: r.x2, y1: r.y1, y2: r.y1], layer: layer, name: name]; CDOps.IncludeInstance[comm.design, inst]; }; MakeMarkComm: PROC [comm: CDSequencer.Command] = { name: Rope.ROPE; inst: CD.Instance; r: CD.Rect = CDBasics.RectAt[comm.pos, [0, 0]]; TerminalIO.PutRope["draw mark object\n"]; name _ TerminalIO.RequestRope[" type name of mark: "]; inst _ CDSymbolicObjects.CreateSymInst[denotes: r, name: name]; CDOps.IncludeInstance[comm.design, inst]; }; CDSequencer.ImplementCommand[$GetLayer, GetLayerCommand,, doQueue]; CDSequencer.ImplementCommand[$GetWidth, GetWidthCommand,, doQueue]; CDSequencer.ImplementCommand[$GetWidthLayer, GetWidthLayerCommand,, doQueue]; CDSequencer.ImplementCommand[$AddSelectLayer, AddSelectLayer,, doQueue]; CDSequencer.ImplementCommand[$Coordinates, CoordinatesCommand,, doQueue]; CDSequencer.ImplementCommand[$Statistic, StatisticCommand,, doQueue]; CDSequencer.ImplementCommand[$IncreaseByWidth, IncreaseByWidthComm]; CDSequencer.ImplementCommand[$ChangeLayerS, ChangeLayerComm]; CDSequencer.ImplementCommand[$Help, HelpComm,, dontQueue]; CDSequencer.ImplementCommand[$DrawMark, MakeMarkComm]; CDSequencer.ImplementCommand[$DrawPin, MakePinComm]; CDSequencer.ImplementCommand[$DrawSegment, MakeSegmentComm]; CDCommandOps.RegisterCurrentLayerCommand[key: $LayerComment, layer: CD.commentLayer]; CDCommandOps.RegisterCurrentLayerCommand[key: $LayerGreen, layer: CD.FetchLayer[NIL, $green], w: -2]; CDCommandOps.RegisterCurrentLayerCommand[key: $LayerYellow, layer: CD.FetchLayer[NIL, $yellow], w: -2]; CDCommandOps.RegisterCurrentLayerCommand[key: $LayerRed, layer: CD.FetchLayer[NIL, $red], w: -2]; CDCommandOps.RegisterCurrentLayerCommand[key: $LayerBlue, layer: CD.FetchLayer[NIL, $blue], w: -2]; CDSequencer.ImplementCommand[$ShowErrors, ShowErrorComm,, doQueue]; CDSequencer.ImplementCommand[$SelectAllErrors, SelectAllErrorsComm,, doQueue]; CDPanel.Button[button: [text: "menu"], command: $GlobalMenu, topLine: TRUE]; CDPanel.Button[button: [text: "help"], command: $Help, topLine: TRUE]; END.