Extended the "maxwidth" DRC rule to take an optional set of layers
that exclude the maxwidth rule from taking effect. This is especially useful for implementing a maxwidth rule on top metal that does not apply to pads, using the passivation cut layer to prevent the maxwidth rule from being applied.
This commit is contained in:
parent
47778971ee
commit
246c0ea7a4
|
|
@ -449,6 +449,31 @@ drcCheckRectSize(starttile, arg, cptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* MaxRectsExclude ---
|
||||||
|
*
|
||||||
|
* Trivial callback function which detects if a type is found
|
||||||
|
* overlapping a Maxrects area.
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* Always return 1 to immediately halt the search.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* None.
|
||||||
|
*
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
MaxRectsExclude(
|
||||||
|
Tile *tile,
|
||||||
|
ClientData clientdata)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -563,10 +588,31 @@ drcCanonicalMaxwidth(starttile, dir, arg, cptr)
|
||||||
mrd->maxdist = edgelimit;
|
mrd->maxdist = edgelimit;
|
||||||
TTMaskCom2(&wrongtypes, &cptr->drcc_mask);
|
TTMaskCom2(&wrongtypes, &cptr->drcc_mask);
|
||||||
boundorig = *boundrect;
|
boundorig = *boundrect;
|
||||||
DBSrPaintArea(starttile, arg->dCD_celldef->cd_planes[cptr->drcc_plane],
|
DBSrPaintArea(starttile, arg->dCD_celldef->cd_planes[cptr->drcc_edgeplane],
|
||||||
&boundorig, &wrongtypes, FindMaxRects, mrd);
|
&boundorig, &wrongtypes, FindMaxRects, mrd);
|
||||||
if (mrd->entries == 0)
|
if (mrd->entries == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
else if (cptr->drcc_plane != cptr->drcc_edgeplane)
|
||||||
|
{
|
||||||
|
/* If the "exclude" option is used, then the maxrect rule will be
|
||||||
|
* ignored for any metal area partially or totally covered by any
|
||||||
|
* type in cptr->drcc_corner on plane cptr->drcc_plane (!=
|
||||||
|
* cptr->drcc_edgeplane).
|
||||||
|
*/
|
||||||
|
for (s = 0; s < mrd->entries; s++)
|
||||||
|
{
|
||||||
|
Rect *r = &(mrd->rlist[s]);
|
||||||
|
if (DBSrPaintArea((Tile *)NULL,
|
||||||
|
arg->dCD_celldef->cd_planes[cptr->drcc_plane],
|
||||||
|
r, &cptr->drcc_corner, MaxRectsExclude, NULL) != 0)
|
||||||
|
{
|
||||||
|
/* Take this area out of consideration */
|
||||||
|
r->r_xtop = r->r_xbot;
|
||||||
|
r->r_ytop = r->r_ybot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (MaxRectsData *)mrd;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return (MaxRectsData *)mrd;
|
return (MaxRectsData *)mrd;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1061,7 +1061,7 @@ DRCTechAddRule(sectionName, argc, argv)
|
||||||
"layers area horizon why"},
|
"layers area horizon why"},
|
||||||
{"off_grid", 4, 4, drcOffGrid,
|
{"off_grid", 4, 4, drcOffGrid,
|
||||||
"layers pitch why"},
|
"layers pitch why"},
|
||||||
{"maxwidth", 4, 5, drcMaxwidth,
|
{"maxwidth", 4, 6, drcMaxwidth,
|
||||||
"layers maxwidth bends why"},
|
"layers maxwidth bends why"},
|
||||||
{"cifstyle", 2, 2, drcCifSetStyle,
|
{"cifstyle", 2, 2, drcCifSetStyle,
|
||||||
"cif_style"},
|
"cif_style"},
|
||||||
|
|
@ -1582,7 +1582,7 @@ drcOffGrid(argc, argv)
|
||||||
* Process a maxwidth rule.
|
* Process a maxwidth rule.
|
||||||
* This is of the form:
|
* This is of the form:
|
||||||
*
|
*
|
||||||
* maxwidth layers distance [bends] why
|
* maxwidth layers distance [bends] [exclude_layers] why
|
||||||
*
|
*
|
||||||
* This routine was updated 3/6/05 to match the "canonical" definition of
|
* This routine was updated 3/6/05 to match the "canonical" definition of
|
||||||
* a maxwidth region, which is any rectangle containing <layers> that is
|
* a maxwidth region, which is any rectangle containing <layers> that is
|
||||||
|
|
@ -1591,6 +1591,11 @@ drcOffGrid(argc, argv)
|
||||||
* (see below) for backwards-compatibility. Otherwise ("bend_ok" or
|
* (see below) for backwards-compatibility. Otherwise ("bend_ok" or
|
||||||
* nothing), the new routine is used.
|
* nothing), the new routine is used.
|
||||||
*
|
*
|
||||||
|
* exclude_layers is optional and indicates a type or types (which if more
|
||||||
|
* than one must all be on the same plane) that prevent "maxwidth" from
|
||||||
|
* being checked. A common use case is using "glass" (passivation cut) to
|
||||||
|
* exclude top metal on a pad from being checked for maximum metal width.
|
||||||
|
*
|
||||||
* maxwidth metal1 389 "metal1 width > 35um must be slotted"
|
* maxwidth metal1 389 "metal1 width > 35um must be slotted"
|
||||||
* maxwidth pmc 4 bend_illegal "poly contact area must be no wider than 4"
|
* maxwidth pmc 4 bend_illegal "poly contact area must be no wider than 4"
|
||||||
* maxwidth trench 4 bend_ok "trench width must be exactly 4"
|
* maxwidth trench 4 bend_ok "trench width must be exactly 4"
|
||||||
|
|
@ -1629,11 +1634,11 @@ drcMaxwidth(argc, argv)
|
||||||
int distance = atoi(argv[2]);
|
int distance = atoi(argv[2]);
|
||||||
char *bends = argv[3];
|
char *bends = argv[3];
|
||||||
int why;
|
int why;
|
||||||
TileTypeBitMask set, setC;
|
TileTypeBitMask set, setC, setE;
|
||||||
DRCCookie *dp, *dpnew;
|
DRCCookie *dp, *dpnew;
|
||||||
TileType i, j;
|
TileType i, j;
|
||||||
PlaneMask pmask, ptest, pset;
|
PlaneMask pmask, pmask2, ptest, pset;
|
||||||
int plane;
|
int plane, plane2;
|
||||||
int bend;
|
int bend;
|
||||||
|
|
||||||
ptest = DBTechNoisyNameMask(layers, &set);
|
ptest = DBTechNoisyNameMask(layers, &set);
|
||||||
|
|
@ -1667,8 +1672,34 @@ drcMaxwidth(argc, argv)
|
||||||
TechError("unknown bend option %s\n",bends);
|
TechError("unknown bend option %s\n",bends);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
if (argc == 6)
|
||||||
|
why = drcWhyCreate(argv[5]);
|
||||||
|
else
|
||||||
why = drcWhyCreate(argv[4]);
|
why = drcWhyCreate(argv[4]);
|
||||||
}
|
}
|
||||||
|
if (argc == 6)
|
||||||
|
{
|
||||||
|
ptest = DBTechNoisyNameMask(argv[4], &setE);
|
||||||
|
pmask2 = CoincidentPlanes(&setE, ptest);
|
||||||
|
if (pmask2 == 0)
|
||||||
|
{
|
||||||
|
TechError("All layers for \"maxwidth\" exclude types must "
|
||||||
|
"be on same plane.\n");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (plane2 = PL_TECHDEPBASE; plane2 < DBNumPlanes; plane2++)
|
||||||
|
if (PlaneMaskHasPlane(pmask2, plane2))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (plane2 == plane)
|
||||||
|
TechError("Warning: Exclude types for \"maxwidth\" are on the "
|
||||||
|
"same plane and so cannot be checked.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
plane2 = -1;
|
||||||
|
|
||||||
for (i = 0; i < DBNumTypes; i++)
|
for (i = 0; i < DBNumTypes; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -1689,8 +1720,12 @@ drcMaxwidth(argc, argv)
|
||||||
/* find bucket preceding the new one we wish to insert */
|
/* find bucket preceding the new one we wish to insert */
|
||||||
dp = drcFindBucket(i, j, distance);
|
dp = drcFindBucket(i, j, distance);
|
||||||
dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie));
|
dpnew = (DRCCookie *) mallocMagic(sizeof (DRCCookie));
|
||||||
|
if (plane2 == -1)
|
||||||
drcAssign(dpnew, distance, dp->drcc_next, &set, &set, why,
|
drcAssign(dpnew, distance, dp->drcc_next, &set, &set, why,
|
||||||
distance, DRC_MAXWIDTH | bend, plane, plane);
|
distance, DRC_MAXWIDTH | bend, plane, plane);
|
||||||
|
else
|
||||||
|
drcAssign(dpnew, distance, dp->drcc_next, &set, &setE, why,
|
||||||
|
distance, DRC_MAXWIDTH | bend, plane2, plane);
|
||||||
|
|
||||||
dp->drcc_next = dpnew;
|
dp->drcc_next = dpnew;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue