Corrected the use of EF_SUBS_NODE to distinguish between device

substrate (bulk terminal) and global substrate.  Otherwise, the
routine in ext2hier.c that finds the substrate node will find the
first device bulk connection, not the default substrate.
This commit is contained in:
Tim Edwards 2021-12-30 13:27:42 -05:00
parent be5b6dec0c
commit 9a17539ca7
8 changed files with 33 additions and 18 deletions

View File

@ -1246,7 +1246,7 @@ spcsubHierVisit(hc, node, res, cap, resstrptr)
HierName *hierName;
char *nsn;
if (node->efnode_flags & EF_SUBS_NODE)
if (node->efnode_flags & EF_GLOB_SUBS_NODE)
{
hierName = (HierName *) node->efnode_name->efnn_hier;
nsn = nodeSpiceHierName(hc, hierName);
@ -1676,7 +1676,7 @@ esMakePorts(hc, cdata)
nn = (EFNodeName *) HashGetValue(he);
if (nn == NULL)
{
efBuildNode(portdef, FALSE, portname, 0.0,
efBuildNode(portdef, FALSE, FALSE, portname, 0.0,
0, 0, NULL, NULL, 0);
nn = (EFNodeName *) HashGetValue(he);
}
@ -1778,7 +1778,7 @@ esMakePorts(hc, cdata)
nn = (EFNodeName *) HashGetValue(he);
if (nn == NULL)
{
efBuildNode(portdef, FALSE, portname, 0.0,
efBuildNode(portdef, FALSE, FALSE, portname, 0.0,
0, 0, NULL, NULL, 0);
nn = (EFNodeName *) HashGetValue(he);
}

View File

@ -3352,7 +3352,7 @@ spcsubVisit(node, res, cap, resstr)
HierName *hierName;
char *nsn;
if (node->efnode_flags & EF_SUBS_NODE)
if (node->efnode_flags & EF_GLOB_SUBS_NODE)
{
hierName = (HierName *) node->efnode_name->efnn_hier;
nsn = nodeSpiceName(hierName, NULL);

View File

@ -135,9 +135,10 @@ extern float locScale;
*/
void
efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
efBuildNode(def, isSubsnode, isDevSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
Def *def; /* Def to which this connection is to be added */
bool isSubsnode; /* TRUE if the node is the substrate */
bool isSubsnode; /* TRUE if the node is the global substrate */
bool isDevSubsnode; /* TRUE if the node is a device body connection */
char *nodeName; /* One of the names for this node */
double nodeCap; /* Capacitance of this node to ground */
int x; int y; /* Location of a point inside this node */
@ -170,10 +171,15 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
newnode->efnode_pa[n].pa_perim += atoi(*av++);
}
/* If this node is identified as substrate, ensure that */
/* the flag is set. */
if (isSubsnode == TRUE)
/* If this node is identified as a device substrate or */
/* the global substrate, ensure that the corresponding */
/* flag is set. */
if (isDevSubsnode == TRUE)
newnode->efnode_flags |= EF_SUBS_NODE;
if (isSubsnode == TRUE)
newnode->efnode_flags |= EF_GLOB_SUBS_NODE;
return;
}
@ -193,8 +199,8 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
/* New node itself */
size = sizeof (EFNode) + (efNumResistClasses - 1) * sizeof (EFPerimArea);
newnode = (EFNode *) mallocMagic((unsigned)(size));
newnode->efnode_flags = (isSubsnode == TRUE) ? EF_SUBS_NODE : 0;
newnode->efnode_cap = nodeCap;
newnode->efnode_flags = 0;
newnode->efnode_attrs = (EFAttr *) NULL;
newnode->efnode_loc.r_xbot = (int)(0.5 + (float)x * locScale);
newnode->efnode_loc.r_ybot = (int)(0.5 + (float)y * locScale);
@ -206,6 +212,9 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName);
else newnode->efnode_type = 0;
if (isSubsnode == TRUE) newnode->efnode_flags |= EF_GLOB_SUBS_NODE;
if (isDevSubsnode == TRUE) newnode->efnode_flags |= EF_SUBS_NODE;
for (n = 0; n < efNumResistClasses && ac > 1; n++, ac -= 2)
{
newnode->efnode_pa[n].pa_area = atoi(*av++);
@ -465,7 +474,7 @@ efBuildEquiv(def, nodeName1, nodeName2)
{
if (efWarn)
efReadError("Creating new node %s\n", nodeName1);
efBuildNode(def, FALSE,
efBuildNode(def, FALSE, FALSE,
nodeName1, (double)0, 0, 0,
(char *) NULL, (char **) NULL, 0);
nn1 = (EFNodeName *) HashGetValue(he1);
@ -1075,7 +1084,7 @@ efBuildPortNode(def, name, idx, x, y, layername, toplevel)
if (nn == (EFNodeName *) NULL)
{
/* Create node if it doesn't already exist */
efBuildNode(def, FALSE, name, (double)0, x, y,
efBuildNode(def, FALSE, FALSE, name, (double)0, x, y,
layername, (char **) NULL, 0);
nn = (EFNodeName *) HashGetValue(he);
@ -1180,7 +1189,7 @@ efBuildDevNode(def, name, isSubsNode)
/* Create node if it doesn't already exist */
if (efWarn && !isSubsNode)
efReadError("Node %s doesn't exist so creating it\n", name);
efBuildNode(def, isSubsNode, name, (double)0, 0, 0,
efBuildNode(def, FALSE, isSubsNode, name, (double)0, 0, 0,
(char *) NULL, (char **) NULL, 0);
nn = (EFNodeName *) HashGetValue(he);

View File

@ -1058,9 +1058,9 @@ efFlatSingleCap(hc, name1, name2, conn)
if (n1 == n2)
return 0;
if (n1->efnode_flags & EF_SUBS_NODE)
if (n1->efnode_flags & EF_GLOB_SUBS_NODE)
n2->efnode_cap += conn->conn_cap; /* node 2 to substrate */
else if (n2->efnode_flags & EF_SUBS_NODE)
else if (n2->efnode_flags & EF_GLOB_SUBS_NODE)
n1->efnode_cap += conn->conn_cap; /* node 1 to substrate */
else
{

View File

@ -741,7 +741,7 @@ EFHierVisitNodes(hc, nodeProc, cdata)
res = EFNodeResist(snode);
cap = snode->efnode_cap;
hierName = (HierName *) snode->efnode_name->efnn_hier;
if (snode->efnode_flags & EF_SUBS_NODE)
if (snode->efnode_flags & EF_GLOB_SUBS_NODE)
cap = 0;
if (snode->efnode_flags & EF_KILLED) continue;

View File

@ -420,6 +420,7 @@ readfile:
cap = atoCap(argv[3])*cscale;
efBuildNode(def,
(keyTable[n].k_key == SUBSTRATE) ? TRUE : FALSE,
FALSE,
argv[1], (double) cap,
atoi(argv[4]), atoi(argv[5]), argv[6],
&argv[7], ac);
@ -446,7 +447,7 @@ readfile:
*/
case RNODE:
cap = atoCap(argv[3])*cscale;
efBuildNode(def, FALSE, argv[1], (double) cap,
efBuildNode(def, FALSE, FALSE, argv[1], (double) cap,
atoi(argv[4]), atoi(argv[5]), argv[6],
(char **) NULL, 0);
break;

View File

@ -691,7 +691,7 @@ EFVisitNodes(nodeProc, cdata)
}
else
{
if (node->efnode_flags & EF_SUBS_NODE)
if (node->efnode_flags & EF_GLOB_SUBS_NODE)
cap = 0;
}
if (efWatchNodes)

View File

@ -206,6 +206,11 @@ typedef struct efnhdr
* .ext file.
*/
#define EF_SUBS_NODE 0x40
/*
* EF_GLOB_SUBS_NODE is set for the node declared on the "substrate"
* line of the .ext file as the global default substrate node.
*/
#define EF_GLOB_SUBS_NODE 0x80
extern int efNumResistClasses; /* Number of resistance classes in efResists */