Re-implemented parts of the DRC angle check to make it consider

that all layer types passed to a single "angles" statement in the
tech file are mutually non-interacting.  That is, "angles allm1 45"
will check angles on edges between metal1 and space, but not edges
between metal1 and via (which makes sense, given that a via is an
area into which to place contact cuts, and its edge is not a
physical boundary).
This commit is contained in:
R. Timothy Edwards 2025-08-06 09:22:12 -04:00
parent a3d02d92cc
commit 3472474617
3 changed files with 39 additions and 36 deletions

View File

@ -1 +1 @@
8.3.536
8.3.537

View File

@ -478,34 +478,18 @@ drcTile (tile, arg)
int deltax, deltay;
TileType tt, to;
/* Check rules for DRC_ANGLES_90 rule and process */
tt = TiGetLeftType(tile);
if (tt != TT_SPACE)
{
for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt];
cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next)
if (cptr->drcc_flags & DRC_ANGLES_90)
{
drcCheckAngles(tile, arg, cptr);
break;
}
}
tt = TiGetRightType(tile);
if (tt != TT_SPACE)
{
for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt];
cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next)
if (cptr->drcc_flags & DRC_ANGLES_90)
{
drcCheckAngles(tile, arg, cptr);
break;
}
}
/* Full check of edge rules along the diagonal. */
tt = TiGetLeftType(tile); /* inside type */
to = TiGetRightType(tile); /* outside type */
/* Check rules for DRC_ANGLES_90 rule and process */
for (cptr = DRCCurStyle->DRCRulesTbl[to][tt];
cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next)
if (cptr->drcc_flags & DRC_ANGLES_90)
{
drcCheckAngles(tile, arg, cptr);
break;
}
for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL;
cptr = cptr->drcc_next)
{

View File

@ -1708,6 +1708,12 @@ drcMaxwidth(argc, argv)
* must be limited to 90 degrees or 45 degrees. If not specified, any
* angle is allowed, although width rules will flag errors on acute angles.
*
* For all types in "layers" (argv[1]), edges between types on the same
* plane are considered false edges (e.g., if poly is 90-degrees only,
* then a transistor-to-poly edge is not considered because it represents
* an angled edge on diffusion, not poly, assuming that both poly and
* transistor types appear in the layers list).
*
* ----------------------------------------------------------------------------
*/
@ -1763,7 +1769,7 @@ drcAngles(argc, argv)
if (pmask == 0)
{
TechError("All types for \"rect_only\" must be on the same plane.\n");
TechError("All types for \"angles\" must be on the same plane.\n");
return 0;
}
@ -1842,16 +1848,29 @@ drcAngles(argc, argv)
{
plane = DBPlane(i);
/* Insert rule at boundary of tile and TT_SPACE. This is */
/* processed for each tile, separately from other rules, so */
/* we don't really care what the edge is; TT_SPACE is */
/* chosen as an arbitrary place to hold the rule. */
/* Insert rule at boundary of type and all other types */
/* in the same plane that do not belong to the layer list. */
dp = drcFindBucket(TT_SPACE, i, 1);
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why,
1, angles, plane, plane);
dp->drcc_next = dpnew;
for (j = 0; j < DBNumTypes; j++)
{
if (i == j) continue;
if ((j != TT_SPACE) && (DBPlane(j) != plane)) continue;
if (!TTMaskHasType(&set, j))
{
dp = drcFindBucket(j, i, 1);
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why,
1, angles, plane, plane);
dp->drcc_next = dpnew;
dp = drcFindBucket(i, j, 1);
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why,
1, angles | DRC_REVERSE, plane, plane);
dp->drcc_next = dpnew;
}
}
}
}
return 1;