Modified the handling of "why" strings in the DRC mechanism, so that

DRC records contain an index into a string array instead of containing
a copy of a string.  This is preliminary to changing the way the DRC
error plane is painted, so that the types painted will mark the error
type.  This will (1) allow "drc why" to simply scan the DRC error
plane rather than running the DRC engine, (2) allow DRC errors to be
counted by area rather than by tile, and (3) let the DRC count be the
same whether done by "drc listall why" or "drc count".
This commit is contained in:
Tim Edwards 2020-02-25 13:57:41 -05:00
parent b62efea43d
commit 2beb5ee0e9
7 changed files with 130 additions and 104 deletions

View File

@ -46,7 +46,7 @@ static DRCCookie drcArrayCookie = {
0, 0, 0, 0, 0, 0, 0, 0,
{ 0 }, { 0 }, { 0 }, { 0 },
0, 0, 0, 0, 0, 0,
"This layer can't abut or partially overlap between array elements", DRC_ARRAY_OVERLAP_TAG,
(DRCCookie *) NULL (DRCCookie *) NULL
}; };

View File

@ -47,7 +47,7 @@ static DRCCookie drcOverlapCookie = {
0, 0, 0, 0, 0, 0, 0, 0,
{ 0 }, { 0 }, { 0 }, { 0 },
0, 0, 0, 0, 0, 0,
"Can't overlap those layers", DRC_OVERLAP_TAG,
(DRCCookie *) NULL (DRCCookie *) NULL
}; };

View File

@ -48,7 +48,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/malloc.h" #include "utils/malloc.h"
#include "utils/utils.h" #include "utils/utils.h"
extern char *drcWhyDup();
extern int drcCifTile(); extern int drcCifTile();
extern int areaCifCheck(); extern int areaCifCheck();
extern void drcCheckCifMaxwidth(); extern void drcCheckCifMaxwidth();
@ -169,7 +168,7 @@ drcCifWidth(argc, argv)
char *layername = argv[1]; char *layername = argv[1];
int scalefactor; int scalefactor;
int centidistance = atoi(argv[2]); int centidistance = atoi(argv[2]);
char *why = drcWhyDup(argv[3]); int why = drcWhyCreate(argv[3]);
TileTypeBitMask set, setC, tmp1; TileTypeBitMask set, setC, tmp1;
int thislayer = -1; int thislayer = -1;
DRCCookie *dpnew,*dpnext; DRCCookie *dpnew,*dpnext;
@ -228,7 +227,7 @@ drcCifSpacing(argc, argv)
char *argv[]; char *argv[];
{ {
char *adjacency = argv[4]; char *adjacency = argv[4];
char *why = drcWhyDup(argv[5]); int why = drcWhyCreate(argv[5]);
DRCCookie *dpnext, *dpnew; DRCCookie *dpnext, *dpnew;
int needReverse = FALSE; int needReverse = FALSE;
TileType i, j; TileType i, j;
@ -1065,7 +1064,7 @@ drcCifArea(argc, argv)
char *layers = argv[1]; char *layers = argv[1];
int centiarea = atoi(argv[2]); int centiarea = atoi(argv[2]);
int centihorizon = atoi(argv[3]); int centihorizon = atoi(argv[3]);
char *why = drcWhyDup(argv[4]); int why = drcWhyCreate(argv[4]);
TileTypeBitMask set, setC, tmp1; TileTypeBitMask set, setC, tmp1;
DRCCookie *dpnext, *dpnew; DRCCookie *dpnext, *dpnew;
TileType i, j; TileType i, j;
@ -1126,7 +1125,7 @@ drcCifMaxwidth(argc, argv)
char *layers = argv[1]; char *layers = argv[1];
int centidistance = atoi(argv[2]); int centidistance = atoi(argv[2]);
char *bends = argv[3]; char *bends = argv[3];
char *why = drcWhyDup(argv[4]); int why = drcWhyCreate(argv[4]);
TileTypeBitMask set, setC, tmp1; TileTypeBitMask set, setC, tmp1;
DRCCookie *dpnext, *dpnew; DRCCookie *dpnext, *dpnew;
TileType i, j; TileType i, j;

View File

@ -69,9 +69,8 @@ TileType DRCErrorType; /* Type of error tile to paint. */
/* Used by drcPrintError: */ /* Used by drcPrintError: */
HashTable DRCErrorTable; /* Hash table used to eliminate duplicate int *DRCErrorList; /* List of DRC error type counts */
* error strings. HashTable DRCErrorTable; /* Table of DRC errors and geometry */
*/
/* Global variables used by all DRC modules to record statistics. /* Global variables used by all DRC modules to record statistics.
* For each statistic we keep two values, the count since stats * For each statistic we keep two values, the count since stats
@ -183,11 +182,12 @@ drcSubstitute (cptr)
DRCCookie * cptr; /* Design rule violated */ DRCCookie * cptr; /* Design rule violated */
{ {
static char *why_out = NULL; static char *why_out = NULL;
char *whyptr = cptr->drcc_why, *sptr, *wptr; char *whyptr, *sptr, *wptr;
int subscnt = 0, whylen; int subscnt = 0, whylen;
float oscale, value; float oscale, value;
extern float CIFGetOutputScale(); extern float CIFGetOutputScale();
whyptr = DRCCurStyle->DRCWhyList[cptr->drcc_tag];
while ((sptr = strchr(whyptr, '%')) != NULL) while ((sptr = strchr(whyptr, '%')) != NULL)
{ {
subscnt++; subscnt++;
@ -195,7 +195,7 @@ drcSubstitute (cptr)
} }
if (subscnt == 0) return whyptr; /* No substitutions */ if (subscnt == 0) return whyptr; /* No substitutions */
whyptr = cptr->drcc_why; whyptr = DRCCurStyle->DRCWhyList[cptr->drcc_tag];
whylen = strlen(whyptr) + 20 * subscnt; whylen = strlen(whyptr) + 20 * subscnt;
if (why_out != NULL) freeMagic(why_out); if (why_out != NULL) freeMagic(why_out);
why_out = (char *)mallocMagic(whylen * sizeof(char)); why_out = (char *)mallocMagic(whylen * sizeof(char));
@ -256,7 +256,7 @@ drcSubstitute (cptr)
* *
* Side effects: * Side effects:
* DRCErrorCount is incremented. The text associated with * DRCErrorCount is incremented. The text associated with
* the error is entered into DRCErrorTable, and, if this is * the error is entered into DRCErrorList, and, if this is
* the first time that entry has been seen, then the error * the first time that entry has been seen, then the error
* text is printed. If the area parameter is non-NULL, then * text is printed. If the area parameter is non-NULL, then
* only errors intersecting that area are considered. * only errors intersecting that area are considered.
@ -279,12 +279,11 @@ drcPrintError (celldef, rect, cptr, scx)
area = &scx->scx_area; area = &scx->scx_area;
if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return;
DRCErrorCount += 1; DRCErrorCount += 1;
h = HashFind(&DRCErrorTable, cptr->drcc_why);
i = (spointertype) HashGetValue(h); i = DRCErrorList[cptr->drcc_tag];
if (i == 0) if (i == 0)
TxPrintf("%s\n", drcSubstitute(cptr)); TxPrintf("%s\n", drcSubstitute(cptr));
i++; DRCErrorList[cptr->drcc_tag] = i + 1;
HashSetValue(h, (spointertype)i);
} }
/* Same routine as above, but output goes to a Tcl list and is appended */ /* Same routine as above, but output goes to a Tcl list and is appended */
@ -308,8 +307,7 @@ drcListError (celldef, rect, cptr, scx)
area = &scx->scx_area; area = &scx->scx_area;
if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return; if ((area != NULL) && (!GEO_OVERLAP(area, rect))) return;
DRCErrorCount += 1; DRCErrorCount += 1;
h = HashFind(&DRCErrorTable, cptr->drcc_why); i = DRCErrorList[cptr->drcc_tag];
i = (spointertype) HashGetValue(h);
if (i == 0) if (i == 0)
{ {
Tcl_Obj *lobj; Tcl_Obj *lobj;
@ -318,8 +316,7 @@ drcListError (celldef, rect, cptr, scx)
Tcl_NewStringObj(drcSubstitute(cptr), -1)); Tcl_NewStringObj(drcSubstitute(cptr), -1));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
} }
i += 1; DRCErrorList[cptr->drcc_tag] = i + 1;
HashSetValue(h, (spointertype)i);
} }
/* Same routine as above, but output for every single error is recorded */ /* Same routine as above, but output for every single error is recorded */
@ -475,11 +472,15 @@ DRCWhy(dolist, use, area)
{ {
SearchContext scx; SearchContext scx;
Rect box; Rect box;
int i;
extern int drcWhyFunc(); /* Forward reference. */ extern int drcWhyFunc(); /* Forward reference. */
/* Create a hash table to used for eliminating duplicate messages. */ /* Create a hash table to eliminate duplicate messages. */
DRCErrorList = (int *)mallocMagic((DRCCurStyle->DRCWhySize + 1) * sizeof(int));
for (i = 0; i <= DRCCurStyle->DRCWhySize; i++)
DRCErrorList[i] = 0;
HashInit(&DRCErrorTable, 16, HT_STRINGKEYS);
DRCErrorCount = 0; DRCErrorCount = 0;
box = DRCdef->cd_bbox; box = DRCdef->cd_bbox;
@ -494,11 +495,8 @@ DRCWhy(dolist, use, area)
drcWhyFunc(&scx, (pointertype)dolist); drcWhyFunc(&scx, (pointertype)dolist);
UndoEnable(); UndoEnable();
/* Delete the hash table now that we're finished (otherwise there /* Delete the error list */
* will be a core leak. freeMagic(DRCErrorList);
*/
HashKill(&DRCErrorTable);
/* Redisplay the DRC yank definition in case anyone is looking /* Redisplay the DRC yank definition in case anyone is looking
* at it. * at it.
@ -532,7 +530,7 @@ DRCWhyAll(use, area, fout)
HashEntry *he; HashEntry *he;
Tcl_Obj *lobj, *robj; Tcl_Obj *lobj, *robj;
/* Create a hash table to used for eliminating duplicate messages. */ /* Create a hash table for storing all of the results */
HashInit(&DRCErrorTable, 16, HT_STRINGKEYS); HashInit(&DRCErrorTable, 16, HT_STRINGKEYS);
DRCErrorCount = 0; DRCErrorCount = 0;
@ -566,10 +564,7 @@ DRCWhyAll(use, area, fout)
} }
Tcl_SetObjResult(magicinterp, robj); Tcl_SetObjResult(magicinterp, robj);
/* Delete the hash table now that we're finished (otherwise there /* Delete the error table now that we're finished */
* will be a core leak.
*/
HashKill(&DRCErrorTable); HashKill(&DRCErrorTable);
/* Redisplay the DRC yank definition in case anyone is looking /* Redisplay the DRC yank definition in case anyone is looking

View File

@ -59,7 +59,7 @@ static DRCCookie drcSubcellCookie = {
0, 0, 0, 0, 0, 0, 0, 0,
{ 0 }, { 0 }, { 0 }, { 0 },
0, 0, 0, 0, 0, 0,
"This layer can't abut or partially overlap between subcells", DRC_SUBCELL_OVERLAP_TAG,
(DRCCookie *) NULL (DRCCookie *) NULL
}; };

View File

@ -61,6 +61,11 @@ global int DRCRuleOptimization = TRUE;
static int drcRulesSpecified = 0; static int drcRulesSpecified = 0;
static int drcRulesOptimized = 0; static int drcRulesOptimized = 0;
/* Rules with unique names are tagged with a reference number */
/* for use in placing errors into the DRC error plane. */
static int DRCtag = 0;
/* /*
* Forward declarations. * Forward declarations.
*/ */
@ -281,21 +286,14 @@ drcTechFreeStyle()
dp = DRCCurStyle->DRCRulesTbl[i][j]; dp = DRCCurStyle->DRCRulesTbl[i][j];
while (dp != NULL) while (dp != NULL)
{ {
char *old = (char *) dp; char *old = (char *)dp;
dp = dp->drcc_next; dp = dp->drcc_next;
freeMagic(old); freeMagic(old);
} }
} }
/* Clear the DRCWhyList */ /* Clear the Why string list */
freeMagic(DRCCurStyle->DRCWhyList);
while (DRCCurStyle->DRCWhyList != NULL)
{
old = (char *) DRCCurStyle->DRCWhyList;
StrDup(&(DRCCurStyle->DRCWhyList->dwl_string), (char *) NULL);
DRCCurStyle->DRCWhyList = DRCCurStyle->DRCWhyList->dwl_next;
freeMagic(old);
}
freeMagic(DRCCurStyle); freeMagic(DRCCurStyle);
DRCCurStyle = NULL; DRCCurStyle = NULL;
@ -329,31 +327,54 @@ drcTechNewStyle()
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* drcWhyDup -- * drcWhyCreate --
* *
* Duplicate a shared "why" string using StrDup() and remember it so we can * Create a hash entry for the DRC "why" string, if it does not already
* free it sometime later, in drcWhyClear(). * exist.
* *
* Returns: * Returns:
* A copy of the given string. * A pointer to the drcWhy structure containing the string and tag.
* *
* Side effects: * Side effects:
* Adds to the DRCWhyList. Calls StrDup(). * Adds to the DRCWhyList if whystring has not been used before.
* Calls StrDup() and increments DRCWhySize. DRCWhyList is allocated
* in blocks of 50 at a time and only expands when filled.
* Temporary hash table DRCErrorTable is used to determine if a
* string entry is unique. It is cleared after the technology file
* has been processed.
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
char * int
drcWhyDup(why) drcWhyCreate(whystring)
char * why; char *whystring;
{ {
struct drcwhylist * new; HashEntry *he;
new = (struct drcwhylist *) mallocMagic((unsigned) (sizeof *new)); he = HashLookOnly(&DRCErrorTable, whystring);
new->dwl_string = StrDup((char **) NULL, why); if (he != NULL)
new->dwl_next = DRCCurStyle->DRCWhyList; return (int)((pointertype)HashGetValue(he));
DRCCurStyle->DRCWhyList = new;
return new->dwl_string; /* Grow the list in increments of 50 */
if ((DRCCurStyle->DRCWhySize % 50) == 0)
{
int i;
char **newList;
newList = (char **)mallocMagic((DRCCurStyle->DRCWhySize + 51) * sizeof(char *));
for (i = 0; i < DRCCurStyle->DRCWhySize; i++)
newList[i] = DRCCurStyle->DRCWhyList[i];
if (DRCCurStyle->DRCWhySize > 0)
freeMagic((char *)DRCCurStyle->DRCWhyList);
DRCCurStyle->DRCWhyList = newList;
}
DRCCurStyle->DRCWhySize++;
he = HashFind(&DRCErrorTable, whystring);
HashSetValue(he, (char *)((pointertype)DRCCurStyle->DRCWhySize));
DRCCurStyle->DRCWhyList[DRCCurStyle->DRCWhySize] = StrDup((char **)NULL, whystring);
return DRCCurStyle->DRCWhySize;
} }
/* /*
@ -535,12 +556,29 @@ DRCTechStyleInit()
DRCCurStyle->ds_status = TECH_NOT_LOADED; DRCCurStyle->ds_status = TECH_NOT_LOADED;
TTMaskZero(&DRCCurStyle->DRCExactOverlapTypes); TTMaskZero(&DRCCurStyle->DRCExactOverlapTypes);
DRCCurStyle->DRCWhyList = NULL;
DRCCurStyle->DRCTechHalo = 0; DRCCurStyle->DRCTechHalo = 0;
DRCCurStyle->DRCScaleFactorN = 1; DRCCurStyle->DRCScaleFactorN = 1;
DRCCurStyle->DRCScaleFactorD = 1; DRCCurStyle->DRCScaleFactorD = 1;
DRCCurStyle->DRCStepSize = 0; DRCCurStyle->DRCStepSize = 0;
DRCCurStyle->DRCFlags = (char)0; DRCCurStyle->DRCFlags = (char)0;
DRCCurStyle->DRCWhySize = 0;
HashInit(&DRCErrorTable, 16, HT_STRINGKEYS);
/* First DRC entry is associated with the statically-allocated */
/* drcArrayCookie and has a tag of DRC_ARRAY_OVERLAP_TAG = 1 */
/* (see DRCarray.c). */
drcWhyCreate("This layer can't abut or partially overlap between array elements");
/* Second DRC entry is associated with the statically-allocated */
/* drcOverlapCookie and has a tag of DRC_OVERLAP_TAG = 2 */
/* (see DRCbasic.c). */
drcWhyCreate("Can't overlap those layers");
/* Third DRC entry is associated with the statically-allocated */
/* drcSubcellCookie and has a tag of DRC_SUBCELL_OVERLAP_TAG = 3 */
/* (see DRCsubcell.c). */
drcWhyCreate("This layer can't abut or partially overlap between subcells");
DRCTechHalo = 0; DRCTechHalo = 0;
@ -872,18 +910,18 @@ DRCTechLine(sectionName, argc, argv)
} }
void void
drcCifAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefrom) drcCifAssign(cookie, dist, next, mask, corner, tag, cdist, flags, planeto, planefrom)
DRCCookie *cookie, *next; DRCCookie *cookie, *next;
int dist, cdist; int dist, cdist;
TileTypeBitMask *mask, *corner; TileTypeBitMask *mask, *corner;
char *why; int tag;
int flags, planeto, planefrom; int flags, planeto, planefrom;
{ {
(cookie)->drcc_dist = dist; (cookie)->drcc_dist = dist;
(cookie)->drcc_next = next; (cookie)->drcc_next = next;
(cookie)->drcc_mask = *mask; (cookie)->drcc_mask = *mask;
(cookie)->drcc_corner = *corner; (cookie)->drcc_corner = *corner;
(cookie)->drcc_why = why; (cookie)->drcc_tag = tag;
(cookie)->drcc_cdist = cdist; (cookie)->drcc_cdist = cdist;
(cookie)->drcc_flags = flags; (cookie)->drcc_flags = flags;
(cookie)->drcc_edgeplane = planefrom; (cookie)->drcc_edgeplane = planefrom;
@ -900,7 +938,7 @@ drcAssign(cookie, dist, next, mask, corner, why, cdist, flags, planeto, planefro
DRCCookie *cookie, *next; DRCCookie *cookie, *next;
int dist, cdist; int dist, cdist;
TileTypeBitMask *mask, *corner; TileTypeBitMask *mask, *corner;
char *why; int why;
int flags, planeto, planefrom; int flags, planeto, planefrom;
{ {
/* Diagnostic */ /* Diagnostic */
@ -1088,7 +1126,7 @@ drcExtend(argc, argv)
char *layers1 = argv[1]; char *layers1 = argv[1];
char *layers2 = argv[2]; char *layers2 = argv[2];
int distance = atoi(argv[3]); int distance = atoi(argv[3]);
char *why; int why;
TileTypeBitMask set1, setC; TileTypeBitMask set1, setC;
DRCCookie *dp, *dpnew, *dptrig; DRCCookie *dp, *dpnew, *dptrig;
TileType i, j; TileType i, j;
@ -1100,10 +1138,10 @@ drcExtend(argc, argv)
if (!strncmp(argv[4], "exact_", 6)) if (!strncmp(argv[4], "exact_", 6))
{ {
exact = TRUE; exact = TRUE;
why = drcWhyDup(argv[5]); why = drcWhyCreate(argv[5]);
} }
else else
why = drcWhyDup(argv[4]); why = drcWhyCreate(argv[4]);
ptest = DBTechNoisyNameMask(layers1, &set1); ptest = DBTechNoisyNameMask(layers1, &set1);
pMask1 = CoincidentPlanes(&set1, ptest); pMask1 = CoincidentPlanes(&set1, ptest);
@ -1257,7 +1295,7 @@ drcWidth(argc, argv)
{ {
char *layers = argv[1]; char *layers = argv[1];
int distance = atoi(argv[2]); int distance = atoi(argv[2]);
char *why = drcWhyDup(argv[3]); int why = drcWhyCreate(argv[3]);
TileTypeBitMask set, setC; TileTypeBitMask set, setC;
PlaneMask pmask, pset, ptest; PlaneMask pmask, pset, ptest;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
@ -1342,7 +1380,7 @@ drcArea(argc, argv)
char *layers = argv[1]; char *layers = argv[1];
int distance = atoi(argv[2]); int distance = atoi(argv[2]);
int horizon = atoi(argv[3]); int horizon = atoi(argv[3]);
char *why = drcWhyDup(argv[4]); int why = drcWhyCreate(argv[4]);
TileTypeBitMask set, setC; TileTypeBitMask set, setC;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
TileType i, j; TileType i, j;
@ -1442,7 +1480,7 @@ drcMaxwidth(argc, argv)
char *layers = argv[1]; char *layers = argv[1];
int distance = atoi(argv[2]); int distance = atoi(argv[2]);
char *bends = argv[3]; char *bends = argv[3];
char *why; int why;
TileTypeBitMask set, setC; TileTypeBitMask set, setC;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
TileType i, j; TileType i, j;
@ -1469,7 +1507,7 @@ drcMaxwidth(argc, argv)
bend = 0; bend = 0;
else else
bend = DRC_BENDS; bend = DRC_BENDS;
why = drcWhyDup(argv[3]); why = drcWhyCreate(argv[3]);
} }
else else
{ {
@ -1480,7 +1518,7 @@ drcMaxwidth(argc, argv)
TechError("unknown bend option %s\n",bends); TechError("unknown bend option %s\n",bends);
return (0); return (0);
} }
why = drcWhyDup(argv[4]); why = drcWhyCreate(argv[4]);
} }
for (i = 0; i < DBNumTypes; i++) for (i = 0; i < DBNumTypes; i++)
@ -1531,7 +1569,7 @@ drcAngles(argc, argv)
{ {
char *layers = argv[1]; char *layers = argv[1];
int angles = atoi(argv[2]); int angles = atoi(argv[2]);
char *why = drcWhyDup(argv[3]); int why = drcWhyCreate(argv[3]);
TileTypeBitMask set; TileTypeBitMask set;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
int plane; int plane;
@ -1599,7 +1637,7 @@ drcSpacing3(argc, argv)
char *layers3 = argv[5]; char *layers3 = argv[5];
int distance = atoi(argv[3]); int distance = atoi(argv[3]);
char *adjacency = argv[4]; char *adjacency = argv[4];
char *why = drcWhyDup(argv[6]); int why = drcWhyCreate(argv[6]);
TileTypeBitMask set1, set2, set3; TileTypeBitMask set1, set2, set3;
int plane; int plane;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
@ -2151,7 +2189,7 @@ drcSpacing(argc, argv)
{ {
char *layers1 = argv[1], *layers2; char *layers1 = argv[1], *layers2;
char *adjacency; char *adjacency;
char *why; int 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, runlength; int wwidth, distance, plane, plane2, runlength;
@ -2172,7 +2210,7 @@ drcSpacing(argc, argv)
layers2 = argv[4]; layers2 = argv[4];
distance = atoi(argv[5]); distance = atoi(argv[5]);
adjacency = argv[6]; adjacency = argv[6];
why = drcWhyDup(argv[7]); why = drcWhyCreate(argv[7]);
} }
else else
{ {
@ -2180,7 +2218,7 @@ drcSpacing(argc, argv)
distance = atoi(argv[4]); distance = atoi(argv[4]);
runlength = distance; runlength = distance;
adjacency = argv[5]; adjacency = argv[5];
why = drcWhyDup(argv[6]); why = drcWhyCreate(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); */
@ -2191,7 +2229,7 @@ drcSpacing(argc, argv)
distance = atoi(argv[3]); distance = atoi(argv[3]);
adjacency = argv[4]; adjacency = argv[4];
wwidth = distance; wwidth = distance;
why = drcWhyDup(argv[5]); why = drcWhyCreate(argv[5]);
runlength = distance; runlength = distance;
if (argc >= 7) if (argc >= 7)
{ {
@ -2325,7 +2363,7 @@ drcEdge(argc, argv)
int distance = atoi(argv[3]); int distance = atoi(argv[3]);
char *okTypes = argv[4], *cornerTypes = argv[5]; char *okTypes = argv[4], *cornerTypes = argv[5];
int cdist = atoi(argv[6]); int cdist = atoi(argv[6]);
char *why = drcWhyDup(argv[7]); int why = drcWhyCreate(argv[7]);
bool fourway = (strcmp(argv[0], "edge4way") == 0); bool fourway = (strcmp(argv[0], "edge4way") == 0);
TileTypeBitMask set1, set2, setC, setM; TileTypeBitMask set1, set2, setC, setM;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
@ -2491,7 +2529,7 @@ drcOverhang(argc, argv)
{ {
char *layers2 = argv[1], *layers1 = argv[2]; char *layers2 = argv[1], *layers1 = argv[2];
int distance = atoi(argv[3]); int distance = atoi(argv[3]);
char *why = drcWhyDup(argv[4]); int why = drcWhyCreate(argv[4]);
TileTypeBitMask set1, set2, setM, setC, setN, set2inv; TileTypeBitMask set1, set2, setM, setC, setN, set2inv;
DRCCookie *dp, *dpnew, *dptrig; DRCCookie *dp, *dpnew, *dptrig;
int plane, plane2; int plane, plane2;
@ -2627,7 +2665,7 @@ drcRectOnly(argc, argv)
char *argv[]; char *argv[];
{ {
char *layers = argv[1]; char *layers = argv[1];
char *why = drcWhyDup(argv[2]); int why = drcWhyCreate(argv[2]);
TileTypeBitMask set1, set2, setC; TileTypeBitMask set1, set2, setC;
PlaneMask pmask, pset, ptest; PlaneMask pmask, pset, ptest;
DRCCookie *dp, *dpnew; DRCCookie *dp, *dpnew;
@ -2727,7 +2765,7 @@ drcSurround(argc, argv)
char *layers1 = argv[1], *layers2 = argv[2]; char *layers1 = argv[1], *layers2 = argv[2];
int distance = atoi(argv[3]); int distance = atoi(argv[3]);
char *presence = argv[4]; char *presence = argv[4];
char *why = drcWhyDup(argv[5]); int why = drcWhyCreate(argv[5]);
TileTypeBitMask set1, set2, setM, invM, setR; TileTypeBitMask set1, set2, setM, invM, setR;
DRCCookie *dp, *dpnew, *dptrig; DRCCookie *dp, *dpnew, *dptrig;
int plane1, plane2; int plane1, plane2;
@ -3100,7 +3138,7 @@ drcRectangle(argc, argv)
char *argv[]; char *argv[];
{ {
char *layers = argv[1]; char *layers = argv[1];
char *why = drcWhyDup(argv[4]); int why = drcWhyCreate(argv[4]);
TileTypeBitMask types, nottypes; TileTypeBitMask types, nottypes;
int maxwidth; int maxwidth;
static char *drcRectOpt[4] = {"any", "even", "odd", 0}; static char *drcRectOpt[4] = {"any", "even", "odd", 0};
@ -3466,6 +3504,9 @@ drcTechFinalStyle(style)
DRCCookie **dpp, **dp2back; DRCCookie **dpp, **dp2back;
TileType i, j; TileType i, j;
/* Done with DRCErrorTable */
HashKill(&DRCErrorTable);
/* If the scale factor is not 1, then divide all distances by */ /* If the scale factor is not 1, then divide all distances by */
/* the scale factor, take the ceiling, and save the (negative) */ /* the scale factor, take the ceiling, and save the (negative) */
/* remainder. */ /* remainder. */
@ -3587,7 +3628,6 @@ drcTechFinalStyle(style)
} }
else else
{ {
/* Don't free the shared drcc_why string here! */
freeMagic((char *)dptest); freeMagic((char *)dptest);
drcRulesOptimized++; drcRulesOptimized++;
} }
@ -3682,7 +3722,8 @@ drcTechFinalStyle(style)
/* TxPrintf("For edge %s-%s, \"%s\" covers \"%s\"\n", /* TxPrintf("For edge %s-%s, \"%s\" covers \"%s\"\n",
DBTypeShortName(i), DBTypeShortName(j), DBTypeShortName(i), DBTypeShortName(j),
next->drcc_why, dp->drcc_why); DRCCurStyle->DRCWhyList[next->drcc_tag],
DRCCurStyle->DRCWhyList[dp->drcc_tag]);
*/ */
dp2back = &(style->DRCRulesTbl[i][j]); dp2back = &(style->DRCRulesTbl[i][j]);
while (*dp2back != dp) while (*dp2back != dp)
@ -3704,7 +3745,6 @@ drcTechFinalStyle(style)
else else
*dp2back = dp->drcc_next; *dp2back = dp->drcc_next;
/* Don't free the shared drcc_why string here! */
freeMagic((char *) dp); freeMagic((char *) dp);
drcRulesOptimized += 1; drcRulesOptimized += 1;
} }

View File

@ -39,10 +39,15 @@ typedef struct drccookie
int drcc_edgeplane; /* Plane of edge */ int drcc_edgeplane; /* Plane of edge */
int drcc_plane; /* Index of plane on which to check int drcc_plane; /* Index of plane on which to check
* legal types. */ * legal types. */
char *drcc_why; /* Explanation of error found */ int drcc_tag; /* Tag to explanation of error found */
struct drccookie *drcc_next; struct drccookie *drcc_next;
} DRCCookie; } DRCCookie;
/* These DRC tags in DRCcookie are predefined. */
#define DRC_ARRAY_OVERLAP_TAG 1
#define DRC_OVERLAP_TAG 2
#define DRC_SUBCELL_OVERLAP_TAG 3
/* *This is size "int" because it holds an area for DRC_AREA rules, */ /* *This is size "int" because it holds an area for DRC_AREA rules, */
/* and therefore may have twice the bit length of a normal rule distance. */ /* and therefore may have twice the bit length of a normal rule distance. */
@ -142,22 +147,6 @@ typedef struct drckeep
char *ds_name; char *ds_name;
} DRCKeep; } DRCKeep;
/*
* DRC "why" strings are potentially referred to hundreds of times by
* DRC cookies in the rule table. Rather than creating hundreds of
* copies of each string, we create just one copy and let all the cookies
* point to that one copy.
*
* Since we can't free these shared "why" strings when we delete a cookie,
* we keep a list of these strings and free them all when convenient.
*/
typedef struct drcwhylist
{
char * dwl_string;
struct drcwhylist * dwl_next;
} drcWhyList;
/* /*
* Structure defining a DRC style * Structure defining a DRC style
*/ */
@ -173,7 +162,8 @@ typedef struct drcstyle
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 */ char DRCFlags; /* Option flags */
drcWhyList *DRCWhyList; char **DRCWhyList; /* Indexed list of "why" text strings */
int DRCWhySize; /* Length of DRCWhyList */
PaintResultType DRCPaintTable[NP][NT][NT]; PaintResultType DRCPaintTable[NP][NT][NT];
} DRCStyle; } DRCStyle;
@ -229,6 +219,7 @@ extern DRCKeep *DRCStyleList; /* List of available DRC styles */
extern DRCStyle *DRCCurStyle; /* Current DRC style in effect */ extern DRCStyle *DRCCurStyle; /* Current DRC style in effect */
extern CellDef *DRCdef; /* Current cell being checked for DRC */ extern CellDef *DRCdef; /* Current cell being checked for DRC */
extern CellUse *DRCuse, *DRCDummyUse; extern CellUse *DRCuse, *DRCDummyUse;
extern HashTable DRCErrorTable; /* DRC errors, hashed by name */
/* /*
* Internal procedures * Internal procedures
@ -241,6 +232,7 @@ extern int drcExactOverlapTile();
extern void drcInitRulesTbl(); extern void drcInitRulesTbl();
extern void drcAssign(); extern void drcAssign();
extern void drcCifAssign(); extern void drcCifAssign();
extern int drcWhyCreate();
/* /*
* Exported procedures * Exported procedures