diff --git a/src/spicelib/devices/dio/Makefile.am b/src/spicelib/devices/dio/Makefile.am index 7218d39b0..abb29045e 100644 --- a/src/spicelib/devices/dio/Makefile.am +++ b/src/spicelib/devices/dio/Makefile.am @@ -27,6 +27,7 @@ libdio_la_SOURCES = \ diosacl.c \ diosetup.c \ diosload.c \ + diosoachk.c \ diosprt.c \ diosset.c \ diosupd.c \ diff --git a/src/spicelib/devices/dio/dio.c b/src/spicelib/devices/dio/dio.c index 2ac0cf599..17c4ff5f4 100644 --- a/src/spicelib/devices/dio/dio.c +++ b/src/spicelib/devices/dio/dio.c @@ -104,6 +104,10 @@ IFparm DIOmPTable[] = { /* model parameters */ IOPR( "ib", DIO_MOD_IBV, IF_REAL, "Current at reverse breakdown voltage"), IOP( "tcv", DIO_MOD_TCV, IF_REAL, "Reverse breakdown voltage temperature coefficient"), OPU( "cond", DIO_MOD_COND,IF_REAL, "Ohmic conductance"), + + IOP( "fv_max", DIO_MOD_FV_MAX, IF_REAL, "maximum voltage in forward direction"), + IOP( "bv_max", DIO_MOD_BV_MAX, IF_REAL, "maximum voltage in reverse direction"), + IP( "d", DIO_MOD_D, IF_FLAG, "Diode model") }; diff --git a/src/spicelib/devices/dio/diodefs.h b/src/spicelib/devices/dio/diodefs.h index 2ea4cd4ac..7cb4da8a2 100644 --- a/src/spicelib/devices/dio/diodefs.h +++ b/src/spicelib/devices/dio/diodefs.h @@ -217,6 +217,8 @@ typedef struct sDIOmodel { /* model structure for a diode */ unsigned DIOtunEmissionCoeffGiven : 1; unsigned DIOtunSaturationCurrentExpGiven : 1; unsigned DIOtunEGcorrectionFactorGiven : 1; + unsigned DIOfv_maxGiven : 1; + unsigned DIObv_maxGiven : 1; int DIOlevel; /* level selector */ double DIOsatCur; /* saturation current */ @@ -268,6 +270,8 @@ typedef struct sDIOmodel { /* model structure for a diode */ double DIOtunEmissionCoeff; /* tunneling emission coefficient (NTUN) */ double DIOtunSaturationCurrentExp; /* exponent for the tunneling current temperature (XTITUN) */ double DIOtunEGcorrectionFactor; /* EG correction factor for tunneling (KEG) */ + double DIOfv_max; /* maximum voltage in forward direction */ + double DIObv_max; /* maximum voltage in reverse direction */ } DIOmodel; @@ -344,6 +348,8 @@ typedef struct sDIOmodel { /* model structure for a diode */ #define DIO_MOD_NTUN 144 #define DIO_MOD_XTITUN 145 #define DIO_MOD_KEG 146 +#define DIO_MOD_FV_MAX 147 +#define DIO_MOD_BV_MAX 148 #include "dioext.h" #endif /*DIO*/ diff --git a/src/spicelib/devices/dio/dioext.h b/src/spicelib/devices/dio/dioext.h index bb0a132d0..803efea33 100644 --- a/src/spicelib/devices/dio/dioext.h +++ b/src/spicelib/devices/dio/dioext.h @@ -28,4 +28,5 @@ extern int DIOtrunc(GENmodel*,CKTcircuit*,double*); extern int DIOdisto(int,GENmodel*,CKTcircuit*); extern int DIOnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int DIOdSetup(DIOmodel*,CKTcircuit*); +extern int DIOsoaCheck(CKTcircuit *, GENmodel *); diff --git a/src/spicelib/devices/dio/dioinit.c b/src/spicelib/devices/dio/dioinit.c index f5c43f251..4161316d2 100644 --- a/src/spicelib/devices/dio/dioinit.c +++ b/src/spicelib/devices/dio/dioinit.c @@ -68,7 +68,7 @@ SPICEdev DIOinfo = { /* DEVsenTrunc */ NULL, /* DEVdisto */ DIOdisto, /* DEVnoise */ DIOnoise, - /* DEVsoaCheck */ NULL, + /* DEVsoaCheck */ DIOsoaCheck, #ifdef CIDER /* DEVdump */ NULL, /* DEVacct */ NULL, diff --git a/src/spicelib/devices/dio/diomask.c b/src/spicelib/devices/dio/diomask.c index 916b24a85..04925761b 100644 --- a/src/spicelib/devices/dio/diomask.c +++ b/src/spicelib/devices/dio/diomask.c @@ -164,6 +164,12 @@ DIOmAsk (CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) case DIO_MOD_KEG: value->rValue = model->DIOtunEGcorrectionFactor; return(OK); + case DIO_MOD_FV_MAX: + value->rValue = model->DIOfv_max; + return(OK); + case DIO_MOD_BV_MAX: + value->rValue = model->DIObv_max; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/dio/diompar.c b/src/spicelib/devices/dio/diompar.c index 225815e0f..f65236267 100644 --- a/src/spicelib/devices/dio/diompar.c +++ b/src/spicelib/devices/dio/diompar.c @@ -201,6 +201,14 @@ DIOmParam(int param, IFvalue *value, GENmodel *inModel) model->DIOtunEGcorrectionFactor = value->rValue; model->DIOtunEGcorrectionFactorGiven = TRUE; break; + case DIO_MOD_FV_MAX: + model->DIOfv_max = value->rValue; + model->DIOfv_maxGiven = TRUE; + break; + case DIO_MOD_BV_MAX: + model->DIObv_max = value->rValue; + model->DIObv_maxGiven = TRUE; + break; case DIO_MOD_D: /* no action - we already know we are a diode, but this */ /* makes life easier for spice-2 like parsers */ diff --git a/src/spicelib/devices/dio/diosetup.c b/src/spicelib/devices/dio/diosetup.c index fc0d37b16..9181e6823 100644 --- a/src/spicelib/devices/dio/diosetup.c +++ b/src/spicelib/devices/dio/diosetup.c @@ -153,6 +153,12 @@ DIOsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->DIOtunEGcorrectionFactorGiven) { model->DIOtunEGcorrectionFactor = 1.0; } + if(!model->DIOfv_maxGiven) { + model->DIOfv_max = 1e99; + } + if(!model->DIObv_maxGiven) { + model->DIObv_max = 1e99; + } /* loop through all the instances of the model */ for (here = model->DIOinstances; here != NULL ; diff --git a/src/spicelib/devices/dio/diosoachk.c b/src/spicelib/devices/dio/diosoachk.c new file mode 100644 index 000000000..f1ed25980 --- /dev/null +++ b/src/spicelib/devices/dio/diosoachk.c @@ -0,0 +1,60 @@ +/********** +Copyright 2013 Dietmar Warning. All rights reserved. +Author: 2013 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "diodefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +DIOsoaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + DIOmodel *model = (DIOmodel *) inModel; + DIOinstance *here; + double vd; /* current diode voltage */ + int maxwarns; + static int warns_fv = 0, warns_bv = 0; + + if (!ckt) { + warns_fv = 0; + warns_bv = 0; + return OK; + } + + maxwarns = ckt->CKTsoaMaxWarns; + + for (; model; model = model->DIOnextModel) { + + for (here = model->DIOinstances; here; here = here->DIOnextInstance) { + + vd = ckt->CKTrhsOld [here->DIOposPrimeNode] - + ckt->CKTrhsOld [here->DIOnegNode]; + + if (vd > model->DIOfv_max) + if (warns_fv < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vj=%g has exceeded Fv_max=%g\n", + vd, model->DIOfv_max); + warns_fv++; + } + + if (-vd > model->DIObv_max) + if (warns_bv < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "Vj=%g has exceeded Bv_max=%g\n", + vd, model->DIObv_max); + warns_bv++; + } + + } + + } + + return OK; +} diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index 24c254df4..704356b79 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -5384,6 +5384,10 @@ RelativePath="..\src\spicelib\devices\dio\diosload.c" > + +