From c45d51e950b123d6814b2f4d00b5f854a11c0621 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 31 Jul 2020 12:22:50 -0400 Subject: [PATCH 1/2] Tracked down and fixed problems with implicit pins in verilog (pins that are not declared in the verilog netlist because they don't connect to anything, and their presence is not required by verilog syntax) and the printing of proxy pins created to act as placeholders for those implicit pins. Also removed the pinting of the "disconnected pin" messages for black-box modules (since by definition they have disconnected pins, because black-box modules have no contents). --- VERSION | 2 +- base/netcmp.c | 29 +++++++++++++++++++++++++++-- base/query.c | 6 +++++- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 589628c..336a6bc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.152 +1.5.153 diff --git a/base/netcmp.c b/base/netcmp.c index fb49c30..39bcf71 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -6918,6 +6918,8 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) if (*(cover + i) == (char)0) { j = 0; for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) { + char *name1, *name2; + if (!IsPort(ob2)) break; bangptr2 = strrchr(ob2->name, '!'); @@ -6925,7 +6927,14 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) *bangptr2 = '\0'; else bangptr2 = NULL; - if ((*matchfunc)(ob1->name, ob2->name)) { + name1 = ob1->name; + name2 = ob2->name; + + /* Recognize proxy pins as matching */ + if (!strncmp(name1, "proxy", 5)) name1 +=5; + if (!strncmp(name2, "proxy", 5)) name2 +=5; + + if ((*matchfunc)(name1, name2)) { ob2->model.port = i; /* save order */ *(cover + i) = (char)1; @@ -7032,7 +7041,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) obn->name = (char *)MALLOC(6 + strlen(ob2->name)); sprintf(obn->name, "proxy%s", ob2->name); obn->type = UNKNOWN; - obn->model.port = -1; + // obn->model.port = -1; obn->instance.name = NULL; obn->node = -1; if (ob1 == tc1->cell) { @@ -7102,6 +7111,22 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) obn->instance.name = NULL; obn->node = -1; + if (Debug == 0) { + if (strcmp(ob1->name, "(no pins)")) { + for (m = 0; m < left_col_end; m++) *(ostr + m) = ' '; + for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' '; + snprintf(ostr, left_col_end, "%s", ob1->name); + snprintf(ostr + left_col_end + 1, left_col_end, "(no matching pin)"); + for (m = 0; m < right_col_end + 1; m++) + if (*(ostr + m) == '\0') *(ostr + m) = ' '; + Fprintf(stdout, ostr); + } + } + else { + Fprintf(stderr, "No netlist match for cell %s pin %s\n", + tc1->name, ob1->name); + } + if (ob2 == tc2->cell) { obn->next = ob2; tc2->cell = obn; diff --git a/base/query.c b/base/query.c index 7067242..7da724f 100644 --- a/base/query.c +++ b/base/query.c @@ -801,7 +801,11 @@ void DescribeInstance(char *name, int file) { if (ob->node > nodemax) nodemax = ob->node; else if ((ob->node == -1) && (ob->model.port != PROXY)) { - if (!(tp->flags & CELL_PLACEHOLDER)) + + /* All black-box modules and placeholders by definition have all */ + /* disconnected pins, so don't report those. */ + + if (!(tp->flags & CELL_PLACEHOLDER) && (tp->class != CLASS_MODULE)) { if (disconnectednodes == 0) Fprintf(stderr, "\n"); disconnectednodes++; From 8e215d3b66acd6a6fa937cc1d1f594cdb75f3d62 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 31 Jul 2020 12:56:20 -0400 Subject: [PATCH 2/2] Corrected the PropertyMatch() routine; previously the symmetry breaking by property was only matching properties between circuits but not within the same circuit, which is needed for correct symmetry breaking. But the PropertyMatch() routine assumed that it is passed one item from each circuit, leading to a segfault when running the symmetry breaking within a single circuit. This has been fixed. --- base/netcmp.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/base/netcmp.c b/base/netcmp.c index 39bcf71..2d83357 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -5246,6 +5246,12 @@ void DumpNetworkAll(char *model, int file) /* NOTE: ob1 must belong to Circuit1, and ob2 must belong to */ /* Circuit2. The calling procedure is responsble for ensuring */ /* that this is true. */ +/* */ +/* NOTE: This routine assumes that if file1 == file2 or if */ +/* file2 != Circuit1->graph, then "do_print" is FALSE. It */ +/* hard-codes "Circuit 1" and "Circuit 2" in most print */ +/* statements. file1 == file2 only when checking properties */ +/* for symmetry breaking, where nothing is printed. */ /*--------------------------------------------------------------*/ #ifdef TCL_NETGEN @@ -5253,8 +5259,9 @@ Tcl_Obj * #else void #endif -PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print, - int do_list, int *retval) +PropertyMatch(struct objlist *ob1, int file1, + struct objlist *ob2, int file2, + int do_print, int do_list, int *retval) { struct nlist *tc1, *tc2; struct objlist *tp1, *tp2, *obn1, *obn2; @@ -5268,8 +5275,22 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print, Tcl_Obj *proplist = NULL, *mpair, *mlist; #endif - tc1 = LookupCellFile(ob1->model.class, Circuit1->file); - tc2 = LookupCellFile(ob2->model.class, Circuit2->file); + tc1 = LookupCellFile(ob1->model.class, file1); + tc2 = LookupCellFile(ob2->model.class, file2); + + if (tc1 == NULL || tc2 == NULL) { + if (tc1 == NULL) + Fprintf(stdout, "Error: Circuit %d device \"%s\" not found!\n", + file1, ob1->model.class); + else + Fprintf(stdout, "Error: Circuit %d device \"%s\" not found!\n", + file2, ob2->model.class); +#ifdef TCL_NETGEN + return NULL; +#else + return; +#endif + } if (tc1->classhash != tc2->classhash) { *retval = -1; @@ -5550,9 +5571,11 @@ PropertyCheck(struct ElementClass *EC, int do_print, int do_list, int *rval) E2 = Etmp; } #ifdef TCL_NETGEN - return PropertyMatch(E1->object, E2->object, do_print, do_list, rval); + return PropertyMatch(E1->object, E1->graph, E2->object, E2->graph, + do_print, do_list, rval); #else - PropertyMatch(E1->object, E2->object, do_print, do_list, rval); + PropertyMatch(E1->object, E1->graph, E2->object, E2->graph, + do_print, do_list, rval); #endif } @@ -5791,10 +5814,8 @@ int ResolveAutomorphsByProperty() badmatch = FALSE; for (E2 = E1->next; E2 != NULL; E2 = E2->next) { if (E2->hashval != orighash) continue; - if (E1->graph == Circuit1->file) - PropertyMatch(E1->object, E2->object, FALSE, FALSE, &result); - else - PropertyMatch(E2->object, E1->object, FALSE, FALSE, &result); + PropertyMatch(E1->object, E1->graph, E2->object, E2->graph, + FALSE, FALSE, &result); if (result == 0) { E2->hashval = newhash; if (E2->graph == E1->graph)