DIRECTORY
CD, CDBasics, CDDirectory, CDInstances, CDSimpleRules, CDSymbolicObjects, CMosB, Core, CoreClasses, CoreGeometry, CoreOps, CoreProperties, HashTable,
IO, OnionCore,
PW, PWCore, PWPins, Rope, TerminalIO;
CRPadFrame:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDDirectory, CDInstances, CDSimpleRules, CDSymbolicObjects, CMosB, CoreGeometry, CoreOps, CoreProperties, HashTable, IO, OnionCore, PW, PWCore, PWPins, Rope, TerminalIO
SHARES PW =
BEGIN
LayoutCRPadFrame: PWCore.LayoutProc = {
AddInnerPinsToNets:
PROC [wire: Wire] = {
EachPin: CoreGeometry.EachPinProc = {
seg: Seg;
IF layer#CMosB.met
THEN {
TerminalIO.PutF["*** Inner pin %g not made of met but of %g discarded\n", IO.rope[name], IO.atom[CD.LayerKey[layer]]];
RETURN;
};
SELECT side
FROM
top, bottom => {min ← min + innerPos.x; max ← max + innerPos.x};
left, right => {min ← min + innerPos.y; max ← max + innerPos.y};
ENDCASE => ERROR;
seg ←
SELECT side
FROM
top, left => NEW [OnionCore.SegRec ← [max, min, side, side]],
bottom, right => NEW [OnionCore.SegRec ← [min, max, side, side]],
ENDCASE => ERROR;
net.innerSegs ← CONS [seg, net.innerSegs];
};
name: ROPE ← CoreOps.GetFullWireName[innerCT.public, wire];
net: Net ← NARROW [HashTable.Fetch[nets, name].value];
IF net=NIL THEN net ← NEW [OnionCore.NetRec ← [name: name]];
IF Rope.Equal[name, "Vdd"] THEN net.width ← 200*CMosB.lambda;
IF Rope.Equal[name, "Gnd"] THEN net.width ← 96*CMosB.lambda;
IF Rope.Equal[name, "Net3"] THEN {net.routeEveryOuterSeg ← FALSE};
[] ← PWCore.InterestRect[innerCT];
[] ← CoreGeometry.EnumerateSides[PWCore.extractMode.decoration, innerCT, wire, EachPin];
[] ← HashTable.Store[nets, name, net];
};
EachOuterPin: CDSymbolicObjects.InstEnumerator = {
seg: Seg;
name: ROPE ← CDSymbolicObjects.GetName[inst];
layer: CD.Layer ← CDSymbolicObjects.GetLayer[inst];
sides: CoreGeometry.Sides ← CoreGeometry.GetSides[CD.InterestRect[outer], [inst.ob, inst.trans]];
pos: CD.Position ← CDBasics.BaseOfRect[CDInstances.InstRectO[inst]];
min, max: INT;
net: Net ← NARROW [HashTable.Fetch[nets, name].value];
IF layer#CMosB.met
THEN {
TerminalIO.PutF["*** Outer pin %g not made of met but of %g discarded\n", IO.rope[name], IO.atom[CD.LayerKey[layer]]];
RETURN;
};
IF net=
NIL
THEN {
TerminalIO.PutF["*** Outer pin %g discarded (no corresponding inner pin)\n", IO.rope[name]];
RETURN;
};
FOR side: CoreGeometry.Side
IN CoreGeometry.Side
DO
size: CD.Position = CD.InterestSize[inst.ob];
IF NOT sides[side] THEN LOOP;
SELECT side
FROM
top, bottom => {min ← pos.x-outerBase.x; max ← min + size.x};
left, right => {min ← pos.y-outerBase.x; max ← min + size.y};
ENDCASE => ERROR;
seg ←
SELECT side
FROM
top, left => NEW [OnionCore.SegRec ← [max, min, side, side]],
bottom, right => NEW [OnionCore.SegRec ← [min, max, side, side]],
ENDCASE => ERROR;
net.outerSegs ← CONS [seg, net.outerSegs];
ENDLOOP;
};
PutDummyPins: PROC [wire: Wire] = {CoreGeometry.PutPins[PWCore.extractMode.decoration, wire, LIST [[CDSimpleRules.Rect[[16, 16], CMosB.met]]]]};
design: CD.Design ← NARROW [CoreProperties.GetCellTypeProp[cellType, $PWCoreSourceDesign]];
recordData: CoreClasses.RecordCellType = NARROW [cellType.data];
innerCT, outerCT: CellType;
inner, outer: CD.Object;
nets: HashTable.Table ← HashTable.Create[5, HashTable.RopeEqual, HashTable.HashRope];
innerPos, outerBase: CD.Position;
IF Rope.Equal[CoreOps.GetCellTypeName[recordData[0].type], "CrossRAMInner"]
THEN {innerCT ← recordData[0].type; outerCT ← recordData[1].type}
ELSE {outerCT ← recordData[0].type; innerCT ← recordData[1].type};
inner ← PWCore.Layout[innerCT];
outer ← CDDirectory.Fetch[design, "CrossRAMPadFrame.mask"].object;
innerPos ← OnionCore.Center[inner, outer];
outerBase ← CDBasics.BaseOfRect[CD.InterestRect[outer]];
innerPos ← [107*CMosB.lambda, 27*CMosB.lambda];
innerPos ← [107*CMosB.lambda, 2722*CMosB.lambda];
obj ← PW.CreateEmptyCell[];
CoreOps.VisitRootAtomics[innerCT.public, AddInnerPinsToNets];
[] ← PWPins.EnumerateDeepPins[outer, EachOuterPin];
[] ← PW.IncludeInCell[obj, inner, innerPos];
[] ← PW.IncludeInCell[obj, outer];
IF NOT OnionCore.IncludeInOuter[obj, nets, innerPos, CD.InterestSize[inner], CD.InterestSize[outer]] THEN TerminalIO.PutF["*** Did not finish properly!\n"];
PW.RepositionCell[obj];
CoreOps.VisitRootAtomics[cellType.public, PutDummyPins];
};
[] ← PWCore.RegisterLayoutAtom[$CRPadFrame, LayoutCRPadFrame, DecorateCRPadFrame];