$C2Trans, $C2WellTrans =>
-- straight transistors
BEGIN
difRect, polRect, chRect, difExtRectNorth, difExtRectSouth: CD.Rect;
difRect ← difList.first; polRect ← polList.first;
chRect ← [difRect.x1, polRect.y1, difRect.x2, polRect.y2];
difExtRectNorth ← difExtRectSouth ← difRect;
difExtRectNorth.y1 ← polRect.y2; difExtRectSouth. y2 ← polRect.y1;
length ← polRect.y2 - polRect.y1; width ← difRect.x2 - difRect.x1;
extL ← polRect.y1 - difRect.y1; extW ← difRect.x1 - polRect.x1;
gateA ← (width + 2*extW) * length; gateP ← (width + 2*extW + length) * 2;
sourceA ← drainA ← extL * width; sourceP ← drainP ← 2 * extL + width;
Process poly layer
gateNode ← SX.AddRect [cir: cir, lev: CMosB.pol, dim: polRect, inst: inst, pos: pos, orient: orient];
IF extL > sep
THEN
-- Add rectangles for poly exclusion
BEGIN
rect ← difExtRectNorth; rect.y1 ← rect.y1 + sep;
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.WNEGrow [extSep], exclPol];
rect ← difExtRectSouth; rect.y2 ← rect.y2 - sep;
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.ESWGrow [extSep], exclPol];
END;
Process channel lead-in
rect ← difExtRectNorth; rect.y2 ← rect.y1+sep;
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]];
rect ← difExtRectSouth; rect.y1 ← rect.y2-sep;
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]];
Fill channel gap. NOTE: The DRC of channels is affected by the change made to CMosSpinifexInitImpl on April 2, 1985.
[] ← SX.AddBox [cir: cir, spinifexLayer: difSXLayer,
dim: chRect, inst: inst, pos: pos, orient: orient,
interestBloat: [dx1: (CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2), dy1: 0, dx2: (CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2), dy2: 0],
value: difChannel];
Add rectangles for diff width spacing and connection
sourceNode ← SX.AddBox[cir: cir, spinifexLayer: difSXLayer,
dim: difExtRectNorth, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.WNEGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)]];
drainNode ← SX.AddBox[cir: cir, spinifexLayer: difSXLayer,
dim: difExtRectSouth, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.ESWGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)]];
Process well.
IF tClass = $C2WellTrans
THEN
BEGIN
l: CD.Layer = IF isNWell THEN CMosB.nwell ELSE CMosB.pwell;
IF NOT CDBasics.NonEmpty[wellRect] THEN ERROR SX.IllegalConstruct [errorRect, "Well transistor must have a well"];
wellNode ← SX.AddRect [cir: cir, lev: l, dim: wellRect, inst: inst, pos: pos, orient: orient];
wellNode.properties ← Properties.PutProp [propList: wellNode.properties, prop: wellNode, val: wellNode];
END;
END; -- case $CTrans
$C2LTrans, $CLWellTrans =>
-- angle transistors
BEGIN
diffNE: CD.Position ← CDBasics.minposition;
diffSW, polSW: CD.Position ← CDBasics.highposition;
polHor, polVert: CD.Rect;
IF ((polList.first.y2-polList.first.y1) < (polList.rest.first.y2-polList.rest.first.y1)) THEN
{polHor ← polList.first; polVert ← polList.rest.first}
ELSE {polHor ← polList.rest.first; polVert ← polList.first};
FOR diff:
LIST
OF
CD.Rect ← difList, diff.rest
WHILE diff #
NIL
DO
IF (diff.first.x1 <= diffSW.x)
AND (diff.first.y1 <= diffSW.y)
THEN
diffSW ← [diff.first.x1, diff.first.y1];
IF (diff.first.x2 >= diffNE.x)
AND (diff.first.y2 >= diffNE.y)
THEN
diffNE ← [diff.first.x2, diff.first.y2];
ENDLOOP;
polSW ← [polHor.x1, polHor.y1];
extW ← diffSW.x - polSW.x;
extL ← polSW.y - diffSW.y;
length ← polHor.y2 - polHor.y1;
width ← ((polHor.x2 - polHor.x1) - extW) + ((polVert.y2 - polVert.y1) - extW) - (length*3/2);
gateA ← ((width+length/2) + 2*extW) * length;
gateP ← ((polHor.x2 - polHor.x1) + (polVert.y2 - polVert.y1)) * 2;
sourceA ← ((diffNE.x - diffSW.x) + (diffNE.y - diffSW.y - extL)) * extL;
sourceP ← 2 * extL + (diffNE.x - diffSW.x) + (diffNE.y - diffSW.y);
drainP ← diffNE.x + diffNE.y - diffSW.x - diffSW.y - 2 * (extL + length);
drainA ← drainP * extL;
Process poly layer
gateNode ← SX.AddRect [cir: cir, lev: CMosB.pol, dim: polHor, inst: inst, pos: pos, orient: orient];
[] ← SX.AddRect [cir: cir, lev: CMosB.pol, dim: polVert, inst: inst, pos: pos, orient: orient, value: gateNode];
IF extL > sep
THEN
-- Add rectangles for poly exclusion
BEGIN
d: CD.Number ← extL + length + sep;
rect ← [x1: diffSW.x, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffSW.y+length+2*extL];
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.WNGrow [extSep], exclPol]; -- North
rect ← [x1: diffNE.x-length-2*extL, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffNE.y];
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.WNGrow [extSep], exclPol]; -- West
d ← extL - sep;
rect ← [x1: diffSW.x, y1: diffSW.y, x2: diffNE.x, y2: diffSW.y+d];
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.ESWGrow [extSep], exclPol]; -- South
rect ← [x1: diffNE.x-d, y1: diffSW.y, x2: diffNE.x, y2: diffNE.y];
[] ← SX.AddBox [cir, polSpinifex, rect, inst, pos, orient, SXTechnology.NESGrow [extSep], exclPol] -- East
END; -- poly excl
Process channel lead-in
BEGIN
d: CD.Number ← extL + length + sep;
rect ← [x1: diffSW.x, y1: diffSW.y+extL+length, x2: diffNE.x-extL-length, y2: diffSW.y+d];
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]]; -- North
rect ← [x1: diffNE.x-d, y1: diffSW.y+extL+length, x2: diffNE.x-extL-length, y2: diffNE.y];
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]]; -- West
d ← extL - sep;
rect ← [x1: diffSW.x, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffSW.y+extL];
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]]; -- South
rect ← [x1: diffNE.x-extL, y1: diffSW.y+d, x2: diffNE.x-d, y2: diffNE.y];
[] ← SX.AddBox [cir: cir, spinifexLayer: polSpinifex, dim: rect, inst: inst, pos: pos, orient: orient, value: polCnstr[pChE]] -- East
END; -- ch lead-in
Fill channel gap. NOTE: The DRC of channels is affected by the change made to CMosSpinifexInitImpl on April 2, 1985.
rect ← polHor; rect.x1 ← rect.x1 + extW;
[] ← SX.AddBox [cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: [dx1: (CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2), dy1: 0, dx2: 0, dy2: 0],
value: difChannel];
rect ← polVert; rect.y2 ← rect.y2 - extW;
[] ← SX.AddBox [cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: [dx1: 0, dy1: 0, dx2: 0, dy2: (CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)],
value: difChannel];
Add rectangles for diff width spacing and connection
rect ← [x1: diffSW.x, y1: diffSW.y+extL+length, x2: diffNE.x-extL-length, y2: diffSW.y+2*extL+length];
sourceNode ← SX.AddBox [cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.WNGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)]];
IF difList.rest #
NIL
THEN --
supposed source is concave
BEGIN
rect ← [x1: diffNE.x-length-2*extL, y1: rect.y1, x2: rect.x2, y2: diffNE.y];
[] ← SX.AddBox [cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.WNGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)],
value: sourceNode]
END;
rect ← [x1: diffSW.x, y1: diffSW.y, x2: diffNE.x, y2: diffSW.x+extL];
drainNode ← SX.AddBox[cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.ESWGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)]];
rect ← [x1: diffNE.x-extL, y1: rect.y2, x2: diffNE.x, y2: diffNE.y];
[] ← SX.AddBox[cir: cir, spinifexLayer: difSXLayer,
dim: rect, inst: inst, pos: pos, orient: orient,
interestBloat: SXTechnology.NESGrow[(CDSimpleRules.MinDist[CMosB.ndif, CMosB.ndif]/2)],
value: drainNode];
Process well.
IF tClass = $CWellTrans
THEN
BEGIN
l: CD.Layer = IF isNWell THEN CMosB.nwell ELSE CMosB.pwell;
IF NOT CDBasics.NonEmpty[wellRect] THEN ERROR SX.IllegalConstruct [errorRect, "Well transistor must have a well"];
wellNode ← SX.AddRect [cir: cir, lev: l, dim: wellRect, inst: inst, pos: pos, orient: orient];
wellNode.properties ← Properties.PutProp [propList: wellNode.properties, prop: wellNode, val: wellNode];
END;
END; -- case $CTrans