Added new tech DRC rule option "angles 45-only", which handles

rules such as "No 90 degree bends on transistors".
This commit is contained in:
Tim Edwards 2022-04-20 16:16:20 -04:00
parent 30ab57ee79
commit 8b2c33d8dd
5 changed files with 138 additions and 31 deletions

View File

@ -260,7 +260,10 @@ areaCheck(tile, arg)
}
arg->dCD_rlist[arg->dCD_entries - 1] = rect;
}
else
/* "angles 45-only" needs to reject errors that are inside split tiles */
else if (!IsSplit(tile) ||
((arg->dCD_cptr->drcc_flags & (DRC_ANGLES_45 | DRC_ANGLES_90))
!= DRC_ANGLES_45))
{
(*(arg->dCD_function))(arg->dCD_celldef, &rect, arg->dCD_cptr,
arg->dCD_clientData);
@ -461,13 +464,13 @@ drcTile (tile, arg)
int deltax, deltay;
TileType tt, to;
/* Check rules for DRC_ANGLES rule and process */
/* 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)
if (cptr->drcc_flags & DRC_ANGLES_90)
{
drcCheckAngles(tile, arg, cptr);
break;
@ -478,7 +481,7 @@ drcTile (tile, arg)
{
for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][tt];
cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next)
if (cptr->drcc_flags & DRC_ANGLES)
if (cptr->drcc_flags & DRC_ANGLES_90)
{
drcCheckAngles(tile, arg, cptr);
break;
@ -508,7 +511,7 @@ drcTile (tile, arg)
/* Note: Triggered wide-spacing rule will require handling */
/* the DRC_MAXWIDTH rule on non-Manhattan edges. */
if (cptr->drcc_flags & (DRC_ANGLES | DRC_AREA | DRC_MAXWIDTH
if (cptr->drcc_flags & (DRC_ANGLES_90 | DRC_AREA | DRC_MAXWIDTH
| DRC_RECTSIZE | DRC_OFFGRID))
continue;
@ -643,7 +646,7 @@ drcTile (tile, arg)
for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL;
cptr = cptr->drcc_next)
{
if (cptr->drcc_flags & DRC_ANGLES) continue;
if (cptr->drcc_flags & DRC_ANGLES_90) continue;
/* Find the rule distances according to the scale factor */
dist = cptr->drcc_dist;
@ -1041,7 +1044,7 @@ drcTile (tile, arg)
for (cptr = DRCCurStyle->DRCRulesTbl[to][tt]; cptr != (DRCCookie *) NULL;
cptr = cptr->drcc_next)
{
if (cptr->drcc_flags & DRC_ANGLES) continue;
if (cptr->drcc_flags & DRC_ANGLES_90) continue;
/* Find the rule distances according to the scale factor */
dist = cptr->drcc_dist;

View File

@ -40,6 +40,9 @@ Stack *DRCstack = (Stack *)NULL;
*
* Side Effects: may cause errors to be painted.
*
* NOTES: Tile has been determined to be a split tile before this
* routine is called.
*
*-------------------------------------------------------------------------
*/
@ -51,21 +54,18 @@ drcCheckAngles(tile, arg, cptr)
DRCCookie *cptr;
{
Rect rect;
int ortho = (cptr->drcc_flags & 0x01); /* 1 = orthogonal, 0 = 45s */
bool ortho = (cptr->drcc_flags & DRC_ANGLES_45) ? FALSE : TRUE;
if (IsSplit(tile))
if (ortho || ((RIGHT(tile) - LEFT(tile)) != (TOP(tile) - BOTTOM(tile))))
{
if (ortho || (RIGHT(tile) - LEFT(tile)) != (TOP(tile) - BOTTOM(tile)))
TiToRect(tile, &rect);
GeoClip(&rect, arg->dCD_clip);
if (!GEO_RECTNULL(&rect))
{
TiToRect(tile, &rect);
GeoClip(&rect, arg->dCD_clip);
if (!GEO_RECTNULL(&rect))
{
arg->dCD_cptr = cptr;
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
arg->dCD_cptr = cptr;
(*(arg->dCD_function)) (arg->dCD_celldef, &rect,
arg->dCD_cptr, arg->dCD_clientData);
(*(arg->dCD_errors))++;
}
(*(arg->dCD_errors))++;
}
}
}

View File

@ -129,8 +129,10 @@ DRCPrintRulesTable (fp)
fprintf(fp," bends");
if (dp->drcc_flags & DRC_RECTSIZE)
fprintf(fp," rect-size");
if (dp->drcc_flags & DRC_ANGLES)
fprintf(fp," angles");
if (dp->drcc_flags & DRC_ANGLES_45)
fprintf(fp," angles_45");
if (dp->drcc_flags & DRC_ANGLES_90)
fprintf(fp," angles_90");
fprintf(fp,"\n");
}
}

View File

@ -1667,22 +1667,123 @@ drcAngles(argc, argv)
char *argv[];
{
char *layers = argv[1];
int angles = atoi(argv[2]);
char *endptr;
long value;
int angles;
int why = drcWhyCreate(argv[3]);
TileTypeBitMask set;
DRCCookie *dp, *dpnew;
int plane;
PlaneMask ptest, pset, pmask;
TileType i, j;
DBTechNoisyNameMask(layers, &set);
value = strtol(argv[2], &endptr, 10);
angles /= 45;
angles--; /* angles now 0 for 45s and 1 for 90s */
if ((angles != 0) && (angles != 1))
switch (value)
{
TechError("angles must be 45 or 90\n");
return 0;
case 45:
angles = DRC_ANGLES_45 | DRC_ANGLES_90;
break;
case 90:
angles = DRC_ANGLES_90;
break;
default:
TechError("angles must be 45 or 90\n");
return 0;
}
if (endptr != NULL)
if (!strcmp(endptr + 1, "only"))
if (angles & DRC_ANGLES_45)
angles = DRC_ANGLES_45; /* 45 degrees only */
ptest = DBTechNoisyNameMask(layers, &set);
/* The 45 degrees only case is implemented like drcRectOnly, except */
/* that drcRectOnly checks only for inside corners, while this */
/* also checks for outside corners. Where inside and outside */
/* corners have been beveled, the error is discarded while */
/* processing. */
if (angles == DRC_ANGLES_45)
{
TileTypeBitMask set2, setC, setM;
pmask = CoincidentPlanes(&set, ptest);
if (pmask == 0)
{
TechError("All types for \"rect_only\" must be on the same plane.\n");
return 0;
}
/* set2 is the inverse of set */
TTMaskCom2(&set2, &set);
for (i = 0; i < DBNumTypes; i++)
{
for (j = 0; j < DBNumTypes; j++)
{
if (i == j) continue;
if (pset = (DBTypesOnSamePlane(i, j) & pmask))
{
/* Inside corners */
if (TTMaskHasType(&set, i) && TTMaskHasType(&set2, j))
{
plane = LowestMaskBit(pset);
/* setC = all types in plane */
TTMaskZero(&setC);
TTMaskSetMask(&setC, &DBPlaneTypes[plane]);
/* Find bucket preceding the new one we wish to insert */
dp = drcFindBucket(i, j, 1);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, 1, dp->drcc_next, &set2, &setC, why, 1,
angles | DRC_FORWARD | DRC_BOTHCORNERS,
plane, plane);
dp->drcc_next = dpnew;
/* find bucket preceding new one we wish to insert */
dp = drcFindBucket(j, i, 1);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, 1, dp->drcc_next, &set2, &setC, why, 1,
angles | DRC_REVERSE | DRC_BOTHCORNERS,
plane, plane);
dp->drcc_next = dpnew;
}
/* Outside corners */
if (TTMaskHasType(&set2, i) && TTMaskHasType(&set, j))
{
plane = LowestMaskBit(pset);
/* setC = all types in plane */
TTMaskZero(&setC);
TTMaskSetMask(&setC, &DBPlaneTypes[plane]);
/* setM = not(i) */
TTMaskSetOnlyType(&setM, i);
TTMaskCom(&setM);
/* Find bucket preceding the new one we wish to insert */
dp = drcFindBucket(i, j, 1);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, 1, dp->drcc_next, &setM, &setC, why, 1,
angles | DRC_FORWARD | DRC_BOTHCORNERS,
plane, plane);
dp->drcc_next = dpnew;
/* find bucket preceding new one we wish to insert */
dp = drcFindBucket(j, i, 1);
dpnew = (DRCCookie *)mallocMagic(sizeof (DRCCookie));
drcAssign(dpnew, 1, dp->drcc_next, &setM, &setC, why, 1,
angles | DRC_REVERSE | DRC_BOTHCORNERS,
plane, plane);
dp->drcc_next = dpnew;
}
}
}
}
}
for (i = 0; i < DBNumTypes; i++)
@ -1699,7 +1800,7 @@ drcAngles(argc, argv)
dp = drcFindBucket(TT_SPACE, i, 1);
dpnew = (DRCCookie *) mallocMagic((unsigned) (sizeof (DRCCookie)));
drcAssign(dpnew, 1, dp->drcc_next, &set, &set, why,
1, DRC_ANGLES | angles, plane, plane);
1, angles, plane, plane);
dp->drcc_next = dpnew;
}
}

View File

@ -75,9 +75,10 @@ typedef struct drccookie
#define DRC_MAXWIDTH 0x080
#define DRC_MAXWIDTH_BOTH 0x100
#define DRC_RECTSIZE 0x200
#define DRC_ANGLES 0x400
#define DRC_ANGLES_45 0x400
#define DRC_ANGLES_90 0x800
#define DRC_NONSTANDARD (DRC_AREA|DRC_MAXWIDTH|DRC_RECTSIZE\
|DRC_ANGLES|DRC_OFFGRID)
|DRC_ANGLES_90|DRC_OFFGRID)
/* More flags for indicating what the rule type represents */
#define DRC_CIFRULE 0x400