SoSCommandImpl.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.
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: 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
DRVSummary: TYPE = SymTab.Ref;
Execute: PROC [comm: CDSequencer.Command] ~ BEGIN
Called by ChipNDale upon activation of the command.
ENABLE SoS.coreInconsistent => GOTO failure;
violations: DRVSummary = SymTab.Create [];
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 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
Called by ChipNDale upon activation of the command.
violations: DRVSummary = NARROW [CDProperties.GetDesignProp [comm.design, $SoSCmdDir]];
abort: REF BOOLNEW [BOOLFALSE];
ListDRV: PROC [comm: CDSequencer.Command] ~ BEGIN
Protected procedure.
existsInCD: BOOL; drv: SoS.DRV;
cell: Rope.ROPE ← CDMenuSpecials.SelectOneOf [violations, "Cells with errors"];
muss Variable sein nicht Konstante [Compiler].
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];
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
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
Called by ChipNDale upon activation of the command.
violations: DRVSummary = NARROW [CDProperties.GetDesignProp [comm.design, $SoSCmdDir]];
abort: REF BOOLNEW [BOOLFALSE];
PrintDRV: SymTab.EachPairAction ~ BEGIN
[key: Key, val: Val] RETURNS [quit: BOOL]
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
Protected procedure.
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
Enumerates the cell and puts the DesignRuleViolations in the directory.
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
[key: Key, val: Val] RETURNS [quit: BOOL]
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
[event: REF, design: CD.Design, x: REF] RETURNS [dont: BOOLFALSE]
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.
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
[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.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
Traverses the cell and reports undiscovered rectangles.
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
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
[] ← 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.
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).