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:
parent
52a424e511
commit
09f335862b
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue