From a3534e29548f8cb9d598cf7a8a9d8083f1eb62d9 Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Thu, 9 Jun 2016 18:27:33 +0200 Subject: [PATCH] Some fixes for the Reliability Analysis --- src/spicelib/devices/bsim4/b4reliability.c | 198 +++++++++++++-------- src/spicelib/devices/bsim4/b4set.c | 6 + src/spicelib/devices/bsim4/b4temp.c | 2 +- src/spicelib/devices/bsim4/bsim4def.h | 5 + 4 files changed, 140 insertions(+), 71 deletions(-) diff --git a/src/spicelib/devices/bsim4/b4reliability.c b/src/spicelib/devices/bsim4/b4reliability.c index 5005249ba..27e2b49c7 100644 --- a/src/spicelib/devices/bsim4/b4reliability.c +++ b/src/spicelib/devices/bsim4/b4reliability.c @@ -164,89 +164,142 @@ 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 latest timestep - if (here->relStruct->IsON == 1) + if (NowIsON) { - // 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, 1e-12, 1) ; - if (ret == 1) + if (here->relStruct->IsON == 1) { - return (E_INTERN) ; + // 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 = 1 ; + + // Calculate Aging - Giorgio Liatis' Model + ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1e-12, 1) ; + if (ret == 1) + { + return (E_INTERN) ; + } + + // Update the semiperiod counter + here->relStruct->semiPeriods++ ; + } else if (here->relStruct->IsON == 0) { + // 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, 1e-12, 0) ; + if (ret == 1) + { + return (E_INTERN) ; + } + + // Update the semiperiod counter + here->relStruct->semiPeriods++ ; + } else { + fprintf (stderr, "Reliability Analysis Error\n") ; } - - // Update the semiperiod counter - here->relStruct->semiPeriods++ ; - } 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, 1e-12, 0) ; - if (ret == 1) - { - return (E_INTERN) ; - } - - // Update the semiperiod counter - here->relStruct->semiPeriods++ ; } else { - fprintf (stderr, "Reliability Analysis Error\n") ; + if (here->relStruct->IsON == 1) + { + // 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, 1e-12, 1) ; + if (ret == 1) + { + return (E_INTERN) ; + } + + // Update the semiperiod counter + here->relStruct->semiPeriods++ ; + } else if (here->relStruct->IsON == 0) { + // 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 = 0 ; + + // Calculate Aging - Giogio Liatis' Model + ret = RELMODELcalculateAging ((GENinstance *)here, here->BSIM4modPtr->BSIM4modType, delta, 1e-12, 0) ; + if (ret == 1) + { + return (E_INTERN) ; + } + + // Update the semiperiod counter + here->relStruct->semiPeriods++ ; + } else { + fprintf (stderr, "Reliability Analysis Error\n") ; + } + } + + if (here->relStruct->deltaVth > 0) { + model->number_of_aged_instances++ ; + model->total_deltaVth += here->relStruct->deltaVth * 1000 ; + + printf ("DEVICE OK!!!\tTime: %-.9gs\t\t", ckt->CKTtime) ; + 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) ; + } else if (here->relStruct->deltaVth > 0) { + printf ("\n\n\n\nWarning: PROBLEMATIC DEVICE!!!\tTime: %-.9gs\t\t", ckt->CKTtime) ; + printf ("DeltaVth: %-.9gmV\t\t", here->relStruct->deltaVth * 1000) ; + printf ("Device Name: %s\t\t", here->BSIM4name) ; + printf ("Device Type: %s\n\n\n\n\n\n", model->BSIM4modName) ; + } else { + printf ("THIS DEVICE IS OFF!!!\tTime: %-.9gs\t\t", ckt->CKTtime) ; + 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) ; } - printf ("\tTime: %-.9gs\t\t", ckt->CKTtime) ; - 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 */ - /* 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] = current->deltaVth ; - i++ ; - current = current->next ; - } - if (here->relStruct->semiPeriods > 1) { /* The model behavior is periodic - Use Fourier basis fitting */ + + double *deltaVthFit, f, factor_for_2pi, *fitting_matrix, target, *timeFit ; + RELMODELrelList *current ; + unsigned int columns, i, j, number_of_modes, number_of_periods, rows, size ; + + /* Count how many deltaVth we have */ + i = 0 ; + current = here->relStruct->deltaVthList ; + while (current != NULL) + { + i++ ; + current = current->next ; + } + + /* Assign list members to vectors */ + timeFit = TMALLOC (double, i) ; + deltaVthFit = TMALLOC (double, i) ; + + i = 0 ; + current = here->relStruct->deltaVthList ; + while (current != NULL) + { + timeFit [i] = current->time ; + deltaVthFit [i] = current->deltaVth ; + i++ ; + current = current->next ; + } + /* Generate the fitting matrix */ - - 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) ; @@ -358,6 +411,11 @@ BSIM4reliability (GENmodel *inModel, CKTcircuit *ckt, unsigned int mode) BSIM4reliability_internal (here, ckt, mode) ; } } + + if (mode == 1) { + printf ("Number of aged BSIM4 PMOS instances: %u\n\twith a mean DeltaVth of: %-.9gmV\n\n\n", + model->number_of_aged_instances, model->total_deltaVth / model->number_of_aged_instances) ; + } } } diff --git a/src/spicelib/devices/bsim4/b4set.c b/src/spicelib/devices/bsim4/b4set.c index b2f20e76f..f30e89b2e 100644 --- a/src/spicelib/devices/bsim4/b4set.c +++ b/src/spicelib/devices/bsim4/b4set.c @@ -2671,6 +2671,12 @@ do { if((here->ptr = SMPmakeElt(matrix,here->first,here->second))==(double *)NUL #endif } + +#ifdef RELAN + model->number_of_aged_instances = 0 ; + model->total_deltaVth = 0 ; +#endif + } #ifdef USE_OMP diff --git a/src/spicelib/devices/bsim4/b4temp.c b/src/spicelib/devices/bsim4/b4temp.c index 81908a030..cf8feb5ee 100644 --- a/src/spicelib/devices/bsim4/b4temp.c +++ b/src/spicelib/devices/bsim4/b4temp.c @@ -1721,7 +1721,7 @@ int Size_Not_Found, i; { if (here->relStruct->IsON != -1) { - here->BSIM4delvto = here->relStruct->deltaVth ; + here->BSIM4delvto = model->BSIM4type * here->relStruct->deltaVth ; } } #endif diff --git a/src/spicelib/devices/bsim4/bsim4def.h b/src/spicelib/devices/bsim4/bsim4def.h index 414998a5f..76d8bef44 100644 --- a/src/spicelib/devices/bsim4/bsim4def.h +++ b/src/spicelib/devices/bsim4/bsim4def.h @@ -2723,6 +2723,11 @@ typedef struct sBSIM4model unsigned BSIM4pku0weGiven :1; +#ifdef RELAN + unsigned int number_of_aged_instances ; + double total_deltaVth ; +#endif + } BSIM4model;