Skip to content

Commit

Permalink
Corrected a recently-discovered error in the "minimum area" DRC rule.
Browse files Browse the repository at this point in the history
The fractional part of the rule distance (modulus after scaling)
does not fit in the unsigned char variable unless it is first
divided by the scalefactor (also requires multiplying up by the same
amount when scaling the other direction).  The truncation of the
unsigned char value was causing the minimum area value to be off by
a small amount, causing false negatives (no DRC violation is shown
when metal area is slightly smaller than the minimum allowed).
  • Loading branch information
RTimothyEdwards committed Jan 14, 2024
1 parent a816da6 commit 6b8239e
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8.3.457
8.3.458
27 changes: 25 additions & 2 deletions drc/DRCtech.c
Original file line number Diff line number Diff line change
Expand Up @@ -3686,14 +3686,30 @@ drcScaleDown(style, scalefactor)
}
if (dp->drcc_cdist > 0)
{
int cmod;
int locscale = scalefactor;
if (dp->drcc_flags & DRC_AREA)
locscale *= scalefactor;

dist = dp->drcc_cdist;
dp->drcc_cdist /= locscale;
if ((dp->drcc_cmod = (unsigned char)(dist % locscale)) != 0)

/* Save the amount by which the distance needs to be
* corrected when multiplied back to the original
* scale. For area, the modulus will always be
* a multiple of the scalefactor, so it can be
* divided by the scalefactor so it still fits in an
* unsigned char.
*/

if ((cmod = (dist % locscale)) != 0)
{
dp->drcc_cdist++;
if (dp->drcc_flags & DRC_AREA)
dp->drcc_cmod = (unsigned char)(cmod / scalefactor);
else
dp->drcc_cmod = (unsigned char)cmod;
}
}
}
}
Expand Down Expand Up @@ -3748,8 +3764,15 @@ drcScaleUp(style, scalefactor)
dp->drcc_cdist--;
dp->drcc_cdist *= scalefactor;
if (dp->drcc_flags & DRC_AREA)
{
dp->drcc_cdist *= scalefactor;
dp->drcc_cdist += (short)dp->drcc_cmod;
/* See note above on how cmod is divided by the
* scalefactor for area values.
*/
dp->drcc_cdist += (short)(dp->drcc_cmod * scalefactor);
}
else
dp->drcc_cdist += (short)dp->drcc_cmod;
dp->drcc_cmod = 0;
}
}
Expand Down

0 comments on commit 6b8239e

Please sign in to comment.