diff --git a/VERSION b/VERSION index 338640b..9dcb9bd 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.289 +1.5.290 diff --git a/base/flatten.c b/base/flatten.c index 0a8c7af..90017dd 100644 --- a/base/flatten.c +++ b/base/flatten.c @@ -1306,6 +1306,14 @@ int UniquePins(char *name, int filenum) return 1; } +/* Structure used below for keeping track of node numbers + * belonging to removed nodes. + */ +struct LinkedNum { + int node; + struct LinkedNum *next; +}; + /*------------------------------------------------------*/ /* Callback function for CleanupPins */ /* Note that if the first pin of the instance is a */ @@ -1318,6 +1326,7 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata) struct nlist *ptr; struct objlist *ob, *obt, *lob, *nob, *firstpin, *pob; struct nlist *tc = (struct nlist *)clientdata; + struct LinkedNum *newnodenum, *removedNodes = (struct LinkedNum *)NULL; int pinnum; char *saveinst = NULL; @@ -1373,6 +1382,15 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata) saveinst = ob->instance.name; } if (ob->model.class != NULL) FREE(ob->model.class); + + // Record the net number of the pin being removed, to + // check at the end if the net belonged to a pin that + // got orphaned. + newnodenum = (struct LinkedNum *)MALLOC(sizeof(struct LinkedNum)); + newnodenum->node = ob->node; + newnodenum->next = removedNodes; + removedNodes = newnodenum; + FREE(ob); } else { @@ -1416,6 +1434,28 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata) } } + while (removedNodes != NULL) { + int nodenum = removedNodes->node; + struct objlist *ob2; + + /* Only concerned with nodes that are in the pin list of ptr->cell */ + for (ob = ptr->cell; ob != NULL; ob = ob->next) { + if (ob->type != PORT) break; + if (ob->node == nodenum) break; + } + if (ob && (ob->type == PORT)) { + /* Check if this node number exists only in the port record */ + for (nob = ob->next; nob != NULL; nob = nob->next) + if (nob->node == nodenum) break; + if (nob == NULL) { + ob->node = -1; /* This pin is now disconnected */ + } + } + newnodenum = removedNodes; + removedNodes = removedNodes->next; + FREE(newnodenum); + } + if (saveinst != NULL) FREE(saveinst); return NULL; /* Keep the search going */ } diff --git a/base/netcmp.c b/base/netcmp.c index 0fa925a..c209fe1 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -6585,7 +6585,10 @@ int ResolveAutomorphsByPin(int match_nets) int portnum; /* Diagnostic */ - Fprintf(stdout, "Resolving symmetries by pin name.\n"); + if (match_nets) + Fprintf(stdout, "Resolving symmetries by net name.\n"); + else + Fprintf(stdout, "Resolving symmetries by pin name.\n"); for (NC = NodeClasses; NC != NULL; NC = NC->next) { struct Node *N1, *N2; @@ -7589,6 +7592,10 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) { if (ob2->type != PORT) break; else haspins = 1; + /* The model.port record for pins will be used to match the pin order + * of the cells in each netlist. Make sure the value is reset on + * entering this subroutine. + */ ob2->model.port = -1; } numnodes = 0; @@ -7742,7 +7749,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) if (strcmp(obn->name, "(no pins)")) { output_string_fill(ostr); output_string_left(ostr, "%s", obn->name); - output_string_right(ostr, "(no pin, node is %s", + output_string_right(ostr, "(no pin, node is %s)", obp->name); output_string_print(ostr); } @@ -8034,11 +8041,36 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) if (ob2->type != PORT) break; if (ob2->model.port == -1) { + /* Find this node in NodeClasses and find the corresponding + * net in the other circuit, if there is one (NOTE: Needs + * refactoring; should not be going through NodeClasses + * inside a loop.) + */ + obn = NULL; + for (NC = NodeClasses; NC != NULL; NC = NC->next) { + for (N2 = NC->nodes; N2 != NULL; N2 = N2->next) { + if (N2->graph != Circuit1->file) { + obp = N2->object; + if (IsPort(obp) && (obp->node == ob2->node)) { + for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) { + if (N1->graph == Circuit1->file) { + obn = N1->object; + } + } + } + } + } + } + if (Debug == 0) { // See above for reverse case if (strcmp(ob2->name, "(no pins)")) { output_string_fill(ostr); - output_string_left(ostr, "%s", "(no matching pin)"); + if (obn == NULL) + output_string_left(ostr, "%s", "(no matching pin)"); + else + output_string_left(ostr, "(no pin, node is %s)", + obn->name); output_string_right(ostr, "%s", ob2->name); output_string_print(ostr); } @@ -8155,12 +8187,15 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) if (obn == NULL) ob1->node = -1; /* Make disconnected */ } + /* NOTE: Previously kept the port if model.port is -1; however, + * all ports are -1 here so not sure why that was in there. . . + */ if (ob1 == NULL || ob1->type != PORT || ob1->node >= 0 - || (ob1->node < 0 && tc1->class == CLASS_MODULE) - || (ob1->node < 0 && ob1->model.port == -1)) { + || (ob1->node < 0 && tc1->class == CLASS_MODULE)) { /* Add a proxy pin to tc2 */ obn = (struct objlist *)CALLOC(1, sizeof(struct objlist)); + obn->node = -1; if (ob1 == NULL) { obn->name = (char *)MALLOC(15); sprintf(obn->name, "proxy%d", rand() & 0x3ffffff); @@ -8172,7 +8207,6 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) obn->type = UNKNOWN; obn->model.port = (i - j); obn->instance.name = NULL; - obn->node = -1; if (ob2 == tc2->cell) { obn->next = ob2; @@ -8188,9 +8222,16 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) HashPtrInstall(obn->name, obn, &(tc2->objdict)); } - else if (ob1 != NULL && ob1->type == PORT) { + else if (ob1 != NULL && ob1->type == PORT && ob1->node < 0) { /* Disconnected node was not meaningful, has no pin match in */ - /* the compared circuit, and so should be discarded. */ + /* the compared circuit, and so should be discarded. This */ + /* case is not output above, so do it here. */ + + output_string_fill(ostr); + output_string_left(ostr, "%s", ob1->name); + output_string_right(ostr, "%s", "(no matching pin)"); + output_string_print(ostr); + ob1->node = -2; needclean1 = 1; diff --git a/tcltk/netgen.tcl.in b/tcltk/netgen.tcl.in index 164850c..2d5c13c 100644 --- a/tcltk/netgen.tcl.in +++ b/tcltk/netgen.tcl.in @@ -655,6 +655,11 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { } } elseif {[netgen::print queue] == {} && $result == 0} { set pinMismatch 1 + } else { + # This assumes that proxy pins are added correctly. Previously, + # that was not trusted, and so an initial pin mismatch would + # always force subcells to be flattened. + set doFlatten 0 } } if {$doFlatten} {