Fixed two independent errors, both of which can cause devices to be
missing from a netlist generated by ext2spice with the "extresist" option enabled. The first had to do with some parts of nets being given alias names for a net, and the second was caused during "extresist" and would also result in error messages about devices missing terminals.
This commit is contained in:
parent
21336607e0
commit
84af801608
|
|
@ -162,7 +162,50 @@ efBuildNode(def, isSubsnode, isDevSubsnode, isExtNode, nodeName, nodeCap,
|
||||||
int tnew = 0;
|
int tnew = 0;
|
||||||
|
|
||||||
he = HashFind(&def->def_nodes, nodeName);
|
he = HashFind(&def->def_nodes, nodeName);
|
||||||
if (newname = (EFNodeName *) HashGetValue(he))
|
newname = (EFNodeName *)HashGetValue(he);
|
||||||
|
|
||||||
|
if (newname && (def->def_kills != NULL))
|
||||||
|
{
|
||||||
|
HashEntry *hek;
|
||||||
|
EFNodeName *nn, *knn, *nodeAlias, *lastAlias;
|
||||||
|
|
||||||
|
/* Watch for nodes that are aliases of the node that was most
|
||||||
|
* recently killed. This can occur in .res.ext files where an
|
||||||
|
* equivalent node name (alias) is used as one of the node
|
||||||
|
* points. It must be regenerated as its own node and removed
|
||||||
|
* from the name list of the killed node.
|
||||||
|
*/
|
||||||
|
hek = HashLookOnly(&def->def_nodes, EFHNToStr(def->def_kills->kill_name));
|
||||||
|
if (hek != NULL)
|
||||||
|
{
|
||||||
|
knn = (EFNodeName *) HashGetValue(hek);
|
||||||
|
if ((knn != NULL) && (knn->efnn_node == newname->efnn_node))
|
||||||
|
{
|
||||||
|
/* Remove alias from killed node's name list */
|
||||||
|
lastAlias = NULL;
|
||||||
|
for (nodeAlias = knn->efnn_node->efnode_name; nodeAlias != NULL;
|
||||||
|
nodeAlias = nodeAlias->efnn_next)
|
||||||
|
{
|
||||||
|
if (!strcmp(EFHNToStr(nodeAlias->efnn_hier), nodeName))
|
||||||
|
{
|
||||||
|
if (lastAlias == NULL)
|
||||||
|
knn->efnn_node->efnode_name = nodeAlias->efnn_next;
|
||||||
|
else
|
||||||
|
lastAlias->efnn_next = nodeAlias->efnn_next;
|
||||||
|
EFHNFree(nodeAlias->efnn_hier, (HierName *)NULL, HN_ALLOC);
|
||||||
|
freeMagic(nodeAlias);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastAlias = nodeAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Force name to be made into a new node */
|
||||||
|
newname = (EFNodeName *)NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newname)
|
||||||
{
|
{
|
||||||
if (efWarn)
|
if (efWarn)
|
||||||
efReadError("Warning: duplicate node name %s\n", nodeName);
|
efReadError("Warning: duplicate node name %s\n", nodeName);
|
||||||
|
|
|
||||||
|
|
@ -1449,8 +1449,6 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||||
}
|
}
|
||||||
layoutDev->rd_fet_drain = (resNode *)NULL;
|
layoutDev->rd_fet_drain = (resNode *)NULL;
|
||||||
if (source->rn_name != NULL) resNodeNum--;
|
if (source->rn_name != NULL) resNodeNum--;
|
||||||
ResFixDevName(newname, SOURCE, simDev, source);
|
|
||||||
source->rn_name = simDev->source->name;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -1459,9 +1457,9 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||||
resNodeNum--;
|
resNodeNum--;
|
||||||
notdecremented = FALSE;
|
notdecremented = FALSE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
ResFixDevName(newname, SOURCE, simDev, source);
|
ResFixDevName(newname, SOURCE, simDev, source);
|
||||||
source->rn_name = simDev->source->name;
|
source->rn_name = simDev->source->name;
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1472,26 +1470,36 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||||
}
|
}
|
||||||
else if (simDev->drain == simNode)
|
else if (simDev->drain == simNode)
|
||||||
{
|
{
|
||||||
if ((source = layoutDev->rd_fet_source) != NULL)
|
/* Check for devices with only one terminal. If it was cast as source, */
|
||||||
|
/* then swap it with the drain so that the code below handles it */
|
||||||
|
/* correctly. */
|
||||||
|
|
||||||
|
if (layoutDev->rd_fet_drain == NULL && layoutDev->rd_fet_source != NULL)
|
||||||
{
|
{
|
||||||
|
layoutDev->rd_fet_drain = layoutDev->rd_fet_source;
|
||||||
|
layoutDev->rd_fet_source = (struct resnode *)NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((drain = layoutDev->rd_fet_drain) != NULL)
|
if ((drain = layoutDev->rd_fet_drain) != NULL)
|
||||||
|
{
|
||||||
|
if ((source = layoutDev->rd_fet_source) != NULL)
|
||||||
{
|
{
|
||||||
if (drain != source)
|
if (drain != source)
|
||||||
{
|
{
|
||||||
if (drain->rn_why & ORIGIN)
|
if (source->rn_why & ORIGIN)
|
||||||
{
|
|
||||||
ResMergeNodes(drain, source, &ResNodeQueue,
|
|
||||||
&ResNodeList);
|
|
||||||
ResDoneWithNode(drain);
|
|
||||||
source = drain;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
ResMergeNodes(source, drain, &ResNodeQueue,
|
ResMergeNodes(source, drain, &ResNodeQueue,
|
||||||
&ResNodeList);
|
&ResNodeList);
|
||||||
ResDoneWithNode(source);
|
ResDoneWithNode(source);
|
||||||
drain = source;
|
drain = source;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ResMergeNodes(drain, source, &ResNodeQueue,
|
||||||
|
&ResNodeList);
|
||||||
|
ResDoneWithNode(drain);
|
||||||
|
source = drain;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
layoutDev->rd_fet_source = (resNode *) NULL;
|
layoutDev->rd_fet_source = (resNode *) NULL;
|
||||||
if (drain->rn_name != NULL)
|
if (drain->rn_name != NULL)
|
||||||
|
|
@ -1499,19 +1507,17 @@ ResFixUpConnections(simDev, layoutDev, simNode, nodename)
|
||||||
resNodeNum--;
|
resNodeNum--;
|
||||||
notdecremented = FALSE;
|
notdecremented = FALSE;
|
||||||
}
|
}
|
||||||
ResFixDevName(newname, DRAIN, simDev, drain);
|
|
||||||
drain->rn_name = simDev->drain->name;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (source->rn_name != NULL && notdecremented)
|
if (drain->rn_name != NULL && notdecremented)
|
||||||
{
|
{
|
||||||
resNodeNum--;
|
resNodeNum--;
|
||||||
notdecremented = FALSE;
|
notdecremented = FALSE;
|
||||||
}
|
}
|
||||||
ResFixDevName(newname, DRAIN, simDev, source);
|
|
||||||
source->rn_name = simDev->drain->name;
|
|
||||||
}
|
}
|
||||||
|
ResFixDevName(newname, DRAIN, simDev, drain);
|
||||||
|
drain->rn_name = simDev->drain->name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TxError("Missing terminal connection of device at (%d %d) on net %s\n",
|
TxError("Missing terminal connection of device at (%d %d) on net %s\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue