Modifed the DRC section of the techfile to add two additional
behaviors: (1) An additional syntax for "widespacing" that allows both the triggering metal's width AND run-length, which is typical of rules in 65nm-and-below processes; and (2) a new "option" statement for the DRC section, with (for now) one possible flag "wide-width-noninclusive", indicating that the metal width given for "widespacing" rules means that a violation is only triggered for material with a width greater than the given rule width (as opposed to the default interpretation of a width greater than or equal to the given rule width).
This commit is contained in:
parent
f8b79133fb
commit
005a4880a3
|
|
@ -546,7 +546,9 @@ drcTile (tile, arg)
|
||||||
Rect *lr;
|
Rect *lr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!trigpending) cptr->drcc_dist++;
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||||
|
cptr->drcc_dist++;
|
||||||
|
|
||||||
if (cptr->drcc_flags & DRC_REVERSE)
|
if (cptr->drcc_flags & DRC_REVERSE)
|
||||||
mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr);
|
mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr);
|
||||||
|
|
@ -554,14 +556,23 @@ drcTile (tile, arg)
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr);
|
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr);
|
||||||
else
|
else
|
||||||
mrd = NULL;
|
mrd = NULL;
|
||||||
if (!trigpending) cptr->drcc_dist--;
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||||
|
cptr->drcc_dist--;
|
||||||
if (trigpending)
|
if (trigpending)
|
||||||
{
|
{
|
||||||
if (mrd)
|
if (mrd)
|
||||||
|
{
|
||||||
|
/* Run-length rule */
|
||||||
|
if ((cptr->drcc_cdist <= cptr->drcc_dist) ||
|
||||||
|
((edgeTop - edgeBot) > cptr->drcc_cdist))
|
||||||
triggered = mrd->entries;
|
triggered = mrd->entries;
|
||||||
else
|
else
|
||||||
cptr = cptr->drcc_next;
|
cptr = cptr->drcc_next;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
cptr = cptr->drcc_next;
|
||||||
|
}
|
||||||
else if (mrd)
|
else if (mrd)
|
||||||
{
|
{
|
||||||
for (i = 0; i < mrd->entries; i++)
|
for (i = 0; i < mrd->entries; i++)
|
||||||
|
|
@ -903,7 +914,9 @@ checkbottom:
|
||||||
Rect *lr;
|
Rect *lr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!trigpending) cptr->drcc_dist++;
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||||
|
cptr->drcc_dist++;
|
||||||
|
|
||||||
if (cptr->drcc_flags & DRC_REVERSE)
|
if (cptr->drcc_flags & DRC_REVERSE)
|
||||||
mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr);
|
mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr);
|
||||||
|
|
@ -911,13 +924,20 @@ checkbottom:
|
||||||
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr);
|
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr);
|
||||||
else
|
else
|
||||||
mrd = NULL;
|
mrd = NULL;
|
||||||
if (!trigpending) cptr->drcc_dist--;
|
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||||
|
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||||
|
cptr->drcc_dist--;
|
||||||
if (trigpending)
|
if (trigpending)
|
||||||
{
|
{
|
||||||
if (mrd)
|
if (mrd)
|
||||||
|
/* Run-length rule */
|
||||||
|
if ((cptr->drcc_cdist <= cptr->drcc_dist) ||
|
||||||
|
((edgeRight - edgeLeft) > cptr->drcc_cdist))
|
||||||
triggered = mrd->entries;
|
triggered = mrd->entries;
|
||||||
else
|
else
|
||||||
cptr = cptr->drcc_next;
|
cptr = cptr->drcc_next;
|
||||||
|
else
|
||||||
|
cptr = cptr->drcc_next;
|
||||||
}
|
}
|
||||||
else if (mrd)
|
else if (mrd)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ static int drcRulesOptimized = 0;
|
||||||
int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap();
|
int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap();
|
||||||
int drcExactOverlap(), drcExtend();
|
int drcExactOverlap(), drcExtend();
|
||||||
int drcSurround(), drcRectOnly(), drcOverhang();
|
int drcSurround(), drcRectOnly(), drcOverhang();
|
||||||
int drcStepSize();
|
int drcStepSize(), drcOption();
|
||||||
int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles();
|
int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles();
|
||||||
int drcCifSetStyle(), drcCifWidth(), drcCifSpacing();
|
int drcCifSetStyle(), drcCifWidth(), drcCifSpacing();
|
||||||
int drcCifMaxwidth(), drcCifArea();
|
int drcCifMaxwidth(), drcCifArea();
|
||||||
|
|
@ -540,6 +540,7 @@ DRCTechStyleInit()
|
||||||
DRCCurStyle->DRCScaleFactorN = 1;
|
DRCCurStyle->DRCScaleFactorN = 1;
|
||||||
DRCCurStyle->DRCScaleFactorD = 1;
|
DRCCurStyle->DRCScaleFactorD = 1;
|
||||||
DRCCurStyle->DRCStepSize = 0;
|
DRCCurStyle->DRCStepSize = 0;
|
||||||
|
DRCCurStyle->DRCFlags = (char)0;
|
||||||
|
|
||||||
DRCTechHalo = 0;
|
DRCTechHalo = 0;
|
||||||
|
|
||||||
|
|
@ -959,6 +960,8 @@ DRCTechAddRule(sectionName, argc, argv)
|
||||||
"layers1 layers2 distance why",
|
"layers1 layers2 distance why",
|
||||||
"no_overlap", 3, 3, drcNoOverlap,
|
"no_overlap", 3, 3, drcNoOverlap,
|
||||||
"layers1 layers2",
|
"layers1 layers2",
|
||||||
|
"option", 2, 2, drcOption,
|
||||||
|
"option_name option_value",
|
||||||
"overhang", 5, 5, drcOverhang,
|
"overhang", 5, 5, drcOverhang,
|
||||||
"layers1 layers2 distance why",
|
"layers1 layers2 distance why",
|
||||||
"rect_only", 3, 3, drcRectOnly,
|
"rect_only", 3, 3, drcRectOnly,
|
||||||
|
|
@ -971,7 +974,7 @@ DRCTechAddRule(sectionName, argc, argv)
|
||||||
"layers1 layers2 distance presence why",
|
"layers1 layers2 distance presence why",
|
||||||
"width", 4, 4, drcWidth,
|
"width", 4, 4, drcWidth,
|
||||||
"layers width why",
|
"layers width why",
|
||||||
"widespacing", 7, 7, drcSpacing,
|
"widespacing", 7, 8, drcSpacing,
|
||||||
"layers1 width layers2 separation adjacency why",
|
"layers1 width layers2 separation adjacency why",
|
||||||
"area", 5, 5, drcArea,
|
"area", 5, 5, drcArea,
|
||||||
"layers area horizon why",
|
"layers area horizon why",
|
||||||
|
|
@ -1661,12 +1664,14 @@ drcSpacing3(argc, argv)
|
||||||
|
|
||||||
int
|
int
|
||||||
drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||||
why, widerule, multiplane)
|
why, widerule, runlength, multiplane)
|
||||||
TileTypeBitMask *set1, *set2;
|
TileTypeBitMask *set1, *set2;
|
||||||
PlaneMask pmask1, pmask2;
|
PlaneMask pmask1, pmask2;
|
||||||
int wwidth, distance;
|
int wwidth, distance;
|
||||||
char *adjacency, *why;
|
char *adjacency, *why;
|
||||||
bool widerule, multiplane;
|
bool widerule;
|
||||||
|
int runlength;
|
||||||
|
bool multiplane;
|
||||||
{
|
{
|
||||||
TileTypeBitMask tmp1, tmp2, setR, setRreverse;
|
TileTypeBitMask tmp1, tmp2, setR, setRreverse;
|
||||||
int plane, plane2;
|
int plane, plane2;
|
||||||
|
|
@ -1825,7 +1830,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||||
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
||||||
(sizeof (DRCCookie)));
|
(sizeof (DRCCookie)));
|
||||||
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
||||||
wwidth, DRC_REVERSE | DRC_MAXWIDTH |
|
runlength, DRC_REVERSE | DRC_MAXWIDTH |
|
||||||
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
||||||
|
|
||||||
dp->drcc_next = dptrig;
|
dp->drcc_next = dptrig;
|
||||||
|
|
@ -1880,7 +1885,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||||
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
||||||
(sizeof (DRCCookie)));
|
(sizeof (DRCCookie)));
|
||||||
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
||||||
wwidth, DRC_FORWARD | DRC_MAXWIDTH |
|
runlength, DRC_FORWARD | DRC_MAXWIDTH |
|
||||||
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
||||||
dp->drcc_next = dptrig;
|
dp->drcc_next = dptrig;
|
||||||
}
|
}
|
||||||
|
|
@ -2089,7 +2094,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||||
* Notes:
|
* Notes:
|
||||||
* Extended to include the rule syntax:
|
* Extended to include the rule syntax:
|
||||||
*
|
*
|
||||||
* widespacing layers1 width layers2 distance adjacency why
|
* widespacing layers1 width [runlength] layers2 distance adjacency why
|
||||||
*
|
*
|
||||||
* This extension covers rules such as "If m1 width > 10um, then spacing to
|
* This extension covers rules such as "If m1 width > 10um, then spacing to
|
||||||
* unconnected m1 must be at least 0.6um". This assumes that the instantiated
|
* unconnected m1 must be at least 0.6um". This assumes that the instantiated
|
||||||
|
|
@ -2113,6 +2118,10 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||||
* (Added 11/6/06) Adjacency may be "corner_ok", in which case it calls
|
* (Added 11/6/06) Adjacency may be "corner_ok", in which case it calls
|
||||||
* routing drcSpacing3() (see above).
|
* routing drcSpacing3() (see above).
|
||||||
*
|
*
|
||||||
|
* (Added 9/19/18) Additional run-length distance can be used to limit the
|
||||||
|
* maxwidth rule to geometry exceeding the given run-length (often used with
|
||||||
|
* 65nm and smaller feature size processes).
|
||||||
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -2126,7 +2135,7 @@ drcSpacing(argc, argv)
|
||||||
char *why;
|
char *why;
|
||||||
TileTypeBitMask set1, set2, tmp1, tmp2;
|
TileTypeBitMask set1, set2, tmp1, tmp2;
|
||||||
PlaneMask pmask1, pmask2, pmaskA, pmaskB, ptest;
|
PlaneMask pmask1, pmask2, pmaskA, pmaskB, ptest;
|
||||||
int wwidth, distance, plane, plane2;
|
int wwidth, distance, plane, plane2, runlength;
|
||||||
bool widerule, multiplane = FALSE;
|
bool widerule, multiplane = FALSE;
|
||||||
|
|
||||||
if ((argc == 7) && (!strcmp(argv[4], "corner_ok")))
|
if ((argc == 7) && (!strcmp(argv[4], "corner_ok")))
|
||||||
|
|
@ -2137,10 +2146,23 @@ drcSpacing(argc, argv)
|
||||||
if (widerule)
|
if (widerule)
|
||||||
{
|
{
|
||||||
wwidth = atoi(argv[2]);
|
wwidth = atoi(argv[2]);
|
||||||
|
|
||||||
|
if (argc == 8)
|
||||||
|
{
|
||||||
|
runlength = atoi(argv[3]);
|
||||||
|
layers2 = argv[4];
|
||||||
|
distance = atoi(argv[5]);
|
||||||
|
adjacency = argv[6];
|
||||||
|
why = drcWhyDup(argv[7]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runlength = distance;
|
||||||
layers2 = argv[3];
|
layers2 = argv[3];
|
||||||
distance = atoi(argv[4]);
|
distance = atoi(argv[4]);
|
||||||
adjacency = argv[5];
|
adjacency = argv[5];
|
||||||
why = drcWhyDup(argv[6]);
|
why = drcWhyDup(argv[6]);
|
||||||
|
}
|
||||||
/* TxPrintf("Info: DRCtech: widespacing rule for %s width %d:"
|
/* TxPrintf("Info: DRCtech: widespacing rule for %s width %d:"
|
||||||
" spacing must be %d\n", layers1, wwidth, distance); */
|
" spacing must be %d\n", layers1, wwidth, distance); */
|
||||||
}
|
}
|
||||||
|
|
@ -2151,7 +2173,8 @@ drcSpacing(argc, argv)
|
||||||
adjacency = argv[4];
|
adjacency = argv[4];
|
||||||
wwidth = distance;
|
wwidth = distance;
|
||||||
why = drcWhyDup(argv[5]);
|
why = drcWhyDup(argv[5]);
|
||||||
if (argc == 7)
|
runlength = distance;
|
||||||
|
if (argc >= 7)
|
||||||
{
|
{
|
||||||
TechError("Unknown argument in spacing line.\n");
|
TechError("Unknown argument in spacing line.\n");
|
||||||
return(0);
|
return(0);
|
||||||
|
|
@ -2236,13 +2259,13 @@ drcSpacing(argc, argv)
|
||||||
|
|
||||||
return drcMaskSpacing(&tmp1, &tmp2, pmaskA, pmaskB,
|
return drcMaskSpacing(&tmp1, &tmp2, pmaskA, pmaskB,
|
||||||
wwidth, distance, adjacency, why,
|
wwidth, distance, adjacency, why,
|
||||||
widerule, multiplane);
|
widerule, runlength, multiplane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return drcMaskSpacing(&set1, &set2, pmask1, pmask2, wwidth,
|
return drcMaskSpacing(&set1, &set2, pmask1, pmask2, wwidth,
|
||||||
distance, adjacency, why, widerule, multiplane);
|
distance, adjacency, why, widerule, runlength, multiplane);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -3152,6 +3175,53 @@ drcRectangle(argc, argv)
|
||||||
return maxwidth;
|
return maxwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* drcOption --
|
||||||
|
*
|
||||||
|
* Process an option declaration
|
||||||
|
* This is of the form:
|
||||||
|
*
|
||||||
|
* option option_name [...]
|
||||||
|
*
|
||||||
|
* e.g,
|
||||||
|
*
|
||||||
|
* option wide-width-inclusive
|
||||||
|
*
|
||||||
|
* Results:
|
||||||
|
* Returns 0.
|
||||||
|
*
|
||||||
|
* Side effects:
|
||||||
|
* Updates DRCFlags.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
drcOption(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (DRCCurStyle == NULL) return 0;
|
||||||
|
|
||||||
|
/* Assume space-separated list of options. Flag an error on any */
|
||||||
|
/* option name not recognized. */
|
||||||
|
|
||||||
|
for (i = 1; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(argv[i], "wide-width-noninclusive"))
|
||||||
|
DRCCurStyle->DRCFlags |= DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TechError("Unrecognized DRC option \"%s\" (ignored).\n", argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
14
drc/drc.h
14
drc/drc.h
|
|
@ -172,10 +172,24 @@ typedef struct drcstyle
|
||||||
int DRCScaleFactorD; /* Multiply dist by this to get magic units */
|
int DRCScaleFactorD; /* Multiply dist by this to get magic units */
|
||||||
int DRCTechHalo; /* largest action distance of design rules */
|
int DRCTechHalo; /* largest action distance of design rules */
|
||||||
int DRCStepSize; /* chunk size for decomposing large areas */
|
int DRCStepSize; /* chunk size for decomposing large areas */
|
||||||
|
char DRCFlags; /* Option flags */
|
||||||
drcWhyList *DRCWhyList;
|
drcWhyList *DRCWhyList;
|
||||||
PaintResultType DRCPaintTable[NP][NT][NT];
|
PaintResultType DRCPaintTable[NP][NT][NT];
|
||||||
} DRCStyle;
|
} DRCStyle;
|
||||||
|
|
||||||
|
/* flag values used by DRCFlags */
|
||||||
|
|
||||||
|
/* DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE: If set, indicates that the ruleset */
|
||||||
|
/* defines "wide" as material of MORE THAN the given DRC rule width value, as */
|
||||||
|
/* opposed to the default behavior, which is to define "wide" as material of */
|
||||||
|
/* AT LEAST the given DRC rule width value. */
|
||||||
|
|
||||||
|
/* (Note that at least for now, there is no similar flag for "maxwidth" rules, */
|
||||||
|
/* which are always interpreted as inclusive, meaning that material of the */
|
||||||
|
/* exact width of the DRC rule width value is legal.) */
|
||||||
|
|
||||||
|
#define DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE 0x01
|
||||||
|
|
||||||
/* Things shared between DRC functions, but not used by the
|
/* Things shared between DRC functions, but not used by the
|
||||||
* outside world:
|
* outside world:
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue