Extended the "spacing" and "edge"/"edge4way" rules to take an

option "manhattan_dist" that causes corner checks to assume a
manhattan distance measure.  This is useful for checking
distances involving generated edges that are created by a CIF
"grow" operator.  For "spacing", "manhattan_dist" is equivalent
to "touching_illegal", as a use-case for forcing manhattan
distance measurements in corners has not been found for other
"spacing" options.
This commit is contained in:
R. Timothy Edwards 2025-08-13 11:34:29 -04:00
parent 5791ae3701
commit 0fb19e568c
4 changed files with 61 additions and 28 deletions

View File

@ -1 +1 @@
8.3.539
8.3.540

View File

@ -823,7 +823,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpr)))
{
errRect.r_ybot -= cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_SW;
}
}
@ -851,7 +851,8 @@ drcTile (tile, arg)
TiGetBottomType(tpr)))
{
errRect.r_ytop += cdist;
if (DRCEuclidean)
if (DRCEuclidean &&
!(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_NW;
}
}
@ -897,7 +898,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpl)))
{
errRect.r_ytop += cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_NE;
}
}
@ -924,7 +925,8 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpl)))
{
errRect.r_ybot -= cdist;
if (DRCEuclidean)
if (DRCEuclidean &&
!(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_SE;
}
}
@ -1196,7 +1198,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpx)))
{
errRect.r_xtop += cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_SE;
}
@ -1213,7 +1215,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetBottomType(tpx)))
{
errRect.r_xbot -= cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_SW;
}
}
@ -1250,7 +1252,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpx)))
{
errRect.r_xbot -= cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_NW;
}
@ -1266,7 +1268,7 @@ drcTile (tile, arg)
if (TTMaskHasType(&cptr->drcc_corner, TiGetTopType(tpx)))
{
errRect.r_xtop += cdist;
if (DRCEuclidean)
if (DRCEuclidean && !(cptr->drcc_flags & DRC_MANHATTAN))
arg->dCD_radial |= RADIAL_NE;
}
}

View File

@ -1031,10 +1031,10 @@ DRCTechAddRule(sectionName, argc, argv)
} ruleKeys[] = {
{"angles", 4, 4, drcAngles,
"layers 45|90 why"},
{"edge", 8, 9, drcEdge,
"layers1 layers2 distance okTypes cornerTypes cornerDistance why [plane]"},
{"edge4way", 8, 9, drcEdge,
"layers1 layers2 distance okTypes cornerTypes cornerDistance why [plane]"},
{"edge", 8, 10, drcEdge,
"layers1 layers2 distance okTypes cornerTypes cornerDistance [option] why [plane]"},
{"edge4way", 8, 10, drcEdge,
"layers1 layers2 distance okTypes cornerTypes cornerDistance [option] why [plane]"},
{"exact_overlap", 2, 2, drcExactOverlap,
"layers"},
{"extend", 5, 6, drcExtend,
@ -1985,6 +1985,10 @@ drcSpacing3(argc, argv)
* Side effects:
* Adds rules to the DRC rule table.
*
* Notes:
* 8/13/2025: Added "manhattan_dist" as an option indicating
* that corner checks should assume manhattan distance. Otherwise
* the rule type is the same as "touching_illegal".
*-------------------------------------------------------------------
*/
@ -2010,6 +2014,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
bool touchingok = TRUE;
bool cornerok = FALSE;
bool surroundok = FALSE;
unsigned short flags = 0;
if (!strcmp(adjacency, "surround_ok"))
{
@ -2065,6 +2070,12 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
touchingok = FALSE;
needtrigger = FALSE;
}
else if (!strcmp(adjacency, "manhattan_dist"))
{
touchingok = FALSE;
needtrigger = FALSE;
flags = DRC_MANHATTAN;
}
else
{
TechError("Badly formed drc spacing line: need \"touching_ok\", "
@ -2198,7 +2209,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
else
{
drcAssign(dpnew, distance, dp->drcc_next, &tmp1,
&tmp2, why, wwidth, DRC_FORWARD, plane2, plane);
&tmp2, why, wwidth, DRC_FORWARD | flags, plane2, plane);
dp->drcc_next = dpnew;
}
@ -2267,7 +2278,8 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
{
drcAssign(dpnew,distance,dp->drcc_next,
&tmp1, &tmp2, why, wwidth,
DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane);
DRC_REVERSE | DRC_BOTHCORNERS | flags,
plane2, plane);
dp->drcc_next = dpnew;
}
}
@ -2320,7 +2332,8 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
else
{
drcAssign(dpnew, distance, dp->drcc_next, &tmp1, &tmp2,
why, distance, DRC_FORWARD, plane2, plane);
why, distance, DRC_FORWARD | flags,
plane2, plane);
dp->drcc_next = dpnew;
}
@ -2358,7 +2371,8 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
{
drcAssign(dpnew, distance, dp->drcc_next,
&tmp1, &tmp2, why, distance,
DRC_REVERSE | DRC_BOTHCORNERS, plane2, plane);
DRC_REVERSE | DRC_BOTHCORNERS | flags,
plane2, plane);
dp->drcc_next = dpnew;
}
}
@ -2418,7 +2432,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
TTMaskZero(&tmp2);
drcAssign(dpnew, 1, dp->drcc_next, &tmp1, &tmp2, why,
distance, DRC_FORWARD, plane2, plane);
distance, DRC_FORWARD | flags, plane2, plane);
dp->drcc_next = dpnew;
}
}
@ -2640,8 +2654,8 @@ drcSpacing(argc, argv)
* Process a primitive edge rule.
* This is of the form:
*
* edge layers1 layers2 dist OKtypes cornerTypes cornerDist why [plane]
* or edge4way layers1 layers2 dist OKtypes cornerTypes cornerDist why [plane]
* edge layers1 layers2 dist OKtypes cornerTypes cornerDist [option] why [plane]
* or edge4way layers1 layers2 dist OKtypes cornerTypes cornerDist [option] why [plane]
*
* e.g,
*
@ -2650,6 +2664,9 @@ drcSpacing(argc, argv)
* An "edge" rule is applied only down and to the left.
* An "edge4way" rule is applied in all four directions.
*
* "option" can be "manhattan_dist", which forces the corner areas to be
* checked per manhattan distance rules, not euclidean distance rules.
*
* Results:
* Returns greater of dist and cdist.
*
@ -2668,14 +2685,30 @@ drcEdge(argc, argv)
int distance = atoi(argv[3]);
char *okTypes = argv[4], *cornerTypes = argv[5];
int cdist = atoi(argv[6]);
int why = drcWhyCreate(argv[7]);
unsigned short flags = 0;
int why;
bool fourway = (strcmp(argv[0], "edge4way") == 0);
TileTypeBitMask set1, set2, setC, setM;
DRCCookie *dp, *dpnew;
int plane, checkPlane, tmpPlane;
int plane, checkPlane, tmpPlane = 0;
PlaneMask pMask1, pMaskM, pMaskC, pset, ptest;
TileType i, j;
if ((argc > 7) && (!strcmp(argv[7], "manhattan_dist")))
{
flags = DRC_MANHATTAN;
why = drcWhyCreate(argv[8]);
if (argc == 10)
tmpPlane = DBTechNoisyNamePlane(argv[9]);
argc--;
}
else
{
why = drcWhyCreate(argv[7]);
if (argc == 9)
tmpPlane = DBTechNoisyNamePlane(argv[8]);
}
/*
* Edge4way rules produce [j][i] entries as well as [i][j]
* ones, and check both corners rather than just one corner.
@ -2708,9 +2741,6 @@ drcEdge(argc, argv)
return (0);
}
if (argc == 9)
tmpPlane = DBTechNoisyNamePlane(argv[8]);
/*
* OKtypes determine the checkPlane. If checkPlane exists, it should
* only be used to check against the plane of OKtypes.
@ -2786,7 +2816,7 @@ drcEdge(argc, argv)
dp = drcFindBucket(i, j, distance);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, distance, dp->drcc_next, &setM, &setC,
why, cdist, DRC_FORWARD, checkPlane, plane);
why, cdist, DRC_FORWARD | flags, checkPlane, plane);
if (fourway) dpnew->drcc_flags |= DRC_BOTHCORNERS;
dp->drcc_next = dpnew;
@ -2796,7 +2826,7 @@ drcEdge(argc, argv)
dp = drcFindBucket(j, i, distance);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew,distance,dp->drcc_next, &setM, &setC,
why, cdist, DRC_REVERSE, checkPlane, plane);
why, cdist, DRC_REVERSE | flags, checkPlane, plane);
dpnew->drcc_flags |= DRC_BOTHCORNERS;
dp->drcc_next = dpnew;
}

View File

@ -80,11 +80,12 @@ typedef struct drccookie
#define DRC_ANGLES_90 0x0800
#define DRC_SPLITTILE 0x1000
#define DRC_RUNLENGTH 0x2000
#define DRC_MANHATTAN 0x4000
#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE\
|DRC_ANGLES_90|DRC_OFFGRID)
/* More flags for indicating what the rule type represents */
#define DRC_CIFRULE 0x4000
#define DRC_CIFRULE 0x8000
#define DRC_PENDING 0
#define DRC_UNPROCESSED CLIENTDEFAULT