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;
HashSearch hs;
HashEntry *he;
int portorder, portmax, portidx, imp_max, tchars;
int portorder, portmax, portidx, tchars;
char stmp[MAX_STR_SIZE];
char *instname, *subcktname;
DevParam *plist, *pptr;
@ -1502,7 +1502,7 @@ subcktVisit(use, hierName, is_top)
/* Note that the ports of the subcircuit will not necessarily be */
/* ALL the entries in the hash table, so we have to check. */
portmax = EFGetPortMax(def, &imp_max);
portmax = EFGetPortMax(def);
if (portmax < 0)
{
@ -1532,34 +1532,6 @@ subcktVisit(use, hierName, is_top)
"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
{
@ -1612,45 +1584,8 @@ subcktVisit(use, hierName, is_top)
tchars += spcdevOutNode(hierName, nodeName->efnn_hier,
"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);
/* 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. */
@ -1772,6 +1707,7 @@ topVisit(def, doStub)
char *subcktname;
char *pname;
char **sorted_ports;
bool *valid_ports;
linkedNodeName *lnn = NULL;
HashInit(&portNameTable, 32, HT_STRINGKEYS);
@ -1832,6 +1768,32 @@ topVisit(def, doStub)
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 */
/* printed in numerical order. This is done by allocating space for */
/* the output first and generating text into the allocated array */
@ -1845,12 +1807,12 @@ topVisit(def, doStub)
{
char stmp[MAX_STR_SIZE];
int portidx;
EFNodeName *unnumbered;
EFNodeName *unnumbered, *snname;
sname = (EFNodeName *) HashGetValue(he);
if (sname == NULL) continue; /* Should not happen */
snode = sname->efnn_node;
snode = sname->efnn_node;
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue;
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
@ -1858,6 +1820,13 @@ topVisit(def, doStub)
portidx = nodeName->efnn_port;
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
* the node. Otherwise, artifacts of the abstract view
* may cause nodes to be merged and the names lost.
@ -1911,40 +1880,6 @@ topVisit(def, doStub)
}
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
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
*
* Side effects:
* Larger value including the implicit ports is placed in the
* location of the pointer imp_max.
* None.
*
* ----------------------------------------------------------------------------
*/
int
EFGetPortMax(def, imp_max)
EFGetPortMax(def)
Def *def;
int *imp_max;
{
EFNode *snode;
EFNodeName *nodeName;
int portmax, portorder;
portmax = -1;
if (imp_max) *imp_max = -1;
for (snode = (EFNode *) def->def_firstn.efnode_next;
snode != &def->def_firstn;
@ -1140,15 +1137,7 @@ EFGetPortMax(def, imp_max)
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;
}
@ -1869,6 +1858,9 @@ efNodeMerge(node1ptr, node2ptr)
if (removing->efnode_flags & EF_SUBS_NODE)
keeping->efnode_flags |= EF_SUBS_NODE;
/* Test! */
removing->efnode_flags = 0;
/* Get rid of "removing" */
freeMagic((char *) removing);