Added Reliability Analysis based upon BSIM4 model

This commit is contained in:
Francesco Lannutti 2014-08-23 13:12:45 +02:00
parent 5e8856d944
commit 3ab6e419a7
79 changed files with 1120 additions and 90 deletions

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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) */

View File

@ -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);

View File

@ -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 */

View File

@ -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*/

View File

@ -79,6 +79,11 @@ struct plotab plotabs[NUMPLOTTYPES] = {
{ "harm", "harm" },
{ "spect", "spect" },
{ "pss", "periodic" },
#ifdef RELAN
{ "relan", "reliability" }
#endif
};
int notypes = 19;

View File

@ -125,4 +125,9 @@ include_HEADERS = \
wallace.h \
wstdio.h
if RELAN_WANTED
include_HEADERS += \
relandefs.h
endif
MAINTAINERCLEANFILES = Makefile.in

View File

@ -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 *);

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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) ;
}

View File

@ -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) ;
}

View File

@ -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) ;
}

View File

@ -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) ;
}

View File

@ -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) ;
}

View File

@ -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
} ;

View File

@ -74,7 +74,13 @@ SPICEdev ASRCinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &ASRCiSize,
/* DEVmodSize */ &ASRCmSize
/* DEVmodSize */ &ASRCmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -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
};

View File

@ -73,7 +73,12 @@ SPICEdev B1info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &B1iSize,
/* DEVmodSize */ &B1mSize
/* DEVmodSize */ &B1mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev B2info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &B2iSize,
/* DEVmodSize */ &B2mSize
/* DEVmodSize */ &B2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -72,7 +72,12 @@ SPICEdev BSIM3info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &BSIM3iSize,
/* DEVmodSize */ &BSIM3mSize
/* DEVmodSize */ &BSIM3mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -70,7 +70,13 @@ SPICEdev B3SOIDDinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &B3SOIDDiSize,
/* DEVmodSize */ &B3SOIDDmSize
/* DEVmodSize */ &B3SOIDDmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};
SPICEdev *

View File

@ -71,7 +71,13 @@ SPICEdev B3SOIFDinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize*/ &B3SOIFDiSize,
/* DEVmodSize*/ &B3SOIFDmSize
/* DEVmodSize*/ &B3SOIFDmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -72,7 +72,13 @@ SPICEdev B3SOIPDinfo = {
/* DEVacct*/ NULL,
#endif
/* DEVinstSize*/ &B3SOIPDiSize,
/* DEVmodSize*/ &B3SOIPDmSize
/* DEVmodSize*/ &B3SOIPDmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};
SPICEdev *

View File

@ -71,7 +71,12 @@ SPICEdev B3v0info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &BSIM3v0iSize,
/* DEVmodSize */ &BSIM3v0mSize
/* DEVmodSize */ &BSIM3v0mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -71,7 +71,12 @@ SPICEdev BSIM3v1info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &BSIM3v1iSize,
/* DEVmodSize */ &BSIM3v1mSize
/* DEVmodSize */ &BSIM3v1mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -72,7 +72,12 @@ SPICEdev BSIM3v32info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &BSIM3v32iSize,
/* DEVmodSize */ &BSIM3v32mSize
/* DEVmodSize */ &BSIM3v32mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -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)

View File

@ -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) ;
}

View File

@ -572,6 +572,10 @@ typedef struct sBSIM4instance
double **BSIM4nVar;
#endif /* NONOISE */
#ifdef RELAN
double *BSIM4agingDelvto ;
#endif
} BSIM4instance ;
struct bsim4SizeDependParam

View File

@ -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

View File

@ -73,7 +73,13 @@ SPICEdev BSIM4info = {
NULL, /* DEVacct */
#endif
&BSIM4iSize, /* DEVinstSize */
&BSIM4mSize /* DEVmodSize */
&BSIM4mSize, /* DEVmodSize */
#ifdef RELAN
BSIM4agingAdd, /* DEVagingAdd */
BSIM4agingSetup /* DEVagingSetup */
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev BSIM4v5info = {
NULL, /* DEVacct */
#endif
&BSIM4v5iSize, /* DEVinstSize */
&BSIM4v5mSize /* DEVmodSize */
&BSIM4v5mSize, /* DEVmodSize */
#ifdef RELAN
NULL, /* DEVagingAdd */
NULL /* DEVagingSetup */
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev BSIM4v6info = {
NULL, /* DEVacct */
#endif
&BSIM4v6iSize, /* DEVinstSize */
&BSIM4v6mSize /* DEVmodSize */
&BSIM4v6mSize, /* DEVmodSize */
#ifdef RELAN
NULL, /* DEVagingAdd */
NULL /* DEVagingSetup */
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev BSIM4v7info = {
NULL, /* DEVacct */
#endif
&BSIM4v7iSize, /* DEVinstSize */
&BSIM4v7mSize /* DEVmodSize */
&BSIM4v7mSize, /* DEVmodSize */
#ifdef RELAN
NULL, /* DEVagingAdd */
NULL /* DEVagingSetup */
#endif
};

View File

@ -71,7 +71,13 @@ SPICEdev B4SOIinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &B4SOIiSize,
/* DEVmodSize */ &B4SOImSize
/* DEVmodSize */ &B4SOImSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};
SPICEdev *

View File

@ -72,7 +72,13 @@ SPICEdev CAPinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &CAPiSize,
/* DEVmodSize */ &CAPmSize
/* DEVmodSize */ &CAPmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -72,7 +72,12 @@ SPICEdev CCCSinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &CCCSiSize,
/* DEVmodSize */ &CCCSmSize
/* DEVmodSize */ &CCCSmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev CCVSinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &CCVSiSize,
/* DEVmodSize */ &CCVSmSize
/* DEVmodSize */ &CCVSmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev CPLinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &CPLiSize,
/* DEVmodSize */ &CPLmSize
/* DEVmodSize */ &CPLmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -75,7 +75,12 @@ SPICEdev CSWinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &CSWiSize,
/* DEVmodSize */ &CSWmSize
/* DEVmodSize */ &CSWmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,13 @@ SPICEdev DIOinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &DIOiSize,
/* DEVmodSize */ &DIOmSize
/* DEVmodSize */ &DIOmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev HFETAinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &HFETAiSize,
/* DEVmodSize */ &HFETAmSize
/* DEVmodSize */ &HFETAmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev HFET2info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &HFET2iSize,
/* DEVmodSize */ &HFET2mSize
/* DEVmodSize */ &HFET2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -71,7 +71,12 @@ SPICEdev HSM2info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &HSM2iSize,
/* DEVmodSize */ &HSM2mSize
/* DEVmodSize */ &HSM2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -71,7 +71,12 @@ SPICEdev HSMHVinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &HSMHViSize,
/* DEVmodSize */ &HSMHVmSize
/* DEVmodSize */ &HSMHVmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -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
};

View File

@ -73,7 +73,13 @@ SPICEdev ISRCinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &ISRCiSize,
/* DEVmodSize */ &ISRCmSize
/* DEVmodSize */ &ISRCmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev JFETinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &JFETiSize,
/* DEVmodSize */ &JFETmSize
/* DEVmodSize */ &JFETmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev JFET2info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &JFET2iSize,
/* DEVmodSize */ &JFET2mSize
/* DEVmodSize */ &JFET2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev LTRAinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &LTRAiSize,
/* DEVmodSize */ &LTRAmSize
/* DEVmodSize */ &LTRAmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev MESinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MESiSize,
/* DEVmodSize */ &MESmSize
/* DEVmodSize */ &MESmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev MESAinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MESAiSize,
/* DEVmodSize */ &MESAmSize
/* DEVmodSize */ &MESAmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev MOS1info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MOS1iSize,
/* DEVmodSize */ &MOS1mSize
/* DEVmodSize */ &MOS1mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev MOS2info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MOS2iSize,
/* DEVmodSize */ &MOS2mSize
/* DEVmodSize */ &MOS2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev MOS3info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MOS3iSize,
/* DEVmodSize */ &MOS3mSize
/* DEVmodSize */ &MOS3mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev MOS6info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MOS6iSize,
/* DEVmodSize */ &MOS6mSize
/* DEVmodSize */ &MOS6mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev MOS9info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &MOS9iSize,
/* DEVmodSize */ &MOS9mSize
/* DEVmodSize */ &MOS9mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NBJTinfo = {
#endif
/* DEVinstSize */ &NBJTiSize,
/* DEVmodSize */ &NBJTmSize
/* DEVmodSize */ &NBJTmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NBJT2info = {
#endif
/* DEVinstSize */ &NBJT2iSize,
/* DEVmodSize */ &NBJT2mSize
/* DEVmodSize */ &NBJT2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NDEVinfo = {
#endif
/* DEVinstSize */ &NDEViSize,
/* DEVmodSize */ &NDEVmSize
/* DEVmodSize */ &NDEVmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NUMDinfo = {
#endif
/* DEVinstSize */ &NUMDiSize,
/* DEVmodSize */ &NUMDmSize
/* DEVmodSize */ &NUMDmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NUMD2info = {
#endif
/* DEVinstSize */ &NUMD2iSize,
/* DEVmodSize */ &NUMD2mSize
/* DEVmodSize */ &NUMD2mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev NUMOSinfo = {
#endif
/* DEVinstSize */ &NUMOSiSize,
/* DEVmodSize */ &NUMOSmSize
/* DEVmodSize */ &NUMOSmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev RESinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &RESiSize,
/* DEVmodSize */ &RESmSize
/* DEVmodSize */ &RESmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev SOI3info = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &SOI3iSize,
/* DEVmodSize */ &SOI3mSize
/* DEVmodSize */ &SOI3mSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -74,7 +74,12 @@ SPICEdev SWinfo = {
/* DEVacct */ NULL,
#endif /* CIDER */
/* DEVinstSize */ &SWiSize,
/* DEVmodSize */ &SWmSize
/* DEVmodSize */ &SWmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev TRAinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &TRAiSize,
/* DEVmodSize */ &TRAmSize
/* DEVmodSize */ &TRAmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -78,7 +78,12 @@ SPICEdev TXLinfo = {
/* DEVacct */ NULL,
#endif
&TXLiSize,
&TXLmSize
&TXLmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev URCinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &URCiSize,
/* DEVmodSize */ &URCmSize
/* DEVmodSize */ &URCmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -78,7 +78,12 @@ SPICEdev VBICinfo = {
NULL, /* DEVacct */
#endif
&VBICiSize, /* DEVinstSize */
&VBICmSize /* DEVmodSize */
&VBICmSize, /* DEVmodSize */
#ifdef RELAN
NULL, /* DEVagingAdd */
NULL /* DEVagingSetup */
#endif
};

View File

@ -73,8 +73,12 @@ SPICEdev VCCSinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &VCCSiSize,
/* DEVmodSize */ &VCCSmSize
/* DEVmodSize */ &VCCSmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,12 @@ SPICEdev VCVSinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &VCVSiSize,
/* DEVmodSize */ &VCVSmSize
/* DEVmodSize */ &VCVSmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -73,7 +73,13 @@ SPICEdev VSRCinfo = {
/* DEVacct */ NULL,
#endif
/* DEVinstSize */ &VSRCiSize,
/* DEVmodSize */ &VSRCmSize
/* DEVmodSize */ &VSRCmSize,
#ifdef RELAN
/* DEVagingAdd */ NULL,
/* DEVagingSetup */ NULL
#endif
};

View File

@ -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 <AgingStart> <UIC> */
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 */