Added a check for interrupt in "extresist". Modified the output of

ports in SPICE so that ports are first ordered by index into a
string array, and then output.  This avoids executing an expensive
double loop.
This commit is contained in:
Tim Edwards 2021-10-04 19:52:22 -04:00
parent 52a424e511
commit 09f335862b
2 changed files with 68 additions and 56 deletions

View File

@ -1718,6 +1718,7 @@ topVisit(def, doStub)
char *instname; char *instname;
char *subcktname; char *subcktname;
char *pname; char *pname;
char **sorted_ports;
linkedNodeName *lnn = NULL; linkedNodeName *lnn = NULL;
HashInit(&portNameTable, 32, HT_STRINGKEYS); HashInit(&portNameTable, 32, HT_STRINGKEYS);
@ -1778,76 +1779,84 @@ topVisit(def, doStub)
lnn = lnn->lnn_next; lnn = lnn->lnn_next;
} }
/* Port numbers need not start at zero or be contiguous. */ /* Port numbers need not start at zero or be contiguous. They will be */
/* They will be printed in numerical order. */ /* printed in numerical order. This is done by allocating space for */
/* the output first and generating text into the allocated array */
/* indexed by port, to avoid multiple scans through the hash table. */
portorder = 0; sorted_ports = (char **)mallocMagic((portmax + 1) * sizeof(char *));
while (portorder <= portmax) for (portorder = 0; portorder <= portmax; portorder++) sorted_ports[portorder] = NULL;
HashStartSearch(&hs);
while (he = HashNext(&def->def_nodes, &hs))
{ {
HashStartSearch(&hs); char stmp[MAX_STR_SIZE];
while (he = HashNext(&def->def_nodes, &hs)) int portidx;
EFNodeName *unnumbered;
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)
{ {
char stmp[MAX_STR_SIZE]; portidx = nodeName->efnn_port;
int portidx;
EFNodeName *unnumbered;
sname = (EFNodeName *) HashGetValue(he); /* If view is abstract, rely on the given port name, not
if (sname == NULL) continue; /* Should not happen */ * the node. Otherwise, artifacts of the abstract view
snode = sname->efnn_node; * may cause nodes to be merged and the names lost.
*/
if ((!snode) || (!(snode->efnode_flags & EF_PORT))) continue; if (def->def_flags & DEF_ABSTRACT)
for (nodeName = sname; nodeName != NULL; nodeName = nodeName->efnn_next)
{ {
portidx = nodeName->efnn_port; EFHNSprintf(stmp, nodeName->efnn_hier);
if (portidx == portorder) pname = stmp;
{ }
if (tchars > 80) else
{ pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
/* Line continuation */
fprintf(esSpiceF, "\n+");
tchars = 1;
}
/* If view is abstract, rely on the given port name, not if (HashLookOnly(&portNameTable, pname) == NULL)
* the node. Otherwise, artifacts of the abstract view {
* may cause nodes to be merged and the names lost. hep = HashFind(&portNameTable, pname);
*/ HashSetValue(hep, (ClientData)(pointertype)nodeName->efnn_port);
sorted_ports[portidx] = StrDup((char **)NULL, pname);
}
else
{
// Node that was unassigned has been found to be
// a repeat (see NOTE at top), so make sure its
// port number is set correctly.
if (def->def_flags & DEF_ABSTRACT) hep = HashFind(&portNameTable, pname);
{ nodeName->efnn_port = (int)(pointertype)HashGetValue(hep);
EFHNSprintf(stmp, nodeName->efnn_hier);
pname = stmp;
}
else
pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
if (HashLookOnly(&portNameTable, pname) == NULL)
{
hep = HashFind(&portNameTable, pname);
HashSetValue(hep,
(ClientData)(pointertype)nodeName->efnn_port);
fprintf(esSpiceF, " %s", pname);
tchars += strlen(pname) + 1;
}
else
{
// Node that was unassigned has been found to be
// a repeat (see NOTE at top), so make sure its
// port number is set correctly.
hep = HashFind(&portNameTable, pname);
nodeName->efnn_port = (int)(pointertype)HashGetValue(hep);
}
break;
}
} }
if (nodeName != NULL) break; if (nodeName != NULL) break;
} }
portorder++;
} }
HashKill(&portNameTable); HashKill(&portNameTable);
/* Output all ports, in order */
for (portorder = 0; portorder <= portmax; portorder++)
{
if (sorted_ports[portorder] != NULL)
{
if (tchars > 80)
{
/* Line continuation */
fprintf(esSpiceF, "\n+");
tchars = 1;
}
fprintf(esSpiceF, " %s", sorted_ports[portorder]);
tchars += strlen(pname) + 1;
freeMagic(sorted_ports[portorder]);
}
}
freeMagic(sorted_ports);
/* Add all implicitly-defined local substrate node names */ /* Add all implicitly-defined local substrate node names */
if (!doStub) if (!doStub)

View File

@ -17,6 +17,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "tiles/tile.h" #include "tiles/tile.h"
#include "utils/hash.h" #include "utils/hash.h"
#include "utils/undo.h" #include "utils/undo.h"
#include "utils/signals.h"
#include "database/database.h" #include "database/database.h"
#include "utils/malloc.h" #include "utils/malloc.h"
#include "textio/textio.h" #include "textio/textio.h"
@ -984,6 +985,8 @@ ResCheckSimNodes(celldef, resisdata)
{ {
HashEntry *he; HashEntry *he;
if (SigInterruptPending) break;
/* Ignore or include specified nodes */ /* Ignore or include specified nodes */
if (ResIncludeTable.ht_nEntries > 0) if (ResIncludeTable.ht_nEntries > 0)