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:
parent
30ab57ee79
commit
8b2c33d8dd
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
119
drc/DRCtech.c
119
drc/DRCtech.c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue