DIRECTORY CD, CDBasics, CStitching, CDCells, Recognizer, TerminalIO; RecognizerImpl: CEDAR MONITOR IMPORTS CD, CDBasics, CStitching, CDCells, TerminalIO EXPORTS Recognizer = BEGIN RegionList: TYPE = LIST OF REF CStitching.Region; Plane: TYPE = CStitching.Tesselation; PossibleProcedureRec: TYPE = RECORD [ technology: CD.Technology, rectCount: INT, instProc: Recognizer.PossibleInstanceProc --the procedure that will return possible instances ]; procRegistration: LIST OF REF PossibleProcedureRec _ NIL; --Contains registered possible procedures ActiveLayersRec: TYPE = RECORD [ technology: CD.Technology, active1: CD.Layer, active2: CD.Layer, layerList: LIST OF CD.Layer ]; layerRegistration: LIST OF REF ActiveLayersRec _ NIL; --Contains registered active layer pairs Handle: TYPE = REF HandleRep; HandleRep: TYPE = RECORD [ design: CD.Design, cellOb: CD.Object, active1: CD.Layer _ CD.undefLayer, active2: CD.Layer _ CD.undefLayer, overlapPlane: Plane _ NIL, active1CheckTess: Plane _ NIL, active2CheckTess: Plane _ NIL, coveredList: LIST OF REF CStitching.Region _ NIL, matches: BOOL _ TRUE, layerPlanes: ARRAY CD.Layer OF Plane _ ALL[NIL] ]; Free: PROC [p: Plane] = { CStitching.ResetTesselation[p]; }; RecognizeObjects: PUBLIC PROC [design: CD.Design, cellOb: CD.Object] = BEGIN FOR activeList: LIST OF REF ActiveLayersRec _ layerRegistration, activeList.rest WHILE activeList#NIL DO IF activeList.first.technology = design.technology THEN { h: Handle _ NEW[HandleRep _ [design, cellOb]]; h.active1 _ activeList.first.active1; h.active2 _ activeList.first.active2; h.layerPlanes[h.active1] _ CStitching.NewTesselation[]; h.layerPlanes[h.active2] _ CStitching.NewTesselation[]; FOR layerList: LIST OF CD.Layer _ activeList.first.layerList, layerList.rest WHILE layerList#NIL DO h.layerPlanes[layerList.first] _ CStitching.NewTesselation[]; ENDLOOP; FillPlanesByDrawingRects[design, h]; h.overlapPlane _ CStitching.NewTesselation[]; FormOverlapPlane[plane1: h.layerPlanes[h.active1], plane2: h.layerPlanes[h.active2], overlapPlane: h.overlapPlane]; CStitching.EnumerateArea[plane: h.overlapPlane, rect: CDBasics.universe, skip: $none, eachTile: GrowTransistorTile, data: h]; Free[h.overlapPlane]; FOR layerList: LIST OF CD.Layer _ activeList.first.layerList, layerList.rest WHILE layerList#NIL DO Free[h.layerPlanes[layerList.first]]; ENDLOOP; Free[h.layerPlanes[h.active1]]; Free[h.layerPlanes[h.active2]]; }; [] _ CDCells.ResizeCell[design, cellOb]; ENDLOOP; END; FillPlanesByDrawingRects: PROC [design: CD.Design, h: Handle] = BEGIN dummyInst: CD.Instance ~ NEW[CD.InstanceRep _ [ob: h.cellOb]]; pr: CD.DrawRef _ CD.CreateDrawRef[[ design: h.design, drawRect: DrawRectIntoPlane, drawChild: DrawChildIntoPlane, devicePrivate: h ]]; h.cellOb.class.drawMe[inst: dummyInst, trans: [], pr: pr]; END; DrawChildIntoPlane: CD.DrawProc = BEGIN IF inst.ob.class.wireTyped THEN inst.ob.class.drawMe[inst, trans, pr] END; DrawRectIntoPlane: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN h: Handle ~ NARROW[pr.devicePrivate]; IF h.layerPlanes[l]#NIL THEN CStitching.ChangeRect[plane: h.layerPlanes[l], rect: r, new: $cover]; END; FormOverlapPlane: PUBLIC PROC [plane1, plane2, overlapPlane: Plane] = BEGIN FOR rl1: RegionList _ CStitching.ListArea[plane1, CDBasics.universe, $none], rl1.rest WHILE rl1#NIL DO IF rl1.first.value=$cover THEN FOR ovL: RegionList _ CStitching.ListArea[plane2, rl1.first.rect, $none], ovL.rest WHILE ovL#NIL DO IF ovL.first.value=$cover THEN CStitching.ChangeRect[plane: overlapPlane, rect: ovL.first.rect, new: $cover]; ENDLOOP; ENDLOOP; END; GrowTransistorTile: PROC [tile: CStitching.Tile, data: REF ANY] = BEGIN IF tile.value = $cover THEN { currentTess: Plane ~ CStitching.NewTesselation[]; h: Handle _ NARROW[data]; tileList: LIST OF CStitching.Tile _ LIST[tile]; WHILE tileList#NIL DO tile: CStitching.Tile _ tileList.first; tileList _ tileList.rest; IF tile.value#$done THEN { tileList _ GetNeighborsSameAsMe[tile, h.overlapPlane, tileList]; CStitching.ChangeRect[currentTess, CStitching.Area[tile], $cover]; tile.value _ $done; }; ENDLOOP; AnalyzeTransistor[currentTess, h]; Free[currentTess]; } END; GetNeighborsSameAsMe: PROC [tile: CStitching.Tile, tess: Plane, tileList: LIST OF CStitching.Tile] RETURNS [newList: LIST OF CStitching.Tile] = BEGIN cur: CStitching.Tile; newList _ tileList; cur _ CStitching.EN[tile]; WHILE CStitching.WS[cur] = tile DO IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.SW[cur]; ENDLOOP; IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.SW[tile]; WHILE CStitching.NE[cur] = tile DO IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.EN[cur]; ENDLOOP; IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.WS[tile]; WHILE CStitching.EN[cur] = tile DO IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.NE[cur]; ENDLOOP; IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.NE[tile]; WHILE CStitching.SW[cur] = tile DO IF cur.value = tile.value THEN newList _ CONS[cur, newList]; cur _ CStitching.WS[cur]; ENDLOOP; IF cur.value = tile.value THEN newList _ CONS[cur, newList]; END; AnalyzeTransistor: PROC [plane: Plane, h: Handle] = BEGIN currentList: RegionList _ CStitching.ListArea[plane, CDBasics.universe, $none]; count: INT _ 0; possibleInstListPtr: REF Recognizer.InstAndForbidLayerList _ NEW[Recognizer.InstAndForbidLayerList _ NIL]; h.coveredList _ NIL; FOR countList: RegionList _ currentList, countList.rest WHILE countList#NIL DO IF countList.first.value#NIL THEN { count _ count + 1; h.coveredList _ CONS[countList.first, h.coveredList]; }; ENDLOOP; FOR procList: LIST OF REF PossibleProcedureRec _ procRegistration, procList.rest WHILE procList#NIL DO IF procList.first.technology = h.design.technology AND procList.first.rectCount = count THEN procList.first.instProc[h.active1, h.active2, h.coveredList, possibleInstListPtr]; ENDLOOP; WHILE possibleInstListPtr^#NIL DO IF InstanceMatches[possibleInstListPtr^.first.instance, h] AND NoForbiddenOverlap[possibleInstListPtr^.first.forbidLayerList, h] THEN { newInst: CD.Instance _ CDCells.IncludeOb[ design: h.design, cell: h.cellOb, ob: possibleInstListPtr^.first.instance.ob, trans: possibleInstListPtr^.first.instance.trans, mode: dontResize ].newInst; newInst.selected _ TRUE; EXIT; } ELSE possibleInstListPtr^ _ possibleInstListPtr^.rest; ENDLOOP; END; InstanceMatches: PROC [instance: CD.Instance, h: Handle] RETURNS [BOOL _ FALSE] = BEGIN pr: CD.DrawRef _ CD.CreateDrawRef[[ design: h.design, devicePrivate: h, drawRect: DrawRectAgainstTess ]]; h.matches _ TRUE; h.active1CheckTess _ CStitching.NewTesselation[]; h.active2CheckTess _ CStitching.NewTesselation[]; instance.ob.class.drawMe[inst: instance, trans: instance.trans, pr: pr]; IF h.matches THEN RETURN[OverlapRegionsMatch[h]]; END; DrawRectAgainstTess: PROC [r: CD.Rect, l: CD.Layer, pr: CD.DrawRef] = BEGIN h: Handle _ NARROW[pr.devicePrivate]; checkPlane: Plane _ h.layerPlanes[l]; IF CDBasics.NonEmpty[r] THEN { IF l = h.active1 THEN CStitching.ChangeRect[h.active1CheckTess, r, $cover] ELSE IF l = h.active2 THEN CStitching.ChangeRect[h.active2CheckTess, r, $cover]; IF checkPlane = NIL THEN { h.matches _ FALSE; TerminalIO.PutRope["Unexpected Layer Encountered\n"]; RETURN }; FOR checkList: RegionList _ CStitching.ListArea[checkPlane, r, $none], checkList.rest WHILE checkList#NIL DO IF checkList.first.value = NIL THEN { h.matches _ FALSE; RETURN } ENDLOOP; } END; OverlapRegionsMatch: PROC [h: Handle] RETURNS [b: BOOL _ TRUE] = BEGIN checkTess: Plane _ CStitching.NewTesselation[]; FOR list1: RegionList _ CStitching.ListArea[plane: h.active1CheckTess, rect: CDBasics.universe, skip: $none], list1.rest WHILE list1#NIL DO IF list1.first.value#NIL THEN FOR overlapList: RegionList _ CStitching.ListArea[plane: h.active2CheckTess, rect: list1.first.rect, skip: $none], overlapList.rest WHILE overlapList#NIL DO IF overlapList.first.value#NIL THEN CStitching.ChangeRect[checkTess, overlapList.first.rect, $cover]; ENDLOOP; ENDLOOP; b _ RegionAndTessOverlapCompletely[h.coveredList, checkTess]; Free[checkTess]; END; NoForbiddenOverlap: PROC [layerList: LIST OF CD.Layer, h: Handle] RETURNS [BOOL _ TRUE] = BEGIN WHILE layerList#NIL DO IF h.layerPlanes[layerList.first] = NIL THEN { TerminalIO.PutRope["Unexpected Layer Encountered\n"]; RETURN [FALSE]; } ELSE IF RegionAndTessIntersect[h.coveredList, h.layerPlanes[layerList.first]] THEN RETURN [FALSE] ELSE layerList _ layerList.rest; ENDLOOP; END; RegionAndTessOverlapCompletely: PROC [checkList: RegionList, tess: Plane] RETURNS [BOOL _ TRUE] = BEGIN FOR list: RegionList _ checkList, list.rest WHILE list#NIL DO FOR list2: RegionList _ CStitching.ListArea[plane: tess, rect: list.first.rect, skip: $none], list2.rest WHILE list2#NIL DO IF list2.first.value = NIL THEN RETURN[FALSE] ENDLOOP; ENDLOOP; END; RegionAndTessIntersect: PROC [checkList: RegionList, tess: Plane] RETURNS [BOOL _ FALSE] = BEGIN WHILE checkList#NIL DO FOR intersectList: RegionList _ CStitching.ListArea[tess, checkList.first.rect, $none], intersectList.rest WHILE intersectList#NIL DO IF intersectList.first.value#NIL THEN RETURN [TRUE]; ENDLOOP; checkList _ checkList.rest; ENDLOOP; END; RegisterPossibleInstanceProc: PUBLIC ENTRY PROC [technology: CD.Technology, rectCount: INT, instProc: Recognizer.PossibleInstanceProc] = BEGIN procRegistration _ CONS[NEW[PossibleProcedureRec _ [technology, rectCount, instProc]], procRegistration]; END; RegisterLayerList: PUBLIC ENTRY PROC [technology: CD.Technology, active1, active2: CD.Layer, layerList: LIST OF CD.Layer] = BEGIN layerRegistration _ CONS[NEW[ActiveLayersRec _ [technology, active1, active2, layerList]], layerRegistration]; END; END.  RecognizerImpl.mesa Last Edited by: Gbier, July 11, 1985 12:18:45 pm PDT Last edited by: Christian Jacobi, November 4, 1986 5:43:29 pm PST Last Edidmd by: Gbier, July 26, 1985 1:41:17 pm PDT Jacobi, March 19, 1986 6:33:30 pm PST --help the garbage collector --Overlapping regions between plane1 and plane2 will be added to the overlapPlane --A new tesselation called currentTess is formed which contains the maximum connected region that has the same value as tile and contains tile. --Returns all tiles adjacent to tile that have the same value as tile --Enumerates plane, counting the covered regions and storing the covered regions on h.coveredList. The count and technology are used to select the proper Possible Instance Procedures to call. The Possible Instance Procedures return a list of possible instances which are then searched for a match. --Draws the instance using the instances drawMe procedure Reaching here means that the instance drawn against the design matched. However it is still neccessary to make sure that the overlapping region in the instance matches what is on the coveredList. This guarantees that the matching instance is exactly the same size as the overlapping region in question in the design. --The rect is enumerated against its layer plane, if it is not covered then h.matches is set to false. --Forms the overlap of what is stored in active1CheckTess and active2CheckTess and makes sure that everthing on the coveredList is really covered by the overlap --h.coveredList is enumerated against the layerList. Returns FALSE if any piece of the coveredList is covered on any of the layers. --Returns true if everything on checkList is covered on the Tesselation --Returns true if the intersection between items on the checklist and the tesselation is non-empty Κ ϋ˜codešœ™Kšœ4™4K™AKšœ3™3K™%—K˜šΟk ˜ Kšœ˜Kšœ ˜ Kšœ ˜ K˜Kšœ ˜ Kšœ ˜ —K˜K˜šΟbœœ˜Kšœœ+˜5Kšœ˜—Kšœ˜K˜Kšœ œœœ˜1Kšœœ˜%K˜šœœœ˜%Kšœ œ ˜Kšœ œ˜Kšœ+Οc3˜^K˜—K˜Kš œœœœœŸ)˜dK˜šœœœ˜ Kšœ œ ˜Kšœ œ˜Kšœ œ˜Kšœ œœœ˜K˜—K˜Kš œœœœœŸ(˜_K˜Kšœœœ ˜šœ œœ˜Kšœœ ˜Kšœœ˜Kšœ œ œ ˜"Kšœ œ œ ˜"Kšœœ˜Kšœœ˜Kšœœ˜Kš œ œœœœ˜3Kšœ œœ˜Kš œ œœœ œœ˜/K˜—K˜K˜šΟnœœ˜Kšœ˜Kšœ˜—K˜š  œœœ œœ ˜FKš˜š œ œœœ6œ˜hšœ1œ˜9Kšœ œ ˜/K˜%K˜%Kšœ7˜7Kšœ7˜7š œ œœœ4œ œ˜cKšœ=˜=Kšœ˜—K˜$Kšœ-˜-K˜tKšœ~˜~K™™Kšœ˜š œ œœœ4œ œ˜cKšœ%˜%Kšœ˜—Kšœ˜Kšœ˜—K˜—K˜(Kšœ˜—Kšœ˜—K˜šΠbnœœ œ˜?Kš˜Kšœ œ œœ˜>šœœ œ˜#Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—Kšœ:˜:Kšœ˜K˜šžœœ ˜!Kš˜Kšœœ&˜EKšœ˜—K˜š ‘œœœ œ œ ˜CKš˜Kšœ œ˜%šœœ˜KšœE˜E—Kšœ˜——K˜š‘œœœ(˜EK™QKš˜šœSœœ˜fšœœ˜šœPœœ˜cšœ˜KšœN˜N—Kšœ˜——Kšœ˜—Kšœ˜—K˜š ‘œœ œ œœ˜AKšœ™Kš˜šœœ˜Kšœ1˜1Kšœ œ˜Kš œ œœ œœ˜/šœ œœ˜Kšœ œ˜'K˜šœœ˜K˜@KšœB˜BK˜K˜—Kšœ˜—K˜"Kšœ˜K˜—Kšœ˜—K˜š‘œœ œœœ œœ œœ œ˜KšœE™EKš˜Kšœ œ˜K˜Kšœ˜šœ˜"šœ˜Kšœ œ˜—Kšœ˜Kšœ˜—Kšœœ œ˜