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:
parent
5791ae3701
commit
0fb19e568c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue