DIRECTORY Basics, CD, CDBasics, CDCells, CDDirectory, CDImports, CDInstances, CDLayers, CDMenus, CDOps, CDOrient, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDSequencer, CDTexts, CDViewer, Core, CoreClasses, CoreOps, CoreGeometry, GList, IO, PW, Rope, RopeList, Sinix, SinixOps, Sisyph, TerminalIO, ViewerClasses, ViewerOps; SisyphCmdsImpl: CEDAR PROGRAM IMPORTS Basics, CD, CDBasics, CDCells, CDDirectory, CDImports, CDInstances, CDLayers, CDMenus, CDOps, CDOrient, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDTexts, CDViewer, CoreOps, CoreGeometry, GList, IO, PW, Rope, RopeList, Sinix, SinixOps, Sisyph, TerminalIO, ViewerOps SHARES Sinix = BEGIN ROPE: TYPE = Rope.ROPE; ROPES: TYPE = LIST OF ROPE; Wire: TYPE = Core.Wire; CellType: TYPE = Core.CellType; Icon: TYPE ~ REF IconRep; IconRep: TYPE ~ RECORD [ name: ROPE _ NIL, -- The short name of the icon, i.e. excluding the ".icon" part boxWidth: CD.Number, -- Width of lines for icon box pinRect: CD.Position, -- Size of pins (horizontal pin) guard: CD.Number, -- Spacing between pin and pin name grid: CD.Number, -- The grid on which pins should be aligned font: CDTexts.CDFont, -- ChipNDale font to be used for all texts pins: ARRAY CoreGeometry.Side OF ROPES -- The sorted pin names on all four sides ]; cdIconForKey: ATOM = $IconFor; MakeIcon: PROC [comm: CDSequencer.Command] = { CDMenus.CallMenuAndExecute[$SisyphIconMenu, comm]; }; UnMakeIcon: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; exprs, news: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; FlushCache[selected.ob]; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; WHILE exprs#NIL DO IF NOT Sisyph.IsResultExpression[exprs.first] THEN news _ CONS [exprs.first, news]; exprs _ exprs.rest; ENDLOOP; CDProperties.PutProp[selected.ob, cdIconForKey, NIL]; CDProperties.PutProp[selected.ob, Sisyph.expressionsProp, news]; }; ChangeVisibility: PROC [comm: CDSequencer.Command] = { CDMenus.CallMenuAndExecute[$SisyphVisibilityMenu, comm]; }; MakeInvisibleToExtractor: PROC [comm: CDSequencer.Command] = { nInstances: INT _ 0; FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO inst: CD.Instance _ w.first; IF inst.selected THEN { CDProperties.PutProp[inst, Sisyph.mode.extractProcProp, $ExtractNull]; nInstances _ nInstances+1; FlushCache[inst.ob] } ENDLOOP; TerminalIO.WriteF["Made %g instances invisible to Sisyph\n", IO.int[nInstances]] }; MakeVisibleToExtractor: PROC [comm: CDSequencer.Command] = { nInstances: INT _ 0; FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO inst: CD.Instance _ w.first; IF inst.selected THEN { CDProperties.PutProp[inst, Sisyph.mode.extractProcProp, NIL]; nInstances _ nInstances+1; FlushCache[inst.ob] } ENDLOOP; TerminalIO.WriteF["Made %g instances visible to Sisyph\n", IO.int[nInstances]] }; FlushCache: PROC [obj: CD.Object] = { CDProperties.PutProp[obj, Sinix.cacheProp, NIL]; IF CDCells.IsCell[obj] THEN { cellPtr: CD.CellPtr _ NARROW [obj.specificRef]; FOR l: LIST OF CD.Instance _ cellPtr.contents, l.rest WHILE l#NIL DO FlushCache[l.first.ob]; ENDLOOP; }; }; FlushSisyphCaches: PROC [comm: CDSequencer.Command] = { FOR w: LIST OF CD.Instance _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF w.first.selected THEN FlushCache[w.first.ob]; ENDLOOP; }; MakeCellIconWithCodeDef: PROC [comm: CDSequencer.Command] = { iconName: ROPE; selected: CD.Instance; multiple: BOOL; cellIconExprPrefix: ROPE _ Rope.Cat[Sisyph.cellIconRope, " _ "]; cellIconExpr: ROPE; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; FlushCache[selected.ob]; iconName _ CDDirectory.Name[selected.ob]; IF NOT Rope.Match["*.icon", iconName] THEN TerminalIO.WriteF["*** Convention for icons is to suffix them with '.icon'.\n"]; cellIconExpr _ PW.RequestRope[Rope.Cat["Type code: ", cellIconExprPrefix]]; cellIconExpr _ Rope.Cat[cellIconExprPrefix, cellIconExpr]; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ CONS [cellIconExpr, StripResultExprs[exprs]]; CDProperties.PutProp[selected.ob, Sisyph.expressionsProp, exprs]; CDProperties.PutProp[selected.ob, cdIconForKey, NIL]; }; MakeCellIconWithGeometryDef: PROC [comm: CDSequencer.Command] = { iconName: ROPE; selected: CD.Instance; multiple: BOOL; schematicName: ROPE; cellIconExprPrefix: ROPE _ Rope.Cat[Sisyph.cellIconRope, " _ "]; cellIconExpr: ROPE; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; FlushCache[selected.ob]; iconName _ CDDirectory.Name[selected.ob]; IF NOT Rope.Match["*.icon", iconName] THEN TerminalIO.WriteF["*** Convention for icons is to suffix them with '.icon'.\n"]; schematicName _ PW.RequestRope["Type schematic name: "]; IF CDDirectory.Fetch[comm.design, schematicName].object = NIL THEN { TerminalIO.WriteF["*** No such object in design.\n"]; RETURN; }; IF NOT Rope.Match["*.sch", schematicName] THEN TerminalIO.WriteF["*** Convention for schematics is to suffix them with '.sch'.\n"]; cellIconExpr _ Rope.Cat[cellIconExprPrefix, "ES[\"", schematicName, "\", cx]"]; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ CONS [cellIconExpr, StripResultExprs[exprs]]; CDProperties.PutProp[selected.ob, Sisyph.expressionsProp, exprs]; CDProperties.PutProp[selected.ob, cdIconForKey, schematicName]; }; MakeWireIconWithCodeDef: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; wireIconExprPrefix: ROPE _ Rope.Cat[Sisyph.wireIconRope, " _ "]; wireIconExpr: ROPE; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; FlushCache[selected.ob]; wireIconExpr _ PW.RequestRope[Rope.Cat["Type code: ", wireIconExprPrefix]]; wireIconExpr _ Rope.Cat[wireIconExprPrefix, wireIconExpr]; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ CONS [wireIconExpr, StripResultExprs[exprs]]; CDProperties.PutProp[selected.ob, Sisyph.expressionsProp, exprs]; CDProperties.PutProp[selected.ob, cdIconForKey, NIL]; }; CreateIconCommand: PROC [comm: CDSequencer.Command] ~ { schematicName, iconShortName: ROPE; icon: CD.Object; cell: Core.CellType; selected: CD.Instance; multiple: BOOL; grid: CD.Number _ -1; cellRef: REF; viewer: ViewerClasses.Viewer _ CDViewer.GetViewer[comm]; IF viewer#NIL THEN WITH ViewerOps.GetViewer[viewer, $Grid] SELECT FROM rgrid: REF CD.Number => grid _ rgrid^; ENDCASE => NULL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; schematicName _ CDDirectory.Name[selected.ob]; IF schematicName=NIL THEN { TerminalIO.WriteF["*** Selected schematic has no name.\n"]; RETURN; }; IF NOT Rope.Match["*.sch", schematicName] THEN TerminalIO.WriteF["*** Convention for schematics is to suffix them with '.sch'.\n"]; cellRef _ SinixOps.ExtractCDInstance[selected, comm.design, Sisyph.mode].result; IF ISTYPE [cellRef, Core.CellType] THEN cell _ NARROW [cellRef] ELSE { TerminalIO.WriteF["*** Selected cell does not extract to Core CellType\n"]; RETURN; }; iconShortName _ PW.RequestRope["Type icon short name: "]; IF Rope.IsEmpty[iconShortName] THEN iconShortName _ IF Rope.Match["*.sch", schematicName] THEN Rope.Substr[schematicName, 0, Rope.Length[schematicName]-4] ELSE schematicName; IF Rope.IsEmpty[schematicName] THEN { TerminalIO.WriteF["No name provided, no default from schematic.\n"]; RETURN; }; IF CDDirectory.Fetch[comm.design, Rope.Cat[iconShortName, ".icon"]].found THEN { TerminalIO.WriteF["*** The icon %g.icon already exists!\n", IO.rope[iconShortName]]; RETURN; }; icon _ IconFromSchematic[cell, schematicName, iconShortName, comm.design, grid]; IF icon=NIL THEN RETURN; CDCells.SetSimplificationTreshhold[cell: icon, val: 30, inPixels: TRUE]; CDOps.IncludeObjectI[comm.design, icon, comm.pos]; }; ShowInstExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Instance Expressions:\n"]; PutRopes[NARROW [CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]]; }; AddInstExpression: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Add Instance Expression\n"]; exprs _ NARROW [CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]; exprs _ CONS [PW.RequestRope[Rope.Cat[" New Expression: "]], exprs]; CDProperties.PutInstanceProp[selected, Sisyph.expressionsProp, exprs] }; EditInstExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Edit Instance Expressions\n"]; exprs _ NARROW[CDProperties.GetInstanceProp[selected, Sisyph.expressionsProp]]; exprs _ EditExpressions[exprs, "Expression"]; CDProperties.PutInstanceProp[selected, Sisyph.expressionsProp, exprs] }; ShowObjExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Object Expressions:\n"]; PutRopes[NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]]; IF NOT CDImports.IsImport[selected.ob] THEN RETURN; IF NARROW [selected.ob.specificRef, CDImports.ImportPtr].boundInstance=NIL THEN {TerminalIO.WriteF["Object is an unbound import.\n"]; RETURN}; TerminalIO.WriteF["Object Expressions of the bound import:\n"]; PutRopes[NARROW [CDProperties.GetObjectProp[NARROW [selected.ob.specificRef, CDImports.ImportPtr].boundInstance.ob, Sisyph.expressionsProp]]]; }; AddObjExpression: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Add Object Expression\n"]; exprs _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ CONS [PW.RequestRope[Rope.Cat[" New Expression: "]], exprs]; CDProperties.PutObjectProp[selected.ob, Sisyph.expressionsProp, exprs] }; EditObjExpressions: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; exprs: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Edit Object Expressions\n"]; exprs _ NARROW[CDProperties.GetObjectProp[selected.ob, Sisyph.expressionsProp]]; exprs _ EditExpressions[exprs, "Expression"]; CDProperties.PutObjectProp[selected.ob, Sisyph.expressionsProp, exprs] }; ShowParmNames: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; parms: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Parm Names:"]; parms _ NARROW[CDProperties.GetObjectProp[selected.ob, Sisyph.parmNamesProp]]; WHILE parms#NIL DO TerminalIO.WriteF[Rope.Cat["\n ", parms.first]]; parms _ parms.rest; ENDLOOP; TerminalIO.WriteF["\n"]; }; AddParmName: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; parms: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Add Parameter Name\n"]; parms _ NARROW [CDProperties.GetObjectProp[selected.ob, Sisyph.parmNamesProp]]; parms _ CONS [PW.RequestRope[Rope.Cat[" New Parameter: "]], parms]; CDProperties.PutObjectProp[selected.ob, Sisyph.parmNamesProp, parms] }; EditParmNames: PROC [comm: CDSequencer.Command] = { selected: CD.Instance; multiple: BOOL; parms: ROPES; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; TerminalIO.WriteF["Edit Object Expressions\n"]; parms _ NARROW[CDProperties.GetObjectProp[selected.ob, Sisyph.parmNamesProp]]; parms _ EditExpressions[parms, "Parameter"]; CDProperties.PutObjectProp[selected.ob, Sisyph.parmNamesProp, parms] }; AlignUpToGrid: PROC [x, grid: CD.Number] RETURNS [CD.Number] ~ { RETURN [IF x>=0 THEN ((x+grid-1)/grid)*grid ELSE (x/grid)*grid] }; AlignDownToGrid: PROC [x, grid: CD.Number] RETURNS [CD.Number] ~ { RETURN [IF x>=0 THEN (x/grid)*grid ELSE ((x-grid+1)/grid)*grid] }; AlignPositionUpToGrid: PROC [p: CD.Position, grid: CD.Number] RETURNS [CD.Position] ~ { RETURN [[AlignUpToGrid[p.x, grid], AlignUpToGrid[p.y, grid]]] }; AlignRectUpToGrid: PROC [r: CD.Rect, grid: CD.Number] RETURNS [CD.Rect] ~ { RETURN [[x1: AlignDownToGrid[r.x1, grid], x2: AlignUpToGrid[r.x2, grid], y1: AlignDownToGrid[r.y1, grid], y2: AlignUpToGrid[r.y2, grid]]] }; MoveInstances: PROC [list: CD.InstanceList, by: CD.Position] ~ { WHILE list#NIL DO list.first.location _ CDBasics.AddPoints[list.first.location, by]; list _ list.rest; ENDLOOP; }; BuildIconSides: PROC [icon: Icon] RETURNS [sideSize: ARRAY CoreGeometry.Side OF CD.Position, sideList: ARRAY CoreGeometry.Side OF CD.InstanceList] ~ { BuildSideGeometry: PROC [on: CoreGeometry.Side, rotate: CD.Orientation, useTextEnd: BOOL, textOffset: CD.Position, pinStartPos: CD.Position] ~ { iList: CD.InstanceList _ NIL; pinPos, satPos: CD.Position; -- real ones pinPos _ pinStartPos; FOR names: ROPES _ icon.pins[on], names.rest WHILE names#NIL DO satObject: CD.Object = CDTexts.CreateText[text: names.first, font: icon.font]; pinObject: CD.Object = CDRects.CreateRect[size: icon.pinRect, l: CD.commentLayer]; satInst, pinInst: CD.Instance; pinInst _ CDInstances.NewInst[ob: pinObject, location: pinPos, orientation: rotate]; satPos _ CDBasics.AddPoints[pinPos, textOffset]; satPos _ CDBasics.SubPoints[ satPos, CDOrient.OrientedSize[ [IF useTextEnd THEN satObject.size.x ELSE 0,satObject.size.y/2], rotate]]; satInst _ CDInstances.NewInst[ob: satObject, location: satPos, orientation: rotate]; pinPos _ AlignPositionUpToGrid[CDBasics.AddPoints[pinPos, CDOrient.OrientedSize[[0, satObject.size.y], rotate]], icon.grid]; CDSatellites.Associate[master: pinInst, text: satInst]; iList _ CONS[pinInst, iList]; iList _ CONS[satInst, iList]; ENDLOOP; IF iList#NIL THEN { -- Compute size (not default) and set logical base at [0,0] r: CD.Rect = AlignRectUpToGrid[CDInstances.BoundingRectO[iList], icon.grid]; pos: CD.Position = CDBasics.BaseOfRect[r]; sideSize[on] _ CDBasics.SizeOfRect[r]; MoveInstances[iList, CDBasics.NegOffset[pos]]; } ELSE sideSize[on] _ [0, 0]; sideList[on] _ iList; }; BuildSideGeometry[on: top, rotate: CDOrient.rotate270, useTextEnd: TRUE, textOffset: [0, -icon.guard], pinStartPos: [0, -icon.pinRect.x]]; BuildSideGeometry[on: bottom, rotate: CDOrient.rotate270, useTextEnd: FALSE, textOffset: [0, icon.pinRect.x+icon.guard], pinStartPos: [0, 0]]; BuildSideGeometry[on: right, rotate: CDOrient.original, useTextEnd: TRUE, textOffset: [-icon.guard, 0], pinStartPos: [-icon.pinRect.x, 0]]; BuildSideGeometry[on: left, rotate: CDOrient.original, useTextEnd: FALSE, textOffset: [icon.pinRect.x+icon.guard, 0], pinStartPos: [0, 0]]; }; BuildIconFrame: PROC [icon: Icon, box: CD.Rect] RETURNS [list: CD.InstanceList _ NIL] ~ { BuildBoxSide: PROC [size, at: CD.Position] ~ { orient: CD.Orientation; IF size.x>size.y THEN { -- This trick is necessary for stretchy moves... orient _ CDOrient.rotate90; size _ [size.y, size.x]; } ELSE orient _ CDOrient.original; list _ CONS [CDInstances.NewInst[ob: CDRects.CreateRect[size: size, l: CD.commentLayer], location: at, orientation: orient], list]; CDProperties.PutProp[list.first, Sisyph.mode.extractProcProp, $ExtractNull]; }; w: CD.Number = icon.boxWidth; BuildBoxSide[size: [w, w+box.y2-box.y1], at: [box.x1, box.y1]]; -- left BuildBoxSide[size: [w, w+box.y2-box.y1], at: [box.x2, box.y1]]; -- right BuildBoxSide[size: [w+box.x2-box.x1, w], at: [box.x1, box.y1]]; -- bottom BuildBoxSide[size: [w+box.x2-box.x1, w], at: [box.x1, box.y2]]; -- top }; CommentText: PROC [text: ROPE, font: CDTexts.CDFont] RETURNS [ob: CD.Object] ~ { IsItalic: PROC [fontName: ROPE] RETURNS [BOOL] = { RETURN [Rope.Find[fontName, "i", Rope.Length[fontName]-1, FALSE]#-1] }; italicFont: CDTexts.CDFont _ IF ~IsItalic[font.supposedName] THEN CDTexts.MakeFont[ name: Rope.Cat[font.supposedName, "I"], scale: font.scaleI] ELSE font; ob _ CDTexts.CreateText[text: text, font: italicFont]; }; BuildIconObject: PROC [icon: Icon, design: CD.Design] RETURNS [obj: CD.Object] ~ { sideSize: ARRAY CoreGeometry.Side OF CD.Position; sideList: ARRAY CoreGeometry.Side OF CD.InstanceList; internalInstances: CD.InstanceList _ NIL; iconFullName: ROPE = Rope.Cat[icon.name, ".icon"]; iconTextObject: CD.Object = CommentText[text: icon.name, font: icon.font]; iconText: CD.Instance; inside, outside: CD.Rect; width, height: CD.Number; cellPtr: CD.CellPtr; IF icon.grid<=0 THEN icon.grid _ design.technology.lambda; [sideSize, sideList] _ BuildIconSides[icon]; width _ sideSize[left].x+sideSize[right].x+MAX[ sideSize[bottom].x, sideSize[top].x, AlignUpToGrid[2*iconTextObject.size.x, icon.grid]]; height _ MAX[ sideSize[left].y, sideSize[right].y, sideSize[bottom].y+sideSize[top].y+AlignUpToGrid[4*iconTextObject.size.y, icon.grid]]; inside.x1 _ sideSize[left].x; inside.y1 _ sideSize[bottom].y; inside.x2 _ width+icon.pinRect.y-sideSize[right].x; inside.y2 _ height+icon.pinRect.y-sideSize[top].y; outside.x1 _ IF sideList[left]=NIL THEN 0 ELSE icon.pinRect.x; outside.y1 _ IF sideList[bottom]=NIL THEN 0 ELSE icon.pinRect.x; outside.x2 _ IF sideList[right]=NIL THEN width ELSE width-icon.pinRect.x; outside.y2 _ IF sideList[top]=NIL THEN height ELSE height-icon.pinRect.x; MoveInstances[ sideList[bottom], [AlignDownToGrid[(width+sideSize[left].x-sideSize[right].x-sideSize[bottom].x)/2, icon.grid], 0]]; MoveInstances[ sideList[top], [AlignDownToGrid[(width+sideSize[left].x-sideSize[right].x-sideSize[top].x)/2, icon.grid], inside.y2]]; MoveInstances[ sideList[left], [0, AlignDownToGrid[(height-sideSize[left].y)/2, icon.grid]]]; MoveInstances[ sideList[right], [inside.x2, AlignDownToGrid[(height-sideSize[right].y)/2, icon.grid]]]; iconText _ CDInstances.NewInst[ ob: iconTextObject, location: CDBasics.SubPoints[CDBasics.Center[inside], CDBasics.Center[CDBasics.RectAt[[0, 0], iconTextObject.size]]]]; internalInstances _ BuildIconFrame[icon, outside]; internalInstances _ CONS [iconText, internalInstances]; FOR on: CoreGeometry.Side IN CoreGeometry.Side DO FOR list: CD.InstanceList _ sideList[on], list.rest WHILE list#NIL DO internalInstances _ CONS [list.first, internalInstances]; ENDLOOP; ENDLOOP; obj _ CDCells.CreateEmptyCell[]; cellPtr _ NARROW [obj.specificRef]; cellPtr.contents _ internalInstances; [] _ CDCells.RepositionCell[obj, NIL]; -- This is only to set all cell values OK IF CDDirectory.Fetch[design, iconFullName].found THEN { TerminalIO.WriteF["*** The icon %g already exists!\n", IO.rope[iconFullName]]; ERROR; }; IF NOT CDDirectory.Include[design, obj, iconFullName] THEN { TerminalIO.WriteF["*** Direction insertion of icon %g failed.\n", IO.rope[iconFullName]]; ERROR; }; }; IconFromSchematic: PROC [cell: Core.CellType, schematicName, iconName: ROPE, design: CD.Design, grid: CD.Number _ -1] RETURNS [obj: CD.Object] ~ { InternalPin: TYPE ~ REF InternalPinRep; InternalPinRep: TYPE ~ RECORD [ name: ROPE, rect: CD.Rect -- The InstRectO of the pin, used to sort along the side ]; Side: TYPE ~ RECORD [ border: CD.Rect, -- Representation of schematic side pins: LIST OF InternalPin _ NIL ]; SearchPins: CoreOps.EachWireProc ~ { pinGeom: CD.InstanceList _ CoreGeometry.GetPins[Sisyph.mode.decoration, wire]; pinName: ROPE = CoreOps.GetShortWireName[wire]; IF pinGeom=NIL THEN RETURN; IF pinName=NIL THEN { TerminalIO.WriteF["*** The wire %g has pins, but no short name\n", IO.rope[CoreOps.GetFullWireName[root: cell.public, wire: wire]]]; RETURN[quit: TRUE]; }; WHILE pinGeom#NIL DO -- Paranoid! the first pin should touch a side of the schematic pinRect: CD.Rect = CDInstances.InstRectO[pinGeom.first]; FOR on: CoreGeometry.Side IN CoreGeometry.Side DO IF CDBasics.Intersect[pinRect, sides[on].border] THEN { sides[on].pins _ CONS [NEW [InternalPinRep _ [name: pinName, rect: pinRect]], sides[on].pins]; RETURN [subWires: FALSE]; }; ENDLOOP; pinGeom _ pinGeom.rest; ENDLOOP; TerminalIO.WriteF["*** The wire %g has pins, but none of them touches the icon of the schematic.\n", IO.rope[CoreOps.GetFullWireName[root: cell.public, wire: wire]]]; RETURN [quit: TRUE]; }; XSort: GList.CompareProc ~ { -- Reverse order comparison RETURN [Basics.CompareINT[NARROW[ref2, InternalPin].rect.x1, NARROW[ref1, InternalPin].rect.x1]]; }; YSort: GList.CompareProc ~ { -- Reverse order comparison RETURN [Basics.CompareINT[NARROW[ref2, InternalPin].rect.y1, NARROW[ref1, InternalPin].rect.y1]]; }; lineWidth: CD.Number = CDLayers.LayerWidth[design, CD.commentLayer]; icon: Icon _ NEW [IconRep _ [name: iconName, boxWidth: lineWidth, pinRect: [x: 4*lineWidth, y: lineWidth], guard: 2*lineWidth, grid: grid, font: CDPanelFonts.CurrentFont[design]]]; sides: ARRAY CoreGeometry.Side OF Side; cellIR: CD.Rect = CoreGeometry.GetIR[Sisyph.mode.decoration, cell]; exprs: ROPES _ NIL; sides[top].border _ [x1: cellIR.x1, x2: cellIR.x2, y1: cellIR.y2, y2: cellIR.y2]; sides[bottom].border _ [x1: cellIR.x1, x2: cellIR.x2, y1: cellIR.y1, y2: cellIR.y1]; sides[right].border _ [x1: cellIR.x2, x2: cellIR.x2, y1: cellIR.y1, y2: cellIR.y2]; sides[left].border _ [x1: cellIR.x1, x2: cellIR.x1, y1: cellIR.y1, y2: cellIR.y2]; IF CoreOps.VisitWireSeq[cell.public, SearchPins] THEN RETURN [NIL]; FOR on: CoreGeometry.Side IN CoreGeometry.Side DO icon.pins[on] _ NIL; FOR list: LIST OF InternalPin _ NARROW [GList.UniqueSort[list: sides[on].pins, compareProc: IF on=top OR on=bottom THEN XSort ELSE YSort]], list.rest WHILE list#NIL DO icon.pins[on] _ CONS [list.first.name, icon.pins[on]]; ENDLOOP; ENDLOOP; obj _ BuildIconObject[icon, design]; exprs _ CONS [Rope.Cat[Sisyph.cellIconRope, " _ ES[\"", schematicName, "\", cx]"], exprs]; CDProperties.PutProp[obj, Sisyph.expressionsProp, exprs]; CDProperties.PutProp[obj, $IconFor, schematicName]; }; PutRopes: PROC [ropes: ROPES] = { WHILE ropes#NIL DO TerminalIO.WriteF["\t%g\n", IO.rope[ropes.first]]; ropes _ ropes.rest; ENDLOOP; }; IsSingleSelectedAndCell: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF ~IsSingleSelected[selected, multiple] THEN RETURN [FALSE]; IF ~CDCells.IsCell[selected.ob] THEN { TerminalIO.WriteF["*** Selected instance is not a cellcan't do it.\n"]; RETURN[FALSE]; }; RETURN[TRUE]; }; IsSingleSelected: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF selected=NIL THEN { TerminalIO.WriteF["*** No current selection--can't do it.\n"]; RETURN[FALSE]; }; IF multiple THEN { TerminalIO.WriteF["*** Multiple instances selected--can't do it.\n"]; RETURN[FALSE]; }; RETURN[TRUE]; }; StripResultExprs: PROC [in: ROPES] RETURNS [out: ROPES] = { out _ NIL; FOR l: ROPES _ in, l.rest WHILE l#NIL DO IF ~Sisyph.IsResultExpression[l.first] THEN out _ CONS [l.first, out] ENDLOOP; }; EditExpressions: PROC [oldExprs: ROPES, prompt: ROPE] RETURNS [allExprs: ROPES _ NIL] = { input: ROPE; noOldExprs: BOOL _ oldExprs=NIL; TerminalIO.WriteF["\n"]; WHILE oldExprs#NIL DO input _ PW.RequestRope[Rope.Cat[" ", prompt, ": ", oldExprs.first, " Replacement: "]]; SELECT TRUE FROM Rope.Equal[input, "-"] => TerminalIO.WriteF[" ** Deleted\n"]; Rope.IsEmpty[input] => allExprs _ CONS [oldExprs.first, allExprs]; ENDCASE => allExprs _ CONS [input, allExprs]; oldExprs _ oldExprs.rest; ENDLOOP; IF noOldExprs THEN { input _ PW.RequestRope[Rope.Cat[" New ", prompt, ": "]]; WHILE ~Rope.IsEmpty[input] AND ~Rope.Equal[input, "-"] DO allExprs _ CONS [input, allExprs]; input _ PW.RequestRope[Rope.Cat[" New ", prompt, ": "]]; ENDLOOP; }; allExprs _ RopeList.Reverse[allExprs]; }; FilterSch: SinixOps.FilterProc = {RETURN [Rope.Match["*.sch", name] OR Rope.Match["*.icon", name]]}; CDMenus.ImplementEntryCommand[menu: $OtherProgramMenu, entry: "Make Icon", p: MakeIcon, key: $SisyphMakeIcon, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $OtherProgramMenu, entry: "Flush Sisyph Caches", p: FlushSisyphCaches, key: $FlushSisyphCaches, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $OtherProgramMenu, entry: "Change Visibility For Sisyph", p: ChangeVisibility, key: $SisyphChangeVisibility, queue: doQueueAndMark]; SinixOps.RegisterExtractCommand[mode: Sisyph.mode, prompt: "Sisyph Extract", key: $SisyphExtractSelectedObj]; SinixOps.RegisterHighlightCommand[mode: Sisyph.mode, prompt: "Highlight net in schematic", key: $HighlightNetInSchematic]; SinixOps.RegisterBackgroundExtractionCommand[CD.FetchTechnology[$cmosB], Sisyph.mode, "Sch background extraction", $SchBackgroundExtract, FilterSch]; -- only works for CMosB. Not very clean [] _ CDMenus.CreateMenu["Sisyph: Make Icon", $SisyphIconMenu]; CDMenus.ImplementCommandToCallMenu[$SisyphIconMenu, $SisyphIconMenu]; CDMenus.ImplementEntryCommand[menu: $SisyphIconMenu, entry: "Create cell icon from schematic", p: CreateIconCommand, key: $CreateIconCommand, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphIconMenu, entry: "Associate cell icon with schematic", p: MakeCellIconWithGeometryDef, key: $MakeCellIconWithGeometryDef, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphIconMenu, entry: "Associate cell icon with code", p: MakeCellIconWithCodeDef, key: $MakeCellIconWithCodeDef, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphIconMenu, entry: "Associate wire icon with code", p: MakeWireIconWithCodeDef, key: $MakeWireIconWithCodeDef, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphIconMenu, entry: "Dissociate icon from source", p: UnMakeIcon, key: $UnMakeIcon, queue: doQueueAndMark]; [] _ CDMenus.CreateMenu["Sisyph: Change Visibility", $SisyphVisibilityMenu]; CDMenus.ImplementCommandToCallMenu[$SisyphVisibilityMenu, $SisyphVisibilityMenu]; CDMenus.ImplementEntryCommand[menu: $SisyphVisibilityMenu, entry: "Make Invisible to Sisyph", p: MakeInvisibleToExtractor, key: $MakeInvisibleToExtractor, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphVisibilityMenu, entry: "Make Visible to Sisyph", p: MakeVisibleToExtractor, key: $MakeVisibleToExtractor, queue: doQueueAndMark]; [] _ CDMenus.CreateMenu["Sisyph: Parameter Specification", $SisyphParameterMenu]; CDMenus.ImplementCommandToCallMenu[$SisyphParameterMenu, $SisyphParameterMenu]; CDMenus.ImplementEntryCommand[menu: $SisyphParameterMenu, entry: "Show Parameter Names", p: ShowParmNames, key: $SisyphShowParmNames]; CDMenus.ImplementEntryCommand[menu: $SisyphParameterMenu, entry: "Add Parameter Name", p: AddParmName, key: $SisyphAddParmName, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SisyphParameterMenu, entry: "Edit Parameter Names", p: EditParmNames, key: $SisyphEditParmNames, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Show Instance Expressions (LI-Left)", p: ShowInstExpressions, key: $SisyphShowInstExpressions]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Add Instance Expression (LI-Middle)", p: AddInstExpression, key: $SisyphAddInstExpression, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Edit Instance Expressions (LI-Right)", p: EditInstExpressions, key: $SisyphEditInstExpressions, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Show Object Expressions (LO-Left)", p: ShowObjExpressions, key: $SisyphShowObjExpressions]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Add Object Expression (LO-Middle)", p: AddObjExpression, key: $SisyphAddObjExpression, queue: doQueueAndMark]; CDMenus.ImplementEntryCommand[menu: $SatellitesMenu, entry: "Edit Object Expressions (LO-Right)", p: EditObjExpressions, key: $SisyphEditObjExpressions, queue: doQueueAndMark]; END. ΞSisyphCmdsImpl.mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Created by Pradeep Sindhu, December 9, 1985 10:01:52 pm PST Pradeep Sindhu, September 26, 1986 2:06:15 pm PDT Barth, January 13, 1986 3:30:05 pm PST Bertrand Serlet December 8, 1986 6:41:13 pm PST Jean-Marc Frailong June 20, 1986 8:25:11 pm PDT Last Edited by: Jacobi July 15, 1986 2:40:48 pm PDT Command Procs User interface to create icon from schematic Create icon from schematic Move all instances in the list by the required amount Build all the pins and pin names for the icon. Create geometry (pins and names) along an edge of the icon. All pins are aligned on grid coordinates. Text is centered on associated pin, at left or right according to request. Text is separated by guard CD units from the pin. The returned iLists alternates pins and names. Progress pin position Set satellite property and add to result list Build the geometry for the icon box Build the CD object for the icon in the design. The object is included in the design. Raises an ERROR if the object already existed (should be checked by caller). Compute a reasonable size for the inside and outside of the icon. Move the sides at their final locations and setup the icon name Build the icon object Build an icon straight from the schematic. Return NIL object if error. The schematicName had better be the right one. First, build rectangles representing the sides of the schematic Scan the public to build the sides structure Sort the pins on each side and setup the names in the icon structure Finally create the object from the icon structure Internal Utilities Initialization Main Menu Make Icon Menu Change Visibility Menu Make Parameter Menu Expressions Menu Κl˜™Jšœ Οmœ7™BJšœ8Οk™;Jšœ.ž™1Icodešœ#ž™&Kšœ/™/Kšœ,ž™/Kšœ0ž™3—J™šž ˜ JšœžœβžœžœP˜ΒJ˜—šΟnœžœž˜Kšžœ žœΒžœžœ@˜šKšžœ ž˜K™Kšžœžœžœ˜Kš žœžœžœžœžœ˜Kšœžœ ˜Kšœ žœ˜K˜Kšœžœžœ ˜šœ žœžœ˜KšœžœžœΟc>˜PKšœ žœ  ˜3Kšœ žœ   ˜6Kšœžœ  #˜5Kšœžœ  +˜Kšœ žœ˜š žœžœžœžœ0žœžœž˜OKšœžœ˜šžœžœ˜KšœF˜FKšœ˜K˜K˜—Kšžœ˜—Kšœ=žœ˜PKšœ˜—K˜šŸœžœ ˜žœ˜KKšžœ7žœ˜C—Kšœ?˜?Kšœ žœžœ\˜ŽK˜—K˜šŸœžœ ˜6Kšœ žœ ˜Kšœ žœ˜Kšœžœ˜ K˜Kšœ;˜;Kšžœ'žœžœ˜5K˜Kšœ-˜-KšœžœC˜QKšœžœžœ5˜EKšœF˜FK˜—K˜šŸœžœ ˜8Kšœ žœ ˜Kšœ žœ˜Kšœžœ˜ K˜Kšœ;˜;Kšžœ'žœžœ˜5K˜Kšœ/˜/KšœžœB˜PK˜-KšœF˜FK˜—K˜šŸ œžœ ˜3Kšœ žœ ˜Kšœ žœ˜Kšœžœ˜ K˜Kšœ;˜;Kšžœ'žœžœ˜5K˜Kšœ!˜!Kšœžœ@˜Nšžœžœž˜Kšœ1˜1K˜Kšžœ˜—Kšœ˜K˜—K™šŸ œžœ ˜1Kšœ žœ ˜Kšœ žœ˜Kšœžœ˜ K˜Kšœ;˜;Kšžœ'žœžœ˜5K˜Kšœ*˜*KšœžœA˜OKšœžœžœ4˜DKšœD˜DK˜—K™šŸ œžœ ˜3Kšœ žœ ˜Kšœ žœ˜Kšœžœ˜ K˜Kšœ;˜;Kšžœ'žœžœ˜5K˜Kšœ/˜/Kšœžœ@˜NK˜,KšœD˜DK˜——™š Ÿ œžœ žœ žœžœ ˜@Kšžœžœžœžœ˜?K˜—K˜š Ÿœžœ žœ žœžœ ˜BKšžœžœžœžœ˜?K˜—K˜š Ÿœžœžœžœ žœžœ˜WKšžœ7˜=K˜—K˜š Ÿœžœžœ žœ žœžœ ˜KKšžœƒ˜‰K˜—K˜šŸ œžœžœžœ˜@K™5šœžœžœž˜KšœB˜BK˜Kšžœ˜—K˜—K˜šŸœžœžœ žœžœžœžœžœžœ˜–K™/K˜š Ÿœžœ!žœžœžœžœ˜KšœΜžœC™‘Kšœžœžœ˜Kšœžœ   ˜)Kšœ˜š žœžœžœžœž˜?Kšœ žœA˜NKšœ žœ4žœ˜RKšœžœ ˜KšœT˜TKšœ0˜0šœ˜Kšœ˜šœ˜Kšœžœ žœžœ˜@Kšœ ˜ ——KšœT˜TKšœ™Jšœ|˜|J™-Kšœ7˜7Jšœžœ˜Jšœžœ˜Kšžœ˜—šžœžœžœ ;˜OKšœžœG˜LKšœžœ#˜*Kšœ&˜&Kšœ.˜.K˜—Kšžœ˜K˜K˜—K˜šœ˜Kšœ˜Kšœ žœ˜Kšœ˜Kšœ#˜#—šœ˜Kšœ˜Kšœ žœ˜Kšœ+˜+Kšœ˜—šœ˜Kšœ˜Kšœ žœ˜Kšœ˜Kšœ#˜#—šœ˜Kšœ˜Kšœ žœ˜Kšœ+˜+Kšœ˜—K˜—K˜š Ÿœžœžœžœžœžœ˜YK™#šŸ œžœ žœ˜.Kšœžœ ˜šžœžœ 0˜HKšœ˜K˜K˜—Kšžœ˜ Kšœžœ<žœ:˜ƒKšœL˜LK˜—Kšœžœ˜Kšœ@ ˜GKšœ@ ˜HKšœ@  ˜IKšœ@ ˜FK˜—K˜š Ÿ œžœžœžœžœ ˜Pš Ÿœžœ žœžœžœ˜2Jšžœ4žœ˜DJ˜—šœ˜šžœžœ˜6Jšœ'˜'Jšœ˜—Kšžœ˜ —Kšœ6˜6K˜—K˜š Ÿœžœžœ žœžœ ˜RKšœ žœTžœ=™’Kšœ žœžœžœ ˜1Kšœ žœžœžœ˜5Kšœžœžœ˜)Kšœžœ ˜2Kšœžœ8˜JKšœ žœ ˜Kšœžœ˜Kšœžœ˜Kšœ žœ ˜Kšžœžœ&˜:Kšœ,˜,KšœA™Ašœ+žœ˜/Jšœ˜Jšœ˜Jšœ3˜3—šœ žœ˜ Jšœ˜Jšœ˜JšœV˜V—Jšœ˜Jšœ˜Jšœ3˜3Jšœ2˜2Kš œ žœžœžœžœ˜>Kš œ žœžœžœžœ˜@Kš œ žœžœžœžœ˜IKš œ žœžœžœžœ˜IK™?šœ˜Jšœ˜Jšœb˜b—šœ˜Jšœ˜Jšœg˜g—šœ˜Jšœ˜Jšœ>˜>—šœ˜Jšœ˜JšœG˜G—šœ˜Jšœ˜Jšœv˜v—J™Kšœ2˜2Jšœžœ˜7šžœžœž˜1š žœžœ(žœžœž˜EKšœžœ!˜9Kšžœ˜—Kšžœ˜—Kšœ ˜ Kšœ žœ˜#Kšœ%˜%Kšœ!žœ )˜Pšžœ/žœ˜7Kšœ7žœ˜NKšžœ˜K˜—–b[design: CD.Design, object: CD.Object, alternateName: ROPE _ NIL, fiddleName: BOOL _ TRUE]šžœžœ0žœ˜˜>Kšžœžœ˜K˜—šžœ žœ˜KšœE˜EKšžœžœ˜K˜—Kšžœžœ˜ Kšœ˜—K˜K˜š Ÿœžœžœžœžœ˜;Kšœžœ˜ š žœžœžœžœž˜(Kšžœ%žœžœ˜EKšžœ˜—K˜K˜—šŸœžœ žœ žœžœ žœžœ˜YKšœžœ˜ Kšœ žœ žœ˜ Kšœ˜šžœ žœž˜KšœžœN˜Xšžœžœž˜Kšœ>˜>Kšœ"žœ˜BKšžœžœ˜-—K˜Kšžœ˜—K˜šžœ žœ˜Kšœžœ/˜9šžœžœž˜9Kšœ žœ˜"Kšœžœ/˜9Kšžœ˜—K˜—J˜Jšœ&˜&K˜——™šŸ œžœžœ˜dJ˜—K™ Kšœ…˜…Kšœ›˜›Kšœ¨˜¨Kšœm˜mKšœz˜zKšœ-žœg (˜ΎK˜K™K˜Kšœ>˜>KšœE˜EKšœ₯˜₯KšœΌ˜ΌKšœ―˜―Kšœ―˜―Kšœ“˜“K˜K™KšœL˜LKšœQ˜QK˜Kšœ²˜²Kšœ¬˜¬K˜K˜K™K™KšœQ˜QKšœO˜OK™Kšœ†˜†Kšœ—˜—Kšœ˜K˜K˜K™Kšœœ˜œKšœ―˜―Kšœ΄˜΄K˜Kšœ˜˜˜Kšœ«˜«Kšœ°˜°K–~[technology: CD.Technology, contextCreator: SinixHighlight.ExtractContextCreator, prompt: ROPE _ NIL, key: ATOM _ NIL]˜K˜Kšžœ˜——…—o$’^