From 542bb9cd26256ff1f66f4d97788dd9cd48c35eed Mon Sep 17 00:00:00 2001 From: dwarning Date: Wed, 30 Oct 2013 20:08:57 +0100 Subject: [PATCH] devices/cap, implement CAPsoaCheck() --- src/spicelib/devices/cap/Makefile.am | 1 + src/spicelib/devices/cap/cap.c | 2 ++ src/spicelib/devices/cap/capask.c | 3 ++ src/spicelib/devices/cap/capdefs.h | 6 ++++ src/spicelib/devices/cap/capext.h | 1 + src/spicelib/devices/cap/capinit.c | 2 +- src/spicelib/devices/cap/capmask.c | 3 ++ src/spicelib/devices/cap/capmpar.c | 4 +++ src/spicelib/devices/cap/capparam.c | 4 +++ src/spicelib/devices/cap/capsetup.c | 6 ++++ src/spicelib/devices/cap/capsoachk.c | 51 ++++++++++++++++++++++++++++ visualc/vngspice.vcproj | 4 +++ 12 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/spicelib/devices/cap/capsoachk.c 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" > + +