-- ChipNetDefs.mesa
-- last modified by E. McCreight, January 10, 1983 6:22 PM
-- written by E. McCreight, November 3, 1981 12:14 PM
DIRECTORY
InlineDefs,
MiscDefs,
ppdefs,
StreamDefs,
ZoneAllocDefs;
ChipNetDefs: DEFINITIONS IMPORTS InlineDefs =
BEGIN
-- T y p e s
NanoMeters: TYPE = LONG INTEGER; -- on the silicon
Coord: TYPE = NanoMeters;
LocNumScale: TYPE = {lambdaRelative, absolute};
CoordPoint: TYPE = RECORD[x, y: Coord];
CoordRect: TYPE = RECORD[x1, y1, x2, y2: Coord];
-- [x1..x2), [y1..y2)
Interval: TYPE = RECORD[min,max: Coord];
-- [min..max)
ExtractLevel: TYPE = ppdefs.Level[cut..l39] ← unknown;
unknown: ExtractLevel = NOcOL;
nWell: ExtractLevel = nwel;
nWellRequired: ExtractLevel = l16;
nWellForbidden: ExtractLevel = l17;
pWell: ExtractLevel = pwel;
pWellRequired: ExtractLevel = l18;
pWellForbidden: ExtractLevel = l19;
nDepletion: ExtractLevel = imp;
nDepletionRequired: ExtractLevel = l20;
nDepletionForbidden: ExtractLevel = l21;
nBuriedContact: ExtractLevel = bur;
nBuriedContactRequired: ExtractLevel = l22;
nBuriedContactForbidden: ExtractLevel = l23;
thinOx: ExtractLevel = l24;
nPlus: ExtractLevel = dif;
nPlusRequired: ExtractLevel = l25;
nPlusForbidden: ExtractLevel = l26;
pPlus: ExtractLevel = pdif;
pPlusRequired: ExtractLevel = l27;
pPlusForbidden: ExtractLevel = l28;
nImplant: ExtractLevel = l29;
pImplant: ExtractLevel = l30;
nGate: ExtractLevel = l31;
nGateRequired: ExtractLevel = l32;
nGateForbidden: ExtractLevel = l33;
pGate: ExtractLevel = l34;
pGateRequired: ExtractLevel = l35;
pGateForbidden: ExtractLevel = l36;
poly: ExtractLevel = pol;
polyRequired: ExtractLevel = l37;
polyForbidden: ExtractLevel = l38;
cutForbidden: ExtractLevel = l39;
metal: ExtractLevel = met;
via: ExtractLevel = cut2;
metal2: ExtractLevel = met2;
pad: ExtractLevel = ovg;
LevCoordRect: TYPE = RECORD[lev: ExtractLevel,
r: CoordRect];
PropPtr: TYPE = LONG POINTER TO ppdefs.prop ← NIL;
Conductors: TYPE = {diffusion, poly, metal, metal2};
NetPtr, netPtr, netIntPtr: TYPE = LONG POINTER TO Net ← NIL;
CanonNetPtr: TYPE = LONG POINTER TO canon Net ← NIL;
LinkNetPtr: TYPE = LONG POINTER TO link Net ← NIL;
Net, net: TYPE = RECORD[
refs: CARDINAL ← 1, -- number of references passing through
rest: SELECT type: * FROM
link => [nxt: netIntPtr],
canon => [id: NetIdPtr],
ENDCASE
];
NetIdPtr: TYPE = LONG POINTER TO NetId ← NIL;
FreeNetIdPtr: TYPE = LONG POINTER TO free NetId ←
NIL;
NormalNetIdPtr: TYPE = LONG POINTER TO normal NetId ← NIL;
NetId: TYPE = RECORD
[next: NetIdPtr, -- in allNets chain
final: LevCoordRect ← [r: [x1: FIRST[Coord], x2: FIRST[Coord],
y1: FIRST[Coord], y2: FIRST[Coord]]],
-- final.x2 is the greatest x value at which
-- any piece of geometry
-- known to belong to this net exists.
violations: ConditionalViolationPtr,
-- violations only if otherNet is different
details: SELECT type: * FROM
free => [nextFree: FreeNetIdPtr],
well => [attachedTo: NetPtr],
normal =>
[
lastX: Coord ← LAST[Coord],
-- last value of x where caps were changed
caps: ARRAY Conductors OF LayerCap,
source: CellCallPtr, -- highest named source for
-- this net, or if none are named, highest unnamed source
hasPathToGnd, hasPathToVdd, hasDepletionPullup:
BOOLEAN ← FALSE,
couldBeLogo: BOOLEAN ← TRUE, -- if all metal
name: SELECT nameClass: * FROM
anonymous => [],
numeric => [n: CARDINAL],
qualified => [see: CellIndex -- (in .source) -- ],
ENDCASE
],
ENDCASE
] ← [details: normal[lastX: 0, name: anonymous[]]];
ConditionalViolationPtr: TYPE = LONG POINTER TO
ConditionalViolation ← NIL;
ConditionalViolation: TYPE = RECORD [
next: ConditionalViolationPtr,
otherNet: netPtr,
v: Violation
];
Violation: TYPE = RECORD [
place: ppdefs.Point ← [0,0],
caller: ItemRef,
type: ViolationType,
lev1, lev2: ExtractLevel -- parameters to type
];
ViolationType: TYPE = {unknown, tooNarrow, tooClose,
noNetToWell, differentNetsToWell, terminalsUnconnected,
coverageNeeded, coverageForbidden, bogusTransistor,
cantCheck} ← unknown;
ViolationListPtr: TYPE = LONG POINTER TO ViolationList ← NIL;
ViolationList: TYPE = RECORD [
next: ViolationListPtr,
v: Violation
];
LayerCapPtr: TYPE = LONG POINTER TO LayerCap ← NIL;
LayerCap: TYPE = RECORD [
cutSides: CARDINAL ← 0,
cutWidth, perimeter: ppdefs.locNum ← 0,
area: LONG CARDINAL ← 0 -- locNum↑2
];
SortClass: TYPE = {minX, maxX, minY, maxY};
orientToSortClass: ARRAY ppdefs.orientationIndex OF SortClass;
FeaturePtr: TYPE = LONG POINTER TO Feature ← NIL;
Feature: TYPE = RECORD[ -- cut by scan line
cover: CoordRect,
lev: ExtractLevel,
caller: ItemRef,
net: netIntPtr
];
CellInstPt: TYPE = RECORD [ -- priority queue item
x: Coord,
call: ItemRef
];
ItemRef: TYPE = RECORD[
head: InstancePtr,
idx: CellIndex ← 0 -- in head.seq[?] according
-- to head.orient
];
CellCallPtr: TYPE = LONG POINTER TO cell Instance ← NIL;
XstrCallPtr: TYPE = LONG POINTER TO xstr Instance ← NIL;
InstancePtr: TYPE = LONG POINTER TO Instance ← NIL;
Instance: TYPE = RECORD[
min: CoordPoint, -- as placed
orient: ppdefs.orientationIndex ← 0, -- as placed
proto: ProtoPtr,
caller: ItemRef,
sibling: InstancePtr,
nets: SELECT type: * FROM -- depending on .proto.ob.otyp
cell =>
[
offspring: InstancePtr,
clusters: ClusterPtr,
nets: NormalNetIdPtr
],
xstr =>
[
map: ARRAY XstrTerminals OF netPtr,
sameHash: XstrCallPtr,
inSimFile: BOOLEAN ← FALSE
],
cont => [net: netPtr],
ENDCASE
];
XstrTerminals: TYPE = {gate, source, drain};
ClusterPtr: TYPE = LONG POINTER TO Cluster ← NIL;
Cluster: TYPE = RECORD[
next: ClusterPtr,
netName: STRING,
first: MustConnect
];
MustConnectPtr: TYPE = LONG POINTER TO MustConnect ← NIL;
MustConnect: TYPE = RECORD[
next: MustConnectPtr,
net: netPtr,
source: ItemRef -- not counted in netMap, but
-- counted in unsatisfied
];
ProtoPtr: TYPE = LONG POINTER TO CellProto ← NIL;
CellProto: TYPE = RECORD[
ob: LONG POINTER TO ppdefs.object, -- cell, repeat
name: STRING ← NIL, -- from cList
size: CoordPoint,
itemCount: CellIndex ← 0,
stretchMasks: BOOLEAN ← TRUE,
locNumScale: LocNumScale ← lambdaRelative,
lp: ppdefs.listPtr ← NIL, -- of itemCount elements
seq: ARRAY SortClass OF ListPtrSeqPtr,
connections: ARRAY SortClass OF ConnectorPtr
];
CellIndex: TYPE = CARDINAL;
ListPtrSeqPtr: TYPE = LONG POINTER TO ListPtrSeq ← NIL;
ListPtrSeq: TYPE = RECORD[
lp: SEQUENCE count: CellIndex OF ppdefs.listPtr
];
ConnectorPtr: TYPE = LONG POINTER TO Connector ← NIL;
Connector: TYPE = RECORD [
next: ConnectorPtr,
lev: ExtractLevel,
range: Interval, -- the range of distances down
-- the left edge of the bounding box, or to the right
-- along the top edge of the bounding box.
depth: Coord,
-- inward from the edge of the bounding box
net: netIntPtr
];
-- C o n s t a n t s
checkAll: BOOLEAN = FALSE; -- turns on all structure-
-- checking routines.
featureDelay: ppdefs.locNum = 8*ppdefs.Lambda;
levelMap: ARRAY ppdefs.level OF ExtractLevel;
levelNames: ARRAY ExtractLevel OF STRING;
isConductor: ARRAY ExtractLevel OF BOOLEAN;
-- V a r i a b l e s
featureZ, netZ, netIdZ, instanceZ, clusterZ, transZ, uz:
UNCOUNTED ZONE;
origCifScale: INTEGER; -- centiMicrometers per lambda
lambdaRelativeCoordScale: Coord; -- Coords per ppdefs.locNum
coordScale: ARRAY LocNumScale OF Coord;
deltaOrigin: CoordPoint; -- actual - ideal
currentX: Coord; -- scan increases in x
notingMark: BOOLEAN; -- for debugging
extractCaps: BOOLEAN;
allNets: NetIdPtr;
-- P r o c e d u r e s
WriteSimFile: PUBLIC PROCEDURE[c: CellCallPtr];
-- explores the call tree rooted at c
AppendNet: PROCEDURE[s: STRING, net: netPtr]
RETURNS[CanonNetPtr];
AppendNetId: PROCEDURE[s: STRING, netId: NormalNetIdPtr];
AppendTerminalName:
PROCEDURE[s: STRING, c: ItemRef];
AppendCallerChain, AppendCallerLink:
PROCEDURE[s: STRING, c: InstancePtr];
AppendLocNum: PROCEDURE[s: STRING, n: ppdefs.locNum];
AppendCoord: PROCEDURE[s: STRING, n: Coord];
AppendCard: PROCEDURE[s: STRING,
n: LONG CARDINAL];
HeSetsParamsAndSaysYes: PROCEDURE[s1, s2: STRING ← NIL]
RETURNS[bit: BOOLEAN];
ItemInWorld: PROCEDURE[c: ItemRef] RETURNS[CoordRect];
SortOrder: ARRAY SortClass OF
PROCEDURE[lp1, lp2: ppdefs.listPtr] RETURNS[BOOLEAN];
SortListPtrSeq: PROCEDURE[lps: ListPtrSeqPtr,
less: PROCEDURE[lp1, lp2: ppdefs.listPtr] RETURNS[BOOLEAN]
];
NewNet: PROCEDURE[initRefs: CARDINAL ← 1]
RETURNS[CanonNetPtr];
MergeNets: PROCEDURE[n1, n2: netPtr]
RETURNS[CanonNetPtr];
-- n1, n2 # NIL
RefCanonNet: PROCEDURE[n: netPtr, newRefs: INTEGER ← 1]
RETURNS[CanonNetPtr];
UpdateAreas: PROCEDURE[n: NormalNetIdPtr];
GetNormalNetId: PROCEDURE[n: LONG POINTER TO netPtr]
RETURNS[NormalNetIdPtr];
CanonNet: PROCEDURE[n: netPtr]
RETURNS[CanonNetPtr] = INLINE
{RETURN[RefCanonNet[n: n, newRefs: 0]]};
DeRefNet: PROCEDURE[n: netPtr, removedRefs: INTEGER ← 1]
RETURNS[CanonNetPtr] = INLINE
BEGIN
[] ← RefCanonNet[n: n, newRefs: -removedRefs];
RETURN[NIL];
END;
ItemRefToLp: PROCEDURE[c: ItemRef]
RETURNS[ppdefs.listPtr] = INLINE
{RETURN[c.head.proto.seq[orientToSortClass[c.head.orient]]
[c.idx]]};
CoordSize: PROCEDURE[size: CoordPoint,
orient: ppdefs.orientationIndex] RETURNS[CoordPoint] =
INLINE
{RETURN[IF InlineDefs.BITAND[orient, 4]=0 THEN size
ELSE [x: size.y, y: size.x]]};
ScaleToChipmonk: PROCEDURE[x: Coord]
RETURNS[ppdefs.locNum] = INLINE
{RETURN[InlineDefs.LowHalf[x/lambdaRelativeCoordScale]]};
ScalePointToChipmonk: PROCEDURE[p: CoordPoint]
RETURNS[ppdefs.Point] = INLINE
{RETURN[[x: ScaleToChipmonk[p.x+deltaOrigin.x],
y: ScaleToChipmonk[p.y+deltaOrigin.y]]]};
ScaleFromChipmonk: PROCEDURE[x: ppdefs.locNum]
RETURNS[Coord] = INLINE
{RETURN[x*lambdaRelativeCoordScale]};
ScalePointFromChipmonk: PROCEDURE[p: ppdefs.Point]
RETURNS[CoordPoint] = INLINE
{RETURN[[x: ScaleFromChipmonk[p.x]-deltaOrigin.x,
y: ScaleFromChipmonk[p.y]-deltaOrigin.y]]};
RefCoordPt: PROCEDURE[r: CoordRect] RETURNS[ppdefs.Point];
ShowFeature: PROCEDURE[f: FeaturePtr];
-- shows it on the screen from debugger
END. -- of ChipNetDefs