diff --git a/src/spicelib/devices/hisim2/Makefile.am b/src/spicelib/devices/hisim2/Makefile.am
index 33fff2074..9446b93c3 100644
--- a/src/spicelib/devices/hisim2/Makefile.am
+++ b/src/spicelib/devices/hisim2/Makefile.am
@@ -27,6 +27,7 @@ libhisim2_la_SOURCES = hisim2.h \
hsm2par.c \
hsm2pzld.c \
hsm2set.c \
+ hsm2soachk.c \
hsm2temp.c \
hsm2trunc.c
diff --git a/src/spicelib/devices/hisim2/hsm2.c b/src/spicelib/devices/hisim2/hsm2.c
index c972d9e4d..13a3ff08e 100644
--- a/src/spicelib/devices/hisim2/hsm2.c
+++ b/src/spicelib/devices/hisim2/hsm2.c
@@ -619,7 +619,14 @@ IFparm HSM2mPTable[] = { /* model parameters */
IOP("pnfalp", HSM2_MOD_PNFALP, IF_REAL, "Cross-term dependence of nfalp"),
IOP("pvdiffj", HSM2_MOD_PVDIFFJ, IF_REAL, "Cross-term dependence of vdiffj"),
IOP("pibpc1", HSM2_MOD_PIBPC1, IF_REAL, "Cross-term dependence of ibpc1"),
- IOP("pibpc2", HSM2_MOD_PIBPC2, IF_REAL, "Cross-term dependence of ibpc2")
+ IOP("pibpc2", HSM2_MOD_PIBPC2, IF_REAL, "Cross-term dependence of ibpc2"),
+
+ IOP("vgs_max", HSM2_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
+ IOP("vgd_max", HSM2_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
+ IOP("vgb_max", HSM2_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"),
+ IOP("vds_max", HSM2_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
+ IOP("vbs_max", HSM2_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"),
+ IOP("vbd_max", HSM2_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch")
};
diff --git a/src/spicelib/devices/hisim2/hsm2def.h b/src/spicelib/devices/hisim2/hsm2def.h
index d24ae6faf..7848e80ad 100644
--- a/src/spicelib/devices/hisim2/hsm2def.h
+++ b/src/spicelib/devices/hisim2/hsm2def.h
@@ -1126,6 +1126,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
double HSM2_ktnom ;
int HSM2_bypass_enable ;
+ double HSM2vgsMax;
+ double HSM2vgdMax;
+ double HSM2vgbMax;
+ double HSM2vdsMax;
+ double HSM2vbsMax;
+ double HSM2vbdMax;
+
HSM2modelMKSParam modelMKS ; /* unit-converted parameters */
/* flag for model */
unsigned HSM2_type_Given :1;
@@ -1647,6 +1654,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
unsigned HSM2_pibpc1_Given :1;
unsigned HSM2_pibpc2_Given :1;
+ unsigned HSM2vgsMaxGiven :1;
+ unsigned HSM2vgdMaxGiven :1;
+ unsigned HSM2vgbMaxGiven :1;
+ unsigned HSM2vdsMaxGiven :1;
+ unsigned HSM2vbsMaxGiven :1;
+ unsigned HSM2vbdMaxGiven :1;
+
} HSM2model;
#ifndef NMOS
@@ -2282,6 +2296,13 @@ typedef struct sHSM2model { /* model structure for a resistor */
#define HSM2_MOD_TCJBDSWG 96
#define HSM2_MOD_TCJBSSWG 97
+#define HSM2_MOD_VGS_MAX 4001
+#define HSM2_MOD_VGD_MAX 4002
+#define HSM2_MOD_VGB_MAX 4003
+#define HSM2_MOD_VDS_MAX 4004
+#define HSM2_MOD_VBS_MAX 4005
+#define HSM2_MOD_VBD_MAX 4006
+
#include "hsm2ext.h"
/*
diff --git a/src/spicelib/devices/hisim2/hsm2ext.h b/src/spicelib/devices/hisim2/hsm2ext.h
index 0d7225cd2..b5670af84 100644
--- a/src/spicelib/devices/hisim2/hsm2ext.h
+++ b/src/spicelib/devices/hisim2/hsm2ext.h
@@ -37,3 +37,4 @@ extern int HSM2unsetup(GENmodel*,CKTcircuit*);
extern int HSM2temp(GENmodel*,CKTcircuit*);
extern int HSM2trunc(GENmodel*,CKTcircuit*,double*);
extern int HSM2noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
+extern int HSM2soaCheck(CKTcircuit *, GENmodel *);
diff --git a/src/spicelib/devices/hisim2/hsm2init.c b/src/spicelib/devices/hisim2/hsm2init.c
index 5651efa34..f07f6190f 100644
--- a/src/spicelib/devices/hisim2/hsm2init.c
+++ b/src/spicelib/devices/hisim2/hsm2init.c
@@ -65,7 +65,7 @@ SPICEdev HSM2info = {
/* DEVsenTrunc */ NULL,
/* DEVdisto */ NULL,
/* DEVnoise */ HSM2noise,
- /* DEVsoaCheck */ NULL,
+ /* DEVsoaCheck */ HSM2soaCheck,
#ifdef CIDER
/* DEVdump */ NULL,
/* DEVacct */ NULL,
diff --git a/src/spicelib/devices/hisim2/hsm2mask.c b/src/spicelib/devices/hisim2/hsm2mask.c
index afc7349a7..5c6ce69df 100644
--- a/src/spicelib/devices/hisim2/hsm2mask.c
+++ b/src/spicelib/devices/hisim2/hsm2mask.c
@@ -1567,6 +1567,25 @@ int HSM2mAsk(
value->rValue = model->HSM2_pibpc2;
return(OK);
+ case HSM2_MOD_VGS_MAX:
+ value->rValue = model->HSM2vgsMax;
+ return(OK);
+ case HSM2_MOD_VGD_MAX:
+ value->rValue = model->HSM2vgdMax;
+ return(OK);
+ case HSM2_MOD_VGB_MAX:
+ value->rValue = model->HSM2vgbMax;
+ return(OK);
+ case HSM2_MOD_VDS_MAX:
+ value->rValue = model->HSM2vdsMax;
+ return(OK);
+ case HSM2_MOD_VBS_MAX:
+ value->rValue = model->HSM2vbsMax;
+ return(OK);
+ case HSM2_MOD_VBD_MAX:
+ value->rValue = model->HSM2vbdMax;
+ return(OK);
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/hisim2/hsm2mpar.c b/src/spicelib/devices/hisim2/hsm2mpar.c
index d0c5e1793..ec864768b 100644
--- a/src/spicelib/devices/hisim2/hsm2mpar.c
+++ b/src/spicelib/devices/hisim2/hsm2mpar.c
@@ -2071,6 +2071,31 @@ int HSM2mParam(
mod->HSM2_pibpc2_Given = TRUE;
break;
+ case HSM2_MOD_VGS_MAX:
+ mod->HSM2vgsMax = value->rValue;
+ mod->HSM2vgsMaxGiven = TRUE;
+ break;
+ case HSM2_MOD_VGD_MAX:
+ mod->HSM2vgdMax = value->rValue;
+ mod->HSM2vgdMaxGiven = TRUE;
+ break;
+ case HSM2_MOD_VGB_MAX:
+ mod->HSM2vgbMax = value->rValue;
+ mod->HSM2vgbMaxGiven = TRUE;
+ break;
+ case HSM2_MOD_VDS_MAX:
+ mod->HSM2vdsMax = value->rValue;
+ mod->HSM2vdsMaxGiven = TRUE;
+ break;
+ case HSM2_MOD_VBS_MAX:
+ mod->HSM2vbsMax = value->rValue;
+ mod->HSM2vbsMaxGiven = TRUE;
+ break;
+ case HSM2_MOD_VBD_MAX:
+ mod->HSM2vbdMax = value->rValue;
+ mod->HSM2vbdMaxGiven = TRUE;
+ break;
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/hisim2/hsm2set.c b/src/spicelib/devices/hisim2/hsm2set.c
index 7b7412a5c..7c460ab49 100644
--- a/src/spicelib/devices/hisim2/hsm2set.c
+++ b/src/spicelib/devices/hisim2/hsm2set.c
@@ -641,6 +641,12 @@ int HSM2setup(
if ( !model->HSM2_pibpc1_Given ) model->HSM2_pibpc1 = 0.0 ;
if ( !model->HSM2_pibpc2_Given ) model->HSM2_pibpc2 = 0.0 ;
+ if (!model->HSM2vgsMaxGiven) model->HSM2vgsMax = 1e99;
+ if (!model->HSM2vgdMaxGiven) model->HSM2vgdMax = 1e99;
+ if (!model->HSM2vgbMaxGiven) model->HSM2vgbMax = 1e99;
+ if (!model->HSM2vdsMaxGiven) model->HSM2vdsMax = 1e99;
+ if (!model->HSM2vbsMaxGiven) model->HSM2vbsMax = 1e99;
+ if (!model->HSM2vbdMaxGiven) model->HSM2vbdMax = 1e99;
if ( model->HSM2_corecip == 1 ){
model->HSM2_sc2 = 0.0 ; model->HSM2_lsc2 = 0.0 ; model->HSM2_wsc2 = 0.0 ; model->HSM2_psc2 = 0.0 ;
diff --git a/src/spicelib/devices/hisim2/hsm2soachk.c b/src/spicelib/devices/hisim2/hsm2soachk.c
new file mode 100644
index 000000000..9a0d33d38
--- /dev/null
+++ b/src/spicelib/devices/hisim2/hsm2soachk.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 "hsm2def.h"
+#include "ngspice/trandefs.h"
+#include "ngspice/sperror.h"
+#include "ngspice/suffix.h"
+#include "ngspice/cpdefs.h"
+
+
+int
+HSM2soaCheck(CKTcircuit *ckt, GENmodel *inModel)
+{
+ HSM2model *model = (HSM2model *) inModel;
+ HSM2instance *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->HSM2nextModel) {
+
+ for (here = model->HSM2instances; here; here = here->HSM2nextInstance) {
+
+ vgs = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
+ ckt->CKTrhsOld [here->HSM2sNodePrime]);
+
+ vgd = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
+ ckt->CKTrhsOld [here->HSM2dNodePrime]);
+
+ vgb = fabs(ckt->CKTrhsOld [here->HSM2gNode] -
+ ckt->CKTrhsOld [here->HSM2bNode]);
+
+ vds = fabs(ckt->CKTrhsOld [here->HSM2dNodePrime] -
+ ckt->CKTrhsOld [here->HSM2sNodePrime]);
+
+ vbs = fabs(ckt->CKTrhsOld [here->HSM2bNode] -
+ ckt->CKTrhsOld [here->HSM2sNodePrime]);
+
+ vbd = fabs(ckt->CKTrhsOld [here->HSM2bNode] -
+ ckt->CKTrhsOld [here->HSM2dNodePrime]);
+
+ if (vgs > model->HSM2vgsMax)
+ if (warns_vgs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgs|=%g has exceeded Vgs_max=%g\n",
+ vgs, model->HSM2vgsMax);
+ warns_vgs++;
+ }
+
+ if (vgd > model->HSM2vgdMax)
+ if (warns_vgd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgd|=%g has exceeded Vgd_max=%g\n",
+ vgd, model->HSM2vgdMax);
+ warns_vgd++;
+ }
+
+ if (vgb > model->HSM2vgbMax)
+ if (warns_vgb < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgb|=%g has exceeded Vgb_max=%g\n",
+ vgb, model->HSM2vgbMax);
+ warns_vgb++;
+ }
+
+ if (vds > model->HSM2vdsMax)
+ if (warns_vds < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vds|=%g has exceeded Vds_max=%g\n",
+ vds, model->HSM2vdsMax);
+ warns_vds++;
+ }
+
+ if (vbs > model->HSM2vbsMax)
+ if (warns_vbs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbs|=%g has exceeded Vbs_max=%g\n",
+ vbs, model->HSM2vbsMax);
+ warns_vbs++;
+ }
+
+ if (vbd > model->HSM2vbdMax)
+ if (warns_vbd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbd|=%g has exceeded Vbd_max=%g\n",
+ vbd, model->HSM2vbdMax);
+ warns_vbd++;
+ }
+
+ }
+ }
+
+ return OK;
+}
diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj
index debaaa32c..a2d0dbfdd 100644
--- a/visualc/vngspice.vcproj
+++ b/visualc/vngspice.vcproj
@@ -5860,6 +5860,10 @@
RelativePath="..\src\spicelib\devices\hisim2\hsm2set.c"
>
+
+