<> <> <> <> 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*CMos.lambda; cutExt: CD.Number = CMos.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;>> <> <> 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.>> <> 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.>> <> 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.>> <> 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>> <> <<>> 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.