HybridDiePad.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Don Curry May 12, 1988 8:30:02 pm PDT
DIRECTORY
BondingPads, CD, CDBasics, CDCells, CDInstances, CDProperties, CDRects, CMosB, Core, CoreClasses, CoreCreate, CoreGeometry, CoreOps, CoreProperties, IO, PW, PWCore, RefTab, Rope, Route, Sisyph, TerminalIO;
HybridDiePad: CEDAR PROGRAM
IMPORTS
BondingPads, CD, CDBasics, CDCells, CDInstances, CDProperties, CDRects, CMosB, CoreGeometry, CoreOps, CoreProperties, IO, PW, PWCore, RefTab, Rope, Sisyph, TerminalIO =
BEGIN
Types and constants
Wires:   TYPE       = Core.Wires;
Side:   TYPE       = CoreGeometry.Side;
Trans:   TYPE       = CoreGeometry.Transformation;
Instance:  TYPE       = CoreGeometry.Instance;
Instances:  TYPE       = CoreGeometry.Instances;
PadArray: TYPE       = BondingPads.PadArray;
SidePads:  TYPE       = BondingPads.SidePads;
Pads:   TYPE       = BondingPads.Pads;
Pad:   TYPE       = BondingPads.Pad;
tech:   CD.Technology    ← CMosB.cmosB;
grid:   INT       ← tech.lambda*2;
layDeco:  CoreGeometry.Decoration ← PWCore.extractMode.decoration;
schDeco:  CoreGeometry.Decoration ← Sisyph.mode.decoration;
Layout and Decorate
Layout:  PWCore.LayoutProc  = {
name:    IO.ROPE   ← CoreOps.GetCellTypeName[cellType];
instances:   CD.InstanceList ← NIL;
padArray:  PadArray;
gndPlane:  Instance;
recordCellType: CoreClasses.RecordCellType ← NARROW[cellType.data];
subInst:   CoreClasses.CellInstance ← recordCellType.instances[0];
size:    CD.Position;
ir:     CD.Rect;
used:    RefTab.Ref ← RefTab.Create[];
widths:   ARRAY Side OF INT;
bindPads:   CoreOps.EachWirePairProc = {
pubInsts: Instances ← NARROW[CoreProperties.GetWireProp[actualWire, $BondingPads]];
actInsts: Instances ← NARROW[CoreProperties.GetWireProp[publicWire, $BondingPads]];
IF RefTab.Store[used, publicWire, publicWire] -- Store is TRUE if new
THEN FOR actInsts ← actInsts, actInsts.rest WHILE actInsts#NIL DO
pubInsts ← CONS[actInsts.first, pubInsts] ENDLOOP;
CoreProperties.PutWireProp[actualWire, $BondingPads, pubInsts]};
BuildCDInstanceList: PROC[w: Core.Wire] = {
geo: Instances ← NARROW[CoreProperties.GetWireProp[w, $PadGeometry]];
CoreProperties.PutWireProp[w, $PadGeometry, NIL];
FOR geo ← geo, geo.rest WHILE geo#NIL DO
inst: CD.Instance ← CDInstances.NewInst[geo.first.obj, geo.first.trans];
CDProperties.PutProp[inst, $SignalName, CoreOps.GetFullWireName[cellType.public, w]];
instances ← CONS[inst, instances] ENDLOOP};
[]←PWCore.Layout[subInst.type];
BondingPads.EnsureBondingPads[subInst.type];
size   ← BondingPads.GetSize[subInst.type];
CoreProperties.PutCellTypeProp[cellType, $BondingFrameSize, NEW[CD.Position ← size]];
[]𡤌oreOps.VisitBindingSeq[subInst.actual, subInst.type.public, bindPads];
padArray  ← BondingPads.GetPads[cellType];
TerminalIO.PutF["HybridDiePad for: %g.\n", IO.rope[name]];
FOR side: Side IN Side DO
twoTier: BOOL ← padArray[side].offSets.rest#NIL;
pads:  Pads ← padArray[side].pads;
length: INTIF side=top OR side=bottom THEN size.x ELSE size.y;
width: INTIF twoTier THEN width2 ELSE width1;
trans:  Trans;
vddPlane: CD.Object ← CDRects.CreateRect[[loc1, length], layer1];
trans.off ← SELECT side FROM
left  => [-width,   0    ],
right  => [size.x+width, 0    ],
top  => [0,     size.y+width ],
ENDCASE => [0,     -width   ];
trans.orient ← SELECT side FROM
left  => original,
right  => mirrorX,
top  => rotate270,
ENDCASE => rotate90X;
widths[side] ← width;
FOR pads ← pads, pads.rest WHILE pads#NIL DO
wire:  Core.Wire ← pads.first.wire;
pwr:  BOOL ← IsVdd[wire] OR IsGnd[wire];
centerY: INT ← pads.first.pos.y;
inset:  BOOL ← twoTier AND pads.first.pos.x=padArray[side].offSets.first;
AddPad[inset, centerY, wire, trans] ENDLOOP;
AddPositionedObject
[CoreOps.FindWire[cellType.public, "Vdd"], vddPlane, 0, length/2, trans, TRUE];
ENDLOOP;
ir ← [-widths[left], -widths[bottom], size.x + widths[right], size.y + widths[top]];
gndPlane ← [CDRects.CreateRect[CDBasics.SizeOfRect[ir], layer0], [CDBasics.BaseOfRect[ir]] ];
AddInstance[CoreOps.FindWire[cellType.public, "Gnd"], gndPlane, TRUE];
[]𡤌oreOps.VisitRootAtomics[cellType.public, BuildCDInstanceList];
obj ← CDCells.CreateCell[il: instances, ir: ir];
CDCells.ToSequenceMode[obj]};
AddPositionedObject: PROC
[wire: Core.Wire, obj: CD.Object, posX, centerY: INT, trans: Trans, isPin: BOOLFALSE] = {
szY: INTCD.InterestSize[obj].y;
trans ← CDBasics.ComposeTransform[ [[posX, centerY-szY/2 ]], trans];
AddInstance[wire, [obj, trans], isPin]};
AddInstance: PROC
[wire: Core.Wire, inst: Instance, isPin: BOOLFALSE] = {
geo: Instances ← NARROW[CoreProperties.GetWireProp[wire, $PadGeometry]];
IF isPin THEN CoreGeometry.AddPins[layDeco, wire, LIST[inst]];
geo ← CONS[inst, geo];
CoreProperties.PutWireProp[wire, $PadGeometry, geo]};
AddPad: PROC[inset: BOOL, centerY: INT, sig: Core.Wire, trans: Trans] = {
SELECT TRUE FROM
inset AND IsVdd[sig] => {
AddPositionedObject[sig, short1,  loc1, centerY, trans];
AddPositionedObject[sig, long1,  loc2, centerY, trans];
AddPositionedObject[sig, cntc23,  loc2, centerY, trans];
AddPositionedObject[sig, cntc12,  loc3l, centerY, trans]};
inset AND IsGnd[sig] => {
AddPositionedObject[sig, cntc23,  loc2, centerY, trans];
AddPositionedObject[sig, cntc12,  loc3l, centerY, trans];
AddPositionedObject[sig, cntc01,  loc4, centerY, trans]};
inset       => {
AddPositionedObject[sig, cntc23,  loc0, centerY, trans, TRUE];
AddPositionedObject[sig, short2,  loc1, centerY, trans];
AddPositionedObject[sig, cntc23,  loc2, centerY, trans]};
IsVdd[sig] => { -- twoTier or not
AddPositionedObject[sig, cntc23,  loc0, centerY, trans, TRUE];
AddPositionedObject[sig, short1,  loc1, centerY, trans];
AddPositionedObject[sig, short2,  loc1, centerY, trans];
AddPositionedObject[sig, cntc12,  loc2, centerY, trans]};
IsGnd[sig] => { -- twoTier or not
AddPositionedObject[sig, cntc23,  loc0, centerY, trans, TRUE];
AddPositionedObject[sig, short2,  loc1, centerY, trans];
AddPositionedObject[sig, cntc12,  loc2, centerY, trans];
AddPositionedObject[sig, cntc01,  loc3s, centerY, trans]};
ENDCASE  => {
AddPositionedObject[sig, cntc23,  loc0, centerY, trans, TRUE]}};
The only direct references to CMosB layers
See HybridDiePadRef.dale
sml:  INT ← 100 * tech.lambda;
lrg:  INT ← 250 * tech.lambda;
loc0:  INT ← 0;
loc1:  INT ← loc0 + lrg;
loc2:  INT ← loc1 + sml;
loc3s:  INT ← loc2 + sml;
loc3l:  INT ← loc2 + lrg;
loc4:  INT ← loc3l + sml;
width1: INT ← loc3s + sml*2;
width2: INT ← loc4 + sml*2;
layer0: CD.Layer ← CMosB.ndif;
layer1: CD.Layer ← CMosB.pol;
short1: CD.Object ← CDRects.CreateRect[[sml, sml], CMosB.pol]; -- for gaps
short2: CD.Object ← CDRects.CreateRect[[sml, sml], CMosB.met]; -- for gaps
long1:  CD.Object ← CDRects.CreateRect[[lrg, sml], CMosB.pol]; -- for beneath cntc23
cntc01: CD.Object ← MakeContact[CMosB.ndif, CMosB.bur, CMosB.pol, sml, sml, sml/4];
cntc12: CD.Object ← MakeContact[CMosB.pol, CMosB.cut, CMosB.met, sml, sml, sml/4];
cntc23: CD.Object ← MakeContact[CMosB.met, CMosB.cut2, CMosB.met2, lrg, sml, sml/20];
IsVdd: PROC[wire: Core.Wire] RETURNS[BOOL] =
{RETURN[wire#NIL AND CoreOps.GetShortWireName[wire].Equal["Vdd"]]};
{RETURN[CoreOps.GetShortWireName[wire].Find["Vdd", 0, FALSE]#-1]};
IsGnd: PROC[wire: Core.Wire] RETURNS[BOOL] =
{RETURN[wire#NIL AND CoreOps.GetShortWireName[wire].Equal["Gnd"]]};
{RETURN[CoreOps.GetShortWireName[wire].Find["Gnd", 0, FALSE]#-1]};
MakeContact: PROC[l0, l1, l2: CD.Layer, sizex, sizey, border: INT]
RETURNS[obj: CD.Object] = {
node:  IO.ROPE   ← "node";
insts:  CD.InstanceList ← NIL;
middle: CD.Object   ← CDRects.CreateRect[[sizex-2*border, sizey-2*border], l1];
insts ← CONS[NEW[CD.InstanceRep ← [middle, [[border, border]]]], insts];
CDProperties.PutProp[insts.first, $SignalName, node];
insts ← CONS[NEW[CD.InstanceRep ← [CDRects.CreateRect[[sizex, sizey], l0]]], insts];
CDProperties.PutProp[insts.first, $SignalName, node];
insts ← CONS[NEW[CD.InstanceRep ← [CDRects.CreateRect[[sizex, sizey], l2]]], insts];
CDProperties.PutProp[insts.first, $SignalName, node];
obj ← PW.CreateCell[instances: insts, ir: [0, 0, sizex, sizey]];
CDProperties.PutProp[obj, PWCore.extractMode.extractProcProp, $ExtractAtomic]};
Register layout atoms
[] ← PWCore.RegisterLayoutAtom[$HybridDiePad, Layout];
END.