First trial of fitting, based upon GSL Library
This commit is contained in:
parent
b9ebfe2ce6
commit
dda38c9df2
|
|
@ -39,6 +39,8 @@ endif
|
|||
AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include
|
||||
AM_CFLAGS = $(STATIC)
|
||||
|
||||
AM_LDFLAGS = -lgsl -lgslcblas
|
||||
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
EXTRA_DIST = B4TERMS_OF_USE
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ Author: 2015 Francesco Lannutti - July 2015
|
|||
#include "bsim4def.h"
|
||||
#include "ngspice/sperror.h"
|
||||
|
||||
#include <gsl/gsl_fit.h>
|
||||
|
||||
static int
|
||||
BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mode)
|
||||
{
|
||||
|
|
@ -19,7 +21,7 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
// Determine if the transistor is ON or OFF
|
||||
vds = ckt->CKTstate0 [here->BSIM4vds] ;
|
||||
vgs = ckt->CKTstate0 [here->BSIM4vgs] ;
|
||||
von = model->BSIM4type * here->BSIM4von ;
|
||||
von = here->BSIM4von ;
|
||||
if (vds >= 0)
|
||||
{
|
||||
// printf ("VDS >= 0\tBSIM4type: %d\tBSIM4instance: %s\tVgs: %-.9g\tVon: %-.9g\t", model->BSIM4type, here->BSIM4name, vgs, von) ;
|
||||
|
|
@ -118,16 +120,16 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
// Until now, the device was OFF - Calculate recovery
|
||||
delta = ckt->CKTtime - here->relStruct->time ;
|
||||
|
||||
// Update time and flag - Stress begins
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 1 ;
|
||||
|
||||
// Calculate Aging - Giogio Liatis' Model
|
||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
||||
if (ret == 1)
|
||||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update time and flag - Stress begins
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 1 ;
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
@ -137,16 +139,16 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
// Until now, the device was ON - Calculate stress
|
||||
delta = ckt->CKTtime - here->relStruct->time ;
|
||||
|
||||
// Update time and flag - Recovery begins
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 0 ;
|
||||
|
||||
// Calculate Aging - Giorgio Liatis' Model
|
||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
||||
if (ret == 1)
|
||||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update time and flag - Recovery begins
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 0 ;
|
||||
} else if (here->relStruct->IsON == 0) {
|
||||
// Until now, the device was OFF - Do NOTHING
|
||||
delta = -1 ;
|
||||
|
|
@ -155,32 +157,36 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
}
|
||||
}
|
||||
} else if (mode == 1) {
|
||||
// In this mode, it doesn't matter if NOW the device is in stress or in recovery, since it's the last timestep
|
||||
// In this mode, it doesn't matter if NOW the device is in stress or in recovery, since it's the latest timestep
|
||||
if (here->relStruct->IsON == 1)
|
||||
{
|
||||
// Calculate stress
|
||||
delta = ckt->CKTtime - here->relStruct->time ;
|
||||
|
||||
// Update time and flag - Maybe Optional
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 1 ;
|
||||
|
||||
// Calculate Aging - Giorgio Liatis' Model
|
||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1) ;
|
||||
if (ret == 1)
|
||||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update time and flag - Maybe Optional
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 1 ;
|
||||
} else if (here->relStruct->IsON == 0) {
|
||||
// Calculate recovery
|
||||
delta = ckt->CKTtime - here->relStruct->time ;
|
||||
|
||||
// Update time and flag - Maybe Optional
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 0 ;
|
||||
|
||||
// Calculate Aging - Giorgio Liatis' Model
|
||||
ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 0) ;
|
||||
if (ret == 1)
|
||||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update time and flag - Maybe Optional
|
||||
here->relStruct->time = ckt->CKTtime ;
|
||||
here->relStruct->IsON = 0 ;
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
@ -188,6 +194,50 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
printf ("DeltaVth: %-.9gmV\t\t", here->relStruct->deltaVth * 1000) ;
|
||||
printf ("Device Name: %s\t\t", here->BSIM4name) ;
|
||||
printf ("Device Type: %s\n\n", model->BSIM4modName) ;
|
||||
|
||||
|
||||
/* Calculate fitting */
|
||||
double c0, c1, cov00, cov01, cov11, chisq ;
|
||||
|
||||
/* Count how many deltaVth we have */
|
||||
unsigned int i ;
|
||||
RELMODELrelList *current ;
|
||||
|
||||
i = 0 ;
|
||||
current = here->relStruct->deltaVthList ;
|
||||
while (current != NULL)
|
||||
{
|
||||
i++ ;
|
||||
current = current->next ;
|
||||
}
|
||||
|
||||
/* Assign list members to vectors */
|
||||
double *timeFit, *deltaVthFit ;
|
||||
|
||||
timeFit = TMALLOC (double, i) ;
|
||||
deltaVthFit = TMALLOC (double, i) ;
|
||||
|
||||
i = 0 ;
|
||||
current = here->relStruct->deltaVthList ;
|
||||
while (current != NULL)
|
||||
{
|
||||
timeFit [i] = current->time ;
|
||||
deltaVthFit [i] = exp (current->deltaVth) ;
|
||||
printf ("Time: %-.9g\n", current->time) ;
|
||||
printf ("DeltaVth: %-.9g\n", current->deltaVth) ;
|
||||
printf ("DeltaVth (exp): %-.9g\n", exp (current->deltaVth)) ;
|
||||
i++ ;
|
||||
current = current->next ;
|
||||
}
|
||||
|
||||
/* Execute Fitting */
|
||||
gsl_fit_linear (timeFit + 1, 1, deltaVthFit + 1, 1, i - 1, &c0, &c1, &cov00, &cov01, &cov11, &chisq) ;
|
||||
|
||||
/* Perform Extrapolation */
|
||||
double yFit, yFitErr ;
|
||||
gsl_fit_linear_est (2e-6, c0, c1, cov00, cov01, cov11, &yFit, &yFitErr) ;
|
||||
|
||||
printf ("\n\tFitting -> %-.9gs\t%-.9gmV\n\n", 31536000.0, log (yFit) * 1000) ;
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2663,6 +2663,7 @@ do { if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NUL
|
|||
here->relStruct->deltaVth = 0 ;
|
||||
here->relStruct->t_star = 0 ;
|
||||
here->relStruct->IsON = -1 ;
|
||||
here->relStruct->deltaVthList = NULL ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,39 @@ Author: Francesco Lannutti - July 2015
|
|||
//#define CONSTepsZero (8.854214871e-12) /* epsilon zero F/m */
|
||||
//#define CONSTepsSiO2 (3.4531479969e-11) /* epsilon SiO2 F/m */
|
||||
|
||||
static int
|
||||
listInsert (RELMODELrelList **list, double time, double deltaVth)
|
||||
{
|
||||
RELMODELrelList *current ;
|
||||
RELMODELrelList *previous ;
|
||||
|
||||
/* Loop until the end of the list */
|
||||
previous = NULL ;
|
||||
current = *list ;
|
||||
while (current != NULL)
|
||||
{
|
||||
previous = current ;
|
||||
current = current->next ;
|
||||
}
|
||||
|
||||
/* Insert the new element into the list */
|
||||
if (previous == NULL)
|
||||
{
|
||||
*list = TMALLOC (RELMODELrelList, 1) ;
|
||||
current = *list ;
|
||||
} else {
|
||||
current = TMALLOC (RELMODELrelList, 1) ;
|
||||
previous->next = current ;
|
||||
}
|
||||
|
||||
/* Populate the element */
|
||||
current->time = time ;
|
||||
current->deltaVth = deltaVth ;
|
||||
current->next = NULL ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int
|
||||
RELMODELcalculateAging (GENinstance *inInstance, int modType, double t_aging, unsigned int stress_or_recovery)
|
||||
{
|
||||
|
|
@ -50,6 +83,16 @@ RELMODELcalculateAging (GENinstance *inInstance, int modType, double t_aging, un
|
|||
here->relStruct->deltaVth = here->relStruct->deltaVth * log (1 + (1.718 / (1 + pow ((t_aging / relmodel->RELMODELtau_e), relmodel->RELMODELbeta1)))) ;
|
||||
}
|
||||
|
||||
/* Insert 'here->relStruct->deltaVth' into the list for the later fitting */
|
||||
listInsert (&(here->relStruct->deltaVthList), here->relStruct->time, here->relStruct->deltaVth) ;
|
||||
// RELMODELrelList *temp ;
|
||||
// temp = TMALLOC (RELMODELrelList, 1) ;
|
||||
// temp->time = here->relStruct->time ;
|
||||
// temp->deltaVth = here->relStruct->deltaVth ;
|
||||
// temp->next = here->relStruct->deltaVthList ;
|
||||
// here->relStruct->deltaVthList = temp ;
|
||||
// printf ("QUI\n\n") ;
|
||||
|
||||
if (!stress_or_recovery)
|
||||
{
|
||||
here->relStruct->t_star = pow ((exp (sqrt (here->relStruct->deltaVth / (Nt * A))) - 1), (1 / relmodel->RELMODELbeta)) * relmodel->RELMODELtau_0 ;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,18 @@ Author: Francesco Lannutti - July 2015
|
|||
#include "ngspice/complex.h"
|
||||
#include "ngspice/noisedef.h"
|
||||
|
||||
typedef struct sRELMODELrelList {
|
||||
double time ;
|
||||
double deltaVth ;
|
||||
struct sRELMODELrelList *next ;
|
||||
} RELMODELrelList ;
|
||||
|
||||
typedef struct sRELMODELrelStruct {
|
||||
double time ;
|
||||
double deltaVth ;
|
||||
double t_star ;
|
||||
int IsON ;
|
||||
RELMODELrelList *deltaVthList ;
|
||||
} RELMODELrelStruct ;
|
||||
|
||||
typedef struct sRELMODELmodel
|
||||
|
|
|
|||
Loading…
Reference in New Issue