BuildPadModel:
PUBLIC
PROC[
cell: Core.CellType,
keepOutside: BOOL ← FALSE,
refGrid: INT ← 0, -- default 2 lambda
pinWidth: INT ← 0, -- default 1/2 lambda
scale: INT ← 40,
refFont: CDTexts.CDFont ←
NIL ]
RETURNS[obj: CD.Object] ~ {
ToGrid:
PROC [x:
CD.Number]
RETURNS [v:
CD.Number] ~
{v ← IF x>=0 THEN ((x+grid/2)/grid)*grid ELSE ((x-grid/2)/grid)*grid};
ScaleIR:
PROC [r:
CD.Rect]
RETURNS [v:
CD.Rect] ~ {v ← [
x1: r.x1/scale, x2: r.x2/scale,
y1: r.y1/scale, y2: r.y2/scale]};
size: CD.Position ← BondingPads.GetSize[cell];
grid: INT ← IF refGrid#0 THEN refGrid ELSE tech.lambda*2;
pWidth: INT ← IF pinWidth#0 THEN pinWidth ELSE tech.lambda;
cellName: IO.ROPE ← Root[CoreOps.GetCellTypeName[cell], "IcPack"];
basicLayer: CD.Layer ← CD.commentLayer;
sigLayer: CD.Layer ← CD.FetchLayer[tech, $blue];
vddLayer: CD.Layer ← CD.FetchLayer[tech, $red];
gndLayer: CD.Layer ← CD.FetchLayer[tech, $green];
sclSize: CD.Position ← [ToGrid[size.x/scale]+pWidth, ToGrid[size.y/scale]+pWidth];
cRect: CD.Rect ← [0, 0, sclSize.x, sclSize.y];
guard: CD.Number ← 2*pWidth;
font: CDTexts.CDFont ←
IF refFont#
NIL
THEN refFont ELSE CDTexts.MakeFont["Xerox/TiogaFonts/Helvetica7", 4];
fontCorrection: CD.Number ← -font.height/2 + font.origin.y;
triplets: Triplets;
iList: CD.InstanceList;
nmScale: INT ← 4;
nmInst: CD.Instance;
eachPublic:
PROC[wire: Core.Wire] = {
name: IO.ROPE ← AtomicName[CoreOps.GetFullWireName[cell.public, wire]];
text: CD.Object ← CDTexts.Create[name, font, basicLayer];
instances:
LIST
OF CoreGeometry.Instance ←
NARROW[CoreProperties.GetWireProp[wire, $BondingPads]];
padLayer:
CD.Layer ←
SELECT
TRUE
FROM
name.Find["Gnd", 0, FALSE]#-1 => gndLayer,
name.Find["Vdd", 0, FALSE]#-1 => vddLayer,
ENDCASE => sigLayer;
FOR instances ← instances, instances.rest
WHILE instances#
NIL
DO
ir: CD.Rect ← ScaleIR[CoreGeometry.BBox[instances.first]];
side: Side ← NearestSide[ir, cRect];
ave: CD.Position ← [(ir.x1+ir.x2)/2, (ir.y1+ir.y2)/2];
pinPos:
CD.Position ←
SELECT side
FROM
left => [0, ToGrid[ave.y-pWidth/2] ],
right => [cRect.x2, ToGrid[ave.y-pWidth/2] ],
top => [ToGrid[ave.x-pWidth/2], cRect.y2 ],
ENDCASE => [ToGrid[ave.x-pWidth/2], 0 ];
pinSize:
CD.Position ←
SELECT side
FROM
left => [ave.x - cRect.x1, pWidth ],
right => [cRect.x2 - ave.x, pWidth ],
top => [cRect.y2 - ave.y, pWidth ],
ENDCASE => [ave.y - cRect.y1, pWidth ];
pinObj: CD.Object ← CDRects.CreateRect[pinSize, basicLayer];
textPos:
CD.Position ←
SELECT side
FROM
left => [ir.x2+guard, ave.y + fontCorrection],
right => [ir.x1-guard, ave.y + fontCorrection],
top => [ave.x + fontCorrection, ir.y1-guard],
ENDCASE => [ave.x + fontCorrection, ir.y2+guard];
orient:
CD.Orientation ←
SELECT side
FROM
left => original,
right => mirrorX,
top => rotate270,
ENDCASE => rotate90X;
padObj: CD.Object ← CDRects.CreateRect[CDBasics.SizeOfRect[ir], padLayer];
padInst: CD.Instance ← CDInstances.NewInst[padObj, [CDBasics.BaseOfRect[ir]]];
pinInst: CD.Instance ← CDInstances.NewInst[pinObj, [pinPos, orient]];
textInst: CD.Instance ← CDInstances.NewInst[text, [textPos, orient]];
CDProperties.PutInstanceProp[padInst, Sisyph.mode.extractProcProp, $ExtractNull];
CDSatellites.Associate[master: pinInst, text: textInst];
triplets[side] ← CONS[[pad: padInst, pin: pinInst, text: textInst], triplets[side]];
ENDLOOP};
DO
nmFont: CDTexts.CDFont ← CDTexts.MakeFont["Xerox/TiogaFonts/Helvetica7", nmScale];
nmText: CD.Object ← CDTexts.Create[cellName, nmFont, basicLayer];
nmTextSz: CD.Position ← CD.InterestSize[nmText];
nmPos: CD.Position ← [sclSize.x/2-nmTextSz.x/2, sclSize.y/2];
nmInst ← CDInstances.NewInst[nmText, [nmPos]];
IF nmTextSz.x*3 > (cRect.x2 - cRect.x1) THEN EXIT;
nmScale ← nmScale*2 ENDLOOP;
obj ← CDCells.CreateEmptyCell[];
BondingPads.MarkBondingPads[cell];
[]𡤌oreOps.VisitRootAtomics[cell.public, eachPublic];
iList ← FilterOutsidePins[triplets, keepOutside, grid];
obj ← CDCells.CreateCell[il: CONS[nmInst, iList], ir: cRect];
CDCells.ToSequenceMode[obj]};
Compare:
PROC[side: Side, ir1, ir2:
CD.Rect]
RETURNS[ioSide: {in, out, equal}] = {
AboutTheSame:
PROC[a1, a2, b1, b2:
INT]
RETURNS[same:
BOOL] ← {
size: INT ← MAX[b2-b1, a2-a1];
overLap: INT ← MIN[a2, b2] - MAX[a1, b1];
RETURN[((overLap*100)/size) > 90]}; -- more than 90% overlap
SELECT side
FROM
left => {IF ir1.x2<ir2.x1 THEN RETURN[out]; IF ir1.x1>ir2.x2 THEN RETURN[in]};
right => {IF ir1.x2<ir2.x1 THEN RETURN[in]; IF ir1.x1>ir2.x2 THEN RETURN[out]};
top => {IF ir1.y2<ir2.y1 THEN RETURN[in]; IF ir1.y1>ir2.y2 THEN RETURN[out]};
bottom => {IF ir1.y2<ir2.y1 THEN RETURN[out]; IF ir1.y1>ir2.y2 THEN RETURN[in]};
ENDCASE;
SELECT side
FROM
left, right => {IF AboutTheSame[ir1.x1, ir1.x2, ir2.x1, ir2.x2] THEN RETURN[equal]};
top, bottom=> {IF AboutTheSame[ir1.y1, ir1.y2, ir2.y1, ir2.y2] THEN RETURN[equal]};
ENDCASE;
ERROR}; -- pads overlap in range (0..90%)