Reverted the "drc count" command to the way it was. There is more
to be investigated here. I am no longer sure why I removed the cell search from DRC count, but it appears that the cell search is non-functional, and it should be determined why. There is no particular reason not to have a DRC count search. It could be implemented such that "list" vs. "listall" counts the top cell vs. all cells. First it must be determined why there are no subcell counts.
This commit is contained in:
parent
b2c6193589
commit
fba66b7dff
|
|
@ -3182,6 +3182,7 @@ CmdDrc(w, cmd)
|
|||
bool doforall = FALSE;
|
||||
bool dolist = FALSE;
|
||||
int count_total;
|
||||
DRCCountList *dcl;
|
||||
int argc = cmd->tx_argc;
|
||||
char **argv = cmd->tx_argv;
|
||||
#ifdef MAGIC_WRAPPER
|
||||
|
|
@ -3196,7 +3197,7 @@ CmdDrc(w, cmd)
|
|||
"*stepsize [d] change DRC step size to d units",
|
||||
"catchup run checker and wait for it to complete",
|
||||
"check recheck area under box in all cells",
|
||||
"count count error tiles in each cell under box",
|
||||
"count [total] count error tiles in each cell under box",
|
||||
"euclidean on|off enable/disable Euclidean geometry checking",
|
||||
"find [nth] locate next (or nth) error in the layout",
|
||||
"help print this help information",
|
||||
|
|
@ -3304,6 +3305,14 @@ CmdDrc(w, cmd)
|
|||
break;
|
||||
|
||||
case COUNT:
|
||||
count_total = -1;
|
||||
if (argc == 3)
|
||||
if (!strncmp(argv[2], "total", 5))
|
||||
count_total = 0;
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (count_total == -1) lobj = Tcl_NewListObj(0, NULL);
|
||||
#endif
|
||||
if ((window = w) == NULL)
|
||||
{
|
||||
window = ToolGetBoxWindow(&rootArea, (int *) NULL);
|
||||
|
|
@ -3313,44 +3322,61 @@ CmdDrc(w, cmd)
|
|||
rootArea = w->w_surfaceArea;
|
||||
|
||||
rootUse = (CellUse *) window->w_surfaceID;
|
||||
count_total = DRCCount(rootUse, &rootArea);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (dolist)
|
||||
{
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(rootUse->cu_def->cd_name, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(count_total));
|
||||
}
|
||||
else
|
||||
dcl = DRCCount(rootUse, &rootArea);
|
||||
while (dcl != NULL)
|
||||
{
|
||||
if (count_total >= 0)
|
||||
count_total += dcl->dcl_count;
|
||||
else
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (dolist)
|
||||
{
|
||||
Tcl_Obj *pobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewStringObj(dcl->dcl_def->cd_name, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj(dcl->dcl_count));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
|
||||
if (count_total > 1)
|
||||
TxPrintf("Cell %s has %d error tiles.\n",
|
||||
rootUse->cu_def->cd_name, count_total);
|
||||
else if (count_total == 1)
|
||||
TxPrintf("Cell %s has just one error tile.\n",
|
||||
rootUse->cu_def->cd_name);
|
||||
if (dcl->dcl_count > 1)
|
||||
TxPrintf("Cell %s has %d error tiles.\n",
|
||||
dcl->dcl_def->cd_name, dcl->dcl_count);
|
||||
else if (dcl->dcl_count == 1)
|
||||
TxPrintf("Cell %s has just one error tile.\n",
|
||||
dcl->dcl_def->cd_name);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
}
|
||||
freeMagic((char *)dcl);
|
||||
dcl = dcl->dcl_next;
|
||||
}
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doforall)
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
else if (count_total >= 0)
|
||||
if (count_total >= 0)
|
||||
{
|
||||
if (dolist)
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(count_total));
|
||||
else
|
||||
TxPrintf("Total DRC errors found: %d\n", count_total);
|
||||
{
|
||||
if ((DRCBackGround != DRC_SET_OFF) && (count_total == -1))
|
||||
count_total = 0;
|
||||
if (count_total >= 0)
|
||||
TxPrintf("Total DRC errors found: %d\n", count_total);
|
||||
}
|
||||
}
|
||||
else if (dolist)
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
|
||||
#else
|
||||
TxPrintf("Total DRC errors found: %d\n", count_total);
|
||||
if ((DRCBackGround != DRC_SET_OFF) && (count_total == -1))
|
||||
count_total = 0;
|
||||
if (count_gotal >= 0)
|
||||
TxPrintf("Total DRC errors found: %d\n", count_total);
|
||||
#endif
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -747,31 +747,97 @@ drcCheckFunc(scx, cdarg)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
DRCCountList *
|
||||
DRCCount(use, area)
|
||||
CellUse *use; /* Top-level use of hierarchy. */
|
||||
Rect *area; /* Area in which violations are counted. */
|
||||
{
|
||||
DRCCountList *dcl, *newdcl;
|
||||
HashTable dupTable;
|
||||
HashEntry *he;
|
||||
HashSearch hs;
|
||||
int count;
|
||||
SearchContext scx;
|
||||
CellDef *def;
|
||||
extern int drcCountFunc2();
|
||||
extern int drcCountFunc();
|
||||
|
||||
/* Use a hash table to make sure that we don't output information
|
||||
* for any cell more than once.
|
||||
*/
|
||||
|
||||
HashInit(&dupTable, 16, HT_WORDKEYS);
|
||||
|
||||
scx.scx_use = use;
|
||||
scx.scx_x = use->cu_xlo;
|
||||
scx.scx_y = use->cu_ylo;
|
||||
scx.scx_area = *area;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
(void) drcCountFunc(&scx, &dupTable);
|
||||
|
||||
def = use->cu_def;
|
||||
/* Create the list from the hash table */
|
||||
|
||||
dcl = NULL;
|
||||
if (dupTable.ht_table != (HashEntry **) NULL)
|
||||
{
|
||||
HashStartSearch(&hs);
|
||||
while ((he = HashNext(&dupTable, &hs)) != (HashEntry *)NULL)
|
||||
{
|
||||
count = (spointertype)HashGetValue(he);
|
||||
if (count > 1)
|
||||
{
|
||||
newdcl = (DRCCountList *)mallocMagic(sizeof(DRCCountList));
|
||||
newdcl->dcl_count = count - 1;
|
||||
newdcl->dcl_def = (CellDef *)he->h_key.h_ptr;
|
||||
newdcl->dcl_next = dcl;
|
||||
dcl = newdcl;
|
||||
}
|
||||
}
|
||||
}
|
||||
HashKill(&dupTable);
|
||||
return dcl;
|
||||
}
|
||||
|
||||
int
|
||||
drcCountFunc(scx, dupTable)
|
||||
SearchContext *scx;
|
||||
HashTable *dupTable; /* Passed as client data, used to
|
||||
* avoid searching any cell twice.
|
||||
*/
|
||||
{
|
||||
int count;
|
||||
HashEntry *h;
|
||||
CellDef *def;
|
||||
extern int drcCountFunc2();
|
||||
|
||||
/* If we've already seen this cell definition before, then skip it
|
||||
* now.
|
||||
*/
|
||||
|
||||
def = scx->scx_use->cu_def;
|
||||
h = HashFind(dupTable, (char *)def);
|
||||
if (HashGetValue(h) != 0) goto done;
|
||||
HashSetValue(h, 1);
|
||||
|
||||
/* Count errors in this cell definition by scanning the error plane. */
|
||||
|
||||
count = 0;
|
||||
(void) DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR],
|
||||
&def->cd_bbox, &DBAllButSpaceBits, drcCountFunc2, (ClientData)(&count));
|
||||
HashSetValue(h, (spointertype)count + 1);
|
||||
|
||||
return count;
|
||||
/* Ignore children that have not been loaded---we will only report */
|
||||
/* errors that can be seen. This avoids immediately loading and */
|
||||
/* drc processing large layouts simply because we asked for an */
|
||||
/* error count. When the cell is loaded, drc will be checked */
|
||||
/* anyway, and the count can be updated in response to that check. */
|
||||
|
||||
if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0) return 0;
|
||||
|
||||
/* As a special performance hack, if the complete cell area is
|
||||
* handled here, don't bother to look at any more array elements.
|
||||
*/
|
||||
done: if (GEO_SURROUND(&scx->scx_area, &def->cd_bbox)) return 2;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
11
drc/drc.h
11
drc/drc.h
|
|
@ -125,6 +125,15 @@ typedef struct drcpendingcookie
|
|||
struct drcpendingcookie *dpc_next;
|
||||
} DRCPendingCookie;
|
||||
|
||||
/* Structure used to pass back lists of cell definitions and error tile counts */
|
||||
|
||||
typedef struct drccountlist
|
||||
{
|
||||
CellDef *dcl_def;
|
||||
int dcl_count;
|
||||
struct drccountlist *dcl_next;
|
||||
} DRCCountList;
|
||||
|
||||
/* Structure used to keep information about the current DRC style */
|
||||
|
||||
typedef struct drckeep
|
||||
|
|
@ -258,7 +267,7 @@ extern void DRCPrintRulesTable();
|
|||
extern void DRCWhy();
|
||||
extern void DRCPrintStats();
|
||||
extern void DRCCheck();
|
||||
extern int DRCCount();
|
||||
extern DRCCountList *DRCCount();
|
||||
extern int DRCFind();
|
||||
extern void DRCCatchUp();
|
||||
extern bool DRCFindInteractions();
|
||||
|
|
|
|||
Loading…
Reference in New Issue