Made a small change to the "cifmaxwidth" rule check implementation
to ignore non-Manhattan (split) tiles. This avoids creating false- positive DRC results on split tiles which are larger in X and Y than the max-width distance. False negatives are possible but correctly implementing a "maxwidth" rule for non-orthogonal areas requires a completely different algorithm.
This commit is contained in:
parent
b4912fd550
commit
5791ae3701
147
drc/DRCcif.c
147
drc/DRCcif.c
|
|
@ -328,7 +328,7 @@ drcCifSpacing(argc, argv)
|
||||||
dpnext = drcCifRules[layer[1]][DRC_CIF_SOLID];
|
dpnext = drcCifRules[layer[1]][DRC_CIF_SOLID];
|
||||||
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
|
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
|
||||||
drcCifAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask,
|
drcCifAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask,
|
||||||
why, centidistance, DRC_FORWARD|DRC_BOTHCORNERS | DRC_CIFRULE,
|
why, centidistance, DRC_FORWARD | DRC_BOTHCORNERS | DRC_CIFRULE,
|
||||||
layer[0], 0);
|
layer[0], 0);
|
||||||
drcCifRules[layer[1]][DRC_CIF_SOLID] = dpnew;
|
drcCifRules[layer[1]][DRC_CIF_SOLID] = dpnew;
|
||||||
|
|
||||||
|
|
@ -336,7 +336,7 @@ drcCifSpacing(argc, argv)
|
||||||
dpnext = drcCifRules[layer[1]][DRC_CIF_SPACE];
|
dpnext = drcCifRules[layer[1]][DRC_CIF_SPACE];
|
||||||
dpnew = (DRCCookie *) mallocMagic((unsigned) sizeof (DRCCookie));
|
dpnew = (DRCCookie *) mallocMagic((unsigned) sizeof (DRCCookie));
|
||||||
drcCifAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask,
|
drcCifAssign(dpnew, centidistance, dpnext, &DBSpaceBits, &cmask,
|
||||||
why, centidistance, DRC_REVERSE|DRC_BOTHCORNERS | DRC_CIFRULE,
|
why, centidistance, DRC_REVERSE | DRC_BOTHCORNERS | DRC_CIFRULE,
|
||||||
layer[0], 0);
|
layer[0], 0);
|
||||||
drcCifRules[layer[1]][DRC_CIF_SPACE] = dpnew;
|
drcCifRules[layer[1]][DRC_CIF_SPACE] = dpnew;
|
||||||
|
|
||||||
|
|
@ -1432,7 +1432,7 @@ forgetit:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
drcCheckCifMaxwidth(starttile,arg,cptr)
|
drcCheckCifMaxwidth(starttile, arg, cptr)
|
||||||
Tile *starttile;
|
Tile *starttile;
|
||||||
struct drcClientData *arg;
|
struct drcClientData *arg;
|
||||||
DRCCookie *cptr;
|
DRCCookie *cptr;
|
||||||
|
|
@ -1441,7 +1441,7 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
int edgelimit = cptr->drcc_dist;
|
int edgelimit = cptr->drcc_dist;
|
||||||
Rect boundrect;
|
Rect boundrect;
|
||||||
TileTypeBitMask *oktypes = &cptr->drcc_mask;
|
TileTypeBitMask *oktypes = &cptr->drcc_mask;
|
||||||
Tile *tile,*tp;
|
Tile *tile, *tp;
|
||||||
int scale = drcCifStyle->cs_scaleFactor;
|
int scale = drcCifStyle->cs_scaleFactor;
|
||||||
|
|
||||||
arg->dCD_cptr = (DRCCookie *)cptr;
|
arg->dCD_cptr = (DRCCookie *)cptr;
|
||||||
|
|
@ -1458,43 +1458,53 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
|
|
||||||
if (cptr->drcc_flags & DRC_MAXWIDTH_BOTH)
|
if (cptr->drcc_flags & DRC_MAXWIDTH_BOTH)
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
TiToRect(starttile,&rect);
|
TiToRect(starttile, &rect);
|
||||||
if ((rect.r_xtop-rect.r_xbot > edgelimit) ||
|
if ((rect.r_xtop-rect.r_xbot > edgelimit) ||
|
||||||
(rect.r_ytop-rect.r_ybot > edgelimit))
|
(rect.r_ytop-rect.r_ybot > edgelimit))
|
||||||
{
|
{
|
||||||
rect.r_xbot /= scale;
|
rect.r_xbot /= scale;
|
||||||
rect.r_xtop /= scale;
|
rect.r_xtop /= scale;
|
||||||
rect.r_ybot /= scale;
|
rect.r_ybot /= scale;
|
||||||
rect.r_ytop /= scale;
|
rect.r_ytop /= scale;
|
||||||
GeoClip(&rect, arg->dCD_clip);
|
GeoClip(&rect, arg->dCD_clip);
|
||||||
if (!GEO_RECTNULL(&rect)) {
|
if (!GEO_RECTNULL(&rect))
|
||||||
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
{
|
||||||
|
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
||||||
arg->dCD_cptr, arg->dCD_clientData);
|
arg->dCD_cptr, arg->dCD_clientData);
|
||||||
(*(arg->dCD_errors))++;
|
(*(arg->dCD_errors))++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (cptr->drcc_flags & DRC_BENDS)
|
else if (cptr->drcc_flags & DRC_BENDS)
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
TiToRect(starttile,&rect);
|
|
||||||
if (rect.r_xtop-rect.r_xbot > edgelimit &&
|
/* Ignore split tiles; this is a limitation but another
|
||||||
rect.r_ytop-rect.r_ybot > edgelimit)
|
* algorithm is needed to check for maximum width in a
|
||||||
{
|
* non-Manhattan area.
|
||||||
rect.r_xbot /= scale;
|
*/
|
||||||
rect.r_xtop /= scale;
|
if (IsSplit(starttile)) return;
|
||||||
rect.r_ybot /= scale;
|
|
||||||
rect.r_ytop /= scale;
|
TiToRect(starttile, &rect);
|
||||||
GeoClip(&rect, arg->dCD_clip);
|
|
||||||
if (!GEO_RECTNULL(&rect)) {
|
if (rect.r_xtop-rect.r_xbot > edgelimit &&
|
||||||
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
rect.r_ytop-rect.r_ybot > edgelimit)
|
||||||
|
{
|
||||||
|
rect.r_xbot /= scale;
|
||||||
|
rect.r_xtop /= scale;
|
||||||
|
rect.r_ybot /= scale;
|
||||||
|
rect.r_ytop /= scale;
|
||||||
|
GeoClip(&rect, arg->dCD_clip);
|
||||||
|
if (!GEO_RECTNULL(&rect))
|
||||||
|
{
|
||||||
|
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
||||||
arg->dCD_cptr, arg->dCD_clientData);
|
arg->dCD_cptr, arg->dCD_clientData);
|
||||||
(*(arg->dCD_errors))++;
|
(*(arg->dCD_errors))++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark this tile as pending and push it */
|
/* Mark this tile as pending and push it */
|
||||||
|
|
@ -1513,12 +1523,12 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
if (boundrect.r_ytop < TOP(tile)) boundrect.r_ytop = TOP(tile);
|
if (boundrect.r_ytop < TOP(tile)) boundrect.r_ytop = TOP(tile);
|
||||||
TiSetClientINT(tile, DRC_PROCESSED);
|
TiSetClientINT(tile, DRC_PROCESSED);
|
||||||
|
|
||||||
if (boundrect.r_xtop - boundrect.r_xbot > edgelimit &&
|
if (boundrect.r_xtop - boundrect.r_xbot > edgelimit &&
|
||||||
boundrect.r_ytop - boundrect.r_ybot > edgelimit) break;
|
boundrect.r_ytop - boundrect.r_ybot > edgelimit) break;
|
||||||
|
|
||||||
/* Top */
|
/* Top */
|
||||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||||
if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp);
|
if (TTMaskHasType(oktypes, TiGetType(tp)))PUSHTILE(tp);
|
||||||
|
|
||||||
/* Left */
|
/* Left */
|
||||||
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp = RT(tp))
|
||||||
|
|
@ -1531,40 +1541,40 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
/* Right */
|
/* Right */
|
||||||
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp = LB(tp))
|
||||||
if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp);
|
if (TTMaskHasType(oktypes, TiGetType(tp))) PUSHTILE(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boundrect.r_xtop - boundrect.r_xbot > edgelimit &&
|
if (boundrect.r_xtop - boundrect.r_xbot > edgelimit &&
|
||||||
boundrect.r_ytop - boundrect.r_ybot > edgelimit)
|
boundrect.r_ytop - boundrect.r_ybot > edgelimit)
|
||||||
{
|
{
|
||||||
Rect rect;
|
Rect rect;
|
||||||
TiToRect(starttile,&rect);
|
TiToRect(starttile, &rect);
|
||||||
{
|
{
|
||||||
rect.r_xbot /= scale;
|
rect.r_xbot /= scale;
|
||||||
rect.r_xtop /= scale;
|
rect.r_xtop /= scale;
|
||||||
rect.r_ybot /= scale;
|
rect.r_ybot /= scale;
|
||||||
rect.r_ytop /= scale;
|
rect.r_ytop /= scale;
|
||||||
GeoClip(&rect, arg->dCD_clip);
|
GeoClip(&rect, arg->dCD_clip);
|
||||||
if (!GEO_RECTNULL(&rect)) {
|
if (!GEO_RECTNULL(&rect))
|
||||||
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
{
|
||||||
|
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
|
||||||
arg->dCD_cptr, arg->dCD_clientData);
|
arg->dCD_cptr, arg->dCD_clientData);
|
||||||
(*(arg->dCD_errors))++;
|
(*(arg->dCD_errors))++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
/* reset the tiles */
|
||||||
/* reset the tiles */
|
TiSetClient(starttile, DRC_UNPROCESSED);
|
||||||
TiSetClient(starttile, DRC_UNPROCESSED);
|
STACKPUSH(starttile, DRCstack);
|
||||||
STACKPUSH(starttile, DRCstack);
|
while (!StackEmpty(DRCstack))
|
||||||
while (!StackEmpty(DRCstack))
|
{
|
||||||
{
|
tile = (Tile *)STACKPOP(DRCstack);
|
||||||
tile = (Tile *) STACKPOP(DRCstack);
|
|
||||||
|
|
||||||
/* Top */
|
/* Top */
|
||||||
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp = BL(tp))
|
||||||
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
||||||
{
|
{
|
||||||
TiSetClient(tp, DRC_UNPROCESSED);
|
TiSetClient(tp, DRC_UNPROCESSED);
|
||||||
STACKPUSH(tp,DRCstack);
|
STACKPUSH(tp, DRCstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Left */
|
/* Left */
|
||||||
|
|
@ -1572,7 +1582,7 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
||||||
{
|
{
|
||||||
TiSetClient(tp, DRC_UNPROCESSED);
|
TiSetClient(tp, DRC_UNPROCESSED);
|
||||||
STACKPUSH(tp,DRCstack);
|
STACKPUSH(tp, DRCstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bottom */
|
/* Bottom */
|
||||||
|
|
@ -1580,7 +1590,7 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
||||||
{
|
{
|
||||||
TiSetClient(tp, DRC_UNPROCESSED);
|
TiSetClient(tp, DRC_UNPROCESSED);
|
||||||
STACKPUSH(tp,DRCstack);
|
STACKPUSH(tp, DRCstack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Right */
|
/* Right */
|
||||||
|
|
@ -1588,9 +1598,8 @@ drcCheckCifMaxwidth(starttile,arg,cptr)
|
||||||
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
if (TiGetClient(tp) != DRC_UNPROCESSED)
|
||||||
{
|
{
|
||||||
TiSetClient(tp, DRC_UNPROCESSED);
|
TiSetClient(tp, DRC_UNPROCESSED);
|
||||||
STACKPUSH(tp,DRCstack);
|
STACKPUSH(tp, DRCstack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue