BicPadFrameImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Bertrand Serlet September 10, 1987 11:17:02 pm PDT
Louis Monier November 2, 1987 10:46:10 pm PST
DIRECTORY
Cabbage,
CD, CDBasics, CDSimpleRules,
Connections,
Core, CoreClasses, CoreCreate, CoreOps, CoreProperties,
CoreGeometry, CoreRoute, PWCore, Rope, RTBasic, Sisyph;
BicPadFrameImpl: CEDAR PROGRAM
IMPORTS Cabbage, CD, CDBasics, CDSimpleRules, Connections, CoreOps, CoreProperties, CoreGeometry, CoreRoute, PWCore, Rope, Sisyph = BEGIN
Common types
ROPE: TYPE = Core.ROPE;
Wire: TYPE = Core.Wire;
WireSeq: TYPE = Core.WireSeq;
CellType: TYPE = Core.CellType;
CellInstance: TYPE = CoreCreate.CellInstance;
Utilities
GetCTPropBool: PROC [ct: CellType, prop: ATOM, default: BOOL] RETURNS [val: BOOL] ~ {
ref: REF ← CoreProperties.GetCellTypeProp[ct, prop];
val ← IF ref=NIL THEN default ELSE NARROW[ref, REF BOOL]^;
};
GetCTPropInt: PROC [ct: CellType, prop: ATOM, default: INT] RETURNS [val: INT] ~ {
ref: REF ← CoreProperties.GetCellTypeProp[ct, prop];
val ← IF ref=NIL THEN default ELSE NARROW[ref, REF INT]^;
};
GetCTPropRope: PROC [ct: CellType, prop: ATOM, default: ROPE] RETURNS [val: ROPE] ~ {
ref: REF ← CoreProperties.GetCellTypeProp[ct, prop];
val ← IF ref=NIL THEN default ELSE NARROW[ref, ROPE];
};
SideToSide: PROC [side: CoreGeometry.Side] RETURNS [RTBasic.Side] = {
RETURN [SELECT side FROM
top => top, bottom => bottom, left => left, right => right, ENDCASE => ERROR
];
};
AddConnection: PROC [nets: Connections.Table, internal: WireSeq, actual: Wire, object: CD.Object, min, max: INT, side: CoreGeometry.Side, layer: CD.Layer] = {
name: ROPE ← CoreRoute.LabelInternal[internal, actual];
net: Connections.Net ← Connections.Fetch[nets, name].net;
widthVal: REF ANY ← CoreProperties.GetWireProp[actual, wireWidthProp];
width: INTIF widthVal = NIL THEN 0 ELSE NARROW[widthVal, REF INT]^;
IF net=NIL THEN {
net ← NEW [Connections.NetRec ← [name: name, width: width]]; [] ← Connections.Store[nets, name, net];
};
net.segments ← CONS [
NEW [Connections.SegmentRec ← [object: object, range: [min, max], side: SideToSide[side], layer: layer]],
net.segments];
};
Layout Proc
BBox: PROC [inst: CellInstance] RETURNS [CD.Rect] ~ {
RETURN[CDBasics.MapRect[CD.InterestRect[CoreGeometry.GetObject[Sisyph.mode.decoration, inst.type]], CoreGeometry.GetTrans[Sisyph.mode.decoration, inst]]]
};
AttributePadFrame: PWCore.AttributesProc = {
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
minX, minY: INT ← LAST[INT];
maxX, maxY: INT ← FIRST[INT];
left, right, top, bottom: CellInstance ← NIL;
IF data.size#5 THEN ERROR;  -- 4 sides and inner
FOR i: NAT IN [0..data.size) DO
IF BBox[data[i]].x1<minX THEN {left ← data[i]; minX ← BBox[data[i]].x1};
IF BBox[data[i]].x2>maxX THEN {right ← data[i]; maxX ← BBox[data[i]].x2};
IF BBox[data[i]].y1<minY THEN {bottom ← data[i]; minY ← BBox[data[i]].y1};
IF BBox[data[i]].y2>maxY THEN {top ← data[i]; maxY ← BBox[data[i]].y2};
ENDLOOP;
CoreProperties.PutCellInstanceProp[left, $PadFrameSide, $Left];
CoreProperties.PutCellInstanceProp[bottom, $PadFrameSide, $Bottom];
CoreProperties.PutCellInstanceProp[right, $PadFrameSide, $Right];
CoreProperties.PutCellInstanceProp[top, $PadFrameSide, $Top];
};
technologyKey: ATOM = $cmosB;
wireWidthProp: ATOM = $w;
lambda: INT ← CDSimpleRules.GetTechnology[technologyKey].lambda;
LayoutPadFrame: PWCore.LayoutProc = {
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
leftInst, rightInst, topInst, bottomInst, innerInst: CellInstance ← NIL;
leftOb, rightOb, topOb, bottomOb, innerOb: CD.Object ← NIL;
prop: REF ← CoreProperties.GetCellTypeProp[cellType, $VerticalMetal];
innerDX: INT ← GetCTPropInt[cellType, $innerDX, 0];
innerDY: INT ← GetCTPropInt[cellType, $innerDY, 0];
vertLayer: ROPEIF prop=NIL THEN "metal2" ELSE NARROW[prop];
-- default: metal2 is vertical (to conform to standard cells)
horizLayer: ROPEIF Rope.Equal[vertLayer, "metal2"] THEN "metal" ELSE "metal2";
outerChanWidth: INT ← GetCTPropInt[cellType, $outerWidth, 90];
powerCellWidth: INT ← GetCTPropInt[cellType, $powerWidth, 200];
hLayer: CD.Layer ← CDSimpleRules.GetLayer[technologyKey, horizLayer];
vLayer: CD.Layer ← CDSimpleRules.GetLayer[technologyKey, vertLayer];
params: Cabbage.PadRingParams ← NEW [Cabbage.PadRingParamsRec ← [
horizLayer: horizLayer,
vertLayer: vertLayer,
technologyKey: technologyKey, -- $cmosB
outerBTChanWidth: outerChanWidth, -- enough for xxx tracks
outerLRChanWidth: outerChanWidth, -- enough for xxx tracks
powerBTCellWidth : powerCellWidth, -- xxx lambda power busses
powerLRCellWidth : powerCellWidth, -- xxx lambda power busses
opt: noIncompletes,
signalSinglePinNets: TRUE]];
nets: Connections.Table ← Connections.CreateForRopes[];
innerPos: CD.Position;
leftSize, rightSize, topSize, bottomSize: CD.Position;
ConnectionsFromList: PROC [nets: Connections.Table, inst: CellInstance, side: CoreGeometry.Side, layer: CD.Layer] ~ {
FOR l: CoreRoute.WirePins ← CoreRoute.FilteredInstanceLayoutPins[inst, side], l.rest WHILE l#NIL DO
actual: Wire ← l.first.wire;
name: ROPE ← CoreRoute.LabelInternal[data.internal, actual];
net: Connections.Net ← Connections.Fetch[nets, name].net;
widthVal: REF ANY ← CoreProperties.GetWireProp[actual, wireWidthProp];
width: INTIF widthVal = NIL THEN 0 ELSE NARROW[widthVal, REF INT]^;
IF layer#l.first.layer THEN LOOP;
IF l.first.min>l.first.max THEN ERROR;
IF net=NIL THEN net ← NEW [Connections.NetRec ← [name: name, width: width]]; [] ← Connections.Store[nets, name, net];
net.segments ← CONS [
NEW [Connections.SegmentRec ← [object: PWCore.Layout[inst.type], range: [l.first.min, l.first.max], side: SideToSide[side], layer: l.first.layer]],
net.segments];
ENDLOOP;
};
IF data.size#5 THEN ERROR;  -- 4 sides and inner
FOR i: NAT IN [0..data.size) DO
SELECT CoreProperties.GetCellInstanceProp[data[i], $PadFrameSide] FROM
$Left => leftInst ← data[i];
$Right => rightInst ← data[i];
$Top => topInst ← data[i];
$Bottom => bottomInst ← data[i];
NIL => innerInst ← data[i];
ENDCASE => ERROR;
ENDLOOP;
IF leftInst=NIL OR rightInst=NIL OR topInst=NIL OR bottomInst=NIL OR innerInst=NIL THEN ERROR;
leftOb ← PWCore.Layout[leftInst.type];
rightOb ← PWCore.Layout[rightInst.type];
topOb ← PWCore.Layout[topInst.type];
bottomOb ← PWCore.Layout[bottomInst.type];
innerOb ← PWCore.Layout[innerInst.type];
leftSize ← CD.InterestSize[leftOb];
rightSize ← CD.InterestSize[rightOb];
topSize ← CD.InterestSize[topOb];
bottomSize ← CD.InterestSize[bottomOb];
IF NOT(bottomSize.x=topSize.x AND leftSize.y=rightSize.y) THEN ERROR;
-- warning: the new Cabbage changes layer from inner to pads, so pads on the left will use their pins in vertLayer!!!
ConnectionsFromList[nets, leftInst, right, vLayer];
ConnectionsFromList[nets, rightInst, left, vLayer];
ConnectionsFromList[nets, topInst, bottom, hLayer];
ConnectionsFromList[nets, bottomInst, top, hLayer];
ConnectionsFromList[nets, innerInst, right, hLayer];
ConnectionsFromList[nets, innerInst, left, hLayer];
ConnectionsFromList[nets, innerInst, bottom, vLayer];
ConnectionsFromList[nets, innerInst, top, vLayer];
-- Call Cabbage
innerPos ← CDBasics.AddPoints[
[innerDX*lambda, innerDY*lambda],
Cabbage.Center[innerOb, NIL, bottomOb, NIL, rightOb, NIL, topOb, NIL, leftOb, params]
];
CoreGeometry.PutTrans[PWCore.extractMode.decoration, innerInst, [innerPos]];
CoreGeometry.PutTrans[PWCore.extractMode.decoration, bottomInst, [[leftSize.x, 0]]];
CoreGeometry.PutTrans[PWCore.extractMode.decoration, rightInst, [[leftSize.x+bottomSize.x, bottomSize.y]]];
CoreGeometry.PutTrans[PWCore.extractMode.decoration, topInst, [[leftSize.x, bottomSize.y+leftSize.y]]];
CoreGeometry.PutTrans[PWCore.extractMode.decoration, leftInst, [[0, bottomSize.y]]];
obj ← Cabbage.PadLimitedRoute[
inner: innerOb,
bottom: bottomOb,
right: rightOb,
top: topOb,
left: leftOb,
bottomLeft: NIL, bottomRight: NIL, topRight: NIL, topLeft: NIL,
innerPos: innerPos,
connections: nets,
parms: params,
name: CoreOps.GetCellTypeName[cellType]
];
};
Decorate Proc
DecoratePadframe: PWCore.DecorateProc = {
CoreGeometry.PutRecordLazyPins[PWCore.extractMode.decoration, cellType, CD.InterestRect[obj]];
};
Initialization
[] ← PWCore.RegisterLayoutAtom[$PadFrame, LayoutPadFrame, DecoratePadframe, AttributePadFrame];
END.