diff --git a/src/spicelib/devices/bsim3/Makefile.am b/src/spicelib/devices/bsim3/Makefile.am
index 2871b0f2e..2489d1e5a 100644
--- a/src/spicelib/devices/bsim3/Makefile.am
+++ b/src/spicelib/devices/bsim3/Makefile.am
@@ -19,6 +19,7 @@ libbsim3_la_SOURCES = \
b3par.c \
b3pzld.c \
b3set.c \
+ b3soachk.c \
b3temp.c \
b3trunc.c \
bsim3def.h \
diff --git a/src/spicelib/devices/bsim3/b3.c b/src/spicelib/devices/bsim3/b3.c
index 6dc6cc27c..1f696d632 100644
--- a/src/spicelib/devices/bsim3/b3.c
+++ b/src/spicelib/devices/bsim3/b3.c
@@ -500,6 +500,13 @@ IOP( "ef", BSIM3_MOD_EF, IF_REAL, "Flicker noise frequency exponent"),
IOP( "af", BSIM3_MOD_AF, IF_REAL, "Flicker noise exponent"),
IOP( "kf", BSIM3_MOD_KF, IF_REAL, "Flicker noise coefficient"),
+IOP("vgs_max", BSIM3_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
+IOP("vgd_max", BSIM3_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
+IOP("vgb_max", BSIM3_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"),
+IOP("vds_max", BSIM3_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
+IOP("vbs_max", BSIM3_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"),
+IOP("vbd_max", BSIM3_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"),
+
IP( "nmos", BSIM3_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"),
IP( "pmos", BSIM3_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"),
};
diff --git a/src/spicelib/devices/bsim3/b3mask.c b/src/spicelib/devices/bsim3/b3mask.c
index 48fc54192..e78e42271 100644
--- a/src/spicelib/devices/bsim3/b3mask.c
+++ b/src/spicelib/devices/bsim3/b3mask.c
@@ -1283,6 +1283,26 @@ IFvalue *value)
case BSIM3_MOD_KF:
value->rValue = model->BSIM3kf;
return(OK);
+
+ case BSIM3_MOD_VGS_MAX:
+ value->rValue = model->BSIM3vgsMax;
+ return(OK);
+ case BSIM3_MOD_VGD_MAX:
+ value->rValue = model->BSIM3vgdMax;
+ return(OK);
+ case BSIM3_MOD_VGB_MAX:
+ value->rValue = model->BSIM3vgbMax;
+ return(OK);
+ case BSIM3_MOD_VDS_MAX:
+ value->rValue = model->BSIM3vdsMax;
+ return(OK);
+ case BSIM3_MOD_VBS_MAX:
+ value->rValue = model->BSIM3vbsMax;
+ return(OK);
+ case BSIM3_MOD_VBD_MAX:
+ value->rValue = model->BSIM3vbdMax;
+ return(OK);
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/bsim3/b3mpar.c b/src/spicelib/devices/bsim3/b3mpar.c
index 3cd3dc4a9..0cd9d6eec 100644
--- a/src/spicelib/devices/bsim3/b3mpar.c
+++ b/src/spicelib/devices/bsim3/b3mpar.c
@@ -1719,6 +1719,32 @@ GENmodel *inMod)
mod->BSIM3kf = value->rValue;
mod->BSIM3kfGiven = TRUE;
break;
+
+ case BSIM3_MOD_VGS_MAX:
+ mod->BSIM3vgsMax = value->rValue;
+ mod->BSIM3vgsMaxGiven = TRUE;
+ break;
+ case BSIM3_MOD_VGD_MAX:
+ mod->BSIM3vgdMax = value->rValue;
+ mod->BSIM3vgdMaxGiven = TRUE;
+ break;
+ case BSIM3_MOD_VGB_MAX:
+ mod->BSIM3vgbMax = value->rValue;
+ mod->BSIM3vgbMaxGiven = TRUE;
+ break;
+ case BSIM3_MOD_VDS_MAX:
+ mod->BSIM3vdsMax = value->rValue;
+ mod->BSIM3vdsMaxGiven = TRUE;
+ break;
+ case BSIM3_MOD_VBS_MAX:
+ mod->BSIM3vbsMax = value->rValue;
+ mod->BSIM3vbsMaxGiven = TRUE;
+ break;
+ case BSIM3_MOD_VBD_MAX:
+ mod->BSIM3vbdMax = value->rValue;
+ mod->BSIM3vbdMaxGiven = TRUE;
+ break;
+
case BSIM3_MOD_NMOS :
if(value->iValue) {
mod->BSIM3type = 1;
diff --git a/src/spicelib/devices/bsim3/b3set.c b/src/spicelib/devices/bsim3/b3set.c
index 4d2d753be..0e6a73885 100644
--- a/src/spicelib/devices/bsim3/b3set.c
+++ b/src/spicelib/devices/bsim3/b3set.c
@@ -894,6 +894,20 @@ BSIM3instance **InstArray;
model->BSIM3af = 1.0;
if (!model->BSIM3kfGiven)
model->BSIM3kf = 0.0;
+
+ if (!model->BSIM3vgsMaxGiven)
+ model->BSIM3vgsMax = 1e99;
+ if (!model->BSIM3vgdMaxGiven)
+ model->BSIM3vgdMax = 1e99;
+ if (!model->BSIM3vgbMaxGiven)
+ model->BSIM3vgbMax = 1e99;
+ if (!model->BSIM3vdsMaxGiven)
+ model->BSIM3vdsMax = 1e99;
+ if (!model->BSIM3vbsMaxGiven)
+ model->BSIM3vbsMax = 1e99;
+ if (!model->BSIM3vbdMaxGiven)
+ model->BSIM3vbdMax = 1e99;
+
/* loop through all the instances of the model */
for (here = model->BSIM3instances; here != NULL ;
here=here->BSIM3nextInstance)
diff --git a/src/spicelib/devices/bsim3/b3soachk.c b/src/spicelib/devices/bsim3/b3soachk.c
new file mode 100644
index 000000000..f002aca88
--- /dev/null
+++ b/src/spicelib/devices/bsim3/b3soachk.c
@@ -0,0 +1,110 @@
+/**********
+Copyright 2013 Dietmar Warning. All rights reserved.
+Author: 2013 Dietmar Warning
+**********/
+
+#include "ngspice/ngspice.h"
+#include "ngspice/cktdefs.h"
+#include "bsim3def.h"
+#include "ngspice/trandefs.h"
+#include "ngspice/sperror.h"
+#include "ngspice/suffix.h"
+#include "ngspice/cpdefs.h"
+
+
+int
+BSIM3soaCheck(CKTcircuit *ckt, GENmodel *inModel)
+{
+ BSIM3model *model = (BSIM3model *) inModel;
+ BSIM3instance *here;
+ double vgs, vgd, vgb, vds, vbs, vbd; /* actual mos voltages */
+ int maxwarns;
+ static int warns_vgs = 0, warns_vgd = 0, warns_vgb = 0, warns_vds = 0, warns_vbs = 0, warns_vbd = 0;
+
+ if (!ckt) {
+ warns_vgs = 0;
+ warns_vgd = 0;
+ warns_vgb = 0;
+ warns_vds = 0;
+ warns_vbs = 0;
+ warns_vbd = 0;
+ return OK;
+ }
+
+ maxwarns = ckt->CKTsoaMaxWarns;
+
+ for (; model; model = model->BSIM3nextModel) {
+
+ for (here = model->BSIM3instances; here; here = here->BSIM3nextInstance) {
+
+ vgs = fabs(ckt->CKTrhsOld [here->BSIM3gNode] -
+ ckt->CKTrhsOld [here->BSIM3sNodePrime]);
+
+ vgd = fabs(ckt->CKTrhsOld [here->BSIM3gNode] -
+ ckt->CKTrhsOld [here->BSIM3dNodePrime]);
+
+ vgb = fabs(ckt->CKTrhsOld [here->BSIM3gNode] -
+ ckt->CKTrhsOld [here->BSIM3bNode]);
+
+ vds = fabs(ckt->CKTrhsOld [here->BSIM3dNodePrime] -
+ ckt->CKTrhsOld [here->BSIM3sNodePrime]);
+
+ vbs = fabs(ckt->CKTrhsOld [here->BSIM3bNode] -
+ ckt->CKTrhsOld [here->BSIM3sNodePrime]);
+
+ vbd = fabs(ckt->CKTrhsOld [here->BSIM3bNode] -
+ ckt->CKTrhsOld [here->BSIM3dNodePrime]);
+
+ if (vgs > model->BSIM3vgsMax)
+ if (warns_vgs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgs|=%g has exceeded Vgs_max=%g\n",
+ vgs, model->BSIM3vgsMax);
+ warns_vgs++;
+ }
+
+ if (vgd > model->BSIM3vgdMax)
+ if (warns_vgd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgd|=%g has exceeded Vgd_max=%g\n",
+ vgd, model->BSIM3vgdMax);
+ warns_vgd++;
+ }
+
+ if (vgb > model->BSIM3vgbMax)
+ if (warns_vgb < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgb|=%g has exceeded Vgb_max=%g\n",
+ vgb, model->BSIM3vgbMax);
+ warns_vgb++;
+ }
+
+ if (vds > model->BSIM3vdsMax)
+ if (warns_vds < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vds|=%g has exceeded Vds_max=%g\n",
+ vds, model->BSIM3vdsMax);
+ warns_vds++;
+ }
+
+ if (vbs > model->BSIM3vbsMax)
+ if (warns_vbs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbs|=%g has exceeded Vbs_max=%g\n",
+ vbs, model->BSIM3vbsMax);
+ warns_vbs++;
+ }
+
+ if (vbd > model->BSIM3vbdMax)
+ if (warns_vbd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbd|=%g has exceeded Vbd_max=%g\n",
+ vbd, model->BSIM3vbdMax);
+ warns_vbd++;
+ }
+
+ }
+ }
+
+ return OK;
+}
diff --git a/src/spicelib/devices/bsim3/bsim3def.h b/src/spicelib/devices/bsim3/bsim3def.h
index 0a944d553..ac9609e42 100644
--- a/src/spicelib/devices/bsim3/bsim3def.h
+++ b/src/spicelib/devices/bsim3/bsim3def.h
@@ -861,6 +861,13 @@ typedef struct sBSIM3model
double BSIM3kf;
double BSIM3lintnoi; /* lint offset for noise calculation */
+ double BSIM3vgsMax;
+ double BSIM3vgdMax;
+ double BSIM3vgbMax;
+ double BSIM3vdsMax;
+ double BSIM3vbsMax;
+ double BSIM3vbdMax;
+
struct bsim3SizeDependParam *pSizeDependParamKnot;
@@ -1282,6 +1289,13 @@ typedef struct sBSIM3model
unsigned BSIM3kfGiven :1;
unsigned BSIM3lintnoiGiven :1;
+ unsigned BSIM3vgsMaxGiven :1;
+ unsigned BSIM3vgdMaxGiven :1;
+ unsigned BSIM3vgbMaxGiven :1;
+ unsigned BSIM3vdsMaxGiven :1;
+ unsigned BSIM3vbsMaxGiven :1;
+ unsigned BSIM3vbdMaxGiven :1;
+
unsigned BSIM3LintGiven :1;
unsigned BSIM3LlGiven :1;
unsigned BSIM3LlcGiven :1;
@@ -1864,6 +1878,12 @@ typedef struct sBSIM3model
#define BSIM3_CBDB 792
#define BSIM3_CBSB 793
+#define BSIM3_MOD_VGS_MAX 801
+#define BSIM3_MOD_VGD_MAX 802
+#define BSIM3_MOD_VGB_MAX 803
+#define BSIM3_MOD_VDS_MAX 804
+#define BSIM3_MOD_VBS_MAX 805
+#define BSIM3_MOD_VBD_MAX 806
#include "bsim3ext.h"
diff --git a/src/spicelib/devices/bsim3/bsim3ext.h b/src/spicelib/devices/bsim3/bsim3ext.h
index 71662ea8b..2282a6d37 100644
--- a/src/spicelib/devices/bsim3/bsim3ext.h
+++ b/src/spicelib/devices/bsim3/bsim3ext.h
@@ -28,3 +28,4 @@ extern int BSIM3temp(GENmodel*,CKTcircuit*);
extern int BSIM3trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM3noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM3unsetup(GENmodel*,CKTcircuit*);
+extern int BSIM3soaCheck(CKTcircuit *, GENmodel *);
diff --git a/src/spicelib/devices/bsim3/bsim3init.c b/src/spicelib/devices/bsim3/bsim3init.c
index cea6cd270..e27f3925b 100644
--- a/src/spicelib/devices/bsim3/bsim3init.c
+++ b/src/spicelib/devices/bsim3/bsim3init.c
@@ -66,7 +66,7 @@ SPICEdev BSIM3info = {
/* DEVsenTrunc */ NULL,
/* DEVdisto */ NULL,
/* DEVnoise */ BSIM3noise,
- /* DEVsoaCheck */ NULL,
+ /* DEVsoaCheck */ BSIM3soaCheck,
#ifdef CIDER
/* DEVdump */ NULL,
/* DEVacct */ NULL,
diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj
index 7cf5d461c..d7677e2c8 100644
--- a/visualc/vngspice.vcproj
+++ b/visualc/vngspice.vcproj
@@ -3460,6 +3460,10 @@
RelativePath="..\src\spicelib\devices\bsim3\b3set.c"
>
+
+