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: 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: 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 [ 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: PUBLIC TYPE ~ RECORD [ name: ATOM, index: SpinifexConstraintIndex, -- a small integer. 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); 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. ]; GeometricRule: TYPE ~ RECORD [ extent: INTEGER, message: Rope.ROPE _ NIL, okIfConnected: BOOLEAN _ FALSE, trigger1, trigger2: PACKED ARRAY SpinifexConstraintIndex OF BOOLEAN _ ALL[FALSE] ]; END. ώSpinifexCircuit.mesa Copyright c 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 -- 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. -- AddRect adds a Rectangle from a normal chipndale mask level, to each of the analysis layers which the techHandle dictates. May raise ERROR IllegalLevel. -- A space saving Hack. Allows interest bloats of no more than 255/Lambda. Also requires strict containment of Rectangle's dimension in its InterestBoundary. -- CircuitConstraint may contain circular REF chains, however they are a small in number fixed at compile time by the tech. dependent client software. -- withNodeResolution: leave node in conflict region if NIL else replace by REFed CircuitConstraint. -- 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. -- 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. Κ ά˜code™Kšœ Οmœ1™šœ žœžœ˜Kšœžœž˜K˜—šœžœžœ˜Kšœ"˜"Kšœ žœ£˜(KšœžœžœžœM˜aJ˜—Lšœ„™„šœžœžœ˜Kšœžœ˜Kšœžœžœ˜Kšœžœžœ˜Kš œžœžœžœžœžœžœ˜PK˜—Kšžœ˜J˜—…—r-L