src/spicelib/devices/*/*set.c, missing CKTdltNNum() invocations, complex cases

All locally created nodes (CKTmk..() invocations in XXXsetup())
  must be deleted in XXXunsetup()

Otherwise CKTmk..() invocations during a following CKTsetup()
  will re-emit still used node numbers,
  thus accidentally shorting nodes.

This patch fixes the complex cases,
  which are external node variables (ports of the instance),
  which might be moved over to other external node variables
  to cope with optional port connections.
This is fixed by copying the node numbers to local shadow variables
  to avoid messing with the external nodes.
Otherwise a following CKTsetup() might again meddle with the external
  node variables, at least causing considerable confusion, probably causing
  hard to find bugs.
This commit is contained in:
rlar 2017-01-22 19:25:14 +01:00
parent c0921250b7
commit 0e9576cb34
12 changed files with 130 additions and 2 deletions

View File

@ -30,6 +30,9 @@ typedef struct sB3SOIDDinstance
int B3SOIDDgNode;
int B3SOIDDsNode;
int B3SOIDDeNode;
int B3SOIDDbNodeExt;
int B3SOIDDtempNodeExt;
int B3SOIDDpNodeExt;
int B3SOIDDbNode;
int B3SOIDDtempNode;
int B3SOIDDpNode;

View File

@ -998,6 +998,11 @@ IFuid tmpName;
model->B3SOIDDadice = model->B3SOIDDadice0 / ( 1 + Cboxt / model->B3SOIDDcox);
here->B3SOIDDfloat = 0;
here->B3SOIDDpNode = here->B3SOIDDpNodeExt;
here->B3SOIDDbNode = here->B3SOIDDbNodeExt;
here->B3SOIDDtempNode = here->B3SOIDDtempNodeExt;
if (here->B3SOIDDbNode == -1)
/* no body contact but bNode to be created for SPICE iteration */
{ error = CKTmkVolt(ckt,&tmp,here->B3SOIDDname,"Body");
@ -1574,6 +1579,23 @@ B3SOIDDunsetup(GENmodel *inModel, CKTcircuit *ckt)
here->B3SOIDDvbsNode = 0;
}
if (here->B3SOIDDtempNode &&
here->B3SOIDDtempNode != here->B3SOIDDtempNodeExt &&
here->B3SOIDDtempNode != here->B3SOIDDbNodeExt &&
here->B3SOIDDtempNode != here->B3SOIDDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIDDtempNode);
here->B3SOIDDtempNode = 0;
}
if (here->B3SOIDDbNode &&
here->B3SOIDDbNode != here->B3SOIDDbNodeExt &&
here->B3SOIDDbNode != here->B3SOIDDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIDDbNode);
here->B3SOIDDbNode = 0;
}
here->B3SOIDDpNode = 0;
if (here->B3SOIDDsNodePrime
&& here->B3SOIDDsNodePrime != here->B3SOIDDsNode)
{

View File

@ -30,6 +30,9 @@ typedef struct sB3SOIFDinstance
int B3SOIFDgNode;
int B3SOIFDsNode;
int B3SOIFDeNode;
int B3SOIFDbNodeExt;
int B3SOIFDtempNodeExt;
int B3SOIFDpNodeExt;
int B3SOIFDbNode;
int B3SOIFDtempNode;
int B3SOIFDpNode;

View File

@ -1001,6 +1001,11 @@ IFuid tmpName;
model->B3SOIFDadice = model->B3SOIFDadice0 / ( 1 + Cboxt / model->B3SOIFDcox);
here->B3SOIFDfloat = 0;
here->B3SOIFDpNode = here->B3SOIFDpNodeExt;
here->B3SOIFDbNode = here->B3SOIFDbNodeExt;
here->B3SOIFDtempNode = here->B3SOIFDtempNodeExt;
if (here->B3SOIFDbNode == -1)
/* no internal body node is needed for SPICE iteration */
{ here->B3SOIFDbNode = here->B3SOIFDpNode = 0;
@ -1563,6 +1568,23 @@ B3SOIFDunsetup(GENmodel *inModel, CKTcircuit *ckt)
here->B3SOIFDvbsNode = 0;
}
if (here->B3SOIFDtempNode &&
here->B3SOIFDtempNode != here->B3SOIFDtempNodeExt &&
here->B3SOIFDtempNode != here->B3SOIFDbNodeExt &&
here->B3SOIFDtempNode != here->B3SOIFDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIFDtempNode);
here->B3SOIFDtempNode = 0;
}
if (here->B3SOIFDbNode &&
here->B3SOIFDbNode != here->B3SOIFDbNodeExt &&
here->B3SOIFDbNode != here->B3SOIFDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIFDbNode);
here->B3SOIFDbNode = 0;
}
here->B3SOIFDpNode = 0;
if (here->B3SOIFDsNodePrime
&& here->B3SOIFDsNodePrime != here->B3SOIFDsNode)
{

View File

@ -34,6 +34,9 @@ typedef struct sB3SOIPDinstance
int B3SOIPDgNode;
int B3SOIPDsNode;
int B3SOIPDeNode;
int B3SOIPDbNodeExt;
int B3SOIPDtempNodeExt;
int B3SOIPDpNodeExt;
int B3SOIPDpNode;
int B3SOIPDbNode;
int B3SOIPDtempNode;

View File

@ -1168,6 +1168,11 @@ IFuid tmpName;
here->B3SOIPDfloat = 0;
here->B3SOIPDpNode = here->B3SOIPDpNodeExt;
here->B3SOIPDbNode = here->B3SOIPDbNodeExt;
here->B3SOIPDtempNode = here->B3SOIPDtempNodeExt;
if (here->B3SOIPDpNode == -1) { /* floating body case -- 4-node */
error = CKTmkVolt(ckt,&tmp,here->B3SOIPDname,"Body");
if (error) return(error);
@ -1558,6 +1563,23 @@ B3SOIPDunsetup(
here->B3SOIPDvbsNode = 0;
}
if (here->B3SOIPDtempNode &&
here->B3SOIPDtempNode != here->B3SOIPDtempNodeExt &&
here->B3SOIPDtempNode != here->B3SOIPDbNodeExt &&
here->B3SOIPDtempNode != here->B3SOIPDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIPDtempNode);
here->B3SOIPDtempNode = 0;
}
if (here->B3SOIPDbNode &&
here->B3SOIPDbNode != here->B3SOIPDbNodeExt &&
here->B3SOIPDbNode != here->B3SOIPDpNodeExt)
{
CKTdltNNum(ckt, here->B3SOIPDbNode);
here->B3SOIPDbNode = 0;
}
here->B3SOIPDpNode = 0;
if (here->B3SOIPDsNodePrime
&& here->B3SOIPDsNodePrime != here->B3SOIPDsNode)
{

View File

@ -35,6 +35,9 @@ typedef struct sB4SOIinstance
int B4SOIgNodeExt; /* v3.1 changed gNode to gNodeExt */
int B4SOIsNode;
int B4SOIeNode;
int B4SOIpNodeExt;
int B4SOIbNodeExt;
int B4SOItempNodeExt;
int B4SOIpNode;
int B4SOIbNode;
int B4SOItempNode;

View File

@ -2259,6 +2259,10 @@ B4SOIinstance **InstArray;
}
}
here->B4SOIpNode = here->B4SOIpNodeExt;
here->B4SOIbNode = here->B4SOIbNodeExt;
here->B4SOItempNode = here->B4SOItempNodeExt;
here->B4SOIfloat = 0;
if (here->B4SOIsoiMod == 2) /* v3.2 */
{
@ -2888,6 +2892,23 @@ B4SOIunsetup(
here->B4SOIgNode = 0;
}
if (here->B4SOItempNode &&
here->B4SOItempNode != here->B4SOItempNodeExt &&
here->B4SOItempNode != here->B4SOIbNodeExt &&
here->B4SOItempNode != here->B4SOIpNodeExt)
{
CKTdltNNum(ckt, here->B4SOItempNode);
here->B4SOItempNode = 0;
}
if (here->B4SOIbNode &&
here->B4SOIbNode != here->B4SOIbNodeExt &&
here->B4SOIbNode != here->B4SOIpNodeExt)
{
CKTdltNNum(ckt, here->B4SOIbNode);
here->B4SOIbNode = 0;
}
here->B4SOIpNode = 0;
if (here->B4SOIsNodePrime
&& here->B4SOIsNodePrime != here->B4SOIsNode)
{

View File

@ -223,8 +223,10 @@ typedef struct sHSMHVinstance {
int HSMHVgNode; /* number of the gate node of the mosfet */
int HSMHVsNode; /* number of the source node of the mosfet */
int HSMHVbNode; /* number of the bulk node of the mosfet */
int HSMHVsubNodeExt; /* number of the substrate node */
int HSMHVtempNodeExt;/* number of the temp node----------SHE--------*/
int HSMHVsubNode; /* number of the substrate node */
int HSMHVtempNode; /* number of the temp node----------SHE--------*/
int HSMHVtempNode; /* number of the temp node */
int HSMHVdNodePrime; /* number od the inner drain node */
int HSMHVgNodePrime; /* number of the inner gate node */
int HSMHVsNodePrime; /* number od the inner source node */

View File

@ -921,6 +921,9 @@ int HSMHVsetup(
here->HSMHVdbNode = here->HSMHVbNodePrime = here->HSMHVsbNode = here->HSMHVbNode;
}
here->HSMHVtempNode = here->HSMHVtempNodeExt;
here->HSMHVsubNode = here->HSMHVsubNodeExt;
if ( here->HSMHV_cosubnode == 0 && here->HSMHVsubNode >= 0 ) {
if ( here->HSMHVtempNode >= 0 ) {
/* FATAL Error when 6th node is defined and COSUBNODE=0 */
@ -1483,6 +1486,16 @@ HSMHVunsetup(
CKTdltNNum(ckt, here->HSMHVqiNode);
here->HSMHVqiNode = 0;
}
if (here->HSMHVtempNode > 0 &&
here->HSMHVtempNode != here->HSMHVtempNodeExt &&
here->HSMHVtempNode != here->HSMHVsubNodeExt)
{
CKTdltNNum(ckt, here->HSMHVtempNode);
here->HSMHVtempNode = 0;
}
here->HSMHVsubNode = 0;
if (here->HSMHVsbNode
&& here->HSMHVsbNode != here->HSMHVbNode)
{

View File

@ -271,8 +271,10 @@ typedef struct sHSMHV2instance {
int HSMHV2gNode; /* number of the gate node of the mosfet */
int HSMHV2sNode; /* number of the source node of the mosfet */
int HSMHV2bNode; /* number of the bulk node of the mosfet */
int HSMHV2subNodeExt; /* number of the substrate node */
int HSMHV2tempNodeExt;/* number of the temp node----------SHE--------*/
int HSMHV2subNode; /* number of the substrate node */
int HSMHV2tempNode; /* number of the temp node----------SHE--------*/
int HSMHV2tempNode; /* number of the temp node */
int HSMHV2dNodePrime; /* number od the inner drain node */
int HSMHV2gNodePrime; /* number of the inner gate node */
int HSMHV2sNodePrime; /* number od the inner source node */

View File

@ -1144,6 +1144,9 @@ int HSMHV2setup(
here->HSMHV2dbNode = here->HSMHV2bNodePrime = here->HSMHV2sbNode = here->HSMHV2bNode;
}
here->HSMHV2tempNode = here->HSMHV2tempNodeExt;
here->HSMHV2subNode = here->HSMHV2subNodeExt;
if ( here->HSMHV2_cosubnode == 0 && here->HSMHV2subNode >= 0 ) {
if ( here->HSMHV2tempNode >= 0 ) {
/* FATAL Error when 6th node is defined and COSUBNODE=0 */
@ -1741,6 +1744,15 @@ HSMHV2unsetup(
for (here = model->HSMHV2instances; here != NULL;
here=here->HSMHV2nextInstance)
{
if (here->HSMHV2tempNode > 0 &&
here->HSMHV2tempNode != here->HSMHV2tempNodeExt &&
here->HSMHV2tempNode != here->HSMHV2subNodeExt)
{
CKTdltNNum(ckt, here->HSMHV2tempNode);
here->HSMHV2tempNode = 0;
}
here->HSMHV2subNode = 0;
if (here->HSMHV2qbNode)
{
CKTdltNNum(ckt, here->HSMHV2qbNode);