LayoutPadFrame: PWCore.LayoutProc = {
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
ia: CoreRoute.InstanceArray ←
NARROW[CoreProperties.GetCellTypeProp
[cellType, $PadFrameInstanceArray]];
cornersOK: BOOL ← ConstructCorners[ia];
innerDX: INT ← GetCTPropInt[cellType, $innerDX, 0];
innerDY: INT ← GetCTPropInt[cellType, $innerDY, 0];
outerChanWidth: INT ← GetCTPropInt[cellType, $outerWidth, 90];
powerCellWidth: INT ← GetCTPropInt[cellType, $powerWidth, 200];
leftSize: CD.Position ← CD.InterestSize[PWCore.Layout[ia[1][0].type]];
rightSize: CD.Position ← CD.InterestSize[PWCore.Layout[ia[1][2].type]];
topSize: CD.Position ← CD.InterestSize[PWCore.Layout[ia[2][1].type]];
bottomSize: CD.Position ← CD.InterestSize[PWCore.Layout[ia[0][1].type]];
innerPos: CD.Position;
bottomLeftInst: CellInstance ← ia[0][0];
bottomInst: CellInstance ← ia[0][1];
bottomRightInst: CellInstance ← ia[0][2];
leftInst: CellInstance ← ia[1][0];
innerInst: CellInstance ← ia[1][1];
rightInst: CellInstance ← ia[1][2];
topLeftInst: CellInstance ← ia[2][0];
topInst: CellInstance ← ia[2][1];
topRightInst: CellInstance ← ia[2][2];
params: Cabbage.PadRingParams;
metalLayer: CD.Layer ← CDSimpleRules.GetLayer[technologyKey, "Metal"];
vLayer: CD.Layer;
hLayer: CD.Layer;
nets: Connections.Table ← Connections.CreateForRopes[];
[vLayer, hLayer] ← CoreRoute.GetCellTypePropLayer[cellType, $VerticalMetal, $met2];
params ←
NEW [Cabbage.PadRingParamsRec ← [
horizLayer: IF hLayer=metalLayer THEN "Metal" ELSE "Metal2",
vertLayer: IF vLayer=metalLayer THEN "Metal" ELSE "Metal2",
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 ]];
IF NOT(bottomSize.x=topSize.x AND leftSize.y=rightSize.y) THEN ERROR;
Layer changes from inner to pads; vLayer is vertical for inner and horizontal for pads.
ConnectionsFromList[data, nets, leftInst, right, vLayer];
ConnectionsFromList[data, nets, rightInst, left, vLayer];
ConnectionsFromList[data, nets, topInst, bottom, hLayer];
ConnectionsFromList[data, nets, bottomInst, top, hLayer];
ConnectionsFromList[data, nets, innerInst, right, hLayer];
ConnectionsFromList[data, nets, innerInst, left, hLayer];
ConnectionsFromList[data, nets, innerInst, bottom, vLayer];
ConnectionsFromList[data, nets, innerInst, top, vLayer];
innerPos ← CDBasics.AddPoints[
[innerDX*lambda, innerDY*lambda],
Cabbage.Center[
inner: InstLayout[innerInst],
bottomLeft: InstLayout[bottomLeftInst],
bottom: InstLayout[bottomInst],
bottomRight: InstLayout[bottomRightInst],
right: InstLayout[rightInst],
topRight: InstLayout[topRightInst],
top: InstLayout[topInst],
topLeft: InstLayout[topLeftInst],
left: InstLayout[leftInst],
parms: params] ];
PutInstTrans[innerInst, innerPos];
PutInstTrans[bottomLeftInst, [0, 0]];
PutInstTrans[bottomInst, [leftSize.x, 0]];
PutInstTrans[bottomRightInst, [leftSize.x+bottomSize.x, 0]];
PutInstTrans[rightInst, [leftSize.x+bottomSize.x, bottomSize.y]];
PutInstTrans[topLeftInst, [0, bottomSize.y+leftSize.y]];
PutInstTrans[topInst, [leftSize.x, bottomSize.y+leftSize.y]];
PutInstTrans[topRightInst, [leftSize.x+bottomSize.x, bottomSize.y+leftSize.y]];
PutInstTrans[leftInst, [0, bottomSize.y]];
obj ← Cabbage.PadLimitedRoute[
inner: InstLayout[innerInst],
bottomLeft: InstLayout[bottomLeftInst],
bottom: InstLayout[bottomInst],
bottomRight: InstLayout[bottomRightInst],
right: InstLayout[rightInst],
topRight: InstLayout[topRightInst],
top: InstLayout[topInst],
topLeft: InstLayout[topLeftInst],
left: InstLayout[leftInst],
innerPos: innerPos,
connections: nets,
parms: params,
name: CoreOps.GetCellTypeName[cellType] ] };
DecoratePadFrame: PWCore.DecorateProc = {
WireToLabels:
PROC [wire: Core.Wire]
RETURNS [labels:
LIST
OF
IO.
ROPE ←
NIL] =
{RETURN[LIST[CoreRoute.LabelInternal[data.internal, wire]]]};
name: IO.ROPE ← CoreOps.GetCellTypeName[cellType];
data: CoreClasses.RecordCellType ← NARROW [cellType.data];
size: REF CD.Position ← NEW[CD.Position ← CD.InterestSize[obj]];
ia: CoreRoute.InstanceArray ←
NARROW[CoreProperties.GetCellTypeProp
[cellType, $PadFrameInstanceArray]];
markBondingPads:
REF
BOOL ←
NARROW[CoreProperties.GetCellTypeProp
[cellType, $MarkBondingPads]];
CoreRoute.DecorateRoutedArea[cellType, obj, WireToLabels, CoreRoute.CompareXorYStack];
MarkBondingPads
IF markBondingPads=NIL OR ~markBondingPads^ THEN RETURN;
IF markBondingPads#NIL AND ~markBondingPads^ THEN RETURN;
TerminalIO.PutF["Marking Bonding Pads: %g.\n", IO.rope[name]];
CoreProperties.PutCellTypeProp[cellType, $BondingFrameSize, size];
FOR row:
INT
IN [0..3)
DO
FOR col:
INT
IN [0..3)
DO
eachPair: CoreOps.EachWirePairProc = {
aList:
LIST
OF CoreGeometry.Instance ←
NARROW[CoreProperties.GetWireProp[actualWire, $BondingPads]];
pList:
LIST
OF CoreGeometry.Instance ←
NARROW[CoreProperties.GetWireProp[publicWire, $BondingPads]];
trans: CoreGeometry.Transformation
← CoreGeometry.GetTrans[PWCore.extractMode.decoration, ia[row][col]];
FOR pList ← pList, pList.rest
WHILE pList#
NIL
DO
inst: CoreGeometry.Instance ← pList.first;
inst.trans ← CDBasics.ComposeTransform[pList.first.trans, trans];
aList ← CONS[inst, aList] ENDLOOP;
CoreProperties.PutWireProp[actualWire, $BondingPads, aList]};
IF row=1 AND col=1 THEN LOOP;
IF ia[row][col]=NIL THEN LOOP;
name ← CoreOps.GetCellTypeName[ia[row][col].type];
TerminalIO.PutF[" Mark Pads: [%g, %g] %g.\n",
IO.int[row], IO.int[col], IO.rope[name]];
IcPack.MarkBondingPads[ia[row][col].type];
[]𡤌oreOps.VisitBinding[ia[row][col].actual, ia[row][col].type.public, eachPair];
ENDLOOP;
ENDLOOP};