diff --git a/src/spicelib/devices/bsim4v6/Makefile.am b/src/spicelib/devices/bsim4v6/Makefile.am index 0815d57eb..ad03052c0 100644 --- a/src/spicelib/devices/bsim4v6/Makefile.am +++ b/src/spicelib/devices/bsim4v6/Makefile.am @@ -20,6 +20,7 @@ libbsim4v6_la_SOURCES = \ b4v6par.c \ b4v6pzld.c \ b4v6set.c \ + b4v6soachk.c \ b4v6temp.c \ b4v6trunc.c \ bsim4v6def.h \ diff --git a/src/spicelib/devices/bsim4v6/b4v6.c b/src/spicelib/devices/bsim4v6/b4v6.c index acb95ab00..7c0c8d2b0 100644 --- a/src/spicelib/devices/bsim4v6/b4v6.c +++ b/src/spicelib/devices/bsim4v6/b4v6.c @@ -974,6 +974,13 @@ IOP( "ef", BSIM4v6_MOD_EF, IF_REAL, "Flicker noise frequency exponent"), IOP( "af", BSIM4v6_MOD_AF, IF_REAL, "Flicker noise exponent"), IOP( "kf", BSIM4v6_MOD_KF, IF_REAL, "Flicker noise coefficient"), +IOP("vgs_max", BSIM4v6_MOD_VGS_MAX, IF_REAL, "maximum voltage G-S branch"), +IOP("vgd_max", BSIM4v6_MOD_VGD_MAX, IF_REAL, "maximum voltage G-D branch"), +IOP("vgb_max", BSIM4v6_MOD_VGB_MAX, IF_REAL, "maximum voltage G-B branch"), +IOP("vds_max", BSIM4v6_MOD_VDS_MAX, IF_REAL, "maximum voltage D-S branch"), +IOP("vbs_max", BSIM4v6_MOD_VBS_MAX, IF_REAL, "maximum voltage B-S branch"), +IOP("vbd_max", BSIM4v6_MOD_VBD_MAX, IF_REAL, "maximum voltage B-D branch"), + IP( "nmos", BSIM4v6_MOD_NMOS, IF_FLAG, "Flag to indicate NMOS"), IP( "pmos", BSIM4v6_MOD_PMOS, IF_FLAG, "Flag to indicate PMOS"), }; diff --git a/src/spicelib/devices/bsim4v6/b4v6mask.c b/src/spicelib/devices/bsim4v6/b4v6mask.c index 39bb05a0a..72175e747 100644 --- a/src/spicelib/devices/bsim4v6/b4v6mask.c +++ b/src/spicelib/devices/bsim4v6/b4v6mask.c @@ -2489,6 +2489,26 @@ IFvalue *value) case BSIM4v6_MOD_KF: value->rValue = model->BSIM4v6kf; return(OK); + + case BSIM4v6_MOD_VGS_MAX: + value->rValue = model->BSIM4v6vgsMax; + return(OK); + case BSIM4v6_MOD_VGD_MAX: + value->rValue = model->BSIM4v6vgdMax; + return(OK); + case BSIM4v6_MOD_VGB_MAX: + value->rValue = model->BSIM4v6vgbMax; + return(OK); + case BSIM4v6_MOD_VDS_MAX: + value->rValue = model->BSIM4v6vdsMax; + return(OK); + case BSIM4v6_MOD_VBS_MAX: + value->rValue = model->BSIM4v6vbsMax; + return(OK); + case BSIM4v6_MOD_VBD_MAX: + value->rValue = model->BSIM4v6vbdMax; + return(OK); + default: return(E_BADPARM); } diff --git a/src/spicelib/devices/bsim4v6/b4v6mpar.c b/src/spicelib/devices/bsim4v6/b4v6mpar.c index 181139846..25faa22d8 100644 --- a/src/spicelib/devices/bsim4v6/b4v6mpar.c +++ b/src/spicelib/devices/bsim4v6/b4v6mpar.c @@ -3377,6 +3377,31 @@ GENmodel *inMod) mod->BSIM4v6kf = value->rValue; mod->BSIM4v6kfGiven = TRUE; break; + case BSIM4v6_MOD_VGS_MAX: + mod->BSIM4v6vgsMax = value->rValue; + mod->BSIM4v6vgsMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VGD_MAX: + mod->BSIM4v6vgdMax = value->rValue; + mod->BSIM4v6vgdMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VGB_MAX: + mod->BSIM4v6vgbMax = value->rValue; + mod->BSIM4v6vgbMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VDS_MAX: + mod->BSIM4v6vdsMax = value->rValue; + mod->BSIM4v6vdsMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VBS_MAX: + mod->BSIM4v6vbsMax = value->rValue; + mod->BSIM4v6vbsMaxGiven = TRUE; + break; + case BSIM4v6_MOD_VBD_MAX: + mod->BSIM4v6vbdMax = value->rValue; + mod->BSIM4v6vbdMaxGiven = TRUE; + break; + case BSIM4v6_MOD_NMOS : if(value->iValue) { mod->BSIM4v6type = 1; diff --git a/src/spicelib/devices/bsim4v6/b4v6set.c b/src/spicelib/devices/bsim4v6/b4v6set.c index 93e573eaf..e7b5682b1 100644 --- a/src/spicelib/devices/bsim4v6/b4v6set.c +++ b/src/spicelib/devices/bsim4v6/b4v6set.c @@ -1937,6 +1937,19 @@ BSIM4v6instance **InstArray; if (!model->BSIM4v6kfGiven) model->BSIM4v6kf = 0.0; + if (!model->BSIM4v6vgsMaxGiven) + model->BSIM4v6vgsMax = 1e99; + if (!model->BSIM4v6vgdMaxGiven) + model->BSIM4v6vgdMax = 1e99; + if (!model->BSIM4v6vgbMaxGiven) + model->BSIM4v6vgbMax = 1e99; + if (!model->BSIM4v6vdsMaxGiven) + model->BSIM4v6vdsMax = 1e99; + if (!model->BSIM4v6vbsMaxGiven) + model->BSIM4v6vbsMax = 1e99; + if (!model->BSIM4v6vbdMaxGiven) + model->BSIM4v6vbdMax = 1e99; + /* stress effect */ if (!model->BSIM4v6sarefGiven) model->BSIM4v6saref = 1e-6; /* m */ diff --git a/src/spicelib/devices/bsim4v6/b4v6soachk.c b/src/spicelib/devices/bsim4v6/b4v6soachk.c new file mode 100644 index 000000000..69dc14a07 --- /dev/null +++ b/src/spicelib/devices/bsim4v6/b4v6soachk.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 "bsim4v6def.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +BSIM4v6soaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + BSIM4v6model *model = (BSIM4v6model *) inModel; + BSIM4v6instance *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->BSIM4v6nextModel) { + + for (here = model->BSIM4v6instances; here; here = here->BSIM4v6nextInstance) { + + vgs = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + + vgd = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6dNodePrime]); + + vgb = fabs(ckt->CKTrhsOld [here->BSIM4v6gNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6bNodePrime]); + + vds = fabs(ckt->CKTrhsOld [here->BSIM4v6dNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + + vbs = fabs(ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6sNodePrime]); + + vbd = fabs(ckt->CKTrhsOld [here->BSIM4v6bNodePrime] - + ckt->CKTrhsOld [here->BSIM4v6dNodePrime]); + + if (vgs > model->BSIM4v6vgsMax) + if (warns_vgs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vgs|=%g has exceeded Vgs_max=%g\n", + vgs, model->BSIM4v6vgsMax); + warns_vgs++; + } + + if (vgd > model->BSIM4v6vgdMax) + if (warns_vgd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vgd|=%g has exceeded Vgd_max=%g\n", + vgd, model->BSIM4v6vgdMax); + warns_vgd++; + } + + if (vgb > model->BSIM4v6vgbMax) + if (warns_vgb < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vgb|=%g has exceeded Vgb_max=%g\n", + vgb, model->BSIM4v6vgbMax); + warns_vgb++; + } + + if (vds > model->BSIM4v6vdsMax) + if (warns_vds < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vds|=%g has exceeded Vds_max=%g\n", + vds, model->BSIM4v6vdsMax); + warns_vds++; + } + + if (vbs > model->BSIM4v6vbsMax) + if (warns_vbs < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbs|=%g has exceeded Vbs_max=%g\n", + vbs, model->BSIM4v6vbsMax); + warns_vbs++; + } + + if (vbd > model->BSIM4v6vbdMax) + if (warns_vbd < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbd|=%g has exceeded Vbd_max=%g\n", + vbd, model->BSIM4v6vbdMax); + warns_vbd++; + } + + } + } + + return OK; +} diff --git a/src/spicelib/devices/bsim4v6/bsim4v6def.h b/src/spicelib/devices/bsim4v6/bsim4v6def.h index fc0900441..8e522bd73 100644 --- a/src/spicelib/devices/bsim4v6/bsim4v6def.h +++ b/src/spicelib/devices/bsim4v6/bsim4v6def.h @@ -1692,6 +1692,13 @@ typedef struct sBSIM4v6model double BSIM4v6af; double BSIM4v6kf; + double BSIM4v6vgsMax; + double BSIM4v6vgdMax; + double BSIM4v6vgbMax; + double BSIM4v6vdsMax; + double BSIM4v6vbsMax; + double BSIM4v6vbdMax; + struct bsim4v6SizeDependParam *pSizeDependParamKnot; @@ -2493,6 +2500,13 @@ typedef struct sBSIM4v6model unsigned BSIM4v6afGiven :1; unsigned BSIM4v6kfGiven :1; + unsigned BSIM4v6vgsMaxGiven :1; + unsigned BSIM4v6vgdMaxGiven :1; + unsigned BSIM4v6vgbMaxGiven :1; + unsigned BSIM4v6vdsMaxGiven :1; + unsigned BSIM4v6vbsMaxGiven :1; + unsigned BSIM4v6vbdMaxGiven :1; + unsigned BSIM4v6LintGiven :1; unsigned BSIM4v6LlGiven :1; unsigned BSIM4v6LlcGiven :1; @@ -3546,6 +3560,13 @@ typedef struct sBSIM4v6model #define BSIM4v6_MOD_TNJTSSWD 1254 #define BSIM4v6_MOD_TNJTSSWGD 1255 +#define BSIM4v6_MOD_VGS_MAX 1301 +#define BSIM4v6_MOD_VGD_MAX 1302 +#define BSIM4v6_MOD_VGB_MAX 1303 +#define BSIM4v6_MOD_VDS_MAX 1304 +#define BSIM4v6_MOD_VBS_MAX 1305 +#define BSIM4v6_MOD_VBD_MAX 1306 + #include "bsim4v6ext.h" extern void BSIM4v6evaluate(double,double,double,BSIM4v6instance*,BSIM4v6model*, diff --git a/src/spicelib/devices/bsim4v6/bsim4v6ext.h b/src/spicelib/devices/bsim4v6/bsim4v6ext.h index c78426430..c08a6b9b9 100644 --- a/src/spicelib/devices/bsim4v6/bsim4v6ext.h +++ b/src/spicelib/devices/bsim4v6/bsim4v6ext.h @@ -28,3 +28,4 @@ extern int BSIM4v6temp(GENmodel*,CKTcircuit*); extern int BSIM4v6trunc(GENmodel*,CKTcircuit*,double*); extern int BSIM4v6noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BSIM4v6unsetup(GENmodel*,CKTcircuit*); +extern int BSIM4v6soaCheck(CKTcircuit *, GENmodel *); diff --git a/src/spicelib/devices/bsim4v6/bsim4v6init.c b/src/spicelib/devices/bsim4v6/bsim4v6init.c index 05f49a494..28cd3e28a 100644 --- a/src/spicelib/devices/bsim4v6/bsim4v6init.c +++ b/src/spicelib/devices/bsim4v6/bsim4v6init.c @@ -67,7 +67,7 @@ SPICEdev BSIM4v6info = { NULL, /* DEVsenTrunc */ NULL, /* DEVdisto */ BSIM4v6noise, /* DEVnoise */ - NULL, /* DEVsoaCheck */ + BSIM4v6soaCheck,/* DEVsoaCheck */ #ifdef CIDER NULL, /* DEVdump */ NULL, /* DEVacct */ diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index 8b79e4940..feec3a5f0 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -4296,6 +4296,10 @@ RelativePath="..\src\spicelib\devices\bsim4v6\b4v6set.c" > + +