Added code to catch and print an error in connectivity between a

port and an internal node which can be missed when pin permutations
are present.  Previously, that could produce a situation where
netgen would report a "port error" but otherwise list all ports
as matching.  Because the permutation handling makes this hard to
detect while generating pin correspondence output, the non-matching
pins are listed separately at the end, and only if no mismatch was
detected during output.
This commit is contained in:
R. Timothy Edwards 2025-09-09 13:45:29 -04:00
parent e84700a607
commit 6e6e9fb73f
2 changed files with 38 additions and 8 deletions

View File

@ -1 +1 @@
1.5.299 1.5.300

View File

@ -7601,6 +7601,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
int hasproxy1 = 0, hasproxy2 = 0; int hasproxy1 = 0, hasproxy2 = 0;
int needclean1 = 0, needclean2 = 0; int needclean1 = 0, needclean2 = 0;
int nomatch = 0; int nomatch = 0;
int P1, P2;
int filenum = -1; int filenum = -1;
int *correspond; int *correspond;
char *ostr; char *ostr;
@ -7633,6 +7634,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
return 2; return 2;
} }
correspond = (int *)CALLOC((tc1->nodename_cache_maxnodenum + 1), sizeof(int));
cover = (char *)CALLOC(numnodes, sizeof(char)); cover = (char *)CALLOC(numnodes, sizeof(char));
numorig = numnodes; numorig = numnodes;
@ -7851,8 +7853,6 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
ob1 = tc1->cell; ob1 = tc1->cell;
correspond = (int *)CALLOC((tc1->nodename_cache_maxnodenum + 1), sizeof(int));
for (i = 0; i < numorig; i++) { for (i = 0; i < numorig; i++) {
bangptr1 = strrchr(ob1->name, '!'); bangptr1 = strrchr(ob1->name, '!');
if (bangptr1 && (*(bangptr1 + 1) == '\0')) if (bangptr1 && (*(bangptr1 + 1) == '\0'))
@ -7973,7 +7973,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if (bangptr2) *bangptr2 = '!'; if (bangptr2) *bangptr2 = '!';
break; break;
} }
else { else if (IsPort(ob1) && IsPort(ob2)) {
struct Permutation *permute1, *permute2; struct Permutation *permute1, *permute2;
struct objlist *ob1a = NULL, *ob2a = NULL; struct objlist *ob1a = NULL, *ob2a = NULL;
@ -8003,10 +8003,8 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
} }
if (ob1a && ob2a) { if (ob1a && ob2a) {
if ((ob1->node == ob1a->node) && (ob2->node == ob2a->node)) { if ((ob1->node == ob1a->node) && (ob2->node == ob2a->node)) {
/* This should be enough to prove equivalency */ if ((correspond[ob1->node] == 0) ||
if ((correspond[ob1->node] == 0) || (correspond[ob1->node] == ob2->node)) { (correspond[ob1->node] == ob2->node)) {
correspond[ob1->node] = ob2->node; /* remember corresponding node */
ob2->model.port = i; /* save order */ ob2->model.port = i; /* save order */
*(cover + i) = (char)1; *(cover + i) = (char)1;
@ -8269,6 +8267,38 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if (Debug == 0) if (Debug == 0)
output_string_print_divider(ostr, FALSE); output_string_print_divider(ostr, FALSE);
/* Catch errors where disconnected ports get effectively hidden by */
/* pin permutations. */
if (result == 1) {
int found = 0;
for (NC = NodeClasses; NC != NULL; NC = NC->next) {
P1 = P2 = 0;
for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) {
if (N1->graph == Circuit2->file)
if (IsPort(N1->object)) P2++;
if (N1->graph == Circuit1->file)
if (IsPort(N1->object)) P1++;
}
if (P1 != P2) {
if (found == 0)
Fprintf(stdout, "\nPort connection errors found:\n");
found = 1;
for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) {
obn = N1->object;
if (IsPort(obn))
Fprintf(stdout, " %s (%d)\n", obn->name, N1->graph);
else
Fprintf(stdout, " %s (%d) (no port)\n", obn->name, N1->graph);
if (N1->graph == Circuit1->file)
correspond[obn->node] = -1;
}
}
}
if (found == 1) Fprintf(stdout, "\n");
}
/* Run cleanuppins on circuit 1 */ /* Run cleanuppins on circuit 1 */
if (needclean1) if (needclean1)
CleanupPins(tc1->name, tc1->file); CleanupPins(tc1->name, tc1->file);