DIRECTORY CD, CMosB, CDInstances, CDBasics, CMosBObjects, Recognizer, CStitching, CDOrient; CMosBRecognizerImpl: CEDAR PROGRAM IMPORTS CMosB, CDInstances, CMosBObjects, Recognizer, CDBasics, CDOrient = BEGIN RegionList: TYPE = LIST OF REF CStitching.Region; cutExt: CD.Number = CMosB.lambda; --metal extends cut dExt: CD.Number = 3*CMosB.lambda; --diffusion extends gate pExt: CD.Number = 2*CMosB.lambda; --poly extends gate SingleRectInstances: PROC [active1, active2: CD.Layer, coveredList: RegionList, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN SELECT active1 FROM CMosB.pol => IF active2 = CMosB.ndif THEN SingleRectTransistors[coveredList, active2, possibleInstListPtr] ELSE IF active2 = CMosB.pdif THEN SingleRectTransistors[coveredList, active2, possibleInstListPtr]; CMosB.pdif => IF active2 = CMosB.pol THEN SingleRectTransistors[coveredList, active1, possibleInstListPtr]; CMosB.ndif => IF active2 = CMosB.pol THEN SingleRectTransistors[coveredList, active1, possibleInstListPtr]; CMosB.cut => IF active2 = CMosB.met THEN SingleRectCutContacts[coveredList, possibleInstListPtr]; CMosB.met => IF active2 = CMosB.cut THEN SingleRectCutContacts[coveredList, possibleInstListPtr]; CMosB.cut2 => IF active2 = CMosB.met2 THEN SingleRectVias[coveredList, possibleInstListPtr]; CMosB.met2 => IF active2 = CMosB.cut2 THEN SingleRectVias[coveredList, possibleInstListPtr]; ENDCASE => NULL; END; SingleRectTransistors: PROC [coveredList: RegionList, difLayer: CD.Layer, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN TryTrans: PROC [size, pos: CD.Position, diff: CD.Layer, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN forbiddenList: LIST OF CD.Layer _ LIST [CMosB.cut, CMosB.bur]; ob: CD.Object; inst: CD.Instance; s, p: CD.Position; s _ [size.x+2*pExt, size.y+2*dExt]; p _ [pos.x-pExt, pos.y-dExt]; ob _ CMosBObjects.CreateTransistor[size: s, difLayer: diff]; inst _ CDInstances.NewInstI[ob: ob, orientation: CDOrient.original, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; s _ [size.y+2*pExt, size.x+2*dExt]; p _ [pos.x-dExt, pos.y-pExt]; ob _ CMosBObjects.CreateTransistor[size: s, difLayer: diff]; inst _ CDInstances.NewInstI[ob: ob, orientation: CDOrient.rotate90, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; END; rect: CD.Rect _ coveredList.first.rect; gatePos: CD.Position _ CDBasics.BaseOfRect[rect]; gateSize: CD.Position _ CDBasics.SizeOfRect[rect]; TryTrans[gateSize, gatePos, difLayer, possibleInstListPtr]; IF difLayer=CMosB.pdif THEN TryTrans[gateSize, gatePos, CMosB.wpdif, possibleInstListPtr] ELSE IF difLayer=CMosB.ndif THEN TryTrans[gateSize, gatePos, CMosB.wndif, possibleInstListPtr]; END; SingleRectCutContacts: PROC [coveredList: RegionList, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN shortExt: CD.Number = CMosB.lambda; longExt: CD.Number = 2*CMosB.lambda; rect: CD.Rect _ coveredList.first.rect; size, cutPos: CD.Position; cutPos _ CDBasics.BaseOfRect[rect]; cutPos _ [cutPos.x-shortExt, cutPos.y-shortExt]; Try[CDInstances.NewInstI[ob: CMosBObjects.CreatePolyCon[], location: cutPos], possibleInstListPtr]; FOR diffList: LIST OF CD.Layer _ LIST[CMosB.pdif, CMosB.ndif, CMosB.wpdif, CMosB.wndif], diffList.rest WHILE diffList #NIL DO Try[CDInstances.NewInstI[ob: CMosBObjects.CreateDifCon[diffList.first], location: cutPos], possibleInstListPtr]; ENDLOOP; cutPos _ CDBasics.BaseOfRect[rect]; cutPos _ [cutPos.x-longExt, cutPos.y-longExt]; size _ [rect.y2 - rect.y1 + 2*longExt, rect.x2 - rect.x1 + 2*longExt]; Try[CDInstances.NewInstI[ob: CMosBObjects.CreateLargePolyCon[size], location: cutPos], possibleInstListPtr]; FOR diffList: LIST OF CD.Layer _ LIST[CMosB.pdif, CMosB.ndif, CMosB.wpdif, CMosB.wndif], diffList.rest WHILE diffList #NIL DO Try[CDInstances.NewInstI[ob: CMosBObjects.CreateLargeDifCon[size, diffList.first], location: cutPos], possibleInstListPtr]; ENDLOOP; END; SingleRectVias: PROC [coveredList: RegionList, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN shortExt: CD.Number = CMosB.lambda; longExt: CD.Number = 2*CMosB.lambda; rect: CD.Rect _ coveredList.first.rect; size, cutPos: CD.Position; cutPos _ CDBasics.BaseOfRect[rect]; cutPos _ [cutPos.x-shortExt, cutPos.y-shortExt]; Try[CDInstances.NewInstI[ob: CMosBObjects.CreateVia[], location: cutPos], possibleInstListPtr]; cutPos _ CDBasics.BaseOfRect[rect]; size _ [rect.y2 - rect.y1 + 2*longExt, rect.x2 - rect.x1 + 2*longExt]; cutPos _ [cutPos.x-longExt, cutPos.y-longExt]; Try[CDInstances.NewInstI[ob: CMosBObjects.CreateLargeVia[size], location: cutPos], possibleInstListPtr]; END; DoubleRectInstances: PROC [active1, active2: CD.Layer, coveredList: RegionList, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN SELECT active1 FROM CMosB.pol => IF active2 = CMosB.ndif THEN DoubleRectTransistors[coveredList, active2, possibleInstListPtr] ELSE IF active2 = CMosB.pdif THEN DoubleRectTransistors[coveredList, active2, possibleInstListPtr]; CMosB.pdif => IF active2 = CMosB.pol THEN DoubleRectTransistors[coveredList, active1, possibleInstListPtr]; CMosB.ndif => IF active2 = CMosB.pol THEN DoubleRectTransistors[coveredList, active1, possibleInstListPtr]; ENDCASE => NULL; END; DoubleRectTransistors: PROC [coveredList: RegionList, difLayer: CD.Layer, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList] = BEGIN rect1: CD.Rect _ coveredList.first.rect; rect2: CD.Rect _ coveredList.rest.first.rect; sur: CD.Rect _ CDBasics.Surround[rect1, rect2]; gatePos: CD.Position _ CDBasics.BaseOfRect[sur]; size: CD.Position _ [sur.x2-sur.x1+dExt+pExt, sur.y2-sur.y1+dExt+pExt]; forbiddenList: LIST OF CD.Layer _ LIST [CMosB.cut, CMosB.bur]; DoForLayer: PROC [l: CD.Layer] = { FOR orient: CD.Orientation IN CD.Orientation DO s: CD.Position = CDOrient.OrientedSize[size, orient]; ob: CD.Object _ CMosBObjects.CreateAngleTransistor[size: s, difLayer: difLayer]; p: CD.Position; inst: CD.Instance; p _ [gatePos.x-pExt, gatePos.y-pExt]; inst _ CDInstances.NewInstI[ob: ob, orientation: orient, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-pExt, gatePos.y-dExt]; inst _ CDInstances.NewInstI[ob: ob, orientation: orient, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-dExt, gatePos.y-pExt]; inst _ CDInstances.NewInstI[ob: ob, orientation: orient, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-dExt, gatePos.y-dExt]; inst _ CDInstances.NewInstI[ob: ob, orientation: orient, location: p]; Try[inst, possibleInstListPtr, forbiddenList]; ENDLOOP; }; DoForLayer[difLayer]; IF difLayer = CMosB.ndif THEN DoForLayer[CMosB.wndif] ELSE IF difLayer = CMosB.pdif THEN DoForLayer[CMosB.wpdif] END; Try: PROC [instance: CD.Instance, possibleInstListPtr: REF Recognizer.InstAndForbidLayerList, forbiddenList: LIST OF CD.Layer _ NIL] = BEGIN possibleInstListPtr^ _ CONS[NEW[Recognizer.InstAndForbidLayerRec _ [instance, forbiddenList]], possibleInstListPtr^]; END; Recognizer.RegisterPossibleInstanceProc [CMosB.cmosB, 1, SingleRectInstances]; Recognizer.RegisterPossibleInstanceProc[CMosB.cmosB, 2, DoubleRectInstances]; Recognizer.RegisterLayerList[technology: CMosB.cmosB, active1: CMosB.ndif, active2: CMosB.pol, layerList: LIST[CMosB.pwell, CMosB.cut, CMosB.bur]]; Recognizer.RegisterLayerList[technology: CMosB.cmosB, active1: CMosB.pdif, active2: CMosB.pol, layerList: LIST[CMosB.nwell, CMosB.cut, CMosB.bur]]; Recognizer.RegisterLayerList[technology: CMosB.cmosB, active1: CMosB.cut, active2: CMosB.met, layerList: LIST[CMosB.pol, CMosB.ndif, CMosB.pdif, CMosB.nwell, CMosB.pwell]]; Recognizer.RegisterLayerList[technology: CMosB.cmosB, active1: CMosB.cut2, active2: CMosB.met2, layerList: LIST[CMosB.met]]; END. ¬CMosBRecognizerImpl.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 Jacobi, March 19, 1986 6:40:13 pm PST --size pos of gate! not object --bare diffusion --well diffusion -- 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 -- ORDER!!!! --places instance on possibleInstList -- 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 ΚS˜codešœN™NKšœ$™$Kšœ#™#K™%—K˜šΟk ˜ Kšœ˜Kšœ˜K˜ K˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ ˜ —K˜šΟbœœ˜"KšœD˜K—Kš˜K˜Kš œ œœœœ˜1K˜KšœœΟc˜6J˜JšœœŸ˜;JšœœŸ˜6K˜šΠbnœœœ6œ&˜ŽKš˜šœ ˜šœ ˜ šœœ˜K˜@—š˜šœ˜K˜A———šœ˜šœ˜K˜A——šœ ˜ šœ˜K˜A——šœ ˜ šœ˜K˜8——šœ ˜ šœ˜K˜8——šœ ˜ šœ˜K˜1——šœ ˜ šœ˜K˜1——Kšœœ˜—Kšœ˜—K˜š œœ%œœ%˜‡Kš˜K˜š  œœ œœœ%˜uK™Kš˜Kš œœœœ œ˜>Kšœœ˜Kšœœ ˜Kšœœ ˜K˜Kšœ#˜#Kšœ˜Kšœ<˜˜>—K˜Kšœ˜—K˜š œœ0œ%˜sKš˜Kšœ œ˜#Kšœ œ˜$Kšœœ˜'Kšœœ ˜K™Kšœ#˜#Kšœ0˜0Kšœc˜cšœ œœœ œBœ œ˜}Kšœp˜pKšœ˜—K˜Kšœ#˜#Kšœ.˜.KšœF˜FKšœl˜lšœ œœœ œBœ œ˜}Kšœ{˜{Kšœ˜—K˜Kšœ˜—š œœ0œ%˜lKš˜Kšœ œ˜#Kšœ œ˜$Kšœœ˜'Kšœœ ˜K˜Kšœ#˜#Kšœ0˜0Kšœ_˜_K˜Kšœ#˜#KšœF˜FKšœ.˜.Kšœh˜hKšœ˜—š œœœ6œ&˜ŽKš˜šœ ˜šœ ˜ šœœ˜K˜@—š˜šœ˜K˜A———šœ˜šœ˜K˜A——šœ ˜ šœ˜K˜A——Kšœœ˜—Kšœ˜—K˜šΟnœœ%œœ%˜‡Kš˜Kšœœ˜(Kšœœ$˜-Kšœ/˜/Kšœ œ%˜0Kšœœ?˜Gš œœœœ œ˜>K˜—š‘ œœœ ˜"š œ œ œœ ˜/Kšœœ0˜5KšœœJ˜PK˜Kšœœ ˜K˜Kšœ%˜%KšœF˜FKšœ.˜.K˜Kšœ%˜%KšœF˜FKšœ.˜.K˜Kšœ%˜%KšœF˜FKšœ.˜.K˜Kšœ%˜%KšœF˜FKšœ.˜.K˜Kšœ˜—Kšœ˜—K˜K™ Kšœ˜Kšœœ˜6Kšœœ4˜;Kšœ˜—K˜š œœ œ œ3œœœ œ˜†K™%Kš˜KšœœœV˜uKšœ˜—K˜KšœN˜NKšœM˜MK™K™LK™LK™Kšœjœ%˜“K˜Kšœjœ%˜“K˜Kšœiœ?˜¬K˜Kšœkœ ˜|K˜Kšœ˜—…—†(