diff --git a/src/spicelib/devices/cap/Makefile.am b/src/spicelib/devices/cap/Makefile.am
index 78d8daaff..4205040ae 100644
--- a/src/spicelib/devices/cap/Makefile.am
+++ b/src/spicelib/devices/cap/Makefile.am
@@ -23,6 +23,7 @@ libcap_la_SOURCES = \
capsacl.c \
capsetup.c \
capsload.c \
+ capsoachk.c \
capsprt.c \
capsset.c \
capsupd.c \
diff --git a/src/spicelib/devices/cap/cap.c b/src/spicelib/devices/cap/cap.c
index 370ae170d..9a3c69b49 100644
--- a/src/spicelib/devices/cap/cap.c
+++ b/src/spicelib/devices/cap/cap.c
@@ -22,6 +22,7 @@ IFparm CAPpTable[] = { /* parameters */
IOPU( "m", CAP_M, IF_REAL, "Parallel multiplier"),
IOPU( "tc1", CAP_TC1, IF_REAL, "First order temp. coefficient"),
IOPU( "tc2", CAP_TC2, IF_REAL, "Second order temp. coefficient"),
+ IOP( "bv_max", CAP_BV_MAX, IF_REAL, "maximum voltage over capacitance"),
IOPU( "scale", CAP_SCALE, IF_REAL, "Scale factor"),
IP( "sens_cap", CAP_CAP_SENS, IF_FLAG, "flag to request sens. WRT cap."),
OP( "i", CAP_CURRENT, IF_REAL, "Device current"),
@@ -53,6 +54,7 @@ IFparm CAPmPTable[] = { /* names of model parameters */
IOPXU("tnom", CAP_MOD_TNOM, IF_REAL, "Parameter measurement temperature"),
IOPA( "di", CAP_MOD_DI, IF_REAL, "Relative dielectric constant"),
IOPA( "thick", CAP_MOD_THICK, IF_REAL, "Insulator thickness"),
+ IOP( "bv_max", CAP_MOD_BV_MAX, IF_REAL, "maximum voltage over capacitance"),
IP( "c", CAP_MOD_C, IF_FLAG, "Capacitor model")
};
diff --git a/src/spicelib/devices/cap/capask.c b/src/spicelib/devices/cap/capask.c
index 46ff8676b..f8afdebf4 100644
--- a/src/spicelib/devices/cap/capask.c
+++ b/src/spicelib/devices/cap/capask.c
@@ -48,6 +48,9 @@ CAPask(CKTcircuit *ckt, GENinstance *inst, int which, IFvalue *value,
case CAP_SCALE:
value->rValue = here->CAPscale;
return(OK);
+ case CAP_BV_MAX:
+ value->rValue = here->CAPbv_max;
+ return(OK);
case CAP_M:
value->rValue = here->CAPm;
return(OK);
diff --git a/src/spicelib/devices/cap/capdefs.h b/src/spicelib/devices/cap/capdefs.h
index 09ebf9fa9..c9acb9158 100644
--- a/src/spicelib/devices/cap/capdefs.h
+++ b/src/spicelib/devices/cap/capdefs.h
@@ -37,6 +37,7 @@ typedef struct sCAPinstance {
double CAPm; /* parallel multiplier */
double CAPtc1; /* first temperature coefficient of capacitors */
double CAPtc2; /* second temperature coefficient of capacitors */
+ double CAPbv_max; /* Maximum capacitor voltage */
double *CAPposPosptr; /* pointer to sparse matrix diagonal at
* (positive,positive) */
@@ -56,6 +57,7 @@ typedef struct sCAPinstance {
unsigned CAPmGiven : 1; /* flag to indicate parallel multiplier given */
unsigned CAPtc1Given : 1; /* flag indicates tc1 was specified */
unsigned CAPtc2Given : 1; /* flag indicates tc2 was specified */
+ unsigned CAPbv_maxGiven : 1; /* flags indicates maximum voltage is given */
int CAPsenParmNo; /* parameter # for sensitivity use;
set equal to 0 if not a design parameter*/
@@ -91,6 +93,7 @@ typedef struct sCAPmodel { /* model structure for a capacitor */
double CAPdel; /* amount by which length and width are less than drawn */
double CAPdi; /* Relative dielectric constant */
double CAPthick; /* Insulator thickness */
+ double CAPbv_max; /* Maximum capacitor voltage */
unsigned CAPmCapGiven : 1; /* flag indicates default capacitance given */
unsigned CAPcjGiven : 1; /* Unit Area Capacitance ( F/ M**2 ) */
unsigned CAPcjswGiven : 1; /* Unit Length Sidewall Capacitance( F/M )*/
@@ -104,6 +107,7 @@ typedef struct sCAPmodel { /* model structure for a capacitor */
unsigned CAPtc2Given : 1; /* flag indicates tc2 was specified */
unsigned CAPdiGiven : 1; /* flag indicates epsilon-ins given */
unsigned CAPthickGiven : 1; /* flags indicates insulator thickness given */
+ unsigned CAPbv_maxGiven : 1; /* flags indicates maximum voltage is given */
} CAPmodel;
@@ -121,6 +125,7 @@ typedef struct sCAPmodel { /* model structure for a capacitor */
#define CAP_M 11
#define CAP_TC1 12
#define CAP_TC2 13
+#define CAP_BV_MAX 14
/* model parameters */
#define CAP_MOD_CJ 101
@@ -137,6 +142,7 @@ typedef struct sCAPmodel { /* model structure for a capacitor */
#define CAP_MOD_THICK 112
#define CAP_MOD_CAP 113
#define CAP_MOD_DEFLENGTH 114
+#define CAP_MOD_BV_MAX 115
/* device questions */
#define CAP_QUEST_SENS_REAL 201
diff --git a/src/spicelib/devices/cap/capext.h b/src/spicelib/devices/cap/capext.h
index 4fd5c6d0d..d128959c4 100644
--- a/src/spicelib/devices/cap/capext.h
+++ b/src/spicelib/devices/cap/capext.h
@@ -22,4 +22,5 @@ extern int CAPsUpdate(GENmodel*,CKTcircuit*);
extern int CAPsetup(SMPmatrix*,GENmodel*,CKTcircuit*,int*);
extern int CAPtemp(GENmodel*,CKTcircuit*);
extern int CAPtrunc(GENmodel*,CKTcircuit*,double*);
+extern int CAPsoaCheck(CKTcircuit *, GENmodel *);
diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c
index 2cb9b4eff..1c8bb5126 100644
--- a/src/spicelib/devices/cap/capinit.c
+++ b/src/spicelib/devices/cap/capinit.c
@@ -66,7 +66,7 @@ SPICEdev CAPinfo = {
/* DEVsenTrunc */ NULL,
/* DEVdisto */ NULL, /* DISTO */
/* DEVnoise */ NULL, /* NOISE */
- /* DEVsoaCheck */ NULL,
+ /* DEVsoaCheck */ CAPsoaCheck,
#ifdef CIDER
/* DEVdump */ NULL,
/* DEVacct */ NULL,
diff --git a/src/spicelib/devices/cap/capmask.c b/src/spicelib/devices/cap/capmask.c
index 8f8c5ebe4..ce70aacc2 100644
--- a/src/spicelib/devices/cap/capmask.c
+++ b/src/spicelib/devices/cap/capmask.c
@@ -63,6 +63,9 @@ CAPmAsk(CKTcircuit *ckt, GENmodel *inst, int which, IFvalue *value)
case CAP_MOD_THICK:
value->rValue = here->CAPthick;
return(OK);
+ case CAP_MOD_BV_MAX:
+ value->rValue = here->CAPbv_max;
+ return(OK);
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/cap/capmpar.c b/src/spicelib/devices/cap/capmpar.c
index f7fefd1d9..044ce9c13 100644
--- a/src/spicelib/devices/cap/capmpar.c
+++ b/src/spicelib/devices/cap/capmpar.c
@@ -70,6 +70,10 @@ CAPmParam(int param, IFvalue *value, GENmodel *inModel)
mod->CAPthick = value->rValue;
mod->CAPthickGiven = TRUE;
break;
+ case CAP_MOD_BV_MAX:
+ mod->CAPbv_max = value->rValue;
+ mod->CAPbv_maxGiven = TRUE;
+ break;
case CAP_MOD_C:
/* just being reassured by the user that we are a capacitor */
/* no-op */
diff --git a/src/spicelib/devices/cap/capparam.c b/src/spicelib/devices/cap/capparam.c
index 7ebf478cc..003ebc2bb 100644
--- a/src/spicelib/devices/cap/capparam.c
+++ b/src/spicelib/devices/cap/capparam.c
@@ -73,6 +73,10 @@ CAPparam(int param, IFvalue *value, GENinstance *inst, IFvalue *select)
here->CAPtc2 = value->rValue;
here->CAPtc2Given = TRUE;
break;
+ case CAP_BV_MAX:
+ here->CAPbv_max = value->rValue;
+ here->CAPbv_maxGiven = TRUE;
+ break;
default:
return(E_BADPARM);
}
diff --git a/src/spicelib/devices/cap/capsetup.c b/src/spicelib/devices/cap/capsetup.c
index f41c85fdf..6d2bbdc55 100644
--- a/src/spicelib/devices/cap/capsetup.c
+++ b/src/spicelib/devices/cap/capsetup.c
@@ -64,6 +64,9 @@ CAPsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if (!model->CAPthickGiven) {
model->CAPthick = 0.0;
}
+ if (!model->CAPbv_maxGiven) {
+ model->CAPbv_max = 1e99;
+ }
if (!model->CAPcjGiven) {
if((model->CAPthickGiven)
@@ -92,6 +95,9 @@ CAPsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states)
if (!here->CAPlengthGiven) {
here->CAPlength = 0;
}
+ if (!here->CAPbv_maxGiven) {
+ here->CAPbv_max = model->CAPbv_max;
+ }
here->CAPqcap = *states;
*states += 2;
diff --git a/src/spicelib/devices/cap/capsoachk.c b/src/spicelib/devices/cap/capsoachk.c
new file mode 100644
index 000000000..17172a832
--- /dev/null
+++ b/src/spicelib/devices/cap/capsoachk.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 "capdefs.h"
+#include "ngspice/trandefs.h"
+#include "ngspice/sperror.h"
+#include "ngspice/suffix.h"
+#include "ngspice/cpdefs.h"
+
+
+int
+CAPsoaCheck(CKTcircuit *ckt, GENmodel *inModel)
+{
+ CAPmodel *model = (CAPmodel *) inModel;
+ CAPinstance *here;
+ double vc; /* current capacitor voltage */
+ int maxwarns;
+ static int warns_bv = 0;
+
+ if (!ckt) {
+ warns_bv = 0;
+ return OK;
+ }
+
+ maxwarns = ckt->CKTsoaMaxWarns;
+
+ for (; model; model = model->CAPnextModel) {
+
+ for (here = model->CAPinstances; here; here = here->CAPnextInstance) {
+
+ vc = fabs(ckt->CKTrhsOld [here->CAPposNode] -
+ ckt->CKTrhsOld [here->CAPnegNode]);
+
+ if (vc > here->CAPbv_max)
+ if (warns_bv < maxwarns) {
+ soa_printf(ckt, (GENinstance*) here,
+ "|Vc|=%g has exceeded Bv_max=%g\n",
+ vc, here->CAPbv_max);
+ warns_bv++;
+ }
+
+ }
+
+ }
+
+ return OK;
+}
diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj
index 172f03892..24c254df4 100644
--- a/visualc/vngspice.vcproj
+++ b/visualc/vngspice.vcproj
@@ -4516,6 +4516,10 @@
RelativePath="..\src\spicelib\devices\cap\capsload.c"
>
+
+