-- 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