Found a way to work around the problem of having subcell DRC
errors show up as "See error definition in subcell", which has been the case since I modified the code to prevent showing DRC errors in subcells that have been resolved by the hierarchy above them. DRC errors are now intelligently searched downward in the heirarchy when enumerated for "drc why". Also changed the DRC check tile definition to offset such that there is a tile centered on the origin, instead of the origin being between four tiles. Since most layouts are subcells and most subcells are small relative to the DRC check tile area, and most subcells are placed near the origin, then most subcells will appear in only one tile, which speeds up the DRC process somewhat.
This commit is contained in:
parent
42aa06f8f5
commit
0ac4d3a465
|
|
@ -277,13 +277,42 @@ drcPrintError (celldef, rect, cptr, scx)
|
|||
{
|
||||
HashEntry *h;
|
||||
int i;
|
||||
Rect *area, r;
|
||||
Rect *area;
|
||||
int drcsave = DRCErrorCount;
|
||||
|
||||
/* Forward declaration */
|
||||
void drcWhyFunc(SearchContext *scx, ClientData cdarg);
|
||||
|
||||
ASSERT (cptr != (DRCCookie *) NULL, "drcPrintError");
|
||||
|
||||
area = &scx->scx_area;
|
||||
if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return;
|
||||
|
||||
if (cptr->drcc_tag == DRC_IN_SUBCELL_TAG)
|
||||
{
|
||||
SearchContext newscx;
|
||||
|
||||
/* Recurse into subcells to find the error being flagged */
|
||||
/* recursive call is drcWhyFunc, clientdata is FALSE */
|
||||
|
||||
newscx.scx_area = *rect;
|
||||
newscx.scx_use = scx->scx_use;
|
||||
newscx.scx_x = scx->scx_use->cu_xlo;
|
||||
newscx.scx_y = scx->scx_use->cu_ylo;
|
||||
newscx.scx_trans = scx->scx_trans;
|
||||
|
||||
DBTreeSrCells(&newscx, 0, drcWhyFunc, (ClientData)FALSE);
|
||||
}
|
||||
/* Hack to avoid printing "no errors found" when recursing on
|
||||
* drcWhyFunc() above. In some cases like run-length rules,
|
||||
* changing the search area can make the error disappear. If
|
||||
* that happens, "See error definition in subcell" will be
|
||||
* printed. The underlying error needs to be fixed, but this
|
||||
* method provides the information the user needs to find the
|
||||
* error.
|
||||
*/
|
||||
if (drcsave == DRCErrorCount)
|
||||
{
|
||||
i = DRCErrorList[cptr->drcc_tag];
|
||||
if (i == 0)
|
||||
TxPrintf("%s\n", drcSubstitute(cptr));
|
||||
|
|
@ -293,6 +322,7 @@ drcPrintError (celldef, rect, cptr, scx)
|
|||
DRCErrorList[cptr->drcc_tag] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Same routine as above, but output goes to a Tcl list and is appended */
|
||||
/* to the interpreter result. */
|
||||
|
|
@ -309,11 +339,33 @@ drcListError (celldef, rect, cptr, scx)
|
|||
HashEntry *h;
|
||||
int i;
|
||||
Rect *area;
|
||||
int drcsave = DRCErrorCount;
|
||||
|
||||
/* Forward declaration */
|
||||
void drcWhyFunc(SearchContext *scx, ClientData cdarg);
|
||||
|
||||
ASSERT (cptr != (DRCCookie *) NULL, "drcListError");
|
||||
|
||||
area = &scx->scx_area;
|
||||
if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return;
|
||||
|
||||
if (cptr->drcc_tag == DRC_IN_SUBCELL_TAG)
|
||||
{
|
||||
SearchContext newscx;
|
||||
|
||||
/* Recurse into subcells to find the error being flagged */
|
||||
/* recursive call is drcWhyFunc, clientdata is TRUE */
|
||||
|
||||
newscx.scx_area = *rect;
|
||||
newscx.scx_use = scx->scx_use;
|
||||
newscx.scx_x = scx->scx_use->cu_xlo;
|
||||
newscx.scx_y = scx->scx_use->cu_ylo;
|
||||
newscx.scx_trans = scx->scx_trans;
|
||||
|
||||
DBTreeSrCells(&newscx, 0, drcWhyFunc, (ClientData)TRUE);
|
||||
}
|
||||
if (drcsave == DRCErrorCount)
|
||||
{
|
||||
i = DRCErrorList[cptr->drcc_tag];
|
||||
if (i == 0)
|
||||
{
|
||||
|
|
@ -329,6 +381,7 @@ drcListError (celldef, rect, cptr, scx)
|
|||
DRCErrorList[cptr->drcc_tag] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Same routine as above, but output for every single error is recorded */
|
||||
/* along with position information. */
|
||||
|
|
@ -343,6 +396,10 @@ drcListallError (celldef, rect, cptr, scx)
|
|||
Tcl_Obj *lobj, *pobj;
|
||||
HashEntry *h;
|
||||
Rect *area, r;
|
||||
int drcsave = DRCErrorCount;
|
||||
|
||||
/* Forward declaration */
|
||||
int drcWhyAllFunc(SearchContext *scx, ClientData cdarg);
|
||||
|
||||
ASSERT (cptr != (DRCCookie *) NULL, "drcListallError");
|
||||
|
||||
|
|
@ -350,6 +407,24 @@ drcListallError (celldef, rect, cptr, scx)
|
|||
GeoTransRect(&scx->scx_trans, rect, &r);
|
||||
area = &scx->scx_area;
|
||||
if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return;
|
||||
|
||||
if (cptr->drcc_tag == DRC_IN_SUBCELL_TAG)
|
||||
{
|
||||
SearchContext newscx;
|
||||
|
||||
/* Recurse into subcells to find the error being flagged */
|
||||
/* recursive call is drcWhyAllFunc, clientdata is NULL */
|
||||
|
||||
newscx.scx_area = *rect;
|
||||
newscx.scx_use = scx->scx_use;
|
||||
newscx.scx_x = scx->scx_use->cu_xlo;
|
||||
newscx.scx_y = scx->scx_use->cu_ylo;
|
||||
newscx.scx_trans = scx->scx_trans;
|
||||
|
||||
DBTreeSrCells(&newscx, 0, drcWhyAllFunc, (ClientData)NULL);
|
||||
}
|
||||
if (drcsave == DRCErrorCount)
|
||||
{
|
||||
DRCErrorCount += 1;
|
||||
h = HashFind(&DRCErrorTable, drcSubstitute(cptr));
|
||||
lobj = (Tcl_Obj *) HashGetValue(h);
|
||||
|
|
@ -366,6 +441,7 @@ drcListallError (celldef, rect, cptr, scx)
|
|||
|
||||
HashSetValue(h, lobj);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
|
|
|||
|
|
@ -734,9 +734,9 @@ DRCInteractionCheck(def, area, erasebox, func, cdarg)
|
|||
* square separately.
|
||||
*/
|
||||
|
||||
x = (area->r_xbot/DRCStepSize) * DRCStepSize;
|
||||
x = (area->r_xbot/DRCStepSize) * DRCStepSize - (DRCStepSize / 2);
|
||||
if (x > area->r_xbot) x -= DRCStepSize;
|
||||
y = (area->r_ybot/DRCStepSize) * DRCStepSize;
|
||||
y = (area->r_ybot/DRCStepSize) * DRCStepSize - (DRCStepSize / 2);
|
||||
if (y > area->r_ybot) y -= DRCStepSize;
|
||||
for (square.r_xbot = x; square.r_xbot < area->r_xtop;
|
||||
square.r_xbot += DRCStepSize)
|
||||
|
|
|
|||
Loading…
Reference in New Issue