<> <> <> <<>> <> <> <> DIRECTORY Atom USING [PropList], CD USING [Layer, ApplicationPtr, ApplicationList, Rect, DesignPosition, Orientation, ObPtr], CDOrient USING [original], RefTab USING [Ref], Rope USING [ROPE], SXQuadTree USING [QuadTreeRoot, RectDelta]; SX: CEDAR DEFINITIONS = BEGIN TranslateGeometry: PROCEDURE [cell: REF LogicalCell]; <<--Translates ChipNDale layers into Spinifex layers (e.g. only explicit contacts [which must be correct and hence are not checked] are allowed. Also a node number is assigned, which is used to identify the nodes. The translation is performed using the drawRect mechanism of ChipNDale. The ChipNDale design is translated into a quad-tree. It is not possible to use a tesselation because of overlaps. The quad-tree contains only cells already analysed. There are four types of rectangles: 1. constraints; 2. material; 3. extra constraint rectangles for transistors; 4. interlayer checks. Everithing that is not a rectangle is considered to be a child.>> <<-- 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.>> <<-- Escape mechanism, i.e. used to get around AddRect.>> 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: SXQuadTree.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 IllegalLayer.>> AddRect: PROCEDURE [ cir: REF Circuit, lev: CD.Layer, 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]; IllegalLayer: ERROR [rect: CD.Rect, lev: CD.Layer]; CreateLinkage: PROCEDURE [ cir: REF Circuit, source: CD.ApplicationPtr] RETURNS [REF NodeLinkage]; LinkageAttach: PROCEDURE [link: REF NodeLinkage, attachType: ATOM, node: REF CircuitNode _ NIL]; NormalizeCircuit: PROCEDURE [cir: REF Circuit]; LookupNode: PROCEDURE [l: REF CircuitNode] RETURNS [REF CircuitNode]; FindRootNode: PROCEDURE [ -- look at HighlightNode for usage 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]; <<--node "from" will be superceded to by "to" >> <<-- Combines areas, perimeters, and properties >> AdjustmentMode: TYPE = {relative, absolute}; AdjustNode: PROCEDURE [node: REF CircuitNode, layer: SpinifexLayerIndex, area: INT, perim: INT, mode: AdjustmentMode _ relative]; AnalysisState: TYPE = {notYetDone, useCircuit, reservedForFuture}; LogicalCell: TYPE = RECORD [ circuit: REF Circuit _ NIL, cellObj: CD.ObPtr, --bad circular ref, REMOVE analysisState: AnalysisState _ notYetDone, rootOnInvocation: REF _ NIL, --must do special check for root cells lastInvocation: REF _ NIL, errorCount: INT _ 0, errorContext: Rope.ROPE _ NIL, -- Place where errors have been put if not in this cell. privateForSX: REF _ NIL --for future use ]; <<--A node is a conductive region. When nodes are merged as a result of an overlap or abutment of similar rectangles, the estimated capacitance to ground must be adjsted due to the change in perimeter and area of these regions when combined.>> 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, -- copies; have instance names mergeDirectory: RefTab.Ref _ NIL, -- establishes a correspondence between a node in this cell and a node in a cell at the end of a chain of cell instantations. Key: Circuit node (of a subcircuit); val: MergeRecList. properties: Atom.PropList _ NIL, invocationKey: INT, --remove !! spinifexLayers: ARRAY SpinifexLayerIndex OF SXQuadTree.QuadTreeRoot -- build up on 1st step: translate ]; CircuitNode: TYPE = RECORD [ superceded: REF CircuitNode _ NIL, -- NIL if analysis finished dim: LIST OF AreaPerimRec _ NIL, loc: NodeLocation, properties: Atom.PropList _ NIL -- Cedar ]; NodeLocation: TYPE = RECORD [ xy: CD.DesignPosition, layer: SpinifexLayerIndex ]; AreaPerimRec: TYPE = RECORD [ layer: SpinifexLayerIndex, area, perim: INT ]; SignalName: TYPE = RECORD [ depth: INTEGER _ 0, name: Rope.ROPE, alias: REF SignalName _ NIL, makePort: BOOL _ FALSE -- in a root cell it will be considered to be a port ]; <<-- Constraint may contain circular REF chains, however they are a small in number fixed at compile time by the tech. dependent client software.>> maxConstraints: INTEGER = 16; ConstraintIndex: TYPE = [0..maxConstraints) _ ConstraintIndex.FIRST; spaceIndex: ConstraintIndex = 0; -- space regions. nodeIndex: ConstraintIndex = 1; -- node regions. excludeIndex: ConstraintIndex = 2; -- region excluded by Opaque cell. violateIndex: ConstraintIndex = 3; -- Opaque cell exclusion region violated techCIndexBase: ConstraintIndex = 4; -- Technology dependent clients should start number their constraints in each layer from here. Constraint: PUBLIC TYPE = RECORD [ -- belongs to the technology name: ATOM, index: ConstraintIndex, -- index into the constrain array hasCorrespondingNode: BOOLEAN _ FALSE, -- used where connectivity affects the rule and there is a corresponding layer which has the node associated with this region. correspondingNodeLayer: SpinifexLayerIndex _ SpinifexLayerIndex.FIRST -- way to attach node values to constraints by looking at other layers. ]; ConstraintPtr: TYPE = REF Constraint; ConstraintArray: TYPE = ARRAY ConstraintIndex OF ConstraintPtr _ ALL[NIL]; <<-- This table looked up when constraints overlap other constraints or nodes.>> <<-- The first Row (and Column) of the ARRAY (corresponding to spaceIndex) actually hold in each Column (Respectively Row) position, the Contraint having that index.>> <<-- NIL entries in the table are defined to mean this pair should map to node and should only arise in the Column (Respectively Row) corresponding to nodeIndex.>> ConstraintResolution: TYPE = ARRAY ConstraintIndex OF ConstraintArray; NodeLinkage: TYPE = RECORD [ -- transistors source: CD.ApplicationPtr, nodes: LIST OF REF AttachedNode _ NIL ]; AttachedNode: TYPE = RECORD [ attachmentType: ATOM, -- e.g. $Gate, $Drain, $Source node: REF CircuitNode ]; MergeRecList: TYPE = LIST OF MergeRec; MergeRec: TYPE = RECORD [ applChain: LIST OF CD.ApplicationPtr, -- bottom up, one application per subcircuit becomes: REF CircuitNode -- in the parent circuit ]; 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); <<>> <<-- Constraints contain unique (for each SpinifexLayer) small integers (ConstraintIndex) which are then used to access the trigger tables in GeometricRules, the integers are relevant only within a given SpinifexLayer. Space regions map to spaceIndex and node regions map to nodeIndex. The trigger tables must be hand generated by the tech dependent client and are therefore error prone.>> TechHandle: TYPE = RECORD [ numSpinifexLayers: SpinifexLayerIndex, -- Technology dependent (NMOS: 3, CMOS: 6). spinifexLayerNames: ARRAY SpinifexLayerIndex OF LayerNames, -- For Thyme layerInterestBloat: ARRAY SpinifexLayerIndex OF INTEGER _ ALL[0], -- (design number). Because bloat depends on material. These fields hold the maximum. rules: ARRAY SpinifexLayerIndex OF LIST OF REF GeometricRule _ ALL[NIL], constraintResolutions: ARRAY SpinifexLayerIndex OF REF ConstraintResolution _ ALL [NIL], cdLayerMapping: ARRAY CD.Layer OF LIST OF MapRec _ ALL[NIL], -- Map from ChipNDale rectangles to quad-tree rectangles. A ChipNDale rectangle may map (in TranslateGeometry) to several spinifex layers, as a conductive region on one, and as contraints on other conductive regions on other spinifex layers. illegalLayer: ARRAY CD.Layer OF BOOLEAN _ ALL[TRUE], -- To detect isolated curts that should only be used inside objects. combineNodeProperties: CombineNodePropertyProc _ NIL, -- For technology dependent properties. For merging phase. 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]; <<-- to: top level; from: deeper level>> CellPostProcessProc: TYPE = PROCEDURE [cell: REF LogicalCell]; LayerNames: TYPE = RECORD [ layerId: ATOM _ NIL, thymeName: Rope.ROPE _ NIL ]; MapRec: TYPE = RECORD [ spinifexLayer: SpinifexLayerIndex, bloatFactor: INTEGER, -- Interest Bloat. short design number value: REF ANY _ NIL -- There are 3 possiblities. < A new the region represents conductive material on this layer and a new node is created.>> < region represents a constraint on other material in this layer.>> < A procedural escape for more complex rectangle mapping. (e.g. for mapping n-well)>> ]; <<-- 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 ConstraintIndex OF BOOLEAN _ ALL[FALSE] ]; END. <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<>>