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.
This commit is contained in:
Tim Edwards 2019-10-29 13:55:28 -04:00
parent c342178458
commit fc86f44bb1
2 changed files with 44 additions and 26 deletions

View File

@ -1627,8 +1627,8 @@ esMakePorts(hc, cdata)
nn->efnn_port = -1; // Will be sorted later nn->efnn_port = -1; // Will be sorted later
// Diagnostic // Diagnostic
TxPrintf("Port connection in %s from net %s to net %s (%s)\n", // TxPrintf("Port connection in %s from net %s to net %s (%s)\n",
def->def_name, locname, name, portname); // def->def_name, locname, name, portname);
} }
} }

View File

@ -1372,10 +1372,11 @@ subcktVisit(use, hierName, is_top)
EFNode *snode; EFNode *snode;
Def *def = use->use_def; Def *def = use->use_def;
EFNodeName *nodeName; EFNodeName *nodeName;
int portorder, portmax, imp_max, tchars; int portorder, portmax, portidx, imp_max, tchars;
char stmp[MAX_STR_SIZE]; char stmp[MAX_STR_SIZE];
char *instname, *subcktname; char *instname, *subcktname;
DevParam *plist, *pptr; DevParam *plist, *pptr;
EFNodeName **nodeList;
if (is_top == TRUE) return 0; /* Ignore the top-level cell */ 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. */ /* Port numbers need not start at zero or be contiguous. */
/* They will be printed in numerical order. */ /* They will be printed in numerical order. */
portorder = 0; nodeList = (EFNodeName **)mallocMagic((portmax + 1) * sizeof(EFNodeName *));
while (portorder <= portmax) for (portidx = 0; portidx <= portmax; portidx++)
{ nodeList[portidx] = (EFNodeName *)NULL;
for (snode = (EFNode *) def->def_firstn.efnode_next;
for (snode = (EFNode *) def->def_firstn.efnode_next;
snode != &def->def_firstn; snode != &def->def_firstn;
snode = (EFNode *) snode->efnode_next) snode = (EFNode *) snode->efnode_next)
{ {
if (!(snode->efnode_flags & EF_PORT)) continue; if (!(snode->efnode_flags & EF_PORT)) continue;
for (nodeName = snode->efnode_name; nodeName != NULL; for (nodeName = snode->efnode_name; nodeName != NULL;
nodeName = nodeName->efnn_next) nodeName = nodeName->efnn_next)
{
EFNodeName *nn;
HashEntry *he;
char *pname;
portidx = nodeName->efnn_port;
if (nodeList[portidx] == NULL)
{ {
int portidx = nodeName->efnn_port; nodeList[portidx] = nodeName;
if (portidx == portorder) }
{ else if (EFHNBest(nodeName->efnn_hier, nodeList[portidx]->efnn_hier))
if (tchars > 80) {
{ nodeList[portidx] = nodeName;
fprintf(esSpiceF, "\n+");
tchars = 1;
}
tchars += spcdevOutNode(hierName, nodeName->efnn_hier,
"subcircuit", esSpiceF);
break;
}
} }
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 */ /* Look for all implicit substrate connections that are */
/* declared as local node names, and put them last. */ /* declared as local node names, and put them last. */
@ -1682,8 +1701,7 @@ topVisit(def, doStub)
tchars += strlen(pname) + 1; tchars += strlen(pname) + 1;
basenode->efnode_name->efnn_port = portorder++; 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;
} }
} }
} }