SpinifexCircuit.mesa
Copyright © 1984 by Xerox Corporation. All rights reserved.
Written by Shand, September 12, 1983 11:40 pm
Last Edited by: Shand, September 4, 1984 8:54:22 pm PDT
DIRECTORY
CD USING [Level, ApplicationPtr, ApplicationList, Number, Rect, Design, DesignPosition, Orientation, ObPtr],
CDInline USING [empty],
CDOrient USING [original],
Atom USING [PropList],
Rope USING [ROPE],
RefTab USING [Ref]
;
SpinifexCircuit: CEDAR DEFINITIONS ~ BEGIN
AZ: ZONE;
PaintErrorRect: PROCEDURE [cell: REF LogicalCell, errorBox: CD.Rect, message: Rope.ROPE];
TranslateGeometry: PROCEDURE [cell: REF LogicalCell];
PerRectProc: TYPE ~ PROCEDURE [r: REF Rectangle, data: REF ANY];
EnumerateGeometry: PUBLIC PROCEDURE [circuit: REF Circuit, layer: SpinifexLayerIndex, clipRect: CD.Rect, PerRect: PerRectProc, data: REF ANY];
-- AddBox adds a box to a particular analysis layer when fine control or asymetric interest bloating is required. The box, of dimension dim is transform according to appl.
AddBox:
PROCEDURE [ cir:
REF Circuit,
spinifexLayer: SpinifexLayerIndex,
dim:
CD.Rect,
appl:
CD.ApplicationPtr ←
NIL,
pos:
CD.DesignPosition ← [0,0],
orient:
CD.Orientation ← CDOrient.original,
interestBloat: RectDelta ← [0,0,0,0],
value:
REF
ANY ←
NIL]
RETURNS [cirNode: REF CircuitNode ← NIL];
-- AddRect adds a Rectangle from a normal chipndale mask level, to each of the analysis layers which the techHandle dictates. May raise ERROR IllegalLevel.
AddRect:
PROCEDURE [ cir:
REF Circuit,
lev:
CD.Level,
dim:
CD.Rect,
appl:
CD.ApplicationPtr ←
NIL,
pos:
CD.DesignPosition ← [0,0],
orient:
CD.Orientation ← CDOrient.original,
value:
REF CircuitNode ←
NIL]
RETURNS [cirNode: REF CircuitNode ← NIL];
IllegalConstruct: ERROR [rect: CD.Rect, reason: Rope.ROPE];
IllegalLevel: ERROR [rect: CD.Rect, lev: CD.Level];
CreateLinkage: PROCEDURE [ cir: REF Circuit, source: CD.ApplicationPtr] RETURNS [REF NodeLinkage];
LinkageAttach: PROCEDURE [link: REF NodeLinkage, attachType: ATOM, areaAdj: INTEGER ← 0, perimAdj: INTEGER ← 0, node: REF CircuitNode ← NIL];
NormalizeCircuit: PROCEDURE [cir: REF Circuit];
LookupNode: PROCEDURE [l: REF CircuitNode] RETURNS [REF CircuitNode];
FindRootNode: PROCEDURE [circuit: REF Circuit, subcircuitNode: REF CircuitNode, qualifier: LIST OF CD.ApplicationPtr, insertIfNotInCircuit: BOOLEAN ← FALSE] RETURNS [node: REF CircuitNode, rootQualifier: LIST OF CD.ApplicationPtr];
MergeNode: PROCEDURE [ circuit: REF Circuit, to, from: REF CircuitNode];
AdjustmentMode: TYPE ~ {relative, absolute};
AdjustNode: PROCEDURE [node: REF CircuitNode, layer: SpinifexLayerIndex, area: INT, perim: INT, mode: AdjustmentMode ← relative];
LogicalCell:
TYPE ~
RECORD [
cellObj: CD.ObPtr,
design: CD.Design,
circuit: REF Circuit ← NIL,
errorCount: INT ← 0,
errorContext: CD.ObPtr ← NIL, -- Most immediate enclosing context which is a real cell, i.e. has an accessible application list.
relativePos: CD.DesignPosition ← [0,0], -- cellObj within errorContext
relativeOrient: CD.Orientation ← CDOrient.original
];
Circuit:
TYPE ~
RECORD [
nodes: LIST OF REF CircuitNode ← NIL,
linkages: LIST OF REF NodeLinkage ← NIL,
linkageCount:
RECORD [
inSelf: INT ← 0,
inChildren: INT ← 0
],
subcircuits: CD.ApplicationList ← NIL,
mergeDirectory: RefTab.Ref ← NIL,
technologyHandle: REF TechHandle ← NIL,
properties: Atom.PropList ← NIL,
invocationKey: INT,
spinifexLayers: ARRAY SpinifexLayerIndex OF QuadTreeRoot
];
QuadTreeRoot:
TYPE ~
RECORD [
size: CD.Rect ← CDInline.empty,
unsortedBoxes: LIST OF REF Rectangle ← NIL,
geometry: REF QuadTree ← NIL
];
QuadTree:
TYPE ~
RECORD [
boxes: LIST OF REF Rectangle,
midX, midY: CD.Number ← ,
subTrees: ARRAY AreaSplit OF REF QuadTree -- Note SubTrees overlap! north or south is prefered over east or west distribution.
];
AreaSplit: TYPE ~ {north, south, east, west};
Rectangle:
TYPE ~
RECORD [
interestBound: CD.Rect, -- Bounding box of region which Rectangle influences.
dimDecr: RectDelta, -- Decrement to be applied to interestBound give actual dimension.
nodeInformation: REF ANY -- CircuitNode for conductive primitive rects, cell application for cells.
];
RectDelta:
TYPE ~
RECORD [
-- A space saving Hack. Allows interest bloats of no more than 255/Lambda. Also requires strict containment of Rectangle's dimension in its InterestBoundary.
dx1, dy1, dx2, dy2: [0..256)
];
Dimension:
PROCEDURE [r:
REF Rectangle]
RETURNS [
CD.Rect] ~
INLINE {
RETURN [[x1~r.interestBound.x1+r.dimDecr.dx1, y1~r.interestBound.y1+r.dimDecr.dy1, x2~r.interestBound.x2-r.dimDecr.dx2, y2~r.interestBound.y2-r.dimDecr.dy2]];
};
CircuitNode:
PUBLIC
TYPE ~
RECORD [
superceded: REF CircuitNode ← NIL,
dim: LIST OF AreaPerimRec ← NIL,
attached: BOOLEAN ← FALSE, -- TRUE if the node is attached to some linkage. Filters logos from DRC.
properties: Atom.PropList ← NIL
];
AreaPerimRec:
TYPE ~
RECORD [
layer: SpinifexLayerIndex,
area, perim: INT
];
SignalName:
TYPE ~
RECORD [
depth: INTEGER,
name: Rope.ROPE,
alias: REF SignalName ← NIL
];
-- CircuitConstraint may contain circular REF chains, however they are a small in number fixed at compile time by the tech. dependent client software.
CircuitConstraint:
PUBLIC
TYPE ~
RECORD [
name: ATOM,
index: SpinifexConstraintIndex, -- a small integer.
-- withNodeResolution: leave node in conflict region if NIL else replace by REFed CircuitConstraint.
withNode: REF CircuitConstraint ← NIL,
withConstraint: LIST OF ConstraintResolution ← NIL,
hasCorrespondingNode: BOOLEAN ← FALSE,
correspondingNodeLayer: SpinifexLayerIndex ← SpinifexLayerIndex.FIRST
];
ConstraintResolution:
PUBLIC
TYPE ~
RECORD [
opponent, result: REF CircuitConstraint
];
NodeLinkage:
PUBLIC
TYPE ~
RECORD [
source: CD.ApplicationPtr,
nodes: LIST OF REF AttachedNode ← NIL
];
AttachedNode:
TYPE ~
RECORD [
attachmentType: ATOM,
areaAdjustment, perimAdjustment: INT,
node: REF CircuitNode
];
MergeRecList: TYPE ~ LIST OF MergeRec;
MergeRec:
TYPE ~
RECORD [
applChain: LIST OF CD.ApplicationPtr,
becomes: REF CircuitNode
];
ConversionProc: TYPE ~ PROCEDURE [appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, cir: REF Circuit];
BoxMapProc: TYPE ~ PROCEDURE [cir: REF Circuit, dim: CD.Rect, appl: CD.ApplicationPtr, pos: CD.DesignPosition, orient: CD.Orientation, node: REF CircuitNode] RETURNS [cirNode: REF CircuitNode ← NIL];
maxSpinifexLayer: INTEGER ~ 8;
SpinifexLayerIndex: TYPE ~ [0..maxSpinifexLayer);
-- Fact: this is a real hack, but let's face it I've got a day and a half to do a design rule checker. Anyway constraints are mapped to small integers which are then used to access the trigger tables in GeometricRules, the integers are relevant only with a given SpinifexLayer. The hack comes in that space regions map to 0 (zero) and node regions map to 1 (one). The trigger tables must be hand generated by the tech dependent client and are therefore error prone.
spaceIndex: INTEGER ~ 0; -- constraints with this index will be treated as space regions.
nodeIndex: INTEGER ~ 1; -- constraints with this index will be treated as node regions.
maxSpinifexConstraint: INTEGER ~ 16;
SpinifexConstraintIndex: TYPE ~ [0..maxSpinifexConstraint);
TechHandle:
TYPE ~
RECORD [
errorLevel: CD.Level,
numSpinifexLayers: SpinifexLayerIndex,
spinifexLayerNames: ARRAY SpinifexLayerIndex OF LayerNames,
layerInterestBloat: ARRAY SpinifexLayerIndex OF INTEGER ← ALL[0],
rules: ARRAY SpinifexLayerIndex OF LIST OF REF GeometricRule ← ALL[NIL],
cdLayerMapping: ARRAY CD.Level OF LIST OF MapRec ← ALL[NIL],
illegalLevel: ARRAY CD.Level OF BOOLEAN ← ALL[TRUE],
CombineNodeProperties: CombineNodePropertyProc ← NIL, -- For technology dependent properties.
CellPostProcess: CellPostProcessProc ← NIL -- For technology dependent manipulation and checking. (e.g. cmos n-well connects)
];
CombineNodePropertyProc: TYPE ~ PROCEDURE [circuit: REF Circuit, to, from: Atom.PropList, fromNesting: LIST OF CD.ApplicationPtr] RETURNS [Atom.PropList];
CellPostProcessProc: TYPE ~ PROCEDURE [cell: REF LogicalCell];
LayerNames:
TYPE ~
RECORD [
thymeName: Rope.ROPE ← NIL
];
MapRec:
TYPE ~
RECORD [
spinifexLayer: SpinifexLayerIndex,
bloatFactor: INTEGER, -- Interest Bloat.
value: REF ANY ← NIL -- If value is a REF BoxMapProc then this func is called to perform mapping.
];
-- So how does checking work? The four quads around a corner are mapped through trigger1 to TRUE/FALSE value for each quadrant. The TRUE area represents 'stuff' and if it forms a convex or concave corner a check is made of size extent into the corresponding 'non-stuff' in the FALSE region. To do a width check we map space to TRUE and the material being width checked to FALSE, thus an appropriate check is generated extending into the material. The check fails if anything in the check region maps through trigger2 to TRUE. If okIfConnected is TRUE then the violation is overidden if trigger1 and trigger2 circuit nodes and are the same.
GeometricRule:
TYPE ~
RECORD [
extent: INTEGER,
message: Rope.ROPE ← NIL,
okIfConnected: BOOLEAN ← FALSE,
trigger1, trigger2: PACKED ARRAY SpinifexConstraintIndex OF BOOLEAN ← ALL[FALSE]
];
END.