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;
|
||||
int i;
|
||||
|
||||
if (!trigpending) cptr->drcc_dist++;
|
||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||
cptr->drcc_dist++;
|
||||
|
||||
if (cptr->drcc_flags & DRC_REVERSE)
|
||||
mrd = drcCanonicalMaxwidth(tpleft, GEO_WEST, arg, cptr);
|
||||
|
|
@ -554,11 +556,20 @@ drcTile (tile, arg)
|
|||
mrd = drcCanonicalMaxwidth(tile, GEO_EAST, arg, cptr);
|
||||
else
|
||||
mrd = NULL;
|
||||
if (!trigpending) cptr->drcc_dist--;
|
||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||
cptr->drcc_dist--;
|
||||
if (trigpending)
|
||||
{
|
||||
if (mrd)
|
||||
triggered = mrd->entries;
|
||||
{
|
||||
/* Run-length rule */
|
||||
if ((cptr->drcc_cdist <= cptr->drcc_dist) ||
|
||||
((edgeTop - edgeBot) > cptr->drcc_cdist))
|
||||
triggered = mrd->entries;
|
||||
else
|
||||
cptr = cptr->drcc_next;
|
||||
}
|
||||
else
|
||||
cptr = cptr->drcc_next;
|
||||
}
|
||||
|
|
@ -903,7 +914,9 @@ checkbottom:
|
|||
Rect *lr;
|
||||
int i;
|
||||
|
||||
if (!trigpending) cptr->drcc_dist++;
|
||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||
cptr->drcc_dist++;
|
||||
|
||||
if (cptr->drcc_flags & DRC_REVERSE)
|
||||
mrd = drcCanonicalMaxwidth(tpbot, GEO_SOUTH, arg, cptr);
|
||||
|
|
@ -911,11 +924,18 @@ checkbottom:
|
|||
mrd = drcCanonicalMaxwidth(tile, GEO_NORTH, arg, cptr);
|
||||
else
|
||||
mrd = NULL;
|
||||
if (!trigpending) cptr->drcc_dist--;
|
||||
if (!trigpending || (DRCCurStyle->DRCFlags
|
||||
& DRC_FLAGS_WIDEWIDTH_NONINCLUSIVE))
|
||||
cptr->drcc_dist--;
|
||||
if (trigpending)
|
||||
{
|
||||
if (mrd)
|
||||
triggered = mrd->entries;
|
||||
/* Run-length rule */
|
||||
if ((cptr->drcc_cdist <= cptr->drcc_dist) ||
|
||||
((edgeRight - edgeLeft) > cptr->drcc_cdist))
|
||||
triggered = mrd->entries;
|
||||
else
|
||||
cptr = cptr->drcc_next;
|
||||
else
|
||||
cptr = cptr->drcc_next;
|
||||
}
|
||||
|
|
|
|||
100
drc/DRCtech.c
100
drc/DRCtech.c
|
|
@ -67,7 +67,7 @@ static int drcRulesOptimized = 0;
|
|||
int drcWidth(), drcSpacing(), drcEdge(), drcNoOverlap();
|
||||
int drcExactOverlap(), drcExtend();
|
||||
int drcSurround(), drcRectOnly(), drcOverhang();
|
||||
int drcStepSize();
|
||||
int drcStepSize(), drcOption();
|
||||
int drcMaxwidth(), drcArea(), drcRectangle(), drcAngles();
|
||||
int drcCifSetStyle(), drcCifWidth(), drcCifSpacing();
|
||||
int drcCifMaxwidth(), drcCifArea();
|
||||
|
|
@ -540,6 +540,7 @@ DRCTechStyleInit()
|
|||
DRCCurStyle->DRCScaleFactorN = 1;
|
||||
DRCCurStyle->DRCScaleFactorD = 1;
|
||||
DRCCurStyle->DRCStepSize = 0;
|
||||
DRCCurStyle->DRCFlags = (char)0;
|
||||
|
||||
DRCTechHalo = 0;
|
||||
|
||||
|
|
@ -959,6 +960,8 @@ DRCTechAddRule(sectionName, argc, argv)
|
|||
"layers1 layers2 distance why",
|
||||
"no_overlap", 3, 3, drcNoOverlap,
|
||||
"layers1 layers2",
|
||||
"option", 2, 2, drcOption,
|
||||
"option_name option_value",
|
||||
"overhang", 5, 5, drcOverhang,
|
||||
"layers1 layers2 distance why",
|
||||
"rect_only", 3, 3, drcRectOnly,
|
||||
|
|
@ -971,7 +974,7 @@ DRCTechAddRule(sectionName, argc, argv)
|
|||
"layers1 layers2 distance presence why",
|
||||
"width", 4, 4, drcWidth,
|
||||
"layers width why",
|
||||
"widespacing", 7, 7, drcSpacing,
|
||||
"widespacing", 7, 8, drcSpacing,
|
||||
"layers1 width layers2 separation adjacency why",
|
||||
"area", 5, 5, drcArea,
|
||||
"layers area horizon why",
|
||||
|
|
@ -1661,12 +1664,14 @@ drcSpacing3(argc, argv)
|
|||
|
||||
int
|
||||
drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
||||
why, widerule, multiplane)
|
||||
why, widerule, runlength, multiplane)
|
||||
TileTypeBitMask *set1, *set2;
|
||||
PlaneMask pmask1, pmask2;
|
||||
int wwidth, distance;
|
||||
char *adjacency, *why;
|
||||
bool widerule, multiplane;
|
||||
bool widerule;
|
||||
int runlength;
|
||||
bool multiplane;
|
||||
{
|
||||
TileTypeBitMask tmp1, tmp2, setR, setRreverse;
|
||||
int plane, plane2;
|
||||
|
|
@ -1825,7 +1830,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
|||
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
||||
(sizeof (DRCCookie)));
|
||||
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
||||
wwidth, DRC_REVERSE | DRC_MAXWIDTH |
|
||||
runlength, DRC_REVERSE | DRC_MAXWIDTH |
|
||||
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
||||
|
||||
dp->drcc_next = dptrig;
|
||||
|
|
@ -1880,7 +1885,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
|||
dptrig = (DRCCookie *) mallocMagic((unsigned)
|
||||
(sizeof (DRCCookie)));
|
||||
drcAssign(dptrig, wwidth, dpnew, set1, set1, why,
|
||||
wwidth, DRC_FORWARD | DRC_MAXWIDTH |
|
||||
runlength, DRC_FORWARD | DRC_MAXWIDTH |
|
||||
DRC_TRIGGER | DRC_BENDS, plane2, plane);
|
||||
dp->drcc_next = dptrig;
|
||||
}
|
||||
|
|
@ -2089,7 +2094,7 @@ drcMaskSpacing(set1, set2, pmask1, pmask2, wwidth, distance, adjacency,
|
|||
* Notes:
|
||||
* 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
|
||||
* 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
|
||||
* 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;
|
||||
TileTypeBitMask set1, set2, tmp1, tmp2;
|
||||
PlaneMask pmask1, pmask2, pmaskA, pmaskB, ptest;
|
||||
int wwidth, distance, plane, plane2;
|
||||
int wwidth, distance, plane, plane2, runlength;
|
||||
bool widerule, multiplane = FALSE;
|
||||
|
||||
if ((argc == 7) && (!strcmp(argv[4], "corner_ok")))
|
||||
|
|
@ -2137,10 +2146,23 @@ drcSpacing(argc, argv)
|
|||
if (widerule)
|
||||
{
|
||||
wwidth = atoi(argv[2]);
|
||||
layers2 = argv[3];
|
||||
distance = atoi(argv[4]);
|
||||
adjacency = argv[5];
|
||||
why = drcWhyDup(argv[6]);
|
||||
|
||||
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];
|
||||
distance = atoi(argv[4]);
|
||||
adjacency = argv[5];
|
||||
why = drcWhyDup(argv[6]);
|
||||
}
|
||||
/* TxPrintf("Info: DRCtech: widespacing rule for %s width %d:"
|
||||
" spacing must be %d\n", layers1, wwidth, distance); */
|
||||
}
|
||||
|
|
@ -2151,7 +2173,8 @@ drcSpacing(argc, argv)
|
|||
adjacency = argv[4];
|
||||
wwidth = distance;
|
||||
why = drcWhyDup(argv[5]);
|
||||
if (argc == 7)
|
||||
runlength = distance;
|
||||
if (argc >= 7)
|
||||
{
|
||||
TechError("Unknown argument in spacing line.\n");
|
||||
return(0);
|
||||
|
|
@ -2236,13 +2259,13 @@ drcSpacing(argc, argv)
|
|||
|
||||
return drcMaskSpacing(&tmp1, &tmp2, pmaskA, pmaskB,
|
||||
wwidth, distance, adjacency, why,
|
||||
widerule, multiplane);
|
||||
widerule, runlength, multiplane);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return drcMaskSpacing(&set1, &set2, pmask1, pmask2, wwidth,
|
||||
distance, adjacency, why, widerule, multiplane);
|
||||
distance, adjacency, why, widerule, runlength, multiplane);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3152,6 +3175,53 @@ drcRectangle(argc, argv)
|
|||
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 DRCTechHalo; /* largest action distance of design rules */
|
||||
int DRCStepSize; /* chunk size for decomposing large areas */
|
||||
char DRCFlags; /* Option flags */
|
||||
drcWhyList *DRCWhyList;
|
||||
PaintResultType DRCPaintTable[NP][NT][NT];
|
||||
} 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
|
||||
* outside world:
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue