Removed code from ext2spice that is no longer functional.

Implemented a separate check for ports when writing a subcircuit
that cross-checks against the port list in the flattened
extraction.  This allows ports that were optimized out during
flattening of the hierarchy to be removed from the cell's port
list, which cuts down on disconnected nodes in the output port
list.
This commit is contained in:
Tim Edwards 2022-01-12 15:30:07 -05:00
parent f43bd19e36
commit b5f2b75768
3 changed files with 44 additions and 117 deletions

View File

@ -1 +1 @@
8.3.254 8.3.255

View File

@ -1463,7 +1463,7 @@ subcktVisit(use, hierName, is_top)
EFNodeName *sname, *nodeName; EFNodeName *sname, *nodeName;
HashSearch hs; HashSearch hs;
HashEntry *he; HashEntry *he;
int portorder, portmax, portidx, imp_max, tchars; int portorder, portmax, portidx, tchars;
char stmp[MAX_STR_SIZE]; char stmp[MAX_STR_SIZE];
char *instname, *subcktname; char *instname, *subcktname;
DevParam *plist, *pptr; DevParam *plist, *pptr;
@ -1502,7 +1502,7 @@ subcktVisit(use, hierName, is_top)
/* Note that the ports of the subcircuit will not necessarily be */ /* Note that the ports of the subcircuit will not necessarily be */
/* ALL the entries in the hash table, so we have to check. */ /* ALL the entries in the hash table, so we have to check. */
portmax = EFGetPortMax(def, &imp_max); portmax = EFGetPortMax(def);
if (portmax < 0) if (portmax < 0)
{ {
@ -1532,34 +1532,6 @@ subcktVisit(use, hierName, is_top)
"subcircuit", esSpiceF); "subcircuit", esSpiceF);
} }
} }
/* Look for all implicit substrate connections that are */
/* declared as local node names, and put them last. */
HashStartSearch(&hs);
while (he = HashNext(&def->def_nodes, &hs))
{
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue;
snode = sname->efnn_node;
if (snode && (snode->efnode_flags & EF_SUBS_PORT))
{
nodeName = snode->efnode_name;
if (nodeName->efnn_port < 0)
nodeName->efnn_port = ++portmax;
/* This is not a hierarchical name or node! */
EFHNSprintf(stmp, nodeName->efnn_hier);
if (tchars > 80)
{
fprintf(esSpiceF, "\n+");
tchars = 1;
}
fprintf(esSpiceF, " %s", stmp);
tchars += (1 + strlen(stmp));
}
}
} }
else else
{ {
@ -1612,45 +1584,8 @@ subcktVisit(use, hierName, is_top)
tchars += spcdevOutNode(hierName, nodeName->efnn_hier, tchars += spcdevOutNode(hierName, nodeName->efnn_hier,
"subcircuit", esSpiceF); "subcircuit", esSpiceF);
} }
else
{
// As port indexes do not have to be contiguous, this does not
// necessarily indicate an error condition. No need to report?
// TxError("No port connection on port %d; need to resolve.\n", portidx);
}
} }
freeMagic(nodeList); freeMagic(nodeList);
/* Look for all implicit substrate connections that are */
/* declared as local node names, and put them last. */
portorder = portmax + 1;
while (portorder <= imp_max)
{
HashStartSearch(&hs);
while (he = HashNext(&def->def_nodes, &hs))
{
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue;
snode = sname->efnn_node;
if ((snode == NULL) || !(snode->efnode_flags & EF_SUBS_PORT)) continue;
nodeName = snode->efnode_name;
if (nodeName->efnn_port == portorder)
{
/* This is not a hierarchical name or node! */
EFHNSprintf(stmp, nodeName->efnn_hier);
if (tchars > 80)
{
fprintf(esSpiceF, "\n+");
tchars = 1;
}
fprintf(esSpiceF, " %s", stmp);
tchars += (1 + strlen(stmp));
}
}
portorder++;
}
} }
/* SPICE subcircuit names must begin with A-Z. */ /* SPICE subcircuit names must begin with A-Z. */
@ -1772,6 +1707,7 @@ topVisit(def, doStub)
char *subcktname; char *subcktname;
char *pname; char *pname;
char **sorted_ports; char **sorted_ports;
bool *valid_ports;
linkedNodeName *lnn = NULL; linkedNodeName *lnn = NULL;
HashInit(&portNameTable, 32, HT_STRINGKEYS); HashInit(&portNameTable, 32, HT_STRINGKEYS);
@ -1832,6 +1768,32 @@ topVisit(def, doStub)
lnn = lnn->lnn_next; lnn = lnn->lnn_next;
} }
/* TEST */
valid_ports = (bool *)mallocMagic((portmax + 1) * sizeof(bool));
for (portorder = 0; portorder <= portmax; portorder++) valid_ports[portorder] = FALSE;
HashStartSearch(&hs);
while (he = HashNext(&efNodeHashTable, &hs))
{
char stmp[MAX_STR_SIZE];
int portidx;
EFNodeName *unnumbered, *snname;
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue; /* Should not happen */
snode = sname->efnn_node;
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
{
portidx = nodeName->efnn_port;
if (portidx < 0) continue;
valid_ports[portidx] = TRUE;
}
}
/* Port numbers need not start at zero or be contiguous. They will be */ /* Port numbers need not start at zero or be contiguous. They will be */
/* printed in numerical order. This is done by allocating space for */ /* printed in numerical order. This is done by allocating space for */
/* the output first and generating text into the allocated array */ /* the output first and generating text into the allocated array */
@ -1845,12 +1807,12 @@ topVisit(def, doStub)
{ {
char stmp[MAX_STR_SIZE]; char stmp[MAX_STR_SIZE];
int portidx; int portidx;
EFNodeName *unnumbered; EFNodeName *unnumbered, *snname;
sname = (EFNodeName *) HashGetValue(he); sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue; /* Should not happen */ if (sname == NULL) continue; /* Should not happen */
snode = sname->efnn_node;
snode = sname->efnn_node;
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue; if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next) for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
@ -1858,6 +1820,13 @@ topVisit(def, doStub)
portidx = nodeName->efnn_port; portidx = nodeName->efnn_port;
if (portidx < 0) continue; if (portidx < 0) continue;
/* Ignore (and unflag) ports that were removed from efNodeHashTable */
if (valid_port[portidx] == FALSE)
{
snode->efnode_flags &= ~EF_PORT;
continue;
}
/* If view is abstract, rely on the given port name, not /* If view is abstract, rely on the given port name, not
* the node. Otherwise, artifacts of the abstract view * the node. Otherwise, artifacts of the abstract view
* may cause nodes to be merged and the names lost. * may cause nodes to be merged and the names lost.
@ -1911,40 +1880,6 @@ topVisit(def, doStub)
} }
freeMagic(sorted_ports); freeMagic(sorted_ports);
/* Add all implicitly-defined local substrate node names */
if (!doStub)
{
HashStartSearch(&hs);
while (he = HashNext(&def->def_nodes, &hs))
{
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue;
snode = sname->efnn_node;
if (snode && (snode->efnode_flags & EF_SUBS_PORT) &&
!(snode->efnode_flags & EF_PORT))
{
if (snode->efnode_name->efnn_port < 0)
{
char stmp[MAX_STR_SIZE];
if (tchars > 80)
{
/* Line continuation */
fprintf(esSpiceF, "\n+");
tchars = 1;
}
/* This is not a hierarchical name or node! */
EFHNSprintf(stmp, snode->efnode_name->efnn_hier);
fprintf(esSpiceF, " %s", stmp);
snode->efnode_name->efnn_port = portorder++;
tchars += strlen(stmp) + 1;
}
}
}
}
// Add any parameters defined by "property parameter" in the cell // Add any parameters defined by "property parameter" in the cell
instname = mallocMagic(2 + strlen(def->def_name)); instname = mallocMagic(2 + strlen(def->def_name));

View File

@ -1109,23 +1109,20 @@ efBuildPortNode(def, name, idx, x, y, layername, toplevel)
* Value of highest port number in the cell def's node list * Value of highest port number in the cell def's node list
* *
* Side effects: * Side effects:
* Larger value including the implicit ports is placed in the * None.
* location of the pointer imp_max.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
int int
EFGetPortMax(def, imp_max) EFGetPortMax(def)
Def *def; Def *def;
int *imp_max;
{ {
EFNode *snode; EFNode *snode;
EFNodeName *nodeName; EFNodeName *nodeName;
int portmax, portorder; int portmax, portorder;
portmax = -1; portmax = -1;
if (imp_max) *imp_max = -1;
for (snode = (EFNode *) def->def_firstn.efnode_next; for (snode = (EFNode *) def->def_firstn.efnode_next;
snode != &def->def_firstn; snode != &def->def_firstn;
@ -1140,15 +1137,7 @@ EFGetPortMax(def, imp_max)
if (portorder > portmax) portmax = portorder; if (portorder > portmax) portmax = portorder;
} }
} }
else if (imp_max && (snode->efnode_flags & EF_SUBS_PORT))
{
nodeName = snode->efnode_name;
portorder = nodeName->efnn_port;
if (portorder > (*imp_max)) (*imp_max) = portorder;
}
} }
if (imp_max)
if (portmax > (*imp_max)) (*imp_max) = portmax;
return portmax; return portmax;
} }
@ -1869,6 +1858,9 @@ efNodeMerge(node1ptr, node2ptr)
if (removing->efnode_flags & EF_SUBS_NODE) if (removing->efnode_flags & EF_SUBS_NODE)
keeping->efnode_flags |= EF_SUBS_NODE; keeping->efnode_flags |= EF_SUBS_NODE;
/* Test! */
removing->efnode_flags = 0;
/* Get rid of "removing" */ /* Get rid of "removing" */
freeMagic((char *) removing); freeMagic((char *) removing);