DIRECTORY CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDSequencer, CDTexts, CDViewer, Core, CoreCreate, CoreGeometry, CoreOps, CoreProperties, PopUpMenus, IO, PW, REFBit, Rope, SinixOps, Sisyph, TerminalIO, ViewerClasses, ViewerOps, WireIconExtras; WireIconExtrasImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDInstances, CDLayers, CDOps, CDPanelFonts, CDProperties, CDRects, CDSatellites, CDTexts, CDViewer, CoreCreate, CoreGeometry, CoreProperties, CoreOps, IO, PW, REFBit, Rope, SinixOps, Sisyph, TerminalIO, ViewerOps EXPORTS WireIconExtras = BEGIN ROPE: TYPE = Rope.ROPE; Wire: TYPE = Core.Wire; ConstructIconCommand: PROC [comm: CDSequencer.Command] ~ { schFullName: ROPE; iconName: ROPE; icon: CD.Object; cell: Core.CellType; selected: CD.Instance; multiple: BOOL; cellRef: REF; sort: BOOL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelectedAndCell[selected, multiple] THEN RETURN; schFullName _ CDDirectory.Name[selected.ob, comm.design]; IF schFullName=NIL THEN {TerminalIO.PutF["*** Selected schematic has no name.\n"]; RETURN}; IF NOT Rope.Match["*.sch", schFullName] THEN TerminalIO.PutF["*** 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.PutF["*** Selected cell does not extract to Core CellType\n"]; RETURN}; iconName _ TerminalIO.RequestRope["Type icon short name: "]; IF Rope.IsEmpty[iconName] THEN iconName _ IF Rope.Match["*.sch", schFullName] THEN Rope.Substr[schFullName, 0, Rope.Length[schFullName]-4] ELSE schFullName; IF Rope.IsEmpty[schFullName] THEN {TerminalIO.PutF["No name provided, no default from schematic.\n"]; RETURN}; IF CDDirectory.Fetch[comm.design, Rope.Cat[iconName, ".icon"]]#NIL THEN { TerminalIO.PutF["*** The icon %g.icon already exists!\n", IO.rope[iconName]]; RETURN}; sort _ SELECT comm.key FROM $ConstructIconCommand => FALSE, $ConstructIconCommandSort => TRUE, ENDCASE => ERROR; icon _ IconFromSchematic[cell, schFullName, iconName, comm.design, sort]; IF icon=NIL THEN RETURN; CDCells.SetSimplificationTreshhold[cell: icon, val: 30, inPixels: TRUE]; []_CDOps.IncludeObjectI[comm.design, icon, comm.pos]}; ConstructRecWireIconCommand: PROC [comm: CDSequencer.Command] ~ { type: ROPE _ TerminalIO.RequestRope["Type (eg. Def.Record): "]; wire: Core.Wire _ RecWire[type]; name: ROPE _ type.Substr[type.Index[0,"."]+1]; icon: CD.Object _ ConstructWireIcon[comm, wire, name.Cat[".icon"]]; CDProperties.PutObjectProp[icon, $CodeFor, Rope.Cat["WireIconExtras.RecWire[\"", type, "\"]" ]]; CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]}; ConstructDETWireIconCommand: PROC [comm: CDSequencer.Command] ~ { type: ROPE _ TerminalIO.RequestRope["Type (eg. Def.Enumerated): "]; pre: ROPE _ TerminalIO.RequestRope["Prefix:"]; suf: ROPE _ TerminalIO.RequestRope["Suffix:"]; wire: Core.Wire _ ETWire[pre, suf, type]; icon: CD.Object _ ConstructWireIcon[comm, wire, Rope.Cat[pre, suf, ".icon"]]; CDProperties.PutObjectProp [icon, $CodeFor, IO.PutFR["WireIconExtras.ETWire[\"%g\", \"%g\", \"%g\"]", IO.rope[pre], IO.rope[suf], IO.rope[type] ]]; CDProperties.PutObjectProp[icon, Sisyph.mode.extractProcProp, $SisyphExtractNamedWireIcon]}; ConstructWireIcon: PROC [comm: CDSequencer.Command, wire: Core.Wire, name: ROPE] RETURNS[icon: CD.Object] ~ { font: CDTexts.CDFont _ CDPanelFonts.CurrentFont[comm.design]; w: INT _ CDLayers.LayerWidth[comm.design, CD.commentLayer]; fw2: INT _ font.height/2 - w - font.origin.y; grid: CD.Number _ Grid[comm.design, font]; insts: CD.InstanceList _ NIL; pinObject: CD.Object _ CDRects.CreateRect[size: [grid/2, w], l: CD.commentLayer]; text: CD.Object; sat: CD.Instance; pin: CD.Instance; maxX: INT _ 0; FOR i: INT IN [0..wire.size) DO text _ CDTexts.Create[CoreOps.GetShortWireName[wire[i]], font]; maxX _ MAX[ maxX, CD.InterestSize[text].x]; sat _ CDInstances.NewInst[text, [[x: grid, y: grid*(i+2)-fw2 ]]]; pin _ CDInstances.NewInst[pinObject, [[x: 0, y: grid*(i+2) ]]]; insts _ CONS[sat, CONS[pin, insts]]; CDSatellites.Associate[master: pin, text: sat] ENDLOOP; text _ CDTexts.Create[CoreOps.GetShortWireName[wire], font]; maxX _ ((MAX[ maxX, CD.InterestSize[text].x] + 3*grid-1)/grid)*grid; sat _ CDInstances.NewInst[text, [[x: maxX-grid-CD.InterestSize[text].x, y: grid-fw2 ]]]; pin _ CDInstances.NewInst[pinObject, [[x: maxX-grid/2, y: grid ]]]; insts _ CONS[sat, CONS[pin, insts]]; CDSatellites.Associate[master: pin, text: sat]; icon _ PW.CreateCell[instances: insts, ir: [0, 0, maxX, grid*(wire.size+2)+w]]; IF NOT CDDirectory.Include[comm.design, icon, name] THEN {TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[name]]; ERROR}; []_CDOps.IncludeObjectI[comm.design, icon, comm.pos]}; mark: ATOM _ CoreProperties.RegisterProperty[$TemporaryMark]; IconFromSchematic: PROC[ schCT: Core.CellType, schFullName: ROPE, iconName: ROPE, design: CD.Design, sort: BOOL ] RETURNS [iconObj: CD.Object] ~ { L16: PROC[in: INT] RETURNS[INT] = {XX: INT _ design.technology.lambda*16; RETURN[((in+XX-1)/XX)*XX]}; font: CDTexts.CDFont _ CDPanelFonts.CurrentFont[design]; grid: CD.Number _ Grid[design, font]; insts: CD.InstanceList _ NIL; schDeco: CoreGeometry.Decoration _ Sisyph.mode.decoration; schSize: CD.Position _ CD.InterestSize[CoreGeometry.GetObject[schDeco, schCT]]; iconSize: CD.Position; hChans: INT; vChans: INT; iNmOb: CD.Object _ CDTexts.Create[iconName, font]; pins: ARRAY CoreGeometry.Side OF CD.InstanceList _ ALL[NIL]; cnt: ARRAY CoreGeometry.Side OF NAT _ ALL[0]; smax: ARRAY CoreGeometry.Side OF INT _ ALL[16]; w: INT _ CDLayers.LayerWidth[design, CD.commentLayer]; fw2: INT _ font.height/2 - w - font.origin.y; iconFullName: ROPE _ iconName.Cat[".icon"]; pinObject: CD.Object; horWall: CD.Object; verWall: CD.Object; clearMark: CoreOps.EachWireProc = {CoreProperties.PutWireProp[wire, mark, NIL]}; FOR side: CoreGeometry.Side IN CoreGeometry.Side DO eachSortedPin: CoreGeometry.EachSortedPinProc = { IF CoreProperties.GetWireProp[wire, mark]=NIL THEN { text: CD.Object _ CDTexts.Create[CoreOps.GetShortWireName[wire], font]; inst: CD.Instance _ CDInstances.NewInst[text]; CoreProperties.PutWireProp[wire, mark, mark]; pins[side] _ CONS[inst, pins[side]]; cnt[side] _ cnt[side] + 1; smax[side] _ MAX[ smax[side], CD.InterestSize[text].x] }}; [] _ CoreGeometry.EnumerateSortedSides[schDeco, schCT, side, eachSortedPin]; []_CoreOps.VisitWire[schCT.public, clearMark]; ENDLOOP; IF sort THEN FOR side: CoreGeometry.Side IN CoreGeometry.Side DO DO ok: BOOL _ TRUE; FOR insts: CD.InstanceList _ pins[side], insts.rest WHILE insts#NIL AND insts.rest#NIL DO TwoObj: TYPE = RECORD[ob1, ob2: CD.Object]; r1: ROPE _ NARROW[insts.first.ob.specific, CDTexts.TextSpecific].text; r2: ROPE _ NARROW[insts.rest.first.ob.specific, CDTexts.TextSpecific].text; SELECT Rope.Compare[r1, r2] FROM less => LOOP; equal => ERROR; ENDCASE; [insts.first.ob, insts.rest.first.ob] _ TwoObj[insts.rest.first.ob, insts.first.ob]; ok_FALSE; ENDLOOP; IF ok THEN EXIT; ENDLOOP; ENDLOOP; hChans _ MAX[cnt[left], cnt[right]]; vChans _ MAX[cnt[top], cnt[bottom]]; iconSize.x_ L16[(vChans+4)*grid + 2*MAX[smax[left], smax[right],CD.InterestSize[iNmOb].x]]; iconSize.y_ L16[(hChans+4)*grid + 2*MAX[smax[top], smax[bottom]]]; IF schSize.x > schSize.y THEN iconSize.x _ L16[MAX[iconSize.x, (iconSize.y*schSize.x + schSize.y/2) /schSize.y]] ELSE iconSize.y _ L16[MAX[iconSize.y, (iconSize.x*schSize.y + schSize.x/2) /schSize.x]]; pinObject _ CDRects.CreateRect[size: [grid/2, w], l: CD.commentLayer]; horWall _ CDRects.CreateRect[size: [iconSize.x, w], l: CD.commentLayer]; verWall _ CDRects.CreateRect[size: [w, iconSize.y], l: CD.commentLayer]; FOR side: CoreGeometry.Side DECREASING IN CoreGeometry.Side DO tr: CD.Transformation _ SELECT side FROM top => [ [iconSize.x/2 - vChans*grid/2, iconSize.y], rotate270 ], bottom => [ [iconSize.x/2 - vChans*grid/2, 0], rotate90 ], left => [ [0, iconSize.y/2 - hChans*grid/2], original], right => [ [iconSize.x, iconSize.y/2 - hChans*grid/2], rotate180], ENDCASE => ERROR; index: INT _ (cnt[side]+(SELECT side FROM top,bottom=>vChans, ENDCASE => hChans)+1)/2; FOR temp: CD.InstanceList _ pins[side], temp.rest WHILE temp#NIL DO pin, sat: CD.Instance; index _ index-1; insts _ CONS[(sat _ temp.first), insts]; insts _ CONS[(pin _ CDInstances.NewInst[pinObject]), insts]; sat.trans.orient _ pin.trans.orient _ tr.orient; CDSatellites.Associate[master: pin, text: sat]; SELECT side FROM top => { pin.trans.off _ CDBasics.AddPoints[tr.off, [index*grid+0, 0 ]]; sat.trans.off _ CDBasics.AddPoints[tr.off, [index*grid+0-fw2, -grid ]]}; bottom => { pin.trans.off _ CDBasics.AddPoints[tr.off, [index*grid+w, 0 ]]; sat.trans.off _ CDBasics.AddPoints[tr.off, [index*grid+w+fw2, +grid ]]}; left => { pin.trans.off _ CDBasics.AddPoints[tr.off, [0, index*grid+0 ]]; sat.trans.off _ CDBasics.AddPoints[tr.off, [+grid, index*grid+0-fw2 ]]}; right => { pin.trans.off _ CDBasics.AddPoints[tr.off, [0, index*grid+w ]]; sat.trans.off _ CDBasics.AddPoints[tr.off, [-grid, index*grid+w+fw2 ]]}; ENDCASE => ERROR; ENDLOOP; ENDLOOP; insts _ CONS[CDInstances.NewInst[horWall, [off:[0, 0 ]]], insts]; CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull]; insts _ CONS[CDInstances.NewInst[horWall, [off:[0, iconSize.y-w ]]], insts]; CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull]; insts _ CONS[CDInstances.NewInst[verWall, [off:[0, 0 ]]], insts]; CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull]; insts _ CONS[CDInstances.NewInst[verWall, [off:[iconSize.x-w, 0 ]]], insts]; CDProperties.PutInstanceProp[insts.first, Sisyph.mode.extractProcProp, $ExtractNull]; insts _ CONS[CDInstances.NewInst[iNmOb, [off:[grid, iconSize.y-2*grid ]]], insts]; iconObj _ PW.CreateCell[instances: insts]; IF NOT CDDirectory.Include[design, iconObj, iconFullName] THEN {TerminalIO.PutF["*** Directory insertion of %g failed.\n", IO.rope[iconFullName]]; ERROR}; CDProperties.PutObjectProp[iconObj, Sisyph.mode.extractProcProp, $SisyphExtractCellIcon]; CDProperties.PutObjectProp[iconObj, $IconFor, schFullName]}; Grid: PROC[design: CD.Design, font: CDTexts.CDFont _ NIL] RETURNS[grid: NAT] = { viewers: CDViewer.ViewerList _ CDViewer.ViewersOf[design]; IF viewers#NIL THEN WITH ViewerOps.GetViewer[viewers.first, $Grid] SELECT FROM rgrid: REF CD.Number => grid _ rgrid^; ENDCASE => NULL ELSE grid _ design.technology.lambda*2; IF font#NIL THEN WHILE font.height > (grid*4)/3 DO grid _ grid*2 ENDLOOP}; IsSingleSelected: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF selected=NIL THEN {TerminalIO.PutF["*** No current selection--can't do it.\n"]; RETURN[FALSE]}; IF multiple THEN {TerminalIO.PutF["*** Multiple instances selected--can't do it.\n"]; RETURN[FALSE]}; RETURN[TRUE]}; IsSingleSelectedAndCell: PROC [selected: CD.Instance, multiple: BOOL] RETURNS [BOOL] = { IF ~IsSingleSelected[selected, multiple] THEN RETURN [FALSE]; IF ~CDCells.IsCell[selected.ob] THEN {TerminalIO.PutF["*** Selected instance is not a cellcan't do it.\n"]; RETURN[FALSE]}; RETURN[TRUE]}; GridComposer: PW.GeneratorProc = { name: ROPE; grid: INT _ Grid[design]; n: INT _ TerminalIO.RequestInt["Size of the composer? "]; w: INT _ CDLayers.LayerWidth[design, CD.commentLayer]; IF n<1 THEN {TerminalIO.PutF["*** Invalid parameter.\n"]; RETURN}; name _ IO.PutFR["Grid%gW%gComposer[%g].icon", IO.int[grid], IO.int[w], IO.int[n]]; ob _ CDDirectory.Fetch[design, name].object; IF ob=NIL THEN { ob _ GridComposeObj[design, grid, n].obj; [] _ CDDirectory.Include[design, ob, name]}}; GridComposeWire: PUBLIC PROC[n: NAT] RETURNS [wire: Wire] ~ { wire _ CoreOps.CreateWires[n, "w"]; FOR ii: INT IN [0..n) DO wire[ii] _ CoreOps.CreateWires[0, IO.PutFR["w%g", IO.int[ii]]] ENDLOOP}; GridComposeObj: PROC [design: CD.Design, grid, n: INT] RETURNS [obj: CD.Object] = { Add: PROC[name: ROPE _ NIL, size, pos: CD.Position] = { list _ CONS[CDInstances.NewInst[CDRects.CreateRect[size, CD.commentLayer], [pos]], list]; IF name#NIL THEN { names: LIST OF ROPE _ LIST[name]; CDProperties.PutInstanceProp[list.first, Sisyph.expressionsProp, names]}}; list: CD.InstanceList _ NIL; w: INT _ CDLayers.LayerWidth[design, CD.commentLayer]; l: INT _ MAX[w, grid/4]; Add[size:[2*l, grid*2*n+w], pos:[l, 0]]; CDProperties.PutInstanceProp[list.first, Sisyph.mode.extractProcProp, $ExtractNull]; Add[name: "w", size:[l, w], pos:[0, grid]]; FOR ii: INT IN [0..n) DO Add[name: IO.PutFR["w%g", IO.int[ii]], size:[l, w], pos:[3*l, (2*ii+1)*grid]] ENDLOOP; obj _ PW.CreateCell[instances: list]; CDProperties.PutObjectProp [obj, $CodeFor, IO.PutFR["WireIconExtras.GridComposeWire[%g]", IO.int[n]]]; CDProperties.PutObjectProp[obj, Sisyph.mode.extractProcProp, $SisyphExtractUnNamedWireIcon]; CDCells.SetSimplificationTreshhold[obj, 20]}; RecWire: PUBLIC PROC[rec: ROPE, dual: BOOL _ FALSE] RETURNS[wire: Wire] = {RETURN[RefWire[REFBit.NEWFromName[rec], rec.Substr[rec.Index[0,"."]+1]]]}; RefWire: PUBLIC PROC[ref: REF, name: ROPE, dual: BOOL _ FALSE] RETURNS[wire: Wire] = { ZeroIfOne: PROC[s: INT] RETURNS[INT] = {RETURN[IF s=1 THEN 0 ELSE s]}; fieldForm: REFBit.Format _ REFBit.Desc[ref].fieldForm; wires: LIST OF Wire _ NIL; temp: LIST OF Wire _ NIL; FOR field: INT IN[0..fieldForm.size) DO fieldName: ROPE _ BitRopeToSigRope[fieldForm[field].name]; SELECT fieldForm[field].bitSize FROM 1 => {wires _ CONS[CoreCreate.Seq[fieldName, IF dual THEN 2 ELSE 0], wires]}; >1 => { fieldWire: Wire _ CoreOps.CreateWires[fieldForm[field].bitSize, fieldName]; wires _ CONS[fieldWire, wires]; FOR bit: INT IN[0..fieldWire.size) DO fieldWire[bit] _ CoreCreate.Seq[NIL, IF dual THEN 2 ELSE 0] ENDLOOP}; ENDCASE => ERROR; ENDLOOP; temp _ wires; wires _ NIL; FOR temp _ temp, temp.rest WHILE temp#NIL DO wires _ CONS[temp.first, wires] ENDLOOP; wire _ CoreOps.CreateWire[wires, name]}; ETWire: PUBLIC PROC[prefix, suffix, type: ROPE] RETURNS[wire: Wire] = { bitName, bitNameInv: ROPE; refREF: REF _ REFBit.NEWFromName[type]; format: REFBit.Format _ REFBit.Desc[refREF].bitForm; wire _ CoreOps.CreateWires[MAX[2, format.size], prefix.Cat[suffix]]; FOR i: INT IN[0..format.size) DO bitName _ BitRopeToSigRope[format[i].name]; bitNameInv _ BitRopeToSigRope[format[i].nameInv]; IF ((format.size#1) = (i+1=format.size)) = (bitName#NIL) THEN ERROR; IF ((format.size#1) = (bitNameInv#NIL)) = (bitName#NIL) THEN ERROR; IF bitName=NIL THEN bitName _ bitNameInv; wire[i] _ CoreOps.CreateWires[0, prefix.Cat[bitName, suffix]]; IF format.size=1 THEN wire[1] _ CoreOps.CreateWires[0, prefix.Cat[bitNameInv, suffix]]; ENDLOOP}; BitRopeToSigRope: PROC [name: ROPE] RETURNS [ROPE] ~ { Cap: PROC[rope: ROPE, idx: INT] RETURNS[ROPE] = { char: CHAR _ rope.Fetch[idx+1]; IF char IN ['a..'z] THEN char _ char + LOOPHOLE['A - 'a]; RETURN[IO.PutFR["%g", IO.char[char]]]}; IF name = NIL THEN RETURN[NIL]; name _ Rope.Cat[Cap[name, -1], name.Substr[1]]; DO -- remove peiods and Capitalize next letters until end or next char is number index: INT _ name.Index[0, "."]; IF index+1 >= name.Length[] OR name.Fetch[index+1] IN ['0..'9] THEN RETURN[name]; name _ Rope.Cat[name.Substr[0,index], Cap[name, index], name.Substr[index+2]]; ENDLOOP }; CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Cell Icon from schematics - Grid 2", doc: "Pins on grid 2. Overall size in units of 16.", key: $ConstructIconCommand, proc: ConstructIconCommand ]; CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Cell Icon from schematics - Grid 2 - Sorted", doc: "Pins on grid 2. Overall size in units of 16. Names sorted.", key: $ConstructIconCommandSort, proc: ConstructIconCommand ]; CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Wire Icon from Cedar Record Type", doc: "RECORDs with field types such as: RECORD, INT, BOOL, enumerated, subranges", key: $ConstructRecWireIconCommand, proc: ConstructRecWireIconCommand ]; CDCommandOps.RegisterWithMenu[ menu: $SisyphIconMenu, entry: "Create Wire Icon from Cedar Enumerated Type", doc: "Decoded Enumerated types encoded as: 0, 3, 5, 9, 17 etc.", key: $ConstructDETWireIconCommand, proc: ConstructDETWireIconCommand ]; PW.RegisterGenerator[GridComposer, "Composer - variable grid and width"]; END. 0WireIconExtrasImpl.mesa Don Curry May 14, 1987 4:33:34 pm PDT Last Edited by: Don Curry May 26, 1987 4:25:02 pm PDT CDCells.SetSimplificationTreshhold[cell: icon, val: 30, inPixels: TRUE]; SisyphExtractAndStaticLeafConnections: PROC [comm: CDSequencer.Command] = { root, cellType: Core.CellType; cutSet: CoreFlat.CutSet; [root: root, cell: cellType] _ SinixOps.SelectedCellType[comm.design, Sisyph.mode]; IF root=NIL THEN RETURN; -- Extraction ended in error, message already printed TerminalIO.PutF["\nStatic checking (Leaf connections) %g.\n", IO.rope[CoreOps.GetCellTypeName[cellType]]]; cutSet _ IF CoreProperties.GetCellTypeProp[cellType, Static.staticCutSetProp]=NIL THEN CoreFlat.CreateCutSet[labels: LIST["Logic", "LogicMacro"]] ELSE NIL; Static.CountLeafConnections[cellType, Static.CheckCount, cutSet]; TerminalIO.PutF["Finished static checking %g.\n", IO.rope[CoreOps.GetCellTypeName[cellType]]]}; LayoutStructureAndDrcCheckOfSelectedIcons: PROC [comm: CDSequencer.Command] = { count: INT _ 0; drcErrors: INT _ 0; errs: INT _ 0; result: REF; badguys: LIST OF ROPE; objName: ROPE; errorMsg: ROPE; errorType: ATOM; sourceCT: Core.CellType; indirectOb: CD.Object; directOb: CD.Object; directCT: Core.CellType; drcAtomDesign: ATOM _ DesignRules.FetchRulesID[comm.design]; drcAtom: ATOM _ IF drcAtomDesign#NIL THEN drcAtomDesign ELSE $VTI; rules: DesignRules.Rules _ DesignRules.GetRuleSet[drcAtom]; tech: Drc.Tech _ DrcCMOSB.NewTechnology[DrcCMOSB.cMosBcompleteKey, rules]; IF comm.design.actual.rest#NIL THEN {TerminalIO.PutF["Can't handle pushed in cell\n"]; RETURN}; TerminalIO.PutF["Using %g design rules\n", IO.atom[drcAtom]]; FOR w: CD.InstanceList _ CDOps.InstList[comm.design], w.rest WHILE w#NIL DO IF NOT w.first.selected THEN LOOP; objName _ CDDirectory.Name[w.first.ob, comm.design]; IF Rope.Find[objName, ".icon"]=-1 THEN {TerminalIO.PutF["%g is not an icon.\n", IO.rope[objName]]; LOOP}; result _ SinixOps.ExtractCDInstance[w.first, comm.design, Sisyph.mode].result; IF result=NIL OR NOT ISTYPE[result, Core.CellType] THEN {TerminalIO.PutF["%g does not extract as a cell.\n", IO.rope[objName]]; LOOP}; sourceCT _ NARROW[result]; errorType _ NIL; indirectOb _ PWCore.Layout[sourceCT ! PWCore.Error => {errorType _ type; errorMsg _ message; CONTINUE}]; IF errorType#NIL THEN { TerminalIO.PutF["Cell for %g has Layout %g ERROR\n %g.\n", IO.rope[objName], IO.atom[errorType], IO.rope[errorMsg]]; LOOP}; PWCoreLichen.Compare[sourceCT]; TerminalIO.PutF["Done extracting and comparing.\n"]; directOb _ CDDirectory.Expand1[indirectOb].new; IF directOb=NIL THEN ERROR; directCT _ NARROW[Sinix.Extract[directOb, PWCore.extractMode].result]; IF directCT=NIL THEN ERROR; errs _ Drc.CheckDesignRules[directCT, CoreOps.CopyWire[directCT.public], tech, TRUE, NIL, PWCore.extractMode.decoration]; TerminalIO.PutF[" %2g errors in %g.\n", IO.int[errs], IO.rope[CoreOps.GetCellTypeName[directCT]]]; IF errs#0 THEN { []_CDDebug.Draw[directOb, comm.design.technology, objName]; badguys _ CONS[objName, badguys]}; drcErrors _ drcErrors+errs; count _ count+1; ENDLOOP; TerminalIO.PutF["%2g drc errors in %g cells.\n", IO.int[drcErrors], IO.int[count]]; FOR badguys _ badguys, badguys.rest WHILE badguys#NIL DO TerminalIO.PutF[" %g\n", IO.rope[badguys.first]]; ENDLOOP}; AddProp: PROC [comm: CDSequencer.Command] ~ { selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; IF selected.ob.immutable THEN {TerminalIO.PutRope["*** Can't modify an immutable object\n"]; RETURN}; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, (SELECT comm.key FROM $AWireAddProp => $SisyphExtractUnNamedWireIcon, $PWireAddProp => $SisyphExtractNamedWireIcon, ENDCASE => ERROR)]}; DelProp: PROC [comm: CDSequencer.Command] ~ { selected: CD.Instance; multiple: BOOL; [selected, multiple] _ CDOps.SelectedInstance[comm.design]; IF ~IsSingleSelected[selected, multiple] THEN RETURN; IF selected.ob.immutable THEN {TerminalIO.PutRope["*** Can't modify an immutable object\n"]; RETURN}; CDProperties.PutObjectProp[selected.ob, Sisyph.mode.extractProcProp, NIL]}; menu: PopUpMenus.Menu _ CDPopUpMenus.MakeMenu[ key: $AWireMenu, header: "Sisyph: Anonymous Wire extraction", doc: "Change Wire extraction property" ]; CDCommandOps.RegisterWithMenu[ menu: $OtherProgramMenu, entry: "Sisyph: Anonymous/Public Wire", doc: "Change Anonymous or Public Wire extraction property", key: $AWireMenu, proc: NIL]; CDCommandOps.RegisterWithMenu[ menu: $AWireMenu, entry: "Make Wire Anonymous", doc: "Forces Sisyph extraction to return a wire with all names removed. In the case of cell extraction, the result is the anonymous public.", key: $AWireAddProp, proc: AddProp]; CDCommandOps.RegisterWithMenu[ menu: $AWireMenu, entry: "Make Wire Public", doc: "Forces Sisyph extraction to return a wire even when the result would normally be a cell.", key: $PWireAddProp, proc: AddProp]; CDCommandOps.RegisterWithMenu[ menu: $AWireMenu, entry: "Default Wire", doc: NIL, key: $AWireDelProp, proc: DelProp]; CDCommandOps.RegisterWithMenu[ menu: $OtherProgramMenu, entry: "Sisyph Extract And Static (Leaf Connections)", doc: "Sisyph Extract And Static (Leaf Connections)", key: $SisyphExtractAndStaticLeafConnections, proc: SisyphExtractAndStaticLeafConnections]; CDCommandOps.RegisterWithMenu[ menu: $OtherProgramMenu, entry: "Library Layout Check", doc: "Lichen structure check and design rule check of the layouts of all selected icons", key: $LayoutStructureAndDrcCheckOfSelectedIcons, proc: LayoutStructureAndDrcCheckOfSelectedIcons]; Κα˜šΟnœ™Jšœ"Οk™%Jšœ5™5—J˜Jšž œžœζžœžœW˜ΟJ˜šœžœž˜!JšžœžœΗžœžœ7˜ŽJšžœ˜—Jšž˜J˜Jšžœžœžœ˜Jšœžœ ˜J˜šœžœ ˜:Jšœ žœ˜Jšœ žœ˜Jšœžœ˜J˜Jšœ žœ ˜Jšœ žœ˜Jšœ žœ˜Jšœžœ˜ Jšœ;˜;Jšžœ.žœžœ˜Jšœžœ%˜/Jšœžœ"˜,Jšœ žœžœ˜Jšœ žœ4žœ˜RJšœžœ˜Jšœžœ ˜Jšœžœ ˜Jšœžœ˜šžœžœžœž˜Jšœ?˜?Jšœžœžœ˜+JšœC˜CJšœB˜BJšœžœžœ˜$Jšœ/žœ˜7—Jšœ<˜Jš œžœžœžœžœ˜2Jš œžœžœžœžœ˜5Jšœžœžœ˜9Jšœžœ%˜/Jšœžœ˜+Jšœ žœ˜Jšœ žœ˜Jšœ žœ˜JšœKžœ˜Qšžœžœž˜3šœ1˜1šžœ(žœžœ˜4Jšœžœ@˜HJšœžœ&˜.Jšœ-˜-Jšœžœ˜%Jšœ˜Jšœžœžœ˜<——JšœL˜LJšœ.˜.Jšžœ˜—š žœžœžœžœžœž˜CJšœžœžœ˜š žœžœ'žœžœžœ žœž˜YJšœžœžœ žœ ˜+Jšœžœžœ6˜GJšœžœžœ:˜Kšžœž˜ Jšœ žœ˜Jšœ žœžœ˜—JšœT˜TJšœžœ˜ Jšžœ˜—Jš žœžœžœžœžœ˜"—Jšœ žœ˜%Jšœ žœ˜%Jšœ žœžœžœ˜[Jšœ žœžœ˜Bšžœ˜Jšžœžœžœ>˜WJšžœžœžœ@˜Y—Jšœ5žœ˜FJšœ7žœ˜HJšœ7žœ˜Hšžœž œžœž˜>šœžœžœž˜(JšœC˜CJšœ=˜=Jšœ;˜;JšœC˜CJšžœžœ˜—Jš œžœžœžœžœ˜Vš žœžœ&žœžœž˜CJšœ žœ ˜Jšœ˜Jšœžœ˜(Jšœžœ0˜Jšœ<žœžœ˜[—JšœY˜YJšœB˜B—J™š œžœ žœ žœžœžœ˜PJšœ:˜:šžœ ž˜šžœžœ+žœž˜?Jšœžœžœžœž˜6—Jšžœ#˜'—Jš žœžœžœžœžœžœ˜J—J˜š%œžœ ™KJšœ™Jšœ™JšœS™SJš žœžœžœžœΟc5™Nšœ=™=Jšžœ*™,—šœ žœCž™QJšžœžœ™?Jšžœžœ™ —JšœA™Ašœ1™1Jšžœ+™-—J™—š)œžœ ™OJšœžœ™Jšœ žœ™Jšœžœ™Jšœ žœ™ Jšœ ž œ™Jšœ žœ™Jšœ žœ™Jšœ žœ™Jšœ™Jšœ žœ™Jšœ žœ™Jšœ™Jšœžœ)™™>JšœM™Mšžœžœž™#Jšœ3žœ™;—Jšœ+žœ™=š žœžœ4žœžœž™KJšžœžœžœžœ™"Icodešœ4™4šžœ ž™&Jšœ)žœžœ™B—JšœN™Nš žœžœžœžœžœž™7Kšœ5žœžœ™N—Jšœ žœ ™Jšœ™šœ%™%Jšœ7žœ™B—šžœ žœžœ™šœ;™;Kšžœžœžœžœ™@——Kšœ™Kšœ4™4Jšœ/™/Jšžœ žœž œ™Jšœ žœ5™FJšžœ žœžœžœ™Jš œžœ$œžœžœ!™yšœ)žœ ™6Jšžœ*™,—šžœžœ™Jšœ;™;Jšœ"™"—Jšœ™Jšœ™Jšžœ™—Jšœ0žœžœ ™Sšžœ!žœ žœž™8Jšœžœžœ™<—J™—šœžœ ™-Jšœ žœžœ™&Jšœ;™;Jšžœ'žœžœ™5šžœž™Jšœ?žœ™G—šœFžœ ž™ZJšœ0™0Jšœ/™/Jšžœžœ™——šœžœ ™-Jšœ žœžœ™&Jšœ;™;Jšžœ'žœžœ™5šžœž™Jšœ?žœ™G—JšœEžœ™K—š œžœ žœžœžœžœ˜Qšžœ žœž˜Jšœ>žœžœ˜M—šžœ žœ˜JšœEžœžœ˜T—Jšžœžœ˜—š œžœ žœžœžœžœ˜XJšžœ'žœžœžœ˜=šžœž˜$JšœW˜W—Jšžœžœ˜—š œžœ˜"Jšœžœ˜ Jšœžœ˜Jšœžœ3˜:Jšœžœžœ˜7Jšžœžœ/žœ˜BJš œžœ%žœ žœ žœ ˜RJšœ,˜,šžœžœžœ˜Jšœ)˜)Jšœ-˜-——š œžœžœžœžœ˜=Jšœ#˜#šžœžœžœ˜Jšžœ#žœžœ žœ˜K——šœžœ žœžœ˜6Jšžœžœ ˜š œžœžœžœ žœ˜7Jšœžœ.žœ˜Yšžœžœžœ˜Jš œžœžœžœžœ˜!JšœJ˜J——Jšœžœžœ˜Jšœžœžœ˜7Jšœžœžœ ˜Jšœ(˜(JšœT˜TJšœ+˜+šžœžœžœž˜Jšœ žœžœ2žœ˜V—Jšœžœ˜%šœ˜Jšœžœ-žœ ˜K—Jšœ\˜\Jšœ-˜-—J˜šœžœžœžœžœžœžœ˜IJšœžœD˜K—J˜šœžœžœžœžœžœžœžœ˜VJš œžœžœžœžœžœžœžœžœ˜FJšœ6˜6Jšœ žœžœžœ˜Jšœžœžœžœ˜šžœžœžœž˜'Jšœ žœ+˜:šžœž˜$šœ˜Jš œ žœžœžœžœ ˜H—šœ ˜ JšœK˜KJšœžœ˜šžœžœžœž˜%Jš œ žœžœžœžœžœ˜F——Jšžœžœ˜—Jšžœ˜—Jšœžœ˜Jš žœžœžœžœ žœžœ˜UJšœ(˜(—J™š œžœžœžœžœ˜GJšœžœ˜Jšœžœ˜'Jšœ4˜4Jšœžœ&˜Dšžœžœžœž˜ Jšœ,˜,Jšœ1˜1Jšžœ2žœžœžœ˜DJš žœ žœžœžœžœ˜CJšžœ žœžœ˜)Jšœ>˜>šžœž˜JšœA˜A—Jšžœ˜ ——J˜š œžœžœžœžœ˜6š œžœžœžœžœžœ˜1Jšœžœ˜Jšžœžœ žœžœ ˜9Jšžœžœ žœ˜'—Jš žœžœžœžœžœ˜Jšœ/˜/šžœŸM˜PJšœžœ˜ Jš žœžœžœ žœžœ˜QJšœN˜NJšžœ˜ ——J˜šœ˜Jšœ˜Jšœ4˜4Jšœ6˜6Jšœ˜Jšœ˜—šœ˜Jšœ˜Jšœ=˜=JšœE˜EJšœ ˜ Jšœ˜—šœ˜Jšœ˜Jšœ2˜2JšœS˜SJšœ#˜#Jšœ%˜%—šœ˜Jšœ˜Jšœ6˜6JšœA˜AJšœ#˜#Jšœ%˜%—J˜šœ.™.Jšœ™Jšœ,™,Jšœ*™*—J™šœ™Jšœ™Jšœ)™)Jšœ<™