diff --git a/src/spicelib/devices/res/Makefile.am b/src/spicelib/devices/res/Makefile.am index c3d8f33ae..ab746263d 100644 --- a/src/spicelib/devices/res/Makefile.am +++ b/src/spicelib/devices/res/Makefile.am @@ -21,6 +21,7 @@ libres_la_SOURCES = \ respzld.c \ ressacl.c \ ressetup.c \ + ressoachk.c \ ressload.c \ ressprt.c \ ressset.c \ diff --git a/src/spicelib/devices/res/res.c b/src/spicelib/devices/res/res.c index 61449f300..afc1d09c6 100644 --- a/src/spicelib/devices/res/res.c +++ b/src/spicelib/devices/res/res.c @@ -22,6 +22,7 @@ IFparm RESpTable[] = { /* parameters */ IOPU( "tc", RES_TC1, IF_REAL, "First order temp. coefficient"), IOPU( "tc1", RES_TC1, IF_REAL, "First order temp. coefficient"), IOPU( "tc2", RES_TC2, IF_REAL, "Second order temp. coefficient"), + IOP( "bv_max", RES_BV_MAX, IF_REAL, "maximum voltage over resistor"), IOPU( "scale", RES_SCALE, IF_REAL, "Scale factor"), IOP( "noisy", RES_NOISY, IF_INTEGER, "Resistor generate noise"), IP( "sens_resist", RES_RESIST_SENS, IF_FLAG, @@ -55,7 +56,8 @@ IFparm RESmPTable[] = { /* model parameters */ IOPQ( "af", RES_MOD_AF, IF_REAL,"Flicker noise exponent"), IOPXU( "tnom", RES_MOD_TNOM, IF_REAL,"Parameter measurement temperature"), IOP( "r", RES_MOD_R, IF_REAL,"Resistor model default value"), - IOPR( "res", RES_MOD_R, IF_REAL,"Resistor model default value") + IOPR( "res", RES_MOD_R, IF_REAL,"Resistor model default value"), + IOP( "bv_max", RES_MOD_BV_MAX, IF_REAL,"maximum voltage over resistor") }; char *RESnames[] = { diff --git a/src/spicelib/devices/res/resask.c b/src/spicelib/devices/res/resask.c index 3588f07a2..aacb5f66d 100644 --- a/src/spicelib/devices/res/resask.c +++ b/src/spicelib/devices/res/resask.c @@ -70,6 +70,9 @@ RESask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value, case RES_TC2: value->rValue = fast->REStc2; return(OK); + case RES_BV_MAX: + value->rValue = fast->RESbv_max; + return(OK); case RES_NOISY: value->iValue = fast->RESnoisy; return(OK); diff --git a/src/spicelib/devices/res/resdefs.h b/src/spicelib/devices/res/resdefs.h index ed8581e71..84ddf6e09 100644 --- a/src/spicelib/devices/res/resdefs.h +++ b/src/spicelib/devices/res/resdefs.h @@ -42,6 +42,7 @@ typedef struct sRESinstance { double RESm; /* Multiplicity factor for this instance */ double REStc1; /* first temperature coefficient of resistors */ double REStc2; /* second temperature coefficient of resistors */ + double RESbv_max; /* Maximum resistor voltage */ int RESnoisy; /* Set if the resistor generates noise */ double *RESposPosptr; /* pointer to sparse matrix diagonal at * (positive,positive) */ @@ -63,6 +64,7 @@ typedef struct sRESinstance { unsigned REStc1Given : 1; /* indicates tc1 parameter specified */ unsigned REStc2Given : 1; /* indicates tc2 parameter specified */ unsigned RESnoisyGiven : 1; /* indicates if noisy is specified */ + unsigned RESbv_maxGiven : 1; /* flags indicates maximum voltage is given */ int RESsenParmNo; /* parameter # for sensitivity use; * set equal to 0 if not a design parameter*/ @@ -105,6 +107,7 @@ typedef struct sRESmodel { /* model structure for a resistor */ double RESfNcoef; /* Flicker noise coefficient */ double RESfNexp; /* Flicker noise exponent */ double RESres; /* Default model resistance */ + double RESbv_max; /* Maximum resistor voltage */ unsigned REStnomGiven :1; /* flag to indicate nominal temp. was given */ unsigned REStc1Given :1; /* flag to indicate tc1 was specified */ unsigned REStc2Given :1; /* flag to indicate tc2 was specified */ @@ -116,6 +119,7 @@ typedef struct sRESmodel { /* model structure for a resistor */ unsigned RESfNcoefGiven :1; /* flag to indicate kf given */ unsigned RESfNexpGiven :1; /* flag to indicate af given */ unsigned RESresGiven :1; /* flag to indicate model resistance given */ + unsigned RESbv_maxGiven :1; /* flags indicates maximum voltage is given */ } RESmodel; /* device parameters */ @@ -137,6 +141,7 @@ typedef struct sRESmodel { /* model structure for a resistor */ /* tanaka */ #define RES_TC1 16 #define RES_TC2 17 +#define RES_BV_MAX 18 /* model parameters */ #define RES_MOD_TC1 101 @@ -150,6 +155,7 @@ typedef struct sRESmodel { /* model structure for a resistor */ #define RES_MOD_SHORT 109 #define RES_MOD_KF 110 #define RES_MOD_AF 111 +#define RES_MOD_BV_MAX 112 /* device questions */ #define RES_QUEST_SENS_REAL 201 diff --git a/src/spicelib/devices/res/resext.h b/src/spicelib/devices/res/resext.h index ee4be5516..148d1d222 100644 --- a/src/spicelib/devices/res/resext.h +++ b/src/spicelib/devices/res/resext.h @@ -20,3 +20,4 @@ extern void RESsPrint(GENmodel*,CKTcircuit*); extern int RESsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*); extern int REStemp(GENmodel*,CKTcircuit*); extern int RESnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); +extern int RESsoaCheck(CKTcircuit *, GENmodel *); diff --git a/src/spicelib/devices/res/resinit.c b/src/spicelib/devices/res/resinit.c index a9c9cea7b..d4096de8d 100644 --- a/src/spicelib/devices/res/resinit.c +++ b/src/spicelib/devices/res/resinit.c @@ -67,7 +67,7 @@ SPICEdev RESinfo = { /* DEVsenTrunc */ NULL, /* DEVdisto */ NULL, /* DEVnoise */ RESnoise, - /* DEVsoaCheck */ NULL, + /* DEVsoaCheck */ RESsoaCheck, #ifdef CIDER /* DEVdump */ NULL, /* DEVacct */ NULL, diff --git a/src/spicelib/devices/res/resmask.c b/src/spicelib/devices/res/resmask.c index 698161d3e..d611c4402 100644 --- a/src/spicelib/devices/res/resmask.c +++ b/src/spicelib/devices/res/resmask.c @@ -60,6 +60,9 @@ RESmodAsk(CKTcircuit *ckt, GENmodel *inModel, int which, IFvalue *value) else value->rValue = 0.0; return(OK); + case RES_MOD_BV_MAX: + value->rValue = model->RESbv_max; + return(OK); case RES_MOD_R: value->rValue = model->RESres; return(OK); diff --git a/src/spicelib/devices/res/resmpar.c b/src/spicelib/devices/res/resmpar.c index d47e36202..cf5bdb7e5 100644 --- a/src/spicelib/devices/res/resmpar.c +++ b/src/spicelib/devices/res/resmpar.c @@ -58,6 +58,10 @@ RESmParam(int param, IFvalue *value, GENmodel *inModel) model->RESfNexp = value->rValue; model->RESfNexpGiven = TRUE; break; + case RES_MOD_BV_MAX: + model->RESbv_max = value->rValue; + model->RESbv_maxGiven = TRUE; + break; case RES_MOD_R: if ( value->rValue > 1e-03 ) { model->RESres = value->rValue; diff --git a/src/spicelib/devices/res/resparam.c b/src/spicelib/devices/res/resparam.c index 4e8d75fbe..a5900ab33 100644 --- a/src/spicelib/devices/res/resparam.c +++ b/src/spicelib/devices/res/resparam.c @@ -74,6 +74,10 @@ RESparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select) here->RESnoisy = value->iValue; here->RESnoisyGiven = TRUE; break; + case RES_BV_MAX: + here->RESbv_max = value->rValue; + here->RESbv_maxGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/res/ressetup.c b/src/spicelib/devices/res/ressetup.c index 1ed10d246..0077f3750 100644 --- a/src/spicelib/devices/res/ressetup.c +++ b/src/spicelib/devices/res/ressetup.c @@ -25,12 +25,17 @@ RESsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit*ckt, int *state) /* loop through all the resistor models */ for( ; model != NULL; model = model->RESnextModel ) { + if(!model->RESbv_maxGiven) + model->RESbv_max = 1e99; + /* loop through all the instances of the model */ for (here = model->RESinstances; here != NULL ; here=here->RESnextInstance) { if(!here->RESmGiven) here->RESm = 1.0; + if(!here->RESbv_maxGiven) + here->RESbv_max = model->RESbv_max; /* macro to make elements with built in test for out of memory */ #define TSTALLOC(ptr,first,second) \ diff --git a/src/spicelib/devices/res/ressoachk.c b/src/spicelib/devices/res/ressoachk.c new file mode 100644 index 000000000..846a7fc3d --- /dev/null +++ b/src/spicelib/devices/res/ressoachk.c @@ -0,0 +1,51 @@ +/********** +Copyright 2013 Dietmar Warning. All rights reserved. +Author: 2013 Dietmar Warning +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "resdefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +RESsoaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + RESmodel *model = (RESmodel *) inModel; + RESinstance *here; + double vr; /* current resistor voltage */ + int maxwarns; + static int warns_bv = 0; + + if (!ckt) { + warns_bv = 0; + return OK; + } + + maxwarns = ckt->CKTsoaMaxWarns; + + for (; model; model = model->RESnextModel) { + + for (here = model->RESinstances; here; here = here->RESnextInstance) { + + vr = fabs(ckt->CKTrhsOld [here->RESposNode] - + ckt->CKTrhsOld [here->RESnegNode]); + + if (vr > here->RESbv_max) + if (warns_bv < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vr|=%g has exceeded Bv_max=%g\n", + vr, here->RESbv_max); + warns_bv++; + } + + } + + } + + return OK; +} diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index 953f8e9a6..172f03892 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -7984,6 +7984,10 @@ RelativePath="..\src\spicelib\devices\res\ressload.c" > + +