SCLibGenImpl.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Created by: Christian Jacobi June 2, 1986 3:48:19 pm PDT
Last Edited by: Louis Monier August 13, 1986 4:19:23 pm PDT
Last edited by: Christian Jacobi, December 22, 1986 1:41:50 pm PST
Bertrand Serlet March 30, 1987 10:41:03 pm PST
DIRECTORY
CD, CDBasics, CDRects, CDCells, CDOps, SCLibGen, CDGenerate, CDDirectory, CDProperties, CDRemote, CDSimpleRules, CDSymbolicObjects, CDUtil, Rope;
SCLibGenImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDRects, CDCells, CDOps, CDGenerate, CDDirectory, CDProperties, CDRemote, CDSimpleRules, CDSymbolicObjects, CDUtil, Rope
EXPORTS SCLibGen =
BEGIN
SetUpTech:
PROC [t:
CD.Technology] = {
lambda ← t.lambda;
met ← CD.FetchLayer[t, $met];
met2 ← CD.FetchLayer[t, $met2];
};
seeMeProc: PROC[CD.Object] ← NIL;
SeeMe: PUBLIC PROC [p: PROC[CD.Object]] = {seeMeProc←p};
met, met2: CD.Layer;
gDesign: CD.Design;
cell: CD.Object;
ptype: BOOL;
originP, pitchP, bottomContactN, topContactP, m2ContP, heightP: CD.Position;
topPinR, botPinR, vddPinR, gndPinR: CD.Rect;
lambda, pitch, metWidth, limitPy, limitNy: CD.Number;
sizeOb, p1Ob, p2Ob, p3Ob, p4Ob, contactNOb, contactPOb, contactM2Ob, xViaOb: CD.Object;
topPinOb, botPinOb, vddPinOb, gndPinOb: CD.Object;
specialOb, specialDNOb, specialDPOb: CD.Object;
pinOrder: Rope.ROPE;
GetP1: CDGenerate.GeneratorProc = {
ob ← CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TN", "TP"], remove: FALSE, prop: $X, name: "=template="];
CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE];
};
GetP2: CDGenerate.GeneratorProc = {
ob ← CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TP"], remove: FALSE, prop: $X, name: "=template="];
CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE];
};
GetP3: CDGenerate.GeneratorProc = {
ob ← CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B", "T", "TN"], remove: FALSE, prop: $X, name: "=template="];
CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE];
};
GetP4: CDGenerate.GeneratorProc = {
ob ← CDUtil.PartialCopy[ob: sizeOb, design: design, instances: LIST["B"], remove: FALSE, prop: $X, name: "=template="];
CDCells.SetSimplificationTreshhold[ob, 0.05, FALSE];
};
SetUpInput:
PROC [design:
CD.Design] = {
GetLib:
PROC [name: Rope.
ROPE]
RETURNS [ob:
CD.Object] = {
ob ← CDGenerate.FetchNCall[stdCellInput, design, name];
IF ob=NIL THEN ERROR
};
SetUpTech[design.technology];
gDesign ← design;
sizeOb ← GetLib["size"];
specialOb ← GetLib["special"];
specialDNOb ← GetLib["specialDN"];
specialDPOb ← GetLib["specialDP"];
p1Ob ← CDGenerate.FetchNCall[stdCell, design, "=p1="];
p2Ob ← CDGenerate.FetchNCall[stdCell, design, "=p2="];
p3Ob ← CDGenerate.FetchNCall[stdCell, design, "=p3="];
p4Ob ← CDGenerate.FetchNCall[stdCell, design, "=p4="];
contactNOb ← GetLib["contactN"];
contactPOb ← GetLib["contactP"];
contactM2Ob ← GetLib["contactM2"];
xViaOb ← GetLib["xVia"];
topPinOb ← FetchPin[sizeOb, "topPin"].ob;
botPinOb ← FetchPin[sizeOb, "botPin"].ob;
vddPinOb ← FetchPin[sizeOb, "Vdd"].ob;
gndPinOb ← FetchPin[sizeOb, "Gnd"].ob;
metWidth ← CDSimpleRules.MinWidth[met];
GetNumbers[sizeOb];
};
FetchPin:
PROC [cell:
CD.Object, name: Rope.
ROPE]
RETURNS [inst:
CD.Instance] = {
il: CD.InstanceList ← CDSymbolicObjects.FindSymbolicObs[cell, name];
IF il=NIL OR il.rest#NIL OR il.first.ob=NIL THEN ERROR;
RETURN [il.first]
};
GetNumbers:
PROC [ob:
CD.Object] =
BEGIN
GetOPoint:
PROC [name: Rope.
ROPE]
RETURNS [p:
CD.Position] = {
r: CD.Rect ← CDSymbolicObjects.Denotes[FetchPin[ob, name]];
p ← [r.x1, r.y1];
};
GetRect:
PROC [name: Rope.
ROPE]
RETURNS [r:
CD.Rect] = {
r ← CDBasics.MoveRect[
CDSymbolicObjects.Denotes[FetchPin[ob, name]],
CDBasics.NegOffset[originP]
]
};
GetPoint:
PROC [name: Rope.
ROPE]
RETURNS [p:
CD.Position] = {
p ← CDBasics.SubPoints[GetOPoint[name], originP];
};
originP ← GetOPoint["origin"];
pitchP ← GetPoint["pitch"];
bottomContactN ← GetPoint["bottomContactN"];
topContactP ← GetPoint["topContactP"];
m2ContP ← GetPoint["m2c"];
heightP ← GetPoint["height"];
limitPy ← GetPoint["limitP"].y;
limitNy ← GetPoint["limitN"].y;
topPinR ← GetRect["topPin"];
botPinR ← GetRect["botPin"];
vddPinR ← GetRect["Vdd"];
gndPinR ← GetRect["Gnd"];
pitch ← pitchP.x;
END;
ContactM2:
PUBLIC PROC [pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8, pos9, pos10, pos11, pos12, pos13, pos14, pos15, pos16, pos17, pos18, pos19, pos20, pos21, pos22:
INT ← -1] = {
Incl:
PROC [n:
INT←-1] = {
IF n>=0
THEN {
[] ← CDCells.IncludeOb[cell: cell, ob: contactM2Ob,
trans: [[x: m2ContP.x+(n-1)*pitch, y: m2ContP.y]]
];
}
};
Incl[pos1];
Incl[pos2];
Incl[pos3];
Incl[pos4];
Incl[pos5];
Incl[pos6];
Incl[pos7];
Incl[pos8];
Incl[pos9];
Incl[pos10];
Incl[pos11];
Incl[pos12];
Incl[pos13];
Incl[pos14];
Incl[pos15];
Incl[pos16];
Incl[pos17];
Incl[pos18];
Incl[pos19];
Incl[pos20];
Incl[pos21];
Incl[pos22];
};
Pins:
PUBLIC PROC [cnt:
INT ← 1, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22: Rope.
ROPE ←
NIL] = {
pos: INT ← 0;
SignalPin:
PROC [n: Rope.
ROPE ←
NIL] = {
IF ~Rope.IsEmpty[n]
THEN {
rob: CD.Object;
i: CD.Instance;
i ←
NEW[
CD.InstanceRep← [
ob: botPinOb,
trans: CDOps.FitObjectI[ob: botPinOb, location: [x: botPinR.x1+pos*pitch, y: botPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[south]]
]];
CDSymbolicObjects.SetLayer[i, met2];
CDSymbolicObjects.SetName[i, n];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
--for aid to the Spinifex to Thyme extraction
rob ← CDRects.CreateRect[CD.InterestSize[botPinOb], met2];
i ←
NEW[
CD.InstanceRep← [
ob: rob,
trans: CDOps.FitObjectI[ob: rob, location: [x: botPinR.x1+pos*pitch, y: botPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[south]]
]];
CDProperties.PutProp[i, $SignalName, n];
CDProperties.PutProp[i, $Export, $TRUE];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
i ←
NEW[
CD.InstanceRep← [
ob: botPinOb,
trans: CDOps.FitObjectI[ob: topPinOb, location: [x: topPinR.x1+pos*pitch, y: topPinR.y2-CD.InterestSize[topPinOb].x], orientation: CDSymbolicObjects.OrientFromDirection[north]]
]];
CDSymbolicObjects.SetLayer[i, met2];
CDSymbolicObjects.SetName[i, n];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
};
pos ← pos+1;
};
i: CD.Instance;
gnd: Rope.ROPE = "Gnd";
vdd: Rope.ROPE = "Vdd";
--bottomLeft
i ←
NEW[
CD.InstanceRep← [
ob: gndPinOb,
trans: CDOps.FitObjectI[ob: gndPinOb, location: [x: gndPinR.x1, y: gndPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[west]]
]];
CDSymbolicObjects.SetLayer[i, met];
CDSymbolicObjects.SetName[i, "Gnd"];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
--for aid to the Spinifex to Thyme extraction
i ← CDCells.IncludeOb[cell: cell,
ob: CDRects.CreateRect[CDBasics.SizeOfRect[gndPinOb.bbox], met],
trans: [[x: gndPinR.x1, y: gndPinR.y1]],
mode: dontResize
].newInst;
CDProperties.PutProp[i, $SignalName, gnd];
CDProperties.PutProp[i, $Export, $TRUE];
--bottomRight
i ←
NEW[
CD.InstanceRep← [
ob: gndPinOb,
trans: CDOps.FitObjectI[ob: gndPinOb, location: [x: gndPinR.x1+cnt*pitch-CDBasics.SizeOfRect[gndPinOb.bbox].x, y: gndPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[east]]
]];
CDSymbolicObjects.SetLayer[i, met];
CDSymbolicObjects.SetName[i, "Gnd"];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
--topLeft
i ←
NEW[
CD.InstanceRep← [
ob: vddPinOb,
trans: CDOps.FitObjectI[ob: vddPinOb, location: [x: vddPinR.x1, y: vddPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[west]]
]];
CDSymbolicObjects.SetLayer[i, met];
CDSymbolicObjects.SetName[i, "Vdd"];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
--for aid to the Spinifex to Thyme extraction
i ← CDCells.IncludeOb[cell: cell,
ob: CDRects.CreateRect[CD.InterestSize[vddPinOb], met],
trans: [[x: vddPinR.x1, y: vddPinR.y1]],
mode: dontResize
].newInst;
CDProperties.PutProp[i, $SignalName, vdd];
CDProperties.PutProp[i, $Export, $TRUE];
--topRight
i ←
NEW[
CD.InstanceRep← [
ob: vddPinOb,
trans: CDOps.FitObjectI[ob: vddPinOb, location: [x: vddPinR.x1+cnt*pitch-CD.InterestSize[vddPinOb].x, y: vddPinR.y1], orientation: CDSymbolicObjects.OrientFromDirection[east]]
]];
CDSymbolicObjects.SetLayer[i, met];
CDSymbolicObjects.SetName[i, "Vdd"];
[] ← CDCells.IncludeInstance[cell: cell, inst: i, mode: dontResize];
SignalPin[p1];
SignalPin[p2];
SignalPin[p3];
SignalPin[p4];
SignalPin[p5];
SignalPin[p6];
SignalPin[p7];
SignalPin[p8];
SignalPin[p9];
SignalPin[p10];
SignalPin[p11];
SignalPin[p12];
SignalPin[p13];
SignalPin[p14];
SignalPin[p15];
SignalPin[p16];
SignalPin[p17];
SignalPin[p18];
SignalPin[p19];
SignalPin[p20];
SignalPin[p21];
SignalPin[p22];
[] ← CDCells.ResizeCell[cell: cell, design: NIL];
};
MakeCont:
PUBLIC PROC [row:
INT, start:
INT ← 0, n:
INT ← 1, back:
BOOL ←
FALSE] = {
ct: CD.Object ← IF ptype THEN contactPOb ELSE contactNOb;
ibase: CD.Position ← CD.InterestBase[ct];
yStep: CD.Number ← IF ptype THEN -CD.InterestSize[ct].y ELSE CD.InterestSize[ct].y;
x: CD.Number ← bottomContactN.x+(row-1)*pitch;
y: CD.Number ← (IF ptype THEN topContactP.y ELSE bottomContactN.y)+(start-1)*yStep;
IF back THEN y←y-yStep/2;
WHILE n>0
DO
[] ← CDCells.IncludeOb[cell: cell, ob: ct, trans: [[x: x-ibase.x, y: y-ibase.y]]];
y ← y+yStep;
n ← n-1;
ENDLOOP;
};
MakeVia:
PUBLIC PROC [row:
INT, start:
INT𡤀, n:
INT ← 1, back:
BOOL ←
FALSE] = {
ct: CD.Object ← IF ptype THEN contactPOb ELSE contactNOb;
yStep: CD.Number ← IF ptype THEN -CD.InterestSize[ct].y ELSE CD.InterestSize[ct].y;
x: CD.Number ← bottomContactN.x+(row-1)*pitch;
y: CD.Number ← (IF ptype THEN topContactP.y ELSE bottomContactN.y)+(start-1)*yStep;
IF back THEN y←y-yStep/2;
WHILE n>0
DO
[] ← CDCells.IncludeOb[cell: cell, ob: xViaOb, trans: [[x: x, y: y]]];
y ← y+yStep;
n ← n-1;
ENDLOOP;
};
ContactSize:
PROC [ptype:
BOOL←
FALSE]
RETURNS [s:
CD.Position] = {
ct: CD.Object ← IF ptype THEN contactPOb ELSE contactNOb;
RETURN [CD.InterestSize[ct]]
};
HorizontalM:
PUBLIC PROC [rowL, rowR:
INT, h:
INT, back:
BOOLLSE, shortStart:
BOOL←
TRUE, shortEnd:
BOOL←
TRUE] = {
m: CD.Object;
y1: CD.Number;
x1: CD.Number ← bottomContactN.x+(rowL-1)*pitch;
x2: CD.Number ← bottomContactN.x+(rowR-1)*pitch;
x1 ← x1 + (IF shortStart THEN ContactSize[ptype].x-metWidth ELSE 0);
x2 ← x2 + (IF shortEnd THEN metWidth ELSE ContactSize[ptype].x);
IF ptype
THEN {
y1 ← topContactP.y-(h-1)*ContactSize[ptype].y;
IF back THEN y1 ← y1+ContactSize[ptype].y-metWidth;
}
ELSE {
y1 ← bottomContactN.y+(h-1)*ContactSize[ptype].y;
IF ~back THEN y1 ← y1+ContactSize[ptype].y-metWidth;
};
m ← CDRects.CreateRect[[x2-x1, metWidth], met];
[] ← CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]];
};
PassMetall:
PUBLIC PROC [row:
INT] = {
m: CD.Object;
x1: CD.Number ← bottomContactN.x+(row-1)*pitch;
y1, y2: CD.Number;
y2 ← topContactP.y-(8-1)*ContactSize[ptype].y+metWidth;
y1 ← bottomContactN.y+4*ContactSize[ptype].y-metWidth;
m ← CDRects.CreateRect[[metWidth, y2-y1], met];
[] ← CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]];
};
PassMs:
PUBLIC PROC [r1, r2, r3, r4, r5, r6:
INT ← -1] = {
IF r1>=0 THEN PassMetall[r1];
IF r2>=0 THEN PassMetall[r2];
IF r3>=0 THEN PassMetall[r3];
IF r4>=0 THEN PassMetall[r4];
IF r5>=0 THEN PassMetall[r5];
IF r6>=0 THEN PassMetall[r6];
};
VerticalM:
PUBLIC PROC [row:
INT, h1, h2:
INT, front:
BOOLLSE] = {
m: CD.Object;
x1: CD.Number ← bottomContactN.x+(row-1)*pitch;
y1, y2: CD.Number;
IF ~front THEN x1 ← x1+ContactSize[ptype].x-metWidth;
IF ptype
THEN {
h2 ← MIN[h2, 9];
y2 ← topContactP.y-(h1-1)*ContactSize[ptype].y;
y1 ← topContactP.y-(h2-1)*ContactSize[ptype].y;
}
ELSE {
h2 ← MIN[h2, 5];
y1 ← bottomContactN.y+h1*ContactSize[ptype].y;
y2 ← bottomContactN.y+h2*ContactSize[ptype].y;
};
y1 ← y1-metWidth;
y2 ← y2+metWidth;
IF ptype THEN y1 ← MAX[limitPy, y1] ELSE y2 ← MIN[y2, limitNy];
m ← CDRects.CreateRect[[metWidth, y2-y1], met];
[] ← CDCells.IncludeOb[cell: cell, ob: m, trans: [[x: x1, y: y1]]];
};
Setup:
PUBLIC
PROC [design:
CD.Design, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22: Rope.
ROPE←
NIL] = {
SetUpInput[design];
pinOrder ← NIL;
ptype ← TRUE;
cell ← GetBasis[LIST[x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22]];
};
SetN:
PUBLIC PROC [] = {
ptype ← FALSE
};
PinOrder:
PUBLIC PROC [r: Rope.
ROPE←
NIL] = {
pinOrder ← r
};
Finish:
PUBLIC
PROC [name: Rope.
ROPE←
NIL]
RETURNS [ob:
CD.Object] = {
p: PROC[CD.Object] ← seeMeProc;
cell ← CDUtil.Flatten[cell, NIL, NIL];
[] ← CDCells.ResizeCell[NIL, cell];
[] ← CDDirectory.Include[design: gDesign, object: cell, alternateName: name];
CDProperties.PutProp[cell, $PinOrder, pinOrder];
IF p#NIL THEN p[cell];
ob ← cell;
};
GetBasis:
PROC [contents:
LIST
OF Rope.
ROPE]
RETURNS [cell:
CD.Object] = {
cnt: INT ← 0;
SubCell:
PROC [n: Rope.
ROPE ←
NIL] = {
IF ~Rope.IsEmpty[n]
THEN {
ib: CD.Position;
subOb: CD.Object;
SELECT
TRUE
FROM
Rope.Equal[n, "p1"] => subOb ← p1Ob;
Rope.Equal[n, "p2"] => subOb ← p2Ob;
Rope.Equal[n, "p3"] => subOb ← p3Ob;
Rope.Equal[n, "p4"] => subOb ← p4Ob;
Rope.Equal[n, "weakP1"] => subOb ← specialOb;
Rope.Equal[n, "connectDiffN"] => {subOb ← specialDNOb; cnt ← cnt-1};
Rope.Equal[n, "connectDiffP"] => {subOb ← specialDPOb; cnt ← cnt-1};
ENDCASE => ERROR;
ib ← CD.InterestBase[subOb];
[] ← CDCells.IncludeOb[cell: cell, ob: subOb, trans: [[x: cnt*pitch-ib.x, y: -ib.y]]];
cnt ← cnt+1;
};
};
cell ← CDCells.CreateEmptyCell[];
CDCells.SetSimplificationTreshhold[cell, 0.125, FALSE];
FOR l:
LIST
OF Rope.
ROPE ← contents, l.rest
WHILE l#
NIL
DO
SubCell[l.first];
ENDLOOP
};
CreateAll: CDGenerate.GeneratorProc =
BEGIN
child: CD.Object;
cnt: INT ← 0; x, y: CD.Number ← 0;
ob ← CDCells.CreateEmptyCell[];
FOR l:
LIST
OF RegPair ← contents, l.rest
WHILE l#
NIL
DO
child ← CDGenerate.FetchNCall[stdCell, design, l.first.name];
IF child=NIL THEN ERROR;
[] ← CDCells.IncludeOb[cell: ob, ob: child, trans: [[x: x, y: y]]];
cnt ← cnt+1; x ← x+CD.InterestSize[child].x+2*pitch;
IF cnt>8 THEN {x ← 0; y ← y+CD.InterestSize[child].y+4*pitch; cnt ← 0};
ENDLOOP;
[] ← CDDirectory.Include[design: design, object: ob, alternateName: "All-Standard-Cells"];
END;
Reset:
PUBLIC PROC [] = {
contents ← NIL;
stdCell.Clear[];
Register["=p1=", GetP1];
Register["=p2=", GetP2];
Register["=p3=", GetP3];
Register["=p4=", GetP4];
};
RegPair: TYPE = RECORD[name: Rope.ROPE, proc: CDGenerate.GeneratorProc];
Register:
PUBLIC PROC [name: Rope.
ROPE, proc: CDGenerate.GeneratorProc] = {
[] ← stdCell.Register[name, proc];
contents ← CONS[[name, proc], contents];
};
input: Rope.ROPE ← "StdCellBase";
user: CDGenerate.Context ← CDGenerate.AssertContext["USER"];
stdCell: CDGenerate.Context ← CDGenerate.AssertContext["STDCELLGEN"];
stdCellInput: CDGenerate.Context ← CDRemote.GetContext[input];
contents: LIST OF RegPair ← NIL;
[] ← user.Register["CreateStandardCells", CreateAll, FALSE];
Reset[];
END.