From f116c1e4489f36a3575d796ecd691554bf5e06e9 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 6 Oct 2017 12:38:48 -0400 Subject: [PATCH] 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. --- commands/CmdLQ.c | 3 +- dbwind/DBWdisplay.c | 8 ++++ drc/DRCmain.c | 28 ++++++------- drc/DRCsubcell.c | 95 +++++++++++++++++++++++++++++++++------------ lef/lefWrite.c | 6 +-- 5 files changed, 95 insertions(+), 45 deletions(-) diff --git a/commands/CmdLQ.c b/commands/CmdLQ.c index 0612f5ec..54c8d101 100644 --- a/commands/CmdLQ.c +++ b/commands/CmdLQ.c @@ -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); } /* diff --git a/dbwind/DBWdisplay.c b/dbwind/DBWdisplay.c index 850bc797..8ea1b3bd 100644 --- a/dbwind/DBWdisplay.c +++ b/dbwind/DBWdisplay.c @@ -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); diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 88702e04..a9c879f0 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -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 diff --git a/drc/DRCsubcell.c b/drc/DRCsubcell.c index bd2b3953..05158dff 100644 --- a/drc/DRCsubcell.c +++ b/drc/DRCsubcell.c @@ -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. */ diff --git a/lef/lefWrite.c b/lef/lefWrite.c index 464ad264..bf7ee14c 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -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],