From 0e9576cb3460ff32f7176e8622fc6f832030f089 Mon Sep 17 00:00:00 2001 From: rlar Date: Sun, 22 Jan 2017 19:25:14 +0100 Subject: [PATCH] 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. --- src/spicelib/devices/bsim3soi_dd/b3soidddef.h | 3 +++ src/spicelib/devices/bsim3soi_dd/b3soiddset.c | 22 +++++++++++++++++++ src/spicelib/devices/bsim3soi_fd/b3soifddef.h | 3 +++ src/spicelib/devices/bsim3soi_fd/b3soifdset.c | 22 +++++++++++++++++++ src/spicelib/devices/bsim3soi_pd/b3soipddef.h | 3 +++ src/spicelib/devices/bsim3soi_pd/b3soipdset.c | 22 +++++++++++++++++++ src/spicelib/devices/bsimsoi/b4soidef.h | 3 +++ src/spicelib/devices/bsimsoi/b4soiset.c | 21 ++++++++++++++++++ src/spicelib/devices/hisimhv1/hsmhvdef.h | 4 +++- src/spicelib/devices/hisimhv1/hsmhvset.c | 13 +++++++++++ src/spicelib/devices/hisimhv2/hsmhv2def.h | 4 +++- src/spicelib/devices/hisimhv2/hsmhv2set.c | 12 ++++++++++ 12 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/spicelib/devices/bsim3soi_dd/b3soidddef.h b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h index 01fb81667..35a981ab4 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soidddef.h +++ b/src/spicelib/devices/bsim3soi_dd/b3soidddef.h @@ -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; diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddset.c b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c index e5fff2bc4..c20c0ada8 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soiddset.c +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddset.c @@ -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) { diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifddef.h b/src/spicelib/devices/bsim3soi_fd/b3soifddef.h index f3c0a1007..4816ed689 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifddef.h +++ b/src/spicelib/devices/bsim3soi_fd/b3soifddef.h @@ -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; diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdset.c b/src/spicelib/devices/bsim3soi_fd/b3soifdset.c index 3072fade9..12980107f 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifdset.c +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdset.c @@ -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) { diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipddef.h b/src/spicelib/devices/bsim3soi_pd/b3soipddef.h index ceddbe2f8..c742f9ee8 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipddef.h +++ b/src/spicelib/devices/bsim3soi_pd/b3soipddef.h @@ -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; diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdset.c b/src/spicelib/devices/bsim3soi_pd/b3soipdset.c index 50de3f358..681102226 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipdset.c +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdset.c @@ -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) { diff --git a/src/spicelib/devices/bsimsoi/b4soidef.h b/src/spicelib/devices/bsimsoi/b4soidef.h index 2c0be8af5..726390bb0 100644 --- a/src/spicelib/devices/bsimsoi/b4soidef.h +++ b/src/spicelib/devices/bsimsoi/b4soidef.h @@ -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; diff --git a/src/spicelib/devices/bsimsoi/b4soiset.c b/src/spicelib/devices/bsimsoi/b4soiset.c index 3943dbf32..792a1d9b0 100644 --- a/src/spicelib/devices/bsimsoi/b4soiset.c +++ b/src/spicelib/devices/bsimsoi/b4soiset.c @@ -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) { diff --git a/src/spicelib/devices/hisimhv1/hsmhvdef.h b/src/spicelib/devices/hisimhv1/hsmhvdef.h index 7651f7537..a60dcfb1b 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvdef.h +++ b/src/spicelib/devices/hisimhv1/hsmhvdef.h @@ -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 */ diff --git a/src/spicelib/devices/hisimhv1/hsmhvset.c b/src/spicelib/devices/hisimhv1/hsmhvset.c index 1533415f0..fef19d8cf 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvset.c +++ b/src/spicelib/devices/hisimhv1/hsmhvset.c @@ -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) { diff --git a/src/spicelib/devices/hisimhv2/hsmhv2def.h b/src/spicelib/devices/hisimhv2/hsmhv2def.h index 32db4015e..8569a7d03 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2def.h +++ b/src/spicelib/devices/hisimhv2/hsmhv2def.h @@ -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 */ diff --git a/src/spicelib/devices/hisimhv2/hsmhv2set.c b/src/spicelib/devices/hisimhv2/hsmhv2set.c index 7e5a1e083..5ac4033e9 100644 --- a/src/spicelib/devices/hisimhv2/hsmhv2set.c +++ b/src/spicelib/devices/hisimhv2/hsmhv2set.c @@ -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);