<> <> <> <> <> DIRECTORY BasicTime USING [GMT, Now, Period], CD USING [CreateDrawRef, Design, DrawProc, DrawRef, Instance, InstanceList, Layer, Number, Object], CDCommandOps USING [CallWithResource], CDInstances USING [NewInstance], CDMenus USING [CreateEntry], CDOps USING [InstList, LayerName], CDProperties USING [GetPropFromObject], CDSequencer USING [Command, ImplementCommand], Core USING [CellType], CoreOps USING [PrintCellType], IO USING [int, noWhereStream, PutF, PutFR1, rope, STREAM], PrincOpsUtils USING [], Process USING [priorityBackground, SetPriority], Rope USING [Cat, ROPE], Sinix USING [ExtractCell, Mode], SinixCMos USING [extractAMode, extractBMode], TerminalIO USING [WriteRope], ViewerIO USING [CreateViewerStreams], ViewerTools USING [FindExistingViewer, Viewer], SoS USING [coreInconsistent, CheckDesignRules]; SoSCommandImpl: CEDAR PROGRAM IMPORTS BasicTime, CD, CDCommandOps, CDInstances, CDMenus, CDOps, CDProperties, CDSequencer, CoreOps, IO, Process, Rope, Sinix, SinixCMos, TerminalIO, ViewerIO, ViewerTools, SoS ~ 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 Execute: PROC [comm: CDSequencer.Command] ~ BEGIN <> ENABLE SoS.coreInconsistent => GOTO failure; 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; <<$nmos => tech _ $SinixNMosExtractProc;>> ENDCASE => BEGIN TerminalIO.WriteRope [Rope.Cat ["The technology ", comm.design.technology.name, " is not implemented in 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 _ Sinix.ExtractCell [obj: all.first.ob, mode: tech].cellType; lapTime _ BasicTime.Now []; IF debug THEN CoreOps.PrintCellType [coreCell, dLog]; END; -- Extraction BEGIN startTime2 _ BasicTime.Now []; SoS.CheckDesignRules [coreCell, comm.design, abort, FALSE, cdObjHint, tech.instanceProp, tech.wireGeometryProp ! SoS.coreInconsistent => {TerminalIO.WriteRope ["\nCore data structure is inconsistent. You problably did not use today's keys.\n"]}]; 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 END -- if selected ENDLOOP END; -- ExtractAndCheck TerminalIO.WriteRope ["SoS.\n"]; [] _ CDCommandOps.CallWithResource [ExtractAndCheck, comm, $SoS, abort]; TerminalIO.WriteRope ["SoS done.\n"]; EXITS failure => TerminalIO.WriteRope ["Core structure inconsistent. SoS aborted.\n"]; END; -- Execute VerifyRect: CD.DrawProc ~ BEGIN <<[inst: Instance, pos: Position, orient: Orientation, pr: REF DrawInformation]>> specialLayers: CD.Layer = 5; -- combined, highLightShade, highLightError, pinRepresentation IF (inst.ob.class.objectType = $Rect) AND (inst.ob.layer >= specialLayers) AND (CDProperties.GetPropFromObject [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.NewInstance [obj]; drawRef: CD.DrawRef _ CD.CreateDrawRef [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 CDSequencer.ImplementCommand [a: $SoSSel, p: Execute, queue: doQueue]; CDMenus.CreateEntry [menu: $ProgramMenu, entry: "Extract & DRC", key: $SoSSel]; IF debug THEN Debug []; TerminalIO.WriteRope ["SoS package loaded.\n"] END.