Corrected two annoying errors: (1) SPICE netlist output subcircuits
could have multiple ports of the same name. This problem had been worked over before, but there was an indpendent mechanism producing the same result for a completely different reason, caused by subcells being much larger than the cookie-cutter extraction method's extraction regions. Solved by tracking port names in a hash table and preventing re-use. (2) ext2spice was producing "no such node" errors; like (1) this had been previously worked on, and like (1) this mechanism was independent. Problem came from not passing -1 to extHierSubstrate for the non-arrayed dimension of a 1-dimensional array. Also: Removed the word "fatal" from extraction error reporting, as nearly all extraction errors are entirely benign. This should clear up confusion among alarmed end-users.
This commit is contained in:
parent
0ad9ac91e3
commit
f343863ce3
|
|
@ -951,7 +951,7 @@ CmdExtract(w, cmd)
|
||||||
"style [stylename] set current extraction parameter style",
|
"style [stylename] set current extraction parameter style",
|
||||||
"unique [option] generate unique names when different nodes\n\
|
"unique [option] generate unique names when different nodes\n\
|
||||||
have the same name",
|
have the same name",
|
||||||
"warn [ [no] option] enable/disable reporting of non-fatal errors",
|
"warn [ [no] option] enable/disable reporting of non-serious errors",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1557,6 +1557,7 @@ devDistJunctHierVisit(hc, dev, scale)
|
||||||
* for each connection to it. Note that this generates an arbitrary
|
* for each connection to it. Note that this generates an arbitrary
|
||||||
* port order for each cell. To have a specific port order, it is
|
* port order for each cell. To have a specific port order, it is
|
||||||
* necessary to generate ports for each cell.
|
* necessary to generate ports for each cell.
|
||||||
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1570,6 +1571,7 @@ esMakePorts(hc, cdata)
|
||||||
Use *use;
|
Use *use;
|
||||||
HashEntry *he;
|
HashEntry *he;
|
||||||
EFNodeName *nn;
|
EFNodeName *nn;
|
||||||
|
|
||||||
char *name, *portname, *tptr, *aptr, *locname;
|
char *name, *portname, *tptr, *aptr, *locname;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1635,6 +1635,11 @@ subcktUndef(use, hierName, is_top)
|
||||||
* subcircuit, and implicit substrate connections should not be
|
* subcircuit, and implicit substrate connections should not be
|
||||||
* output.
|
* output.
|
||||||
*
|
*
|
||||||
|
* NOTE: The cookie-cutter method for extraction can result in multiple
|
||||||
|
* connections to the same port if the net spans multiple extraction regions.
|
||||||
|
* Because of this, it is necessary to make sure that the same port name is
|
||||||
|
* not output twice.
|
||||||
|
*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -1646,13 +1651,16 @@ topVisit(def, doStub)
|
||||||
EFNode *snode, *basenode;
|
EFNode *snode, *basenode;
|
||||||
EFNodeName *sname, *nodeName;
|
EFNodeName *sname, *nodeName;
|
||||||
HashSearch hs;
|
HashSearch hs;
|
||||||
HashEntry *he;
|
HashEntry *he, *hep;
|
||||||
|
HashTable portNameTable;
|
||||||
int portorder, portmax, tchars;
|
int portorder, portmax, tchars;
|
||||||
DevParam *plist, *pptr;
|
DevParam *plist, *pptr;
|
||||||
char *instname;
|
char *instname;
|
||||||
char *subcktname;
|
char *subcktname;
|
||||||
char *pname;
|
char *pname;
|
||||||
|
|
||||||
|
HashInit(&portNameTable, 32, HT_STRINGKEYS);
|
||||||
|
|
||||||
/* SPICE subcircuit names must begin with A-Z. This will also be */
|
/* SPICE subcircuit names must begin with A-Z. This will also be */
|
||||||
/* enforced when writing X subcircuit calls. */
|
/* enforced when writing X subcircuit calls. */
|
||||||
subcktname = def->def_name;
|
subcktname = def->def_name;
|
||||||
|
|
@ -1698,19 +1706,24 @@ topVisit(def, doStub)
|
||||||
if (snode->efnode_flags & EF_PORT)
|
if (snode->efnode_flags & EF_PORT)
|
||||||
{
|
{
|
||||||
pname = nodeSpiceName(snode->efnode_name->efnn_hier, &basenode);
|
pname = nodeSpiceName(snode->efnode_name->efnn_hier, &basenode);
|
||||||
if (basenode->efnode_name->efnn_port < 0)
|
if (HashLookOnly(&portNameTable, pname) == NULL)
|
||||||
{
|
{
|
||||||
if (tchars > 80)
|
hep = HashFind(&portNameTable, pname);
|
||||||
|
if (basenode->efnode_name->efnn_port < 0)
|
||||||
{
|
{
|
||||||
/* Line continuation */
|
if (tchars > 80)
|
||||||
fprintf(esSpiceF, "\n+");
|
{
|
||||||
tchars = 1;
|
/* Line continuation */
|
||||||
|
fprintf(esSpiceF, "\n+");
|
||||||
|
tchars = 1;
|
||||||
|
}
|
||||||
|
fprintf(esSpiceF, " %s", pname);
|
||||||
|
tchars += strlen(pname) + 1;
|
||||||
|
basenode->efnode_name->efnn_port = portorder++;
|
||||||
}
|
}
|
||||||
fprintf(esSpiceF, " %s", pname);
|
snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port;
|
||||||
tchars += strlen(pname) + 1;
|
HashSetValue(hep, (ClientData)snode->efnode_name->efnn_port);
|
||||||
basenode->efnode_name->efnn_port = portorder++;
|
|
||||||
}
|
}
|
||||||
snode->efnode_name->efnn_port = basenode->efnode_name->efnn_port;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1757,8 +1770,23 @@ topVisit(def, doStub)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
|
pname = nodeSpiceName(snode->efnode_name->efnn_hier, NULL);
|
||||||
fprintf(esSpiceF, " %s", pname);
|
|
||||||
tchars += strlen(pname) + 1;
|
if (HashLookOnly(&portNameTable, pname) == NULL)
|
||||||
|
{
|
||||||
|
hep = HashFind(&portNameTable, pname);
|
||||||
|
HashSetValue(hep, (ClientData)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)HashGetValue(hep);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (portidx < 0)
|
else if (portidx < 0)
|
||||||
|
|
@ -1779,6 +1807,7 @@ topVisit(def, doStub)
|
||||||
portorder++;
|
portorder++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HashKill(&portNameTable);
|
||||||
|
|
||||||
/* Add all implicitly-defined local substrate node names */
|
/* Add all implicitly-defined local substrate node names */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -606,7 +606,12 @@ extArrayInterFunc(use, trans, x, y, ha)
|
||||||
extHierConnections(ha, extArrayPrimary, oneFlat);
|
extHierConnections(ha, extArrayPrimary, oneFlat);
|
||||||
|
|
||||||
/* Process substrate connection */
|
/* Process substrate connection */
|
||||||
extHierSubstrate(ha, use, x, y);
|
if (use->cu_xlo == use->cu_xhi)
|
||||||
|
extHierSubstrate(ha, use, -1, y);
|
||||||
|
else if (use->cu_ylo == use->cu_yhi)
|
||||||
|
extHierSubstrate(ha, use, x, -1);
|
||||||
|
else
|
||||||
|
extHierSubstrate(ha, use, x, y);
|
||||||
|
|
||||||
ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL;
|
ha->ha_cumFlat.et_nodes = (NodeRegion *) NULL;
|
||||||
if (ExtOptions & EXT_DOADJUST)
|
if (ExtOptions & EXT_DOADJUST)
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ extern FILE *extFileOpen();
|
||||||
/*
|
/*
|
||||||
* See extract.h for the bit flags that may be set in the following.
|
* See extract.h for the bit flags that may be set in the following.
|
||||||
* If any are set, the corresponding warnings get generated, leaving
|
* If any are set, the corresponding warnings get generated, leaving
|
||||||
* feedback messages. If this word is zero, only fatal errors are
|
* feedback messages. If this word is zero, only errors are
|
||||||
* reported.
|
* reported.
|
||||||
*/
|
*/
|
||||||
int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS;
|
int ExtDoWarn = EXTWARN_DUP|EXTWARN_FETS;
|
||||||
|
|
@ -663,7 +663,7 @@ extExtractStack(stack, doExtract, rootDef)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (fatal > 0)
|
if (fatal > 0)
|
||||||
TxError("Total of %d fatal error%s.\n",
|
TxError("Total of %d error%s (check feedback entries).\n",
|
||||||
fatal, fatal != 1 ? "s" : "");
|
fatal, fatal != 1 ? "s" : "");
|
||||||
if (warnings > 0)
|
if (warnings > 0)
|
||||||
TxError("Total of %d warning%s.\n",
|
TxError("Total of %d warning%s.\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue