SinixCMosB.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet January 20, 1986 6:24:09 pm PST
Bertrand Serlet March 18, 1987 3:27:57 am PST
Jean-Marc Frailong July 1, 1986 1:38:00 pm PDT
DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDCommandOps, CDDirectory, CDLayers, CDOps, CDProperties, CDRects, CDSequencer, CDSymbolicObjects, CDTexts,
CMosB,
Core, CoreClasses, CoreOps, CoreProperties,
CoreGeometry, CoreGeometryBackdoor,
PWObjects,
Rope,
Sinix, SinixOps;
SinixCMosB: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDCells, CDCommandOps, CDDirectory, CDLayers, CDOps, CDProperties, CDRects, CDSymbolicObjects, CDTexts, CMosB, CoreClasses, CoreGeometry, CoreGeometryBackdoor, CoreOps, CoreProperties, PWObjects, Rope, Sinix, SinixOps
SHARES CDCells, CDLayers, CDRects, CDSymbolicObjects, CDTexts =
BEGIN
As ever
CellType: TYPE = Core.CellType;
Wire: TYPE = Core.Wire;
Object: TYPE = CD.Object;
Properties: TYPE = Core.Properties;
Instance: TYPE = CoreGeometry.Instance;
ROPE: TYPE = Core.ROPE;
ROPES: TYPE = LIST OF ROPE;
Properties and extraction of common objects
mode: Sinix.Mode ← NEW [Sinix.ModeRec ← [
extractProcProp: PWObjects.RegisterProp[$CMosBExtractProc, TRUE],
decoration: CoreGeometry.CreateDecoration["CMosB"],
nbOfLayers: nbOfInterestingLayers,
instanceLayer: InstanceLayer,
touchProc: CoreGeometry.Touch,
equalProc: Sinix.CompareProps
]];
nbOfInterestingLayers: NAT = 10;
defaultLayerRange: Sinix.LayerRange = [min: 0, max: nbOfInterestingLayers-1];
InterestingLayersArray: TYPE = PACKED ARRAY CD.Layer OF Sinix.LayerRange ← ALL [defaultLayerRange];
interestingLayers: REF InterestingLayersArray;
InstanceLayer: PROC [inst: Instance] RETURNS [layerRange: Sinix.LayerRange] = {
EachInstance: CoreGeometry.EachInstanceProc = {
thisLayerRange: Sinix.LayerRange ← InstanceLayer[instance];
layerRange ← [min: MIN [thisLayerRange.min, layerRange.min], max: MAX [thisLayerRange.max, layerRange.max]];
IF layerRange=defaultLayerRange THEN quit ← TRUE;
};
SELECT TRUE FROM
inst.obj.class=CDRects.bareRectClass  => layerRange ← interestingLayers[CDLayers.AbstractToPaint[inst.obj.layer]];
CDSymbolicObjects.IsSymbolicOb[inst.obj] => layerRange ← interestingLayers[CDLayers.AbstractToPaint[CDSymbolicObjects.GetLayer[CoreGeometry.CoreGeometryPinToCDPin[inst]]]];
ENDCASE  => {
layerRange ← [nbOfInterestingLayers-1, 0];
[] ← CoreGeometry.FlattenInstance[inst, EachInstance];
IF layerRange.min>layerRange.max THEN layerRange ← defaultLayerRange;
};
};
ExtractRect: Sinix.ExtractProc = {
RETURN (IF obj.layer=CMosB.pwell OR obj.layer=CMosB.nwell THEN Sinix.ExtractNull ELSE Sinix.ExtractRect)[obj, mode, properties, userData];
};
AddRect: PROC [mode: Sinix.Mode, wire: Wire, rect: CD.Rect, layer: CD.Layer] = {
instance: Instance ← [
CDRects.CreateRect[CDBasics.SizeOfRect[rect], layer], [CDBasics.BaseOfRect[rect]]
];
CoreGeometry.PutPins[mode.decoration, wire, CONS [instance, CoreGeometry.GetPins[mode.decoration, wire]]];
};
Transistors
PropsFromSatellites: PROC [obj: Object, properties: CD.PropList] RETURNS [props: Core.Properties ← NIL] = {
name: ROPENIL;
FOR ropes: ROPESNARROW [CDProperties.GetListProp[properties, Sinix.satellitesProp]], ropes.rest WHILE ropes#NIL DO
IF name#NIL AND NOT Rope.Equal[ropes.first, name] THEN SIGNAL Sinix.FusionPropMismatch[CDDirectory.Name[obj], CoreOps.nameProp, name, ropes.first];
name ← ropes.first;
ENDLOOP;
IF name#NIL THEN props ← CoreProperties.Props[[CoreOps.nameProp, name]];
};
MakeAbstract: PROC [abstract, represents: CD.Layer] RETURNS [sameAbstract: CD.Layer] = {
CDLayers.MakeAbstract[abstract, represents]; RETURN [abstract];
};
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];
ExtractTransistor: Sinix.ExtractProc = {
size: CD.Position = CDBasics.SizeOfRect[obj.bbox];
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[[
type: IF dif=CMosB.pdif THEN pE ELSE nE,
length: (size.y-2*ext-2*wellSurr)/lambda-2,
width: (size.x-2*ext-2*innerX)/lambda]];
props ← PropsFromSatellites[obj, properties];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN {
AddRect[mode, sourceWire,
[x1: ext, x2: size.x-2*CMosB.wellSurround+ext, y1: 0, y2: ext],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: ext, x2: size.x-2*CMosB.wellSurround+ext, y1: size.y-2*CMosB.wellSurround-ext, y2: size.y-2*CMosB.wellSurround],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
} ELSE {
AddRect[mode, sourceWire,
[x1: ext, x2: size.x-ext, y1: 0, y2: ext],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: ext, x2: size.x-ext, y1: size.y-ext, y2: size.y],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
};
FOR rList: CDAtomicObjects.DrawList ← NARROW [obj.specific, CDAtomicObjects.AtomicObsSpecific].rList, rList.rest WHILE rList#NIL DO
rect: CD.Rect ← rList.first.r;
layer: CD.Layer ← rList.first.layer;
SELECT layer FROM
CMosB.ndif      => {};
CMosB.pdif      => {};
CMosB.pol      => AddRect[mode, gateWire, rect, CMosB.pol];
CMosB.nwell, CMosB.pwell => {};
ENDCASE       => ERROR;
ENDLOOP;
CoreGeometry.PutObject[mode.decoration, cellType, obj];
result ← cellType;
};
ExtractTransistorL: Sinix.ExtractProc = {
size: CD.Position = CDBasics.SizeOfRect[obj.bbox];
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;
IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN {
wellSurr ← wellSurround;
innerX ← wellSurround-ext;
};
cellType ← CoreClasses.CreateTransistor[[
type: IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.pdif THEN pE ELSE nE,
length: 2,
width: (size.x+size.y-2*innerX-2*wellSurr)/lambda - 12]];
props ← PropsFromSatellites[obj, properties];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
source is the smallest diff
IF obj.layer=CMosB.wpdif OR obj.layer=CMosB.wndif THEN {
AddRect[mode, sourceWire,
[x1: ext, x2: size.x-wellSurr-9*lambda, y1: 6*lambda, y2: 8*lambda],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, sourceWire,
[x1: size.x-wellSurr-11*lambda, x2: size.x-wellSurr-9*lambda, y1: 6*lambda, y2: size.y-innerX-ext-wellSurr],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: ext, x2: size.x-wellSurr-3*lambda, y1: 0, y2: 2*lambda],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
AddRect[mode, drainWire,
[x1: size.x-wellSurr-5*lambda, x2: size.x-wellSurr-3*lambda, y1: 0, y2: size.y-innerX-ext-wellSurr],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
} ELSE {
AddRect[mode, sourceWire,
[x1: innerX+ext, x2: size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: wellSurr+8*lambda],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, sourceWire,
[x1: size.x-wellSurr-8*lambda, x2: size.x-wellSurr-6*lambda, y1: wellSurr+6*lambda, y2: size.y-innerX-ext],
IF dif=CMosB.pdif THEN psource ELSE nsource];
AddRect[mode, drainWire,
[x1: innerX+ext, x2: size.x-wellSurr, y1: wellSurr, y2: wellSurr+2*lambda],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
AddRect[mode, drainWire,
[x1: size.x-wellSurr-2*lambda, x2: size.x-wellSurr, y1: wellSurr, y2: size.y-innerX-ext],
IF dif=CMosB.pdif THEN pdrain ELSE ndrain];
};
FOR rList: CDAtomicObjects.DrawList ← NARROW [obj.specific, CDAtomicObjects.AtomicObsSpecific].rList, rList.rest WHILE rList#NIL DO
rect: CD.Rect ← rList.first.r;
layer: CD.Layer ← rList.first.layer;
SELECT layer FROM
CMosB.pol      => AddRect[mode, gateWire, rect, CMosB.pol];
CMosB.ndif      => {};
CMosB.pdif      => {};
CMosB.nwell, CMosB.pwell => {};
ENDCASE       => ERROR;
ENDLOOP;
CoreGeometry.PutObject[mode.decoration, cellType, obj];
result ← cellType;
};
Initialization
Atomic: PROC [className: ATOM] = {
class: CD.ObjectClass = CD.FetchObjectClass[className, CMosB.cmosB];
CDProperties.PutProp[class, mode.extractProcProp, $ExtractAtomic];
};
MakeCMosBShell: PROC [comm: CDSequencer.Command] = {
inst: CD.Instance = CDOps.TheInstance[comm.design, "*** Select one instance!\n"];
IF inst=NIL THEN RETURN;
CDOps.IncludeObjectI[comm.design, CoreGeometry.CreateShell[mode.decoration, NARROW [SinixOps.ExtractCDInstance[inst, comm.design, mode].result], TRUE], comm.pos];
};
FilterMask: SinixOps.FilterProc = {RETURN [Rope.Match["*.mask", name]]};
Layers
interestingLayers ← NEW [InterestingLayersArray];
interestingLayers[CMosB.met2] ← [0, 0];
interestingLayers[CMosB.met] ← [1, 1];
interestingLayers[CMosB.pol] ← [2, 2];
interestingLayers[CMosB.pdif] ← [3, 3];
interestingLayers[CMosB.ndif] ← [4, 4];
interestingLayers[CMosB.pwell] ← [5, 5];
interestingLayers[CMosB.nwell] ← [6, 6];
interestingLayers[CMosB.ovg] ← [7, 7];
interestingLayers[CMosB.pwellCont] ← [8, 8];
interestingLayers[CMosB.nwellCont] ← [9, 9];
interestingLayers[CMosB.cut2] ← [0, 1];
interestingLayers[CMosB.cut] ← [1, 4];
Command to see the shell
CDCommandOps.RegisterWithMenu[$Debug, "Make CMosB shell", "Make a shell from the extracted object", $MakeCMosBShell, MakeCMosBShell, doQueue];
Well properties
CDProperties.PutLayerProp[CMosB.pwell, $Well, $PWell];
CDProperties.PutLayerProp[CMosB.nwell, $Well, $NWell];
CDProperties.PutLayerProp[CMosB.ndif, $RoutingLayer, $RoutingLayer];
CDProperties.PutLayerProp[CMosB.pdif, $RoutingLayer, $RoutingLayer];
CDProperties.PutLayerProp[CMosB.pol, $RoutingLayer, $RoutingLayer];
CDProperties.PutLayerProp[CMosB.met, $RoutingLayer, $RoutingLayer];
CDProperties.PutLayerProp[CMosB.met2, $RoutingLayer, $RoutingLayer];
CDProperties.PutLayerProp[CMosB.ovg, $RoutingLayer, $RoutingLayer];
Highlight and background extraction for this technology
SinixOps.RegisterDefaultLayoutMode[mode, CMosB.cmosB];
SinixOps.RegisterBackgroundExtractionCommand[CMosB.cmosB, mode, "CMosB background extraction", $CMosBBackgroundExtract, FilterMask];
Registering extract procs
Sinix.RegisterExtractProc[$CMosBExtractRect, ExtractRect];
Sinix.RegisterExtractProc[$CMosBExtractTransistor, ExtractTransistor];
Sinix.RegisterExtractProc[$CMosBExtractTransistorL, ExtractTransistorL];
Cells, Abuts, RoutingClass
CDProperties.PutProp[CDCells.pCellClass, mode.extractProcProp, $ExtractCell];
CDProperties.PutProp[PWObjects.abutXClass, mode.extractProcProp, $ExtractAbut];
CDProperties.PutProp[PWObjects.abutYClass, mode.extractProcProp, $ExtractAbut];
CDProperties.PutProp[PWObjects.routingClass, mode.extractProcProp, $ExtractRouting];
Pins
CDProperties.PutProp[CDSymbolicObjects.pinClass, mode.extractProcProp, $ExtractPin];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, mode.extractProcProp, $ExtractPin];
CDProperties.PutProp[CDSymbolicObjects.markClass, mode.extractProcProp, $ExtractPin];
Rectangles
CDProperties.PutProp[CDRects.bareRectClass, mode.extractProcProp, $CMosBExtractRect];
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];
Atomic[className: $C2NDifRect];
Transistors
CDProperties.PutProp[CD.FetchObjectClass[$C2Trans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistor];
CDProperties.PutProp[CD.FetchObjectClass[$C2WellTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistor];
Angle Transistors
CDProperties.PutProp[CD.FetchObjectClass[$C2LTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistorL];
CDProperties.PutProp[CD.FetchObjectClass[$C2LWellTrans, CMosB.cmosB], mode.extractProcProp, $CMosBExtractTransistorL];
Texts
CDProperties.PutProp[CDTexts.rigidTextClass, mode.extractProcProp, $ExtractNull];
CDProperties.PutProp[CDTexts.flipTextClass, mode.extractProcProp, $ExtractNull];
CoreGeometryBackdoor.RegisterDecorationIO[mode.decoration];
END.