From 9cebb767878928b6590bf101a19d262de62636f4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 29 Jul 2020 13:57:08 -0400 Subject: [PATCH 1/3] Corrected a problem in ResolveAutomorphsByProperty() that causes long run-times even when there are no properties to check. Corrected a problem with SPICE and verilog netlist reading which arbitrarily replaces file extensions even when a file extension is given, resulting in reading the wrong file. --- base/netcmp.c | 28 +++++++++++++++++----------- base/spice.c | 17 ++++++++++++----- base/verilog.c | 19 +++++++++++++------ 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/base/netcmp.c b/base/netcmp.c index a571fa3..73c793a 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -5286,8 +5286,10 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print, obn1 = tp1; for (tp2 = ob2->next; (tp2 != NULL) && tp2->type > FIRSTPIN; tp2 = tp2->next) obn2 = tp2; - if (tp1 && (tp1->type == FIRSTPIN)) tp1 = NULL; /* tp1 had no properties */ - if (tp2 && (tp2->type == FIRSTPIN)) tp2 = NULL; /* tp2 had no properties */ + if (tp1 && ((tp1->type == FIRSTPIN) || (tp1->type == NODE))) + tp1 = NULL; /* tp1 had no properties */ + if (tp2 && ((tp2->type == FIRSTPIN) || (tp2->type == NODE))) + tp2 = NULL; /* tp2 had no properties */ /* Check if there are any properties to match */ @@ -5688,21 +5690,20 @@ int ResolveAutomorphsByPin() struct Node *N; int C1, C2; unsigned long newhash, orighash; - struct nlist *tc1, *tc2; - struct objlist *tob, *ob1, *ob2; int portnum; + /* Diagnostic */ + Fprintf(stdout, "Resolving automorphisms by pin name.\n"); + for (NC = NodeClasses; NC != NULL; NC = NC->next) { struct Node *N1, *N2; C1 = C2 = 0; N1 = N2 = NULL; for (N = NC->nodes; N != NULL; N = N->next) { - if (N->graph == Circuit1->file) { + if (N->graph == Circuit1->file) C1++; - } - else { + else C2++; - } } if (C1 == C2 && C1 != 1) { @@ -5714,7 +5715,6 @@ int ResolveAutomorphsByPin() orighash = NC->nodes->hashval; for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) { if (N1->hashval != orighash) continue; - ob1 = N1->object; for (N2 = N1->next; N2 != NULL; N2 = N2->next) { if ((N2->graph != N1->graph) && (*matchfunc)(N2->object->name, N1->object->name)) { @@ -5752,6 +5752,9 @@ int ResolveAutomorphsByProperty() int C1, C2, result, badmatch; unsigned long orighash, newhash; + /* Diagnostic */ + Fprintf(stdout, "Resolving automorphisms by property value.\n"); + for (EC = ElementClasses; EC != NULL; EC = EC->next) { struct Element *E1, *E2; C1 = C2 = 0; @@ -5788,7 +5791,6 @@ int ResolveAutomorphsByProperty() badmatch = FALSE; for (E2 = E1->next; E2 != NULL; E2 = E2->next) { if (E2->hashval != orighash) continue; - if (E2->graph == E1->graph) continue; if (E1->graph == Circuit1->file) PropertyMatch(E1->object, E2->object, FALSE, FALSE, &result); else @@ -5875,6 +5877,8 @@ int ResolveAutomorphisms() Magic(newhash); E1->hashval = newhash; E2->hashval = newhash; + /* Diagnostic */ + // Fprintf(stdout, "Equivalencing 1 element out of %d.\n", C2); goto converge; } } @@ -5898,6 +5902,8 @@ int ResolveAutomorphisms() Magic(newhash); N1->hashval = newhash; N2->hashval = newhash; + /* Diagnostic */ + // Fprintf(stdout, "Equivalencing 1 node out of %d.\n", C2); goto converge; } } @@ -7356,7 +7362,7 @@ int Compare(char *cell1, char *cell2) /* arbitrarily resolve automorphisms */ Fprintf(stdout, "\n"); - Fprintf(stdout, "Arbitrarily resolving automorphisms:\n"); + Fprintf(stdout, "Resolving automorphisms by arbitrary symmetry breaking:\n"); while ((automorphisms = ResolveAutomorphisms()) > 0) ; if (automorphisms == -1) { MatchFail(cell1, cell2); diff --git a/base/spice.c b/base/spice.c index 0c29b0a..af2ec6c 100644 --- a/base/spice.c +++ b/base/spice.c @@ -1883,14 +1883,21 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox) CurrentCell = NULL; if ((filenum = OpenParseFile(fname, *fnum)) < 0) { - char name[100]; - SetExtension(name, fname, SPICE_EXTENSION); - if ((filenum = OpenParseFile(name, *fnum)) < 0) { - Fprintf(stderr,"Error in SPICE file read: No file %s\n",name); + if (strrchr(fname, '.') == NULL) { + char name[1024]; + SetExtension(name, fname, SPICE_EXTENSION); + if ((filenum = OpenParseFile(name, *fnum)) < 0) { + Fprintf(stderr, "Error in SPICE file read: No file %s\n", name); + *fnum = filenum; + return NULL; + } + } + else { + Fprintf(stderr, "Error in SPICE file read: No file %s\n", fname); *fnum = filenum; return NULL; - } + } } /* Make sure all SPICE file reading is case insensitive */ diff --git a/base/verilog.c b/base/verilog.c index 80a91d7..c4e500b 100644 --- a/base/verilog.c +++ b/base/verilog.c @@ -2069,14 +2069,21 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox) CurrentCell = NULL; if ((filenum = OpenParseFile(fname, *fnum)) < 0) { - char name[100]; - SetExtension(name, fname, VERILOG_EXTENSION); - if ((filenum = OpenParseFile(name, *fnum)) < 0) { - Fprintf(stderr,"Error in Verilog file read: No file %s\n",name); - *fnum = filenum; - return NULL; + if (strchr(fname, '.') == NULL) { + char name[1024]; + SetExtension(name, fname, VERILOG_EXTENSION); + if ((filenum = OpenParseFile(name, *fnum)) < 0) { + Fprintf(stderr, "Error in Verilog file read: No file %s\n", name); + *fnum = filenum; + return NULL; + } } + else { + Fprintf(stderr, "Error in Verilog file read: No file %s\n", fname); + *fnum = filenum; + return NULL; + } } /* All Verilog file reading is case sensitive. However: if */ From 339a0d5d4e7c84efd5941b5b28d1ab68cea46ea4 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 29 Jul 2020 13:59:24 -0400 Subject: [PATCH 2/3] Updated version to force the new tarball and github mirror. --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 5065a9f..78e942c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.150 +1.5.151 From 71ad228d8d16095e23ede6b85a0bf1dd37e9b0a0 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 29 Jul 2020 21:13:45 -0400 Subject: [PATCH 3/3] Modified the symmetry breaking routine that arbitrarily resolves automorphisms so that it arbitrarily assigns all pairs from circuit1 and circuit2 at once rather than assigning one pair at a time and rerunning to convergence. I'm not sure of the validity of this, other than that I have never seen a circuit fail to match after resolving automorphisms, leading me to believe that the way the symmetry breaking is done is irrelevant. --- base/netcmp.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/base/netcmp.c b/base/netcmp.c index 73c793a..977035d 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -5874,11 +5874,23 @@ int ResolveAutomorphisms() } if (C1 == C2 && C1 != 1) { unsigned long newhash; - Magic(newhash); - E1->hashval = newhash; - E2->hashval = newhash; - /* Diagnostic */ - // Fprintf(stdout, "Equivalencing 1 element out of %d.\n", C2); + + /* Do all of them at once. */ + /* NOTE: If this were to fail for some reason, it would */ + /* probably be necessary to do this the original slow way */ + /* which is to rehash one pair at a time and iterate to */ + /* convergence, and repeat. */ + + E1 = E2 = EC->elements; + while (E1 != NULL) { + while (E1->graph != Circuit1->file) E1 = E1->next; + while (E2->graph != Circuit2->file) E2 = E2->next; + Magic(newhash); + E1->hashval = newhash; + E2->hashval = newhash; + E1 = E1->next; + E2 = E2->next; + } goto converge; } } @@ -5899,11 +5911,23 @@ int ResolveAutomorphisms() } if (C1 == C2 && C1 != 1) { unsigned long newhash; - Magic(newhash); - N1->hashval = newhash; - N2->hashval = newhash; - /* Diagnostic */ - // Fprintf(stdout, "Equivalencing 1 node out of %d.\n", C2); + + /* Do all of them at once */ + /* NOTE: If this were to fail for some reason, it would */ + /* probably be necessary to do this the original slow way */ + /* which is to rehash one pair at a time and iterate to */ + /* convergence, and repeat. */ + + N1 = N2 = NC->nodes; + while (N1 != NULL) { + while (N1->graph != Circuit1->file) N1 = N1->next; + while (N2->graph != Circuit2->file) N2 = N2->next; + Magic(newhash); + N1->hashval = newhash; + N2->hashval = newhash; + N1 = N1->next; + N2 = N2->next; + } goto converge; } }