CMosRecognizerImpl.mesa The technology dependant part of recognizing objects
Gbier, July 11, 1985 10:48:17 am PDT
Gbier, July 26, 1985 1:29:05 pm PDT
DIRECTORY
CD,
CMos,
CDInstances,
CDBasics,
CMosObjects,
Recognizer,
CornerStitching,
CDOrient;
CMosRecognizerImpl:
CEDAR
PROGRAM
IMPORTS CMos, CDInstances, CMosObjects, Recognizer, CDBasics, CDOrient =
BEGIN
RegionList: TYPE = LIST OF REF CornerStitching.Region;
ext: CD.Number = 2*CD.lambda;
cutExt: CD.Number = CD.lambda;
SingleRectInstances:
PROC [active1, active2:
CD.Layer, coveredList: RegionList, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
SELECT active1
FROM
CMos.pol =>
IF active2 = CMos.ndif
THEN
SingleRectTransistors[coveredList, active2, possibleInstListPtr]
ELSE
IF active2 = CMos.pdif
THEN
SingleRectTransistors[coveredList, active2, possibleInstListPtr];
CMos.pdif =>
IF active2 = CMos.pol
THEN
SingleRectTransistors[coveredList, active1, possibleInstListPtr];
CMos.ndif =>
IF active2 = CMos.pol
THEN
SingleRectTransistors[coveredList, active1, possibleInstListPtr];
CMos.cut =>
IF active2 = CMos.met
THEN
SingleRectCutContacts[coveredList, possibleInstListPtr];
CMos.met =>
IF active2 = CMos.cut
THEN
SingleRectCutContacts[coveredList, possibleInstListPtr];
CMos.cut2 =>
IF active2 = CMos.met2
THEN
SingleRectMmContacts[coveredList, possibleInstListPtr];
CMos.met2 =>
IF active2 = CMos.cut2
THEN
SingleRectMmContacts[coveredList, possibleInstListPtr];
ENDCASE => NULL;
END;
SingleRectTransistors:
PROC [coveredList: RegionList, difLayer:
CD.Layer, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
SingleTransistorInstances:
PROC [size1, size2, position:
CD.Position, diff:
CD.Layer, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
forbiddenLayerList: LIST OF CD.Layer ← LIST [CMos.cut, CMos.bur];
newObject: CD.Object;
newInst: CD.Instance;
newObject ← CMosObjects.CreateTransistor[size: size1, difLayer: diff];
newInst ← CDInstances.NewInstance[ob: newObject, orientation: CDOrient.original, location: position];
PlaceOnList[newInst, possibleInstListPtr, forbiddenLayerList];
newObject ← CMosObjects.CreateTransistor[size: size1, difLayer: diff];
newInst ← CDInstances.NewInstance[ob: newObject, orientation: CDOrient.rotate90, location: position];
PlaceOnList[newInst, possibleInstListPtr, forbiddenLayerList];
newObject ← CMosObjects.CreateTransistor[size: size2, difLayer: diff];
newInst ← CDInstances.NewInstance[ob: newObject, orientation: CDOrient.original, location: position];
PlaceOnList[newInst, possibleInstListPtr, forbiddenLayerList];
newObject ← CMosObjects.CreateTransistor[size: size2, difLayer: diff];
newInst ← CDInstances.NewInstance[ob: newObject, orientation: CDOrient.rotate90, location: position];
PlaceOnList[newInst, possibleInstListPtr, forbiddenLayerList];
END;
rect: CD.Rect ← coveredList.first.rect;
position: CD.Position ← CDBasics.BaseOfRect[rect];
size1, size2: CD.Position;
position ← [position.x-ext, position.y-ext];
-- ndif or pdif type transistors
size1 ← [rect.x2 - rect.x1 + 2*ext, rect.y2 - rect.y1 + 2*ext];
size2 ← [rect.y2 - rect.y1 + 2*ext, rect.x2 - rect.x1 + 2*ext];
SingleTransistorInstances[size1, size2, position, difLayer, possibleInstListPtr];
-- ORDER is important; things placed on the possible instances list will be checked LIFO;
therefore place transistors of type wndif and wpdif onto possible instances list after transistors
of type ndif and pdif
size1 ← CDBasics.SizeOfRect[CDBasics.Extend[[rect.x1, rect.y1-ext, rect.x2, rect.y2+ext], CMos.wellSurround]];
size2 ← CDOrient.OrientedSize[CDBasics.SizeOfRect[CDBasics.Extend[[rect.x1-ext, rect.y1, rect.x2+ext, rect.y2], CMos.wellSurround]], CDOrient.rotate90];
IF difLayer = CMos.pdif
THEN
SingleTransistorInstances[size1, size2, position, CMos.wpdif, possibleInstListPtr]
ELSE
SingleTransistorInstances[size1, size2, position, CMos.wndif, possibleInstListPtr];
END;
SingleRectCutContacts:
PROC [coveredList: RegionList, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
rect: CD.Rect ← coveredList.first.rect;
position: CD.Position ← CDBasics.BaseOfRect[rect];
--should a size parameter be added to the contacts then the below should do it.
size: CD.Position ← [rect.y2 - rect.y1 + 2*cutExt, rect.x2 - rect.x1 + 2*cutExt];
position ← [position.x-cutExt, position.y-cutExt];
PlaceOnList[CDInstances.NewInstance[ob: CMosObjects.CreatePolyCon[], location: position], possibleInstListPtr];
FOR diffList:
LIST
OF
CD.Layer ←
LIST[CMos.pdif, CMos.ndif, CMos.wpdif, CMos.wndif], diffList.rest
WHILE diffList #
NIL
DO
PlaceOnList[CDInstances.NewInstance[ob: CMosObjects.CreateDifCon[diffList.first], location: position], possibleInstListPtr];
FOR orient:
CD.Orientation
IN
CD.Orientation
DO
IF ~CDOrient.IncludesMirrorX[orient]
THEN {
--should a size parameter be added to the contacts then the below should do it.
orientedSize: CD.Position ← CDOrient.OrientedSize[size, orient];
PlaceOnList[CDInstances.NewInstance[ob: CMosObjects.CreateButCon[diffList.first], location: position, orientation: orient], possibleInstListPtr];
}
ENDLOOP;
ENDLOOP;
END;
SingleRectMmContacts:
PROC [coveredList: RegionList, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
rect: CD.Rect ← coveredList.first.rect;
position: CD.Position ← CDBasics.BaseOfRect[rect];
--should a size parameter be added to the contacts then the below should do it.
size: CD.Position ← [rect.y2 - rect.y1 + 2*cutExt, rect.x2 - rect.x1 + 2*cutExt];
position ← [position.x-cutExt, position.y-cutExt];
PlaceOnList[CDInstances.NewInstance[ob: CMosObjects.CreateMmCon[], location: position], possibleInstListPtr];
END;
DoubleRectInstances:
PROC [active1, active2:
CD.Layer, coveredList: RegionList, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
SELECT active1
FROM
CMos.pol =>
IF active2 = CMos.ndif
THEN
DoubleRectTransistors[coveredList, active2, possibleInstListPtr]
ELSE
IF active2 = CMos.pdif
THEN
DoubleRectTransistors[coveredList, active2, possibleInstListPtr];
CMos.pdif =>
IF active2 = CMos.pol
THEN
DoubleRectTransistors[coveredList, active1, possibleInstListPtr];
CMos.ndif =>
IF active2 = CMos.pol
THEN
DoubleRectTransistors[coveredList, active1, possibleInstListPtr];
ENDCASE => NULL;
END;
DoubleRectTransistors:
PROC [coveredList: RegionList, difLayer:
CD.Layer, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList] =
BEGIN
position: CD.Position;
size: CD.Position;
rect1: CD.Rect ← coveredList.first.rect;
rect2: CD.Rect ← coveredList.rest.first.rect;
minX: CD.Number← MIN[rect1.x1, rect2.x1];
minY: CD.Number ← MIN[rect1.y1, rect2.y1];
maxX: CD.Number ← MAX[rect1.x2, rect2.x2];
maxY: CD.Number ← MAX[rect1.y2, rect2.y2];
diffAbstractLayer: CD.Layer;
forbiddenLayerList:
LIST
OF
CD.Layer ←
LIST [CMos.cut, CMos.bur];
position ← [minX - ext, minY - ext];
size ← CDBasics.SizeOfRect[[minX-ext, minY-ext, maxX + ext, maxY + ext]];
FOR orient:
CD.Orientation
IN
CD.Orientation
DO
newObject: CD.Object ← CMosObjects.CreateAngleTransistor[size: CDOrient.OrientedSize[size, orient], difLayer: difLayer];
newInst: CD.Instance ← CDInstances.NewInstance[ob: newObject, orientation: orient, location: position];
PlaceOnList[newInst, possibleInstListPtr, forbiddenLayerList];
ENDLOOP;
-- ORDER is important; things placed on the possible instances list will be checked LIFO; therefore place transistors of type wndif and wpdif onto possible instances list after
transistors of type ndif and pdif
IF difLayer = CMos.ndif
THEN
diffAbstractLayer ← CMos.wndif
ELSE
diffAbstractLayer ← CMos.wpdif;
size ← CDBasics.SizeOfRect[CDBasics.Extend[[minX, minY-ext, maxX+ext, maxY], CMos.wellSurround]];
FOR orient:
CD.Orientation
IN
CD.Orientation
DO
newObject: CD.Object ← CMosObjects.CreateAngleTransistor[size: CDOrient.OrientedSize[size, orient], difLayer: diffAbstractLayer];
PlaceOnList[CDInstances.NewInstance[ob: newObject, orientation: orient, location: position], possibleInstListPtr, forbiddenLayerList];
ENDLOOP;
END;
PlaceOnList:
PROC [instance:
CD.Instance, possibleInstListPtr:
REF Recognizer.InstAndForbidLayerList, forbiddenLayerList:
LIST
OF
CD.Layer ←
NIL] =
--places instance on possibleInstList
BEGIN
possibleInstListPtr^ ← CONS[NEW[Recognizer.InstAndForbidLayerRec ← [instance, forbiddenLayerList]], possibleInstListPtr^];
END;
Recognizer.RegisterPossibleInstanceProc [CMos.cmos, 1, SingleRectInstances];
Recognizer.RegisterPossibleInstanceProc[CMos.cmos, 2, DoubleRectInstances];
-- if diff = ndif then transistors of type wndif and ndif will be recognized
-- if diff = pdif then transistors of type wpdif and pdif will be recognized
Recognizer.RegisterLayerList[technology: CMos.cmos, active1: CMos.ndif, active2: CMos.pol, layerList: LIST[CMos.pwell, CMos.cut, CMos.bur]];
Recognizer.RegisterLayerList[technology: CMos.cmos, active1: CMos.pdif, active2: CMos.pol, layerList: LIST[CMos.nwell, CMos.cut, CMos.bur]];
Recognizer.RegisterLayerList[technology: CMos.cmos, active1: CMos.cut, active2: CMos.met, layerList: LIST[CMos.pol, CMos.ndif, CMos.pdif, CMos.nwell, CMos.pwell]];
Recognizer.RegisterLayerList[technology: CMos.cmos, active1: CMos.cut2, active2: CMos.met2, layerList: LIST[CMos.met]];
END.