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:
Tim Edwards 2020-02-24 21:47:44 -05:00
parent b2c6193589
commit fba66b7dff
3 changed files with 135 additions and 34 deletions

View File

@ -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;

View File

@ -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

View File

@ -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();