diff --git a/base/flatten.c b/base/flatten.c index 11e2cf1..567862c 100644 --- a/base/flatten.c +++ b/base/flatten.c @@ -1421,11 +1421,27 @@ typedef struct ecomplist { ECompListPtr next; } ECompList; +/*----------------------------------------------------------------------*/ +/* Determine if a cell contains at least one device or subcircuit */ +/*----------------------------------------------------------------------*/ + +int +HasContents(struct nlist *tc) +{ + struct objlist *ob; + + for (ob = tc->cell; ob; ob = ob->next) + if (ob->type == FIRSTPIN) + return TRUE; + + return FALSE; +} + /*------------------------------------------------------*/ /* Survey the contents of a cell and sort into a hash */ /*------------------------------------------------------*/ -int +void SurveyCell(struct nlist *tc, struct hashdict *compdict, int file1, int file2, int which) { struct objlist *ob; @@ -1433,12 +1449,10 @@ SurveyCell(struct nlist *tc, struct hashdict *compdict, int file1, int file2, in ECompare *ecomp, *qcomp, *ncomp; int file = (which == 0) ? file1 : file2; int ofile = (which == 0) ? file2 : file1; - int retval = FALSE; char *dstr; for (ob = tc->cell; ob; ob = ob->next) { if (ob->type == FIRSTPIN) { - retval = TRUE; /* Cell has at least one device or subcircuit */ tsub = LookupCellFile(ob->model.class, file); if (tsub->flags & CELL_DUPLICATE) { // Always register a duplicate under the original name @@ -1492,7 +1506,6 @@ SurveyCell(struct nlist *tc, struct hashdict *compdict, int file1, int file2, in if (dstr) *dstr = '['; } } - return retval; } /*------------------------------------------------------*/ @@ -1540,28 +1553,10 @@ PrematchLists(char *name1, int file1, char *name2, int file2) listX0 = list0X = NULL; // Gather information about instances of cell "name1" - hascontents1 = SurveyCell(tc1, &compdict, file1, file2, 0); + SurveyCell(tc1, &compdict, file1, file2, 0); // Gather information about instances of cell "name2" - hascontents2 = SurveyCell(tc2, &compdict, file1, file2, 1); - - // If one cell has no contents, then flattening the other - // isn't going to improve anything, so stop here. - - if (!hascontents1 && !hascontents2 && (tc1->flags & CELL_PLACEHOLDER) - && (tc2->flags & CELL_PLACEHOLDER)) { - goto done; - } - else if (hascontents1 && !hascontents2 && (tc2->flags & CELL_PLACEHOLDER)) { - Fprintf(stdout, "Circuit 2 cell %s is a black box; will not flatten " - "Circuit 1\n", name2); - goto done; - } - else if (hascontents2 && !hascontents1 && (tc1->flags & CELL_PLACEHOLDER)) { - Fprintf(stdout, "Circuit 1 cell %s is a black box; will not flatten " - "Circuit 2\n", name1); - goto done; - } + SurveyCell(tc2, &compdict, file1, file2, 1); // Find all instances of one cell that have fewer in // the compared circuit. Check whether subcircuits diff --git a/base/flatten.h b/base/flatten.h index d259998..64f306b 100644 --- a/base/flatten.h +++ b/base/flatten.h @@ -3,5 +3,6 @@ extern int UniquePins(char *name, int filenum); extern void flattenCell(char *name, int file); +extern int HasContents(struct nlist *); #endif /* _FLATTEN_H */ diff --git a/base/netcmp.h b/base/netcmp.h index da7a722..df77fdd 100644 --- a/base/netcmp.h +++ b/base/netcmp.h @@ -46,6 +46,7 @@ extern int CreateCompareQueue(char *, int, char *, int); extern int GetCompareQueueTop(char **, int *, char **, int *); extern int PeekCompareQueueTop(char **, int *, char **, int *); extern void RemoveCompareQueue(); +extern int FlattenUnmatched(struct nlist *, char *, int, int); extern void PrintIllegalClasses(); extern void PrintIllegalNodeClasses(); diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index 6cb69dc..a75fa14 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -2095,8 +2095,9 @@ _netcmp_compare(ClientData clientData, int dohierarchy = FALSE; int assignonly = FALSE; int argstart = 1, qresult, llen, result; + int hascontents1, hascontents2; struct Correspond *nextcomp; - struct nlist *tp; + struct nlist *tp1 = NULL, *tp2 = NULL; Tcl_Obj *flist = NULL; if (objc > 1) { @@ -2139,24 +2140,24 @@ _netcmp_compare(ClientData clientData, } else if ((objc - argstart) == 2) { - result = CommonParseCell(interp, objv[argstart], &tp, &fnum1); + result = CommonParseCell(interp, objv[argstart], &tp1, &fnum1); if (result != TCL_OK) return TCL_ERROR; else if (fnum1 == -1) { Tcl_SetResult(interp, "Cannot use wildcard with compare command.\n", NULL); return TCL_ERROR; } - name1 = tp->name; + name1 = tp1->name; argstart++; - result = CommonParseCell(interp, objv[argstart], &tp, &fnum2); + result = CommonParseCell(interp, objv[argstart], &tp2, &fnum2); if (result != TCL_OK) return TCL_ERROR; else if (fnum2 == -1) { Tcl_SetResult(interp, "Cannot use wildcard with compare command.\n", NULL); return TCL_ERROR; } - name2 = tp->name; + name2 = tp2->name; if (dohierarchy) { RemoveCompareQueue(); @@ -2195,11 +2196,33 @@ _netcmp_compare(ClientData clientData, ConvertGlobals(name2, fnum2); } + if (tp1 == NULL) tp1 = LookupCellFile(name1, fnum1); + if (tp2 == NULL) tp2 = LookupCellFile(name2, fnum2); + CreateTwoLists(name1, fnum1, name2, fnum2, dolist); - while (PrematchLists(name1, fnum1, name2, fnum2) > 0) { - Fprintf(stdout, "Making another compare attempt.\n"); - Printf("Flattened mismatched instances and attempting compare again.\n"); - CreateTwoLists(name1, fnum1, name2, fnum2, dolist); + + hascontents1 = HasContents(tp1); + hascontents2 = HasContents(tp2); + + if (hascontents1 && !hascontents2 && (tp2->flags & CELL_PLACEHOLDER)) { + Fprintf(stdout, "Circuit 2 cell %s is a black box; will not flatten " + "Circuit 1\n", name2); + } + else if (hascontents2 && !hascontents1 && (tp1->flags & CELL_PLACEHOLDER)) { + Fprintf(stdout, "Circuit 1 cell %s is a black box; will not flatten " + "Circuit 2\n", name1); + } + else if (hascontents1 || hascontents2) { + FlattenUnmatched(tp1, name1, 1, 0); + FlattenUnmatched(tp2, name2, 1, 0); + + while (PrematchLists(name1, fnum1, name2, fnum2) > 0) { + Fprintf(stdout, "Making another compare attempt.\n"); + Printf("Flattened mismatched instances and attempting compare again.\n"); + CreateTwoLists(name1, fnum1, name2, fnum2, dolist); + FlattenUnmatched(tp1, name1, 0, 0); + FlattenUnmatched(tp2, name2, 0, 0); + } } // Return the names of the two cells being compared, if doing "compare