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" > + +