From 83dce151d87e909da6414632fa784dcadf5adcb0 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 17 Dec 2021 20:31:41 -0500 Subject: [PATCH] Made a correction to the last commit. The "FlattenUnmatched()" routine does not have an exact equivalent in PrematchLists() and needs to be run beforehand. This fix keeps FlattenUnmatched() from being run on all cells at the beginning and restricts it to being run on the contents of individual cells during matching, after checking if either of the cells is a black-box. Avoiding flattening contents of one side when the other is a black-box (or simply doesn't contain any subcircuits or devices) prevents unnecessary flattening of cells that will never get compared. --- base/flatten.c | 43 +++++++++++++++++++------------------------ base/flatten.h | 1 + base/netcmp.h | 1 + tcltk/tclnetgen.c | 41 ++++++++++++++++++++++++++++++++--------- 4 files changed, 53 insertions(+), 33 deletions(-) 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