From fc86f44bb16da80f37bbca7f286843d66e77d210 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 29 Oct 2019 13:55:28 -0400 Subject: [PATCH] Again revisited the problem of duplicate nodes. This time, I think I understand the problem, which is that nodes are ordered according to precedence of EFHNBest() within a circuit, but there is no concept of ordering between circuits. So ports end up listing nodes in arbitrary order, and the only way to resolve the order is to use EFHNBest() as is done within a subcircuit. Appears to work for different edge cases tested. --- ext2spice/ext2hier.c | 4 +-- ext2spice/ext2spice.c | 66 +++++++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 9b90f6a3..6f6fc555 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1627,8 +1627,8 @@ esMakePorts(hc, cdata) nn->efnn_port = -1; // Will be sorted later // Diagnostic - TxPrintf("Port connection in %s from net %s to net %s (%s)\n", - def->def_name, locname, name, portname); + // TxPrintf("Port connection in %s from net %s to net %s (%s)\n", + // def->def_name, locname, name, portname); } } diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 03ac5e78..168959cf 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -1372,10 +1372,11 @@ subcktVisit(use, hierName, is_top) EFNode *snode; Def *def = use->use_def; EFNodeName *nodeName; - int portorder, portmax, imp_max, tchars; + int portorder, portmax, portidx, imp_max, tchars; char stmp[MAX_STR_SIZE]; char *instname, *subcktname; DevParam *plist, *pptr; + EFNodeName **nodeList; if (is_top == TRUE) return 0; /* Ignore the top-level cell */ @@ -1467,35 +1468,53 @@ subcktVisit(use, hierName, is_top) /* Port numbers need not start at zero or be contiguous. */ /* They will be printed in numerical order. */ - portorder = 0; - while (portorder <= portmax) - { - for (snode = (EFNode *) def->def_firstn.efnode_next; + nodeList = (EFNodeName **)mallocMagic((portmax + 1) * sizeof(EFNodeName *)); + for (portidx = 0; portidx <= portmax; portidx++) + nodeList[portidx] = (EFNodeName *)NULL; + + for (snode = (EFNode *) def->def_firstn.efnode_next; snode != &def->def_firstn; snode = (EFNode *) snode->efnode_next) - { - if (!(snode->efnode_flags & EF_PORT)) continue; - for (nodeName = snode->efnode_name; nodeName != NULL; + { + if (!(snode->efnode_flags & EF_PORT)) continue; + for (nodeName = snode->efnode_name; nodeName != NULL; nodeName = nodeName->efnn_next) + { + EFNodeName *nn; + HashEntry *he; + char *pname; + + portidx = nodeName->efnn_port; + if (nodeList[portidx] == NULL) { - int portidx = nodeName->efnn_port; - if (portidx == portorder) - { - if (tchars > 80) - { - fprintf(esSpiceF, "\n+"); - tchars = 1; - } - tchars += spcdevOutNode(hierName, nodeName->efnn_hier, - "subcircuit", esSpiceF); - break; - } + nodeList[portidx] = nodeName; + } + else if (EFHNBest(nodeName->efnn_hier, nodeList[portidx]->efnn_hier)) + { + nodeList[portidx] = nodeName; } - if (nodeName != NULL) break; } - portorder++; } + for (portidx = 0; portidx <= portmax; portidx++) + { + nodeName = nodeList[portidx]; + + if (nodeName == NULL) + TxError("No port connection on port %d; need to resolve.\n", portidx); + else + { + if (tchars > 80) + { + fprintf(esSpiceF, "\n+"); + tchars = 1; + } + tchars += spcdevOutNode(hierName, nodeName->efnn_hier, + "subcircuit", esSpiceF); + } + } + freeMagic(nodeList); + /* Look for all implicit substrate connections that are */ /* declared as local node names, and put them last. */ @@ -1682,8 +1701,7 @@ topVisit(def, doStub) tchars += strlen(pname) + 1; basenode->efnode_name->efnn_port = portorder++; } - if (snode->efnode_name->efnn_hier->hn_parent == NULL) - snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port; + snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port; } } }