DIRECTORY BasicTime USING [GMT, Now, Period], CD USING [CreateDrawRef, Design, DrawProc, DrawRef, Instance, InstanceList, Layer, Number, Object], CDCommandOps USING [CallWithResource], CDDirectory USING [Fetch, Name], CDEvents USING [EventProc, RegisterEventProc], CDInstances USING [NewInst], CDMenus USING [CreateEntry], CDMenuSpecials USING [SelectOneOf], CDOps USING [InstList, LayerName], CDProperties USING [GetDesignProp, GetObjectProp, PutDesignProp, RegisterProperty], CDSequencer USING [Command, CommandRec, ExecuteCommand, ImplementCommand], Core USING [CellType], CoreClasses USING [recordCellClass, RecordCellType], 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 [ExtractCell, Mode], SinixCMos USING [extractAMode, extractBMode], SoS USING [CheckDesignRules, coreInconsistent, DRV, DRVkey, ErrorRect], SymTab USING [Create, Delete, EachPairAction, Fetch, GetSize, Insert, Pairs, Ref], TerminalIO USING [WriteRope, WriteLn], ViewerIO USING [CreateViewerStreams], ViewerTools USING [FindExistingViewer, Viewer]; SoSCommandImpl: CEDAR PROGRAM IMPORTS BasicTime, CD, CDCommandOps, CDDirectory, CDEvents, CDInstances, CDMenus, CDMenuSpecials, CDOps, CDProperties, CDSequencer, CoreClasses, CoreOps, CoreProperties, IO, Process, Rope, Sinix, SinixCMos, TerminalIO, ViewerIO, ViewerTools, SoS, SymTab ~ BEGIN debug: BOOL _ FALSE; -- to start debugging enter: _ SoSCommandImpl.Debug[] timing: BOOL _ FALSE; -- turn off fast mouse 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 => GOTO failure; 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; cdObjHint: ATOM _ $PWCoreLayout; SELECT comm.design.technology.key FROM $cmos => tech _ SinixCMos.extractAMode; $cmosB => tech _ SinixCMos.extractBMode; ENDCASE => BEGIN TerminalIO.WriteRope [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 coreCell: Core.CellType; TRUSTED {Process.SetPriority [Process.priorityBackground]}; BEGIN startTime1 _ BasicTime.Now []; coreCell _ NARROW [Sinix.ExtractCell [obj: all.first.ob, mode: tech].result]; lapTime _ BasicTime.Now []; IF debug THEN CoreOps.PrintCellType [coreCell, dLog]; END; -- Extraction BEGIN startTime2 _ BasicTime.Now []; SoS.CheckDesignRules [cell: coreCell, design: comm.design, technology: comm.design.technology, -- redundand -- abortFlag: abort, verbose: FALSE, cdObjKey: cdObjHint, cdInstKey: tech.instanceProp, cdInstListKey: tech.wireGeometryProp]; stopTime _ BasicTime.Now []; IF debug THEN BEGIN currentLambda _ comm.design.technology.lambda; VerifyObjects [comm.design, all.first.ob] END END; IF timing THEN BEGIN TerminalIO.WriteRope [Rope.Cat ["\nElapsed time for extraction: ", TimeToRope [startTime1, lapTime]]]; TerminalIO.WriteRope [Rope.Cat [". Elapsed time for DRC: ", TimeToRope [startTime2, stopTime]]]; TerminalIO.WriteRope [Rope.Cat ["\nTotal elapsed time: ", TimeToRope [startTime1, stopTime], "\n"]] END; UpdateDRVDirectory [coreCell, violations] END -- if selected ENDLOOP END; -- ExtractAndCheck TerminalIO.WriteRope ["SoS.\n"]; CDProperties.PutDesignProp [comm.design, $SoSCmdDir]; [] _ CDCommandOps.CallWithResource [ExtractAndCheck, comm, $SoS, abort]; TerminalIO.WriteRope ["SoS done.\n"]; IF (violations.GetSize[] > 0) THEN BEGIN TerminalIO.WriteRope ["Summary of design rule violations:\n"]; CDProperties.PutDesignProp [comm.design, $SoSCmdDir, violations]; [] _ violations.Pairs [PrintDRVSummary] END; EXITS failure => TerminalIO.WriteRope ["Core structure inconsistent. SoS aborted.\n"]; 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.WriteRope [e.first.msg]; TerminalIO.WriteLn; IF abort^ THEN ERROR ABORTED ENDLOOP; existsInCD _ CDDirectory.Fetch [comm.design, cell].found; IF NOT existsInCD THEN TerminalIO.WriteRope ["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.WriteRope ["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.WriteRope ["List design rule violations.\n"]; IF (violations = NIL) THEN TerminalIO.WriteRope ["None available.\n"] ELSE [] _ CDCommandOps.CallWithResource [ListDRV, comm, $SoS, abort]; TerminalIO.WriteRope ["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.WriteRope [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.WriteRope [e.first.msg]; TerminalIO.WriteLn; IF abort^ THEN ERROR ABORTED ENDLOOP; RETURN [abort^] END; -- PrintDRV ListDRV: PROC [comm: CDSequencer.Command] ~ BEGIN IF violations.Pairs [PrintDRV] THEN TerminalIO.WriteRope ["Aborted.\n"] END; -- ListDRV TerminalIO.WriteRope ["List all design rule violations.\n"]; IF (violations = NIL) THEN TerminalIO.WriteRope ["None available.\n"] ELSE [] _ CDCommandOps.CallWithResource [ListDRV, comm, $SoS, abort]; TerminalIO.WriteRope ["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.WriteRope [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 IO.PutF [stream: dLog, format: "Failed to check rectangle at [%g, %g] %l %g%l\n", v1: IO.int [pos.x / currentLambda], v2: IO.int [pos.y / currentLambda], v3: IO.rope ["b"], v4: IO.rope [CDOps.LayerName[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.location _ [0, 0]; obj.class.drawMe [envelope, envelope.location, 0, 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]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Extract & DRC (Sinix & SoS)", key: $SoSSel]; CDSequencer.ImplementCommand [key: $SoSDir, proc: List, queue: doQueue]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "List Violations (SoS)", key: $SoSDir]; CDSequencer.ImplementCommand [key: $SoSAll, proc: ListAll, queue: doQueue]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "List All Violations (SoS)", key: $SoSAll]; CDEvents.RegisterEventProc [proc: InvalidateDRV, event: $AfterCellReplacement]; CDEvents.RegisterEventProc [proc: InvalidateDRV, event: $AfterChange]; IF debug THEN Debug []; TerminalIO.WriteRope ["SoS package loaded.\n"] END. pSoSCommandImpl.mesa Copyright (C) 1985, 1986 by Xerox Corporation. All rights reserved. Written by gbb September 20, 1985 11:52:24 am PDT gbb June 10, 1986 10:40:40 am PDT Bertrand Serlet June 1, 1986 11:40:16 pm PDT Interface to ChipNDale. Called by ChipNDale upon activation of the command. Protected procedure. $nmos => tech _ $SinixNMosExtractProc; 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, pos: Position, orient: Orientation, 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. 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). Κ F˜™J™DIcode™1K™!K™,K˜—Icode2šΟl™šΟk ˜ Kšœ žœžœ˜#Kšžœžœ[˜cKšœ žœ˜&Kšœ žœ˜ Kšœ žœ ˜.Kšœ žœ ˜Kšœžœ˜Kšœžœ˜#Kšœžœ˜"Kšœ žœA˜SKšœ žœ9˜JKšœžœ ˜Kšœ žœ#˜4Kšœžœ"˜/Kšœžœ ˜Kšžœžœ1žœ˜AKšœžœ˜Kšœžœ#˜0Kšœžœžœ˜Kšœžœ˜ Kšœ žœ˜-Kšœžœ&žœ˜GKšœžœF˜RKšœ žœ˜&Kšœ žœ˜%Kšœ žœ˜/—LšΠlnœž ˜Lšžœ žœ•žœQ˜ύšœž˜LšœžœžœΟcΟo˜JKšœžœžœ ˜,Kšœžœž œ˜#Kšœžœ  1˜KLšœ žœ˜šΟnœžœž˜1L™3Kšžœžœ ˜,Kšœ*˜*Lš œžœžœžœžœžœ˜#unitš’œžœž˜9K™Kšœ5žœ˜9Kšœ˜Kšœ žœ˜ šžœž˜&Kšœ'˜'Kšœ(˜(Kšœ&™&šžœž˜Kšœ{˜{Kšž˜Kšžœ˜——š žœžœ7žœžœž˜Tšžœžœž˜ Jšœ˜Kšžœ4˜;šž˜Kšœ˜Kšœ žœœ)˜MKšœ˜Kšžœžœ(˜5Kšžœ  ˜—šž˜Kšœ˜KšœK œžœ[˜κKšœ˜šžœžœž˜Kšœ.˜.Kšœ)˜)Kšž˜—Kšž˜—šžœžœž˜Kšœf˜fKšœa˜aKšœc˜cKšž˜—Kšœ)˜)Kšžœ ˜—Jšž˜—Kšžœ ˜—Mšœ ˜ Kšœ5˜5KšœH˜HKšœ%˜%šžœžœž˜(Kšœ>˜>KšœA˜AKšœ'˜'Kšžœ˜—šž˜KšœP˜P—Lšžœ  ˜—š’œžœž˜.K™3Kšœžœ8˜WLš œžœžœžœžœžœ˜#š’œžœž˜1K™Kšœ žœ žœ˜šœ žœ@˜OKšœ.™.—Kš žœ žœžœžœ ˜,Kšœžœ*žœ˜;š žœžœžœ$žœžœž˜BJšœ8˜8Kšžœžœžœž˜Jšžœ˜—Kšœ9˜9šžœžœ ž˜KšœJ˜J—šžœž˜ Kšœ!žœ^˜‚Kšœ|˜|Kšœ?˜?šžœžœžœž™2K™%Kšœžœ$™IKšžœ žœžœ(žœ™XKšž™—Kšž˜—Kšžœ  ˜—Mšœ8˜8Kšžœžœžœ+˜EKšžœA˜EKšœ9˜9Kšžœ ˜ —š’œžœž˜1K™3Kšœžœ8˜WLš œžœžœžœžœžœ˜#š’œž˜'Kšœžœžœ™)Kšœ žœžœ˜Kšœžœ%žœ žœ˜aš žœžœžœ$žœžœž˜BJšœ8˜8Kšžœžœžœž˜Jšžœ˜—Kšžœ ˜Kšžœ  ˜—š’œžœž˜1K™Kšžœžœ$˜GKšžœ  ˜—Mšœ<˜£ œžœ/™~Kšœžœ3˜RKš œžœžœžœžœ ˜?Kš žœžœžœ žœžœ"˜QKšžœ ˜—š’ œžœ ž˜Kšœ9žœ™MKšœžœ  >˜[š žœ$žœ"žœ@žœž˜—Kš žœTžœ"žœ"žœžœ,žœ ˜νKšœ˜—Kšžœ  ˜—š ’ œžœ žœžœ ž˜?K™7Kšœ žœ&˜2Kšœ žœ žœ"˜:Kšœ˜Kšœ˜Jšœ:˜:Kšžœ  ˜—š ’ œžœžœžœ žœž˜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˜KKšœ]˜]LšœH˜HKšœW˜WLšœK˜KKšœ[˜[LšœO˜OKšœF˜FLšžœžœ ˜Kšœ.˜.—Lšžœ˜™"K™—™!K™3Kšœ Οr,œ₯1™|—™!K™5Kšœ ₯œ₯ ™2—™K™2Kšœ ₯œ<™W—K™—…—'ά;’