New layers for transistors
nsource: CD.Layer ← MakeAbstract[CD.NewLayer[CMos.cmos, $CNSource], CMos.ndif];
ndrain: CD.Layer ← MakeAbstract[CD.NewLayer[CMos.cmos, $CNDrain], CMos.ndif];
psource: CD.Layer ← MakeAbstract[CD.NewLayer[CMos.cmos, $CPSource], CMos.pdif];
pdrain: CD.Layer ← MakeAbstract[CD.NewLayer[CMos.cmos, $CPDrain], CMos.pdif];
ExtractTransistor: Sinix.ExtractProc = {
cellType: CellType;
lambda: CD.Number = CMos.lambda;
ext: CD.Number = 2*lambda;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
dif: CD.Layer ← IF obj.layer=CMos.wpdif OR obj.layer=CMos.pdif THEN CMos.pdif ELSE CMos.ndif;
gateWire, sourceWire, drainWire: Wire;
IF obj.layer=CMos.wpdif
OR obj.layer=CMos.wndif
THEN {
wellSurr ← CMos.wellSurround;
innerX ← CMos.wellSurround-ext;
};
cellType ← CoreClasses.CreateTransistor[[
type: IF dif=CMos.pdif THEN pE ELSE nE,
length: (obj.size.y-2*ext-2*wellSurr)/lambda,
width: (obj.size.x-2*ext-2*innerX)/lambda]];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
AddRect[mode, sourceWire,
[x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: wellSurr, y2: ext+wellSurr],
IF dif=CMos.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: obj.size.y-wellSurr-ext, y2: obj.size.y-wellSurr],
IF dif=CMos.pdif THEN pdrain ELSE ndrain];
FOR rList: CDAtomicObjects.DrawList ←
NARROW [obj.specificRef, CDAtomicObjects.AtomicObsPtr].rList, rList.rest
WHILE rList#
NIL
DO
rect: CD.Rect ← rList.first.r;
layer: CD.Layer ← rList.first.lev;
SELECT layer
FROM
CMos.ndif => {};
CMos.pdif => {};
CMos.pol => AddRect[mode, gateWire, rect, CMos.pol];
CMos.nwell, CMos.pwell => {};
ENDCASE => ERROR;
ENDLOOP;
CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]];
result ← cellType;
};
ExtractTransistorL: Sinix.ExtractProc = {
cellType: CellType;
lambda: CD.Number = CMos.lambda;
wellSurround: CD.Number = CMos.wellSurround;
ext: CD.Number = 2*lambda;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
gateWire, sourceWire, drainWire: Wire;
dif: CD.Layer ← IF obj.layer=CMos.wpdif OR obj.layer=CMos.pdif THEN CMos.pdif ELSE CMos.ndif;
IF obj.layer=CMos.wpdif
OR obj.layer=CMos.wndif
THEN {
wellSurr ← wellSurround;
innerX ← wellSurround-ext;
};
cellType ← CoreClasses.CreateTransistor[[
type: IF dif=CMos.pdif THEN pE ELSE nE,
length: (obj.size.x+obj.size.y-2*innerX-2*wellSurr)/lambda - 10,
width: 2]];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
source is the smallest diff
AddRect[mode, sourceWire,
[x1: innerX+ext, x2: obj.size.x-wellSurr-4*lambda, y1: wellSurr+4*lambda, y2: wellSurr+6*lambda],
IF dif=CMos.pdif THEN psource ELSE nsource];
AddRect[mode, sourceWire,
[x1: obj.size.x-wellSurr-6*lambda, x2: obj.size.x-wellSurr-4*lambda, y1: wellSurr+4*lambda, y2: obj.size.y-innerX-ext],
IF dif=CMos.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: innerX+ext, x2: obj.size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda],
IF dif=CMos.pdif THEN pdrain ELSE ndrain];
AddRect[mode, drainWire,
[x1: obj.size.x-wellSurr-2*lambda, x2: obj.size.x-wellSurr, y1: wellSurr, y2: obj.size.y-innerX-ext],
IF dif=CMos.pdif THEN pdrain ELSE ndrain];
FOR rList: CDAtomicObjects.DrawList ←
NARROW [obj.specificRef, CDAtomicObjects.AtomicObsPtr].rList, rList.rest
WHILE rList#
NIL
DO
rect: CD.Rect ← rList.first.r;
layer: CD.Layer ← rList.first.lev;
SELECT layer
FROM
CMos.pol => AddRect[mode, gateWire, rect, CMos.pol];
CMos.ndif => {};
CMos.pdif => {};
CMos.nwell, CMos.pwell => {};
ENDCASE => ERROR;
ENDLOOP;
CoreGeometry.PutIR[mode.decoration, cellType, CD.InterestRect[obj]];
result ← cellType;
};