From 114982fc72ce95a1e931df08427f089e9ab8b9c9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 11 Nov 2020 11:50:16 -0500 Subject: [PATCH] Corrected the handling of DRC in cell instance arrays so that it matches the handling of subcell instances generally. Previously it would check the interaction between neighboring cells in an array without regard to any material in the parent cell which might remove those errors; consequently, the array would have to be DRC clean by itself in order for the parent cell to show as DRC clean. The array check has been moved inside the DRCInteractionCheck() routine, so that it runs only where arrayed instances do not interact with anything else. Within interaction areas, the area is flattened and checked, so the array check is not needed. --- VERSION | 2 +- drc/DRCarray.c | 120 +++++++++++++---------------------------------- drc/DRCcontin.c | 13 +---- drc/DRCmain.c | 12 ----- drc/DRCsubcell.c | 10 ++++ drc/drc.h | 2 +- 6 files changed, 46 insertions(+), 113 deletions(-) diff --git a/VERSION b/VERSION index e181c9a0..3d73f92b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.79 +8.3.80 diff --git a/drc/DRCarray.c b/drc/DRCarray.c index f4f8486b..1f44ede6 100644 --- a/drc/DRCarray.c +++ b/drc/DRCarray.c @@ -50,14 +50,6 @@ static DRCCookie drcArrayCookie = { (DRCCookie *) NULL }; -/* Static variables used to pass information between DRCArrayCheck - * and drcArrayFunc: - */ - -static int drcArrayCount; /* Count of number of errors found. */ -static void (*drcArrayErrorFunc)(); /* Function to call on violations. */ -static ClientData drcArrayClientData; /* Extra parameter to pass to func. */ - /* * ---------------------------------------------------------------------------- @@ -106,31 +98,45 @@ static ClientData drcArrayClientData; /* Extra parameter to pass to func. */ */ int -drcArrayFunc(scx, area) +drcArrayFunc(scx, arg) SearchContext *scx; /* Information about the search. */ - Rect *area; /* Area in which errors are to be - * regenerated. - */ + struct drcClientData *arg; /* Information used in overlap */ { int xsep, ysep; int xsize, ysize; + int rval, oldTiles; Rect errorArea, yankArea, tmp, tmp2; + DRCCookie *save_cptr; CellUse *use = scx->scx_use; - struct drcClientData arg; + Rect *area; + int drcArrayCount; /* Count of number of errors found. */ + void (*drcArrayErrorFunc)(); /* Function to call on violations. */ + ClientData drcArrayClientData; /* Extra parameter to pass to func. */ + PaintResultType (*savedPaintTable)[NT][NT]; + PaintResultType (*savedEraseTable)[NT][NT]; + void (*savedPaintPlane)(); if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi)) return 2; + oldTiles = DRCstatTiles; + + /* During array processing, switch the paint table to catch + * illegal overlaps. + */ + savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); + savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); + /* Set up the client data that will be passed down during * checks for exact overlaps. */ - arg.dCD_celldef = DRCdef; - arg.dCD_errors = &drcArrayCount; - arg.dCD_clip = &errorArea; - arg.dCD_cptr = &drcArrayCookie; - arg.dCD_function = drcArrayErrorFunc; - arg.dCD_clientData = drcArrayClientData; + save_cptr = arg->dCD_cptr; + arg->dCD_cptr = &drcArrayCookie; + area = arg->dCD_clip; + drcArrayCount = *arg->dCD_errors; + drcArrayErrorFunc = arg->dCD_function; + drcArrayClientData = arg->dCD_clientData; /* Compute the sizes and separations of elements, in coordinates * of the parend. If the array is 1-dimensional, we set the @@ -178,7 +184,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } /* C */ @@ -195,7 +201,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } } @@ -217,7 +223,7 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } /* D */ @@ -234,80 +240,20 @@ drcArrayFunc(scx, area) drcArrayCount += DRCBasicCheck(DRCdef, &yankArea, &errorArea, drcArrayErrorFunc, drcArrayClientData); (void) DBArraySr(use, &errorArea, drcArrayOverlapFunc, - (ClientData) &arg); + (ClientData) arg); } } - return 2; -} - -/* - * ---------------------------------------------------------------------------- - * DRCArrayCheck -- - * - * This procedure finds all DRC errors in a given area of - * a given cell that stem from array formation errors in - * children of that cell. Func is called for each violation - * found. Func should have the same form as in DRCBasicCheck. - * Note: the def passed to func is the dummy DRC definition, - * and the errors are all expressed in coordinates of celluse. - * - * Results: - * The number of errors found. - * - * Side effects: - * Whatever is done by func. - * - * ---------------------------------------------------------------------------- - */ - -int -DRCArrayCheck(def, area, func, cdarg) - CellDef *def; /* Parent cell containing the arrays to - * be rechecked. - */ - Rect *area; /* Area, in def's coordinates, where all - * array violations are to be regenerated. - */ - void (*func)(); /* Function to call for each error. */ - ClientData cdarg; /* Client data to be passed to func. */ - -{ - SearchContext scx; - int oldTiles; - PaintResultType (*savedPaintTable)[NT][NT]; - PaintResultType (*savedEraseTable)[NT][NT]; - void (*savedPaintPlane)(); - - /* Use DRCDummyUse to fake up a celluse for searching purposes. */ - - DRCDummyUse->cu_def = def; - - drcArrayErrorFunc = func; - drcArrayClientData = cdarg; - drcArrayCount = 0; - oldTiles = DRCstatTiles; - - scx.scx_area = *area; - scx.scx_use = DRCDummyUse; - scx.scx_trans = GeoIdentityTransform; - - /* During array processing, switch the paint table to catch - * illegal overlaps. - */ - - savedPaintTable = DBNewPaintTable(DRCCurStyle->DRCPaintTable); - savedPaintPlane = DBNewPaintPlane(DBPaintPlaneMark); - (void) DBCellSrArea(&scx, drcArrayFunc, (ClientData) area); (void) DBNewPaintTable(savedPaintTable); (void) DBNewPaintPlane(savedPaintPlane); /* Update count of array tiles processed. */ - DRCstatArrayTiles += DRCstatTiles - oldTiles; - return drcArrayCount; -} + /* Restore original DRC cookie pointer in the argument */ + arg->dCD_cptr = save_cptr; + return 2; +} /* * ---------------------------------------------------------------------------- diff --git a/drc/DRCcontin.c b/drc/DRCcontin.c index a8131361..5d9a527f 100644 --- a/drc/DRCcontin.c +++ b/drc/DRCcontin.c @@ -696,8 +696,6 @@ drcCheckTile(tile, arg) (void) DBSrPaintArea((Tile *) NULL, celldef->cd_planes[PL_DRC_ERROR], &square, &DBAllButSpaceBits, drcXorFunc, (ClientData) NULL); - /* Check #1: recheck the paint of the cell, ignoring subcells. */ - DRCErrorType = TT_ERROR_P; DBClearPaintPlane(drcTempPlane); @@ -707,10 +705,7 @@ drcCheckTile(tile, arg) * computed within DRCInteractionCheck()). */ - /* DRCBasicCheck (celldef, &checkbox, &erasebox, drcPaintError, - (ClientData) drcTempPlane); */ - - /* Check #2: check interactions between paint and subcells, and + /* Check interactions between paint and subcells, and * also between subcells and other subcells. If any part of a * square is rechecked for interactions, the whole thing has to * be rechecked. We use TT_ERROR_S tiles for this so that we @@ -722,12 +717,6 @@ drcCheckTile(tile, arg) (void) DRCInteractionCheck(celldef, &square, &erasebox, drcPaintError, (ClientData)drcTempPlane); - /* Check #3: check for array formation errors in the area. */ - - DRCErrorType = TT_ERROR_P; - (void) DRCArrayCheck(celldef, &erasebox, drcPaintError, - (ClientData) drcTempPlane); - /* If there was an interrupt, return without modifying the cell * at all. */ diff --git a/drc/DRCmain.c b/drc/DRCmain.c index d6132940..b57093df 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -616,12 +616,6 @@ drcWhyFunc(scx, cdarg) (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, (dolist) ? drcListError : drcPrintError, (ClientData) scx); - (void) DRCArrayCheck(def, &scx->scx_area, - (dolist) ? drcListError : drcPrintError, (ClientData) scx); - - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcWhyFunc, (ClientData)cdarg); */ - return 0; } @@ -638,12 +632,6 @@ drcWhyAllFunc(scx, cdarg) (void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area, drcListallError, (ClientData)scx); - (void) DRCArrayCheck(def, &scx->scx_area, - drcListallError, (ClientData)scx); - - /* New behavior: Don't search children, instead propagate errors up. */ - /* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */ - return 0; } diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index 9ecdb353..fa461378 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -157,6 +157,9 @@ drcSubCopyErrors(tile, cxp) * be a real error, and not one that might be resolved by additional * material found in the parent or a sibling cell. * + * Added 11/10/2020: Moved drcArrayFunc() here; this limits the array + * checks to non-interaction areas in the parent cell. + * * Returns: * Whatever DBNoTreeSrTiles() returns. * @@ -708,7 +711,9 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; + arg.dCD_clip = &subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); DRCErrorType = errorSaveType; continue; @@ -735,6 +740,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) eraseClip = *erasebox; GeoClip(&eraseClip, &cliparea); subArea = eraseClip; + arg.dCD_clip = &subArea; /* check above */ if (intArea.r_ytop < eraseClip.r_ytop) @@ -745,6 +751,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } /* check below */ if (intArea.r_ybot > eraseClip.r_ybot) @@ -756,6 +763,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } subArea.r_ytop = intArea.r_ytop; subArea.r_ybot = intArea.r_ybot; @@ -769,6 +777,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } /* check left */ if (intArea.r_xbot > eraseClip.r_xbot) @@ -780,6 +789,7 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg) /* Copy errors up from all non-interacting children */ scx.scx_area = subArea; DBCellSrArea(&scx, drcSubCopyFunc, &arg); + DBCellSrArea(&scx, drcArrayFunc, &arg); } DRCErrorType = errorSaveType; } diff --git a/drc/drc.h b/drc/drc.h index 7f3088f5..d1638931 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -247,7 +247,7 @@ extern int DRCGetDefaultWideLayerSpacing(); extern int DRCGetDefaultLayerSurround(); extern int DRCInteractionCheck(); -extern int DRCArrayCheck(); +extern int drcArrayFunc(); extern void DRCTechInit(); extern bool DRCTechLine();