From d44eeb05a4c05fe9ef5e73a5e8f98f3082c4887b Mon Sep 17 00:00:00 2001 From: dwarning Date: Fri, 1 Nov 2013 21:49:16 +0100 Subject: [PATCH] devices/bjt, implement BJTsoaCheck() --- src/spicelib/devices/bjt/Makefile.am | 1 + src/spicelib/devices/bjt/bjt.c | 5 +- src/spicelib/devices/bjt/bjtdefs.h | 9 ++++ src/spicelib/devices/bjt/bjtext.h | 1 + src/spicelib/devices/bjt/bjtinit.c | 2 +- src/spicelib/devices/bjt/bjtmask.c | 9 ++++ src/spicelib/devices/bjt/bjtmpar.c | 12 +++++ src/spicelib/devices/bjt/bjtsetup.c | 9 ++++ src/spicelib/devices/bjt/bjtsoachk.c | 72 ++++++++++++++++++++++++++++ visualc/vngspice.vcproj | 4 ++ 10 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 src/spicelib/devices/bjt/bjtsoachk.c diff --git a/src/spicelib/devices/bjt/Makefile.am b/src/spicelib/devices/bjt/Makefile.am index 8b4ab3664..47aa59d69 100644 --- a/src/spicelib/devices/bjt/Makefile.am +++ b/src/spicelib/devices/bjt/Makefile.am @@ -28,6 +28,7 @@ libbjt_la_SOURCES = \ bjtsacl.c \ bjtsetup.c \ bjtsload.c \ + bjtsoachk.c \ bjtsprt.c \ bjtsset.c \ bjtsupd.c \ diff --git a/src/spicelib/devices/bjt/bjt.c b/src/spicelib/devices/bjt/bjt.c index 2ddcb7de6..134c4705e 100644 --- a/src/spicelib/devices/bjt/bjt.c +++ b/src/spicelib/devices/bjt/bjt.c @@ -212,7 +212,10 @@ IFparm BJTmPTable[] = { /* model parameters */ IOP("tise1", BJT_MOD_TISE1, IF_REAL, "ISE 1. temperature coefficient"), IOP("tise2", BJT_MOD_TISE2, IF_REAL, "ISE 2. temperature coefficient"), IOP("tisc1", BJT_MOD_TISC1, IF_REAL, "ISC 1. temperature coefficient"), - IOP("tisc2", BJT_MOD_TISC2, IF_REAL, "ISC 2. temperature coefficient") + IOP("tisc2", BJT_MOD_TISC2, IF_REAL, "ISC 2. temperature coefficient"), + IOP("vbe_max", BJT_MOD_VBE_MAX, IF_REAL, "maximum voltage B-E junction"), + IOP("vbc_max", BJT_MOD_VBC_MAX, IF_REAL, "maximum voltage B-C junction"), + IOP("vce_max", BJT_MOD_VCE_MAX, IF_REAL, "maximum voltage C-E branch") }; char *BJTnames[] = { diff --git a/src/spicelib/devices/bjt/bjtdefs.h b/src/spicelib/devices/bjt/bjtdefs.h index b11ce3112..7e4c84727 100644 --- a/src/spicelib/devices/bjt/bjtdefs.h +++ b/src/spicelib/devices/bjt/bjtdefs.h @@ -448,6 +448,9 @@ typedef struct sBJTmodel { /* model structure for a bjt */ double BJTtise2; double BJTtisc1; double BJTtisc2; + double BJTvbeMax; /* maximum voltage over B-E junction */ + double BJTvbcMax; /* maximum voltage over B-C junction */ + double BJTvceMax; /* maximum voltage over C-E branch */ unsigned BJTsubsGiven : 1; unsigned BJTtnomGiven : 1; @@ -554,6 +557,9 @@ typedef struct sBJTmodel { /* model structure for a bjt */ unsigned BJTtise2Given : 1; unsigned BJTtisc1Given : 1; unsigned BJTtisc2Given : 1; + unsigned BJTvbeMaxGiven : 1; + unsigned BJTvbcMaxGiven : 1; + unsigned BJTvceMaxGiven : 1; } BJTmodel; #ifndef NPN @@ -691,6 +697,9 @@ typedef struct sBJTmodel { /* model structure for a bjt */ #define BJT_MOD_TISE2 205 #define BJT_MOD_TISC1 206 #define BJT_MOD_TISC2 207 +#define BJT_MOD_VBE_MAX 208 +#define BJT_MOD_VBC_MAX 209 +#define BJT_MOD_VCE_MAX 210 /* device questions */ #define BJT_QUEST_FT 211 diff --git a/src/spicelib/devices/bjt/bjtext.h b/src/spicelib/devices/bjt/bjtext.h index 69e5c3322..16655610f 100644 --- a/src/spicelib/devices/bjt/bjtext.h +++ b/src/spicelib/devices/bjt/bjtext.h @@ -31,5 +31,6 @@ extern int BJTtrunc(GENmodel*,CKTcircuit*,double*); extern int BJTdisto(int,GENmodel*,CKTcircuit*); extern int BJTnoise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BJTdSetup(GENmodel*, register CKTcircuit*); +extern int BJTsoaCheck(CKTcircuit *, GENmodel *); #endif diff --git a/src/spicelib/devices/bjt/bjtinit.c b/src/spicelib/devices/bjt/bjtinit.c index b601a566a..dc5e025b1 100644 --- a/src/spicelib/devices/bjt/bjtinit.c +++ b/src/spicelib/devices/bjt/bjtinit.c @@ -67,7 +67,7 @@ SPICEdev BJTinfo = { /* description from struct IFdevice */ /* DEVsenTrunc */ NULL, /* DEVdisto */ BJTdisto, /* DEVnoise */ BJTnoise, - /* DEVsoaCheck */ NULL, + /* DEVsoaCheck */ BJTsoaCheck, #ifdef CIDER /* DEVdump */ NULL, /* DEVacct */ NULL, diff --git a/src/spicelib/devices/bjt/bjtmask.c b/src/spicelib/devices/bjt/bjtmask.c index adc83bae1..87a22d7fa 100644 --- a/src/spicelib/devices/bjt/bjtmask.c +++ b/src/spicelib/devices/bjt/bjtmask.c @@ -378,6 +378,15 @@ BJTmAsk(CKTcircuit *ckt, GENmodel *instPtr, int which, IFvalue *value) case BJT_MOD_TISC2: value->rValue = here->BJTtisc2; return(OK); + case BJT_MOD_VBE_MAX: + value->rValue = here->BJTvbeMax; + return(OK); + case BJT_MOD_VBC_MAX: + value->rValue = here->BJTvbcMax; + return(OK); + case BJT_MOD_VCE_MAX: + value->rValue = here->BJTvceMax; + return(OK); default: return(E_BADPARM); } diff --git a/src/spicelib/devices/bjt/bjtmpar.c b/src/spicelib/devices/bjt/bjtmpar.c index 1d55c13c4..d917aabee 100644 --- a/src/spicelib/devices/bjt/bjtmpar.c +++ b/src/spicelib/devices/bjt/bjtmpar.c @@ -454,6 +454,18 @@ BJTmParam(int param, IFvalue *value, GENmodel *inModel) mods->BJTtisc2 = value->rValue; mods->BJTtisc2Given = TRUE; break; + case BJT_MOD_VBE_MAX: + mods->BJTvbeMax = value->rValue; + mods->BJTvbeMaxGiven = TRUE; + break; + case BJT_MOD_VBC_MAX: + mods->BJTvbcMax = value->rValue; + mods->BJTvbcMaxGiven = TRUE; + break; + case BJT_MOD_VCE_MAX: + mods->BJTvceMax = value->rValue; + mods->BJTvceMaxGiven = TRUE; + break; default: return(E_BADPARM); } diff --git a/src/spicelib/devices/bjt/bjtsetup.c b/src/spicelib/devices/bjt/bjtsetup.c index 0ca183775..a66ac7399 100644 --- a/src/spicelib/devices/bjt/bjtsetup.c +++ b/src/spicelib/devices/bjt/bjtsetup.c @@ -322,6 +322,15 @@ BJTsetup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt, int *states) if(!model->BJTtisc2Given) { model->BJTtisc2 = 0.0; } + if(!model->BJTvbeMaxGiven) { + model->BJTvbeMax = 1e99; + } + if(!model->BJTvbcMaxGiven) { + model->BJTvbcMax = 1e99; + } + if(!model->BJTvceMaxGiven) { + model->BJTvceMax = 1e99; + } /* * COMPATABILITY WARNING! diff --git a/src/spicelib/devices/bjt/bjtsoachk.c b/src/spicelib/devices/bjt/bjtsoachk.c new file mode 100644 index 000000000..31cad7952 --- /dev/null +++ b/src/spicelib/devices/bjt/bjtsoachk.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 "bjtdefs.h" +#include "ngspice/trandefs.h" +#include "ngspice/sperror.h" +#include "ngspice/suffix.h" +#include "ngspice/cpdefs.h" + + +int +BJTsoaCheck(CKTcircuit *ckt, GENmodel *inModel) +{ + BJTmodel *model = (BJTmodel *) inModel; + BJTinstance *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->BJTnextModel) { + + for (here = model->BJTinstances; here; here=here->BJTnextInstance) { + + vbe = fabs(ckt->CKTrhsOld [here->BJTbasePrimeNode] - + ckt->CKTrhsOld [here->BJTemitPrimeNode]); + vbc = fabs(ckt->CKTrhsOld [here->BJTbasePrimeNode] - + ckt->CKTrhsOld [here->BJTcolPrimeNode]); + vce = fabs(ckt->CKTrhsOld [here->BJTcolPrimeNode] - + ckt->CKTrhsOld [here->BJTemitPrimeNode]); + + if (vbe > model->BJTvbeMax) + if (warns_vbe < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbe|=%g has exceeded Vbe_max=%g\n", + vbe, model->BJTvbeMax); + warns_vbe++; + } + + if (vbc > model->BJTvbcMax) + if (warns_vbc < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vbc|=%g has exceeded Vbc_max=%g\n", + vbc, model->BJTvbcMax); + warns_vbc++; + } + + if (vce > model->BJTvceMax) + if (warns_vce < maxwarns) { + soa_printf(ckt, (GENinstance*) here, + "|Vce|=%g has exceeded Vce_max=%g\n", + vce, model->BJTvceMax); + warns_vce++; + } + + } + } + + return OK; +} diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index 704356b79..7cf5d461c 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -4380,6 +4380,10 @@ RelativePath="..\src\spicelib\devices\bjt\bjtsload.c" > + +