DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDOrient, CDRects, CDSimpleRules, CDSymbolicObjects, CDTexts,
CMosB,
Core, CoreClasses, CoreOps, CoreProperties,
PW, PWObjects, PWPins,
Sinix, SinixCMos, SinixHighlight;
SinixCheckB:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDCells, CDOrient, CDInstances, CDLayers, CDProperties, CDRects, CDSimpleRules, CDSymbolicObjects, CDTexts, CMosB, CoreClasses, CoreOps, CoreProperties, PW, PWObjects, PWPins, Sinix, SinixCMos, SinixHighlight
EXPORTS SinixCMos
SHARES CDCells, CDRects, CDSymbolicObjects, CDTexts =
BEGIN OPEN SinixCMos;
Properties and extraction for certain modes
checkBMode:
PUBLIC Sinix.Mode ←
NEW [Sinix.ModeRec ← [
name: "CheckB",
extractProcProp: PW.RegisterProp[$SinixCMosCheckBProc, TRUE],
pinsProp: CoreProperties.RegisterProperty[$SinixCMosCheckBPins],
wireGeometryProp: CoreProperties.RegisterProperty[$SinixCMosCheckBWireGeometry, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]],
instanceProp: CoreProperties.RegisterProperty[$SinixCMosCheckBInstance, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy]]],
cacheProp: PW.RegisterProp[$SinixCheckBCache, FALSE, TRUE],
cachePropsProp: PW.RegisterProp[$SinixCheckBCacheProps, FALSE, TRUE],
nbOfLayers: NbOfInterestingLayers,
instanceLayer: InstanceLayer,
flatNameSpace: TRUE,
equalProc: Sinix.CompareProps
]];
InterestingLayers: ARRAY [0 .. NbOfInterestingLayers) OF CD.Layer ← [CMosB.met2, CMosB.cut2, CMosB.met, CMosB.cut, CMosB.ovg, CMosB.pol, CMosB.pdif, CMosB.ndif, CMosB.pwellCont, CMosB.nwellCont];
NbOfInterestingLayers: NAT = 10;
InstanceLayer:
PROC [inst:
CD.Instance]
RETURNS [Sinix
.LayerRange] = {
layer:
CD.Layer ← CDLayers.AbstractToPaint[
IF CDSymbolicObjects.IsSymbolicOb[inst.ob]
THEN CDSymbolicObjects.GetLayer[inst]
ELSE inst.ob.layer];
FOR i:
NAT
IN [0 .. NbOfInterestingLayers)
DO
IF InterestingLayers[i]=layer
THEN
RETURN [[i, i]];
ENDLOOP;
RETURN [[0, NbOfInterestingLayers-1]];
};
CheckBPin: Sinix.ExtractProc = {
wire: Wire;
instance: CD.Instance ← PWPins.NewInstance[ob: obj, properties: properties];
layer: CD.Layer ← CDSymbolicObjects.GetLayer[instance];
name: ROPE ← CDSymbolicObjects.GetName[instance];
IF IsWellLayer[layer] OR layer=CD.commentLayer THEN RETURN [NIL];
wire ← CoreOps.CreateWire[];
CheckAddRect[mode, wire, CDBasics.RectAt[[0, 0], obj.size], CDLayers.AbstractToPaint[layer]]; -- CDLayers.AbstractToPaint important to not create geometry bigger than pin
[] ← CoreOps.SetShortWireName[wire, name];
AddNamesToWire[wire, properties];
result ← wire;
};
Special CheckAddRect and Rectangles
nbOfCheckedLayers: NAT = 8;
checkedLayers: ARRAY [0 .. nbOfCheckedLayers) OF CD.Layer ← [CMosB.met, CMosB.met2, CMosB.pol, CMosB.ndif, CMosB.pdif, CMosB.cut, CMosB.cut2, CMosB.ovg];
MaxClipDistance:
PROC
RETURNS [max:
INT ← 0] = {
FOR i:
NAT
IN [0 .. nbOfCheckedLayers)
DO
FOR j:
NAT
IN [i .. nbOfCheckedLayers)
DO
max ← MAX [max, CDSimpleRules.MinDist[checkedLayers[i], checkedLayers[j]]];
ENDLOOP;
ENDLOOP;
};
CheckTouchRect: Sinix.TouchProc = {
RETURN [CheckTouchRectObject[mode, instance2, CDInstances.InstRectO[instance1], instance1.ob.layer]];
};
CheckTouchRectObject:
PROC [mode: Sinix.Mode, instance:
CD.Instance, rect:
CD.Rect, layer:
CD.Layer]
RETURNS [yes:
BOOL ←
FALSE] = {
rectInstance: CD.Instance;
IF instance.ob.class=CDRects.bareRectClass
THEN {
minDist: INT ← CDSimpleRules.MinDist[CDLayers.AbstractToPaint[layer], CDLayers.AbstractToPaint[instance.ob.layer]];
IF minDist=0 THEN RETURN [CDLayers.AbstractToPaint[instance.ob.layer]=CDLayers.AbstractToPaint[layer]];
RETURN [CDBasics.Intersect[CDBasics.Extend[CDInstances.InstRectO[instance], minDist-1], rect]];
};
rectInstance ← PWPins.NewInstance[
ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer],
location: CDBasics.BaseOfRect[rect]
];
yes ← Sinix.Touch[mode, instance, rectInstance];
};
CheckAddRect:
PROC [mode: Sinix.Mode, wire: Wire, rect:
CD.Rect, layer:
CD.Layer] = {
instance:
CD.Instance ← PWPins.NewInstance[
ob: CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer],
location: CDBasics.BaseOfRect[rect]
];
CDProperties.PutInstanceProp[instance, Sinix.touchProcProp, NEW [Sinix.TouchProc ← CheckTouchRect]];
Sinix.AddPinsProp[mode, wire, instance];
};
CheckBRect: Sinix.ExtractProc = {
wire: Wire;
IF IsWellLayer[obj.layer] OR obj.layer=CD.commentLayer THEN RETURN [NIL];
wire ← CoreOps.CreateWire[];
CheckAddRect[mode, wire, CDBasics.RectAt[[0, 0], obj.size], obj.layer];
AddNamesToWire[wire, properties];
result ← wire;
};
Transistors
New layers for transistors
nsource: CD.Layer ← MakeAbstract[CD.NewLayer[CMosB.cmosB, $CNSource], CMosB.ndif];
ndrain: CD.Layer ← MakeAbstract[CD.NewLayer[CMosB.cmosB, $CNDrain], CMosB.ndif];
psource: CD.Layer ← MakeAbstract[CD.NewLayer[CMosB.cmosB, $CPSource], CMosB.pdif];
pdrain: CD.Layer ← MakeAbstract[CD.NewLayer[CMosB.cmosB, $CPDrain], CMosB.pdif];
CheckBTransistor: Sinix.ExtractProc = {
cellType: CellType;
lambda: CD.Number = CMosB.lambda;
ext: CD.Number = 2*lambda;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
dif: CD.Layer ← IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN CMosB.pdif ELSE CMosB.ndif;
gateWire, sourceWire, drainWire: Wire;
IF obj.layer=CMosB.wpdif
OR obj.layer=CMosB.wndif
THEN {
wellSurr ← CMosB.wellSurround;
innerX ← CMosB.wellSurround-ext;
};
cellType ← CoreClasses.CreateTransistor[[IF dif=CMosB.pdif THEN pE ELSE nE]];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
CheckAddRect[mode, sourceWire,
[x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: wellSurr, y2: ext+wellSurr],
IF dif=CMosB.pdif THEN psource ELSE nsource];
CheckAddRect[mode, drainWire,
[x1: innerX+ext, x2: obj.size.x-ext-innerX, y1: obj.size.y-wellSurr-ext, y2: obj.size.y-wellSurr],
IF dif=CMosB.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
CMosB.ndif => {};
CMosB.pdif => {};
CMosB.pol => CheckAddRect[mode, gateWire, rect, CMosB.pol];
CMosB.nwell, CMosB.pwell => {};
ENDCASE => ERROR;
ENDLOOP;
result ← cellType;
};
CheckBTransistorL: Sinix.ExtractProc = {
cellType: CellType;
lambda: CD.Number = CMosB.lambda;
wellSurround: CD.Number = CMosB.wellSurround;
ext: CD.Number = 2*lambda;
wellSurr: CD.Number ← 0;
innerX: CD.Number ← 0;
gateWire, sourceWire, drainWire: Wire;
dif: CD.Layer ← IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN CMosB.pdif ELSE CMosB.ndif;
cellType ← CoreClasses.CreateTransistor[[IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN pE ELSE nE]];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
IF obj.layer=CMosB.wpdif
OR obj.layer=CMosB.wndif
THEN {
wellSurr ← wellSurround;
innerX ← wellSurround-ext;
};
source is the smallest diff
CheckAddRect[mode, sourceWire,
[x1: innerX+ext, x2: obj.size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: wellSurr+8*lambda],
IF dif=CMosB.pdif THEN psource ELSE nsource];
CheckAddRect[mode, sourceWire,
[x1: obj.size.x-wellSurr-8*lambda, x2: obj.size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: obj.size.y-innerX-ext],
IF dif=CMosB.pdif THEN psource ELSE nsource];
CheckAddRect[mode, drainWire,
[x1: innerX+ext, x2: obj.size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
CheckAddRect[mode, drainWire,
[x1: obj.size.x-wellSurr-2*lambda, x2: obj.size.x-wellSurr, y1: wellSurr, y2: obj.size.y-innerX-ext],
IF dif=CMosB.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
CMosB.pol => CheckAddRect[mode, gateWire, rect, CMosB.pol];
CMosB.ndif => {};
CMosB.pdif => {};
CMosB.nwell, CMosB.pwell => {};
ENDCASE => ERROR;
ENDLOOP;
result ← cellType;
};
Initialization
CheckBContextCreator: SinixHighlight.ExtractContextCreator = {
context ← NEW [SinixHighlight.ExtractContextRec ← [mode: checkBMode, userData: NIL]];
};
Atomic:
PROC [className:
ATOM, extractProc:
ATOM ← $CheckBAtomicWell] = {
class: CD.ObjectClass = CD.FetchObjectClass[className, CMosB.cmosB];
CDProperties.PutProp[class, checkBMode.extractProcProp, extractProc];
};
checkBMode.clipDistance ← MaxClipDistance[];
Highlight for this technology
SinixHighlight.RegisterHighlightCommand[CMosB.cmosB, CheckBContextCreator, "Highlight net for CheckB", $HighlightNetForCheckB];
SinixHighlight.RegisterExtractCommand[CMosB.cmosB, CheckBContextCreator, "Extract for CheckB", $ExtractForCheckB];
Registering extract procs
Sinix.RegisterExtractProc[$CheckBPin, CheckBPin];
Sinix.RegisterExtractProc[$CheckBRect, CheckBRect];
Sinix.RegisterExtractProc[$CheckBAtomicWell, CheckBAtomicWell];
Sinix.RegisterExtractProc[$CheckBWellDiff, CheckBWellDiff];
Sinix.RegisterExtractProc[$CheckBTransistor, CheckBTransistor];
Sinix.RegisterExtractProc[$CheckBTransistorL, CheckBTransistorL];
Cells, Pins, Indirect
CDProperties.PutProp[CDCells.cellClass, checkBMode.extractProcProp, $ExtractCell];
CDProperties.PutProp[CDSymbolicObjects.pinClass, checkBMode.extractProcProp, $CheckBPin];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, checkBMode.extractProcProp, $CheckBPin];
CDProperties.PutProp[CDSymbolicObjects.markClass, checkBMode.extractProcProp, $CheckBPin];
CDProperties.PutProp[PWObjects.abutXClass, checkBMode.extractProcProp, $ExtractAbut];
CDProperties.PutProp[PWObjects.abutYClass, checkBMode.extractProcProp, $ExtractAbut];
Rectangles
CDProperties.PutProp[CDRects.bareRectClass, checkBMode.extractProcProp, $CheckBRect];
Contacts
Atomic[className: $C2SimpleCon];
Atomic[className: $C2WellSimpleCon];
Atomic[className: $C2LargeSimpleCon];
Atomic[className: $C2LargeWellSimpleCon];
Atomic[className: $C2DifShortCon];
Atomic[className: $C2WellDifShortCon];
Atomic[className: $C2Via];
Atomic[className: $C2LargeVia];
Diffusion wires
Atomic[className: $C2PDifRect, extractProc: $CheckBWellDiff];
Atomic[className: $C2NDifRect, extractProc: $CheckBWellDiff];
Transistors
CDProperties.PutProp[CD.FetchObjectClass[$C2Trans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistor];
CDProperties.PutProp[CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistor];
Angle Transistors
CDProperties.PutProp[CD.FetchObjectClass[$C2LTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistorL];
In the future, replace CLWellTrans by C2LWellTrans
CDProperties.PutProp[CD.FetchObjectClass[$C2LWellTrans, CMosB.cmosB], checkBMode.extractProcProp, $CheckBTransistorL];
Texts
CDProperties.PutProp[CDTexts.textClass, checkBMode.extractProcProp, $ExtractNull];
END.