diff --git a/Makefile.am b/Makefile.am index 91e8c77d6..19225aa1c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ EXTRA_DIST = FAQ autogen.sh Stuarts_Poly_Notes \ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 ar-lib compile config.guess \ src/include/ngspice/config.h.in config.sub configure install-sh \ missing mkinstalldirs stamp-h.in ltconfig \ - ltmain.sh depcomp ylwrap + ltmain.sh depcomp ylwrap test-driver ACLOCAL_AMFLAGS = -I m4 diff --git a/configure.ac b/configure.ac index c388bd172..dfd680523 100644 --- a/configure.ac +++ b/configure.ac @@ -153,6 +153,10 @@ AC_ARG_ENABLE([adms], AC_ARG_ENABLE([pss], [AS_HELP_STRING([--enable-pss], [Enable PSS Analysis, (experimental)])]) +# --enable-relan: Enable Reliability Analysis +AC_ARG_ENABLE([relan], + [AS_HELP_STRING([--enable-relan], [Enable Reliability Analysis, (experimental)])]) + # --enable-ndev: define NDEV in the code. An interface for external device i.e. numerical device AC_ARG_ENABLE([ndev], [AS_HELP_STRING([--enable-ndev], [Enable NDEV interface, (experimental)])]) @@ -847,6 +851,10 @@ if test "x$enable_pss" = xyes; then AC_DEFINE([WITH_PSS], [], [Define if you want PSS analysis]) AC_MSG_RESULT([WARNING: PSS analysis enabled]) fi +if test "x$enable_relan" = xyes; then + AC_DEFINE([RELAN], [], [Define if you want Reliability Analysis]) + AC_MSG_RESULT([WARNING: Reliability Analysis enabled]) +fi if test "x$enable_blktmsdebug" = xyes; then AC_DEFINE([D_DBG_BLOCKTIMES], [], [Define if we want debug distortion analysis (BLOCKTIMES)]) AC_MSG_RESULT([WARNING: Distortion analysis debug *D_DBG_BLOCKTIMES* is enabled]) @@ -934,6 +942,8 @@ AM_CONDITIONAL([NUMDEV_WANTED], [test "x$enable_cider" = xyes]) AM_CONDITIONAL([PSS_WANTED], [test "x$enable_pss" = xyes]) +AM_CONDITIONAL([RELAN_WANTED], [test "x$enable_relan" = xyes]) + AM_CONDITIONAL([SENSE2_WANTED], [test "x$enable_sense2" = xyes]) # adms option diff --git a/src/frontend/commands.c b/src/frontend/commands.c index bec672c31..1ef977e9c 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -287,6 +287,14 @@ struct comm spcp_coms[] = { "[.pss line args] : Do a periodic state analysis." } , /* SP */ #endif + +#ifdef RELAN + { "relan", com_relan, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + NULL, + "[.relan line args] : Do a Reliability Analysis." } , +#endif + { "ac", com_ac, TRUE, TRUE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, NULL, @@ -718,6 +726,14 @@ struct comm nutcp_coms[] = { "[.pss line args] : Do a periodic steady state analysis." } , /* SP */ #endif + +#ifdef RELAN + { "relan", NULL, TRUE, TRUE, + { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, + NULL, + "[.relan line args] : Do a Reliability Analysis." } , +#endif + { "ac", NULL, TRUE, TRUE, { 0, 0, 0, 0 }, E_DEFHMASK, 0, LOTS, NULL, diff --git a/src/frontend/runcoms.c b/src/frontend/runcoms.c index 475c25ead..10df7ea06 100644 --- a/src/frontend/runcoms.c +++ b/src/frontend/runcoms.c @@ -186,6 +186,15 @@ com_pss(wordlist *wl) #endif +#ifdef RELAN +void +com_relan (wordlist *wl) +{ + dosim ("relan", wl) ; +} +#endif + + static int dosim( char *what, /* in: command (pz,op,dc,ac,tf,tran,sens,disto,noise,run) */ diff --git a/src/frontend/runcoms.h b/src/frontend/runcoms.h index 714239e50..d4b7ebd68 100644 --- a/src/frontend/runcoms.h +++ b/src/frontend/runcoms.h @@ -16,6 +16,11 @@ void com_tran(wordlist *wl); /* SP: Stady State Analysis */ void com_pss(wordlist *wl); /* SP */ + +#ifdef RELAN +void com_relan (wordlist *wl) ; +#endif + void com_sens(wordlist *wl); void com_disto(wordlist *wl); void com_noise(wordlist *wl); diff --git a/src/frontend/shyu.c b/src/frontend/shyu.c index ef2f65a9f..8bc77cbb6 100644 --- a/src/frontend/shyu.c +++ b/src/frontend/shyu.c @@ -314,6 +314,70 @@ if_sens_run(CKTcircuit *ckt, wordlist *args, INPtables *tab) } #endif +#ifdef RELAN + if (strcmp (token, "relan") == 0) + { + JOB *relanJob ; + which = ft_find_analysis ("RELAN") ; + if (which == -1) + { + current->error = INPerrCat (current->error, INPmkTemp ("Reliability Analysis Unsupported\n")) ; + return (0) ; /* temporary */ + } + err = ft_sim->newAnalysis (ft_curckt->ci_ckt, which, "relan", &relanJob, ft_curckt->ci_specTask) ; + if (err) + { + ft_sperror(err, "createRELAN") ; + return (0) ; + } + + parm = INPgetValue (ckt, &line, IF_REAL, tab) ; + error = INPapName (ckt, which, relanJob, "relan_aging_step", parm) ; + if (error) + { + current->error = INPerrCat (current->error, INPerror (error)) ; + } + + parm = INPgetValue (ckt, &line, IF_REAL, tab) ; + error = INPapName (ckt, which, relanJob, "relan_aging_stop", parm) ; + if (error) + { + current->error = INPerrCat (current->error, INPerror (error)) ; + } + + if (*line) + { + if (*line == 'd') + { + goto next ; + } else if (*line == 'u') { + goto uic_relan ; + } + parm = INPgetValue (ckt, &line, IF_REAL, tab) ; /* AgingStart */ + error = INPapName (ckt, which, relanJob, "relan_aging_start", parm) ; + if (error) + { + current->error = INPerrCat (current->error, INPerror (error)) ; + } + + uic_relan: + if (*line == 'u') + { + INPgetTok (&line, &name, 1) ; + if (strcmp (name, "uic") == 0) + { + ptemp.iValue = 1 ; + error = INPapName (ckt, which, relanJob, "uic", &ptemp) ; + if (error) + { + current->error = INPerrCat (current->error, INPerror (error)) ; + } + } + } + } + } +#endif + next: while (*line) { /* read the entire line */ diff --git a/src/frontend/spiceif.c b/src/frontend/spiceif.c index 335bf596e..6f221eb69 100644 --- a/src/frontend/spiceif.c +++ b/src/frontend/spiceif.c @@ -219,6 +219,11 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab) || eq(what, "pss") /* SP */ #endif + +#ifdef RELAN + || eq (what, "relan") +#endif + ) { s = wl_flatten(args); /* va: tfree char's tmalloc'ed in wl_flatten */ @@ -334,6 +339,11 @@ if_run(CKTcircuit *ckt, char *what, wordlist *args, INPtables *tab) (eq(what, "pss")) || /* SP */ #endif + +#ifdef RELAN + (eq (what, "relan")) || +#endif + (eq(what, "run"))) { /*CDHW Run the analysis pointed to by ci_curTask CDHW*/ diff --git a/src/frontend/typesdef.c b/src/frontend/typesdef.c index c03db0378..a4c5c6693 100644 --- a/src/frontend/typesdef.c +++ b/src/frontend/typesdef.c @@ -79,6 +79,11 @@ struct plotab plotabs[NUMPLOTTYPES] = { { "harm", "harm" }, { "spect", "spect" }, { "pss", "periodic" }, + +#ifdef RELAN + { "relan", "reliability" } +#endif + }; int notypes = 19; diff --git a/src/include/ngspice/Makefile.am b/src/include/ngspice/Makefile.am index 216816ef8..7fd5d7800 100644 --- a/src/include/ngspice/Makefile.am +++ b/src/include/ngspice/Makefile.am @@ -125,4 +125,9 @@ include_HEADERS = \ wallace.h \ wstdio.h +if RELAN_WANTED +include_HEADERS += \ + relandefs.h +endif + MAINTAINERCLEANFILES = Makefile.in diff --git a/src/include/ngspice/cktdefs.h b/src/include/ngspice/cktdefs.h index 5e907fb41..46e4e2cfa 100644 --- a/src/include/ngspice/cktdefs.h +++ b/src/include/ngspice/cktdefs.h @@ -278,6 +278,13 @@ struct CKTcircuit { /* SP: 100609 */ #endif +#ifdef RELAN + double CKTagingStartTime ; /* Reliability Analysis - Start Time */ + double CKTagingStep ; /* Reliability Analysis - Time Step */ + double CKTagingTotalTime ; /* Reliability Analysis - Stop Time */ + int CKTagingN ; /* Reliability Analysis - Number of Steps */ +#endif + unsigned int CKTisLinear:1; /* flag to indicate that the circuit contains only linear elements */ unsigned int CKTnoopac:1; /* flag to indicate that OP will not be evaluated @@ -416,6 +423,15 @@ extern int DCpss(CKTcircuit *, int); /* SP */ #endif +#ifdef RELAN +extern int RELANaskQuest (CKTcircuit *, JOB *, int, IFvalue *) ; +extern int RELANsetParm (CKTcircuit *, JOB *, int, IFvalue *) ; +extern int RELANinit (CKTcircuit *, JOB *) ; +extern int RELANanalysis (CKTcircuit *, int) ; +extern int CKTagingAdd (CKTcircuit *, int) ; +extern int CKTagingSetup (CKTcircuit *) ; +#endif + extern int NaskQuest(CKTcircuit *, JOB *, int, IFvalue *); extern int NsetParm(CKTcircuit *, JOB *, int, IFvalue *); extern int NIacIter(CKTcircuit *); diff --git a/src/include/ngspice/devdefs.h b/src/include/ngspice/devdefs.h index f9b89f989..efe647cd1 100644 --- a/src/include/ngspice/devdefs.h +++ b/src/include/ngspice/devdefs.h @@ -114,6 +114,11 @@ typedef struct SPICEdev { int *DEVinstSize; /* size of an instance */ int *DEVmodSize; /* size of a model */ +#ifdef RELAN + int (*DEVagingAdd)(GENmodel *, int) ; + int (*DEVagingSetup)(GENmodel *, CKTcircuit *) ; +#endif + } SPICEdev; /* instance of structure for each possible type of device */ diff --git a/src/include/ngspice/relandefs.h b/src/include/ngspice/relandefs.h new file mode 100644 index 000000000..02d9eedd7 --- /dev/null +++ b/src/include/ngspice/relandefs.h @@ -0,0 +1,28 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#ifndef ngspice_RELANDEFS_H +#define ngspice_RELANDEFS_H + +#include "ngspice/cktdefs.h" +#include "ngspice/jobdefs.h" +#include "ngspice/tskdefs.h" + +typedef struct { + int JOBtype ; + JOB *JOBnextJob ; + char *JOBname ; + double RELANagingStep ; + double RELANagingTotalTime ; + double RELANagingStartTime ; + long RELANmode ; + runDesc *RELANplot ; +} RELANan ; + +#define RELAN_AGING_STEP 1 +#define RELAN_AGING_STOP 2 +#define RELAN_AGING_START 3 +#define RELAN_UIC 4 + +#endif diff --git a/src/spicelib/analysis/Makefile.am b/src/spicelib/analysis/Makefile.am index 86d6b7371..1686ac8a9 100644 --- a/src/spicelib/analysis/Makefile.am +++ b/src/spicelib/analysis/Makefile.am @@ -107,6 +107,16 @@ libckt_la_SOURCES += \ endif +if RELAN_WANTED +libckt_la_SOURCES += \ + relanalysis.c \ + relanaskq.c \ + relaninit.c \ + relansetp.c \ + cktreliability.c +endif + + AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/spicelib/devices AM_CFLAGS = $(STATIC) MAINTAINERCLEANFILES = Makefile.in diff --git a/src/spicelib/analysis/analysis.c b/src/spicelib/analysis/analysis.c index ecb9279a6..a635b4035 100644 --- a/src/spicelib/analysis/analysis.c +++ b/src/spicelib/analysis/analysis.c @@ -24,8 +24,17 @@ extern SPICEanalysis PSSinfo; extern SPICEanalysis SEN2info; #endif +#ifdef RELAN +extern SPICEanalysis RELANinfo ; +#endif + SPICEanalysis *analInfo[] = { &OPTinfo, + +#ifdef RELAN + &RELANinfo, +#endif + &ACinfo, &DCTinfo, &DCOinfo, diff --git a/src/spicelib/analysis/cktdojob.c b/src/spicelib/analysis/cktdojob.c index 8b995bb40..a96656e81 100644 --- a/src/spicelib/analysis/cktdojob.c +++ b/src/spicelib/analysis/cktdojob.c @@ -190,52 +190,149 @@ CKTdoJob(CKTcircuit *ckt, int reset, TSKtask *task) error2 = OK; +#ifdef RELAN + int j, relan ; + relan = 0 ; +#endif + /* Analysis order is important */ - for (i = 0; i < ANALmaxnum; i++) { + for (i = 0; i < ANALmaxnum; i++) + { #ifdef WANT_SENSE2 - if (i == sens_num) - continue; + if (i == sens_num) + { + continue ; + } #endif - for (job = task->jobs; job; job = job->JOBnextJob) { - if (job->JOBtype == i) { - ckt->CKTcurJob=job; - error = OK; - if (analInfo[i]->an_init) - error = analInfo[i]->an_init (ckt, job); - if (!error && analInfo[i]->do_ic) - error = CKTic(ckt); - if (!error){ -#ifdef XSPICE - if(reset) { - /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */ - error = EVTsetup(ckt); - if(error) { - ckt->CKTstat->STATtotAnalTime += - SPfrontEnd->IFseconds() - startTime; - return(error); - } - /* gtri - end - 6/10/91 - wbk - Setup event-driven data */ - } + for (job = task->jobs ; job ; job = job->JOBnextJob) + { + if (job->JOBtype == i) + { + +#ifdef RELAN + if (relan) + { + for (j = 0 ; j < ckt->CKTagingN ; j++) + { + printf ("\n\nAdding Aging Effect at %-.9g seconds...\n\n", ckt->CKTagingStep + j * ckt->CKTagingStep) ; + error = CKTagingAdd (ckt, j) ; + if (error) + { + return (error) ; + } + + error = CKTtemp (ckt) ; + if (error) + { + return (error) ; + } #endif - error = analInfo[i]->an_func (ckt, reset); - /* txl, cpl addition */ - if (error == 1111) break; - } - if (error) - error2 = error; - } - } + + ckt->CKTcurJob = job ; + error = OK ; + if (analInfo[i]->an_init) + { + error = analInfo[i]->an_init (ckt, job) ; + } + + if (!error && analInfo[i]->do_ic) + { + error = CKTic (ckt) ; + } + + if (!error) + { + +#ifdef XSPICE + if (reset) + { + /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */ + error = EVTsetup (ckt) ; + if (error) + { + ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime ; + return (error) ; + } + /* gtri - end - 6/10/91 - wbk - Setup event-driven data */ + } +#endif + + error = analInfo[i]->an_func (ckt, reset) ; + /* txl, cpl addition */ + if (error == 1111) + { + break ; + } + if (error) + { + error2 = error ; + } + } + +#ifdef RELAN + } + } else { + ckt->CKTcurJob = job ; + error = OK ; + if (analInfo[i]->an_init) + { + error = analInfo[i]->an_init (ckt, job) ; + } + + if (!error && analInfo[i]->do_ic) + { + error = CKTic (ckt) ; + } + + if (!error) + { + +#ifdef XSPICE + if (reset) + { + /* gtri - begin - 6/10/91 - wbk - Setup event-driven data */ + error = EVTsetup (ckt) ; + if (error) + { + ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime ; + return (error) ; + } + /* gtri - end - 6/10/91 - wbk - Setup event-driven data */ + } +#endif + + error = analInfo[i]->an_func (ckt, reset) ; + /* txl, cpl addition */ + if (error == 1111) + { + break ; + } + if (error) + { + error2 = error ; + } + } + + if (i == 1) + { + /* Reliability Analysis */ + relan = 1 ; + } + } +#endif /* RELAN */ + + } + } } - ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime; + ckt->CKTstat->STATtotAnalTime += SPfrontEnd->IFseconds() - startTime ; #ifdef WANT_SENSE2 if (ckt->CKTsenInfo) SENdestroy(ckt->CKTsenInfo); #endif - return(error2); + return (error2) ; } - diff --git a/src/spicelib/analysis/cktreliability.c b/src/spicelib/analysis/cktreliability.c new file mode 100644 index 000000000..fcda32da5 --- /dev/null +++ b/src/spicelib/analysis/cktreliability.c @@ -0,0 +1,58 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/devdefs.h" +#include "ngspice/sperror.h" + +int +CKTagingAdd (CKTcircuit *ckt, int step) +{ + int i, error ; + + /* Update delvto for every instance */ + for (i = 0 ; i < DEVmaxnum ; i++) + { + if (i == 10) + { + /* BSIM4 */ + if (DEVices[i] && DEVices[i]->DEVagingAdd && ckt->CKThead[i]) + { + error = DEVices[i]->DEVagingAdd (ckt->CKThead [i], step) ; + if (error) + { + return (error) ; + } + } + } + } + + return (OK) ; +} + +int +CKTagingSetup (CKTcircuit *ckt) +{ + int i, error ; + + /* Extract Vth and calculate delvto for every instance */ + for (i = 0 ; i < DEVmaxnum ; i++) + { + if (i == 10) + { + /* BSIM4 */ + if (DEVices[i] && DEVices[i]->DEVagingSetup && ckt->CKThead[i]) + { + error = DEVices[i]->DEVagingSetup (ckt->CKThead [i], ckt) ; + if (error) + { + return (error) ; + } + } + } + } + + return (OK) ; +} diff --git a/src/spicelib/analysis/relanalysis.c b/src/spicelib/analysis/relanalysis.c new file mode 100644 index 000000000..e16564728 --- /dev/null +++ b/src/spicelib/analysis/relanalysis.c @@ -0,0 +1,71 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/sperror.h" +#include "ngspice/ifsim.h" + +int +RELANanalysis (CKTcircuit *ckt, int notused) +{ + int converged ; + int error ; + IFuid *nameList ; + int numNames ; + runDesc *plot = NULL ; + + NG_IGNORE (notused) ; + + error = CKTnames (ckt, &numNames, &nameList) ; + if (error) + { + return (error) ; + } + error = SPfrontEnd->OUTpBeginPlot (ckt, ckt->CKTcurJob, ckt->CKTcurJob->JOBname, NULL, IF_REAL, + numNames, nameList, IF_REAL, &plot) ; + tfree (nameList) ; + if (error) + { + return (error) ; + } + + /* initialize CKTsoaCheck `warn' counters */ + if (ckt->CKTsoaCheck) + { + error = CKTsoaInit () ; + } + + converged = CKTop (ckt, (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITJCT, + (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITFLOAT, ckt->CKTdcMaxIter) ; + if (converged != 0) + { + fprintf (stdout, "\nDC solution failed -\n") ; + CKTncDump (ckt) ; + return (converged) ; + } + + ckt->CKTmode = (ckt->CKTmode & MODEUIC) | MODEDCOP | MODEINITSMSIG ; + + converged = CKTload (ckt) ; + if (converged == 0) + { + CKTdump (ckt, 0.0, plot) ; + if (ckt->CKTsoaCheck) + { + error = CKTsoaCheck (ckt) ; + } + } else { + fprintf (stderr, "error: circuit reload failed.\n") ; + } + + SPfrontEnd->OUTendPlot (plot) ; + + + /* Extract Vth and calculate delvto for every instance */ + error = CKTagingSetup (ckt) ; + + + return (error) ; +} diff --git a/src/spicelib/analysis/relanaskq.c b/src/spicelib/analysis/relanaskq.c new file mode 100644 index 000000000..0419346e6 --- /dev/null +++ b/src/spicelib/analysis/relanaskq.c @@ -0,0 +1,46 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "ngspice/iferrmsg.h" +#include "ngspice/relandefs.h" +#include "ngspice/cktdefs.h" + +int +RELANaskQuest (CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) +{ + RELANan *job = (RELANan *) anal ; + + NG_IGNORE (ckt) ; + + switch (which) + { + case RELAN_AGING_STEP: + value->rValue = job->RELANagingStep ; + break ; + + case RELAN_AGING_STOP: + value->rValue = job->RELANagingTotalTime ; + break ; + + case RELAN_AGING_START: + value->rValue = job->RELANagingStartTime ; + break ; + + case RELAN_UIC: + if (job->RELANmode & MODEUIC) + { + value->iValue = 1 ; + } else { + value->iValue = 0 ; + } + break ; + + default: + return (E_BADPARM) ; + } + + return (OK) ; +} diff --git a/src/spicelib/analysis/relaninit.c b/src/spicelib/analysis/relaninit.c new file mode 100644 index 000000000..b8c8f4fd0 --- /dev/null +++ b/src/spicelib/analysis/relaninit.c @@ -0,0 +1,22 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "ngspice/relandefs.h" +#include "ngspice/iferrmsg.h" + +int +RELANinit (CKTcircuit *ckt, JOB *anal) +{ + RELANan *job = (RELANan *) anal ; + + ckt->CKTagingTotalTime = job->RELANagingTotalTime ; + ckt->CKTagingStartTime = job->RELANagingStartTime ; + ckt->CKTagingStep = job->RELANagingStep ; + + ckt->CKTmode = job->RELANmode ; + + return (OK) ; +} diff --git a/src/spicelib/analysis/relansetp.c b/src/spicelib/analysis/relansetp.c new file mode 100644 index 000000000..0a7d1e89a --- /dev/null +++ b/src/spicelib/analysis/relansetp.c @@ -0,0 +1,87 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/ifsim.h" +#include "ngspice/iferrmsg.h" +#include "ngspice/relandefs.h" +#include "ngspice/cktdefs.h" + +#include "analysis.h" + +int +RELANsetParm (CKTcircuit *ckt, JOB *anal, int which, IFvalue *value) +{ + RELANan *job = (RELANan *) anal ; + + NG_IGNORE (ckt) ; + + switch (which) + { + case RELAN_AGING_STEP: + if (value->rValue <= 0.0) + { + errMsg = copy ("RELAN AGING STEP is invalid, must be greater than zero.") ; + job->RELANagingStep = 1.0 ; + return (E_PARMVAL) ; + } + job->RELANagingStep = value->rValue ; + break ; + + case RELAN_AGING_STOP: + if (value->rValue <= 0.0) + { + errMsg = copy ("RELAN AGING ST0P is invalid, must be greater than zero.") ; + job->RELANagingTotalTime = 1.0 ; + return (E_PARMVAL) ; + } + job->RELANagingTotalTime = value->rValue ; + break ; + + case RELAN_AGING_START: + if (value->rValue >= job->RELANagingTotalTime) + { + errMsg = copy ("RELAN AGING START is invalid, must be less than RELAN AGING STOP.") ; + job->RELANagingStartTime = 0.0 ; + return (E_PARMVAL) ; + } + job->RELANagingStartTime = value->rValue ; + break ; + + case RELAN_UIC: + if (value->iValue) + { + job->RELANmode |= MODEUIC ; + } + break ; + + default: + return (E_BADPARM) ; + } + + return (OK) ; +} + +static IFparm RELANparms [] = { + { "relan_aging_step", RELAN_AGING_STEP, IF_SET|IF_REAL, "Reliability Analysis - Aging Time Step" }, + { "relan_aging_stop", RELAN_AGING_STOP, IF_SET|IF_REAL, "Reliability Analysis - Aging Stop Time" }, + { "relan_aging_start", RELAN_AGING_START, IF_SET|IF_REAL, "Reliability Analysis - Aging Start Time" }, + { "uic", RELAN_UIC, IF_SET|IF_FLAG, "Use Initial Conditions" }, +} ; + +SPICEanalysis RELANinfo = { + { + "RELAN", + "Reliability Analysis", + NUMELEMS (RELANparms), + RELANparms + }, + sizeof(RELANan), + TIMEDOMAIN, + 1, + RELANsetParm, + RELANaskQuest, + RELANinit, + RELANanalysis +} ; diff --git a/src/spicelib/devices/asrc/asrcinit.c b/src/spicelib/devices/asrc/asrcinit.c index b38c95e5e..745a8e9d2 100644 --- a/src/spicelib/devices/asrc/asrcinit.c +++ b/src/spicelib/devices/asrc/asrcinit.c @@ -74,7 +74,13 @@ SPICEdev ASRCinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &ASRCiSize, - /* DEVmodSize */ &ASRCmSize + /* DEVmodSize */ &ASRCmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/bjt/bjtinit.c b/src/spicelib/devices/bjt/bjtinit.c index dc5e025b1..afb379f39 100644 --- a/src/spicelib/devices/bjt/bjtinit.c +++ b/src/spicelib/devices/bjt/bjtinit.c @@ -73,7 +73,12 @@ SPICEdev BJTinfo = { /* description from struct IFdevice */ /* DEVacct */ NULL, #endif /* DEVinstSize */ &BJTiSize, - /* DEVmodSize */ &BJTmSize + /* DEVmodSize */ &BJTmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim1/bsim1init.c b/src/spicelib/devices/bsim1/bsim1init.c index 16d4e9ef7..a59d5fa0f 100644 --- a/src/spicelib/devices/bsim1/bsim1init.c +++ b/src/spicelib/devices/bsim1/bsim1init.c @@ -73,7 +73,12 @@ SPICEdev B1info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &B1iSize, - /* DEVmodSize */ &B1mSize + /* DEVmodSize */ &B1mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim2/bsim2init.c b/src/spicelib/devices/bsim2/bsim2init.c index 6a4294505..18c58a828 100644 --- a/src/spicelib/devices/bsim2/bsim2init.c +++ b/src/spicelib/devices/bsim2/bsim2init.c @@ -73,7 +73,12 @@ SPICEdev B2info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &B2iSize, - /* DEVmodSize */ &B2mSize + /* DEVmodSize */ &B2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim3/bsim3init.c b/src/spicelib/devices/bsim3/bsim3init.c index e27f3925b..cec5a46c9 100644 --- a/src/spicelib/devices/bsim3/bsim3init.c +++ b/src/spicelib/devices/bsim3/bsim3init.c @@ -72,7 +72,12 @@ SPICEdev BSIM3info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &BSIM3iSize, - /* DEVmodSize */ &BSIM3mSize + /* DEVmodSize */ &BSIM3mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c index 12b98c75f..6406b413d 100644 --- a/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c +++ b/src/spicelib/devices/bsim3soi_dd/b3soiddinit.c @@ -70,7 +70,13 @@ SPICEdev B3SOIDDinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &B3SOIDDiSize, - /* DEVmodSize */ &B3SOIDDmSize + /* DEVmodSize */ &B3SOIDDmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; SPICEdev * diff --git a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c index d5213e623..4ef7ff344 100644 --- a/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c +++ b/src/spicelib/devices/bsim3soi_fd/b3soifdinit.c @@ -71,7 +71,13 @@ SPICEdev B3SOIFDinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize*/ &B3SOIFDiSize, - /* DEVmodSize*/ &B3SOIFDmSize + /* DEVmodSize*/ &B3SOIFDmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c index 60c8a0033..0b06ba64d 100644 --- a/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c +++ b/src/spicelib/devices/bsim3soi_pd/b3soipdinit.c @@ -72,7 +72,13 @@ SPICEdev B3SOIPDinfo = { /* DEVacct*/ NULL, #endif /* DEVinstSize*/ &B3SOIPDiSize, - /* DEVmodSize*/ &B3SOIPDmSize + /* DEVmodSize*/ &B3SOIPDmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; SPICEdev * diff --git a/src/spicelib/devices/bsim3v0/bsim3v0init.c b/src/spicelib/devices/bsim3v0/bsim3v0init.c index 9eb299c49..b20edf1dd 100644 --- a/src/spicelib/devices/bsim3v0/bsim3v0init.c +++ b/src/spicelib/devices/bsim3v0/bsim3v0init.c @@ -71,7 +71,12 @@ SPICEdev B3v0info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &BSIM3v0iSize, - /* DEVmodSize */ &BSIM3v0mSize + /* DEVmodSize */ &BSIM3v0mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim3v1/bsim3v1init.c b/src/spicelib/devices/bsim3v1/bsim3v1init.c index 3efb57efc..0b141b3b5 100644 --- a/src/spicelib/devices/bsim3v1/bsim3v1init.c +++ b/src/spicelib/devices/bsim3v1/bsim3v1init.c @@ -71,7 +71,12 @@ SPICEdev BSIM3v1info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &BSIM3v1iSize, - /* DEVmodSize */ &BSIM3v1mSize + /* DEVmodSize */ &BSIM3v1mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim3v32/bsim3v32init.c b/src/spicelib/devices/bsim3v32/bsim3v32init.c index e109cf654..ceeafa92a 100644 --- a/src/spicelib/devices/bsim3v32/bsim3v32init.c +++ b/src/spicelib/devices/bsim3v32/bsim3v32init.c @@ -72,7 +72,12 @@ SPICEdev BSIM3v32info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &BSIM3v32iSize, - /* DEVmodSize */ &BSIM3v32mSize + /* DEVmodSize */ &BSIM3v32mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/bsim4/Makefile.am b/src/spicelib/devices/bsim4/Makefile.am index 047ffdfc6..f7ab5967e 100644 --- a/src/spicelib/devices/bsim4/Makefile.am +++ b/src/spicelib/devices/bsim4/Makefile.am @@ -30,6 +30,11 @@ libbsim4_la_SOURCES = \ bsim4itf.h +if RELAN_WANTED +libbsim4_la_SOURCES += \ + b4reliability.c +endif + AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) diff --git a/src/spicelib/devices/bsim4/b4reliability.c b/src/spicelib/devices/bsim4/b4reliability.c new file mode 100644 index 000000000..33f5eabc7 --- /dev/null +++ b/src/spicelib/devices/bsim4/b4reliability.c @@ -0,0 +1,92 @@ +/********** +Author: Francesco Lannutti - August 2014 +**********/ + +#include "ngspice/ngspice.h" +#include "ngspice/cktdefs.h" +#include "bsim4def.h" +#include "ngspice/sperror.h" + +int +BSIM4agingAdd (GENmodel *inModel, int step) +{ + BSIM4model *model = (BSIM4model*)inModel ; + BSIM4instance *here ; + + /* loop through all the BSIM4 device models */ + for (; model != NULL ; model = model->BSIM4nextModel) + { + /* loop through all the instances of the model */ + for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance) + { + here->BSIM4delvto = here->BSIM4agingDelvto [step] ; + } + } + + return (OK) ; +} + +int +BSIM4agingSetup (GENmodel *inModel, CKTcircuit *ckt) +{ + BSIM4model *model = (BSIM4model*)inModel ; + BSIM4instance *here ; + unsigned int i ; + double vges ; + + const double K1_2 = 81e53 ; // [C^(-1/2) * m^(-5/2)] //------------------fittato 8----->9 ->squared + const double T0 = 0.05e10 ; // [s/m^2] //------------fittato 1---->0.05 + const double E_01 = 0.335e9 ; // [V/m] // + const double Ea = (0.04 * 0.1602136e-18) ; // [J] // Activation energy ---------------- Fittato 0.49-------------------->0.04 + const double X1 = 0.9 ; // [dimensionless] // Process parameter + const double X2 = 0.5 ; // [dimensionless] // Process parameter + + double T_clk = 10e-9 ; // [s] // Clock period (from netlist) + double alfa = 0.5 ; // [dimensionless] // Duty cycle (from paper) + + double f = 0.333333333333333333333333333333333333333 ; + + double Kv ; + double C ; // Temperature dependant constant + double beta ; // Recovery factor + double delta_Vth ; // Voltage threshold shift + + double r ; + + C = 1 / T0 * exp (-Ea / (CONSTboltz * ckt->CKTtemp)) ; + + ckt->CKTagingN = (int)((ckt->CKTagingTotalTime - ckt->CKTagingStartTime) / ckt->CKTagingStep) ; + + /* loop through all the BSIM4 device models */ + for (; model != NULL ; model = model->BSIM4nextModel) + { + /* loop through all the instances of the model */ + for (here = model->BSIM4instances ; here != NULL ; here = here->BSIM4nextInstance) + { + here->BSIM4agingDelvto = TMALLOC (double, (size_t)ckt->CKTagingN) ; + + //vgs = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodePrime] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ; + vges = model->BSIM4type * (ckt->CKTrhsOld [here->BSIM4gNodeExt] - ckt->CKTrhsOld [here->BSIM4sNodePrime]) ; +// printf ("\n\nName: %s\nVth: %-.9g\nVges: %-.9g\nToxe: %-.9g\n", here->BSIM4name, model->BSIM4type * here->BSIM4von, model->BSIM4type * vges, model->BSIM4toxe) ; + + Kv = (CHARGE * CHARGE * CHARGE * model->BSIM4toxe * model->BSIM4toxe) / (CONSTepsSiO2 * CONSTepsSiO2) * K1_2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) * sqrt (C) * exp (2 * (model->BSIM4type * vges - model->BSIM4type * here->BSIM4von) / (model->BSIM4toxe * E_01)) ; + + /* loop through all the aging steps */ + i = 0 ; + for (r = ckt->CKTagingStartTime + ckt->CKTagingStep ; r <= ckt->CKTagingTotalTime ; r += ckt->CKTagingStep) + { + beta = 1 - (2 * X1 * model->BSIM4toxe + sqrt (X2 * C * (1 - alfa) * T_clk)) / (2 * model->BSIM4toxe + sqrt (C * r)) ; + delta_Vth = pow ((sqrt ((pow (Kv, 2)) * alfa * T_clk) / (1 - pow (beta, 3))), f) ; + here->BSIM4agingDelvto [i] = delta_Vth ; +// double Vth ; +// Vth = model->BSIM4type * here->BSIM4von - here->BSIM4agingDelvto [i] ; +// printf ("Delta Vth equals to %-.9g for %.1f second(s)\t\t", here->BSIM4agingDelvto [i], r) ; +// printf ("Vth equals to %-.9g for %.1f second(s)\n", Vth, r) ; + i++ ; + } + } + } + printf ("\n\n") ; + + return (OK) ; +} diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index b3206d16e..b34710e1c 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -572,6 +572,10 @@ typedef struct sBSIM4instance double **BSIM4nVar; #endif /* NONOISE */ +#ifdef RELAN + double *BSIM4agingDelvto ; +#endif + } BSIM4instance ; struct bsim4SizeDependParam diff --git a/src/spicelib/devices/bsim4/bsim4ext.h b/src/spicelib/devices/bsim4/bsim4ext.h index 9618c6328..675ff159d 100644 --- a/src/spicelib/devices/bsim4/bsim4ext.h +++ b/src/spicelib/devices/bsim4/bsim4ext.h @@ -31,3 +31,8 @@ extern int BSIM4trunc(GENmodel*,CKTcircuit*,double*); extern int BSIM4noise(int,int,GENmodel*,CKTcircuit*,Ndata*,double*); extern int BSIM4unsetup(GENmodel*,CKTcircuit*); extern int BSIM4soaCheck(CKTcircuit *, GENmodel *); + +#ifdef RELAN +extern int BSIM4agingAdd (GENmodel *, int) ; +extern int BSIM4agingSetup (GENmodel *, CKTcircuit *) ; +#endif diff --git a/src/spicelib/devices/bsim4/bsim4init.c b/src/spicelib/devices/bsim4/bsim4init.c index e9d13577d..46c5cec4d 100644 --- a/src/spicelib/devices/bsim4/bsim4init.c +++ b/src/spicelib/devices/bsim4/bsim4init.c @@ -73,7 +73,13 @@ SPICEdev BSIM4info = { NULL, /* DEVacct */ #endif &BSIM4iSize, /* DEVinstSize */ - &BSIM4mSize /* DEVmodSize */ + &BSIM4mSize, /* DEVmodSize */ + +#ifdef RELAN + BSIM4agingAdd, /* DEVagingAdd */ + BSIM4agingSetup /* DEVagingSetup */ +#endif + }; diff --git a/src/spicelib/devices/bsim4v5/bsim4v5init.c b/src/spicelib/devices/bsim4v5/bsim4v5init.c index ba6aca999..affd21d93 100644 --- a/src/spicelib/devices/bsim4v5/bsim4v5init.c +++ b/src/spicelib/devices/bsim4v5/bsim4v5init.c @@ -73,7 +73,13 @@ SPICEdev BSIM4v5info = { NULL, /* DEVacct */ #endif &BSIM4v5iSize, /* DEVinstSize */ - &BSIM4v5mSize /* DEVmodSize */ + &BSIM4v5mSize, /* DEVmodSize */ + +#ifdef RELAN + NULL, /* DEVagingAdd */ + NULL /* DEVagingSetup */ +#endif + }; diff --git a/src/spicelib/devices/bsim4v6/bsim4v6init.c b/src/spicelib/devices/bsim4v6/bsim4v6init.c index 28cd3e28a..30d894295 100644 --- a/src/spicelib/devices/bsim4v6/bsim4v6init.c +++ b/src/spicelib/devices/bsim4v6/bsim4v6init.c @@ -73,7 +73,13 @@ SPICEdev BSIM4v6info = { NULL, /* DEVacct */ #endif &BSIM4v6iSize, /* DEVinstSize */ - &BSIM4v6mSize /* DEVmodSize */ + &BSIM4v6mSize, /* DEVmodSize */ + +#ifdef RELAN + NULL, /* DEVagingAdd */ + NULL /* DEVagingSetup */ +#endif + }; diff --git a/src/spicelib/devices/bsim4v7/bsim4v7init.c b/src/spicelib/devices/bsim4v7/bsim4v7init.c index 519fbf6ed..6f6c1558f 100644 --- a/src/spicelib/devices/bsim4v7/bsim4v7init.c +++ b/src/spicelib/devices/bsim4v7/bsim4v7init.c @@ -73,7 +73,13 @@ SPICEdev BSIM4v7info = { NULL, /* DEVacct */ #endif &BSIM4v7iSize, /* DEVinstSize */ - &BSIM4v7mSize /* DEVmodSize */ + &BSIM4v7mSize, /* DEVmodSize */ + +#ifdef RELAN + NULL, /* DEVagingAdd */ + NULL /* DEVagingSetup */ +#endif + }; diff --git a/src/spicelib/devices/bsimsoi/b4soiinit.c b/src/spicelib/devices/bsimsoi/b4soiinit.c index 1372967e4..f2e84c583 100644 --- a/src/spicelib/devices/bsimsoi/b4soiinit.c +++ b/src/spicelib/devices/bsimsoi/b4soiinit.c @@ -71,7 +71,13 @@ SPICEdev B4SOIinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &B4SOIiSize, - /* DEVmodSize */ &B4SOImSize + /* DEVmodSize */ &B4SOImSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; SPICEdev * diff --git a/src/spicelib/devices/cap/capinit.c b/src/spicelib/devices/cap/capinit.c index 1c8bb5126..ac5e5a232 100644 --- a/src/spicelib/devices/cap/capinit.c +++ b/src/spicelib/devices/cap/capinit.c @@ -72,7 +72,13 @@ SPICEdev CAPinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &CAPiSize, - /* DEVmodSize */ &CAPmSize + /* DEVmodSize */ &CAPmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/cccs/cccsinit.c b/src/spicelib/devices/cccs/cccsinit.c index 24fbedfb2..cb9000744 100644 --- a/src/spicelib/devices/cccs/cccsinit.c +++ b/src/spicelib/devices/cccs/cccsinit.c @@ -72,7 +72,12 @@ SPICEdev CCCSinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &CCCSiSize, - /* DEVmodSize */ &CCCSmSize + /* DEVmodSize */ &CCCSmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/ccvs/ccvsinit.c b/src/spicelib/devices/ccvs/ccvsinit.c index c0bf92810..a19ab115e 100644 --- a/src/spicelib/devices/ccvs/ccvsinit.c +++ b/src/spicelib/devices/ccvs/ccvsinit.c @@ -73,7 +73,12 @@ SPICEdev CCVSinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &CCVSiSize, - /* DEVmodSize */ &CCVSmSize + /* DEVmodSize */ &CCVSmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/cpl/cplinit.c b/src/spicelib/devices/cpl/cplinit.c index 34f1bc43c..e7fce5f34 100644 --- a/src/spicelib/devices/cpl/cplinit.c +++ b/src/spicelib/devices/cpl/cplinit.c @@ -73,7 +73,12 @@ SPICEdev CPLinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &CPLiSize, -/* DEVmodSize */ &CPLmSize +/* DEVmodSize */ &CPLmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/csw/cswinit.c b/src/spicelib/devices/csw/cswinit.c index de4a7bf89..9c217a700 100644 --- a/src/spicelib/devices/csw/cswinit.c +++ b/src/spicelib/devices/csw/cswinit.c @@ -75,7 +75,12 @@ SPICEdev CSWinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &CSWiSize, - /* DEVmodSize */ &CSWmSize + /* DEVmodSize */ &CSWmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/dio/dioinit.c b/src/spicelib/devices/dio/dioinit.c index 4161316d2..70160b9c2 100644 --- a/src/spicelib/devices/dio/dioinit.c +++ b/src/spicelib/devices/dio/dioinit.c @@ -74,7 +74,13 @@ SPICEdev DIOinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &DIOiSize, - /* DEVmodSize */ &DIOmSize + /* DEVmodSize */ &DIOmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/hfet1/hfetinit.c b/src/spicelib/devices/hfet1/hfetinit.c index 8af00cbad..e48122b53 100644 --- a/src/spicelib/devices/hfet1/hfetinit.c +++ b/src/spicelib/devices/hfet1/hfetinit.c @@ -73,7 +73,12 @@ SPICEdev HFETAinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &HFETAiSize, - /* DEVmodSize */ &HFETAmSize + /* DEVmodSize */ &HFETAmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/hfet2/hfet2init.c b/src/spicelib/devices/hfet2/hfet2init.c index 7c1679970..b4e26f54f 100644 --- a/src/spicelib/devices/hfet2/hfet2init.c +++ b/src/spicelib/devices/hfet2/hfet2init.c @@ -73,7 +73,12 @@ SPICEdev HFET2info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &HFET2iSize, - /* DEVmodSize */ &HFET2mSize + /* DEVmodSize */ &HFET2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/hisim2/hsm2init.c b/src/spicelib/devices/hisim2/hsm2init.c index f07f6190f..f5a50f305 100644 --- a/src/spicelib/devices/hisim2/hsm2init.c +++ b/src/spicelib/devices/hisim2/hsm2init.c @@ -71,7 +71,12 @@ SPICEdev HSM2info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &HSM2iSize, - /* DEVmodSize */ &HSM2mSize + /* DEVmodSize */ &HSM2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/hisimhv1/hsmhvinit.c b/src/spicelib/devices/hisimhv1/hsmhvinit.c index 6e99917db..d21c967d7 100644 --- a/src/spicelib/devices/hisimhv1/hsmhvinit.c +++ b/src/spicelib/devices/hisimhv1/hsmhvinit.c @@ -71,7 +71,12 @@ SPICEdev HSMHVinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &HSMHViSize, - /* DEVmodSize */ &HSMHVmSize + /* DEVmodSize */ &HSMHVmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/ind/indinit.c b/src/spicelib/devices/ind/indinit.c index 8148abde8..264619921 100644 --- a/src/spicelib/devices/ind/indinit.c +++ b/src/spicelib/devices/ind/indinit.c @@ -72,7 +72,12 @@ SPICEdev INDinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &INDiSize, - /* DEVmodSize */ &INDmSize + /* DEVmodSize */ &INDmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; @@ -142,7 +147,12 @@ SPICEdev MUTinfo = { /* DEVacct */ NULL, #endif &MUTiSize, - &MUTmSize + &MUTmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/isrc/isrcinit.c b/src/spicelib/devices/isrc/isrcinit.c index 34bd23491..83b25ead0 100644 --- a/src/spicelib/devices/isrc/isrcinit.c +++ b/src/spicelib/devices/isrc/isrcinit.c @@ -73,7 +73,13 @@ SPICEdev ISRCinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &ISRCiSize, - /* DEVmodSize */ &ISRCmSize + /* DEVmodSize */ &ISRCmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/jfet/jfetinit.c b/src/spicelib/devices/jfet/jfetinit.c index 6c31d5fb4..358a564b0 100644 --- a/src/spicelib/devices/jfet/jfetinit.c +++ b/src/spicelib/devices/jfet/jfetinit.c @@ -73,7 +73,12 @@ SPICEdev JFETinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &JFETiSize, - /* DEVmodSize */ &JFETmSize + /* DEVmodSize */ &JFETmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/jfet2/jfet2init.c b/src/spicelib/devices/jfet2/jfet2init.c index 4590c84bf..5c1cfd231 100644 --- a/src/spicelib/devices/jfet2/jfet2init.c +++ b/src/spicelib/devices/jfet2/jfet2init.c @@ -73,7 +73,12 @@ SPICEdev JFET2info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &JFET2iSize, - /* DEVmodSize */ &JFET2mSize + /* DEVmodSize */ &JFET2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/ltra/ltrainit.c b/src/spicelib/devices/ltra/ltrainit.c index b2c30b76e..d022f4381 100644 --- a/src/spicelib/devices/ltra/ltrainit.c +++ b/src/spicelib/devices/ltra/ltrainit.c @@ -73,7 +73,12 @@ SPICEdev LTRAinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ <RAiSize, - /* DEVmodSize */ <RAmSize + /* DEVmodSize */ <RAmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/mes/mesinit.c b/src/spicelib/devices/mes/mesinit.c index 4eb612a68..1b4216b0c 100644 --- a/src/spicelib/devices/mes/mesinit.c +++ b/src/spicelib/devices/mes/mesinit.c @@ -73,7 +73,12 @@ SPICEdev MESinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MESiSize, - /* DEVmodSize */ &MESmSize + /* DEVmodSize */ &MESmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/mesa/mesainit.c b/src/spicelib/devices/mesa/mesainit.c index c1a63a43b..1f2ca4209 100644 --- a/src/spicelib/devices/mesa/mesainit.c +++ b/src/spicelib/devices/mesa/mesainit.c @@ -73,7 +73,12 @@ SPICEdev MESAinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MESAiSize, - /* DEVmodSize */ &MESAmSize + /* DEVmodSize */ &MESAmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/mos1/mos1init.c b/src/spicelib/devices/mos1/mos1init.c index a537f411c..541086741 100644 --- a/src/spicelib/devices/mos1/mos1init.c +++ b/src/spicelib/devices/mos1/mos1init.c @@ -73,7 +73,13 @@ SPICEdev MOS1info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MOS1iSize, - /* DEVmodSize */ &MOS1mSize + /* DEVmodSize */ &MOS1mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/mos2/mos2init.c b/src/spicelib/devices/mos2/mos2init.c index 1a6c9afbe..2016abf29 100644 --- a/src/spicelib/devices/mos2/mos2init.c +++ b/src/spicelib/devices/mos2/mos2init.c @@ -73,7 +73,13 @@ SPICEdev MOS2info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MOS2iSize, - /* DEVmodSize */ &MOS2mSize + /* DEVmodSize */ &MOS2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/mos3/mos3init.c b/src/spicelib/devices/mos3/mos3init.c index bd3e8c26a..feff3c3e5 100644 --- a/src/spicelib/devices/mos3/mos3init.c +++ b/src/spicelib/devices/mos3/mos3init.c @@ -73,7 +73,12 @@ SPICEdev MOS3info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MOS3iSize, - /* DEVmodSize */ &MOS3mSize + /* DEVmodSize */ &MOS3mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/mos6/mos6init.c b/src/spicelib/devices/mos6/mos6init.c index 65df0328c..4672ae236 100644 --- a/src/spicelib/devices/mos6/mos6init.c +++ b/src/spicelib/devices/mos6/mos6init.c @@ -73,7 +73,13 @@ SPICEdev MOS6info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MOS6iSize, - /* DEVmodSize */ &MOS6mSize + /* DEVmodSize */ &MOS6mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/devices/mos9/mos9init.c b/src/spicelib/devices/mos9/mos9init.c index 9d0ab50bf..4db77af30 100644 --- a/src/spicelib/devices/mos9/mos9init.c +++ b/src/spicelib/devices/mos9/mos9init.c @@ -73,7 +73,12 @@ SPICEdev MOS9info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &MOS9iSize, - /* DEVmodSize */ &MOS9mSize + /* DEVmodSize */ &MOS9mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/nbjt/nbjtinit.c b/src/spicelib/devices/nbjt/nbjtinit.c index 45a9dbee0..a00872ff6 100644 --- a/src/spicelib/devices/nbjt/nbjtinit.c +++ b/src/spicelib/devices/nbjt/nbjtinit.c @@ -74,7 +74,12 @@ SPICEdev NBJTinfo = { #endif /* DEVinstSize */ &NBJTiSize, - /* DEVmodSize */ &NBJTmSize + /* DEVmodSize */ &NBJTmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/nbjt2/nbt2init.c b/src/spicelib/devices/nbjt2/nbt2init.c index 39eab292f..3e387e58f 100644 --- a/src/spicelib/devices/nbjt2/nbt2init.c +++ b/src/spicelib/devices/nbjt2/nbt2init.c @@ -74,7 +74,12 @@ SPICEdev NBJT2info = { #endif /* DEVinstSize */ &NBJT2iSize, - /* DEVmodSize */ &NBJT2mSize + /* DEVmodSize */ &NBJT2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/ndev/ndevinit.c b/src/spicelib/devices/ndev/ndevinit.c index 4a855c69c..bb9460704 100644 --- a/src/spicelib/devices/ndev/ndevinit.c +++ b/src/spicelib/devices/ndev/ndevinit.c @@ -74,7 +74,12 @@ SPICEdev NDEVinfo = { #endif /* DEVinstSize */ &NDEViSize, - /* DEVmodSize */ &NDEVmSize + /* DEVmodSize */ &NDEVmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/numd/numdinit.c b/src/spicelib/devices/numd/numdinit.c index cd78dee31..6901c134f 100644 --- a/src/spicelib/devices/numd/numdinit.c +++ b/src/spicelib/devices/numd/numdinit.c @@ -74,7 +74,12 @@ SPICEdev NUMDinfo = { #endif /* DEVinstSize */ &NUMDiSize, - /* DEVmodSize */ &NUMDmSize + /* DEVmodSize */ &NUMDmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/numd2/numd2init.c b/src/spicelib/devices/numd2/numd2init.c index dec78e566..de6268de0 100644 --- a/src/spicelib/devices/numd2/numd2init.c +++ b/src/spicelib/devices/numd2/numd2init.c @@ -74,7 +74,12 @@ SPICEdev NUMD2info = { #endif /* DEVinstSize */ &NUMD2iSize, - /* DEVmodSize */ &NUMD2mSize + /* DEVmodSize */ &NUMD2mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/numos/numosinit.c b/src/spicelib/devices/numos/numosinit.c index 851685906..ed0307bc3 100644 --- a/src/spicelib/devices/numos/numosinit.c +++ b/src/spicelib/devices/numos/numosinit.c @@ -74,7 +74,12 @@ SPICEdev NUMOSinfo = { #endif /* DEVinstSize */ &NUMOSiSize, - /* DEVmodSize */ &NUMOSmSize + /* DEVmodSize */ &NUMOSmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/res/resinit.c b/src/spicelib/devices/res/resinit.c index d4096de8d..a8a9ba0ed 100644 --- a/src/spicelib/devices/res/resinit.c +++ b/src/spicelib/devices/res/resinit.c @@ -73,7 +73,12 @@ SPICEdev RESinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &RESiSize, - /* DEVmodSize */ &RESmSize + /* DEVmodSize */ &RESmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/soi3/soi3init.c b/src/spicelib/devices/soi3/soi3init.c index 8d07f800f..3a0e3fbb5 100644 --- a/src/spicelib/devices/soi3/soi3init.c +++ b/src/spicelib/devices/soi3/soi3init.c @@ -73,7 +73,12 @@ SPICEdev SOI3info = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &SOI3iSize, - /* DEVmodSize */ &SOI3mSize + /* DEVmodSize */ &SOI3mSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/sw/swinit.c b/src/spicelib/devices/sw/swinit.c index 34b3ebc4c..279a20fea 100644 --- a/src/spicelib/devices/sw/swinit.c +++ b/src/spicelib/devices/sw/swinit.c @@ -74,7 +74,12 @@ SPICEdev SWinfo = { /* DEVacct */ NULL, #endif /* CIDER */ /* DEVinstSize */ &SWiSize, - /* DEVmodSize */ &SWmSize + /* DEVmodSize */ &SWmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/tra/trainit.c b/src/spicelib/devices/tra/trainit.c index 5b7fa0637..cc999d31e 100644 --- a/src/spicelib/devices/tra/trainit.c +++ b/src/spicelib/devices/tra/trainit.c @@ -73,7 +73,12 @@ SPICEdev TRAinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &TRAiSize, - /* DEVmodSize */ &TRAmSize + /* DEVmodSize */ &TRAmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/txl/txlinit.c b/src/spicelib/devices/txl/txlinit.c index 4c4e6d3f3..350057216 100644 --- a/src/spicelib/devices/txl/txlinit.c +++ b/src/spicelib/devices/txl/txlinit.c @@ -78,7 +78,12 @@ SPICEdev TXLinfo = { /* DEVacct */ NULL, #endif &TXLiSize, - &TXLmSize + &TXLmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/urc/urcinit.c b/src/spicelib/devices/urc/urcinit.c index 0211d14a0..494155b2f 100644 --- a/src/spicelib/devices/urc/urcinit.c +++ b/src/spicelib/devices/urc/urcinit.c @@ -73,7 +73,12 @@ SPICEdev URCinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &URCiSize, - /* DEVmodSize */ &URCmSize + /* DEVmodSize */ &URCmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/vbic/vbicinit.c b/src/spicelib/devices/vbic/vbicinit.c index 9abc37049..77c627019 100644 --- a/src/spicelib/devices/vbic/vbicinit.c +++ b/src/spicelib/devices/vbic/vbicinit.c @@ -78,7 +78,12 @@ SPICEdev VBICinfo = { NULL, /* DEVacct */ #endif &VBICiSize, /* DEVinstSize */ - &VBICmSize /* DEVmodSize */ + &VBICmSize, /* DEVmodSize */ + +#ifdef RELAN + NULL, /* DEVagingAdd */ + NULL /* DEVagingSetup */ +#endif }; diff --git a/src/spicelib/devices/vccs/vccsinit.c b/src/spicelib/devices/vccs/vccsinit.c index a517ceecb..ddd6a50a3 100644 --- a/src/spicelib/devices/vccs/vccsinit.c +++ b/src/spicelib/devices/vccs/vccsinit.c @@ -73,8 +73,12 @@ SPICEdev VCCSinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &VCCSiSize, - /* DEVmodSize */ &VCCSmSize + /* DEVmodSize */ &VCCSmSize, +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/vcvs/vcvsinit.c b/src/spicelib/devices/vcvs/vcvsinit.c index 5bd93c517..1f3cea779 100644 --- a/src/spicelib/devices/vcvs/vcvsinit.c +++ b/src/spicelib/devices/vcvs/vcvsinit.c @@ -73,7 +73,12 @@ SPICEdev VCVSinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &VCVSiSize, - /* DEVmodSize */ &VCVSmSize + /* DEVmodSize */ &VCVSmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif }; diff --git a/src/spicelib/devices/vsrc/vsrcinit.c b/src/spicelib/devices/vsrc/vsrcinit.c index 9bb3c6508..24a1fd4c5 100644 --- a/src/spicelib/devices/vsrc/vsrcinit.c +++ b/src/spicelib/devices/vsrc/vsrcinit.c @@ -73,7 +73,13 @@ SPICEdev VSRCinfo = { /* DEVacct */ NULL, #endif /* DEVinstSize */ &VSRCiSize, - /* DEVmodSize */ &VSRCmSize + /* DEVmodSize */ &VSRCmSize, + +#ifdef RELAN + /* DEVagingAdd */ NULL, + /* DEVagingSetup */ NULL +#endif + }; diff --git a/src/spicelib/parser/inp2dot.c b/src/spicelib/parser/inp2dot.c index 6c946cd7e..9363ebd31 100644 --- a/src/spicelib/parser/inp2dot.c +++ b/src/spicelib/parser/inp2dot.c @@ -611,6 +611,60 @@ dot_pss(char *line, void *ckt, INPtables *tab, card *current, /* SP */ #endif +#ifdef RELAN +static int +dot_relan (char *line, void *ckt, INPtables *tab, card *current, void *task, void *gnode, JOB *foo) +{ + int error ; /* error code temporary */ + IFvalue ptemp ; /* a value structure to package resistance into */ + IFvalue *parm ; /* a pointer to a value struct for function returns */ + int which ; /* which analysis we are performing */ + char *word ; /* something to stick a word of input into */ + double dtemp ; /* random double precision temporary */ + + NG_IGNORE (gnode) ; + + /* .relan AgingStep AgingStop */ + which = ft_find_analysis ("RELAN") ; + if (which == -1) + { + LITERR ("Reliability Analysis unsupported.\n") ; + return (0) ; + } + IFC (newAnalysis, (ckt, which, "Reliability Analysis", &foo, task)) ; + + parm = INPgetValue (ckt, &line, IF_REAL, tab) ; + GCA (INPapName, (ckt, which, foo, "relan_aging_step", parm)) ; + + parm = INPgetValue (ckt, &line, IF_REAL, tab) ; + GCA (INPapName, (ckt, which, foo, "relan_aging_stop", parm)) ; + + if (*line) + { + dtemp = INPevaluate (&line, &error, 1) ; /* AgingStart */ + if (error == 0) + { + ptemp.rValue = dtemp ; + GCA (INPapName, (ckt, which, foo, "relan_aging_start", &ptemp)) ; + } + } + + if (*line) + { + INPgetTok (&line, &word, 1) ; /* UIC */ + if (strcmp (word, "uic") == 0) + { + ptemp.iValue = 1 ; + GCA (INPapName, (ckt, which, foo, "uic", &ptemp)) ; + } else { + fprintf (stderr,"Error: unknown parameter %s on .relan - ignored\n", word) ; + } + } + + return (0) ; +} +#endif + static int dot_options(char *line, CKTcircuit *ckt, INPtables *tab, card *current, TSKtask *task, CKTnode *gnode, JOB *foo) @@ -697,6 +751,13 @@ INP2dot(CKTcircuit *ckt, INPtables *tab, card *current, TSKtask *task, CKTnode * goto quit; /* SP */ #endif + +#ifdef RELAN + } else if ((strcmp (token, ".relan") == 0)) { + rtn = dot_relan (line, ckt, tab, current, task, gnode, foo) ; + goto quit ; +#endif + } else if ((strcmp(token, ".subckt") == 0) || (strcmp(token, ".ends") == 0)) { /* not yet implemented - warn & ignore */