SinixNMosExtract.mesa
Copyright © 1985 by Xerox Corporation. All rights reversed.
Created by Bertrand Serlet January 20, 1986 6:24:09 pm PST
Bertrand Serlet June 1, 1986 2:46:52 pm PDT
Jean-Marc Frailong May 29, 1986 5:02:27 pm PDT
DIRECTORY
CD, CDAtomicObjects, CDBasics, CDCells, CDInstances, CDLayers, CDProperties, CDOrient, CDRects, CDSatellites, CDSymbolicObjects, CDTexts,
NMos, NMosContacts, NMosTransistors,
Core, CoreClasses, CoreOps, CoreProperties,
PW, PWObjects, PWPins,
Rope,
Sinix, SinixNMos, SinixHighlight;
SinixNMosExtract: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDCells, CDInstances, CDLayers, CDOrient, CDProperties, CDRects, CDSatellites, CDSymbolicObjects, CDTexts, NMos, CoreClasses, CoreOps, CoreProperties, PW, PWObjects, PWPins, Rope, Sinix, SinixHighlight
EXPORTS SinixNMos
SHARES CDCells, CDLayers, CDRects, CDSymbolicObjects, CDTexts =
BEGIN OPEN SinixNMos;
Properties and extraction of common objects
specialcontact: ATOM = PW.RegisterProp[$SinixNMosHandcraftedContact, TRUE, FALSE];
flattenProcProp: ATOM = PW.RegisterProp[$SinixNMosFlatten, TRUE, TRUE];
extractMode: PUBLIC Sinix.Mode ← NEW [Sinix.ModeRec ← [
name: "NMos",
extractProcProp: PW.RegisterProp[$SinixNMosExtractProc, TRUE, TRUE],
pinsProp: CoreProperties.RegisterProperty[$SinixNMosPins, CoreProperties.Props[[CoreProperties.propPrint, CoreProperties.PropDontPrint]]],
wireGeometryProp: CoreProperties.RegisterProperty[$SinixNMosWireGeometry, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy], [CoreProperties.propPrint, CoreProperties.PropDontPrint]]],
instanceProp: CoreProperties.RegisterProperty[$SinixNMosInstance, CoreProperties.Props[[CoreProperties.propCopy, CoreProperties.PropDoCopy], [CoreProperties.propPrint, CoreProperties.PropDontPrint]]],
nbOfLayers: NbOfInterestingLayers,
instanceLayer: InstanceLayer,
cacheProp: PW.RegisterProp[$SinixNMosCache, FALSE, TRUE],
cachePropsProp: PW.RegisterProp[$SinixNMosCacheProps, FALSE, TRUE],
flatNameSpace: TRUE,
equalProc: Sinix.CompareProps
]];
InterestingLayers: ARRAY [0 .. NbOfInterestingLayers) OF CD.Layer ← [NMos.dif, NMos.pol, NMos.met, NMos.met2, NMos.cut, NMos.cut2, NMos.imp, NMos.imp0, NMos.impWeak, NMos.ovg, NMos.bur];
NbOfInterestingLayers: NAT = 11;
lambda: CD.Number = NMos.lambda;
Utilities (should be common with SinixCMos)
InstanceLayer: PROC [inst: CD.Instance] RETURNS [Sinix.LayerRange] = {
FOR i: NAT IN [0 .. NbOfInterestingLayers) DO
IF InterestingLayers[i]=CDLayers.AbstractToPaint[inst.ob.layer] THEN RETURN [[i, i]];
ENDLOOP;
RETURN [[0, NbOfInterestingLayers-1]];
};
AddNamesToWire: PROC [wire: Wire, properties: CD.PropList] = {
FOR ropes: LIST OF ROPE ← CDSatellites.GetSatelliteRopes[properties], ropes.rest WHILE ropes#NIL DO
IF CoreOps.GetShortWireName[wire]#NIL AND ~Rope.Equal[CoreOps.GetShortWireName[wire], ropes.first] THEN ERROR; -- two names for the same wire
[] ← CoreOps.SetShortWireName[wire, ropes.first];
ENDLOOP;
};
AddRectList: PROC [mode: Sinix.Mode, wire: Wire, list: CDAtomicObjects.DrawList] = {
WHILE list#NIL DO
instance: CD.Instance ← PWPins.NewInstance[
ob: CDRects.CreateRect[CDBasics.SizeOfRect[list.first.r], list.first.lev],
location: CDBasics.BaseOfRect[list.first.r]
];
Sinix.AddWireGeometryProp[mode, wire, instance];
Sinix.AddPinsProp[mode, wire, instance];
list ← list.rest;
ENDLOOP;
};
MakeAbstract: PROC [abstract, represents: CD.Layer] RETURNS [sameAbstract: CD.Layer] = {
CDLayers.MakeAbstract[abstract, represents]; RETURN [abstract];
};
General extraction routines (some common with SinixCMos)
ExtractPin: Sinix.ExtractProc ~ {
IF obj.layer=CD.commentLayer THEN RETURN [NIL];
[result] ← Sinix.ExtractPin[obj, mode, properties, userData];
AddNamesToWire[NARROW [result], properties];
};
ExtractRect: Sinix.ExtractProc ~ {
IF obj.layer=CD.commentLayer THEN RETURN [NIL];
[result] ← Sinix.ExtractWire[obj, mode, properties, userData];
AddNamesToWire[NARROW [result], properties];
};
ExtractCell: Sinix.ExtractProc ~ {
[result] ← (IF CDProperties.GetObjectProp[obj, specialcontact]#NIL THEN ExtractContact ELSE Sinix.ExtractCell)[obj, mode, properties, userData];
};
ExtractContact: Sinix.ExtractProc ~ {
flatten: REF AtomicFlattenProc ← NARROW [CDProperties.GetProp[from: obj.class, prop: flattenProcProp]];
wire: Wire ← CoreOps.CreateWire[];
AddRectList[mode, wire, flatten[obj]];
AddNamesToWire[wire, properties];
result ← wire;
};
TouchContact: Sinix.TouchProc ~ {
flatten: REF AtomicFlattenProc ← NARROW [CDProperties.GetProp[from: instance1.ob.class, prop: flattenProcProp]];
FOR rList: CDAtomicObjects.DrawList ← flatten [instance1.ob], rList.rest WHILE rList#NIL DO
IF Sinix.TouchRectObject[mode, instance2, CDOrient.MapRect[rList.first.r, instance1.ob.size, instance1.orientation, instance1.location], rList.first.lev] THEN RETURN [TRUE];
ENDLOOP;
};
ExtractTransistor: Sinix.ExtractProc ~ {
cellType: CellType;
gateWire, sourceWire, drainWire: Wire;
sList, dList, gList, xList: CDAtomicObjects.DrawList;
flatten: REF TransistorFlattenProc ← NARROW [CDProperties.GetProp[from: obj.class, prop: flattenProcProp]];
cellType ← CoreClasses.CreateTransistor[[nE]];
gateWire ← cellType.public[0];
sourceWire ← cellType.public[1];
drainWire ← cellType.public[2];
[sList, dList, gList, xList] ← flatten[obj];
AddRectList[mode, sourceWire, sList];
AddRectList[mode, drainWire, dList];
AddRectList[mode, gateWire, gList];
result ← cellType;
};
Contacts
Manage diffusion/poly contacts
DifPolContact: AtomicFlattenProc = {
difpolRimWidth: CD.Number = lambda;
r: CD.Rect = [x1: 0, y1: 0, x2: obj.size.x, y2: obj.size.y];
rList ← CONS[[r, NMos.met], rList];
rList ← CONS[[r, obj.layer], rList];
rList ← CONS[[CDBasics.Extend[r, -difpolRimWidth], NMos.cut], rList];
};
Manage metal-metal contacts
MmContact: AtomicFlattenProc = {
cut2min: CD.Number = 3*lambda;
mmRimWidth: CD.Number = lambda;
mins: CD.Number = cut2min+2*mmRimWidth; -- use old technology for big contacts
r: CD.Rect = [x1: 0, y1: 0, x2: obj.size.x, y2: obj.size.y];
rList ← CONS[[r, NMos.met], rList];
rList ← CONS[[r, NMos.met2], rList];
rList ← CONS[[CDBasics.Extend[r, IF obj.size.x>mins THEN -2*lambda ELSE -mmRimWidth], NMos.cut2], rList];
};
Manage burried contacts
BurriedContact: AtomicFlattenProc = {
class: NMosContacts.ContactPtr = NARROW[obj.specificRef];
dBur: CD.Number = lambda/2;
burAct: CD.Number = lambda*2;
diffBur: CD.Position = [
x: IF class.wExt<burAct THEN MAX[class.wExt+lambda, burAct] ELSE class.wExt-lambda,
y: IF class.lExt<burAct THEN MAX[class.lExt+lambda, burAct] ELSE class.lExt-lambda
];
rList ← CONS[[[x1: dBur, x2: obj.size.x-dBur, y1: dBur, y2: obj.size.y-dBur], NMos.bur], rList];
rList ← CONS[[[x1: burAct, x2: obj.size.x-class.wExt, y1: class.lExt, y2: obj.size.y-class.lExt], NMos.pol], rList];
rList ← CONS[[[x1: lambda, x2: obj.size.x-diffBur.x, y1: diffBur.y, y2: obj.size.y-diffBur.y], obj.layer], rList];
};
Manage butting contacts
ButtingContact: AtomicFlattenProc = {
butConSX: CD.Number = 4*lambda;
butConSY: CD.Number = 6*lambda;
butContactPolyYS: CD.Number = 3*lambda;
butContactDiffY: CD.Number = butContactPolyYS-lambda;
butContactRimWidth: CD.Number = lambda;
rList ← CONS[[[x1: 0, x2: butConSX, y1: 0, y2: butContactPolyYS], NMos.pol], rList];
rList ← CONS[[[x1: 0, x2: butConSX, y1: butContactDiffY, y2: butConSY], NMos.dif], rList];
rList ← CONS[[[x1: 0, x2: butConSX, y1: 0, y2: butConSY], NMos.met], rList];
rList ← CONS[[[x1: butContactRimWidth, x2: butConSX-butContactRimWidth, y1: butContactRimWidth, y2: butConSY-butContactRimWidth],
NMos.cut], rList];
};
Manage handcrafted contacts
HandCraftedContact: AtomicFlattenProc = {
data: CD.CellPtr ← NARROW [obj.specificRef];
FOR list: CD.InstanceList ← data.contents, list.rest WHILE list#NIL DO
IF list.first.ob.class#CDRects.bareRectClass THEN ERROR;
rList ← CONS [[CDInstances.InstRectO[list.first], list.first.ob.layer], rList]
ENDLOOP;
};
Transistors
depletionOverlap: CD.Number = (3*lambda)/2;
New layers for transistors
source: CD.Layer ← MakeAbstract[CD.NewLayer[NMos.nmos, $NSource], NMos.dif];
drain: CD.Layer ← MakeAbstract[CD.NewLayer[NMos.nmos, $NDrain], NMos.dif];
Flatten a regular transistor
RegularTransistor: TransistorFlattenProc = {
class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef];
sList ← CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: 0, y2: class.lExt],
source], sList];
dList ← CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: class.lExt+class.length, y2: obj.size.y], drain], dList];
gList ← CONS [[[x1: 0, x2: obj.size.x, y1: class.lExt, y2: class.lExt+class.length],
NMos.pol], gList];
IF class.implant>0 THEN xList ← CONS [[
[x1: class.wExt-depletionOverlap, x2: obj.size.x-class.wExt+depletionOverlap, y1: class.lExt-depletionOverlap, y2: obj.size.y-class.lExt+depletionOverlap],
SELECT class.implant FROM
NMosTransistors.strongDepletion => NMos.imp,
NMosTransistors.weakDepletion => NMos.impWeak,
NMosTransistors.zeroTresh => NMos.imp0,
NMosTransistors.enhancement => CD.errorLayer,
ENDCASE => CD.errorLayer
], xList];
};
Flatten an angle transistor
AngleTransistor: TransistorFlattenProc = {
class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef];
ele: CD.Number = 2*class.lExt+class.length;
-- Warning: This code is absurd, but so is NMosTransistorsImpl.DrawMeForATransistors in CDNMos23. It is incorrect if ele+wExt > size (which may make sense).
-- The right code should compute the lowx/highy values for dif and go from there, not assuming the structure of the overlap. The CD graphics are wrong, and anyway it is impossible to stretch angle NMos transistors, so only one size is really available!
hPoly: CD.Rect =
[x1: 0, x2: obj.size.x-class.lExt, y1: class.lExt, y2: class.length+class.lExt]; -- horizontal
vPoly: CD.Rect =
[x1: obj.size.x-class.length-class.lExt, x2: hPoly.x2, y1: hPoly.y2, y2: obj.size.y]; -- vertical
nDrain: CD.Rect =
[x1: class.wExt, x2: obj.size.x, y1: 0, y2: hPoly.y1]; -- north
eDrain: CD.Rect =
[x1: vPoly.x2, x2: nDrain.x2, y1: nDrain.y2, y2: obj.size.y-class.wExt]; -- east
wSource: CD.Rect =
[x1: obj.size.x-ele, x2: vPoly.x1, y1: vPoly.y1, y2: eDrain.y2]; -- west
sSource: CD.Rect =
[x1: MIN[nDrain.x1, wSource.x1], x2: wSource.x1, y1: wSource.y1, y2: MIN[ele, wSource.y2]]; -- south
gList ← CONS [[hPoly, NMos.pol], gList];
gList ← CONS [[vPoly, NMos.pol], gList];
IF class.lExt>0 THEN
BEGIN
dList ← CONS [[nDrain, drain], dList];
dList ← CONS [[eDrain, drain], dList];
END;
sList ← CONS [[wSource, source], sList];
IF sSource.x1 < sSource.x2 THEN sList ← CONS [[sSource, source], sList];
IF class.implant>0 THEN BEGIN
xList ← CONS [
[[x1: nDrain.x1-depletionOverlap, x2: hPoly.x2+depletionOverlap, y1: hPoly.y1-depletionOverlap, y2: hPoly.y2+depletionOverlap],
NMos.imp], xList];
xList ← CONS [
[[x1: vPoly.x1-depletionOverlap, x2: vPoly.x2+depletionOverlap, y1: vPoly.y1-depletionOverlap, y2: eDrain.y2+depletionOverlap],
NMos.imp], xList];
END;
};
Flatten a pullup transistor
PullUp: TransistorFlattenProc = {
class: NMosTransistors.TransistorPtr = NARROW[obj.specificRef];
middleX: CD.Number = obj.size.x/2;
metal: CD.Rect =
[x1: middleX-2*lambda, y1: middleX+2*lambda, x2: middleX+2*lambda, y2: obj.size.y];
contact: CD.Rect =
[x1: metal.x1+lambda, x2: metal.x2-lambda, y1: metal.y1+lambda, y2: metal.y2-lambda];
hPoly: CD.Rect = [x1: 0, x2: obj.size.x, y1: class.lExt, y2: class.lExt+class.length];
gList ← CONS [[hPoly, NMos.pol], gList];
gList ← CONS [[contact, NMos.cut], gList];
dList ← CONS [[metal, NMos.met], dList];
dList ← CONS [[contact, NMos.cut], dList];
dList ← CONS [[[x1: metal.x1, x2: metal.x2, y1: hPoly.y2, y2: metal.y2], obj.layer], dList];
sList ← CONS [[[x1: class.wExt, x2: class.wExt+class.width, y1: 0, y2: hPoly.y1], obj.layer], sList];
xList ← CONS [[[x1: 0, x2: hPoly.x2, y1: 0, y2: obj.size.y-lambda], NMos.imp], xList];
};
Initialization
InitContact: PROC [className: ATOM, flattenProc: AtomicFlattenProc] = {
class: CD.ObjectClass = CD.FetchObjectClass[className, NMos.nmos];
CDProperties.PutProp[class, Sinix.touchProcProp, NEW [Sinix.TouchProc ← TouchContact]];
CDProperties.PutProp[class, extractMode.extractProcProp, $NMosExtractContact];
CDProperties.PutProp[class, flattenProcProp, NEW [AtomicFlattenProc ← flattenProc]];
};
InitTransistor: PROC [className: ATOM, flattenProc: TransistorFlattenProc] = {
class: CD.ObjectClass = CD.FetchObjectClass[className, NMos.nmos];
CDProperties.PutProp[class, extractMode.extractProcProp, $NMosExtractTransistor];
CDProperties.PutProp[class, flattenProcProp, NEW [TransistorFlattenProc ← flattenProc]];
};
NMosContextCreator: SinixHighlight.ExtractContextCreator ~ {
context ← NEW [SinixHighlight.ExtractContextRec ← [mode: extractMode, userData: NIL]];
};
Registering extract procs
Sinix.RegisterExtractProc[$NMosExtractPin, ExtractPin];
Sinix.RegisterExtractProc[$NMosExtractRect, ExtractRect];
Sinix.RegisterExtractProc[$NMosExtractCell, ExtractCell];
Sinix.RegisterExtractProc[$NMosExtractContact, ExtractContact];
Sinix.RegisterExtractProc[$NMosExtractTransistor, ExtractTransistor];
Cells, Abuts
CDProperties.PutProp[CDCells.cellClass, extractMode.extractProcProp, $NMosExtractCell];
CDProperties.PutProp[CDCells.cellClass, Sinix.touchProcProp, NEW [Sinix.TouchProc ← Sinix.TouchCell]];
CDProperties.PutProp[CDCells.cellClass, flattenProcProp, NEW [AtomicFlattenProc ← HandCraftedContact]];
CDProperties.PutProp[PWObjects.abutXClass, extractMode.extractProcProp, $ExtractAbut];
CDProperties.PutProp[PWObjects.abutYClass, extractMode.extractProcProp, $ExtractAbut];
Pins
CDProperties.PutProp[CDSymbolicObjects.pinClass, extractMode.extractProcProp, $NMosExtractPin];
CDProperties.PutProp[CDSymbolicObjects.pinClass, Sinix.touchProcProp, NEW [Sinix.TouchProc ← Sinix.TouchPin]];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, extractMode.extractProcProp, $NMosExtractPin];
CDProperties.PutProp[CDSymbolicObjects.segmentClass, Sinix.touchProcProp, NEW [Sinix.TouchProc ← Sinix.TouchPin]];
CDProperties.PutProp[CDSymbolicObjects.markClass, extractMode.extractProcProp, $NMosExtractPin];
CDProperties.PutProp[CDSymbolicObjects.markClass, Sinix.touchProcProp, NEW [Sinix.TouchProc ← Sinix.TouchPin]];
Rectangles
CDProperties.PutProp[CDRects.bareRectClass, extractMode.extractProcProp, $NMosExtractRect];
CDProperties.PutProp[CDRects.bareRectClass, Sinix.touchProcProp, NEW [Sinix.TouchProc ← Sinix.TouchRect]];
Contacts
InitContact[$NMosContactDifAndPol, DifPolContact];
InitContact[$NMosContactDifShort, DifShortContact];
InitContact[$NMosContactBut, ButtingContact];
InitContact[$NMosBurContact, BurriedContact];
InitContact[$NMosMmContact, MmContact];
Transistors
InitTransistor[$NMosTransistor, RegularTransistor];
InitTransistor[$NMosATransistor, AngleTransistor];
InitTransistor[$NMosPullUp, PullUp];
Texts
CDProperties.PutProp[CDTexts.textClass, extractMode.extractProcProp, $ExtractNull];
Highlight for this technology
SinixHighlight.RegisterDefaultLayoutMode[NMos.nmos, NMosContextCreator];
END.