Implemented the final fitting to perform extrapolation at 10 years, when the model behavior is periodic, by using Fourier basis
This commit is contained in:
parent
dda38c9df2
commit
439e229972
|
|
@ -8,6 +8,7 @@ Author: 2015 Francesco Lannutti - July 2015
|
|||
#include "ngspice/sperror.h"
|
||||
|
||||
#include <gsl/gsl_fit.h>
|
||||
#include <gsl/gsl_linalg.h>
|
||||
|
||||
static int
|
||||
BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mode)
|
||||
|
|
@ -130,6 +131,9 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update the semiperiod counter
|
||||
here->relStruct->semiPeriods++ ;
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
@ -149,6 +153,9 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update the semiperiod counter
|
||||
here->relStruct->semiPeriods++ ;
|
||||
} else if (here->relStruct->IsON == 0) {
|
||||
// Until now, the device was OFF - Do NOTHING
|
||||
delta = -1 ;
|
||||
|
|
@ -173,6 +180,9 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update the semiperiod counter
|
||||
here->relStruct->semiPeriods++ ;
|
||||
} else if (here->relStruct->IsON == 0) {
|
||||
// Calculate recovery
|
||||
delta = ckt->CKTtime - here->relStruct->time ;
|
||||
|
|
@ -187,6 +197,9 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
{
|
||||
return (E_INTERN) ;
|
||||
}
|
||||
|
||||
// Update the semiperiod counter
|
||||
here->relStruct->semiPeriods++ ;
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
@ -197,7 +210,6 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
|
||||
|
||||
/* Calculate fitting */
|
||||
double c0, c1, cov00, cov01, cov11, chisq ;
|
||||
|
||||
/* Count how many deltaVth we have */
|
||||
unsigned int i ;
|
||||
|
|
@ -222,22 +234,125 @@ BSIM4reliability_internal (BSIM4instance *here, CKTcircuit *ckt, unsigned int mo
|
|||
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)) ;
|
||||
deltaVthFit [i] = 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) ;
|
||||
// printf ("Number of Semi Periods: %u\n", here->relStruct->semiPeriods) ;
|
||||
|
||||
/* Perform Extrapolation */
|
||||
double yFit, yFitErr ;
|
||||
gsl_fit_linear_est (2e-6, c0, c1, cov00, cov01, cov11, &yFit, &yFitErr) ;
|
||||
if (here->relStruct->semiPeriods > 1)
|
||||
{
|
||||
/* The model behavior is periodic - Use Fourier basis fitting */
|
||||
/* Generate the fitting matrix */
|
||||
|
||||
printf ("\n\tFitting -> %-.9gs\t%-.9gmV\n\n", 31536000.0, log (yFit) * 1000) ;
|
||||
double f, factor_for_2pi, *fitting_matrix, target ;
|
||||
unsigned int columns, j, number_of_modes, number_of_periods, rows, size ;
|
||||
|
||||
number_of_periods = here->relStruct->semiPeriods / 2 ;
|
||||
number_of_modes = 10 * (number_of_periods + 1) ;
|
||||
// printf ("Number of Periods: %u\n", number_of_periods) ;
|
||||
// printf ("Number of Modes: %u\n", number_of_modes) ;
|
||||
|
||||
rows = i ;
|
||||
columns = 2 * number_of_modes + 1 ;
|
||||
size = rows * columns ;
|
||||
fitting_matrix = TMALLOC (double, size) ;
|
||||
// printf ("Rows: %u\n", rows) ;
|
||||
// printf ("Columns: %u\n", columns) ;
|
||||
|
||||
factor_for_2pi = 2 * 3.14159265359 / (timeFit [rows - 1] - timeFit [0]) ;
|
||||
/* for (i = 0 ; i < rows ; i++)
|
||||
{
|
||||
printf ("Time: %-.9g\n", timeFit [i]) ;
|
||||
}
|
||||
printf ("Max Time: %-.9g\n", timeFit [rows - 1]) ;
|
||||
printf ("Min Time: %-.9g\n", timeFit [0]) ;
|
||||
*/
|
||||
for (i = 0 ; i < rows ; i++)
|
||||
{
|
||||
/* The first element of every row is equal to 1 */
|
||||
fitting_matrix [columns * i] = 1 ;
|
||||
|
||||
/* The odd elements of every row are cos(x) */
|
||||
for (j = 0 ; j < number_of_modes ; j++)
|
||||
{
|
||||
fitting_matrix [columns * i + 2 * j + 1] = cos ((j + 1) * timeFit [i] * factor_for_2pi) ;
|
||||
}
|
||||
|
||||
/* The even elements of every row are sin(x) */
|
||||
for (j = 1 ; j <= number_of_modes ; j++)
|
||||
{
|
||||
fitting_matrix [columns * i + 2 * j] = sin (j * timeFit [i] * factor_for_2pi) ;
|
||||
}
|
||||
}
|
||||
|
||||
gsl_matrix_view m = gsl_matrix_view_array (fitting_matrix, rows, columns) ;
|
||||
gsl_vector_view b = gsl_vector_view_array (deltaVthFit, rows) ;
|
||||
gsl_vector *tau = gsl_vector_alloc (MIN (rows, columns)) ;
|
||||
|
||||
gsl_vector *x = gsl_vector_alloc (columns) ;
|
||||
gsl_vector *residual = gsl_vector_alloc (rows) ;
|
||||
|
||||
gsl_linalg_QR_decomp (&m.matrix, tau) ;
|
||||
gsl_linalg_QR_lssolve (&m.matrix, tau, &b.vector, x, residual) ;
|
||||
|
||||
// printf ("fitting_matrix = \n") ;
|
||||
// gsl_matrix_fprintf (stdout, &m.matrix, "%g") ;
|
||||
// printf ("x = \n") ;
|
||||
// gsl_vector_fprintf (stdout, x, "%g") ;
|
||||
|
||||
target = 315360000.0 ;
|
||||
f = gsl_vector_get (x, 0) ;
|
||||
|
||||
/* The odd elements of every row are cos(x) */
|
||||
for (j = 0 ; j < number_of_modes ; j++)
|
||||
{
|
||||
f += gsl_vector_get (x, 2 * j + 1) * cos ((j + 1) * target * factor_for_2pi) ;
|
||||
}
|
||||
|
||||
/* The even elements of every row are sin(x) */
|
||||
for (j = 1 ; j <= number_of_modes ; j++)
|
||||
{
|
||||
f += gsl_vector_get (x, 2 * j) * sin (j * target * factor_for_2pi) ;
|
||||
}
|
||||
|
||||
printf ("\n\nExtrapolation at 10 years:\n\t\t\t\tDeltaVth: %-.9gmV\n\n\n\n", f * 1000) ;
|
||||
|
||||
/* Assign the extrapolated DeltaVth to the model */
|
||||
here->relStruct->deltaVth = f ;
|
||||
|
||||
gsl_vector_free (tau) ;
|
||||
gsl_vector_free (x) ;
|
||||
gsl_vector_free (residual) ;
|
||||
} else {
|
||||
/* Execute Fitting */
|
||||
double c0, c1, cov00, cov01, cov11, chisq, *deltaVthFitExp ;
|
||||
unsigned int j ;
|
||||
|
||||
deltaVthFitExp = TMALLOC (double, i) ;
|
||||
for (j = 0 ; j < i ; j++)
|
||||
{
|
||||
deltaVthFitExp [j] = exp (deltaVthFit [j]) ;
|
||||
}
|
||||
|
||||
gsl_fit_linear (timeFit, 1, deltaVthFitExp, 1, i, &c0, &c1, &cov00, &cov01, &cov11, &chisq) ;
|
||||
printf ("\n\n") ;
|
||||
printf ("c0: %-.9g\n", c0) ;
|
||||
printf ("c1: %-.9g\n", c1) ;
|
||||
printf ("cov00: %-.9g\n", cov00) ;
|
||||
printf ("cov01: %-.9g\n", cov01) ;
|
||||
printf ("cov11: %-.9g\n", cov11) ;
|
||||
printf ("chisq: %-.9g\n", chisq) ;
|
||||
printf ("\n\n") ;
|
||||
|
||||
/* Perform Extrapolation */
|
||||
double yFit, yFitErr ;
|
||||
gsl_fit_linear_est (315360000.0, c0, c1, cov00, cov01, cov11, &yFit, &yFitErr) ;
|
||||
|
||||
printf ("\n\tFitting -> %-.9gs\t%-.9gmV\n\n", 315360000.0, log (yFit) * 1000) ;
|
||||
printf ("\n\tFitting -> %-.9gs\t%-.9gmV\n\n", 315360000.0, log (c0 + c1 * 315360000.0) * 1000) ;
|
||||
}
|
||||
} else {
|
||||
fprintf (stderr, "Reliability Analysis Error\n") ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2660,10 +2660,13 @@ do { if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NUL
|
|||
{
|
||||
here->relStruct = TMALLOC (RELMODELrelStruct, 1) ;
|
||||
here->relStruct->time = 0 ;
|
||||
here->relStruct->offsetTime = 0 ;
|
||||
here->relStruct->deltaVth = 0 ;
|
||||
here->relStruct->deltaVthMax = 0 ;
|
||||
here->relStruct->t_star = 0 ;
|
||||
here->relStruct->IsON = -1 ;
|
||||
here->relStruct->deltaVthList = NULL ;
|
||||
here->relStruct->semiPeriods = 0 ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ listInsert (RELMODELrelList **list, double time, double deltaVth)
|
|||
int
|
||||
RELMODELcalculateAging (GENinstance *inInstance, int modType, double t_aging, unsigned int stress_or_recovery)
|
||||
{
|
||||
double A, Nt ;
|
||||
double A, i, Nt, step ;
|
||||
BSIM4instance *here ;
|
||||
RELMODELmodel *relmodel ;
|
||||
|
||||
|
|
@ -71,32 +71,44 @@ RELMODELcalculateAging (GENinstance *inInstance, int modType, double t_aging, un
|
|||
Nt = pow ((sqrt (relmodel->RELMODELnts)), 3) * 1e-21 ;
|
||||
A = (CHARGE / (4 * CONSTepsZero * 1e-9 * relmodel->RELMODELeps_hk)) * pow ((relmodel->RELMODELh_cut / (2 * sqrt (2 * relmodel->RELMODELm_star * relmodel->RELMODELw)) * 1e9), 2) ;
|
||||
|
||||
if (stress_or_recovery)
|
||||
// printf ("\n\nStart Aging...\n") ;
|
||||
// printf ("\tEnd step: %-.9g\n\n", here->relStruct->t_star + t_aging) ;
|
||||
step = 1e-12 ;
|
||||
for (i = 0 ; i < t_aging ; i += step)
|
||||
{
|
||||
if (relmodel->RELMODELh_cut / (2 * sqrt (2 * relmodel->RELMODELm_star * relmodel->RELMODELw)) * log (1 + pow (((t_aging + here->relStruct->t_star) / relmodel->RELMODELtau_0), relmodel->RELMODELbeta)) * 1e9 <= 2)
|
||||
if (stress_or_recovery)
|
||||
{
|
||||
here->relStruct->deltaVth = Nt * A * pow (log (1 + pow (((t_aging + here->relStruct->t_star) / relmodel->RELMODELtau_0), relmodel->RELMODELbeta)), 2) ;
|
||||
if (relmodel->RELMODELh_cut / (2 * sqrt (2 * relmodel->RELMODELm_star * relmodel->RELMODELw)) * log (1 + pow (((i + here->relStruct->t_star) / relmodel->RELMODELtau_0), relmodel->RELMODELbeta)) * 1e9 <= 2)
|
||||
{
|
||||
here->relStruct->deltaVth = Nt * A * pow (log (1 + pow (((i + here->relStruct->t_star) / relmodel->RELMODELtau_0), relmodel->RELMODELbeta)), 2) ;
|
||||
} else {
|
||||
here->relStruct->deltaVth = pow ((CHARGE / (4 * CONSTepsZero * 1e-9 * relmodel->RELMODELeps_hk)) * Nt * here->BSIM4modPtr->BSIM4toxe * 1e9, 2) ;
|
||||
}
|
||||
here->relStruct->deltaVthMax = here->relStruct->deltaVth ;
|
||||
} else {
|
||||
here->relStruct->deltaVth = pow ((CHARGE / (4 * CONSTepsZero * 1e-9 * relmodel->RELMODELeps_hk)) * Nt * here->BSIM4modPtr->BSIM4toxe * 1e9, 2) ;
|
||||
// printf ("\n\nDeltaVth Prior Recovery: %-.9gmV\n\n", here->relStruct->deltaVth * 1000) ;
|
||||
here->relStruct->deltaVth = here->relStruct->deltaVthMax * log (1 + (1.718 / (1 + pow ((i / relmodel->RELMODELtau_e), relmodel->RELMODELbeta1)))) ;
|
||||
}
|
||||
} else {
|
||||
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") ;
|
||||
/* Insert 'here->relStruct->deltaVth' into the list for the later fitting */
|
||||
listInsert (&(here->relStruct->deltaVthList), here->relStruct->offsetTime + i, here->relStruct->deltaVth) ;
|
||||
// printf ("\nStep: %-.9g\tDeltaVth: %-.9gmV\n\n", i, here->relStruct->deltaVth * 1000) ;
|
||||
// RELMODELrelList *temp ;
|
||||
// temp = TMALLOC (RELMODELrelList, 1) ;
|
||||
// temp->time = i + here->relStruct->t_star ;
|
||||
// temp->deltaVth = here->relStruct->deltaVth ;
|
||||
// temp->next = here->relStruct->deltaVthList ;
|
||||
// here->relStruct->deltaVthList = temp ;
|
||||
// printf ("QUI\n\n") ;
|
||||
}
|
||||
// printf ("Stop Aging...\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 ;
|
||||
}
|
||||
|
||||
here->relStruct->offsetTime += i ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ typedef struct sRELMODELrelList {
|
|||
|
||||
typedef struct sRELMODELrelStruct {
|
||||
double time ;
|
||||
double offsetTime ;
|
||||
double deltaVth ;
|
||||
double deltaVthMax ;
|
||||
double t_star ;
|
||||
int IsON ;
|
||||
RELMODELrelList *deltaVthList ;
|
||||
unsigned int semiPeriods ;
|
||||
} RELMODELrelStruct ;
|
||||
|
||||
typedef struct sRELMODELmodel
|
||||
|
|
|
|||
Loading…
Reference in New Issue