Theory and Trade-offs
This interface defines the ways to attach geometry to Core data structure. All geometry is expressed in the CD coordinate system of its root object.
Two kinds of decorations are defined in this interface:
Interface decorations: The geometric interface of a decorated CellType consists in its interestRect, and its pins (attached on each public wire).
RecordCell decorations: Record cells (and only record cell so far) record the geometry of the internal wires (but only the geometry found at that level), and the geometrical transformation for each CellInstance.
Previous experience has shown that, if pins are stored in the trivial way [Instances], most of the memory goes into those pins, and that seriously limits the size of designs the DA system can handle. Therefore, it is important to be able to store pins in a lazy way: every time the time penalty is not too important, recompute pins instead of storing them. Enumerations are prefered to explicit lists for both storage efficiency [enumerations create less objects] and time efficiency [enumerations may return early].
Common cases when pins can be recomputed:
Indirection: pins of a given wire are the same as the ones of some other wire. This is heavily used in PWCore that generates lots of indirections. The time penalty in that case is a constant time.
Indirection and transformation: pins of a given wire are the same as the ones of some other wire, once applied a geometrical transformation. This case is very frequent for abuts (think of the vertical wires of lines). The time penalty is a constant time.
RecordCell: pins of a public of a RecordCell can always be obtained by enumerating the instances to which the public is bound, assuming that some geometric transformations and some clipping are done. This is of course a very common case, but the time penalty might be quite high (looping both on instances and bindings).
Common cases where it is better to store explicitly pins:
Small number of instances.
Ratio number of instances considered over final number of instances high. When the RecordCell lazyness is used, this is a very important heuristic to avoid recomputing constantly Gnd and Vdd pins.
The implementation of this interface tries to make the best space/time trade-offs using those heuristics.
Conveniences
CellType : TYPE = Core.CellType;
Properties : TYPE = Core.Properties;
ROPE: TYPE = Core.ROPE;
Wire: TYPE = Core.Wire;
CellInstance: TYPE = CoreClasses.CellInstance;
FlatWire: TYPE = CoreFlat.FlatWire;
FlatWireRec: TYPE = CoreFlat.FlatWireRec;
FlatCellType: TYPE = CoreFlat.FlatCellType;
FlatCellTypeRec: TYPE = CoreFlat.FlatCellTypeRec;
Bindings: TYPE = CoreFlat.Bindings;
InstancePath: TYPE = CoreFlat.InstancePath;
Rect: TYPE = CD.Rect;
Instance: TYPE = CD.Instance;
Instances:
TYPE =
LIST
OF Instance;
universe: Rect = CDBasics.universe;
Decoration and Enumeration
Decoration:
TYPE =
REF DecorationRec;
Decoration holds names of properties.
Should only be created by CreateDecoration
Definition of DecorationRec is only given for implementors' information.
DecorationRec:
TYPE =
PRIVATE
RECORD [
name: ROPE, -- Documentation purpose only
irProp: ATOM, -- Hangs on the Cell Type, to specify the InterestRect of the corresponding object
pinsProp: ATOM, -- Hangs on each public wire to specify the pins of the public. Pins should be understood as the more general meaning of "interface geometry", and are not only pins but also rectangles. Access to this property should be made via the procedural interface.
geometryProp: ATOM, -- Hangs on every internal wires of record cellTypes to specify the geometry of the internal (but only at this level in the record).
transfProp: ATOM -- hangs on every CoreClasses.CellInstance of record cellTypes to specify the corresponding Instance.
];
CreateDecoration:
PROC [name:
ROPE]
RETURNS [decoration: Decoration];
Initializes of the fields of decoration properly.
All decorations must have different names (because properties atoms are computed using name).
Currently, the only clients are the one registering an extraction mode. A handle on an existing decoration can be found in an extraction mode.
EachInstanceProc:
TYPE =
PROC [instance: Instance]
RETURNS [quit:
BOOL ←
FALSE];
Basic type for call-back procs.
InterestRect
HasIR:
PROC [decoration: Decoration, cellType: CellType]
RETURNS [
BOOL];
Tests for cellType decorated with an InterestRect.
GetIR:
PROC [decoration: Decoration, cellType: CellType]
RETURNS [ir: Rect];
Provokes an error if cellType is not decorated with an InterestRect.
PutIR: PROC [decoration: Decoration, cellType: CellType, ir: Rect];
Pins
EnumeratePins:
PROC [decoration: Decoration, public: Wire, eachInstance: EachInstanceProc]
RETURNS [quit:
BOOL];
Enumerates all the pins of public.
Instances can be enumerated more than once.
May change the internal representation of pins to increase space/time efficiency.
HasPins:
PROC [decoration: Decoration, public: Wire]
RETURNS [
BOOL];
Tests for public decorated with at least a pin.
GetPins:
PROC [decoration: Decoration, public: Wire]
RETURNS [pins: Instances];
For clients who really want to create all those instances.
Instances can be enumerated more than once.
May change the internal representation of pins to increase space/time efficiency.
PutPin:
PROC [decoration: Decoration, public: Wire, pin: Instance];
Used for explicitly setting pins of a public, when there is only one pin. See further for lazyness.
PutPins:
PROC [decoration: Decoration, public: Wire, pins: Instances];
Used for explicitly setting pins of a public. See further for lazyness.
Geometry
EachFlatWireProc:
TYPE =
PROC [wire: Wire, flatWire: FlatWireRec, geometry: Instances];
geometry is all the instances of wire (at recordCell level only), expressed in the coordinate system of root, which have a non-empty intersection with clipRect.
flatWire is the canonized FlatWireRec at the highest level that defines wire.
EachFlatCellProc:
TYPE =
PROC [bindings: Bindings, cell: CellType, flatCell: FlatCellTypeRec, transf: Instance];
bindings is a HashTable [public of cellType -> CoreFlat.FlatWire]. When cell=root, bindings=NIL
transf is the current transf, expressed in the coordinate system of root, for flatCell.
LeafProc:
TYPE =
PROC [cellType: CellType]
RETURNS [
BOOL];
TRUE stops enumeration and this cellType is not explored recursively.
EnumerateFlatGeometry:
PROC [decoration: Decoration, root: CellType, leafProc: LeafProc, eachFlatWire: EachFlatWireProc ←
NIL, eachFlatCell: EachFlatCellProc ←
NIL, clipRect: Rect ← universe];
Enumerates all internals and all instances which have a non-empty intersection with clipRect. Clipping is done at every level.
Call-back proc recurseProc is called to direct recursion.
Call-back proc eachFlatWire gives as argument the geometry (transformed to be in root coordinate system) which has a non-empty intersection with clipRect.
Call-back proc eachFlatCell gives as argument the current transf (transformed to be in root coordinate system). Only called on atomic cellTypes (recurseProc returns FALSE) which have a non-empty intersection with clipRect.
Recurses only on recordCells.
Instances can be enumerated more than once.
GetGeometry:
PROC [decoration: Decoration, internal: Wire]
RETURNS [geometry: Instances];
For recordCell decorations only.
PutGeometry:
PROC [decoration: Decoration, internal: Wire, geometry: Instances];
For recordCell decorations only.
Enumeration of Sides for Routers
These functions are not primitive, and are implemented using primitives of this interface. They are applicable for all Core data structures decorated with layout (not for structures not yet decorated), and should simplify the task of interfacing routers.
Pin should be understand, for the following functions, in the sense of segment of interface geometry. Min and Max refer to the interesting projection in X or Y (depending on the side of the pin), relatively to the InterestRect of the object. Note that the coordinate system is different from the other functions in this interface.
The only classes of decorations understood by these functions are rectangles, symbolic objects, atomic objects, and objects for which FlattenAtomic is meaningful. Layers without a $RoutingLayer property are discarded.
Side: TYPE = {bottom, right, top, left};
Sides: TYPE = PACKED ARRAY Side OF BOOL ← noSide;
noSide: Sides =
ALL [
FALSE];
GetSides:
PROC [ir: Rect, pin: Instance]
RETURNS [sides: Sides ← noSide];
EachPinProc: TYPE = PROC [min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL ← FALSE];
EnumerateSides:
PROC [decoration: Decoration, cellType: CellType, wire: Wire, eachPin: EachPinProc]
RETURNS [quit:
BOOL];
Enumerates all the pins for wire.
EachWirePinProc: TYPE = PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOL ← FALSE];
EnumerateWireSides:
PROC [decoration: Decoration, cellType: CellType, eachWirePin: EachWirePinProc]
RETURNS [quit:
BOOL];
Enumerates all the pins of the public wires of cellType.
May enumerate several times the overlapping segments.
EnumerateNonOverlappingSides:
PROC [decoration: Decoration, cellType: CellType, eachWirePin: EachWirePinProc]
RETURNS [quit:
BOOL];
Enumerates all the pins of the public wires of cellType, but enumerates once only segments that overlap.
EachSortedPinProc: TYPE = PROC [wire: Wire, min, max: INT, layer: CD.Layer] RETURNS [quit: BOOL ← FALSE];
EnumerateSortedSides:
PROC [decoration: Decoration, cellType: CellType, side: Side, eachSortedPin: EachSortedPinProc]
RETURNS [quit:
BOOL];
Enumerates all the pins of all the wires for cellType. Segments are enumerated in increasing min order.
Fabrication of Shells for Routers or for IO
This function is also not primitive, but can be used by several different programs.
CreateShell:
PROC [decoration: Decoration, cellType: CellType, withCuteFonts:
BOOL ←
FALSE]
RETURNS [shell:
CD.Object];
Creates a CD cell that contains instances which correspond to the pins of the publics of cellType. Each CD instance has an $InstanceName property which is the (public) full name of the wire.
Parameter withCuteFonts provokes, when TRUE, creation of text in front of each instance.
The InterestRect decoration is not stored on the shell, but the shell has an InterestRect of the same size as the cellType interestRect.
Lazy Setting of Pins
LazyPinsEnumerateProc:
TYPE =
PROC [decoration: Decoration, public: Wire, eachInstance: EachInstanceProc]
RETURNS [quit:
BOOL];
PutLazyPins:
PROC [decoration: Decoration, public: Wire, lazyPinsEnumerate: LazyPinsEnumerateProc];
Parameter lazyPinsEnumerate is the function that is called when enumeration of pins of public is called. Typically this function will use some properties stored on the public itself to do the enumeration.
PutIndirectLazyPins:
PROC [decoration: Decoration, public: Wire, indirect: Wire];
Special speed-up of PutLazyPins for pins that are obtained by enumerating the pins of another Wire.
Enumeration assumes that indirect is properly decorated.
PutIndirectsLazyPins:
PROC [decoration: Decoration, public: Wire, indirects:
LIST
OF Wire];
Special speed-up of PutLazyPins for pins that are obtained by enumerating the pins of some other Wires.
Enumeration assumes that indirects are properly decorated.
AddIndirectLazyPins:
PROC [decoration: Decoration, public: Wire, indirect: Wire];
Special speed-up of PutLazyPins for pins that are "also" obtained by enumerating the pins of some other Wire. If public was already decorated by PutIndirectLazyPins or PutIndirectsLazyPins, this indirect is added (if not already present) other, pins are explicitly stored.
Enumeration assumes that indirect is properly decorated.
PutTransfWireIRLazyPins:
PROC [decoration: Decoration, public: Wire, indirect: Wire, transf: Instance, ir: Rect];
Special speed-up of PutLazyPins for pins that are obtained by enumerating the pins of another Wire, once transformed by transf, and clipped to be at the edge of ir.
Enumeration assumes that indirect is properly decorated.
PutRecordLazyPins:
PROC [decoration: Decoration, public: Wire, recordCell: CellType];
Special speed-up of PutLazyPins for pins that are obtained by following the bindings of a recordCell.
Enumeration assumes that recordCell is properly decorated.
Geometry Utilities
Some of these function should obviously be in CD.
AtEdge:
PROC [ir: Rect, instance: Instance]
RETURNS [
BOOL];
Returns TRUE iff instance touches or extends beyond ir.
TransfedNotAtEdge:
PROC [transf: Instance, ir: Rect, instance: Instance]
RETURNS [
BOOL];
Returns FALSE (opposite of previous AtEdge) iff instance, onced applied transf, touches or extends beyond ir.
Semantically identical to, but more efficient than, NOT AtEdge[ir, Transform[transf, instance]].
Intersect:
PROC [clipRect: Rect, instance: Instance]
RETURNS [
BOOL];
Returns TRUE iff instance is partly inside (or touches) clipRect.
Transform:
PROC [transf, instance: Instance]
RETURNS [Instance];
Transforms instance using transf.
TransformList:
PROC [transf: Instance, instances: Instances]
RETURNS [Instances];
Transforms instances using transf. New list is created.
Order not preserved.
FlattenAtomic:
PROC [obj:
CD.Object]
RETURNS [rList: CDAtomicObjects.DrawList ←
NIL];
Convenience to treat some CD primitive objects as Atomic Objects. Result is cached (no dynamic creation of rList when called more than once).
Applicable to CD Atomic Objects and more (such as large contacts).
FlattenAtomic[symbolic object] -> NIL
FlattenAtomic[rectangle] -> InterestRect of itself
The following functions are only meaningful for Layout. They are technology-independent. They only understand Rectangles, Symbolic Objects and objects for which FlattenAtomic is meaningful. Layers with a $Well property are discarded.
TouchProc:
TYPE =
PROC [instance1, instance2: Instance]
RETURNS [
BOOL ←
FALSE];
Returns TRUE if instance1 touches instance2.
TouchRect:
PROC [instance: Instance, rect: Rect, layer:
CD.Layer]
RETURNS [
BOOL ←
FALSE];
Returns TRUE if instance touches rect.
TouchList:
PROC [instances: Instances, instance: Instance]
RETURNS [
BOOL ←
FALSE];
Returns TRUE if some instance of instances touches instance.
TouchListList:
PROC [instances1, instances2: Instances]
RETURNS [
BOOL ←
FALSE];
Returns TRUE if some instance of instances1 touches some instance of instances2.