diff --git a/src/spicelib/devices/vbic/Makefile.am b/src/spicelib/devices/vbic/Makefile.am index 0ea84de4f..a0aee2cb8 100644 --- a/src/spicelib/devices/vbic/Makefile.am +++ b/src/spicelib/devices/vbic/Makefile.am @@ -23,6 +23,7 @@ libvbic_la_SOURCES = \ vbicparam.c \ vbicpzld.c \ vbicsetup.c \ + vbicsoachk.c \ vbictemp.c \ vbictrunc.c diff --git a/src/spicelib/devices/vbic/vbic.c b/src/spicelib/devices/vbic/vbic.c index 8ad41bee4..15d3c2031 100644 --- a/src/spicelib/devices/vbic/vbic.c +++ b/src/spicelib/devices/vbic/vbic.c @@ -183,7 +183,10 @@ IFparm VBICmPTable[] = { /* model parameters */ IOP("ebbe", VBIC_MOD_EBBE, IF_REAL, "exp(-VBBE/(NBBE*Vtv))"), IOP("dtemp", VBIC_MOD_DTEMP, IF_REAL, "Locale Temperature difference"), IOP("vers", VBIC_MOD_VERS, IF_REAL, "Revision Version"), - IOP("vref", VBIC_MOD_VREF, IF_REAL, "Reference Version") + IOP("vref", VBIC_MOD_VREF, IF_REAL, "Reference Version"), + IOP("vbe_max", VBIC_MOD_VBE_MAX, IF_REAL, "maximum voltage B-E junction"), + IOP("vbc_max", VBIC_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"), + IOP("vce_max", VBIC_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch") }; char *VBICnames[] = { diff --git a/src/spicelib/devices/vbic/vbicdefs.h b/src/spicelib/devices/vbic/vbicdefs.h index e446b2f10..22b01f684 100644 --- a/src/spicelib/devices/vbic/vbicdefs.h +++ b/src/spicelib/devices/vbic/vbicdefs.h @@ -475,6 +475,10 @@ typedef struct sVBICmodel { /* model structure for a vbic */ double VBICemitterConduct; /* emitter conductance */ double VBICsubstrateConduct; /* substrate conductance */ + double VBICvbeMax; /* maximum voltage over B-E junction */ + double VBICvbcMax; /* maximum voltage over B-C junction */ + double VBICvceMax; /* maximum voltage over C-E branch */ + unsigned VBICtnomGiven : 1; unsigned VBICextCollResistGiven : 1; unsigned VBICintCollResistGiven : 1; @@ -585,6 +589,9 @@ typedef struct sVBICmodel { /* model structure for a vbic */ unsigned VBIClocTempDiffGiven : 1; unsigned VBICrevVersionGiven : 1; unsigned VBICrefVersionGiven : 1; + unsigned VBICvbeMaxGiven : 1; + unsigned VBICvbcMaxGiven : 1; + unsigned VBICvceMaxGiven : 1; } VBICmodel; #ifndef NPN @@ -715,6 +722,9 @@ typedef struct sVBICmodel { /* model structure for a vbic */ #define VBIC_MOD_DTEMP 210 #define VBIC_MOD_VERS 211 #define VBIC_MOD_VREF 212 +#define VBIC_MOD_VBE_MAX 213 +#define VBIC_MOD_VBC_MAX 214 +#define VBIC_MOD_VCE_MAX 215 /* device questions */ diff --git a/src/spicelib/devices/vbic/vbicext.h b/src/spicelib/devices/vbic/vbicext.h index 96e0d11bc..c0e0ff943 100644 --- a/src/spicelib/devices/vbic/vbicext.h +++ b/src/spicelib/devices/vbic/vbicext.h @@ -25,5 +25,6 @@ extern int VBICunsetup(GENmodel*,CKTcircuit*); extern int VBICtemp(GENmodel*,CKTcircuit*); extern int VBICtrunc(GENmodel*,CKTcircuit*,double*); extern int VBICnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int VBICsoaCheck(CKTcircuit *, GENmodel *); #endif diff --git a/src/spicelib/devices/vbic/vbicinit.c b/src/spicelib/devices/vbic/vbicinit.c index 84118245c..9abc37049 100644 --- a/src/spicelib/devices/vbic/vbicinit.c +++ b/src/spicelib/devices/vbic/vbicinit.c @@ -72,7 +72,7 @@ SPICEdev VBICinfo = { NULL, /* DEVsenTrunc */ NULL, /* DEVdisto */ VBICnoise, /* DEVnoise */ - NULL, /* DEVsoaCheck */ + VBICsoaCheck, /* DEVsoaCheck */ #ifdef CIDER NULL, /* DEVdump */ NULL, /* DEVacct */ diff --git a/src/spicelib/devices/vbic/vbicmask.c b/src/spicelib/devices/vbic/vbicmask.c index 1ada8469c..d5f61d901 100644 --- a/src/spicelib/devices/vbic/vbicmask.c +++ b/src/spicelib/devices/vbic/vbicmask.c @@ -354,6 +354,15 @@ VBICmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) case VBIC_MOD_VREF: value->rValue = here->VBICrefVersion; return(OK); + case VBIC_MOD_VBE_MAX: + value->rValue = here->VBICvbeMax; + return(OK); + case VBIC_MOD_VBC_MAX: + value->rValue = here->VBICvbcMax; + return(OK); + case VBIC_MOD_VCE_MAX: + value->rValue = here->VBICvceMax; + return(OK); case VBIC_MOD_TYPE: if (here->VBICtype == NPN) value->sValue = "npn"; diff --git a/src/spicelib/devices/vbic/vbicmpar.c b/src/spicelib/devices/vbic/vbicmpar.c index 100c71c48..2b4940c65 100644 --- a/src/spicelib/devices/vbic/vbicmpar.c +++ b/src/spicelib/devices/vbic/vbicmpar.c @@ -482,6 +482,18 @@ VBICmParam(int param, IFvalue *value, GENmodel *inModel) mods->VBICrefVersion = value->rValue; mods->VBICrefVersionGiven = TRUE; break; + case VBIC_MOD_VBE_MAX: + mods->VBICvbeMax = value->rValue; + mods->VBICvbeMaxGiven = TRUE; + break; + case VBIC_MOD_VBC_MAX: + mods->VBICvbcMax = value->rValue; + mods->VBICvbcMaxGiven = TRUE; + break; + case VBIC_MOD_VCE_MAX: + mods->VBICvceMax = value->rValue; + mods->VBICvceMaxGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/vbic/vbicsetup.c b/src/spicelib/devices/vbic/vbicsetup.c index 248a98b8c..d5171bf75 100644 --- a/src/spicelib/devices/vbic/vbicsetup.c +++ b/src/spicelib/devices/vbic/vbicsetup.c @@ -369,6 +369,16 @@ VBICsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) model->VBICrefVersion = 0.0; } + if(!model->VBICvbeMaxGiven) { + model->VBICvbeMax = 1e99; + } + if(!model->VBICvbcMaxGiven) { + model->VBICvbcMax = 1e99; + } + if(!model->VBICvceMaxGiven) { + model->VBICvceMax = 1e99; + } + /* loop through all the instances of the model */ for (here = model->VBICinstances; here != NULL ; here=here->VBICnextInstance) { diff --git a/src/spicelib/devices/vbic/vbicsoachk.c b/src/spicelib/devices/vbic/vbicsoachk.c new file mode 100644 index 000000000..f534e5aff --- /dev/null +++ b/src/spicelib/devices/vbic/vbicsoachk.c @@ -0,0 +1,72 @@ +/********** +Copyright 2013 Dietmar Warning. All rights reserved. +Author: 2013 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "vbicdefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +VBICsoaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + VBICmodel *model = (VBICmodel *) inModel; + VBICinstance *here; + double vbe, vbc, vce; /* actual bjt voltages */ + int maxwarns; + static int warns_vbe = 0, warns_vbc = 0, warns_vce = 0; + + if (!ckt) { + warns_vbe = 0; + warns_vbc = 0; + warns_vce = 0; + return OK; + } + + maxwarns = ckt->CKTsoaMaxWarns; + + for (; model; model = model->VBICnextModel) { + + for (here = model->VBICinstances; here; here=here->VBICnextInstance) { + + vbe = fabs(ckt->CKTrhsOld [here->VBICbaseNode] - + ckt->CKTrhsOld [here->VBICemitNode]); + vbc = fabs(ckt->CKTrhsOld [here->VBICbaseNode] - + ckt->CKTrhsOld [here->VBICcollNode]); + vce = fabs(ckt->CKTrhsOld [here->VBICcollNode] - + ckt->CKTrhsOld [here->VBICemitNode]); + + if (vbe > model->VBICvbeMax) + if (warns_vbe < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbe|=%g has exceeded Vbe_max=%g\n", + vbe, model->VBICvbeMax); + warns_vbe++; + } + + if (vbc > model->VBICvbcMax) + if (warns_vbc < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbc|=%g has exceeded Vbc_max=%g\n", + vbc, model->VBICvbcMax); + warns_vbc++; + } + + if (vce > model->VBICvceMax) + if (warns_vce < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vce|=%g has exceeded Vce_max=%g\n", + vce, model->VBICvceMax); + warns_vce++; + } + + } + } + + return OK; +} diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index a2d0dbfdd..8eb2440bd 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -8636,6 +8636,10 @@ RelativePath="..\src\spicelib\devices\vbic\vbicsetup.c" > + +