Experimental change in the way hierarchical DRC is handled. To
avoid the problem where subcells violate DRC themselves but do not violate DRC in the context of the parent (i.e., the parent adds metal to avoid minimum area error), DRC errors in subcells are neither counted nor displayed, but they remain present in the subcell database. The DRC check enumerates all subcell errors as mandatory check areas in DRCFindInteractions(), so that those areas are always counted with the interaction areas. Previously, if a subcell violated a DRC rule by itself, that error would be counted and displayed in the parent even if the parent had paint causing the error to no longer exist.
This commit is contained in:
parent
b26c7de6f6
commit
f116c1e448
|
|
@ -698,7 +698,8 @@ CmdPaint(w, cmd)
|
|||
SelectClear();
|
||||
DBWAreaChanged(EditCellUse->cu_def, &editRect, DBW_ALLWINDOWS, &mask);
|
||||
DBReComputeBbox(EditCellUse->cu_def);
|
||||
DRCCheckThis (EditCellUse->cu_def, TT_CHECKPAINT, &editRect);
|
||||
if (DRCBackGround)
|
||||
DRCCheckThis (EditCellUse->cu_def, TT_CHECKPAINT, &editRect);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -597,6 +597,14 @@ dbwPaintFunc(tile, cxp)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Ignore DRC error tiles in anything but the top-level window */
|
||||
if (scx->scx_use != (CellUse *)dbwWindow->w_surfaceID)
|
||||
{
|
||||
TileType ttype = TiGetType(tile);
|
||||
if (ttype == TT_ERROR_P || ttype == TT_ERROR_S || ttype == TT_ERROR_PS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!dbwIsLocked)
|
||||
{
|
||||
GrLock(dbwLockW, TRUE);
|
||||
|
|
|
|||
|
|
@ -530,9 +530,6 @@ drcWhyFunc(scx, cdarg)
|
|||
|
||||
/* Check paint and interactions in this subcell. */
|
||||
|
||||
// (void) DRCBasicCheck(def, &haloArea, &scx->scx_area,
|
||||
// (dolist) ? drcListError : drcPrintError,
|
||||
// (ClientData) scx);
|
||||
(void) DRCInteractionCheck(def, &scx->scx_area, &scx->scx_area,
|
||||
(dolist) ? drcListError : drcPrintError,
|
||||
(ClientData) scx);
|
||||
|
|
@ -540,9 +537,8 @@ drcWhyFunc(scx, cdarg)
|
|||
(dolist) ? drcListError : drcPrintError,
|
||||
(ClientData) scx);
|
||||
|
||||
/* Also search children. */
|
||||
|
||||
(void) DBCellSrArea(scx, drcWhyFunc, (ClientData)cdarg);
|
||||
/* New behavior: Don't search children, instead propagate errors up. */
|
||||
/* (void) DBCellSrArea(scx, drcWhyFunc, (ClientData)cdarg); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -563,9 +559,8 @@ drcWhyAllFunc(scx, cdarg)
|
|||
(void) DRCArrayCheck(def, &scx->scx_area,
|
||||
drcListallError, (ClientData)scx);
|
||||
|
||||
/* Also search children. */
|
||||
|
||||
(void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg);
|
||||
/* New behavior: Don't search children, instead propagate errors up. */
|
||||
/* (void) DBCellSrArea(scx, drcWhyAllFunc, (ClientData)cdarg); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -637,9 +632,8 @@ drcCheckFunc(scx, cdarg)
|
|||
|
||||
DRCCheckThis(def, TT_CHECKPAINT, (Rect *) NULL);
|
||||
|
||||
/* Check child cells also. */
|
||||
|
||||
(void) DBCellSrArea(scx, drcCheckFunc, (ClientData) NULL);
|
||||
/* New behavior: Don't search children, instead propagate errors up. */
|
||||
/* (void) DBCellSrArea(scx, drcCheckFunc, (ClientData) NULL); */
|
||||
|
||||
/* As a special performance hack, if the complete cell area is
|
||||
* handled here, don't bother to look at any more array elements.
|
||||
|
|
@ -753,9 +747,8 @@ drcCountFunc(scx, dupTable)
|
|||
|
||||
if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) return 0;
|
||||
|
||||
/* Scan children recursively. */
|
||||
|
||||
(void) DBCellSrArea(scx, drcCountFunc, (ClientData) dupTable);
|
||||
/* New behavior: Don't search children, instead propagate errors up. */
|
||||
/* (void) DBCellSrArea(scx, drcCountFunc, (ClientData) dupTable); */
|
||||
|
||||
/* As a special performance hack, if the complete cell area is
|
||||
* handled here, don't bother to look at any more array elements.
|
||||
|
|
@ -901,8 +894,9 @@ drcFindFunc(scx, finddata)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Recursively search children */
|
||||
return DBCellSrArea(scx, drcFindFunc, (ClientData)finddata);
|
||||
/* New behavior: Don't search children, instead propagate errors up. */
|
||||
/* return DBCellSrArea(scx, drcFindFunc, (ClientData)finddata); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
static Rect drcSubIntArea; /* Accumulates area of interactions. */
|
||||
static CellDef *drcSubDef; /* Cell definition we're checking. */
|
||||
static int drcSubRadius; /* Interaction radius. */
|
||||
static CellUse *drcSubCurUse; /* Holds current use when checking to see
|
||||
static CellTileBody *drcCurSub; /* Holds current tile when checking to see
|
||||
* if more than one use in an area.
|
||||
*/
|
||||
static Rect drcSubLookArea; /* Area where we're looking for interactions */
|
||||
|
|
@ -72,7 +72,7 @@ extern int DRCErrorType;
|
|||
* drcFindOtherCells --
|
||||
*
|
||||
* This is a search function invoked when looking around a given
|
||||
* cell for interactions. If a cell is found other than drcSubCurUse,
|
||||
* cell for interactions. If a tile is found other than drcCurSub,
|
||||
* then it constitutes an interaction, and its area is included
|
||||
* into the area parameter.
|
||||
*
|
||||
|
|
@ -92,13 +92,19 @@ drcFindOtherCells(tile, area)
|
|||
Rect *area; /* Area in which to include interactions. */
|
||||
{
|
||||
Rect r;
|
||||
CellUse *use;
|
||||
CellTileBody *ctbptr = (CellTileBody *) tile->ti_body;
|
||||
|
||||
if (ctbptr == NULL) return 0;
|
||||
if ((ctbptr->ctb_use != drcSubCurUse) || (ctbptr->ctb_next != NULL))
|
||||
/* XXX */
|
||||
/* if (ctbptr == NULL) return 0; */
|
||||
|
||||
if (ctbptr == drcCurSub) return 0;
|
||||
|
||||
for (ctbptr = (CellTileBody *) TiGetBody(tile); ctbptr != NULL;
|
||||
ctbptr = ctbptr->ctb_next)
|
||||
{
|
||||
TiToRect(tile, &r);
|
||||
(void) GeoInclude(&r, area);
|
||||
use = ctbptr->ctb_use;
|
||||
GeoInclude(&use->cu_bbox, &r);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -123,12 +129,14 @@ drcFindOtherCells(tile, area)
|
|||
*/
|
||||
|
||||
int
|
||||
drcSubcellTileFunc(tile)
|
||||
drcSubcellTileFunc(tile, propagate)
|
||||
Tile *tile; /* Subcell tile. */
|
||||
bool *propagate; /* Errors to propagate up */
|
||||
{
|
||||
Rect area, haloArea, intArea;
|
||||
Rect area, haloArea, intArea, subIntArea, locIntArea;
|
||||
int i;
|
||||
CellTileBody *ctbptr = (CellTileBody *) tile->ti_body;
|
||||
CellUse *subUse;
|
||||
|
||||
if (ctbptr == NULL) return 0;
|
||||
|
||||
|
|
@ -138,9 +146,20 @@ drcSubcellTileFunc(tile)
|
|||
* we're recomputing errors).
|
||||
*/
|
||||
|
||||
TiToRect(tile, &area);
|
||||
GEO_EXPAND(&area, drcSubRadius, &haloArea);
|
||||
GeoClip(&haloArea, &drcSubLookArea);
|
||||
/* XXX This is not right---the area of the cell plane tile is not */
|
||||
/* the area of the subcell. */
|
||||
/* TiToRect(tile, &area); */
|
||||
|
||||
for (ctbptr = (CellTileBody *) TiGetBody(tile); ctbptr != NULL;
|
||||
ctbptr = ctbptr->ctb_next)
|
||||
{
|
||||
subUse = ctbptr->ctb_use;
|
||||
area = subUse->cu_bbox;
|
||||
|
||||
GEO_EXPAND(&area, drcSubRadius, &haloArea);
|
||||
GeoClip(&haloArea, &drcSubLookArea);
|
||||
}
|
||||
|
||||
intArea = GeoNullRect;
|
||||
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
|
||||
{
|
||||
|
|
@ -148,7 +167,26 @@ drcSubcellTileFunc(tile)
|
|||
&haloArea, &DBAllButSpaceBits, drcIncludeArea,
|
||||
(ClientData) &intArea);
|
||||
}
|
||||
drcSubCurUse = ctbptr->ctb_use;
|
||||
|
||||
/* DRC error tiles in a subcell are automatically pulled into the */
|
||||
/* interaction area of the parent. Ultimately this is recursive as */
|
||||
/* all cells are checked and errors propagate to the top level. */
|
||||
|
||||
/* XXX */
|
||||
for (ctbptr = (CellTileBody *) TiGetBody(tile); ctbptr != NULL;
|
||||
ctbptr = ctbptr->ctb_next)
|
||||
{
|
||||
subUse = ctbptr->ctb_use;
|
||||
subIntArea = GeoNullRect;
|
||||
DBSrPaintArea((Tile *) NULL, subUse->cu_def->cd_planes[PL_DRC_ERROR],
|
||||
&TiPlaneRect, &DBAllButSpaceBits, drcIncludeArea,
|
||||
(ClientData) &subIntArea);
|
||||
GeoTransRect(&(subUse->cu_transform), &subIntArea, &locIntArea);
|
||||
GeoInclude(&locIntArea, &intArea);
|
||||
if (!GEO_RECTNULL(&subIntArea)) *propagate = TRUE;
|
||||
}
|
||||
|
||||
drcCurSub = ctbptr;
|
||||
(void) TiSrArea((Tile *) NULL, drcSubDef->cd_planes[PL_CELL],
|
||||
&haloArea, drcFindOtherCells, (ClientData) &intArea);
|
||||
if (GEO_RECTNULL(&intArea)) return 0;
|
||||
|
|
@ -277,6 +315,7 @@ DRCFindInteractions(def, area, radius, interaction)
|
|||
int i;
|
||||
CellUse *use;
|
||||
SearchContext scx;
|
||||
bool propagate;
|
||||
|
||||
drcSubDef = def;
|
||||
drcSubRadius = radius;
|
||||
|
|
@ -291,8 +330,9 @@ DRCFindInteractions(def, area, radius, interaction)
|
|||
|
||||
drcSubIntArea = GeoNullRect;
|
||||
GEO_EXPAND(area, radius, &drcSubLookArea);
|
||||
propagate = FALSE;
|
||||
(void) TiSrArea((Tile *) NULL, def->cd_planes[PL_CELL],
|
||||
&drcSubLookArea, drcSubcellTileFunc, (ClientData) NULL);
|
||||
&drcSubLookArea, drcSubcellTileFunc, (ClientData)(&propagate));
|
||||
|
||||
/* If there seems to be an interaction area, make a second pass
|
||||
* to make sure there's more than one cell with paint in the
|
||||
|
|
@ -302,21 +342,28 @@ DRCFindInteractions(def, area, radius, interaction)
|
|||
|
||||
if (GEO_RECTNULL(&drcSubIntArea)) return FALSE;
|
||||
use = NULL;
|
||||
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
|
||||
|
||||
/* If errors are being propagated up from child to parent, */
|
||||
/* then the interaction area is always valid. */
|
||||
|
||||
if (propagate == FALSE)
|
||||
{
|
||||
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[i],
|
||||
&drcSubIntArea, &DBAllButSpaceBits, drcAlwaysOne,
|
||||
(ClientData) NULL) != 0)
|
||||
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
|
||||
{
|
||||
use = (CellUse *) -1;
|
||||
break;
|
||||
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[i],
|
||||
&drcSubIntArea, &DBAllButSpaceBits, drcAlwaysOne,
|
||||
(ClientData) NULL) != 0)
|
||||
{
|
||||
use = (CellUse *) -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
scx.scx_use = DRCDummyUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = drcSubIntArea;
|
||||
if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0)
|
||||
return FALSE;
|
||||
}
|
||||
scx.scx_use = DRCDummyUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
scx.scx_area = drcSubIntArea;
|
||||
if (DBTreeSrCells(&scx, 0, drcSubCheckPaint, (ClientData) &use) == 0)
|
||||
return FALSE;
|
||||
|
||||
/* OK, no more excuses, there's really an interaction area here. */
|
||||
|
||||
|
|
|
|||
|
|
@ -754,7 +754,7 @@ lefWriteMacro(def, f, scale)
|
|||
|
||||
if (!TTMaskIsZero(&boundmask))
|
||||
{
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||
DBSrPaintArea((Tile *)NULL, def->cd_planes[pNum],
|
||||
&TiPlaneRect, &boundmask, lefGetBound,
|
||||
(ClientData)(&boundary));
|
||||
|
|
@ -922,7 +922,7 @@ lefWriteMacro(def, f, scale)
|
|||
|
||||
lc.numWrites = 0;
|
||||
lc.lastType = TT_SPACE;
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
lc.pNum = pNum;
|
||||
DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum],
|
||||
|
|
@ -977,7 +977,7 @@ lefWriteMacro(def, f, scale)
|
|||
|
||||
/* Restrict to routing planes only */
|
||||
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
lc.pNum = pNum;
|
||||
DBSrPaintArea((Tile *)NULL, lefFlatDef->cd_planes[pNum],
|
||||
|
|
|
|||
Loading…
Reference in New Issue