SoSCommandImpl.mesa
Copyright (C) 1985 by Xerox Corporation. All rights reserved.
Written by gbb September 20, 1985 11:52:24 am PDT
gbb March 7, 1986 10:22:18 am PST
Interface to ChipNDale.
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: BOOLFALSE; -- to start debugging enter: ← SoSCommandImpl.Debug[]
timing: BOOLFALSE; -- 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
Called by ChipNDale upon activation of the command
ENABLE SoS.coreInconsistent => GOTO failure;
abort: REF BOOLNEW [BOOLFALSE];
ExtractAndCheck: PROC [comm: CDSequencer.Command] ~ BEGIN
Protected procedure
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
Traverses the cell and reports undiscovered rectangles.
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
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.
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
For convenience in debugging. Call this procedure in the Interpreter.
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.