diff --git a/src/spicelib/devices/bsim4/Makefile.am b/src/spicelib/devices/bsim4/Makefile.am
index 9403a4129..047ffdfc6 100644
--- a/src/spicelib/devices/bsim4/Makefile.am
+++ b/src/spicelib/devices/bsim4/Makefile.am
@@ -20,6 +20,7 @@ libbsim4_la_SOURCES = \
b4par.c \
b4pzld.c \
b4set.c \
+ b4soachk.c \
b4temp.c \
b4trunc.c \
bsim4def.h \
diff --git a/src/spicelib/devices/bsim4/b4.c b/src/spicelib/devices/bsim4/b4.c
index 3353b2133..ce7e479e5 100644
--- a/src/spicelib/devices/bsim4/b4.c
+++ b/src/spicelib/devices/bsim4/b4.c
@@ -1031,6 +1031,13 @@ IOP( "ef", BSIM4_MOD_EF, IF_REAL, "Flicker noise frequency exponent"),
IOP( "af", BSIM4_MOD_AF, IF_REAL, "Flicker noise exponent"),
IOP( "kf", BSIM4_MOD_KF, IF_REAL, "Flicker noise coefficient"),
+IOP("vgs_max", BSIM4_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
+IOP("vgd_max", BSIM4_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
+IOP("vgb_max", BSIM4_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"),
+IOP("vds_max", BSIM4_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
+IOP("vbs_max", BSIM4_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"),
+IOP("vbd_max", BSIM4_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"),
+
IP( "nmos", BSIM4_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"),
IP( "pmos", BSIM4_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"),
};
diff --git a/src/spicelib/devices/bsim4/b4mask.c b/src/spicelib/devices/bsim4/b4mask.c
index 4b2487834..5c5b3f7e6 100644
--- a/src/spicelib/devices/bsim4/b4mask.c
+++ b/src/spicelib/devices/bsim4/b4mask.c
@@ -2693,6 +2693,26 @@ IFvalue *value)
case BSIM4_MOD_KF:
value->rValue = model->BSIM4kf;
return(OK);
+
+ case BSIM4_MOD_VGS_MAX:
+ value->rValue = model->BSIM4vgsMax;
+ return(OK);
+ case BSIM4_MOD_VGD_MAX:
+ value->rValue = model->BSIM4vgdMax;
+ return(OK);
+ case BSIM4_MOD_VGB_MAX:
+ value->rValue = model->BSIM4vgbMax;
+ return(OK);
+ case BSIM4_MOD_VDS_MAX:
+ value->rValue = model->BSIM4vdsMax;
+ return(OK);
+ case BSIM4_MOD_VBS_MAX:
+ value->rValue = model->BSIM4vbsMax;
+ return(OK);
+ case BSIM4_MOD_VBD_MAX:
+ value->rValue = model->BSIM4vbdMax;
+ return(OK);
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/bsim4/b4mpar.c b/src/spicelib/devices/bsim4/b4mpar.c
index ca3578a3c..7fc0e25ce 100644
--- a/src/spicelib/devices/bsim4/b4mpar.c
+++ b/src/spicelib/devices/bsim4/b4mpar.c
@@ -3602,6 +3602,32 @@ GENmodel *inMod)
mod->BSIM4kf = value->rValue;
mod->BSIM4kfGiven = TRUE;
break;
+
+ case BSIM4_MOD_VGS_MAX:
+ mod->BSIM4vgsMax = value->rValue;
+ mod->BSIM4vgsMaxGiven = TRUE;
+ break;
+ case BSIM4_MOD_VGD_MAX:
+ mod->BSIM4vgdMax = value->rValue;
+ mod->BSIM4vgdMaxGiven = TRUE;
+ break;
+ case BSIM4_MOD_VGB_MAX:
+ mod->BSIM4vgbMax = value->rValue;
+ mod->BSIM4vgbMaxGiven = TRUE;
+ break;
+ case BSIM4_MOD_VDS_MAX:
+ mod->BSIM4vdsMax = value->rValue;
+ mod->BSIM4vdsMaxGiven = TRUE;
+ break;
+ case BSIM4_MOD_VBS_MAX:
+ mod->BSIM4vbsMax = value->rValue;
+ mod->BSIM4vbsMaxGiven = TRUE;
+ break;
+ case BSIM4_MOD_VBD_MAX:
+ mod->BSIM4vbdMax = value->rValue;
+ mod->BSIM4vbdMaxGiven = TRUE;
+ break;
+
case BSIM4_MOD_NMOS :
if(value->iValue) {
mod->BSIM4type = 1;
diff --git a/src/spicelib/devices/bsim4/b4set.c b/src/spicelib/devices/bsim4/b4set.c
index fd704c99c..96790106e 100644
--- a/src/spicelib/devices/bsim4/b4set.c
+++ b/src/spicelib/devices/bsim4/b4set.c
@@ -2088,6 +2088,19 @@ BSIM4instance **InstArray;
if (!model->BSIM4kfGiven)
model->BSIM4kf = 0.0;
+ if (!model->BSIM4vgsMaxGiven)
+ model->BSIM4vgsMax = 1e99;
+ if (!model->BSIM4vgdMaxGiven)
+ model->BSIM4vgdMax = 1e99;
+ if (!model->BSIM4vgbMaxGiven)
+ model->BSIM4vgbMax = 1e99;
+ if (!model->BSIM4vdsMaxGiven)
+ model->BSIM4vdsMax = 1e99;
+ if (!model->BSIM4vbsMaxGiven)
+ model->BSIM4vbsMax = 1e99;
+ if (!model->BSIM4vbdMaxGiven)
+ model->BSIM4vbdMax = 1e99;
+
/* stress effect */
if (!model->BSIM4sarefGiven)
model->BSIM4saref = 1e-6; /* m */
diff --git a/src/spicelib/devices/bsim4/b4soachk.c b/src/spicelib/devices/bsim4/b4soachk.c
new file mode 100644
index 000000000..c8b0d4b2d
--- /dev/null
+++ b/src/spicelib/devices/bsim4/b4soachk.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 "bsim4def.h"
+#include "ngspice/trandefs.h"
+#include "ngspice/sperror.h"
+#include "ngspice/suffix.h"
+#include "ngspice/cpdefs.h"
+
+
+int
+BSIM4soaCheck(CKTcircuit *ckt, GENmodel *inModel)
+{
+ BSIM4model *model = (BSIM4model *) inModel;
+ BSIM4instance *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->BSIM4nextModel) {
+
+ for (here = model->BSIM4instances; here; here = here->BSIM4nextInstance) {
+
+ vgs = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4sNodePrime]);
+
+ vgd = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4dNodePrime]);
+
+ vgb = fabs(ckt->CKTrhsOld [here->BSIM4gNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4bNodePrime]);
+
+ vds = fabs(ckt->CKTrhsOld [here->BSIM4dNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4sNodePrime]);
+
+ vbs = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4sNodePrime]);
+
+ vbd = fabs(ckt->CKTrhsOld [here->BSIM4bNodePrime] -
+ ckt->CKTrhsOld [here->BSIM4dNodePrime]);
+
+ if (vgs > model->BSIM4vgsMax)
+ if (warns_vgs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgs|=%g has exceeded Vgs_max=%g\n",
+ vgs, model->BSIM4vgsMax);
+ warns_vgs++;
+ }
+
+ if (vgd > model->BSIM4vgdMax)
+ if (warns_vgd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgd|=%g has exceeded Vgd_max=%g\n",
+ vgd, model->BSIM4vgdMax);
+ warns_vgd++;
+ }
+
+ if (vgb > model->BSIM4vgbMax)
+ if (warns_vgb < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgb|=%g has exceeded Vgb_max=%g\n",
+ vgb, model->BSIM4vgbMax);
+ warns_vgb++;
+ }
+
+ if (vds > model->BSIM4vdsMax)
+ if (warns_vds < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vds|=%g has exceeded Vds_max=%g\n",
+ vds, model->BSIM4vdsMax);
+ warns_vds++;
+ }
+
+ if (vbs > model->BSIM4vbsMax)
+ if (warns_vbs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbs|=%g has exceeded Vbs_max=%g\n",
+ vbs, model->BSIM4vbsMax);
+ warns_vbs++;
+ }
+
+ if (vbd > model->BSIM4vbdMax)
+ if (warns_vbd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbd|=%g has exceeded Vbd_max=%g\n",
+ vbd, model->BSIM4vbdMax);
+ warns_vbd++;
+ }
+
+ }
+ }
+
+ return OK;
+}
diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h
index 3505fc347..bfdd9204a 100644
--- a/src/spicelib/devices/bsim4/bsim4def.h
+++ b/src/spicelib/devices/bsim4/bsim4def.h
@@ -1764,6 +1764,13 @@ typedef struct sBSIM4model
double BSIM4af;
double BSIM4kf;
+ double BSIM4vgsMax;
+ double BSIM4vgdMax;
+ double BSIM4vgbMax;
+ double BSIM4vdsMax;
+ double BSIM4vbsMax;
+ double BSIM4vbdMax;
+
struct bsim4SizeDependParam *pSizeDependParamKnot;
#ifdef USE_OMP
@@ -2620,6 +2627,13 @@ typedef struct sBSIM4model
unsigned BSIM4afGiven :1;
unsigned BSIM4kfGiven :1;
+ unsigned BSIM4vgsMaxGiven :1;
+ unsigned BSIM4vgdMaxGiven :1;
+ unsigned BSIM4vgbMaxGiven :1;
+ unsigned BSIM4vdsMaxGiven :1;
+ unsigned BSIM4vbsMaxGiven :1;
+ unsigned BSIM4vbdMaxGiven :1;
+
unsigned BSIM4LintGiven :1;
unsigned BSIM4LlGiven :1;
unsigned BSIM4LlcGiven :1;
@@ -3735,6 +3749,13 @@ typedef struct sBSIM4model
#define BSIM4_MOD_TNOIC 1272
#define BSIM4_MOD_RNOIC 1273
+#define BSIM4_MOD_VGS_MAX 1301
+#define BSIM4_MOD_VGD_MAX 1302
+#define BSIM4_MOD_VGB_MAX 1303
+#define BSIM4_MOD_VDS_MAX 1304
+#define BSIM4_MOD_VBS_MAX 1305
+#define BSIM4_MOD_VBD_MAX 1306
+
#include "bsim4ext.h"
extern void BSIM4evaluate(double,double,double,BSIM4instance*,BSIM4model*,
diff --git a/src/spicelib/devices/bsim4/bsim4ext.h b/src/spicelib/devices/bsim4/bsim4ext.h
index 171406ae5..4d3a93f0e 100644
--- a/src/spicelib/devices/bsim4/bsim4ext.h
+++ b/src/spicelib/devices/bsim4/bsim4ext.h
@@ -28,3 +28,4 @@ extern int BSIM4temp(GENmodel*,CKTcircuit*);
extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*);
extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
extern int BSIM4unsetup(GENmodel*,CKTcircuit*);
+extern int BSIM4soaCheck(CKTcircuit *, GENmodel *);
diff --git a/src/spicelib/devices/bsim4/bsim4init.c b/src/spicelib/devices/bsim4/bsim4init.c
index 63bf6117b..e9d13577d 100644
--- a/src/spicelib/devices/bsim4/bsim4init.c
+++ b/src/spicelib/devices/bsim4/bsim4init.c
@@ -67,7 +67,7 @@ SPICEdev BSIM4info = {
NULL, /* DEVsenTrunc */
NULL, /* DEVdisto */
BSIM4noise, /* DEVnoise */
- NULL, /* DEVsoaCheck */
+ BSIM4soaCheck, /* DEVsoaCheck */
#ifdef CIDER
NULL, /* DEVdump */
NULL, /* DEVacct */
diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj
index 7b5f89e95..4fa4eb9f5 100644
--- a/visualc/vngspice.vcproj
+++ b/visualc/vngspice.vcproj
@@ -3984,6 +3984,10 @@
RelativePath="..\src\spicelib\devices\bsim4\b4set.c"
>
+
+