(1) Modified the method used for the previous commit, as it was

found to make ext2spice runtimes very long for large layouts.
The new method is equivalent but doesn't incur the overhead.
Also:  Changed a flag check which was causing the substrate node
to be output as a port for certain layouts where the substrate
node connects to no devices, and so should be optimized out.
This commit is contained in:
Tim Edwards 2022-01-13 17:00:07 -05:00
parent b68744a944
commit 91b00a633f
2 changed files with 32 additions and 53 deletions

View File

@ -1684,13 +1684,15 @@ esMakePorts(hc, cdata)
if (nn->efnn_node && !(nn->efnn_node->efnode_flags & EF_PORT))
{
/* If a node is marked EF_SUBS_NODE (is substrate) */
/* or EF_GLOB_SUBS_NODE (is global substrate) */
/* but not EF_SUBS_PORT (connects to no devices) */
/* and parasitic output is disabled, then do not */
/* force the substrate connection to be a port. */
if ((EFCapThreshold != (EFCapValue)INFINITE_THRESHOLD_F) ||
(!(nn->efnn_node->efnode_flags & EF_SUBS_NODE)) ||
(nn->efnn_node->efnode_flags & EF_SUBS_PORT))
(!(nn->efnn_node->efnode_flags &
(EF_SUBS_NODE | EF_GLOB_SUBS_NODE))) ||
(nn->efnn_node->efnode_flags & EF_SUBS_PORT))
{
nn->efnn_node->efnode_flags |= EF_PORT;
nn->efnn_port = -1; // Will be sorted later

View File

@ -1698,7 +1698,7 @@ topVisit(def, doStub)
EFNode *snode, *basenode;
EFNodeName *sname, *nodeName;
HashSearch hs;
HashEntry *he, *hep;
HashEntry *he, *hep, *heh;
HashTable portNameTable;
int portorder, portmax, tchars;
bool explicit;
@ -1725,35 +1725,6 @@ topVisit(def, doStub)
fprintf(esSpiceF, ".subckt %s", subcktname);
tchars = 8 + strlen(subcktname);
/* Get list of port names from the flattened/optimized definition */
HashStartSearch(&hs);
while (he = HashNext(&efNodeHashTable, &hs))
{
char stmp[MAX_STR_SIZE];
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)
{
if (def->def_flags & DEF_ABSTRACT)
{
EFHNSprintf(stmp, nodeName->efnn_hier);
pname = stmp;
}
else
pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
/* Create an entry for this port in portNameTable */
hep = HashFind(&portNameTable, pname);
HashSetValue(hep, (ClientData)-1);
}
}
/* Note that the ports of the subcircuit will not necessarily be */
/* ALL the entries in the hash table, so we have to check. */
@ -1822,6 +1793,23 @@ topVisit(def, doStub)
portidx = nodeName->efnn_port;
if (portidx < 0) continue;
/* Check if the same hierName is recorded in the flattened/optimized
* def's efNodeHashTable. If not, then it has been optimized out
* and should be removed from the port list.
*/
if (def->def_flags & DEF_ABSTRACT)
heh = HashLookOnly(&efNodeHashTable, nodeName->efnn_hier);
else
heh = HashLookOnly(&efNodeHashTable, snode->efnode_name->efnn_hier);
if (heh == (HashEntry *)NULL)
{
/* Port was optimized out */
snode->efnode_flags &= ~EF_PORT;
TxPrintf("Note: Port %s was optimized out of %s\n",
pname, def->def_name);
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.
@ -1836,34 +1824,23 @@ topVisit(def, doStub)
pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
hep = HashLookOnly(&portNameTable, pname);
if (hep != (HashEntry *)NULL)
if (hep == (HashEntry *)NULL)
{
int porttest = (int)(pointertype)HashGetValue(hep);
if (porttest != -1)
{
/* Node that was unassigned has been found to be
* a repeat (see NOTE at top), so make sure its
* port number is set correctly.
*/
nodeName->efnn_port = (int)(pointertype)HashGetValue(hep);
}
else
{
HashSetValue(hep, (ClientData)(pointertype)nodeName->efnn_port);
if (sorted_ports[portidx] == NULL)
sorted_ports[portidx] = StrDup((char **)NULL, pname);
}
hep = HashFind(&portNameTable, pname);
HashSetValue(hep, (ClientData)(pointertype)nodeName->efnn_port);
if (sorted_ports[portidx] == NULL)
sorted_ports[portidx] = StrDup((char **)NULL, pname);
}
else
{
/* Port was optimized out */
snode->efnode_flags &= ~EF_PORT;
TxPrintf("Note: Port %s was optimized out of %s\n",
pname, def->def_name);
/* Node that was unassigned has been found to be
* a repeat (see NOTE at top), so make sure its
* port number is set correctly.
*/
nodeName->efnn_port = (int)(pointertype)HashGetValue(hep);
}
}
}
HashKill(&portNameTable);
/* Output all ports, in order */