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