diff --git a/src/spicelib/devices/hisimhv1/Makefile.am b/src/spicelib/devices/hisimhv1/Makefile.am
index ea6d9e6fe..44b121f18 100644
--- a/src/spicelib/devices/hisimhv1/Makefile.am
+++ b/src/spicelib/devices/hisimhv1/Makefile.am
@@ -27,6 +27,7 @@ libhisimhv1_la_SOURCES = hisimhv.h \
hsmhvpar.c \
hsmhvpzld.c \
hsmhvset.c \
+ hsmhvsoachk.c \
hsmhvtemp.c \
hsmhvtemp_eval.h \
hsmhvtrunc.c
diff --git a/src/spicelib/devices/hisimhv1/hsmhv.c b/src/spicelib/devices/hisimhv1/hsmhv.c
index 4fd1ae862..2a4e8376f 100644
--- a/src/spicelib/devices/hisimhv1/hsmhv.c
+++ b/src/spicelib/devices/hisimhv1/hsmhv.c
@@ -718,7 +718,14 @@ IFparm HSMHVmPTable[] = { /* model parameters */
IOP("prdvg11", HSMHV_MOD_PRDVG11, IF_REAL, "Cross-term dependence of rdvg11"),
IOP("prs", HSMHV_MOD_PRS, IF_REAL, "Cross-term dependence of rs"),
IOP("prth0", HSMHV_MOD_PRTH0, IF_REAL, "Cross-term dependence of rth0"),
- IOP("pvover", HSMHV_MOD_PVOVER, IF_REAL, "Cross-term dependence of vover")
+ IOP("pvover", HSMHV_MOD_PVOVER, IF_REAL, "Cross-term dependence of vover"),
+
+ IOP("vgs_max", HSMHV_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"),
+ IOP("vgd_max", HSMHV_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"),
+ IOP("vgb_max", HSMHV_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"),
+ IOP("vds_max", HSMHV_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"),
+ IOP("vbs_max", HSMHV_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"),
+ IOP("vbd_max", HSMHV_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch")
};
diff --git a/src/spicelib/devices/hisimhv1/hsmhvdef.h b/src/spicelib/devices/hisimhv1/hsmhvdef.h
index 2ea750a05..f32b7b211 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvdef.h
+++ b/src/spicelib/devices/hisimhv1/hsmhvdef.h
@@ -1549,6 +1549,13 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */
double HSMHV_qme12 ;
double HSMHV_ktnom ;
+ double HSMHVvgsMax;
+ double HSMHVvgdMax;
+ double HSMHVvgbMax;
+ double HSMHVvdsMax;
+ double HSMHVvbsMax;
+ double HSMHVvbdMax;
+
HSMHVmodelMKSParam modelMKS ; /* unit-converted parameters */
@@ -2175,6 +2182,13 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */
unsigned HSMHV_prth0_Given :1;
unsigned HSMHV_pvover_Given :1;
+ unsigned HSMHVvgsMaxGiven :1;
+ unsigned HSMHVvgdMaxGiven :1;
+ unsigned HSMHVvgbMaxGiven :1;
+ unsigned HSMHVvdsMaxGiven :1;
+ unsigned HSMHVvbsMaxGiven :1;
+ unsigned HSMHVvbdMaxGiven :1;
+
} HSMHVmodel;
#ifndef NMOS
@@ -2926,6 +2940,12 @@ typedef struct sHSMHVmodel { /* model structure for a resistor */
#define HSMHV_MOD_TCJBDSWG 96
#define HSMHV_MOD_TCJBSSWG 97
+#define HSMHV_MOD_VGS_MAX 4001
+#define HSMHV_MOD_VGD_MAX 4002
+#define HSMHV_MOD_VGB_MAX 4003
+#define HSMHV_MOD_VDS_MAX 4004
+#define HSMHV_MOD_VBS_MAX 4005
+#define HSMHV_MOD_VBD_MAX 4006
#include "hsmhvext.h"
diff --git a/src/spicelib/devices/hisimhv1/hsmhvext.h b/src/spicelib/devices/hisimhv1/hsmhvext.h
index ec4f306bf..fc2ff1f4c 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvext.h
+++ b/src/spicelib/devices/hisimhv1/hsmhvext.h
@@ -37,3 +37,4 @@ extern int HSMHVunsetup(GENmodel*,CKTcircuit*);
extern int HSMHVtemp(GENmodel*,CKTcircuit*);
extern int HSMHVtrunc(GENmodel*,CKTcircuit*,double*);
extern int HSMHVnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*);
+extern int HSMHVsoaCheck(CKTcircuit *, GENmodel *);
diff --git a/src/spicelib/devices/hisimhv1/hsmhvinit.c b/src/spicelib/devices/hisimhv1/hsmhvinit.c
index bae987460..6e99917db 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvinit.c
+++ b/src/spicelib/devices/hisimhv1/hsmhvinit.c
@@ -65,7 +65,7 @@ SPICEdev HSMHVinfo = {
/* DEVsenTrunc */ NULL,
/* DEVdisto */ NULL,
/* DEVnoise */ HSMHVnoise,
- /* DEVsoaCheck */ NULL,
+ /* DEVsoaCheck */ HSMHVsoaCheck,
#ifdef CIDER
/* DEVdump */ NULL,
/* DEVacct */ NULL,
diff --git a/src/spicelib/devices/hisimhv1/hsmhvmask.c b/src/spicelib/devices/hisimhv1/hsmhvmask.c
index a851680cc..0796590ce 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvmask.c
+++ b/src/spicelib/devices/hisimhv1/hsmhvmask.c
@@ -1850,6 +1850,25 @@ int HSMHVmAsk(
value->rValue = model->HSMHV_pvover;
return(OK);
+ case HSMHV_MOD_VGS_MAX:
+ value->rValue = model->HSMHVvgsMax;
+ return(OK);
+ case HSMHV_MOD_VGD_MAX:
+ value->rValue = model->HSMHVvgdMax;
+ return(OK);
+ case HSMHV_MOD_VGB_MAX:
+ value->rValue = model->HSMHVvgbMax;
+ return(OK);
+ case HSMHV_MOD_VDS_MAX:
+ value->rValue = model->HSMHVvdsMax;
+ return(OK);
+ case HSMHV_MOD_VBS_MAX:
+ value->rValue = model->HSMHVvbsMax;
+ return(OK);
+ case HSMHV_MOD_VBD_MAX:
+ value->rValue = model->HSMHVvbdMax;
+ return(OK);
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/hisimhv1/hsmhvmpar.c b/src/spicelib/devices/hisimhv1/hsmhvmpar.c
index 7ae19e385..0522f6081 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvmpar.c
+++ b/src/spicelib/devices/hisimhv1/hsmhvmpar.c
@@ -2446,6 +2446,31 @@ int HSMHVmParam(
mod->HSMHV_pvover_Given = TRUE;
break;
+ case HSMHV_MOD_VGS_MAX:
+ mod->HSMHVvgsMax = value->rValue;
+ mod->HSMHVvgsMaxGiven = TRUE;
+ break;
+ case HSMHV_MOD_VGD_MAX:
+ mod->HSMHVvgdMax = value->rValue;
+ mod->HSMHVvgdMaxGiven = TRUE;
+ break;
+ case HSMHV_MOD_VGB_MAX:
+ mod->HSMHVvgbMax = value->rValue;
+ mod->HSMHVvgbMaxGiven = TRUE;
+ break;
+ case HSMHV_MOD_VDS_MAX:
+ mod->HSMHVvdsMax = value->rValue;
+ mod->HSMHVvdsMaxGiven = TRUE;
+ break;
+ case HSMHV_MOD_VBS_MAX:
+ mod->HSMHVvbsMax = value->rValue;
+ mod->HSMHVvbsMaxGiven = TRUE;
+ break;
+ case HSMHV_MOD_VBD_MAX:
+ mod->HSMHVvbdMax = value->rValue;
+ mod->HSMHVvbdMaxGiven = TRUE;
+ break;
+
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/hisimhv1/hsmhvset.c b/src/spicelib/devices/hisimhv1/hsmhvset.c
index a3bd0db4e..e1b83c215 100644
--- a/src/spicelib/devices/hisimhv1/hsmhvset.c
+++ b/src/spicelib/devices/hisimhv1/hsmhvset.c
@@ -738,6 +738,13 @@ int HSMHVsetup(
if ( model->HSMHV_rd26_Given ) model->HSMHV_qovsm = model->HSMHV_rd26 ;
if ( model->HSMHV_ldrift_Given ) model->HSMHV_ldrift2 = model->HSMHV_ldrift ;
+ if (!model->HSMHVvgsMaxGiven) model->HSMHVvgsMax = 1e99;
+ if (!model->HSMHVvgdMaxGiven) model->HSMHVvgdMax = 1e99;
+ if (!model->HSMHVvgbMaxGiven) model->HSMHVvgbMax = 1e99;
+ if (!model->HSMHVvdsMaxGiven) model->HSMHVvdsMax = 1e99;
+ if (!model->HSMHVvbsMaxGiven) model->HSMHVvbsMax = 1e99;
+ if (!model->HSMHVvbdMaxGiven) model->HSMHVvbdMax = 1e99;
+
/* For Symmetrical Device */
if ( model->HSMHV_cosym ) {
if(!model->HSMHV_rs_Given )
diff --git a/src/spicelib/devices/hisimhv1/hsmhvsoachk.c b/src/spicelib/devices/hisimhv1/hsmhvsoachk.c
new file mode 100644
index 000000000..a3362c6a2
--- /dev/null
+++ b/src/spicelib/devices/hisimhv1/hsmhvsoachk.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 "hsmhvdef.h"
+#include "ngspice/trandefs.h"
+#include "ngspice/sperror.h"
+#include "ngspice/suffix.h"
+#include "ngspice/cpdefs.h"
+
+
+int
+HSMHVsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
+{
+ HSMHVmodel *model = (HSMHVmodel *) inModel;
+ HSMHVinstance *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->HSMHVnextModel) {
+
+ for (here = model->HSMHVinstances; here; here = here->HSMHVnextInstance) {
+
+ vgs = fabs(ckt->CKTrhsOld [here->HSMHVgNode] -
+ ckt->CKTrhsOld [here->HSMHVsNodePrime]);
+
+ vgd = fabs(ckt->CKTrhsOld [here->HSMHVgNode] -
+ ckt->CKTrhsOld [here->HSMHVdNodePrime]);
+
+ vgb = fabs(ckt->CKTrhsOld [here->HSMHVgNode] -
+ ckt->CKTrhsOld [here->HSMHVbNode]);
+
+ vds = fabs(ckt->CKTrhsOld [here->HSMHVdNodePrime] -
+ ckt->CKTrhsOld [here->HSMHVsNodePrime]);
+
+ vbs = fabs(ckt->CKTrhsOld [here->HSMHVbNode] -
+ ckt->CKTrhsOld [here->HSMHVsNodePrime]);
+
+ vbd = fabs(ckt->CKTrhsOld [here->HSMHVbNode] -
+ ckt->CKTrhsOld [here->HSMHVdNodePrime]);
+
+ if (vgs > model->HSMHVvgsMax)
+ if (warns_vgs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgs|=%g has exceeded Vgs_max=%g\n",
+ vgs, model->HSMHVvgsMax);
+ warns_vgs++;
+ }
+
+ if (vgd > model->HSMHVvgdMax)
+ if (warns_vgd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgd|=%g has exceeded Vgd_max=%g\n",
+ vgd, model->HSMHVvgdMax);
+ warns_vgd++;
+ }
+
+ if (vgb > model->HSMHVvgbMax)
+ if (warns_vgb < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vgb|=%g has exceeded Vgb_max=%g\n",
+ vgb, model->HSMHVvgbMax);
+ warns_vgb++;
+ }
+
+ if (vds > model->HSMHVvdsMax)
+ if (warns_vds < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vds|=%g has exceeded Vds_max=%g\n",
+ vds, model->HSMHVvdsMax);
+ warns_vds++;
+ }
+
+ if (vbs > model->HSMHVvbsMax)
+ if (warns_vbs < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbs|=%g has exceeded Vbs_max=%g\n",
+ vbs, model->HSMHVvbsMax);
+ warns_vbs++;
+ }
+
+ if (vbd > model->HSMHVvbdMax)
+ if (warns_vbd < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vbd|=%g has exceeded Vbd_max=%g\n",
+ vbd, model->HSMHVvbdMax);
+ warns_vbd++;
+ }
+
+ }
+ }
+
+ return OK;
+}
diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj
index 0d39db8eb..debaaa32c 100644
--- a/visualc/vngspice.vcproj
+++ b/visualc/vngspice.vcproj
@@ -5936,6 +5936,10 @@
RelativePath="..\src\spicelib\devices\hisimhv1\hsmhvset.c"
>
+
+