diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 485909546..67454df70 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -767,6 +767,8 @@ inp_dodeck( bool noparse, ii; int print_listing; bool have_err = FALSE; + int warn; /* whether SOA check should be performed */ + int maxwarns = 0; /* specifies the maximum number of SOA warnings */ double startTime; /* First throw away any old error messages there might be and fix @@ -859,6 +861,16 @@ inp_dodeck( /* set some output terminal data */ out_init(); + if (cp_getvar("warn", CP_NUM, &warn)) + ckt->CKTsoaCheck = warn; + else + ckt->CKTsoaCheck = 0; + + if (cp_getvar("maxwarns", CP_NUM, &maxwarns)) + ckt->CKTsoaMaxWarns = maxwarns; + else + ckt->CKTsoaMaxWarns = 5; + ft_curckt->FTEstats->FTESTATdeckNumLines = 0; /*---------------------------------------------------- Now run through the deck and look to see if there are diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index 18eeed2f5..f1bcfd69d 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -282,6 +282,9 @@ struct CKTcircuit { contains only linear elements */ unsigned int CKTnoopac:1; /* flag to indicate that OP will not be evaluated during AC simulation */ + int CKTsoaCheck; /* flag to indicate that in certain device models + a safe operating area (SOA) check is executed */ + int CKTsoaMaxWarns; /* specifies the maximum number of SOA warnings */ NGHASHPTR DEVnameHash; NGHASHPTR MODnameHash; @@ -314,6 +317,7 @@ extern int CKTdltNNum(CKTcircuit *, int); extern int CKTdltNod(CKTcircuit *, CKTnode *); extern int CKTdoJob(CKTcircuit *, int , TSKtask *); extern void CKTdump(CKTcircuit *, double, void *); +extern int CKTsoaCheck(CKTcircuit *); #ifdef CIDER extern void NDEVacct(CKTcircuit *ckt, FILE *file); #endif /* CIDER */ diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 7ff9b99ee..4434159de 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -290,6 +290,9 @@ extern void SetAnalyse(char *analyse, int percent); #endif + +void soa_printf(CKTcircuit *ckt, GENinstance *instance, const char *fmt, ...); + /* macro to ignore unused variables and parameters */ #define NG_IGNORE(x) (void)x #define NG_IGNOREABLE(x) (void)x diff --git a/src/main.c b/src/main.c index 7db4af0eb..ff4cd5e43 100644 --- a/src/main.c +++ b/src/main.c @@ -102,6 +102,8 @@ char *ft_rawfile = "rawspice.raw"; FILE *flogp = NULL; /* log file ('-o logfile' command line option) */ #endif +FILE *slogp = NULL; /* soa log file ('--soa-log file' command line option) */ + /* Frontend and circuit options */ IFsimulator *ft_sim = NULL; @@ -674,6 +676,7 @@ show_help(void) " -p, --pipe run in I/O pipe mode\n" " -q, --completion activate command completion\n" " -r, --rawfile=FILE set the rawfile output\n" + " --soa-log=FILE set the outputfile for SOA warnings\n" " -s, --server run spice as a server process\n" " -t, --term=TERM set the terminal type\n" " -h, --help display this help and exit\n" @@ -793,6 +796,7 @@ int main(int argc, char **argv) { char log_file[BSIZE_SP]; + char soa_log_file[BSIZE_SP]; volatile bool readinit = TRUE; bool istty = TRUE; bool iflag = FALSE; @@ -800,6 +804,7 @@ main(int argc, char **argv) FILE * volatile circuit_file; bool orflag = FALSE; + bool srflag = FALSE; #ifdef TRACE /* this is used to detect memory leaks during debugging */ @@ -859,6 +864,7 @@ main(int argc, char **argv) /* --- Process command line options --- */ for(;;) { + enum { soa_log = 1001, }; static struct option long_options[] = { {"help", no_argument, 0, 'h'}, @@ -874,6 +880,7 @@ main(int argc, char **argv) {"rawfile", required_argument, 0, 'r'}, {"server", no_argument, 0, 's'}, {"terminal", required_argument, 0, 't'}, + {"soa-log", required_argument, 0, soa_log}, {0, 0, 0, 0} }; @@ -964,6 +971,13 @@ main(int argc, char **argv) cp_vset("term", CP_STRING, optarg); break; + case soa_log: + if (optarg) { + sprintf (soa_log_file, "%s", optarg); + srflag = TRUE; + } + break; + case '?': break; @@ -1007,6 +1021,18 @@ main(int argc, char **argv) #endif } /* orflag */ + if (srflag) { /* --soa-log option has been set */ + + fprintf(stdout, "\nSOA warnings go to log-file: %s\n", soa_log_file); + + /* Open the soa log file */ + slogp = fopen(soa_log_file, "w"); + if (!slogp) { + perror (soa_log_file); + sp_shutdown (EXIT_BAD); + } + } /* srflag */ + #ifdef SIMULATOR if_getparam = spif_getparam_special; #else diff --git a/src/spicelib/analysis/dcop.c b/src/spicelib/analysis/dcop.c index 1e33a6bfa..81b21f579 100644 --- a/src/spicelib/analysis/dcop.c +++ b/src/spicelib/analysis/dcop.c @@ -156,6 +156,9 @@ DCop(CKTcircuit *ckt, int notused) CKTdump(ckt, 0.0, plot); + if (ckt->CKTsoaCheck) + error = CKTsoaCheck(ckt); + if(g_ipc.enabled) ipc_send_dcop_suffix(); @@ -163,6 +166,8 @@ DCop(CKTcircuit *ckt, int notused) #else if(converged == 0) { CKTdump(ckt, 0.0, plot); + if (ckt->CKTsoaCheck) + error = CKTsoaCheck(ckt); } else { fprintf(stderr,"error: circuit reload failed.\n"); } diff --git a/src/spicelib/analysis/dctran.c b/src/spicelib/analysis/dctran.c index eddf96270..30252d17c 100644 --- a/src/spicelib/analysis/dctran.c +++ b/src/spicelib/analysis/dctran.c @@ -396,6 +396,9 @@ DCtran(CKTcircuit *ckt, /* check if current breakpoint is outdated; if so, clear */ if (ckt->CKTtime > ckt->CKTbreaks[0]) CKTclrBreak(ckt); + if (ckt->CKTsoaCheck) + error = CKTsoaCheck(ckt); + /* * Breakpoint handling scheme: * When a timepoint t is accepted (by CKTaccept), clear all previous diff --git a/src/spicelib/analysis/dctrcurv.c b/src/spicelib/analysis/dctrcurv.c index 1188d5a8d..23e021758 100644 --- a/src/spicelib/analysis/dctrcurv.c +++ b/src/spicelib/analysis/dctrcurv.c @@ -477,6 +477,9 @@ resume: CKTdump(ckt,ckt->CKTtime,plot); + if (ckt->CKTsoaCheck) + error = CKTsoaCheck(ckt); + #ifdef XSPICE if(g_ipc.enabled) ipc_send_data_suffix(); diff --git a/src/spicelib/devices/Makefile.am b/src/spicelib/devices/Makefile.am index 9885998a1..e5a9a5afe 100644 --- a/src/spicelib/devices/Makefile.am +++ b/src/spicelib/devices/Makefile.am @@ -130,6 +130,7 @@ libdev_la_SOURCES = \ cktcrte.c \ cktfinddev.c \ cktinit.c \ + cktsoachk.c \ limit.c EXTRA_DIST = @NOTVLADEVDIR@ diff --git a/src/spicelib/devices/cktsoachk.c b/src/spicelib/devices/cktsoachk.c new file mode 100644 index 000000000..259aaa0a3 --- /dev/null +++ b/src/spicelib/devices/cktsoachk.c @@ -0,0 +1,38 @@ +/********** +Copyright 2013 Dietmar Warning. All rights reserved. +Author: 2013 Dietmar Warning +**********/ + +/* + * This is a driver program to iterate through all the various SOA check + * functions provided for the circuit elements in the given circuit */ + +#include "ngspice/config.h" +#include "ngspice/devdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/ifsim.h" +#include "ngspice/devdefs.h" + +#include "dev.h" + + +int +CKTsoaCheck(CKTcircuit *ckt) +{ + int i, error; + + if (ckt->CKTmode & (MODEDC | MODEDCOP | MODEDCTRANCURVE | MODETRAN | MODETRANOP)) { + + SPICEdev **devs = devices(); + + for (i = 0; i < DEVmaxnum; i++) { + if (devs[i] && devs[i]->DEVsoaCheck && ckt->CKThead[i]) { + error = devs[i]->DEVsoaCheck (ckt, ckt->CKThead[i]); + if (error) + return error; + } + } + } + + return OK; +} diff --git a/src/spicelib/devices/devsup.c b/src/spicelib/devices/devsup.c index 6249344b4..dbc6c21cc 100644 --- a/src/spicelib/devices/devsup.c +++ b/src/spicelib/devices/devsup.c @@ -11,6 +11,9 @@ Modified: 2000 AlansFixes #include "ngspice/cktdefs.h" #include "ngspice/suffix.h" +#include + + /* * Limit the per-iteration change of VDS */ @@ -770,3 +773,28 @@ DEVpred(CKTcircuit *ckt, int loct) ( xfact * *(ckt->CKTstate2+loct) ) ); #endif /* NEWTRUNC */ } + + +/* SOA check printout used in DEVsoaCheck functions */ +extern FILE *slogp; /* soa log file ('--soa-log file' command line option) */ + +void +soa_printf(CKTcircuit *ckt, GENinstance *instance, const char *fmt, ...) +{ + FILE *fp = slogp ? slogp : stdout; + + va_list ap; + + va_start(ap, fmt); + + if (ckt->CKTmode & MODETRAN) + fprintf(fp, "Instance: %s Model: %s Time: %g ", + instance->GENname, instance->GENmodPtr->GENmodName, ckt->CKTtime); + else + fprintf(fp, "Instance: %s Model: %s ", + instance->GENname, instance->GENmodPtr->GENmodName); + + vfprintf(fp, fmt, ap); + + va_end(ap); +} diff --git a/visualc/vngspice.vcproj b/visualc/vngspice.vcproj index 9ecf12632..953f8e9a6 100644 --- a/visualc/vngspice.vcproj +++ b/visualc/vngspice.vcproj @@ -4896,6 +4896,10 @@ RelativePath="..\src\spicelib\analysis\cktsgen.c" > + +