DIRECTORY BasicTime USING [GMT, Now, Period], CD USING [CreateDrawRef, Design, DrawProc, DrawRef, Instance, InstanceList, Layer, Number, Object], CDCommandOps USING [DoWithResource], CDDirectory USING [Fetch, Name], CDEvents USING [EventProc, RegisterEventProc], CDInstances USING [NewInst], CDMenuSpecials USING [SelectOneOf], CDOps USING [InstList, LayerRope], CDPanel USING [DefineButton], CDProperties USING [GetDesignProp, GetObjectProp, PutDesignProp, RegisterProperty], CDSequencer USING [Command, CommandRec, ExecuteCommand, ImplementCommand, UseAbortFlag], Core USING [CellType, Wire], CoreClasses USING [recordCellClass, RecordCellType], CoreGeometry, CoreOps USING [GetCellTypeName, PrintCellType], CoreProperties USING [GetProp], IO USING [int, noWhereStream, PutF, PutFR, PutFR1, rope, STREAM], PrincOpsUtils USING [], Process USING [priorityBackground, SetPriority], Rope USING [Cat, ROPE], Sinix USING [Extract, Mode], SinixOps USING [GetExtractMode], SoS USING [CheckDesignRules, coreInconsistent, DRV, DRVkey, ErrorRect], SymTab USING [Create, Delete, EachPairAction, Fetch, GetSize, Insert, Pairs, Ref], TerminalIO USING [PutRope], ViewerIO USING [CreateViewerStreams], ViewerTools USING [FindExistingViewer, Viewer]; SoSCommandImpl: CEDAR PROGRAM IMPORTS BasicTime, CD, CDCommandOps, CDDirectory, CDEvents, CDInstances, CDMenuSpecials, CDOps, CDPanel, CDProperties, CDSequencer, CoreClasses, CoreOps, CoreProperties, IO, Process, Rope, Sinix, SinixOps, TerminalIO, ViewerIO, ViewerTools, SoS, SymTab ~ BEGIN debug: BOOL _ FALSE; -- to start debugging enter: _ SoSCommandImpl.Debug[] timing: BOOL _ FALSE; -- turn off fast mouse failureReason: Rope.ROPE; failureTorch: REF ANY; dLog: IO.STREAM _ IO.noWhereStream; currentLambda: CD.Number; -- sorry for the hack instead of using the handle DRVSummary: TYPE = SymTab.Ref; Execute: PROC [comm: CDSequencer.Command] ~ BEGIN ENABLE SoS.coreInconsistent => BEGIN failureReason _ reason; failureTorch _ torch; GOTO failure END; violations: DRVSummary = SymTab.Create []; abort: REF BOOL _ NEW [BOOL _ FALSE]; ExtractAndCheck: PROC [comm: CDSequencer.Command] ~ BEGIN startTime1, startTime2, lapTime, stopTime: BasicTime.GMT; tech: Sinix.Mode _ SinixOps.GetExtractMode [comm.design.technology]; IF tech=NIL THEN BEGIN TerminalIO.PutRope [Rope.Cat ["The technology ", comm.design.technology.name, " is not implemented in Sinix or SoS.\n"]]; RETURN END; FOR all: CD.InstanceList _ CDOps.InstList [comm.design], all.rest WHILE all # NIL DO IF all.first.selected THEN BEGIN TRUSTED {Process.SetPriority [Process.priorityBackground]}; startTime1 _ BasicTime.Now []; WITH Sinix.Extract [obj: all.first.ob, mode: tech].result SELECT FROM coreCell: Core.CellType => BEGIN lapTime _ BasicTime.Now []; IF debug THEN CoreOps.PrintCellType [coreCell, dLog]; startTime2 _ BasicTime.Now []; [] _ SoS.CheckDesignRules [cell: coreCell, design: comm.design, abortFlag: abort, attributes: tech.decoration]; stopTime _ BasicTime.Now []; IF debug THEN BEGIN currentLambda _ comm.design.technology.lambda; VerifyObjects [comm.design, all.first.ob] END; IF timing THEN BEGIN TerminalIO.PutRope [Rope.Cat ["\nElapsed time for extraction: ", TimeToRope [startTime1, lapTime]]]; TerminalIO.PutRope [Rope.Cat [". Elapsed time for DRC: ", TimeToRope [startTime2, stopTime]]]; TerminalIO.PutRope [Rope.Cat ["\nTotal elapsed time: ", TimeToRope [startTime1, stopTime], "\n"]] END; UpdateDRVDirectory [coreCell, violations] END; w: Core.Wire => NULL; ENDCASE => NULL END -- if selected ENDLOOP END; -- ExtractAndCheck TerminalIO.PutRope ["SoS.\n"]; CDProperties.PutDesignProp [comm.design, $SoSCmdDir]; CDSequencer.UseAbortFlag [comm.design, abort]; [] _ CDCommandOps.DoWithResource [ExtractAndCheck, comm, $SoS]; TerminalIO.PutRope ["SoS done.\n"]; IF (violations.GetSize[] > 0) THEN BEGIN TerminalIO.PutRope ["Summary of design rule violations:\n"]; CDProperties.PutDesignProp [comm.design, $SoSCmdDir, violations]; [] _ violations.Pairs [PrintDRVSummary] END; EXITS failure => BEGIN TerminalIO.PutRope [failureReason]; TerminalIO.PutRope [". Core structure inconsistent. SoS aborted.\n"] END END; -- Execute List: PROC [comm: CDSequencer.Command] ~ BEGIN violations: DRVSummary = NARROW [CDProperties.GetDesignProp [comm.design, $SoSCmdDir]]; abort: REF BOOL _ NEW [BOOL_FALSE]; ListDRV: PROC [comm: CDSequencer.Command] ~ BEGIN existsInCD: BOOL; drv: SoS.DRV; cell: Rope.ROPE _ CDMenuSpecials.SelectOneOf [violations, "Cells with errors"]; IF (cell = NIL) THEN RETURN; -- no selection drv _ NARROW [SymTab.Fetch[violations, cell].val, SoS.DRV]; FOR e: LIST OF SoS.ErrorRect _ drv.places, e.rest WHILE e # NIL DO TerminalIO.PutRope [e.first.msg.Cat ["\n"]]; IF abort^ THEN ERROR ABORTED ENDLOOP; existsInCD _ CDDirectory.Fetch [comm.design, cell].found; IF NOT existsInCD THEN TerminalIO.PutRope ["No ChipNDale correspondent found for this cell.\n"] ELSE BEGIN nestedCmd: CDSequencer.Command _ NEW [CDSequencer.CommandRec _ [key: $PushNamed, design: comm.design, data: cell, ref: comm.ref]]; TerminalIO.PutRope ["Trying to push into ChipNDale correspondent for this cell. Pop out of current cell if it fails.\n"]; CDSequencer.ExecuteCommand [comm: nestedCmd, queue: dontQueue]; END END; -- ListDRV TerminalIO.PutRope ["List design rule violations.\n"]; CDSequencer.UseAbortFlag [comm.design, abort]; IF (violations = NIL) THEN TerminalIO.PutRope ["None available.\n"] ELSE [] _ CDCommandOps.DoWithResource [ListDRV, comm, $SoS]; TerminalIO.PutRope ["Design rule violations listed.\n"] END; -- List ListAll: PROC [comm: CDSequencer.Command] ~ BEGIN violations: DRVSummary = NARROW [CDProperties.GetDesignProp [comm.design, $SoSCmdDir]]; abort: REF BOOL _ NEW [BOOL_FALSE]; PrintDRV: SymTab.EachPairAction ~ BEGIN drv: SoS.DRV = NARROW [val]; TerminalIO.PutRope [IO.PutFR ["cell %g, %g violations:\n", IO.rope [key], IO.int [drv.count]]]; FOR e: LIST OF SoS.ErrorRect _ drv.places, e.rest WHILE e # NIL DO TerminalIO.PutRope [e.first.msg.Cat ["\n"]]; IF abort^ THEN ERROR ABORTED ENDLOOP; RETURN [abort^] END; -- PrintDRV ListDRV: PROC [comm: CDSequencer.Command] ~ BEGIN IF violations.Pairs [PrintDRV] THEN TerminalIO.PutRope ["Aborted.\n"] END; -- ListDRV TerminalIO.PutRope ["List all design rule violations.\n"]; CDSequencer.UseAbortFlag [comm.design, abort]; IF (violations = NIL) THEN TerminalIO.PutRope ["None available.\n"] ELSE [] _ CDCommandOps.DoWithResource [ListDRV, comm, $SoS]; TerminalIO.PutRope ["All design rule violations listed.\n"] END; -- ListAll UpdateDRVDirectory: PROC [cell: Core.CellType, dir: DRVSummary] ~ BEGIN name: Rope.ROPE = CoreOps.GetCellTypeName[cell]; IF SymTab.Fetch[dir, name].found THEN RETURN; -- prune SELECT cell.class FROM CoreClasses.recordCellClass => BEGIN data: CoreClasses.RecordCellType = NARROW [cell.data]; drv: SoS.DRV = NARROW [CoreProperties.GetProp [cell.properties, SoS.DRVkey]]; FOR sub: NAT IN [0 .. data.size) DO UpdateDRVDirectory [data.instances[sub].type, dir] ENDLOOP; IF (drv # NIL) THEN [] _ dir.Insert [name, drv] END; ENDCASE => NULL END; -- UpdateDRVDirectory PrintDRVSummary: SymTab.EachPairAction ~ BEGIN drv: SoS.DRV = NARROW [val]; TerminalIO.PutRope [IO.PutFR ["cell %g: %g\n", IO.rope [key], IO.int [drv.count]]]; RETURN [FALSE] END; -- PrintDRVSummary InvalidateDRV: CDEvents.EventProc ~ BEGIN violations: DRVSummary = NARROW [CDProperties.GetDesignProp [design, $SoSCmdDir]]; cellName: Rope.ROPE = CDDirectory.Name [NARROW [x, CD.Object]]; IF (violations # NIL) AND (cellName # NIL) THEN [] _ violations.Delete [cellName] END; -- InvalidateDRV VerifyRect: CD.DrawProc ~ BEGIN specialLayers: CD.Layer = 5; -- combined, highLightShade, highLightError, pinRepresentation IF (inst.ob.class.objectType = $Rect) AND (inst.ob.layer >= specialLayers) AND (CDProperties.GetObjectProp [inst.ob, $SoSSeparationChecked] = NIL) THEN dLog.PutF [format: "Failed to check rectangle at [%g, %g] %l %g%l\n", v1: IO.int [trans.off.x / currentLambda], v2: IO.int [trans.off.y / currentLambda], v3: IO.rope ["b"], v4: IO.rope [CDOps.LayerRope[inst.ob.layer]], v5: IO.rope ["B"]] END; -- VerifyRect VerifyObjects: PROC [design: CD.Design, obj: CD.Object] ~ BEGIN envelope: CD.Instance = CDInstances.NewInst [obj]; drawRef: CD.DrawRef _ CD.CreateDrawRef [[design: design]]; drawRef.drawChild _ VerifyRect; envelope.trans.off _ [0, 0]; obj.class.drawMe [envelope, envelope.trans, drawRef] END; -- VerifyObjects TimeToRope: PROC [from, to: BasicTime.GMT] RETURNS [time: Rope.ROPE] ~ BEGIN tmp: Rope.ROPE; sec: INT = BasicTime.Period [from, to]; min: INT = sec / 60; h: INT = min / 60; tmp _ IO.PutFR1 [value: IO.int [h]]; time _ SELECT h FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp; tmp _ IO.PutFR1 [value: IO.int [min MOD 60]]; time _ Rope.Cat [time, ":", SELECT min FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp]; tmp _ IO.PutFR1 [value: IO.int [sec MOD 60]]; time _ Rope.Cat [time, ":", SELECT sec FROM = 0 => "00", < 10 => Rope.Cat ["0", tmp], ENDCASE => tmp] END; -- TimeToRope Debug: PROC ~ BEGIN viewer: ViewerTools.Viewer; dummy: IO.STREAM; debug _ TRUE; -- Get all in one viewer _ ViewerTools.FindExistingViewer ["SoS debug"]; IF viewer # NIL THEN [in: dummy, out: dLog] _ ViewerIO.CreateViewerStreams ["SoS debug", viewer] ELSE BEGIN viewer _ ViewerTools.FindExistingViewer ["Terminal"]; [in: dummy, out: dLog] _ ViewerIO.CreateViewerStreams ["Terminal", viewer] END END; -- Debug [] _ CDProperties.RegisterProperty [$SoSCmdDir, $gbb]; CDSequencer.ImplementCommand [key: $SoSSel, proc: Execute, queue: doQueue]; CDSequencer.ImplementCommand [key: $SoSDir, proc: List, queue: doQueue]; CDPanel.DefineButton [name: "List Violations (SoS)", border: TRUE, command: $SoSDir]; CDSequencer.ImplementCommand [key: $SoSAll, proc: ListAll, queue: doQueue]; CDPanel.DefineButton [name: "List All Violations (SoS)", border: TRUE, command: $SoSAll]; CDEvents.RegisterEventProc [proc: InvalidateDRV, event: $AfterCellReplacement]; CDEvents.RegisterEventProc [proc: InvalidateDRV, event: $AfterChange]; IF debug THEN Debug []; TerminalIO.PutRope ["SoS package loaded.\n"] END. ŒSoSCommandImpl.mesa Copyright Σ 1985, 1986, 1987 by Xerox Corporation. All rights reserved. Written by gbb September 20, 1985 11:52:24 am PDT gbb January 9, 1987 1:01:25 pm PST Bertrand Serlet September 6, 1986 0:02:12 am PDT Interface to ChipNDale. Called by ChipNDale upon activation of the command. Protected procedure. Called by ChipNDale upon activation of the command. Protected procedure. muss Variable sein nicht Konstante [Compiler]. IF (ISTYPE [comm.ref, CDVPrivate.VRef]) THEN BEGIN Display error messages in the layout. viewer: ViewerClasses.Viewer = NARROW [comm.ref, CDVPrivate.VRef].viewer; IF (viewer # NIL) THEN ViewerOps.PaintViewer [viewer, client, FALSE, $DrawInstanceNames] END Called by ChipNDale upon activation of the command. [key: Key, val: Val] RETURNS [quit: BOOL] Protected procedure. Enumerates the cell and puts the DesignRuleViolations in the directory. [key: Key, val: Val] RETURNS [quit: BOOL] [event: REF, design: CD.Design, x: REF] RETURNS [dont: BOOL _ FALSE] Deletes a cell from the table when the cell has been edited. violations is NIL if the design has not yet been checked by SoS. [inst: Instance, trans: Transformation, pr: REF DrawInformation] Traverses the cell and reports undiscovered rectangles. Although the INT returned BasicTime.Period is the same as GMT and might hence be loopholed to use IO.time from Conversions, the latter uses BasicTime.Unpack which allows only values that give a valid date. For convenience in debugging. Call this procedure in the Interpreter. CDMenus.CreateEntry [menu: $ProgramMenu, entry: "List Violations (SoS)", key: $SoSDir]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "List All Violations (SoS)", key: $SoSAll]; gbb March 25, 1986 10:39:05 am PST Changed labels of menu entries. gbb March 27, 1986 3:13:47 pm PST Added cosmetics to make it look more like Spinifex. changes to: DIRECTORY, IMPORTS, Execute, ExtractAndCheck (local of Execute), UpdateDRVDirectory, PrintDRVSummary, VerifyRect gbb March 30, 1986 3:17:31 pm PST Added cosmetics to make it look better than Spinifex. changes to: ListDRV (local of List), InvalidateDRV gbb June 9, 1986 6:09:27 pm PDT Tracked addition of a parameter in the call of SoS changes to: ExtractAndCheck (local of Execute): new parameter technology (is not used). gbb October 3, 1986 3:59:55 pm PDT Worked around a really funny bug in the code generation for signals and the signal handler. changes to: Execute Κ ›˜™JšœH™HIcode™1K™"K™0K˜—Icode2šΟl™šΟk ˜ Kšœ žœžœ˜#Kšžœžœ[˜cKšœ žœ˜$Kšœ žœ˜ Kšœ žœ ˜.Kšœ žœ ˜Kšœžœ˜#Kšœžœ˜"Kšœžœ˜Kšœ žœA˜SKšœ žœG˜XKšœžœ˜Kšœ žœ#˜4Kšœ ˜ Kšœžœ"˜/Kšœžœ ˜Kšžœžœ1žœ˜AKšœžœ˜Kšœžœ#˜0Kšœžœžœ˜Kšœžœ˜Kšœ žœ˜ Kšœžœ&žœ˜GKšœžœF˜RKšœ žœ ˜Kšœ žœ˜%Kšœ žœ˜/—LšΠlnœž ˜Lšžœ žœ•žœP˜όšœž˜LšœžœžœΟcΟo˜JKšœžœžœ ˜,Kšœžœžœžœ˜1Kšœžœž œ˜#Kšœžœ  1˜KLšœ žœ˜šΟnœžœž˜1L™3šžœž˜$Kšœ-˜-Kšžœ˜ Kšžœ˜—Kšœ*˜*Lš œžœžœžœžœžœ˜%unitš’œžœž˜9K™Kšœ5žœ˜9MšœD˜Dšžœžœžœž˜Kšœy˜yKšž˜Kšžœ˜—K˜š žœžœ7žœžœž˜Tšžœžœž˜ Kšžœ4˜;Kšœ˜šž œ'ž ˜Ešœž˜ Kšœ˜Kšžœžœ(˜5Kšœ˜KšœV˜oKšœ˜šžœžœž˜Kšœ.˜.Kšœ)˜)Kšž˜—šžœžœž˜Kšœd˜dKšœ_˜_Kšœa˜aKšž˜—Kšœ)˜)Kšžœ˜—Kšœžœ˜Kšžœž˜Kšžœ ˜——Jšž˜—Kšžœ ˜—Mšœ˜Kšœ5˜5Kšœ.˜.Kšœ?˜?Kšœ#˜#šžœžœž˜(Kšœ<˜£ œžœ/™~Kšœžœ3˜RKš œžœžœžœžœ ˜?Kš žœžœžœ žœžœ"˜QKšžœ ˜—š’ œžœ ž˜Kšœ,žœ™@Kšœžœ  >˜[š žœ$žœ"žœ@žœž˜—Kš œJžœ(žœ(žœžœ,žœ ˜νKšœ˜—Kšžœ  ˜—š ’ œžœ žœžœ ž˜?K™7Kšœ žœ&˜2Kšœ žœ žœ"˜:Kšœ˜Kšœ˜Jšœ4˜4Kšžœ  ˜—š ’ œžœžœžœ žœž˜LKšœ Πekœ £œ€œ%€£œ£ œ£œ1™ΝKšœ žœ˜Kšœžœ˜'Kšœžœ ˜Kšœžœ ˜Mšœžœžœ ˜$Kšœžœžœ+žœ˜NMšœžœžœ žœ˜-Kšœžœžœ+žœ ˜fMšœžœžœ žœ˜-Kšœžœžœ+žœ˜eKšžœ  ˜—š’œžœž˜K™EKšœ˜Kšœžœžœ˜Kšœžœ ˜Kšœ6˜6šžœ ž˜KšœK˜K—šžœž˜ Kšœ5˜5KšœJ˜JKšž˜—Kšžœ ˜ —Lšœ6˜6LšœK˜KLšœH˜HKšœ=žœ˜UKšœW™WLšœK˜KKšœAžœ˜YKšœ[™[LšœO˜OKšœF˜FLšžœžœ ˜Kšœ,˜,—Lšžœ˜™"K™—™!K™3Kšœ Οr,œ₯1™|—™!K™5Kšœ ₯œ₯ ™2—™K™2Kšœ ₯œ<™W—™"K™[Kšœ ₯™—K™—…—'t<›