From e12883037c9844fb1bd61f861b264fc7e1028237 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 6 Mar 2023 09:36:35 -0500 Subject: [PATCH] Modified code from EquivalenceClasses() that forces the two cells to have unique class hashes. This has the problem that it prevents comparing N-to-1 cells because declaring X->X1 as equivalent breaks the original name equivalence of X->X. The new implementation adds the switch "-unique" to preserve the original behavior. Otherwise, the class hashes are made the same as the 2nd cell passed to the command, and it is the responsibility of the person running LVS to ensure that this is done in the correct direction. --- VERSION | 2 +- base/netcmp.c | 26 ++++++++++++++++---------- base/netcmp.h | 3 ++- tcltk/tclnetgen.c | 19 +++++++------------ 4 files changed, 26 insertions(+), 24 deletions(-) diff --git a/VERSION b/VERSION index 110fd1b..ce8755f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.248 +1.5.249 diff --git a/base/netcmp.c b/base/netcmp.c index af61c5d..dbfcaf0 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -7068,12 +7068,15 @@ int IgnoreClass(char *name, int file, unsigned char type) /* If file1 and file2 are -1, then these are names to */ /* be checked as netcmp works through the hierarchy. */ /* Otherwise, look up the structure for each file and */ -/* set the classhash of the second to that of the first */ +/* set the classhash of the second to that of the */ +/* first. If "dounique" is 1, then give the two cells */ +/* their own class hash; they will not be compared */ +/* any other cells in either netlist. */ /* */ /* Return 1 on success, 0 on failure */ /*------------------------------------------------------*/ -int EquivalenceClasses(char *name1, int file1, char *name2, int file2) +int EquivalenceClasses(char *name1, int file1, char *name2, int file2, int dounique) { char *class1, *class2; struct Correspond *newc; @@ -7098,16 +7101,19 @@ int EquivalenceClasses(char *name1, int file1, char *name2, int file2) if (tp->flags & CELL_DUPLICATE) reverse = 1; - /* Do a cross-check for each name in the other netlist. If */ - /* conflicting names exist, then alter the classhash to make it */ - /* unique. In the case of duplicate cells, don't do this. */ + if (dounique) { - if (!(tp->flags & CELL_DUPLICATE) && !(tp2->flags & CELL_DUPLICATE) && + /* Do a cross-check for each name in the other netlist. If */ + /* conflicting names exist, then alter the classhash to make */ + /* it unique. In the case of duplicate cells, don't do this. */ + + if (!(tp->flags & CELL_DUPLICATE) && !(tp2->flags & CELL_DUPLICATE) && !(*matchfunc)(name1, name2)) { - tpx = LookupCellFile(name1, file2); - if (tpx != NULL) need_new_seed = 1; - tpx = LookupCellFile(name2, file1); - if (tpx != NULL) need_new_seed = 1; + tpx = LookupCellFile(name1, file2); + if (tpx != NULL) need_new_seed = 1; + tpx = LookupCellFile(name2, file1); + if (tpx != NULL) need_new_seed = 1; + } } /* Now make the classhash values the same so that these cells */ diff --git a/base/netcmp.h b/base/netcmp.h index 72dd03c..3aa7a82 100644 --- a/base/netcmp.h +++ b/base/netcmp.h @@ -38,7 +38,8 @@ extern int PermuteSetup(char *model, int filenum, char *pin1, char *pin2); extern int PermuteForget(char *model, int filenum, char *pin1, char *pin2); extern int EquivalenceElements(char *name1, int file1, char *name2, int file2); extern int EquivalenceNodes(char *name1, int file1, char *name2, int file2); -extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2); +extern int EquivalenceClasses(char *name1, int file1, char *name2, int file2, + int dounique); extern int IgnoreClass(char *name, int file, unsigned char type); extern int MatchPins(struct nlist *tp1, struct nlist *tp2, int dolist); extern int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index 90b415a..a9e927a 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -2902,7 +2902,7 @@ _netcmp_equate(ClientData clientData, struct ElementClass *saveEclass = NULL; struct NodeClass *saveNclass = NULL; int file1, file2; - int i, l1, l2, ltest, lent, dolist = 0, doforce = 0; + int i, l1, l2, ltest, lent, dolist = 0, doforce = 0, dounique = 0; Tcl_Obj *tobj1, *tobj2, *tobj3; while (objc > 1) { @@ -2918,6 +2918,11 @@ _netcmp_equate(ClientData clientData, objv++; objc--; } + else if (!strcmp(optstart, "unique")) { + dounique = 1; + objv++; + objc--; + } else break; } @@ -3342,19 +3347,9 @@ _netcmp_equate(ClientData clientData, return TCL_ERROR; } } - - /* Now that all pins are assigned by name, reorder */ - /* the pin lists of the 2nd cell to match the */ - /* order of the 1st. */ - - /* Reorder the pin lists of instances of the 2nd */ - /* cell to match the order of the 1st. */ - - // pindata.cell2 = tp2; - // RecurseCellHashTable2(pinorder, (void *)(&pindata)); } - if (EquivalenceClasses(tp1->name, file1, tp2->name, file2)) { + if (EquivalenceClasses(tp1->name, file1, tp2->name, file2, dounique)) { Fprintf(stdout, "Device classes %s and %s are equivalent.\n", tp1->name, tp2->name); Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));