CoreRoute.mesa
Copyright Ó 1985, 1987, 1988 by Xerox Corporation. All rights reserved.
Bertrand Serlet, August 16, 1988 10:10:58 am PDT
Louis Monier February 16, 1987 0:44:24 am PST
Don Curry February 24, 1988 9:25:08 am PST
DIRECTORY
CD,
Core, CoreClasses, CoreFlat, CoreGeometry, DABasics,
RefTab, Rope, Route, SymTab;
CoreRoute provides the types and functions to interface routers into PWCore world.
CoreRoute: CEDAR DEFINITIONS =
BEGIN
Side:     TYPE = CoreGeometry.Side;
CellType:    TYPE = Core.CellType;
Wire:     TYPE = Core.Wire;
Purpose
CoreRoute provides the types and functions to interface routers into PWCore world.
Labelling
LabelInternal: PROC [internal: Core.WireSeq, wire: Wire] RETURNS [Route.Label];
Generates a unique label (based on the full name from internal) for wire, but never conflicting with the extractor's names.
LabelFlatWire: PROC [root: CellType, flatWire: CoreFlat.FlatWireRec] RETURNS [Route.Label];
Generates a unique label (based on the full flat name) for flatWire, but never conflicting with the extractor's names.
LabelBrokenNet: PROC [label: Route.Label, number: NAT] RETURNS [Route.Label];
Generates a unique label (based on label) indexed by number, but never conflicting with the extractor's names.
Schematics Analysis
Utilities in this section allow various layout generators to "parse" the schematics in a consistent manner.
WirePin: TYPE = RECORD [wire: Wire, min, max: INT, layer: CD.Layer];
WirePins: TYPE = LIST OF WirePin;
FilteredCellTypeLayoutPins: PROC [cellType: CellType, side: Side] RETURNS [pins: WirePins];
This proc returns the sorted layout WirePins of all marked or global wires for a given side.
A wire is considered to have been marked on a particular side if either it or some parent has schematic geometry on that side.
A wire is considered to be global if it is a top level atomic public and has no schematic pins.
Recommendation: call FlushSchPinCache and FlushLayPinCache when you are through.
FilteredInstanceLayoutPins: PROC [inst: CoreClasses.CellInstance, side: Side]
RETURNS [pins: WirePins];
Same as FilteredCellTypeLayoutPins except the returned wires are from the actual rather than the public.
Recommendation: call FlushSchPinCache and FlushLayPinCache on inst.type when you are through.
OrderedAtomicSchWires: PROC [cellType: CellType, side: Side, min: INTFIRST[INT], max: INTLAST[INT]] RETURNS [wires: Core.Wires];
This proc returns an ordered list of the atomic wires for a given side based on the min of one of its (or it's parents) schematic pins. Wires may appear more than once in the list. The children of structured wires are included in index order. Children inherit pins from their parents iff they have none themselves.
Recommendation: Call FlushSchPinCache when you are through.
FlushLayPinCache: PROC [cellType: CellType];
FlushSchPinCache: PROC [cellType: CellType];
Decorate Procs
The hard part with PatchWork is not only to write LayoutProcs, but to write DecorateProcs. DecorateRoutedArea should help. This function is applicable when:
- The cellType is a record cell for which all flat CT have layout.
- The layout is only made of routing cells or of layout obtained through PWCore.Layout, or any structuration (cells, abuts, etc...) of those.
- All sublayout obtained through PWCore.Layout can be sorted, all flat CT having layout can be sorted, and there is a one to one correspondance between those lists.
- All nodes of all routing cells have a $SignalName property that labels that node.
- A function mapping internal wires to labels is passed as argument.
CompareFlatCTProc: TYPE = PROC [root: CellType, flatCT1, flatCT2: CoreFlat.FlatCellTypeRec] RETURNS [BOOL];
Defines an ordering between flatCT1 and flatCT2.
Returns TRUE if flatCT1 is before flatCT2.
CompareRecordCellInstances: CompareFlatCTProc;
Assumes that the root is a record cell and returns as for increasing instance index.
CompareIRProc: TYPE = PROC [CD.Rect, CD.Rect] RETURNS [BOOL];
Defines an ordering between interest rectangles.
Returns TRUE if rect1 is before rect2.
CompareInX:     CompareIRProc;
CompareInY:     CompareIRProc;
CompareReverseInX:   CompareIRProc;
CompareReverseInY:   CompareIRProc;
CompareOrigin:    CompareIRProc; -- If y1=y2 THEN x1<x2 ELSE y1<y2
CompareXorYStack:   CompareIRProc; -- If overlapY THEN x1<x2 ELSE y1<y2
EachComponentProc: TYPE = PROC [component: CD.Object, trans: CoreGeometry.Transformation] RETURNS [quit: BOOLFALSE];
Components are either cells which have layout (obtained through PWCore) or routing cells.
EnumerateRoutedArea: PROC [obj: CD.Object, eachRoutingCell, eachPatchWorkCell: EachComponentProc ← NIL, trans: CoreGeometry.Transformation ← []] RETURNS [quit: BOOL];
DecorateRoutedArea: PROC [cellType: CellType, obj: CD.Object, wireToLabels: PROC [Wire] RETURNS [LIST OF Route.Label], compareIR: CompareIRProc ← CompareOrigin, compareCT: CompareFlatCTProc ← CompareRecordCellInstances];
Call back transformations are expressed in the coordonnate system of obj.
MakeRoutingCell: PROC [cell: CD.Object, publicToLabel: PROC [Rope.ROPE] RETURNS [Route.Label]] RETURNS [routingCell: CD.Object];
Convenience for transforming cells like feedthroughs into routing cells.
The extraction of cell should not contain any non-public wire.
The rope passed as argument to publicToLabel is the name of the public.
Attention: well rectangles (e.g. associated to p-diffusion rectangles) are enumerated as a conductor. In order to have that conductor named, the source cell should be modified (e.g. by adding a well rectangle with a satellite).
Extension
One LayoutAtom is registered: $Extend. $Extend expects a RecordCell with one instance. The properties $Bottom, $Right, $Top, $Left, specify the amount of extension, in l. If a property is absent, 0 is assumed.
Segments: TYPE = LIST OF Segment;
Segment: TYPE = RECORD [label: Route.Label, min, max: INT, layer: CD.Layer];
min and max are relative to the InterestRect.
ExtendSegmentProc: TYPE = PROC [label: Route.Label, size: INT, layer: CD.Layer, side: Side, extension: INT] RETURNS [CD.Object ← NIL];
This function extends a segment by the amount extension.
If the returned object is NIL, it means no extension for this wirePin.
ExtendSegment: ExtendSegmentProc;
Returns a rectangle of layer layer, of length extension, and of width max-min.
If side=top or side=bottom, this rectangle is vertical, otherwise horizontal.
ExtendObject: PROC [enumerateSegments: PROC [PROC [Segment]], size: CD.Position, side: Side, extendProc: ExtendSegmentProc ← ExtendSegment] RETURNS [extension: CD.Object];
Prepares an object to be abutted on the side side of an object. That side enumerates segments using enumerateSegments.
Size is the size of the generated cell.
For example if side=right, then extension=size.x, and [0 .. size.y] is the range in which all min and all max of segments should lie.
SetExtend: PROC [cellType: CellType, bottom, right, top, left: INT ← 0];
Channel
Two layout atoms are registered for specifying Channels:
$RawChannelRoute, that just assumes a record of type ChannelInfo under the $ChannelInfo property on the cellType;
$ChannelRoute, that calls an attribute proc that computes ChannelInfo from schematics decorations. Details of the parameter specification are in documentation.
For $ChannelRoute, several properties can be found on the schematic, in order to specify parameters of the channel:
$Trunk: ATOM or ROPE denoting a layer. Defaults to Metal.
$Branch: ATOM or ROPE denoting a layer. Defaults to Metal2.
$Justify: ATOM specifies $TopRight, $BottomLeft.
$DesignRules: ATOM specifies the design rules to use. Defaults to $cmosB.
$TotalWidth: REF INT specifies the total width of the channel, in lambdas. Defaults means minimum size channel.
And one property may be placed on the schematic wires:
$w: a REF INT, specifies a larger than default channel trunk wire width.
ChannelInfo: TYPE = REF ChannelInfoRec;
ChannelInfoRec: TYPE = RECORD [
direction: DABasics.Direction, -- Horizontal => that the channel will be abutted in Y.
tech: REF,      -- Technology for that channel.
trunk: REF,      -- From side to side, "poly", "metal" or "metal2".
branch: REF,     -- From cell to cell. "poly", "metal" or "metal2"
justify: BOOLTRUE,  -- Provokes automatic stretch
justifyBottomOrLeft: BOOLTRUE, -- For extension, defines side opposite to the extension.
bottomOrLeftWires: Core.Wires ← NIL, -- **
topOrRightWires: Core.Wires ← NIL,  -- **.
totalWidth: INT ← 0    -- lambda width of channel plus objects; 0 => min
];  
** Indicates the order in which those wires appear at the bottom and top. Might be structured, but then only atomic wires are taken into account. All atomic wires must be part of the internal of the cell.
Stack
Two layout atoms are registered for specifying a Stack:
$Stack derives layout information from schematic geometry with its attribute proc.
$RawStack assumes a record of type StackForm under the cellType property $StackForm.
For $Stack, several properties may be placed on the schematic:
$Trunk: ATOM OR ROPE denoting a layer. If ambiguous, defaults to Metal.
$Branch: ATOM OR ROPE denoting a layer. If ambiguous, defaults to Metal2.
$Justify: ATOM specifies $TopRight, $BottomLeft, $BestFit
$HorizontalStack, REF specifies when non-NIL a horizontal stack. This is used only in the degenerate case of a stack containing just one subcell. It essentially determines which ends of the subcell can have channel routes.
And one property may be placed on the schematic wires:
$w: a REF INT, specifies a larger than default channel trunk wire width.
StackForm:  TYPE = REF StackFormRec;
StackFormRec: TYPE = RECORD[
inX:    BOOL,
justification:  Justification ← bottomLeft,
trunkLayer:  CD.Layer  ← CD.commentLayer,
branchLayer: CD.Layer  ← CD.commentLayer,
min:    INT   ← LAST[INT],
max:    INT   ← FIRST[INT],
auxLabels:  SymTab.Ref    ← NIL,
sec:    LIST OF StackSection ← NIL ];
StackSection: TYPE = RECORD[ -- either chan=NIL OR abuts=NIL but not both
chan:  REF StackChanRec  ← NIL,
abuts:  LIST OF StackAbutRec ← NIL,
abutMin: INT      ← LAST[INT],
abutMax: INT      ← FIRST[INT]];
StackAbutRec:  TYPE = RECORD[
inst:    INT   ← -1,
off:    INT   ← 0,
laySize:   LaySize  ← [0,0],
minPins:   WirePins  ← NIL,
maxPins:   WirePins  ← NIL,
firstPins:   WirePins  ← NIL,
lastPins:   WirePins  ← NIL ];
StackChanRec:  TYPE = RECORD[
minPins:   WirePins  ← NIL,
maxPins:   WirePins  ← NIL,
firstPins:   WirePins  ← NIL,
lastPins:   WirePins  ← NIL ];
LaySize:  TYPE = RECORD[width, height: INT]; -- width: across stack, height: along stack
ChangeLayers
Two layout atoms are registered for specifying a layer change cell:
$ChangeLayers derives layout information from schematic geometry with its attribute proc.
$RawChangeLayers assumes a record of type ChangeLayersForm under the cellType property $ChangeLayersForm.
One property may be placed on the bussed schematic wires:
$w: a REF INT, specifies a larger than default bus width.
ChangeLayersForm:   TYPE = REF ChangeLayersFormAry;
ChangeLayersFormAry: TYPE = RECORD[
vert:  CD.Layer  ← CD.commentLayer,
ary:  ARRAY Side OF ChangeLayersFormRec ];
ChangeLayersFormRec: TYPE = RECORD[
pins:  WirePins  ← NIL,
min:  INT   ← LAST[INT],
max:  INT   ← FIRST[INT],
width: INT   ← 0,
busMin: INT   ← LAST[INT],
busMax: INT   ← FIRST[INT],
bus:  Wire  ← NIL,
busSize: INT   ← 0,
busLo: BOOL   ← FALSE,
busHi: BOOL   ← FALSE];
Low Level Utilities
These two procs return a sorted non overlapping list of WirePins. Elements are sorted by min value. Both procs cache the overall pin enumeration and sorts for all sides so that subsequent calls for other sides should be speedy.
LayPins:    PROC[cellType: CellType, side: Side] RETURNS[pins: WirePins];
SchPins:     PROC[cellType: CellType, side: Side] RETURNS[pins: WirePins];
ReverseWirePins:  PROC[pins: WirePins] RETURNS[rev: WirePins];
GlobalWires:   PROC[cellType: CellType]    RETURNS[wires: Core.Wires];
WirePinWires:   PROC[pins: WirePins]     RETURNS[wires: Core.Wires];
FilterPins:    PROC[pins: WirePins, wires0, wires1: Core.Wires]
RETURNS[sel: WirePins ← NIL];
Returns list of elements of pins which have wires that are memebers of either either wires0 or wires1.
FindBestOffset:  PROC[pins1, pins2: WirePins] RETURNS[offSet: INT]; -- for min routing
SchMappedIR:    PROC[inst: CoreClasses.CellInstance] RETURNS[ir: CD.Rect];
GetCellTypePropLayer: PROC[cellType: CellType, key: ATOM, default: REF ← NIL]
RETURNS[layer, other: CD.Layer←CD.commentLayer];
GetRoutingLayer:   PROC[pins: WirePins] RETURNS[layer: CD.Layer];
GetJustification:   PROC[cellType: CellType] RETURNS[justification: Justification];
Justification:   TYPE = {bottomLeft, topRight, bestFit};
InstanceArray:  TYPE = REF InstanceArraySeq;
InstanceArraySeq: TYPE = RECORD[SEQUENCE size: CARDINAL OF InstanceRow];
InstanceRow:   TYPE = REF InstanceRowSeq;
InstanceRowSeq:  TYPE = RECORD[SEQUENCE size: CARDINAL OF CoreClasses.CellInstance];
ShowInstanceArray:  PROC[ia: InstanceArray];
SortedInstanceArray: PROC[cellType: CellType] RETURNS[ia: InstanceArray];
Sort2DInstances:   PROC[cellType: CellType]; -- priority: overlapY then Left else Bot
MakeChannel:    PROC[
parent:   CellType,
chanIndex:  INT,   -- Insures unique names in auxLabelTab for multi chans.
auxLabelTab:  SymTab.Ref, -- LIST OF Route.Label for broken nets.
trunkLength: INT,    -- firstPins/lastPins min/max must be IN [0..trunkLength]
branchLength: INT,    -- minPins/maxPins min/max ignored (for now)
trunkDirection: DABasics.Direction,
horizLayer:  CD.Layer,
vertLayer:  CD.Layer,
minPins:   WirePins ← NIL, -- IF trunkDirection=vertical THEN bottom
maxPins:   WirePins ← NIL, -- IF trunkDirection=vertical THEN top
firstPins:   WirePins ← NIL, -- IF trunkDirection=vertical THEN left
lastPins:   WirePins ← NIL ] -- IF trunkDirection=vertical THEN right
RETURNS[channel: CD.Object];
END.