<> <> <> <> <> DIRECTORY CD, CMosB, CDInstances, CDBasics, CMosBObjects, Recognizer, CStitching; CMosBRecognizerImpl: CEDAR PROGRAM IMPORTS CMosB, CDInstances, CMosBObjects, Recognizer, CDBasics = 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] = <<--size pos of gate! not object>> 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.NewInst[ob: ob, trans: [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.NewInst[ob: ob, trans: [p, rotate90]]; Try[inst, possibleInstListPtr, forbiddenList]; END; rect: CD.Rect _ coveredList.first.rect; gatePos: CD.Position _ CDBasics.BaseOfRect[rect]; gateSize: CD.Position _ CDBasics.SizeOfRect[rect]; <<>> <<--bare diffusion>> TryTrans[gateSize, gatePos, difLayer, possibleInstListPtr]; <<>> <<--well diffusion>> <<-- ORDER is important; things placed on the possible instances list will be checked LIFO;>> <> <> 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.NewInst[ob: CMosBObjects.CreatePolyCon[], trans: [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.NewInst[ob: CMosBObjects.CreateDifCon[diffList.first], trans: [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.NewInst[ob: CMosBObjects.CreateLargePolyCon[size], trans: [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.NewInst[ob: CMosBObjects.CreateLargeDifCon[size, diffList.first], trans: [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.NewInst[ob: CMosBObjects.CreateVia[], trans: [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.NewInst[ob: CMosBObjects.CreateLargeVia[size], trans: [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 = CDBasics.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.NewInst[ob: ob, trans: [p, orient]]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-pExt, gatePos.y-dExt]; inst _ CDInstances.NewInst[ob: ob, trans: [p, orient]]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-dExt, gatePos.y-pExt]; inst _ CDInstances.NewInst[ob: ob, trans: [p, orient]]; Try[inst, possibleInstListPtr, forbiddenList]; p _ [gatePos.x-dExt, gatePos.y-dExt]; inst _ CDInstances.NewInst[ob: ob, trans: [p, orient]]; Try[inst, possibleInstListPtr, forbiddenList]; ENDLOOP; }; <<-- ORDER!!!!>> 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] = <<--places instance on possibleInstList>> BEGIN possibleInstListPtr^ _ CONS[NEW[Recognizer.InstAndForbidLayerRec _ [instance, forbiddenList]], possibleInstListPtr^]; END; Recognizer.RegisterPossibleInstanceProc [CMosB.cmosB, 1, SingleRectInstances]; Recognizer.RegisterPossibleInstanceProc[CMosB.cmosB, 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: 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.