diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 3f660975..6f6fc555 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -1625,6 +1625,10 @@ esMakePorts(hc, cdata) { nn->efnn_node->efnode_flags |= EF_PORT; 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); } } @@ -1634,9 +1638,6 @@ esMakePorts(hc, cdata) updef = portdef; } - // Diagnostic - // TxPrintf("Connection in %s to net %s (%s)\n", def->def_name, - // name, portname); } } diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index e2e560f4..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. */ @@ -1615,7 +1634,7 @@ topVisit(def, doStub) Def *def; bool doStub; { - EFNode *snode; + EFNode *snode, *basenode; EFNodeName *sname, *nodeName; HashSearch hs; HashEntry *he; @@ -1668,7 +1687,9 @@ topVisit(def, doStub) snode = sname->efnn_node; if (snode->efnode_flags & EF_PORT) - if (snode->efnode_name->efnn_port < 0) + { + pname = nodeSpiceName(snode->efnode_name->efnn_hier, &basenode); + if (basenode->efnode_name->efnn_port < 0) { if (tchars > 80) { @@ -1676,11 +1697,12 @@ topVisit(def, doStub) fprintf(esSpiceF, "\n+"); tchars = 1; } - pname = nodeSpiceName(snode->efnode_name->efnn_hier); fprintf(esSpiceF, " %s", pname); tchars += strlen(pname) + 1; - snode->efnode_name->efnn_port = portorder++; + basenode->efnode_name->efnn_port = portorder++; } + snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port; + } } } else @@ -1714,7 +1736,7 @@ topVisit(def, doStub) fprintf(esSpiceF, "\n+"); tchars = 1; } - pname = nodeSpiceName(snode->efnode_name->efnn_hier); + pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL); fprintf(esSpiceF, " %s", pname); tchars += strlen(pname) + 1; break; @@ -2771,7 +2793,8 @@ FILE *outf; /* Canonical name */ nn = (EFNodeName *) HashGetValue(he); if (outf) - fprintf(outf, "%s", nodeSpiceName(nn->efnn_node->efnode_name->efnn_hier)); + fprintf(outf, "%s", nodeSpiceName(nn->efnn_node->efnode_name->efnn_hier, + NULL)); /* Mark node as visited */ if ((nodeClient *)nn->efnn_node->efnode_client == (ClientData)NULL) @@ -2982,7 +3005,7 @@ spcdevOutNode(prefix, suffix, name, outf) return 0; } nn = (EFNodeName *) HashGetValue(he); - nname = nodeSpiceName(nn->efnn_node->efnode_name->efnn_hier); + nname = nodeSpiceName(nn->efnn_node->efnode_name->efnn_hier, NULL); fprintf(outf, " %s", nname); /* Mark node as visited */ @@ -3028,8 +3051,8 @@ spccapVisit(hierName1, hierName2, cap) if (cap <= EFCapThreshold) return 0; - fprintf(esSpiceF, esSpiceCapFormat ,esCapNum++,nodeSpiceName(hierName1), - nodeSpiceName(hierName2), cap); + fprintf(esSpiceF, esSpiceCapFormat ,esCapNum++,nodeSpiceName(hierName1, NULL), + nodeSpiceName(hierName2, NULL), cap); return 0; } @@ -3064,8 +3087,8 @@ spcresistVisit(hierName1, hierName2, res) HierName *hierName2; float res; { - fprintf(esSpiceF, "R%d %s %s %g\n", esResNum++, nodeSpiceName(hierName1), - nodeSpiceName(hierName2), res / 1000.); + fprintf(esSpiceF, "R%d %s %s %g\n", esResNum++, nodeSpiceName(hierName1, NULL), + nodeSpiceName(hierName2, NULL), res / 1000.); return 0; } @@ -3100,7 +3123,7 @@ spcsubVisit(node, res, cap, resstr) if (node->efnode_flags & EF_SUBS_NODE) { hierName = (HierName *) node->efnode_name->efnn_hier; - nsn = nodeSpiceName(hierName); + nsn = nodeSpiceName(hierName, NULL); *resstr = StrDup((char **)NULL, nsn); return 1; } @@ -3150,7 +3173,7 @@ spcnodeVisit(node, res, cap) if (!isConnected && node->efnode_flags & EF_PORT) isConnected = TRUE; hierName = (HierName *) node->efnode_name->efnn_hier; - nsn = nodeSpiceName(hierName); + nsn = nodeSpiceName(hierName, NULL); if (esFormat == SPICE2 || esFormat == HSPICE && strncmp(nsn, "z@", 2)==0 ) { static char ntmp[MAX_STR_SIZE]; @@ -3195,7 +3218,7 @@ nodeVisitDebug(node, res, cap) EFAttr *ap; hierName = (HierName *) node->efnode_name->efnn_hier; - nsn = nodeSpiceName(hierName); + nsn = nodeSpiceName(hierName, NULL); TxError("** %s (%x)\n", nsn, node); printf("\t client.name=%s, client.m_w=%p\n", @@ -3218,23 +3241,27 @@ nodeVisitDebug(node, res, cap) * * Side effects: * Allocates nodeClients for the node. + * Returns the node in the "rnode" pointer, if non-NULL. * * ---------------------------------------------------------------------------- */ static char esTempName[MAX_STR_SIZE]; -char *nodeSpiceName(hname) +char *nodeSpiceName(hname, rnode) HierName *hname; + EFNode **rnode; { EFNodeName *nn; HashEntry *he; EFNode *node; + if (rnode) *rnode = (EFNode *)NULL; he = EFHNLook(hname, (char *) NULL, "nodeName"); if ( he == NULL ) return "errGnd!"; nn = (EFNodeName *) HashGetValue(he); node = nn->efnn_node; + if (rnode) *rnode = node; if ( (nodeClient *) (node->efnode_client) == NULL ) { initNodeClient(node); diff --git a/extflat/EFflat.c b/extflat/EFflat.c index 49087720..bd02d9c9 100644 --- a/extflat/EFflat.c +++ b/extflat/EFflat.c @@ -527,6 +527,7 @@ efAddNodes(hc, stdcell) HashSetValue(he, (char *) newname); newname->efnn_node = newnode; newname->efnn_hier = hierName; + newname->efnn_port = -1; if (newnode->efnode_name) { newname->efnn_next = newnode->efnode_name->efnn_next;