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.
This commit is contained in:
Tim Edwards 2020-11-11 11:50:16 -05:00
parent 6b84efa86e
commit 114982fc72
6 changed files with 46 additions and 113 deletions

View File

@ -1 +1 @@
8.3.79
8.3.80

View File

@ -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;
}
/*
* ----------------------------------------------------------------------------

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();