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:
parent
f43bd19e36
commit
b5f2b75768
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue