diff --git a/src/spicelib/devices/bsim4v4/b4v4ask.c b/src/spicelib/devices/bsim4v4/b4v4ask.c index 2e8e5b017..e3ee48b65 100644 --- a/src/spicelib/devices/bsim4v4/b4v4ask.c +++ b/src/spicelib/devices/bsim4v4/b4v4ask.c @@ -154,9 +154,11 @@ BSIM4v4instance *here = (BSIM4v4instance*)inst; return(OK); case BSIM4v4_SOURCECONDUCT: value->rValue = here->BSIM4v4sourceConductance; + value->rValue *= here->BSIM4v4m; return(OK); case BSIM4v4_DRAINCONDUCT: value->rValue = here->BSIM4v4drainConductance; + value->rValue *= here->BSIM4v4m; return(OK); case BSIM4v4_VBD: value->rValue = *(ckt->CKTstate0 + here->BSIM4v4vbd); @@ -305,6 +307,7 @@ BSIM4v4instance *here = (BSIM4v4instance*)inst; return(OK); case BSIM4v4_CBDB: value->rValue = here->BSIM4v4cbdb; + value->rValue *= here->BSIM4v4m; return(OK); case BSIM4v4_CBSB: value->rValue = here->BSIM4v4cbsb; diff --git a/src/spicelib/devices/bsim4v4/b4v4check.c b/src/spicelib/devices/bsim4v4/b4v4check.c index 7ce424855..63848d8b9 100644 --- a/src/spicelib/devices/bsim4v4/b4v4check.c +++ b/src/spicelib/devices/bsim4v4/b4v4check.c @@ -1,4 +1,5 @@ /**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/ +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. @@ -20,7 +21,6 @@ #include "const.h" #include "sperror.h" #include "devdefs.h" -#include "suffix.h" int BSIM4v4checkModel( @@ -32,18 +32,22 @@ struct bsim4SizeDependParam *pParam; int Fatal_Flag = 0; FILE *fplog; - if ((fplog = fopen("bsim4.out", "w")) != NULL) + NG_IGNORE(ckt); + + if ((fplog = fopen("bsim4v4.out", "w")) != NULL) { pParam = here->pParam; - fprintf(fplog, "BSIM4v4: Berkeley Short Channel IGFET Model-4\n"); + fprintf(fplog, "BSIM4: Berkeley Short Channel IGFET Model-4\n"); fprintf(fplog, "Developed by Xuemei (Jane) Xi, Jin He, Mohan Dunga, Prof. Ali Niknejad and Prof. Chenming Hu in 2003.\n"); fprintf(fplog, "\n"); - fprintf(fplog, "++++++++++ BSIM4v4 PARAMETER CHECKING BELOW ++++++++++\n"); + fprintf(fplog, "++++++++++ BSIM4v4 PARAMETER CHECKING BELOW ++++++++++\n"); - if ( !strstr( model->BSIM4v4version, "4.4" ) ) - { fprintf(fplog, "Warning: This model is BSIM4.4.0; you specified a wrong version number '%s'.\n",model->BSIM4v4version); - printf("Warning: This model is BSIM4.4.0; you specified a wrong version number '%s'.\n",model->BSIM4v4version); + if ((strcmp(model->BSIM4v4version, "4.4.0")) && (strcmp(model->BSIM4v4version, "4.40")) + && (strcmp(model->BSIM4v4version, "4.3.0")) && (strcmp(model->BSIM4v4version, "4.30")) + && (strcmp(model->BSIM4v4version, "4.2.1")) && (strcmp(model->BSIM4v4version, "4.21"))) + { fprintf(fplog, "Warning: This model supports BSIM4.2.1, 4.3.0 and 4.4.0; you specified a wrong version number.\n"); + printf("Warning: This model supports BSIM4.2.1, 4.3.0 and 4.4.0; you specified a wrong version number.\n"); } - fprintf(fplog, "Model = %s\n", model->BSIM4v4modName); + fprintf(fplog, "Model = %s\n", model->BSIM4v4modName); if ((here->BSIM4v4rgateMod == 2) || (here->BSIM4v4rgateMod == 3)) @@ -53,12 +57,13 @@ FILE *fplog; } } - if (model->BSIM4v4toxe <= 0.0) - { fprintf(fplog, "Fatal: Toxe = %g is not positive.\n", - model->BSIM4v4toxe); - printf("Fatal: Toxe = %g is not positive.\n", model->BSIM4v4toxe); - Fatal_Flag = 1; - } + + if (model->BSIM4v4toxe <= 0.0) + { fprintf(fplog, "Fatal: Toxe = %g is not positive.\n", + model->BSIM4v4toxe); + printf("Fatal: Toxe = %g is not positive.\n", model->BSIM4v4toxe); + Fatal_Flag = 1; + } if (model->BSIM4v4toxp <= 0.0) { fprintf(fplog, "Fatal: Toxp = %g is not positive.\n", model->BSIM4v4toxp); @@ -87,13 +92,41 @@ FILE *fplog; pParam->BSIM4v4lpe0); Fatal_Flag = 1; } - if (model->BSIM4v4lintnoi > pParam->BSIM4v4leff/2) - { fprintf(fplog, "Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", - model->BSIM4v4lintnoi); - printf("Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", - model->BSIM4v4lintnoi); - Fatal_Flag = 1; + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4phin < -0.4) + { fprintf(fplog, "Fatal: Phin = %g is less than -0.4.\n", + pParam->BSIM4v4phin); + printf("Fatal: Phin = %g is less than -0.4.\n", + pParam->BSIM4v4phin); + Fatal_Flag = 1; + } + break; + case BSIM4v40: + if (model->BSIM4v4lintnoi > pParam->BSIM4v4leff/2) + { fprintf(fplog, "Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", + model->BSIM4v4lintnoi); + printf("Fatal: Lintnoi = %g is too large - Leff for noise is negative.\n", + model->BSIM4v4lintnoi); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4phi <= 0.0) + { fprintf(fplog, "Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", + pParam->BSIM4v4phi); + fprintf(fplog, " Phin = %g Ndep = %g \n", + pParam->BSIM4v4phin, pParam->BSIM4v4ndep); + printf("Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", + pParam->BSIM4v4phi); + printf(" Phin = %g Ndep = %g \n", + pParam->BSIM4v4phin, pParam->BSIM4v4ndep); + Fatal_Flag = 1; + } + break; + default: break; } + + if (pParam->BSIM4v4lpeb < -pParam->BSIM4v4leff) { fprintf(fplog, "Fatal: Lpeb = %g is less than -Leff.\n", pParam->BSIM4v4lpeb); @@ -101,139 +134,194 @@ FILE *fplog; pParam->BSIM4v4lpeb); Fatal_Flag = 1; } - if (pParam->BSIM4v4ndep <= 0.0) - { fprintf(fplog, "Fatal: Ndep = %g is not positive.\n", - pParam->BSIM4v4ndep); - printf("Fatal: Ndep = %g is not positive.\n", - pParam->BSIM4v4ndep); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4phi <= 0.0) - { fprintf(fplog, "Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", - pParam->BSIM4v4phi); - fprintf(fplog, " Phin = %g Ndep = %g \n", - pParam->BSIM4v4phin, pParam->BSIM4v4ndep); - printf("Fatal: Phi = %g is not positive. Please check Phin and Ndep\n", - pParam->BSIM4v4phi); - printf(" Phin = %g Ndep = %g \n", - pParam->BSIM4v4phin, pParam->BSIM4v4ndep); + + if (pParam->BSIM4v4ndep <= 0.0) + { fprintf(fplog, "Fatal: Ndep = %g is not positive.\n", + pParam->BSIM4v4ndep); + printf("Fatal: Ndep = %g is not positive.\n", + pParam->BSIM4v4ndep); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4nsub <= 0.0) + { fprintf(fplog, "Fatal: Nsub = %g is not positive.\n", + pParam->BSIM4v4nsub); + printf("Fatal: Nsub = %g is not positive.\n", + pParam->BSIM4v4nsub); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4ngate < 0.0) + { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", + pParam->BSIM4v4ngate); + printf("Fatal: Ngate = %g Ngate is not positive.\n", + pParam->BSIM4v4ngate); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4ngate > 1.e25) + { fprintf(fplog, "Fatal: Ngate = %g is too high.\n", + pParam->BSIM4v4ngate); + printf("Fatal: Ngate = %g Ngate is too high\n", + pParam->BSIM4v4ngate); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4xj <= 0.0) + { fprintf(fplog, "Fatal: Xj = %g is not positive.\n", + pParam->BSIM4v4xj); + printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM4v4xj); Fatal_Flag = 1; } - if (pParam->BSIM4v4nsub <= 0.0) - { fprintf(fplog, "Fatal: Nsub = %g is not positive.\n", - pParam->BSIM4v4nsub); - printf("Fatal: Nsub = %g is not positive.\n", - pParam->BSIM4v4nsub); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4ngate < 0.0) - { fprintf(fplog, "Fatal: Ngate = %g is not positive.\n", - pParam->BSIM4v4ngate); - printf("Fatal: Ngate = %g Ngate is not positive.\n", - pParam->BSIM4v4ngate); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4ngate > 1.e25) - { fprintf(fplog, "Fatal: Ngate = %g is too high.\n", - pParam->BSIM4v4ngate); - printf("Fatal: Ngate = %g Ngate is too high\n", - pParam->BSIM4v4ngate); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4xj <= 0.0) - { fprintf(fplog, "Fatal: Xj = %g is not positive.\n", - pParam->BSIM4v4xj); - printf("Fatal: Xj = %g is not positive.\n", pParam->BSIM4v4xj); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4dvt1 < 0.0) - { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", - pParam->BSIM4v4dvt1); - printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM4v4dvt1); - Fatal_Flag = 1; - } - - if (pParam->BSIM4v4dvt1w < 0.0) - { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", - pParam->BSIM4v4dvt1w); - printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM4v4dvt1w); - Fatal_Flag = 1; - } - - if (pParam->BSIM4v4w0 == -pParam->BSIM4v4weff) - { fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); - printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); - Fatal_Flag = 1; + if (pParam->BSIM4v4dvt1 < 0.0) + { fprintf(fplog, "Fatal: Dvt1 = %g is negative.\n", + pParam->BSIM4v4dvt1); + printf("Fatal: Dvt1 = %g is negative.\n", pParam->BSIM4v4dvt1); + Fatal_Flag = 1; + } + + if (pParam->BSIM4v4dvt1w < 0.0) + { fprintf(fplog, "Fatal: Dvt1w = %g is negative.\n", + pParam->BSIM4v4dvt1w); + printf("Fatal: Dvt1w = %g is negative.\n", pParam->BSIM4v4dvt1w); + Fatal_Flag = 1; + } + + if (pParam->BSIM4v4w0 == -pParam->BSIM4v4weff) + { fprintf(fplog, "Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); + printf("Fatal: (W0 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; } - if (pParam->BSIM4v4dsub < 0.0) - { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM4v4dsub); - printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM4v4dsub); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4b1 == -pParam->BSIM4v4weff) - { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); - printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); - Fatal_Flag = 1; + if (pParam->BSIM4v4dsub < 0.0) + { fprintf(fplog, "Fatal: Dsub = %g is negative.\n", pParam->BSIM4v4dsub); + printf("Fatal: Dsub = %g is negative.\n", pParam->BSIM4v4dsub); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4b1 == -pParam->BSIM4v4weff) + { fprintf(fplog, "Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + printf("Fatal: (B1 + Weff) = 0 causing divided-by-zero.\n"); + Fatal_Flag = 1; } - if (here->BSIM4v4u0temp <= 0.0) - { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", here->BSIM4v4u0temp); - printf("Fatal: u0 at current temperature = %g is not positive.\n", - here->BSIM4v4u0temp); - Fatal_Flag = 1; + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + if (pParam->BSIM4v4u0temp <= 0.0) + { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", pParam->BSIM4v4u0temp); + printf("Fatal: u0 at current temperature = %g is not positive.\n", + pParam->BSIM4v4u0temp); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4vsattemp <= 0.0) + { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", pParam->BSIM4v4vsattemp); + printf("Fatal: Vsat at current temperature = %g is not positive.\n", + pParam->BSIM4v4vsattemp); + Fatal_Flag = 1; + } + break; + case BSIM4v30: case BSIM4v40: + if (here->BSIM4v4u0temp <= 0.0) + { fprintf(fplog, "Fatal: u0 at current temperature = %g is not positive.\n", here->BSIM4v4u0temp); + printf("Fatal: u0 at current temperature = %g is not positive.\n", + here->BSIM4v4u0temp); + Fatal_Flag = 1; + } + if (here->BSIM4v4vsattemp <= 0.0) + { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", here->BSIM4v4vsattemp); + printf("Fatal: Vsat at current temperature = %g is not positive.\n", + here->BSIM4v4vsattemp); + Fatal_Flag = 1; + } + break; + default: break; } if (pParam->BSIM4v4delta < 0.0) - { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", - pParam->BSIM4v4delta); - printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM4v4delta); - Fatal_Flag = 1; + { fprintf(fplog, "Fatal: Delta = %g is less than zero.\n", + pParam->BSIM4v4delta); + printf("Fatal: Delta = %g is less than zero.\n", pParam->BSIM4v4delta); + Fatal_Flag = 1; } - if (here->BSIM4v4vsattemp <= 0.0) - { fprintf(fplog, "Fatal: Vsat at current temperature = %g is not positive.\n", here->BSIM4v4vsattemp); - printf("Fatal: Vsat at current temperature = %g is not positive.\n", - here->BSIM4v4vsattemp); - Fatal_Flag = 1; - } - - if (pParam->BSIM4v4pclm <= 0.0) - { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM4v4pclm); - printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM4v4pclm); - Fatal_Flag = 1; - } - - if (pParam->BSIM4v4drout < 0.0) - { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM4v4drout); - printf("Fatal: Drout = %g is negative.\n", pParam->BSIM4v4drout); - Fatal_Flag = 1; - } - - if (here->BSIM4v4m <= 0.0) - { fprintf(fplog, "Fatal: multiplier = %g is not positive.\n", here->BSIM4v4m); - printf("Fatal: multiplier = %g is not positive.\n", here->BSIM4v4m); + if (pParam->BSIM4v4pclm <= 0.0) + { fprintf(fplog, "Fatal: Pclm = %g is not positive.\n", pParam->BSIM4v4pclm); + printf("Fatal: Pclm = %g is not positive.\n", pParam->BSIM4v4pclm); Fatal_Flag = 1; } + + if (pParam->BSIM4v4drout < 0.0) + { fprintf(fplog, "Fatal: Drout = %g is negative.\n", pParam->BSIM4v4drout); + printf("Fatal: Drout = %g is negative.\n", pParam->BSIM4v4drout); + Fatal_Flag = 1; + } + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4pscbe2 <= 0.0) + { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", + pParam->BSIM4v4pscbe2); + printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4v4pscbe2); + } + break; + case BSIM4v40: + break; + default: break; + } + if (here->BSIM4v4nf < 1.0) { fprintf(fplog, "Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4v4nf); printf("Fatal: Number of finger = %g is smaller than one.\n", here->BSIM4v4nf); Fatal_Flag = 1; } - if((here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && - ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) - { if (model->BSIM4v4saref <= 0.0) - { fprintf(fplog, "Fatal: SAref = %g is not positive.\n",model->BSIM4v4saref); - printf("Fatal: SAref = %g is not positive.\n",model->BSIM4v4saref); - Fatal_Flag = 1; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + break; + case BSIM4v40: + if((here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && + ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) + { if (model->BSIM4v4saref <= 0.0) + { fprintf(fplog, "Fatal: SAref = %g is not positive.\n",model->BSIM4v4saref); + printf("Fatal: SAref = %g is not positive.\n",model->BSIM4v4saref); + Fatal_Flag = 1; + } + if (model->BSIM4v4sbref <= 0.0) + { fprintf(fplog, "Fatal: SBref = %g is not positive.\n",model->BSIM4v4sbref); + printf("Fatal: SBref = %g is not positive.\n",model->BSIM4v4sbref); + Fatal_Flag = 1; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (model->BSIM4v4wlod < 0.0) + { fprintf(fplog, "Warning: WLOD = %g is less than 0. Set to 0.0\n",model->BSIM4v4wlod); + printf("Warning: WLOD = %g is less than 0.\n",model->BSIM4v4wlod); + model->BSIM4v4wlod = 0.0; + } + if (model->BSIM4v4kvsat < -1.0 ) + { fprintf(fplog, "Warning: KVSAT = %g is too small; Reset to -1.0.\n",model->BSIM4v4kvsat); + printf("Warning: KVSAT = %g is is too small; Reset to -1.0.\n",model->BSIM4v4kvsat); + model->BSIM4v4kvsat = -1.0; + } + if (model->BSIM4v4kvsat > 1.0) + { fprintf(fplog, "Warning: KVSAT = %g is too big; Reset to 1.0.\n",model->BSIM4v4kvsat); + printf("Warning: KVSAT = %g is too big; Reset to 1.0.\n",model->BSIM4v4kvsat); + model->BSIM4v4kvsat = 1.0; + } + if (model->BSIM4v4lodk2 <= 0.0) + { fprintf(fplog, "Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); + printf("Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); + } + if (model->BSIM4v4lodeta0 <= 0.0) + { fprintf(fplog, "Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); + printf("Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); + } + break; + case BSIM4v40: + break; + default: break; + } } - if (model->BSIM4v4sbref <= 0.0) - { fprintf(fplog, "Fatal: SBref = %g is not positive.\n",model->BSIM4v4sbref); - printf("Fatal: SBref = %g is not positive.\n",model->BSIM4v4sbref); - Fatal_Flag = 1; - } - } + break; + default: break; + } if ((here->BSIM4v4l + model->BSIM4v4xl) <= model->BSIM4v4xgl) { fprintf(fplog, "Fatal: The parameter xgl must be smaller than Ldrawn+XL.\n"); @@ -257,119 +345,194 @@ FILE *fplog; printf("Warning: Gbmin = %g is too small.\n", model->BSIM4v4gbmin); } - /* Check saturation parameters */ - if (pParam->BSIM4v4fprout < 0.0) - { fprintf(fplog, "Fatal: fprout = %g is negative.\n", - pParam->BSIM4v4fprout); - printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4v4fprout); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4pdits < 0.0) - { fprintf(fplog, "Fatal: pdits = %g is negative.\n", - pParam->BSIM4v4pdits); - printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4v4pdits); - Fatal_Flag = 1; - } - if (model->BSIM4v4pditsl < 0.0) - { fprintf(fplog, "Fatal: pditsl = %g is negative.\n", - model->BSIM4v4pditsl); - printf("Fatal: pditsl = %g is negative.\n", model->BSIM4v4pditsl); - Fatal_Flag = 1; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4noff < 0.1) + { fprintf(fplog, "Warning: Noff = %g is too small.\n", + pParam->BSIM4v4noff); + printf("Warning: Noff = %g is too small.\n", pParam->BSIM4v4noff); + } + + if (pParam->BSIM4v4voffcv < -0.5) + { fprintf(fplog, "Warning: Voffcv = %g is too small.\n", + pParam->BSIM4v4voffcv); + printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4v4voffcv); + } + break; + case BSIM4v40: + /* Check saturation parameters */ + if (pParam->BSIM4v4fprout < 0.0) + { fprintf(fplog, "Fatal: fprout = %g is negative.\n", + pParam->BSIM4v4fprout); + printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4v4fprout); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4pdits < 0.0) + { fprintf(fplog, "Fatal: pdits = %g is negative.\n", + pParam->BSIM4v4pdits); + printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4v4pdits); + Fatal_Flag = 1; + } + if (model->BSIM4v4pditsl < 0.0) + { fprintf(fplog, "Fatal: pditsl = %g is negative.\n", + model->BSIM4v4pditsl); + printf("Fatal: pditsl = %g is negative.\n", model->BSIM4v4pditsl); + Fatal_Flag = 1; + } + + /* Check gate current parameters */ + if (model->BSIM4v4igbMod) { + if (pParam->BSIM4v4nigbinv <= 0.0) + { fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n", + pParam->BSIM4v4nigbinv); + printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4v4nigbinv); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4nigbacc <= 0.0) + { fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n", + pParam->BSIM4v4nigbacc); + printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4v4nigbacc); + Fatal_Flag = 1; + } + } + if (model->BSIM4v4igcMod) { + if (pParam->BSIM4v4nigc <= 0.0) + { fprintf(fplog, "Fatal: nigc = %g is non-positive.\n", + pParam->BSIM4v4nigc); + printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4v4nigc); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4poxedge <= 0.0) + { fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n", + pParam->BSIM4v4poxedge); + printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4v4poxedge); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4pigcd <= 0.0) + { fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n", + pParam->BSIM4v4pigcd); + printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4v4pigcd); + Fatal_Flag = 1; + } + } + break; + default: break; } - /* Check gate current parameters */ - if (model->BSIM4v4igbMod) { - if (pParam->BSIM4v4nigbinv <= 0.0) - { fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n", - pParam->BSIM4v4nigbinv); - printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4v4nigbinv); - Fatal_Flag = 1; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + if (pParam->BSIM4v4noff > 4.0) + { fprintf(fplog, "Warning: Noff = %g is too large.\n", + pParam->BSIM4v4noff); + printf("Warning: Noff = %g is too large.\n", pParam->BSIM4v4noff); + } + if (pParam->BSIM4v4voffcv > 0.5) + { fprintf(fplog, "Warning: Voffcv = %g is too large.\n", + pParam->BSIM4v4voffcv); + printf("Warning: Voffcv = %g is too large.\n", pParam->BSIM4v4voffcv); + } + break; + case BSIM4v40: + break; + default: break; } - if (pParam->BSIM4v4nigbacc <= 0.0) - { fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n", - pParam->BSIM4v4nigbacc); - printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4v4nigbacc); - Fatal_Flag = 1; - } - } - if (model->BSIM4v4igcMod) { - if (pParam->BSIM4v4nigc <= 0.0) - { fprintf(fplog, "Fatal: nigc = %g is non-positive.\n", - pParam->BSIM4v4nigc); - printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4v4nigc); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4poxedge <= 0.0) - { fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n", - pParam->BSIM4v4poxedge); - printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4v4poxedge); - Fatal_Flag = 1; - } - if (pParam->BSIM4v4pigcd <= 0.0) - { fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n", - pParam->BSIM4v4pigcd); - printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4v4pigcd); - Fatal_Flag = 1; - } - } /* Check capacitance parameters */ if (pParam->BSIM4v4clc < 0.0) - { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM4v4clc); - printf("Fatal: Clc = %g is negative.\n", pParam->BSIM4v4clc); - Fatal_Flag = 1; + { fprintf(fplog, "Fatal: Clc = %g is negative.\n", pParam->BSIM4v4clc); + printf("Fatal: Clc = %g is negative.\n", pParam->BSIM4v4clc); + Fatal_Flag = 1; } - /* Check overlap capacitance parameters */ - if (pParam->BSIM4v4ckappas < 0.02) - { fprintf(fplog, "Warning: ckappas = %g is too small. Set to 0.02\n", - pParam->BSIM4v4ckappas); - printf("Warning: ckappas = %g is too small.\n", pParam->BSIM4v4ckappas); - pParam->BSIM4v4ckappas = 0.02; - } - if (pParam->BSIM4v4ckappad < 0.02) - { fprintf(fplog, "Warning: ckappad = %g is too small. Set to 0.02\n", - pParam->BSIM4v4ckappad); - printf("Warning: ckappad = %g is too small.\n", pParam->BSIM4v4ckappad); - pParam->BSIM4v4ckappad = 0.02; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4moin < 5.0) + { fprintf(fplog, "Warning: Moin = %g is too small.\n", + pParam->BSIM4v4moin); + printf("Warning: Moin = %g is too small.\n", pParam->BSIM4v4moin); + } + if (pParam->BSIM4v4moin > 25.0) + { fprintf(fplog, "Warning: Moin = %g is too large.\n", + pParam->BSIM4v4moin); + printf("Warning: Moin = %g is too large.\n", pParam->BSIM4v4moin); + } + if(model->BSIM4v4capMod ==2) { + if (pParam->BSIM4v4acde < 0.1) + { fprintf(fplog, "Warning: Acde = %g is too small.\n", + pParam->BSIM4v4acde); + printf("Warning: Acde = %g is too small.\n", pParam->BSIM4v4acde); + } + if (pParam->BSIM4v4acde > 1.6) + { fprintf(fplog, "Warning: Acde = %g is too large.\n", + pParam->BSIM4v4acde); + printf("Warning: Acde = %g is too large.\n", pParam->BSIM4v4acde); + } + } + break; + case BSIM4v40: + break; + default: break; + } + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + break; + case BSIM4v40: + /* Check overlap capacitance parameters */ + if (pParam->BSIM4v4ckappas < 0.02) + { fprintf(fplog, "Warning: ckappas = %g is too small. Set to 0.02\n", + pParam->BSIM4v4ckappas); + printf("Warning: ckappas = %g is too small.\n", pParam->BSIM4v4ckappas); + pParam->BSIM4v4ckappas = 0.02; + } + if (pParam->BSIM4v4ckappad < 0.02) + { fprintf(fplog, "Warning: ckappad = %g is too small. Set to 0.02\n", + pParam->BSIM4v4ckappad); + printf("Warning: ckappad = %g is too small.\n", pParam->BSIM4v4ckappad); + pParam->BSIM4v4ckappad = 0.02; + } + break; + default: break; } if (model->BSIM4v4paramChk ==1) { /* Check L and W parameters */ - if (pParam->BSIM4v4leff <= 1.0e-9) - { fprintf(fplog, "Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", - pParam->BSIM4v4leff); - printf("Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", - pParam->BSIM4v4leff); - } - - if (pParam->BSIM4v4leffCV <= 1.0e-9) - { fprintf(fplog, "Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", - pParam->BSIM4v4leffCV); - printf("Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", - pParam->BSIM4v4leffCV); - } - + if (pParam->BSIM4v4leff <= 1.0e-9) + { fprintf(fplog, "Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", + pParam->BSIM4v4leff); + printf("Warning: Leff = %g <= 1.0e-9. Recommended Leff >= 1e-8 \n", + pParam->BSIM4v4leff); + } + + if (pParam->BSIM4v4leffCV <= 1.0e-9) + { fprintf(fplog, "Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", + pParam->BSIM4v4leffCV); + printf("Warning: Leff for CV = %g <= 1.0e-9. Recommended LeffCV >=1e-8 \n", + pParam->BSIM4v4leffCV); + } + if (pParam->BSIM4v4weff <= 1.0e-9) - { fprintf(fplog, "Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", - pParam->BSIM4v4weff); - printf("Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", - pParam->BSIM4v4weff); - } - - if (pParam->BSIM4v4weffCV <= 1.0e-9) - { fprintf(fplog, "Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", - pParam->BSIM4v4weffCV); - printf("Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", - pParam->BSIM4v4weffCV); - } - + { fprintf(fplog, "Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", + pParam->BSIM4v4weff); + printf("Warning: Weff = %g <= 1.0e-9. Recommended Weff >=1e-7 \n", + pParam->BSIM4v4weff); + } + + if (pParam->BSIM4v4weffCV <= 1.0e-9) + { fprintf(fplog, "Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", + pParam->BSIM4v4weffCV); + printf("Warning: Weff for CV = %g <= 1.0e-9. Recommended WeffCV >= 1e-7 \n", + pParam->BSIM4v4weffCV); + } + /* Check threshold voltage parameters */ - if (model->BSIM4v4toxe < 1.0e-10) - { fprintf(fplog, "Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", - model->BSIM4v4toxe); - printf("Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", model->BSIM4v4toxe); + if (model->BSIM4v4toxe < 1.0e-10) + { fprintf(fplog, "Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", + model->BSIM4v4toxe); + printf("Warning: Toxe = %g is less than 1A. Recommended Toxe >= 5A\n", model->BSIM4v4toxe); } if (model->BSIM4v4toxp < 1.0e-10) { fprintf(fplog, "Warning: Toxp = %g is less than 1A. Recommended Toxp >= 5A\n", @@ -383,95 +546,131 @@ FILE *fplog; } if (pParam->BSIM4v4ndep <= 1.0e12) - { fprintf(fplog, "Warning: Ndep = %g may be too small.\n", - pParam->BSIM4v4ndep); - printf("Warning: Ndep = %g may be too small.\n", - pParam->BSIM4v4ndep); - } - else if (pParam->BSIM4v4ndep >= 1.0e21) - { fprintf(fplog, "Warning: Ndep = %g may be too large.\n", - pParam->BSIM4v4ndep); - printf("Warning: Ndep = %g may be too large.\n", - pParam->BSIM4v4ndep); - } + { fprintf(fplog, "Warning: Ndep = %g may be too small.\n", + pParam->BSIM4v4ndep); + printf("Warning: Ndep = %g may be too small.\n", + pParam->BSIM4v4ndep); + } + else if (pParam->BSIM4v4ndep >= 1.0e21) + { fprintf(fplog, "Warning: Ndep = %g may be too large.\n", + pParam->BSIM4v4ndep); + printf("Warning: Ndep = %g may be too large.\n", + pParam->BSIM4v4ndep); + } - if (pParam->BSIM4v4nsub <= 1.0e14) - { fprintf(fplog, "Warning: Nsub = %g may be too small.\n", - pParam->BSIM4v4nsub); - printf("Warning: Nsub = %g may be too small.\n", - pParam->BSIM4v4nsub); - } - else if (pParam->BSIM4v4nsub >= 1.0e21) - { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", - pParam->BSIM4v4nsub); - printf("Warning: Nsub = %g may be too large.\n", - pParam->BSIM4v4nsub); - } + if (pParam->BSIM4v4nsub <= 1.0e14) + { fprintf(fplog, "Warning: Nsub = %g may be too small.\n", + pParam->BSIM4v4nsub); + printf("Warning: Nsub = %g may be too small.\n", + pParam->BSIM4v4nsub); + } + else if (pParam->BSIM4v4nsub >= 1.0e21) + { fprintf(fplog, "Warning: Nsub = %g may be too large.\n", + pParam->BSIM4v4nsub); + printf("Warning: Nsub = %g may be too large.\n", + pParam->BSIM4v4nsub); + } - if ((pParam->BSIM4v4ngate > 0.0) && - (pParam->BSIM4v4ngate <= 1.e18)) - { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", - pParam->BSIM4v4ngate); - printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", - pParam->BSIM4v4ngate); - } + if ((pParam->BSIM4v4ngate > 0.0) && + (pParam->BSIM4v4ngate <= 1.e18)) + { fprintf(fplog, "Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->BSIM4v4ngate); + printf("Warning: Ngate = %g is less than 1.E18cm^-3.\n", + pParam->BSIM4v4ngate); + } if (pParam->BSIM4v4dvt0 < 0.0) - { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", - pParam->BSIM4v4dvt0); - printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM4v4dvt0); - } - - if (fabs(1.0e-8 / (pParam->BSIM4v4w0 + pParam->BSIM4v4weff)) > 10.0) - { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); - printf("Warning: (W0 + Weff) may be too small.\n"); + { fprintf(fplog, "Warning: Dvt0 = %g is negative.\n", + pParam->BSIM4v4dvt0); + printf("Warning: Dvt0 = %g is negative.\n", pParam->BSIM4v4dvt0); + } + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (fabs(1.0e-6 / (pParam->BSIM4v4w0 + pParam->BSIM4v4weff)) > 10.0) + { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf("Warning: (W0 + Weff) may be too small.\n"); + } + break; + case BSIM4v40: + if (fabs(1.0e-8 / (pParam->BSIM4v4w0 + pParam->BSIM4v4weff)) > 10.0) + { fprintf(fplog, "Warning: (W0 + Weff) may be too small.\n"); + printf("Warning: (W0 + Weff) may be too small.\n"); + } + break; + default: break; } /* Check subthreshold parameters */ - if (pParam->BSIM4v4nfactor < 0.0) - { fprintf(fplog, "Warning: Nfactor = %g is negative.\n", - pParam->BSIM4v4nfactor); - printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM4v4nfactor); - } - if (pParam->BSIM4v4cdsc < 0.0) - { fprintf(fplog, "Warning: Cdsc = %g is negative.\n", - pParam->BSIM4v4cdsc); - printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM4v4cdsc); - } - if (pParam->BSIM4v4cdscd < 0.0) - { fprintf(fplog, "Warning: Cdscd = %g is negative.\n", - pParam->BSIM4v4cdscd); - printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM4v4cdscd); - } + if (pParam->BSIM4v4nfactor < 0.0) + { fprintf(fplog, "Warning: Nfactor = %g is negative.\n", + pParam->BSIM4v4nfactor); + printf("Warning: Nfactor = %g is negative.\n", pParam->BSIM4v4nfactor); + } + if (pParam->BSIM4v4cdsc < 0.0) + { fprintf(fplog, "Warning: Cdsc = %g is negative.\n", + pParam->BSIM4v4cdsc); + printf("Warning: Cdsc = %g is negative.\n", pParam->BSIM4v4cdsc); + } + if (pParam->BSIM4v4cdscd < 0.0) + { fprintf(fplog, "Warning: Cdscd = %g is negative.\n", + pParam->BSIM4v4cdscd); + printf("Warning: Cdscd = %g is negative.\n", pParam->BSIM4v4cdscd); + } /* Check DIBL parameters */ - if (here->BSIM4v4eta0 < 0.0) - { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", - here->BSIM4v4eta0); - printf("Warning: Eta0 = %g is negative.\n", here->BSIM4v4eta0); - } - -/* Check Abulk parameters */ - if (fabs(1.0e-8 / (pParam->BSIM4v4b1 + pParam->BSIM4v4weff)) > 10.0) - { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); - printf("Warning: (B1 + Weff) may be too small.\n"); - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + if (pParam->BSIM4v4eta0 < 0.0) + { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", + pParam->BSIM4v4eta0); + printf("Warning: Eta0 = %g is negative.\n", pParam->BSIM4v4eta0); + } + break; + case BSIM4v40: + if (here->BSIM4v4eta0 < 0.0) + { fprintf(fplog, "Warning: Eta0 = %g is negative.\n", + here->BSIM4v4eta0); + printf("Warning: Eta0 = %g is negative.\n", here->BSIM4v4eta0); + } + break; + default: break; + } + +/* Check Abulk parameters */ + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (fabs(1.0e-6 / (pParam->BSIM4v4b1 + pParam->BSIM4v4weff)) > 10.0) + { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf("Warning: (B1 + Weff) may be too small.\n"); + } + break; + case BSIM4v40: + if (fabs(1.0e-8 / (pParam->BSIM4v4b1 + pParam->BSIM4v4weff)) > 10.0) + { fprintf(fplog, "Warning: (B1 + Weff) may be too small.\n"); + printf("Warning: (B1 + Weff) may be too small.\n"); + } + break; + default: break; + } /* Check Saturation parameters */ - if (pParam->BSIM4v4a2 < 0.01) - { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM4v4a2); - printf("Warning: A2 = %g is too small. Set to 0.01.\n", - pParam->BSIM4v4a2); - pParam->BSIM4v4a2 = 0.01; - } - else if (pParam->BSIM4v4a2 > 1.0) - { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", - pParam->BSIM4v4a2); - printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", - pParam->BSIM4v4a2); - pParam->BSIM4v4a2 = 1.0; - pParam->BSIM4v4a1 = 0.0; - } + if (pParam->BSIM4v4a2 < 0.01) + { fprintf(fplog, "Warning: A2 = %g is too small. Set to 0.01.\n", pParam->BSIM4v4a2); + printf("Warning: A2 = %g is too small. Set to 0.01.\n", + pParam->BSIM4v4a2); + pParam->BSIM4v4a2 = 0.01; + } + else if (pParam->BSIM4v4a2 > 1.0) + { fprintf(fplog, "Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->BSIM4v4a2); + printf("Warning: A2 = %g is larger than 1. A2 is set to 1 and A1 is set to 0.\n", + pParam->BSIM4v4a2); + pParam->BSIM4v4a2 = 1.0; + pParam->BSIM4v4a1 = 0.0; + + } if (pParam->BSIM4v4prwg < 0.0) { fprintf(fplog, "Warning: Prwg = %g is negative. Set to zero.\n", @@ -480,23 +679,21 @@ FILE *fplog; pParam->BSIM4v4prwg); pParam->BSIM4v4prwg = 0.0; } - - if (pParam->BSIM4v4rdsw < 0.0) - { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", - pParam->BSIM4v4rdsw); - printf("Warning: Rdsw = %g is negative. Set to zero.\n", - pParam->BSIM4v4rdsw); - pParam->BSIM4v4rdsw = 0.0; - pParam->BSIM4v4rds0 = 0.0; - } - - if (pParam->BSIM4v4rds0 < 0.0) - { fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n", - pParam->BSIM4v4rds0); - printf("Warning: Rds at current temperature = %g is negative. Set to zero.\n", - pParam->BSIM4v4rds0); - pParam->BSIM4v4rds0 = 0.0; - } + if (pParam->BSIM4v4rdsw < 0.0) + { fprintf(fplog, "Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->BSIM4v4rdsw); + printf("Warning: Rdsw = %g is negative. Set to zero.\n", + pParam->BSIM4v4rdsw); + pParam->BSIM4v4rdsw = 0.0; + pParam->BSIM4v4rds0 = 0.0; + } + if (pParam->BSIM4v4rds0 < 0.0) + { fprintf(fplog, "Warning: Rds at current temperature = %g is negative. Set to zero.\n", + pParam->BSIM4v4rds0); + printf("Warning: Rds at current temperature = %g is negative. Set to zero.\n", + pParam->BSIM4v4rds0); + pParam->BSIM4v4rds0 = 0.0; + } if (pParam->BSIM4v4rdswmin < 0.0) { fprintf(fplog, "Warning: Rdswmin at current temperature = %g is negative. Set to zero.\n", @@ -506,74 +703,151 @@ FILE *fplog; pParam->BSIM4v4rdswmin = 0.0; } - if (pParam->BSIM4v4pscbe2 <= 0.0) - { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", - pParam->BSIM4v4pscbe2); - printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4v4pscbe2); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (pParam->BSIM4v4pscbe2 <= 0.0) + { fprintf(fplog, "Warning: Pscbe2 = %g is not positive.\n", + pParam->BSIM4v4pscbe2); + printf("Warning: Pscbe2 = %g is not positive.\n", pParam->BSIM4v4pscbe2); + } + break; + default: break; } if (pParam->BSIM4v4vsattemp < 1.0e3) - { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4v4vsattemp); - printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4v4vsattemp); - } + { fprintf(fplog, "Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4v4vsattemp); + printf("Warning: Vsat at current temperature = %g may be too small.\n", pParam->BSIM4v4vsattemp); + } - if((model->BSIM4v4lambdaGiven) && (pParam->BSIM4v4lambda > 0.0) ) - { - if (pParam->BSIM4v4lambda > 1.0e-9) - { fprintf(fplog, "Warning: Lambda = %g may be too large.\n", pParam->BSIM4v4lambda); - printf("Warning: Lambda = %g may be too large.\n", pParam->BSIM4v4lambda); - } - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if((model->BSIM4v4lambdaGiven) && (pParam->BSIM4v4lambda > 0.0) ) + { + if (pParam->BSIM4v4lambda > 1.0e-9) + { fprintf(fplog, "Warning: Lambda = %g may be too large.\n", pParam->BSIM4v4lambda); + printf("Warning: Lambda = %g may be too large.\n", pParam->BSIM4v4lambda); + } + } + + if((model->BSIM4v4vtlGiven) && (pParam->BSIM4v4vtl > 0.0) ) + { + if (pParam->BSIM4v4vtl < 6.0e4) + { fprintf(fplog, "Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4v4vtl); + printf("Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4v4vtl); + } + + if (pParam->BSIM4v4xn < 3.0) + { fprintf(fplog, "Warning: back scattering coeff xn = %g is too small.\n", pParam->BSIM4v4xn); + printf("Warning: back scattering coeff xn = %g is too small. Reset to 3.0 \n", pParam->BSIM4v4xn); + pParam->BSIM4v4xn = 3.0; + + } + if (model->BSIM4v4lc < 0.0) + { fprintf(fplog, "Warning: back scattering coeff lc = %g is too small.\n", model->BSIM4v4lc); + printf("Warning: back scattering coeff lc = %g is too small. Reset to 0.0\n", model->BSIM4v4lc); + pParam->BSIM4v4lc = 0.0; + } + } + break; + default: break; + } - if((model->BSIM4v4vtlGiven) && (pParam->BSIM4v4vtl > 0.0) ) - { - if (pParam->BSIM4v4vtl < 6.0e4) - { fprintf(fplog, "Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4v4vtl); - printf("Warning: Thermal velocity vtl = %g may be too small.\n", pParam->BSIM4v4vtl); - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4fprout < 0.0) + { fprintf(fplog, "Fatal: fprout = %g is negative.\n", + pParam->BSIM4v4fprout); + printf("Fatal: fprout = %g is negative.\n", pParam->BSIM4v4fprout); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4pdits < 0.0) + { fprintf(fplog, "Fatal: pdits = %g is negative.\n", + pParam->BSIM4v4pdits); + printf("Fatal: pdits = %g is negative.\n", pParam->BSIM4v4pdits); + Fatal_Flag = 1; + } + if (model->BSIM4v4pditsl < 0.0) + { fprintf(fplog, "Fatal: pditsl = %g is negative.\n", + model->BSIM4v4pditsl); + printf("Fatal: pditsl = %g is negative.\n", model->BSIM4v4pditsl); + Fatal_Flag = 1; + } + break; + case BSIM4v40: + break; + default: break; + } - if (pParam->BSIM4v4xn < 3.0) - { fprintf(fplog, "Warning: back scattering coeff xn = %g is too small.\n", pParam->BSIM4v4xn); - printf("Warning: back scattering coeff xn = %g is too small. Reset to 3.0 \n", pParam->BSIM4v4xn); - pParam->BSIM4v4xn = 3.0; - } - - if (model->BSIM4v4lc < 0.0) - { fprintf(fplog, "Warning: back scattering coeff lc = %g is too small.\n", model->BSIM4v4lc); - printf("Warning: back scattering coeff lc = %g is too small. Reset to 0.0\n", model->BSIM4v4lc); - pParam->BSIM4v4lc = 0.0; - } - } - - if (pParam->BSIM4v4pdibl1 < 0.0) - { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", - pParam->BSIM4v4pdibl1); - printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM4v4pdibl1); - } - if (pParam->BSIM4v4pdibl2 < 0.0) - { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", - pParam->BSIM4v4pdibl2); - printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM4v4pdibl2); - } + if (pParam->BSIM4v4pdibl1 < 0.0) + { fprintf(fplog, "Warning: Pdibl1 = %g is negative.\n", + pParam->BSIM4v4pdibl1); + printf("Warning: Pdibl1 = %g is negative.\n", pParam->BSIM4v4pdibl1); + } + if (pParam->BSIM4v4pdibl2 < 0.0) + { fprintf(fplog, "Warning: Pdibl2 = %g is negative.\n", + pParam->BSIM4v4pdibl2); + printf("Warning: Pdibl2 = %g is negative.\n", pParam->BSIM4v4pdibl2); + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (pParam->BSIM4v4nigbinv <= 0.0) + { fprintf(fplog, "Fatal: nigbinv = %g is non-positive.\n", + pParam->BSIM4v4nigbinv); + printf("Fatal: nigbinv = %g is non-positive.\n", pParam->BSIM4v4nigbinv); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4nigbacc <= 0.0) + { fprintf(fplog, "Fatal: nigbacc = %g is non-positive.\n", + pParam->BSIM4v4nigbacc); + printf("Fatal: nigbacc = %g is non-positive.\n", pParam->BSIM4v4nigbacc); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4nigc <= 0.0) + { fprintf(fplog, "Fatal: nigc = %g is non-positive.\n", + pParam->BSIM4v4nigc); + printf("Fatal: nigc = %g is non-positive.\n", pParam->BSIM4v4nigc); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4poxedge <= 0.0) + { fprintf(fplog, "Fatal: poxedge = %g is non-positive.\n", + pParam->BSIM4v4poxedge); + printf("Fatal: poxedge = %g is non-positive.\n", pParam->BSIM4v4poxedge); + Fatal_Flag = 1; + } + if (pParam->BSIM4v4pigcd <= 0.0) + { fprintf(fplog, "Fatal: pigcd = %g is non-positive.\n", + pParam->BSIM4v4pigcd); + printf("Fatal: pigcd = %g is non-positive.\n", pParam->BSIM4v4pigcd); + Fatal_Flag = 1; + } + break; + case BSIM4v40: /* Check stress effect parameters */ - if((here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && - ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) - { if (model->BSIM4v4lodk2 <= 0.0) - { fprintf(fplog, "Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); - printf("Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); - } - if (model->BSIM4v4lodeta0 <= 0.0) - { fprintf(fplog, "Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); - printf("Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); - } - } - + if((here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && + ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) + { if (model->BSIM4v4lodk2 <= 0.0) + { fprintf(fplog, "Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); + printf("Warning: LODK2 = %g is not positive.\n",model->BSIM4v4lodk2); + } + if (model->BSIM4v4lodeta0 <= 0.0) + { fprintf(fplog, "Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); + printf("Warning: LODETA0 = %g is not positive.\n",model->BSIM4v4lodeta0); + } + } + break; + default: break; + } + /* Check gate resistance parameters */ if (here->BSIM4v4rgateMod == 1) { if (model->BSIM4v4rshg <= 0.0) - printf("Warning: rshg should be positive for rgateMod = 1.\n"); - } + printf("Warning: rshg should be positive for rgateMod = 1.\n"); + } else if (here->BSIM4v4rgateMod == 2) { if (model->BSIM4v4rshg <= 0.0) printf("Warning: rshg <= 0.0 for rgateMod = 2.\n"); @@ -587,145 +861,164 @@ FILE *fplog; printf("Warning: xrcrg1 should be positive for rgateMod = 3.\n"); } -/* Check capacitance parameters */ - if (pParam->BSIM4v4noff < 0.1) - { fprintf(fplog, "Warning: Noff = %g is too small.\n", - pParam->BSIM4v4noff); - printf("Warning: Noff = %g is too small.\n", pParam->BSIM4v4noff); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + /* Check capacitance parameters */ + if (pParam->BSIM4v4noff < 0.1) + { fprintf(fplog, "Warning: Noff = %g is too small.\n", + pParam->BSIM4v4noff); + printf("Warning: Noff = %g is too small.\n", pParam->BSIM4v4noff); + } + + if (pParam->BSIM4v4voffcv < -0.5) + { fprintf(fplog, "Warning: Voffcv = %g is too small.\n", + pParam->BSIM4v4voffcv); + printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4v4voffcv); + } + + if (pParam->BSIM4v4moin < 5.0) + { fprintf(fplog, "Warning: Moin = %g is too small.\n", + pParam->BSIM4v4moin); + printf("Warning: Moin = %g is too small.\n", pParam->BSIM4v4moin); + } + if (pParam->BSIM4v4moin > 25.0) + { fprintf(fplog, "Warning: Moin = %g is too large.\n", + pParam->BSIM4v4moin); + printf("Warning: Moin = %g is too large.\n", pParam->BSIM4v4moin); + } + if(model->BSIM4v4capMod ==2) { + if (pParam->BSIM4v4acde < 0.1) + { fprintf(fplog, "Warning: Acde = %g is too small.\n", + pParam->BSIM4v4acde); + printf("Warning: Acde = %g is too small.\n", pParam->BSIM4v4acde); + } + if (pParam->BSIM4v4acde > 1.6) + { fprintf(fplog, "Warning: Acde = %g is too large.\n", + pParam->BSIM4v4acde); + printf("Warning: Acde = %g is too large.\n", pParam->BSIM4v4acde); + } + } + break; + default: break; } - - if (pParam->BSIM4v4voffcv < -0.5) - { fprintf(fplog, "Warning: Voffcv = %g is too small.\n", - pParam->BSIM4v4voffcv); - printf("Warning: Voffcv = %g is too small.\n", pParam->BSIM4v4voffcv); - } - - if (pParam->BSIM4v4moin < 5.0) - { fprintf(fplog, "Warning: Moin = %g is too small.\n", - pParam->BSIM4v4moin); - printf("Warning: Moin = %g is too small.\n", pParam->BSIM4v4moin); - } - if (pParam->BSIM4v4moin > 25.0) - { fprintf(fplog, "Warning: Moin = %g is too large.\n", - pParam->BSIM4v4moin); - printf("Warning: Moin = %g is too large.\n", pParam->BSIM4v4moin); - } - if(model->BSIM4v4capMod ==2) { - if (pParam->BSIM4v4acde < 0.1) - { fprintf(fplog, "Warning: Acde = %g is too small.\n", - pParam->BSIM4v4acde); - printf("Warning: Acde = %g is too small.\n", pParam->BSIM4v4acde); - } - if (pParam->BSIM4v4acde > 1.6) - { fprintf(fplog, "Warning: Acde = %g is too large.\n", - pParam->BSIM4v4acde); - printf("Warning: Acde = %g is too large.\n", pParam->BSIM4v4acde); - } - } - /* Check overlap capacitance parameters */ if (model->BSIM4v4cgdo < 0.0) - { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4v4cgdo); - printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4v4cgdo); - model->BSIM4v4cgdo = 0.0; + { fprintf(fplog, "Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4v4cgdo); + printf("Warning: cgdo = %g is negative. Set to zero.\n", model->BSIM4v4cgdo); + model->BSIM4v4cgdo = 0.0; } if (model->BSIM4v4cgso < 0.0) - { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4v4cgso); - printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4v4cgso); - model->BSIM4v4cgso = 0.0; + { fprintf(fplog, "Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4v4cgso); + printf("Warning: cgso = %g is negative. Set to zero.\n", model->BSIM4v4cgso); + model->BSIM4v4cgso = 0.0; } - if (model->BSIM4v4tnoiMod == 1) { - if (model->BSIM4v4tnoia < 0.0) - { fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4v4tnoia); - printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4v4tnoia); - model->BSIM4v4tnoia = 0.0; - } - if (model->BSIM4v4tnoib < 0.0) - { fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4v4tnoib); - printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4v4tnoib); - model->BSIM4v4tnoib = 0.0; + if (model->BSIM4v4tnoiMod == 1) { + if (model->BSIM4v4tnoia < 0.0) + { fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4v4tnoia); + printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4v4tnoia); + model->BSIM4v4tnoia = 0.0; + } + if (model->BSIM4v4tnoib < 0.0) + { fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4v4tnoib); + printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4v4tnoib); + model->BSIM4v4tnoib = 0.0; + } + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (model->BSIM4v4rnoia < 0.0) + { fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4v4rnoia); + printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4v4rnoia); + model->BSIM4v4rnoia = 0.0; + } + if (model->BSIM4v4rnoib < 0.0) + { fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4v4rnoib); + printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4v4rnoib); + model->BSIM4v4rnoib = 0.0; + } + break; + default: break; + } } - if (model->BSIM4v4rnoia < 0.0) - { fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4v4rnoia); - printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4v4rnoia); - model->BSIM4v4rnoia = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (model->BSIM4v4SjctEmissionCoeff < 0.0) + { fprintf(fplog, "Warning: Njs = %g is negative.\n", + model->BSIM4v4SjctEmissionCoeff); + printf("Warning: Njs = %g is negative.\n", + model->BSIM4v4SjctEmissionCoeff); + } + if (model->BSIM4v4DjctEmissionCoeff < 0.0) + { fprintf(fplog, "Warning: Njd = %g is negative.\n", + model->BSIM4v4DjctEmissionCoeff); + printf("Warning: Njd = %g is negative.\n", + model->BSIM4v4DjctEmissionCoeff); + } + if (model->BSIM4v4njtstemp < 0.0) + { fprintf(fplog, "Warning: Njts = %g is negative at temperature = %g.\n", + model->BSIM4v4njtstemp, ckt->CKTtemp); + printf("Warning: Njts = %g is negative at temperature = %g.\n", + model->BSIM4v4njtstemp, ckt->CKTtemp); + } + if (model->BSIM4v4njtsswtemp < 0.0) + { fprintf(fplog, "Warning: Njtssw = %g is negative at temperature = %g.\n", + model->BSIM4v4njtsswtemp, ckt->CKTtemp); + printf("Warning: Njtssw = %g is negative at temperature = %g.\n", + model->BSIM4v4njtsswtemp, ckt->CKTtemp); + } + if (model->BSIM4v4njtsswgtemp < 0.0) + { fprintf(fplog, "Warning: Njtsswg = %g is negative at temperature = %g.\n", + model->BSIM4v4njtsswgtemp, ckt->CKTtemp); + printf("Warning: Njtsswg = %g is negative at temperature = %g.\n", + model->BSIM4v4njtsswgtemp, ckt->CKTtemp); + } + if (model->BSIM4v4vtss < 0.0) + { fprintf(fplog, "Warning: Vtss = %g is negative.\n", + model->BSIM4v4vtss); + printf("Warning: Vtss = %g is negative.\n", + model->BSIM4v4vtss); + } + if (model->BSIM4v4vtsd < 0.0) + { fprintf(fplog, "Warning: Vtsd = %g is negative.\n", + model->BSIM4v4vtsd); + printf("Warning: Vtsd = %g is negative.\n", + model->BSIM4v4vtsd); + } + if (model->BSIM4v4vtssws < 0.0) + { fprintf(fplog, "Warning: Vtssws = %g is negative.\n", + model->BSIM4v4vtssws); + printf("Warning: Vtssws = %g is negative.\n", + model->BSIM4v4vtssws); + } + if (model->BSIM4v4vtsswd < 0.0) + { fprintf(fplog, "Warning: Vtsswd = %g is negative.\n", + model->BSIM4v4vtsswd); + printf("Warning: Vtsswd = %g is negative.\n", + model->BSIM4v4vtsswd); + } + if (model->BSIM4v4vtsswgs < 0.0) + { fprintf(fplog, "Warning: Vtsswgs = %g is negative.\n", + model->BSIM4v4vtsswgs); + printf("Warning: Vtsswgs = %g is negative.\n", + model->BSIM4v4vtsswgs); + } + if (model->BSIM4v4vtsswgd < 0.0) + { fprintf(fplog, "Warning: Vtsswgd = %g is negative.\n", + model->BSIM4v4vtsswgd); + printf("Warning: Vtsswgd = %g is negative.\n", + model->BSIM4v4vtsswgd); + } + break; + default: break; } - if (model->BSIM4v4rnoib < 0.0) - { fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4v4rnoib); - printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4v4rnoib); - model->BSIM4v4rnoib = 0.0; - } - } - - if (model->BSIM4v4SjctEmissionCoeff < 0.0) - { fprintf(fplog, "Warning: Njs = %g is negative.\n", - model->BSIM4v4SjctEmissionCoeff); - printf("Warning: Njs = %g is negative.\n", - model->BSIM4v4SjctEmissionCoeff); - } - if (model->BSIM4v4DjctEmissionCoeff < 0.0) - { fprintf(fplog, "Warning: Njd = %g is negative.\n", - model->BSIM4v4DjctEmissionCoeff); - printf("Warning: Njd = %g is negative.\n", - model->BSIM4v4DjctEmissionCoeff); - } - if (model->BSIM4v4njtstemp < 0.0) - { fprintf(fplog, "Warning: Njts = %g is negative at temperature = %g.\n", - model->BSIM4v4njtstemp, ckt->CKTtemp); - printf("Warning: Njts = %g is negative at temperature = %g.\n", - model->BSIM4v4njtstemp, ckt->CKTtemp); - } - if (model->BSIM4v4njtsswtemp < 0.0) - { fprintf(fplog, "Warning: Njtssw = %g is negative at temperature = %g.\n", - model->BSIM4v4njtsswtemp, ckt->CKTtemp); - printf("Warning: Njtssw = %g is negative at temperature = %g.\n", - model->BSIM4v4njtsswtemp, ckt->CKTtemp); - } - if (model->BSIM4v4njtsswgtemp < 0.0) - { fprintf(fplog, "Warning: Njtsswg = %g is negative at temperature = %g.\n", - model->BSIM4v4njtsswgtemp, ckt->CKTtemp); - printf("Warning: Njtsswg = %g is negative at temperature = %g.\n", - model->BSIM4v4njtsswgtemp, ckt->CKTtemp); - } - if (model->BSIM4v4vtss < 0.0) - { fprintf(fplog, "Warning: Vtss = %g is negative.\n", - model->BSIM4v4vtss); - printf("Warning: Vtss = %g is negative.\n", - model->BSIM4v4vtss); - } - if (model->BSIM4v4vtsd < 0.0) - { fprintf(fplog, "Warning: Vtsd = %g is negative.\n", - model->BSIM4v4vtsd); - printf("Warning: Vtsd = %g is negative.\n", - model->BSIM4v4vtsd); - } - if (model->BSIM4v4vtssws < 0.0) - { fprintf(fplog, "Warning: Vtssws = %g is negative.\n", - model->BSIM4v4vtssws); - printf("Warning: Vtssws = %g is negative.\n", - model->BSIM4v4vtssws); - } - if (model->BSIM4v4vtsswd < 0.0) - { fprintf(fplog, "Warning: Vtsswd = %g is negative.\n", - model->BSIM4v4vtsswd); - printf("Warning: Vtsswd = %g is negative.\n", - model->BSIM4v4vtsswd); - } - if (model->BSIM4v4vtsswgs < 0.0) - { fprintf(fplog, "Warning: Vtsswgs = %g is negative.\n", - model->BSIM4v4vtsswgs); - printf("Warning: Vtsswgs = %g is negative.\n", - model->BSIM4v4vtsswgs); - } - if (model->BSIM4v4vtsswgd < 0.0) - { fprintf(fplog, "Warning: Vtsswgd = %g is negative.\n", - model->BSIM4v4vtsswgd); - printf("Warning: Vtsswgd = %g is negative.\n", - model->BSIM4v4vtsswgd); - } - if (model->BSIM4v4ntnoi < 0.0) { fprintf(fplog, "Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4v4ntnoi); printf("Warning: ntnoi = %g is negative. Set to zero.\n", model->BSIM4v4ntnoi); @@ -733,7 +1026,7 @@ FILE *fplog; } }/* loop for the parameter check for warning messages */ - fclose(fplog); + fclose(fplog); } else { fprintf(stderr, "Warning: Can't open log file. Parameter checking skipped.\n"); diff --git a/src/spicelib/devices/bsim4v4/b4v4ld.c b/src/spicelib/devices/bsim4v4/b4v4ld.c index 85c21db10..256f19240 100644 --- a/src/spicelib/devices/bsim4v4/b4v4ld.c +++ b/src/spicelib/devices/bsim4v4/b4v4ld.c @@ -2,6 +2,7 @@ BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 $Id$ ****/ +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. @@ -23,7 +24,6 @@ #include "const.h" #include "sperror.h" #include "devdefs.h" -#include "suffix.h" #define MAX_EXP 5.834617425e14 #define MIN_EXP 1.713908431e-15 @@ -66,7 +66,7 @@ double vgs_eff, vgd_eff, dvgs_eff_dvg, dvgd_eff_dvg; double dRs_dvg, dRd_dvg, dRs_dvb, dRd_dvb; double dT0_dvg, dT1_dvb, dT3_dvg, dT3_dvb; double vses, vdes, vdedo, delvses, delvded, delvdes; -double Isestot=0.0, cseshat=0.0, Idedtot=0.0, cdedhat=0.0; +double Isestot, cseshat, Idedtot, cdedhat; #ifndef NEWCONV double tol0, tol1, tol2, tol3, tol4, tol5, tol6; #endif @@ -91,46 +91,48 @@ double ceqqb, ceqqd, ceqqg, ceqqjd=0.0, ceqqjs=0.0, ceq, geq; double cdrain, cdhat=0.0, ceqdrn, ceqbd, ceqbs, ceqjd, ceqjs, gjbd, gjbs; double czbd, czbdsw, czbdswg, czbs, czbssw, czbsswg, evbd, evbs, arg, sarg; double delvbd, delvbs, delvds, delvgd, delvgs; -double Vfbeff, dVfbeff_dVg, dVfbeff_dVb, V3, V4; +double Vfbeff=0.0, dVfbeff_dVg=0.0, dVfbeff_dVb=0.0, V3, V4; double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb; double gcgbb, gcdbb, gcsbb, gcbbb; -double gcdbdb, gcsbsb; +double gcdbdb=0.0, gcsbsb=0.0; double gcsgb, gcssb, MJD, MJSWD, MJSWGD, MJS, MJSWS, MJSWGS; double qgate=0.0, qbulk=0.0, qdrn=0.0, qsrc, cqgate, cqbody, cqdrn; double Vdb, Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum; double Igidl, Ggidld, Ggidlg, Ggidlb; double Voxacc=0.0, dVoxacc_dVg=0.0, dVoxacc_dVb=0.0; double Voxdepinv=0.0, dVoxdepinv_dVg=0.0, dVoxdepinv_dVd=0.0, dVoxdepinv_dVb=0.0; -double VxNVt, ExpVxNVt, Vaux, dVaux_dVg, dVaux_dVd, dVaux_dVb; +double VxNVt=0.0, ExpVxNVt, Vaux=0.0, dVaux_dVg, dVaux_dVd, dVaux_dVb; double Igc, dIgc_dVg, dIgc_dVd, dIgc_dVb; double Igcs, dIgcs_dVg, dIgcs_dVd, dIgcs_dVb; double Igcd, dIgcd_dVg, dIgcd_dVd, dIgcd_dVb; double Igs, dIgs_dVg, dIgs_dVs, Igd, dIgd_dVg, dIgd_dVd; double Igbacc, dIgbacc_dVg, dIgbacc_dVb; double Igbinv, dIgbinv_dVg, dIgbinv_dVd, dIgbinv_dVb; + double Pigcd, dPigcd_dVg, dPigcd_dVd, dPigcd_dVb; double Istoteq, gIstotg, gIstotd, gIstots, gIstotb; double Idtoteq, gIdtotg, gIdtotd, gIdtots, gIdtotb; double Ibtoteq, gIbtotg, gIbtotd, gIbtots, gIbtotb; double Igtoteq, gIgtotg, gIgtotd, gIgtots, gIgtotb; -double Igstot=0.0, cgshat=0.0, Igdtot=0.0, cgdhat=0.0, Igbtot=0.0, cgbhat=0.0; +double Igstot, cgshat, Igdtot, cgdhat, Igbtot, cgbhat; double Vgs_eff, Vfb=0.0, Vth_NarrowW; -double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd; +double Phis=0.0, dPhis_dVb=0.0, sqrtPhis=0.0, dsqrtPhis_dVb=0.0, Vth=0.0, dVth_dVb=0.0, dVth_dVd=0.0; double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtms, Nvtmd; double Vtm; double n, dn_dVb, dn_dVd, voffcv, noff, dnoff_dVd, dnoff_dVb; double V0, CoxWLcen, QovCox, LINK; double DeltaPhi, dDeltaPhi_dVg; -double Cox, Tox, Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb; +double Cox=0.0, Tox=100e-09, Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb; double Ccen, Coxeff, dCoxeff_dVd, dCoxeff_dVg, dCoxeff_dVb; double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb; -double ueff, dueff_dVg, dueff_dVd, dueff_dVb; -double Esat, Vdsat; +double ueff=0.0, dueff_dVg, dueff_dVd, dueff_dVb; +double Esat=0.0, Vdsat; double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb; -double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; -double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; -double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb; -double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; + +double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb; +double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, dVa_dVd, dVa_dVg, dVa_dVb; +double Vbseff=0.0, dVbseff_dVb=0.0, VbseffCV, dVbseffCV_dVb; +double Arg1, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL; double T0=0.0, dT0_dVg, dT0_dVd, dT0_dVb; double T1, dT1_dVg, dT1_dVd, dT1_dVb; double T2, dT2_dVg, dT2_dVd, dT2_dVb; @@ -138,10 +140,10 @@ double T3, dT3_dVg, dT3_dVd, dT3_dVb; double T4, dT4_dVd, dT4_dVb; double T5, dT5_dVg, dT5_dVd, dT5_dVb; double T6=0.0, dT6_dVg, dT6_dVd, dT6_dVb; -double T7, dT7_dVg, dT7_dVd, dT7_dVb; +double T7, dT7_dVg=0.0, dT7_dVd=0.0, dT7_dVb=0.0; double T8, dT8_dVg, dT8_dVd, dT8_dVb; double T9, dT9_dVg, dT9_dVd, dT9_dVb; -double T10, dT10_dVg, dT10_dVb, dT10_dVd; +double T10, dT10_dVg, dT10_dVb, dT10_dVd; double T11, T12, T13, T14; double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb; double Cclm, dCclm_dVg, dCclm_dVd, dCclm_dVb; @@ -154,11 +156,11 @@ double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb; double Theta0, dTheta0_dVb; double TempRatio, tmp1, tmp2, tmp3, tmp4; double DIBL_Sft, dDIBL_Sft_dVd, Lambda, dLambda_dVg; -double Idtot, Ibtot, a1, ScalingFactor; +double Idtot=0.0, Ibtot=0.0, a1, ScalingFactor; -double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; -double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; -double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; +double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb; +double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb; +double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb; double diffVds, dAbulk_dVg; double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb; double gche, dgche_dVg, dgche_dVd, dgche_dVb; @@ -170,21 +172,21 @@ double Ids, Gm, Gds, Gmb, devbs_dvb, devbd_dvb; double Isub, Gbd, Gbg, Gbb; double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb; double CoxeffWovL; -double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds; +double Rds, dRds_dVg, dRds_dVb, WVCox=0.0, WVCoxRds; double Vgst2Vtm, VdsatCV; double Leff, Weff, dWeff_dVg, dWeff_dVb; double AbulkCV, dAbulkCV_dVb; -double qcheq=0.0, qdef, gqdef=0.0, cqdef=0.0, cqcheq=0.0; +double qcheq, qdef, gqdef=0.0, cqdef=0.0, cqcheq=0.0; double gcqdb=0.0, gcqsb=0.0, gcqgb=0.0, gcqbb=0.0; double dxpart, sxpart, ggtg, ggtd, ggts, ggtb; double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs; double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs; -double gbspsp, gbbdp, gbbsp, gbspg, gbspb, gbspdp; -double gbdpdp, gbdpg, gbdpb, gbdpsp; -double qgdo, qgso, cgdo, cgso; +double gbspsp, gbbdp, gbbsp, gbspg, gbspb, gbspdp; +double gbdpdp, gbdpg, gbdpb, gbdpsp; +double qgdo=0.0, qgso=0.0, cgdo=0.0, cgso=0.0; double Cgg, Cgd, Cgb, Cdg, Cdd, Cds; double Csg, Csd, Css, Csb, Cbg, Cbd, Cbb; -double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0, Qsub0; +double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Qac0=0.0, Qsub0; double dQac0_dVg, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb; double ggidld, ggidlg, ggidlb, ggislg, ggislb, ggisls; double Igisl, Ggislg, Ggislb, Ggisls; @@ -196,24 +198,24 @@ double vgdx, vgsx; struct bsim4SizeDependParam *pParam; int ByPass, ChargeComputationNeeded, error, Check, Check1, Check2; -double m; +double m, min_exp_tmp=0.0; ScalingFactor = 1.0e-9; -ChargeComputationNeeded = +ChargeComputationNeeded = ((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) || ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) ? 1 : 0; for (; model != NULL; model = model->BSIM4v4nextModel) -{ for (here = model->BSIM4v4instances; here != NULL; +{ for (here = model->BSIM4v4instances; here != NULL; here = here->BSIM4v4nextInstance) - { if (here->BSIM4v4owner != ARCHme) continue; + { if (here->BSIM4v4owner != ARCHme) continue; Check = Check1 = Check2 = 1; ByPass = 0; - pParam = here->pParam; + pParam = here->pParam; if ((ckt->CKTmode & MODEINITSMSIG)) - { vds = *(ckt->CKTstate0 + here->BSIM4v4vds); + { vds = *(ckt->CKTstate0 + here->BSIM4v4vds); vgs = *(ckt->CKTstate0 + here->BSIM4v4vgs); vbs = *(ckt->CKTstate0 + here->BSIM4v4vbs); vges = *(ckt->CKTstate0 + here->BSIM4v4vges); @@ -225,8 +227,8 @@ for (; model != NULL; model = model->BSIM4v4nextModel) qdef = *(ckt->CKTstate0 + here->BSIM4v4qdef); } - else if ((ckt->CKTmode & MODEINITTRAN)) - { vds = *(ckt->CKTstate1 + here->BSIM4v4vds); + else if ((ckt->CKTmode & MODEINITTRAN)) + { vds = *(ckt->CKTstate1 + here->BSIM4v4vds); vgs = *(ckt->CKTstate1 + here->BSIM4v4vgs); vbs = *(ckt->CKTstate1 + here->BSIM4v4vbs); vges = *(ckt->CKTstate1 + here->BSIM4v4vges); @@ -238,49 +240,58 @@ for (; model != NULL; model = model->BSIM4v4nextModel) qdef = *(ckt->CKTstate1 + here->BSIM4v4qdef); } - else if ((ckt->CKTmode & MODEINITJCT) && !here->BSIM4v4off) - { vds = model->BSIM4v4type * here->BSIM4v4icVDS; + else if ((ckt->CKTmode & MODEINITJCT) && !here->BSIM4v4off) + { vds = model->BSIM4v4type * here->BSIM4v4icVDS; vgs = vges = vgms = model->BSIM4v4type * here->BSIM4v4icVGS; vbs = vdbs = vsbs = model->BSIM4v4type * here->BSIM4v4icVBS; - if (vds > 0.0) - { vdes = vds + 0.01; - vses = -0.01; - } - else if (vds < 0.0) + if (vds > 0.0) + { vdes = vds + 0.01; + vses = -0.01; + } + else if (vds < 0.0) { vdes = vds - 0.01; vses = 0.01; } - else - vdes = vses = 0.0; + else + vdes = vses = 0.0; qdef = 0.0; if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) && ((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP | MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) - { vds = 0.1; - vdes = 0.11; - vses = -0.01; - vgs = vges = vgms = model->BSIM4v4type + { vds = 0.1; + vdes = 0.11; + vses = -0.01; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + vgs = vges = vgms = model->BSIM4v4type + * pParam->BSIM4v4vth0 + 0.1; + break; + case BSIM4v30: case BSIM4v40: + vgs = vges = vgms = model->BSIM4v4type * here->BSIM4v4vth0 + 0.1; + break; + default: break; + } vbs = vdbs = vsbs = 0.0; } } - else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && - (here->BSIM4v4off)) + else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) && + (here->BSIM4v4off)) { vds = vgs = vbs = vges = vgms = 0.0; vdbs = vsbs = vdes = vses = qdef = 0.0; - } + } else - { + { #ifndef PREDICTOR if ((ckt->CKTmode & MODEINITPRED)) - { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; - *(ckt->CKTstate0 + here->BSIM4v4vds) = + { xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1]; + *(ckt->CKTstate0 + here->BSIM4v4vds) = *(ckt->CKTstate1 + here->BSIM4v4vds); vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM4v4vds)) - (xfact * (*(ckt->CKTstate2 + here->BSIM4v4vds))); - *(ckt->CKTstate0 + here->BSIM4v4vgs) = + *(ckt->CKTstate0 + here->BSIM4v4vgs) = *(ckt->CKTstate1 + here->BSIM4v4vgs); vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM4v4vgs)) - (xfact * (*(ckt->CKTstate2 + here->BSIM4v4vgs))); @@ -292,11 +303,11 @@ for (; model != NULL; model = model->BSIM4v4nextModel) *(ckt->CKTstate1 + here->BSIM4v4vgms); vgms = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM4v4vgms)) - (xfact * (*(ckt->CKTstate2 + here->BSIM4v4vgms))); - *(ckt->CKTstate0 + here->BSIM4v4vbs) = + *(ckt->CKTstate0 + here->BSIM4v4vbs) = *(ckt->CKTstate1 + here->BSIM4v4vbs); vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM4v4vbs)) - (xfact * (*(ckt->CKTstate2 + here->BSIM4v4vbs))); - *(ckt->CKTstate0 + here->BSIM4v4vbd) = + *(ckt->CKTstate0 + here->BSIM4v4vbd) = *(ckt->CKTstate0 + here->BSIM4v4vbs) - *(ckt->CKTstate0 + here->BSIM4v4vds); *(ckt->CKTstate0 + here->BSIM4v4vdbs) = @@ -324,14 +335,14 @@ for (; model != NULL; model = model->BSIM4v4nextModel) qdef = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM4v4qdef)) -(xfact * (*(ckt->CKTstate2 + here->BSIM4v4qdef))); } - else - { + else + { #endif /* PREDICTOR */ vds = model->BSIM4v4type * (*(ckt->CKTrhsOld + here->BSIM4v4dNodePrime) - *(ckt->CKTrhsOld + here->BSIM4v4sNodePrime)); vgs = model->BSIM4v4type - * (*(ckt->CKTrhsOld + here->BSIM4v4gNodePrime) + * (*(ckt->CKTrhsOld + here->BSIM4v4gNodePrime) - *(ckt->CKTrhsOld + here->BSIM4v4sNodePrime)); vbs = model->BSIM4v4type * (*(ckt->CKTrhsOld + here->BSIM4v4bNodePrime) @@ -362,27 +373,27 @@ for (; model != NULL; model = model->BSIM4v4nextModel) vgdo = *(ckt->CKTstate0 + here->BSIM4v4vgs) - *(ckt->CKTstate0 + here->BSIM4v4vds); - vgedo = *(ckt->CKTstate0 + here->BSIM4v4vges) + vgedo = *(ckt->CKTstate0 + here->BSIM4v4vges) - *(ckt->CKTstate0 + here->BSIM4v4vds); - vgmdo = *(ckt->CKTstate0 + here->BSIM4v4vgms) + vgmdo = *(ckt->CKTstate0 + here->BSIM4v4vgms) - *(ckt->CKTstate0 + here->BSIM4v4vds); vbd = vbs - vds; vdbd = vdbs - vds; vgd = vgs - vds; - vged = vges - vds; - vgmd = vgms - vds; + vged = vges - vds; + vgmd = vgms - vds; delvbd = vbd - *(ckt->CKTstate0 + here->BSIM4v4vbd); delvdbd = vdbd - *(ckt->CKTstate0 + here->BSIM4v4vdbd); delvgd = vgd - vgdo; - delvged = vged - vgedo; - delvgmd = vgmd - vgmdo; + delvged = vged - vgedo; + delvgmd = vgmd - vgmdo; delvds = vds - *(ckt->CKTstate0 + here->BSIM4v4vds); delvgs = vgs - *(ckt->CKTstate0 + here->BSIM4v4vgs); - delvges = vges - *(ckt->CKTstate0 + here->BSIM4v4vges); - delvgms = vgms - *(ckt->CKTstate0 + here->BSIM4v4vgms); + delvges = vges - *(ckt->CKTstate0 + here->BSIM4v4vges); + delvgms = vgms - *(ckt->CKTstate0 + here->BSIM4v4vgms); delvbs = vbs - *(ckt->CKTstate0 + here->BSIM4v4vbs); delvdbs = vdbs - *(ckt->CKTstate0 + here->BSIM4v4vdbs); delvsbs = vsbs - *(ckt->CKTstate0 + here->BSIM4v4vsbs); @@ -390,51 +401,82 @@ for (; model != NULL; model = model->BSIM4v4nextModel) delvses = vses - (*(ckt->CKTstate0 + here->BSIM4v4vses)); vdedo = *(ckt->CKTstate0 + here->BSIM4v4vdes) - *(ckt->CKTstate0 + here->BSIM4v4vds); - delvdes = vdes - *(ckt->CKTstate0 + here->BSIM4v4vdes); + delvdes = vdes - *(ckt->CKTstate0 + here->BSIM4v4vdes); delvded = vdes - vds - vdedo; delvbd_jct = (!here->BSIM4v4rbodyMod) ? delvbd : delvdbd; delvbs_jct = (!here->BSIM4v4rbodyMod) ? delvbs : delvsbs; if (here->BSIM4v4mode >= 0) { Idtot = here->BSIM4v4cd + here->BSIM4v4csub - here->BSIM4v4cbd - + here->BSIM4v4Igidl; + + here->BSIM4v4Igidl; cdhat = Idtot - here->BSIM4v4gbd * delvbd_jct + (here->BSIM4v4gmbs + here->BSIM4v4gbbs + here->BSIM4v4ggidlb) * delvbs - + (here->BSIM4v4gm + here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgs + + (here->BSIM4v4gm + here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgs + (here->BSIM4v4gds + here->BSIM4v4gbds + here->BSIM4v4ggidld) * delvds; - Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd - - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; - cbhat = Ibtot + here->BSIM4v4gbd * delvbd_jct - + here->BSIM4v4gbs * delvbs_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) - * delvbs - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgs - - (here->BSIM4v4gbds + here->BSIM4v4ggidld - here->BSIM4v4ggisls) * delvds - - here->BSIM4v4ggislg * delvgd - here->BSIM4v4ggislb* delvbd; + Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd + - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + cbhat = Ibtot + here->BSIM4v4gbd * delvbd_jct + + here->BSIM4v4gbs * delvbs_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) + * delvbs - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgs + - (here->BSIM4v4gbds + here->BSIM4v4ggidld) * delvds + - here->BSIM4v4ggislg * delvgd - here->BSIM4v4ggislb* delvbd + here->BSIM4v4ggisls * delvds ; + break; + case BSIM4v30: case BSIM4v40: + cbhat = Ibtot + here->BSIM4v4gbd * delvbd_jct + + here->BSIM4v4gbs * delvbs_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) + * delvbs - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgs + - (here->BSIM4v4gbds + here->BSIM4v4ggidld - here->BSIM4v4ggisls) * delvds + - here->BSIM4v4ggislg * delvgd - here->BSIM4v4ggislb* delvbd; + break; + default: break; + } + Igstot = here->BSIM4v4Igs + here->BSIM4v4Igcs; + cgshat = Igstot + (here->BSIM4v4gIgsg + here->BSIM4v4gIgcsg) * delvgs + + here->BSIM4v4gIgcsd * delvds + here->BSIM4v4gIgcsb * delvbs; - Igstot = here->BSIM4v4Igs + here->BSIM4v4Igcs; - cgshat = Igstot + (here->BSIM4v4gIgsg + here->BSIM4v4gIgcsg) * delvgs - + here->BSIM4v4gIgcsd * delvds + here->BSIM4v4gIgcsb * delvbs; - - Igdtot = here->BSIM4v4Igd + here->BSIM4v4Igcd; - cgdhat = Igdtot + here->BSIM4v4gIgdg * delvgd + here->BSIM4v4gIgcdg * delvgs + Igdtot = here->BSIM4v4Igd + here->BSIM4v4Igcd; + cgdhat = Igdtot + here->BSIM4v4gIgdg * delvgd + here->BSIM4v4gIgcdg * delvgs + here->BSIM4v4gIgcdd * delvds + here->BSIM4v4gIgcdb * delvbs; - Igbtot = here->BSIM4v4Igb; - cgbhat = here->BSIM4v4Igb + here->BSIM4v4gIgbg * delvgs + here->BSIM4v4gIgbd - * delvds + here->BSIM4v4gIgbb * delvbs; + Igbtot = here->BSIM4v4Igb; + cgbhat = here->BSIM4v4Igb + here->BSIM4v4gIgbg * delvgs + here->BSIM4v4gIgbd + * delvds + here->BSIM4v4gIgbb * delvbs; } else - { Idtot = here->BSIM4v4cd + here->BSIM4v4cbd - here->BSIM4v4Igidl; /* bugfix */ - cdhat = Idtot + here->BSIM4v4gbd * delvbd_jct + here->BSIM4v4gmbs - * delvbd + here->BSIM4v4gm * delvgd - - (here->BSIM4v4gds + here->BSIM4v4ggidls) * delvds - - here->BSIM4v4ggidlg * delvgs - here->BSIM4v4ggidlb * delvbs; - Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd - - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; - cbhat = Ibtot + here->BSIM4v4gbs * delvbs_jct + here->BSIM4v4gbd - * delvbd_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggislb) * delvbd - - (here->BSIM4v4gbgs + here->BSIM4v4ggislg) * delvgd - + (here->BSIM4v4gbds + here->BSIM4v4ggisld - here->BSIM4v4ggidls) * delvds - - here->BSIM4v4ggidlg * delvgs - here->BSIM4v4ggidlb * delvbs; + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Idtot = here->BSIM4v4cd + here->BSIM4v4cbd - here->BSIM4v4Igisl; + cdhat = Idtot + here->BSIM4v4gbd * delvbd_jct + here->BSIM4v4gmbs + * delvbd + here->BSIM4v4gm * delvgd + - here->BSIM4v4gds * delvds - here->BSIM4v4ggislg * vgd + - here->BSIM4v4ggislb * vbd + here->BSIM4v4ggisls * vds; + Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd + - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; + cbhat = Ibtot + here->BSIM4v4gbs * delvbs_jct + here->BSIM4v4gbd + * delvbd_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) * delvbd + - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * delvgd + + (here->BSIM4v4gbds + here->BSIM4v4ggidld) * delvds + - here->BSIM4v4ggislg * delvgs - here->BSIM4v4ggislb * delvbs + here->BSIM4v4ggisls * delvds; + break; + case BSIM4v30: case BSIM4v40: + Idtot = here->BSIM4v4cd + here->BSIM4v4cbd - here->BSIM4v4Igidl; /* bugfix */ + cdhat = Idtot + here->BSIM4v4gbd * delvbd_jct + here->BSIM4v4gmbs + * delvbd + here->BSIM4v4gm * delvgd + - (here->BSIM4v4gds + here->BSIM4v4ggidls) * delvds + - here->BSIM4v4ggidlg * delvgs - here->BSIM4v4ggidlb * delvbs; + Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd + - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; + cbhat = Ibtot + here->BSIM4v4gbs * delvbs_jct + here->BSIM4v4gbd + * delvbd_jct - (here->BSIM4v4gbbs + here->BSIM4v4ggislb) * delvbd + - (here->BSIM4v4gbgs + here->BSIM4v4ggislg) * delvgd + + (here->BSIM4v4gbds + here->BSIM4v4ggisld - here->BSIM4v4ggidls) * delvds + - here->BSIM4v4ggidlg * delvgs - here->BSIM4v4ggidlb * delvbs; + break; + default: break; + } Igstot = here->BSIM4v4Igs + here->BSIM4v4Igcd; cgshat = Igstot + here->BSIM4v4gIgsg * delvgs + here->BSIM4v4gIgcdg * delvgd @@ -461,7 +503,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) #ifndef NOBYPASS - /* Following should be one IF statement, but some C compilers + /* Following should be one IF statement, but some C compilers * can't handle that all at once, so we split it into several * successive IF's */ @@ -474,10 +516,10 @@ for (; model != NULL; model = model->BSIM4v4nextModel) fabs(*(ckt->CKTstate0 + here->BSIM4v4vbs))) + ckt->CKTvoltTol))) if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd), fabs(*(ckt->CKTstate0 + here->BSIM4v4vbd))) + ckt->CKTvoltTol))) - if ((here->BSIM4v4rgateMod == 0) || (here->BSIM4v4rgateMod == 1) - || (fabs(delvges) < (ckt->CKTreltol * MAX(fabs(vges), - fabs(*(ckt->CKTstate0 + here->BSIM4v4vges))) + ckt->CKTvoltTol))) - if ((here->BSIM4v4rgateMod != 3) || (fabs(delvgms) < (ckt->CKTreltol + if ((here->BSIM4v4rgateMod == 0) || (here->BSIM4v4rgateMod == 1) + || (fabs(delvges) < (ckt->CKTreltol * MAX(fabs(vges), + fabs(*(ckt->CKTstate0 + here->BSIM4v4vges))) + ckt->CKTvoltTol))) + if ((here->BSIM4v4rgateMod != 3) || (fabs(delvgms) < (ckt->CKTreltol * MAX(fabs(vgms), fabs(*(ckt->CKTstate0 + here->BSIM4v4vgms))) + ckt->CKTvoltTol))) if ((!here->BSIM4v4rbodyMod) || (fabs(delvdbs) < (ckt->CKTreltol @@ -512,8 +554,8 @@ for (; model != NULL; model = model->BSIM4v4nextModel) { vds = *(ckt->CKTstate0 + here->BSIM4v4vds); vgs = *(ckt->CKTstate0 + here->BSIM4v4vgs); vbs = *(ckt->CKTstate0 + here->BSIM4v4vbs); - vges = *(ckt->CKTstate0 + here->BSIM4v4vges); - vgms = *(ckt->CKTstate0 + here->BSIM4v4vgms); + vges = *(ckt->CKTstate0 + here->BSIM4v4vges); + vgms = *(ckt->CKTstate0 + here->BSIM4v4vgms); vbd = *(ckt->CKTstate0 + here->BSIM4v4vbd); vdbs = *(ckt->CKTstate0 + here->BSIM4v4vdbs); @@ -524,41 +566,49 @@ for (; model != NULL; model = model->BSIM4v4nextModel) vgd = vgs - vds; vgb = vgs - vbs; - vged = vges - vds; - vgmd = vgms - vds; - vgmb = vgms - vbs; + vged = vges - vds; + vgmd = vgms - vds; + vgmb = vgms - vbs; vbs_jct = (!here->BSIM4v4rbodyMod) ? vbs : vsbs; vbd_jct = (!here->BSIM4v4rbodyMod) ? vbd : vdbd; -/*** qdef should not be kept fixed even if vgs, vds & vbs has converged -**** qdef = *(ckt->CKTstate0 + here->BSIM4v4qdef); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + qdef = *(ckt->CKTstate0 + here->BSIM4v4qdef); + break; + case BSIM4v30: case BSIM4v40: +/*** qdef should not be kept fixed even if vgs, vds & vbs has converged +**** qdef = *(ckt->CKTstate0 + here->BSIM4v4qdef); ***/ + break; + default: break; + } cdrain = here->BSIM4v4cd; - if ((ckt->CKTmode & (MODETRAN | MODEAC)) || - ((ckt->CKTmode & MODETRANOP) && + if ((ckt->CKTmode & (MODETRAN | MODEAC)) || + ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC))) - { ByPass = 1; + { ByPass = 1; qgate = here->BSIM4v4qgate; qbulk = here->BSIM4v4qbulk; qdrn = here->BSIM4v4qdrn; - cgdo = here->BSIM4v4cgdo; - qgdo = here->BSIM4v4qgdo; + cgdo = here->BSIM4v4cgdo; + qgdo = here->BSIM4v4qgdo; cgso = here->BSIM4v4cgso; qgso = here->BSIM4v4qgso; - goto line755; + goto line755; } - else - goto line850; + else + goto line850; } #endif /*NOBYPASS*/ von = here->BSIM4v4von; if (*(ckt->CKTstate0 + here->BSIM4v4vds) >= 0.0) - { vgs = DEVfetlim(vgs, *(ckt->CKTstate0 + here->BSIM4v4vgs), von); + { vgs = DEVfetlim(vgs, *(ckt->CKTstate0 + here->BSIM4v4vgs), von); vds = vgs - vgd; vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->BSIM4v4vds)); vgd = vgs - vds; @@ -574,18 +624,18 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } if (model->BSIM4v4rdsMod) - { vdes = DEVlimvds(vdes, *(ckt->CKTstate0 + here->BSIM4v4vdes)); - vses = -DEVlimvds(-vses, -(*(ckt->CKTstate0 + here->BSIM4v4vses))); - } + { vdes = DEVlimvds(vdes, *(ckt->CKTstate0 + here->BSIM4v4vdes)); + vses = -DEVlimvds(-vses, -(*(ckt->CKTstate0 + here->BSIM4v4vses))); + } } - else - { vgd = DEVfetlim(vgd, vgdo, von); + else + { vgd = DEVfetlim(vgd, vgdo, von); vds = vgs - vgd; vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0 + here->BSIM4v4vds))); vgs = vgd + vds; - if (here->BSIM4v4rgateMod == 3) + if (here->BSIM4v4rgateMod == 3) { vged = DEVfetlim(vged, vgedo, von); vges = vged + vds; vgmd = DEVfetlim(vgmd, vgmdo, von); @@ -603,7 +653,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } if (vds >= 0.0) - { vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->BSIM4v4vbs), + { vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->BSIM4v4vbs), CONSTvt0, model->BSIM4v4vcrit, &Check); vbd = vbs - vds; if (here->BSIM4v4rbodyMod) @@ -614,13 +664,13 @@ for (; model != NULL; model = model->BSIM4v4nextModel) CONSTvt0, model->BSIM4v4vcrit, &Check2); if ((Check1 == 0) && (Check2 == 0)) Check = 0; - else + else Check = 1; } } - else + else { vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->BSIM4v4vbd), - CONSTvt0, model->BSIM4v4vcrit, &Check); + CONSTvt0, model->BSIM4v4vcrit, &Check); vbs = vbd + vds; if (here->BSIM4v4rbodyMod) { vdbd = DEVpnjlim(vdbd, *(ckt->CKTstate0 + here->BSIM4v4vdbd), @@ -643,9 +693,9 @@ for (; model != NULL; model = model->BSIM4v4nextModel) vbd = vbs - vds; vgd = vgs - vds; vgb = vgs - vbs; - vged = vges - vds; - vgmd = vgms - vds; - vgmb = vgms - vbs; + vged = vges - vds; + vgmd = vgms - vds; + vgmb = vgms - vbs; vdbd = vdbs - vds; vbs_jct = (!here->BSIM4v4rbodyMod) ? vbs : vsbs; @@ -653,9 +703,9 @@ for (; model != NULL; model = model->BSIM4v4nextModel) /* Source/drain junction diode DC model begins */ Nvtms = model->BSIM4v4vtm * model->BSIM4v4SjctEmissionCoeff; - if ((here->BSIM4v4Aseff <= 0.0) && (here->BSIM4v4Pseff <= 0.0)) - { SourceSatCurrent = 1.0e-14; - } + if ((here->BSIM4v4Aseff <= 0.0) && (here->BSIM4v4Pseff <= 0.0)) + { SourceSatCurrent = 1.0e-14; + } else { SourceSatCurrent = here->BSIM4v4Aseff * model->BSIM4v4SjctTempSatCurDensity + here->BSIM4v4Pseff * model->BSIM4v4SjctSidewallTempSatCurDensity @@ -663,58 +713,58 @@ for (; model != NULL; model = model->BSIM4v4nextModel) * model->BSIM4v4SjctGateSidewallTempSatCurDensity; } - if (SourceSatCurrent <= 0.0) - { here->BSIM4v4gbs = ckt->CKTgmin; + if (SourceSatCurrent <= 0.0) + { here->BSIM4v4gbs = ckt->CKTgmin; here->BSIM4v4cbs = here->BSIM4v4gbs * vbs_jct; } else - { switch(model->BSIM4v4dioMod) + { switch(model->BSIM4v4dioMod) { case 0: evbs = exp(vbs_jct / Nvtms); T1 = model->BSIM4v4xjbvs * exp(-(model->BSIM4v4bvs + vbs_jct) / Nvtms); - /* WDLiu: Magic T1 in this form; different from BSIM4v4 beta. */ - here->BSIM4v4gbs = SourceSatCurrent * (evbs + T1) / Nvtms + ckt->CKTgmin; - here->BSIM4v4cbs = SourceSatCurrent * (evbs + here->BSIM4v4XExpBVS - - T1 - 1.0) + ckt->CKTgmin * vbs_jct; - break; + /* WDLiu: Magic T1 in this form; different from BSIM4v4 beta. */ + here->BSIM4v4gbs = SourceSatCurrent * (evbs + T1) / Nvtms + ckt->CKTgmin; + here->BSIM4v4cbs = SourceSatCurrent * (evbs + here->BSIM4v4XExpBVS + - T1 - 1.0) + ckt->CKTgmin * vbs_jct; + break; case 1: - T2 = vbs_jct / Nvtms; - if (T2 < -EXP_THRESHOLD) - { here->BSIM4v4gbs = ckt->CKTgmin; + T2 = vbs_jct / Nvtms; + if (T2 < -EXP_THRESHOLD) + { here->BSIM4v4gbs = ckt->CKTgmin; here->BSIM4v4cbs = SourceSatCurrent * (MIN_EXP - 1.0) + ckt->CKTgmin * vbs_jct; } - else if (vbs_jct <= here->BSIM4v4vjsmFwd) - { evbs = exp(T2); - here->BSIM4v4gbs = SourceSatCurrent * evbs / Nvtms + ckt->CKTgmin; + else if (vbs_jct <= here->BSIM4v4vjsmFwd) + { evbs = exp(T2); + here->BSIM4v4gbs = SourceSatCurrent * evbs / Nvtms + ckt->CKTgmin; here->BSIM4v4cbs = SourceSatCurrent * (evbs - 1.0) + ckt->CKTgmin * vbs_jct; - } - else - { T0 = here->BSIM4v4IVjsmFwd / Nvtms; + } + else + { T0 = here->BSIM4v4IVjsmFwd / Nvtms; here->BSIM4v4gbs = T0 + ckt->CKTgmin; - here->BSIM4v4cbs = here->BSIM4v4IVjsmFwd - SourceSatCurrent + T0 - * (vbs_jct - here->BSIM4v4vjsmFwd) + ckt->CKTgmin * vbs_jct; - } + here->BSIM4v4cbs = here->BSIM4v4IVjsmFwd - SourceSatCurrent + T0 + * (vbs_jct - here->BSIM4v4vjsmFwd) + ckt->CKTgmin * vbs_jct; + } break; case 2: if (vbs_jct < here->BSIM4v4vjsmRev) { T0 = vbs_jct / Nvtms; if (T0 < -EXP_THRESHOLD) { evbs = MIN_EXP; - devbs_dvb = 0.0; - } + devbs_dvb = 0.0; + } else - { evbs = exp(T0); + { evbs = exp(T0); devbs_dvb = evbs / Nvtms; - } + } - T1 = evbs - 1.0; - T2 = here->BSIM4v4IVjsmRev + here->BSIM4v4SslpRev - * (vbs_jct - here->BSIM4v4vjsmRev); - here->BSIM4v4gbs = devbs_dvb * T2 + T1 * here->BSIM4v4SslpRev + ckt->CKTgmin; + T1 = evbs - 1.0; + T2 = here->BSIM4v4IVjsmRev + here->BSIM4v4SslpRev + * (vbs_jct - here->BSIM4v4vjsmRev); + here->BSIM4v4gbs = devbs_dvb * T2 + T1 * here->BSIM4v4SslpRev + ckt->CKTgmin; here->BSIM4v4cbs = T1 * T2 + ckt->CKTgmin * vbs_jct; - } + } else if (vbs_jct <= here->BSIM4v4vjsmFwd) { T0 = vbs_jct / Nvtms; if (T0 < -EXP_THRESHOLD) @@ -726,34 +776,34 @@ for (; model != NULL; model = model->BSIM4v4nextModel) devbs_dvb = evbs / Nvtms; } - T1 = (model->BSIM4v4bvs + vbs_jct) / Nvtms; + T1 = (model->BSIM4v4bvs + vbs_jct) / Nvtms; if (T1 > EXP_THRESHOLD) { T2 = MIN_EXP; - T3 = 0.0; - } + T3 = 0.0; + } else - { T2 = exp(-T1); - T3 = -T2 /Nvtms; - } + { T2 = exp(-T1); + T3 = -T2 /Nvtms; + } here->BSIM4v4gbs = SourceSatCurrent * (devbs_dvb - model->BSIM4v4xjbvs * T3) - + ckt->CKTgmin; - here->BSIM4v4cbs = SourceSatCurrent * (evbs + here->BSIM4v4XExpBVS - 1.0 - - model->BSIM4v4xjbvs * T2) + ckt->CKTgmin * vbs_jct; + + ckt->CKTgmin; + here->BSIM4v4cbs = SourceSatCurrent * (evbs + here->BSIM4v4XExpBVS - 1.0 + - model->BSIM4v4xjbvs * T2) + ckt->CKTgmin * vbs_jct; } - else - { here->BSIM4v4gbs = here->BSIM4v4SslpFwd + ckt->CKTgmin; + else + { here->BSIM4v4gbs = here->BSIM4v4SslpFwd + ckt->CKTgmin; here->BSIM4v4cbs = here->BSIM4v4IVjsmFwd + here->BSIM4v4SslpFwd * (vbs_jct - - here->BSIM4v4vjsmFwd) + ckt->CKTgmin * vbs_jct; - } + - here->BSIM4v4vjsmFwd) + ckt->CKTgmin * vbs_jct; + } break; default: break; } - } + } Nvtmd = model->BSIM4v4vtm * model->BSIM4v4DjctEmissionCoeff; - if ((here->BSIM4v4Adeff <= 0.0) && (here->BSIM4v4Pdeff <= 0.0)) - { DrainSatCurrent = 1.0e-14; - } + if ((here->BSIM4v4Adeff <= 0.0) && (here->BSIM4v4Pdeff <= 0.0)) + { DrainSatCurrent = 1.0e-14; + } else { DrainSatCurrent = here->BSIM4v4Adeff * model->BSIM4v4DjctTempSatCurDensity + here->BSIM4v4Pdeff * model->BSIM4v4DjctSidewallTempSatCurDensity @@ -761,8 +811,8 @@ for (; model != NULL; model = model->BSIM4v4nextModel) * model->BSIM4v4DjctGateSidewallTempSatCurDensity; } - if (DrainSatCurrent <= 0.0) - { here->BSIM4v4gbd = ckt->CKTgmin; + if (DrainSatCurrent <= 0.0) + { here->BSIM4v4gbd = ckt->CKTgmin; here->BSIM4v4cbd = here->BSIM4v4gbd * vbd_jct; } else @@ -776,7 +826,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) - T1 - 1.0) + ckt->CKTgmin * vbd_jct; break; case 1: - T2 = vbd_jct / Nvtmd; + T2 = vbd_jct / Nvtmd; if (T2 < -EXP_THRESHOLD) { here->BSIM4v4gbd = ckt->CKTgmin; here->BSIM4v4cbd = DrainSatCurrent * (MIN_EXP - 1.0) @@ -832,11 +882,20 @@ for (; model != NULL; model = model->BSIM4v4nextModel) else { T2 = exp(-T1); T3 = -T2 /Nvtmd; - } + } here->BSIM4v4gbd = DrainSatCurrent * (devbd_dvb - model->BSIM4v4xjbvd * T3) + ckt->CKTgmin; - here->BSIM4v4cbd = DrainSatCurrent * (evbd + here->BSIM4v4XExpBVD - 1.0 - - model->BSIM4v4xjbvd * T2) + ckt->CKTgmin * vbd_jct; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + here->BSIM4v4cbd = DrainSatCurrent * (evbd + here->BSIM4v4XExpBVS - 1.0 + - model->BSIM4v4xjbvd * T2) + ckt->CKTgmin * vbd_jct; + break; + case BSIM4v40: + here->BSIM4v4cbd = DrainSatCurrent * (evbd + here->BSIM4v4XExpBVD - 1.0 + - model->BSIM4v4xjbvd * T2) + ckt->CKTgmin * vbd_jct; + break; + default: break; + } } else { here->BSIM4v4gbd = here->BSIM4v4DslpFwd + ckt->CKTgmin; @@ -846,147 +905,189 @@ for (; model != NULL; model = model->BSIM4v4nextModel) break; default: break; } - } + } /* End of diode DC model */ - /* trap-assisted tunneling and recombination current for reverse bias */ - Nvtmrssw = model->BSIM4v4vtm0 * model->BSIM4v4njtsswtemp; - Nvtmrsswg = model->BSIM4v4vtm0 * model->BSIM4v4njtsswgtemp; - Nvtmrs = model->BSIM4v4vtm0 * model->BSIM4v4njtstemp; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + /* trap-assisted tunneling and recombination current for reverse bias */ + Nvtmrssw = model->BSIM4v4vtm0 * model->BSIM4v4njtsswtemp; + Nvtmrsswg = model->BSIM4v4vtm0 * model->BSIM4v4njtsswgtemp; + Nvtmrs = model->BSIM4v4vtm0 * model->BSIM4v4njtstemp; - if ((model->BSIM4v4vtss - vbs) < 1e-3) - { T9 = 1.0e3; - T0 = - vbs / Nvtmrs * T9; - DEXP(T0, T1, T10); - dT1_dVb = T10 / Nvtmrs * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtss - vbs); - T0 = -vbs / Nvtmrs * model->BSIM4v4vtss * T9; - dT0_dVb = model->BSIM4v4vtss / Nvtmrs * (T9 + vbs * T9 * T9) ; - DEXP(T0, T1, T10); - dT1_dVb = T10 * dT0_dVb; - } + if ((model->BSIM4v4vtss - vbs) < 1e-3) + { T9 = 1.0e3; + T0 = - vbs / Nvtmrs * T9; + DEXP(T0, T1, T10); + dT1_dVb = T10 / Nvtmrs * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtss - vbs); + T0 = -vbs / Nvtmrs * model->BSIM4v4vtss * T9; + dT0_dVb = model->BSIM4v4vtss / Nvtmrs * (T9 + vbs * T9 * T9) ; + DEXP(T0, T1, T10); + dT1_dVb = T10 * dT0_dVb; + } - if ((model->BSIM4v4vtsd - vbd) < 1e-3) - { T9 = 1.0e3; - T0 = -vbd / Nvtmrs * T9; - DEXP(T0, T2, T10); - dT2_dVb = T10 / Nvtmrs * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtsd - vbd); - T0 = -vbd / Nvtmrs * model->BSIM4v4vtsd * T9; - dT0_dVb = model->BSIM4v4vtsd / Nvtmrs * (T9 + vbd * T9 * T9) ; - DEXP(T0, T2, T10); - dT2_dVb = T10 * dT0_dVb; - } - - if ((model->BSIM4v4vtssws - vbs) < 1e-3) - { T9 = 1.0e3; - T0 = -vbs / Nvtmrssw * T9; - DEXP(T0, T3, T10); - dT3_dVb = T10 / Nvtmrssw * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtssws - vbs); - T0 = -vbs / Nvtmrssw * model->BSIM4v4vtssws * T9; - dT0_dVb = model->BSIM4v4vtssws / Nvtmrssw * (T9 + vbs * T9 * T9) ; - DEXP(T0, T3, T10); - dT3_dVb = T10 * dT0_dVb; - } - if ((model->BSIM4v4vtsswd - vbd) < 1e-3) - { T9 = 1.0e3; - T0 = -vbd / Nvtmrssw * T9; - DEXP(T0, T4, T10); - dT4_dVb = T10 / Nvtmrssw * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtsswd - vbd); - T0 = -vbd / Nvtmrssw * model->BSIM4v4vtsswd * T9; - dT0_dVb = model->BSIM4v4vtsswd / Nvtmrssw * (T9 + vbd * T9 * T9) ; - DEXP(T0, T4, T10); - dT4_dVb = T10 * dT0_dVb; - } + if ((model->BSIM4v4vtsd - vbd) < 1e-3) + { T9 = 1.0e3; + T0 = -vbd / Nvtmrs * T9; + DEXP(T0, T2, T10); + dT2_dVb = T10 / Nvtmrs * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtsd - vbd); + T0 = -vbd / Nvtmrs * model->BSIM4v4vtsd * T9; + dT0_dVb = model->BSIM4v4vtsd / Nvtmrs * (T9 + vbd * T9 * T9) ; + DEXP(T0, T2, T10); + dT2_dVb = T10 * dT0_dVb; + } - if ((model->BSIM4v4vtsswgs - vbs) < 1e-3) - { T9 = 1.0e3; - T0 = -vbs / Nvtmrsswg * T9; - DEXP(T0, T5, T10); - dT5_dVb = T10 / Nvtmrsswg * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtsswgs - vbs); - T0 = -vbs / Nvtmrsswg * model->BSIM4v4vtsswgs * T9; - dT0_dVb = model->BSIM4v4vtsswgs / Nvtmrsswg * (T9 + vbs * T9 * T9) ; - DEXP(T0, T5, T10); - dT5_dVb = T10 * dT0_dVb; - } - if ((model->BSIM4v4vtsswgd - vbd) < 1e-3) - { T9 = 1.0e3; - T0 = -vbd / Nvtmrsswg * T9; - DEXP(T0, T4, T10); - dT6_dVb = T10 / Nvtmrsswg * T9; - } else { - T9 = 1.0 / (model->BSIM4v4vtsswgd - vbd); - T0 = -vbd / Nvtmrsswg * model->BSIM4v4vtsswgd * T9; - dT0_dVb = model->BSIM4v4vtsswgd / Nvtmrsswg * (T9 + vbd * T9 * T9) ; - DEXP(T0, T6, T10); - dT6_dVb = T10 * dT0_dVb; - } + if ((model->BSIM4v4vtssws - vbs) < 1e-3) + { T9 = 1.0e3; + T0 = -vbs / Nvtmrssw * T9; + DEXP(T0, T3, T10); + dT3_dVb = T10 / Nvtmrssw * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtssws - vbs); + T0 = -vbs / Nvtmrssw * model->BSIM4v4vtssws * T9; + dT0_dVb = model->BSIM4v4vtssws / Nvtmrssw * (T9 + vbs * T9 * T9) ; + DEXP(T0, T3, T10); + dT3_dVb = T10 * dT0_dVb; + } + if ((model->BSIM4v4vtsswd - vbd) < 1e-3) + { T9 = 1.0e3; + T0 = -vbd / Nvtmrssw * T9; + DEXP(T0, T4, T10); + dT4_dVb = T10 / Nvtmrssw * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtsswd - vbd); + T0 = -vbd / Nvtmrssw * model->BSIM4v4vtsswd * T9; + dT0_dVb = model->BSIM4v4vtsswd / Nvtmrssw * (T9 + vbd * T9 * T9) ; + DEXP(T0, T4, T10); + dT4_dVb = T10 * dT0_dVb; + } - here->BSIM4v4gbs += here->BSIM4v4SjctTempRevSatCur * dT1_dVb - + here->BSIM4v4SswTempRevSatCur * dT3_dVb - + here->BSIM4v4SswgTempRevSatCur * dT5_dVb; - here->BSIM4v4cbs -= here->BSIM4v4SjctTempRevSatCur * (T1 - 1.0) - + here->BSIM4v4SswTempRevSatCur * (T3 - 1.0) - + here->BSIM4v4SswgTempRevSatCur * (T5 - 1.0); - here->BSIM4v4gbd += here->BSIM4v4DjctTempRevSatCur * dT2_dVb - + here->BSIM4v4DswTempRevSatCur * dT4_dVb - + here->BSIM4v4DswgTempRevSatCur * dT6_dVb; - here->BSIM4v4cbd -= here->BSIM4v4DjctTempRevSatCur * (T2 - 1.0) - + here->BSIM4v4DswTempRevSatCur * (T4 - 1.0) - + here->BSIM4v4DswgTempRevSatCur * (T6 - 1.0); + if ((model->BSIM4v4vtsswgs - vbs) < 1e-3) + { T9 = 1.0e3; + T0 = -vbs / Nvtmrsswg * T9; + DEXP(T0, T5, T10); + dT5_dVb = T10 / Nvtmrsswg * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtsswgs - vbs); + T0 = -vbs / Nvtmrsswg * model->BSIM4v4vtsswgs * T9; + dT0_dVb = model->BSIM4v4vtsswgs / Nvtmrsswg * (T9 + vbs * T9 * T9) ; + DEXP(T0, T5, T10); + dT5_dVb = T10 * dT0_dVb; + } + if ((model->BSIM4v4vtsswgd - vbd) < 1e-3) + { T9 = 1.0e3; + T0 = -vbd / Nvtmrsswg * T9; + DEXP(T0, T4, T10); + dT6_dVb = T10 / Nvtmrsswg * T9; + } else { + T9 = 1.0 / (model->BSIM4v4vtsswgd - vbd); + T0 = -vbd / Nvtmrsswg * model->BSIM4v4vtsswgd * T9; + dT0_dVb = model->BSIM4v4vtsswgd / Nvtmrsswg * (T9 + vbd * T9 * T9) ; + DEXP(T0, T6, T10); + dT6_dVb = T10 * dT0_dVb; + } - /* End of diode DC model */ + here->BSIM4v4gbs += here->BSIM4v4SjctTempRevSatCur * dT1_dVb + + here->BSIM4v4SswTempRevSatCur * dT3_dVb + + here->BSIM4v4SswgTempRevSatCur * dT5_dVb; + here->BSIM4v4cbs -= here->BSIM4v4SjctTempRevSatCur * (T1 - 1.0) + + here->BSIM4v4SswTempRevSatCur * (T3 - 1.0) + + here->BSIM4v4SswgTempRevSatCur * (T5 - 1.0); + here->BSIM4v4gbd += here->BSIM4v4DjctTempRevSatCur * dT2_dVb + + here->BSIM4v4DswTempRevSatCur * dT4_dVb + + here->BSIM4v4DswgTempRevSatCur * dT6_dVb; + here->BSIM4v4cbd -= here->BSIM4v4DjctTempRevSatCur * (T2 - 1.0) + + here->BSIM4v4DswTempRevSatCur * (T4 - 1.0) + + here->BSIM4v4DswgTempRevSatCur * (T6 - 1.0); + + /* End of diode DC model */ + break; + default: break; + } if (vds >= 0.0) - { here->BSIM4v4mode = 1; + { here->BSIM4v4mode = 1; Vds = vds; Vgs = vgs; Vbs = vbs; - Vdb = vds - vbs; /* WDLiu: for GIDL */ + Vdb = vds - vbs; /* WDLiu: for GIDL */ } - else - { here->BSIM4v4mode = -1; + else + { here->BSIM4v4mode = -1; Vds = -vds; Vgs = vgd; Vbs = vbd; - Vdb = -vbs; + Vdb = -vbs; } - T0 = Vbs - here->BSIM4v4vbsc - 0.001; - T1 = sqrt(T0 * T0 - 0.004 * here->BSIM4v4vbsc); - if (T0 >= 0.0) - { Vbseff = here->BSIM4v4vbsc + 0.5 * (T0 + T1); - dVbseff_dVb = 0.5 * (1.0 + T0 / T1); - } - else - { T2 = -0.002 / (T1 - T0); - Vbseff = here->BSIM4v4vbsc * (1.0 + T2); - dVbseff_dVb = T2 * here->BSIM4v4vbsc / T1; - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T0 = Vbs - pParam->BSIM4v4vbsc - 0.001; + T1 = sqrt(T0 * T0 - 0.004 * pParam->BSIM4v4vbsc); + if (T0 >= 0.0) + { Vbseff = pParam->BSIM4v4vbsc + 0.5 * (T0 + T1); + dVbseff_dVb = 0.5 * (1.0 + T0 / T1); + } + else + { T2 = -0.002 / (T1 - T0); + Vbseff = pParam->BSIM4v4vbsc * (1.0 + T2); + dVbseff_dVb = T2 * pParam->BSIM4v4vbsc / T1; + } - /* JX: Correction to forward body bias */ - T9 = 0.95 * pParam->BSIM4v4phi; - T0 = T9 - Vbseff - 0.001; - T1 = sqrt(T0 * T0 + 0.004 * T9); - Vbseff = T9 - 0.5 * (T0 + T1); - dVbseff_dVb *= 0.5 * (1.0 + T0 / T1); + if (Vbseff < Vbs) + { Vbseff = Vbs; + } - Phis = pParam->BSIM4v4phi - Vbseff; - dPhis_dVb = -1.0; - sqrtPhis = sqrt(Phis); - dsqrtPhis_dVb = -0.5 / sqrtPhis; + if (Vbseff > 0.0) + { T0 = pParam->BSIM4v4phi / (pParam->BSIM4v4phi + Vbseff); + Phis = pParam->BSIM4v4phi * T0; + dPhis_dVb = -T0 * T0; + sqrtPhis = pParam->BSIM4v4phis3 / (pParam->BSIM4v4phi + 0.5 * Vbseff); + dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / pParam->BSIM4v4phis3; + } + else + { Phis = pParam->BSIM4v4phi - Vbseff; + dPhis_dVb = -1.0; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + } + break; + case BSIM4v30: case BSIM4v40: + T0 = Vbs - here->BSIM4v4vbsc - 0.001; + T1 = sqrt(T0 * T0 - 0.004 * here->BSIM4v4vbsc); + if (T0 >= 0.0) + { Vbseff = here->BSIM4v4vbsc + 0.5 * (T0 + T1); + dVbseff_dVb = 0.5 * (1.0 + T0 / T1); + } + else + { T2 = -0.002 / (T1 - T0); + Vbseff = here->BSIM4v4vbsc * (1.0 + T2); + dVbseff_dVb = T2 * here->BSIM4v4vbsc / T1; + } + /* JX: Correction to forward body bias */ + T9 = 0.95 * pParam->BSIM4v4phi; + T0 = T9 - Vbseff - 0.001; + T1 = sqrt(T0 * T0 + 0.004 * T9); + Vbseff = T9 - 0.5 * (T0 + T1); + dVbseff_dVb *= 0.5 * (1.0 + T0 / T1); + + Phis = pParam->BSIM4v4phi - Vbseff; + dPhis_dVb = -1.0; + sqrtPhis = sqrt(Phis); + dsqrtPhis_dVb = -0.5 / sqrtPhis; + break; + default: break; + } Xdep = pParam->BSIM4v4Xdep0 * sqrtPhis / pParam->BSIM4v4sqrtPhi; dXdep_dVb = (pParam->BSIM4v4Xdep0 / pParam->BSIM4v4sqrtPhi) - * dsqrtPhis_dVb; + * dsqrtPhis_dVb; Leff = pParam->BSIM4v4leff; Vtm = model->BSIM4v4vtm; @@ -997,27 +1098,27 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T0 = pParam->BSIM4v4dvt2 * Vbseff; if (T0 >= - 0.5) - { T1 = 1.0 + T0; - T2 = pParam->BSIM4v4dvt2; - } - else - { T4 = 1.0 / (3.0 + 8.0 * T0); - T1 = (1.0 + 3.0 * T0) * T4; - T2 = pParam->BSIM4v4dvt2 * T4 * T4; - } + { T1 = 1.0 + T0; + T2 = pParam->BSIM4v4dvt2; + } + else + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->BSIM4v4dvt2 * T4 * T4; + } lt1 = model->BSIM4v4factor1 * T3 * T1; dlt1_dVb = model->BSIM4v4factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); T0 = pParam->BSIM4v4dvt2w * Vbseff; if (T0 >= - 0.5) - { T1 = 1.0 + T0; - T2 = pParam->BSIM4v4dvt2w; - } - else - { T4 = 1.0 / (3.0 + 8.0 * T0); - T1 = (1.0 + 3.0 * T0) * T4; - T2 = pParam->BSIM4v4dvt2w * T4 * T4; - } + { T1 = 1.0 + T0; + T2 = pParam->BSIM4v4dvt2w; + } + else + { T4 = 1.0 / (3.0 + 8.0 * T0); + T1 = (1.0 + 3.0 * T0) * T4; + T2 = pParam->BSIM4v4dvt2w * T4 * T4; + } ltw = model->BSIM4v4factor1 * T3 * T1; dltw_dVb = model->BSIM4v4factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2); @@ -1046,7 +1147,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T3 = T2 * T2; T4 = T3 + 2.0 * T1 * MIN_EXP; T5 = T1 / T4; - dT1_dVb = -T0 * T1 * dltw_dVb / ltw; + dT1_dVb = -T0 * T1 * dltw_dVb / ltw; dT5_dVb = dT1_dVb * (T4 - 2.0 * T1 * (T2 + MIN_EXP)) / T4 / T4; } else @@ -1063,60 +1164,85 @@ for (; model != NULL; model = model->BSIM4v4nextModel) + (pParam->BSIM4v4kt1 + pParam->BSIM4v4kt1l / Leff + pParam->BSIM4v4kt2 * Vbseff) * TempRatio; Vth_NarrowW = model->BSIM4v4toxe * pParam->BSIM4v4phi - / (pParam->BSIM4v4weff + pParam->BSIM4v4w0); + / (pParam->BSIM4v4weff + pParam->BSIM4v4w0); - T3 = here->BSIM4v4eta0 + pParam->BSIM4v4etab * Vbseff; - if (T3 < 1.0e-4) - { T9 = 1.0 / (3.0 - 2.0e4 * T3); - T3 = (2.0e-4 - T3) * T9; - T4 = T9 * T9; - } - else - { T4 = 1.0; - } - dDIBL_Sft_dVd = T3 * pParam->BSIM4v4theta0vb0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T3 = pParam->BSIM4v4eta0 + pParam->BSIM4v4etab * Vbseff; + break; + case BSIM4v30: case BSIM4v40: + T3 = here->BSIM4v4eta0 + pParam->BSIM4v4etab * Vbseff; + break; + default: break; + } + if (T3 < 1.0e-4) + { T9 = 1.0 / (3.0 - 2.0e4 * T3); + T3 = (2.0e-4 - T3) * T9; + T4 = T9 * T9; + } + else + { T4 = 1.0; + } + dDIBL_Sft_dVd = T3 * pParam->BSIM4v4theta0vb0; DIBL_Sft = dDIBL_Sft_dVd * Vds; - Lpe_Vb = sqrt(1.0 + pParam->BSIM4v4lpeb / Leff); + Lpe_Vb = sqrt(1.0 + pParam->BSIM4v4lpeb / Leff); - Vth = model->BSIM4v4type * here->BSIM4v4vth0 + (pParam->BSIM4v4k1ox * sqrtPhis - - pParam->BSIM4v4k1 * pParam->BSIM4v4sqrtPhi) * Lpe_Vb - - here->BSIM4v4k2ox * Vbseff - Delt_vth - T2 + (pParam->BSIM4v4k3 - + pParam->BSIM4v4k3b * Vbseff) * Vth_NarrowW + T1 - DIBL_Sft; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Vth = model->BSIM4v4type * pParam->BSIM4v4vth0 + (pParam->BSIM4v4k1ox * sqrtPhis + - pParam->BSIM4v4k1 * pParam->BSIM4v4sqrtPhi) * Lpe_Vb + - pParam->BSIM4v4k2ox * Vbseff - Delt_vth - T2 + (pParam->BSIM4v4k3 + + pParam->BSIM4v4k3b * Vbseff) * Vth_NarrowW + T1 - DIBL_Sft; - dVth_dVb = Lpe_Vb * pParam->BSIM4v4k1ox * dsqrtPhis_dVb - here->BSIM4v4k2ox - - dDelt_vth_dVb - dT2_dVb + pParam->BSIM4v4k3b * Vth_NarrowW - - pParam->BSIM4v4etab * Vds * pParam->BSIM4v4theta0vb0 * T4 - + pParam->BSIM4v4kt2 * TempRatio; - dVth_dVd = -dDIBL_Sft_dVd; + dVth_dVb = Lpe_Vb * pParam->BSIM4v4k1ox * dsqrtPhis_dVb - pParam->BSIM4v4k2ox + - dDelt_vth_dVb - dT2_dVb + pParam->BSIM4v4k3b * Vth_NarrowW + - pParam->BSIM4v4etab * Vds * pParam->BSIM4v4theta0vb0 * T4 + + pParam->BSIM4v4kt2 * TempRatio; + dVth_dVd = -dDIBL_Sft_dVd; + break; + case BSIM4v30: case BSIM4v40: + Vth = model->BSIM4v4type * here->BSIM4v4vth0 + (pParam->BSIM4v4k1ox * sqrtPhis + - pParam->BSIM4v4k1 * pParam->BSIM4v4sqrtPhi) * Lpe_Vb + - here->BSIM4v4k2ox * Vbseff - Delt_vth - T2 + (pParam->BSIM4v4k3 + + pParam->BSIM4v4k3b * Vbseff) * Vth_NarrowW + T1 - DIBL_Sft; + + dVth_dVb = Lpe_Vb * pParam->BSIM4v4k1ox * dsqrtPhis_dVb - here->BSIM4v4k2ox + - dDelt_vth_dVb - dT2_dVb + pParam->BSIM4v4k3b * Vth_NarrowW + - pParam->BSIM4v4etab * Vds * pParam->BSIM4v4theta0vb0 * T4 + + pParam->BSIM4v4kt2 * TempRatio; + dVth_dVd = -dDIBL_Sft_dVd; + break; + default: break; + } /* Calculate n */ tmp1 = EPSSI / Xdep; - here->BSIM4v4nstar = model->BSIM4v4vtm / Charge_q * (model->BSIM4v4coxe - + tmp1 + pParam->BSIM4v4cit); + here->BSIM4v4nstar = model->BSIM4v4vtm / Charge_q * (model->BSIM4v4coxe + + tmp1 + pParam->BSIM4v4cit); tmp2 = pParam->BSIM4v4nfactor * tmp1; tmp3 = pParam->BSIM4v4cdsc + pParam->BSIM4v4cdscb * Vbseff + pParam->BSIM4v4cdscd * Vds; - tmp4 = (tmp2 + tmp3 * Theta0 + pParam->BSIM4v4cit) / model->BSIM4v4coxe; - if (tmp4 >= -0.5) - { n = 1.0 + tmp4; - dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + tmp4 = (tmp2 + tmp3 * Theta0 + pParam->BSIM4v4cit) / model->BSIM4v4coxe; + if (tmp4 >= -0.5) + { n = 1.0 + tmp4; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + pParam->BSIM4v4cdscb * Theta0) / model->BSIM4v4coxe; dn_dVd = pParam->BSIM4v4cdscd * Theta0 / model->BSIM4v4coxe; - } - else - { T0 = 1.0 / (3.0 + 8.0 * tmp4); - n = (1.0 + 3.0 * tmp4) * T0; - T0 *= T0; - dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + } + else + { T0 = 1.0 / (3.0 + 8.0 * tmp4); + n = (1.0 + 3.0 * tmp4) * T0; + T0 *= T0; + dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb + pParam->BSIM4v4cdscb * Theta0) / model->BSIM4v4coxe * T0; dn_dVd = pParam->BSIM4v4cdscd * Theta0 / model->BSIM4v4coxe * T0; - } + } /* Vth correction for Pocket implant */ - if (pParam->BSIM4v4dvtp0 > 0.0) + if (pParam->BSIM4v4dvtp0 > 0.0) { T0 = -pParam->BSIM4v4dvtp1 * Vds; if (T0 < -EXP_THRESHOLD) { T2 = MIN_EXP; @@ -1137,64 +1263,71 @@ for (; model != NULL; model = model->BSIM4v4nextModel) Vth -= n * T4; dVth_dVd -= dDITS_Sft_dVd; dVth_dVb -= dDITS_Sft_dVb; - } + } here->BSIM4v4von = Vth; - /* Poly Gate Si Depletion Effect */ - T0 = here->BSIM4v4vfb + pParam->BSIM4v4phi; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T0 = pParam->BSIM4v4vfb + pParam->BSIM4v4phi; + break; + case BSIM4v30: case BSIM4v40: + T0 = here->BSIM4v4vfb + pParam->BSIM4v4phi; + break; + default: break; + } - BSIM4v4polyDepletion(T0, pParam->BSIM4v4ngate, model->BSIM4v4coxe, vgs, &vgs_eff, &dvgs_eff_dvg); + BSIM4v4polyDepletion(T0, pParam->BSIM4v4ngate, model->BSIM4v4coxe, vgs, &vgs_eff, &dvgs_eff_dvg); - BSIM4v4polyDepletion(T0, pParam->BSIM4v4ngate, model->BSIM4v4coxe, vgd, &vgd_eff, &dvgd_eff_dvg); - - if(here->BSIM4v4mode>0) { - Vgs_eff = vgs_eff; - dVgs_eff_dVg = dvgs_eff_dvg; - } else { - Vgs_eff = vgd_eff; - dVgs_eff_dVg = dvgd_eff_dvg; - } - here->BSIM4v4vgs_eff = vgs_eff; - here->BSIM4v4vgd_eff = vgd_eff; - here->BSIM4v4dvgs_eff_dvg = dvgs_eff_dvg; - here->BSIM4v4dvgd_eff_dvg = dvgd_eff_dvg; + BSIM4v4polyDepletion(T0, pParam->BSIM4v4ngate, model->BSIM4v4coxe, vgd, &vgd_eff, &dvgd_eff_dvg); + + if(here->BSIM4v4mode>0) { + Vgs_eff = vgs_eff; + dVgs_eff_dVg = dvgs_eff_dvg; + } else { + Vgs_eff = vgd_eff; + dVgs_eff_dVg = dvgd_eff_dvg; + } + here->BSIM4v4vgs_eff = vgs_eff; + here->BSIM4v4vgd_eff = vgd_eff; + here->BSIM4v4dvgs_eff_dvg = dvgs_eff_dvg; + here->BSIM4v4dvgd_eff_dvg = dvgd_eff_dvg; Vgst = Vgs_eff - Vth; - /* Calculate Vgsteff */ - T0 = n * Vtm; - T1 = pParam->BSIM4v4mstar * Vgst; - T2 = T1 / T0; - if (T2 > EXP_THRESHOLD) - { T10 = T1; - dT10_dVg = pParam->BSIM4v4mstar * dVgs_eff_dVg; + /* Calculate Vgsteff */ + T0 = n * Vtm; + T1 = pParam->BSIM4v4mstar * Vgst; + T2 = T1 / T0; + if (T2 > EXP_THRESHOLD) + { T10 = T1; + dT10_dVg = pParam->BSIM4v4mstar * dVgs_eff_dVg; dT10_dVd = -dVth_dVd * pParam->BSIM4v4mstar; dT10_dVb = -dVth_dVb * pParam->BSIM4v4mstar; - } - else if (T2 < -EXP_THRESHOLD) - { T10 = Vtm * log(1.0 + MIN_EXP); + } + else if (T2 < -EXP_THRESHOLD) + { T10 = Vtm * log(1.0 + MIN_EXP); dT10_dVg = 0.0; dT10_dVd = T10 * dn_dVd; dT10_dVb = T10 * dn_dVb; - T10 *= n; - } - else - { ExpVgst = exp(T2); - T3 = Vtm * log(1.0 + ExpVgst); + T10 *= n; + } + else + { ExpVgst = exp(T2); + T3 = Vtm * log(1.0 + ExpVgst); T10 = n * T3; dT10_dVg = pParam->BSIM4v4mstar * ExpVgst / (1.0 + ExpVgst); dT10_dVb = T3 * dn_dVb - dT10_dVg * (dVth_dVb + Vgst * dn_dVb / n); dT10_dVd = T3 * dn_dVd - dT10_dVg * (dVth_dVd + Vgst * dn_dVd / n); - dT10_dVg *= dVgs_eff_dVg; - } + dT10_dVg *= dVgs_eff_dVg; + } - T1 = pParam->BSIM4v4voffcbn - (1.0 - pParam->BSIM4v4mstar) * Vgst; - T2 = T1 / T0; + T1 = pParam->BSIM4v4voffcbn - (1.0 - pParam->BSIM4v4mstar) * Vgst; + T2 = T1 / T0; if (T2 < -EXP_THRESHOLD) { T3 = model->BSIM4v4coxe * MIN_EXP / pParam->BSIM4v4cdep0; - T9 = pParam->BSIM4v4mstar + T3 * n; + T9 = pParam->BSIM4v4mstar + T3 * n; dT9_dVg = 0.0; dT9_dVd = dn_dVd * T3; dT9_dVb = dn_dVb * T3; @@ -1208,9 +1341,9 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } else { ExpVgst = exp(T2); - T3 = model->BSIM4v4coxe / pParam->BSIM4v4cdep0; - T4 = T3 * ExpVgst; - T5 = T1 * T4 / T0; + T3 = model->BSIM4v4coxe / pParam->BSIM4v4cdep0; + T4 = T3 * ExpVgst; + T5 = T1 * T4 / T0; T9 = pParam->BSIM4v4mstar + n * T4; dT9_dVg = T3 * (pParam->BSIM4v4mstar - 1.0) * ExpVgst / Vtm; dT9_dVb = T4 * dn_dVb - dT9_dVg * dVth_dVb - T5 * dn_dVb; @@ -1219,106 +1352,122 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } here->BSIM4v4Vgsteff = Vgsteff = T10 / T9; - T11 = T9 * T9; + T11 = T9 * T9; dVgsteff_dVg = (T9 * dT10_dVg - T10 * dT9_dVg) / T11; dVgsteff_dVd = (T9 * dT10_dVd - T10 * dT9_dVd) / T11; dVgsteff_dVb = (T9 * dT10_dVb - T10 * dT9_dVb) / T11; /* Calculate Effective Channel Geometry */ T9 = sqrtPhis - pParam->BSIM4v4sqrtPhi; - Weff = pParam->BSIM4v4weff - 2.0 * (pParam->BSIM4v4dwg * Vgsteff - + pParam->BSIM4v4dwb * T9); + Weff = pParam->BSIM4v4weff - 2.0 * (pParam->BSIM4v4dwg * Vgsteff + + pParam->BSIM4v4dwb * T9); dWeff_dVg = -2.0 * pParam->BSIM4v4dwg; dWeff_dVb = -2.0 * pParam->BSIM4v4dwb * dsqrtPhis_dVb; if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff*/ - { T0 = 1.0 / (6.0e-8 - 2.0 * Weff); - Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; - T0 *= T0 * 4.0e-16; + { T0 = 1.0 / (6.0e-8 - 2.0 * Weff); + Weff = 2.0e-8 * (4.0e-8 - Weff) * T0; + T0 *= T0 * 4.0e-16; dWeff_dVg *= T0; - dWeff_dVb *= T0; + dWeff_dVb *= T0; } - if (model->BSIM4v4rdsMod == 1) - Rds = dRds_dVg = dRds_dVb = 0.0; + if (model->BSIM4v4rdsMod == 1) + Rds = dRds_dVg = dRds_dVb = 0.0; else { T0 = 1.0 + pParam->BSIM4v4prwg * Vgsteff; - dT0_dVg = -pParam->BSIM4v4prwg / T0 / T0; - T1 = pParam->BSIM4v4prwb * T9; - dT1_dVb = pParam->BSIM4v4prwb * dsqrtPhis_dVb; + dT0_dVg = -pParam->BSIM4v4prwg / T0 / T0; + T1 = pParam->BSIM4v4prwb * T9; + dT1_dVb = pParam->BSIM4v4prwb * dsqrtPhis_dVb; - T2 = 1.0 / T0 + T1; - T3 = T2 + sqrt(T2 * T2 + 0.01); /* 0.01 = 4.0 * 0.05 * 0.05 */ - dT3_dVg = 1.0 + T2 / (T3 - T2); - dT3_dVb = dT3_dVg * dT1_dVb; - dT3_dVg *= dT0_dVg; + T2 = 1.0 / T0 + T1; + T3 = T2 + sqrt(T2 * T2 + 0.01); /* 0.01 = 4.0 * 0.05 * 0.05 */ + dT3_dVg = 1.0 + T2 / (T3 - T2); + dT3_dVb = dT3_dVg * dT1_dVb; + dT3_dVg *= dT0_dVg; - T4 = pParam->BSIM4v4rds0 * 0.5; - Rds = pParam->BSIM4v4rdswmin + T3 * T4; + T4 = pParam->BSIM4v4rds0 * 0.5; + Rds = pParam->BSIM4v4rdswmin + T3 * T4; dRds_dVg = T4 * dT3_dVg; dRds_dVb = T4 * dT3_dVb; - if (Rds > 0.0) - here->BSIM4v4grdsw = 1.0 / Rds; - else + if (Rds > 0.0) + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v40: + here->BSIM4v4grdsw = 1.0 / Rds; + break; + case BSIM4v30: + here->BSIM4v4grdsw = 1.0 / Rds * here->BSIM4v4nf; /* bugfix */ + break; + default: break; + } + else here->BSIM4v4grdsw = 0.0; } - + /* Calculate Abulk */ - T9 = 0.5 * pParam->BSIM4v4k1ox * Lpe_Vb / sqrtPhis; - T1 = T9 + here->BSIM4v4k2ox - pParam->BSIM4v4k3b * Vth_NarrowW; + T9 = 0.5 * pParam->BSIM4v4k1ox * Lpe_Vb / sqrtPhis; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T1 = T9 + pParam->BSIM4v4k2ox - pParam->BSIM4v4k3b * Vth_NarrowW; + break; + case BSIM4v30: case BSIM4v40: + T1 = T9 + here->BSIM4v4k2ox - pParam->BSIM4v4k3b * Vth_NarrowW; + break; + default: break; + } dT1_dVb = -T9 / sqrtPhis * dsqrtPhis_dVb; T9 = sqrt(pParam->BSIM4v4xj * Xdep); tmp1 = Leff + 2.0 * T9; - T5 = Leff / tmp1; + T5 = Leff / tmp1; tmp2 = pParam->BSIM4v4a0 * T5; - tmp3 = pParam->BSIM4v4weff + pParam->BSIM4v4b1; + tmp3 = pParam->BSIM4v4weff + pParam->BSIM4v4b1; tmp4 = pParam->BSIM4v4b0 / tmp3; T2 = tmp2 + tmp4; dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb; T6 = T5 * T5; T7 = T5 * T6; - Abulk0 = 1.0 + T1 * T2; + Abulk0 = 1.0 + T1 * T2; dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb; T8 = pParam->BSIM4v4ags * pParam->BSIM4v4a0 * T7; dAbulk_dVg = -T1 * T8; - Abulk = Abulk0 + dAbulk_dVg * Vgsteff; + Abulk = Abulk0 + dAbulk_dVg * Vgsteff; dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb - + 3.0 * T1 * dT2_dVb); + + 3.0 * T1 * dT2_dVb); if (Abulk0 < 0.1) /* added to avoid the problems caused by Abulk0 */ - { T9 = 1.0 / (3.0 - 20.0 * Abulk0); - Abulk0 = (0.2 - Abulk0) * T9; - dAbulk0_dVb *= T9 * T9; - } + { T9 = 1.0 / (3.0 - 20.0 * Abulk0); + Abulk0 = (0.2 - Abulk0) * T9; + dAbulk0_dVb *= T9 * T9; + } if (Abulk < 0.1) - { T9 = 1.0 / (3.0 - 20.0 * Abulk); - Abulk = (0.2 - Abulk) * T9; + { T9 = 1.0 / (3.0 - 20.0 * Abulk); + Abulk = (0.2 - Abulk) * T9; T10 = T9 * T9; - dAbulk_dVb *= T10; + dAbulk_dVb *= T10; dAbulk_dVg *= T10; - } - here->BSIM4v4Abulk = Abulk; + } + here->BSIM4v4Abulk = Abulk; T2 = pParam->BSIM4v4keta * Vbseff; - if (T2 >= -0.9) - { T0 = 1.0 / (1.0 + T2); + if (T2 >= -0.9) + { T0 = 1.0 / (1.0 + T2); dT0_dVb = -pParam->BSIM4v4keta * T0 * T0; - } - else - { T1 = 1.0 / (0.8 + T2); - T0 = (17.0 + 20.0 * T2) * T1; + } + else + { T1 = 1.0 / (0.8 + T2); + T0 = (17.0 + 20.0 * T2) * T1; dT0_dVb = -pParam->BSIM4v4keta * T1 * T1; - } - dAbulk_dVg *= T0; - dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; - dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; - Abulk *= T0; - Abulk0 *= T0; + } + dAbulk_dVg *= T0; + dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb; + dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb; + Abulk *= T0; + Abulk0 *= T0; /* Mobility calculation */ if (model->BSIM4v4mobMod == 0) @@ -1341,65 +1490,98 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM4v4uc * T4; } - else - { T0 = (Vgsteff + here->BSIM4v4vtfbphi1) / model->BSIM4v4toxe; - T1 = exp(pParam->BSIM4v4eu * log(T0)); - dT1_dVg = T1 * pParam->BSIM4v4eu / T0 / model->BSIM4v4toxe; - T2 = pParam->BSIM4v4ua + pParam->BSIM4v4uc * Vbseff; - T5 = T1 * T2; - dDenomi_dVg = T2 * dT1_dVg; + else + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T0 = (Vgsteff + pParam->BSIM4v4vtfbphi1) / model->BSIM4v4toxe; + break; + case BSIM4v30: case BSIM4v40: + T0 = (Vgsteff + here->BSIM4v4vtfbphi1) / model->BSIM4v4toxe; + break; + default: break; + } + T1 = exp(pParam->BSIM4v4eu * log(T0)); + dT1_dVg = T1 * pParam->BSIM4v4eu / T0 / model->BSIM4v4toxe; + T2 = pParam->BSIM4v4ua + pParam->BSIM4v4uc * Vbseff; + T5 = T1 * T2; + dDenomi_dVg = T2 * dT1_dVg; dDenomi_dVd = 0.0; dDenomi_dVb = T1 * pParam->BSIM4v4uc; - } + } - if (T5 >= -0.8) - { Denomi = 1.0 + T5; - } - else - { T9 = 1.0 / (7.0 + 10.0 * T5); - Denomi = (0.6 + T5) * T9; - T9 *= T9; + if (T5 >= -0.8) + { Denomi = 1.0 + T5; + } + else + { T9 = 1.0 / (7.0 + 10.0 * T5); + Denomi = (0.6 + T5) * T9; + T9 *= T9; dDenomi_dVg *= T9; dDenomi_dVd *= T9; dDenomi_dVb *= T9; - } + } - here->BSIM4v4ueff = ueff = here->BSIM4v4u0temp / Denomi; - T9 = -ueff / Denomi; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + here->BSIM4v4ueff = ueff = pParam->BSIM4v4u0temp / Denomi; + break; + case BSIM4v30: case BSIM4v40: + here->BSIM4v4ueff = ueff = here->BSIM4v4u0temp / Denomi; + break; + default: break; + } + T9 = -ueff / Denomi; dueff_dVg = T9 * dDenomi_dVg; dueff_dVd = T9 * dDenomi_dVd; dueff_dVb = T9 * dDenomi_dVb; /* Saturation Drain Voltage Vdsat */ - WVCox = Weff * here->BSIM4v4vsattemp * model->BSIM4v4coxe; - WVCoxRds = WVCox * Rds; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + WVCox = Weff * pParam->BSIM4v4vsattemp * model->BSIM4v4coxe; + break; + case BSIM4v30: case BSIM4v40: + WVCox = Weff * here->BSIM4v4vsattemp * model->BSIM4v4coxe; + break; + default: break; + } + WVCoxRds = WVCox * Rds; - Esat = 2.0 * here->BSIM4v4vsattemp / ueff; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Esat = 2.0 * pParam->BSIM4v4vsattemp / ueff; + break; + case BSIM4v30: case BSIM4v40: + Esat = 2.0 * here->BSIM4v4vsattemp / ueff; + break; + default: break; + } here->BSIM4v4EsatL = EsatL = Esat * Leff; T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; - - /* Sqrt() */ + + /* Sqrt() */ a1 = pParam->BSIM4v4a1; - if (a1 == 0.0) - { Lambda = pParam->BSIM4v4a2; - dLambda_dVg = 0.0; - } - else if (a1 > 0.0) - { T0 = 1.0 - pParam->BSIM4v4a2; - T1 = T0 - pParam->BSIM4v4a1 * Vgsteff - 0.0001; - T2 = sqrt(T1 * T1 + 0.0004 * T0); - Lambda = pParam->BSIM4v4a2 + T0 - 0.5 * (T1 + T2); - dLambda_dVg = 0.5 * pParam->BSIM4v4a1 * (1.0 + T1 / T2); - } - else - { T1 = pParam->BSIM4v4a2 + pParam->BSIM4v4a1 * Vgsteff - 0.0001; - T2 = sqrt(T1 * T1 + 0.0004 * pParam->BSIM4v4a2); - Lambda = 0.5 * (T1 + T2); - dLambda_dVg = 0.5 * pParam->BSIM4v4a1 * (1.0 + T1 / T2); - } + if (a1 == 0.0) + { Lambda = pParam->BSIM4v4a2; + dLambda_dVg = 0.0; + } + else if (a1 > 0.0) + { T0 = 1.0 - pParam->BSIM4v4a2; + T1 = T0 - pParam->BSIM4v4a1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * T0); + Lambda = pParam->BSIM4v4a2 + T0 - 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->BSIM4v4a1 * (1.0 + T1 / T2); + } + else + { T1 = pParam->BSIM4v4a2 + pParam->BSIM4v4a1 * Vgsteff - 0.0001; + T2 = sqrt(T1 * T1 + 0.0004 * pParam->BSIM4v4a2); + Lambda = 0.5 * (T1 + T2); + dLambda_dVg = 0.5 * pParam->BSIM4v4a1 * (1.0 + T1 / T2); + } Vgst2Vtm = Vgsteff + 2.0 * Vtm; if (Rds > 0) @@ -1409,48 +1591,48 @@ for (; model != NULL; model = model->BSIM4v4nextModel) else { tmp2 = dWeff_dVg / Weff; tmp3 = dWeff_dVb / Weff; - } + } if ((Rds == 0.0) && (Lambda == 1.0)) { T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); tmp1 = 0.0; - T1 = T0 * T0; - T2 = Vgst2Vtm * T0; + T1 = T0 * T0; + T2 = Vgst2Vtm * T0; T3 = EsatL * Vgst2Vtm; Vdsat = T3 * T0; - + dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1; - dT0_dVd = -(Abulk * dEsatL_dVd) * T1; - dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; + dT0_dVd = -(Abulk * dEsatL_dVd) * T1; + dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1; dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0; dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd; - dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; + dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb; } else { tmp1 = dLambda_dVg / (Lambda * Lambda); T9 = Abulk * WVCoxRds; - T8 = Abulk * T9; - T7 = Vgst2Vtm * T9; + T8 = Abulk * T9; + T7 = Vgst2Vtm * T9; T6 = Vgst2Vtm * WVCoxRds; - T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); + T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda); dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1 - + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); - + + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg); + dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) - + (1.0 / Lambda - 1.0) * dAbulk_dVb); - dT0_dVd = 0.0; + + (1.0 / Lambda - 1.0) * dAbulk_dVb); + dT0_dVd = 0.0; T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7; - + dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 - + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9 - + T7 * tmp2 + T6 * dAbulk_dVg); + + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9 + + T7 * tmp2 + T6 * dAbulk_dVg); dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb - + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); + + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3); dT1_dVd = Abulk * dEsatL_dVd; T2 = Vgst2Vtm * (EsatL + 2.0 * T6); dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg - + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); + + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2); dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); dT2_dVd = Vgst2Vtm * dEsatL_dVd; @@ -1458,16 +1640,16 @@ for (; model != NULL; model = model->BSIM4v4nextModel) Vdsat = (T1 - T3) / T0; dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) - / T3; + / T3; dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) - / T3; + / T3; dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) - / T3; + / T3; dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 - - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; + - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0; dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2 - - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; + - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0; dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; } here->BSIM4v4vdsat = Vdsat; @@ -1479,98 +1661,104 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dT1_dVb = dVdsat_dVb; T2 = sqrt(T1 * T1 + 4.0 * pParam->BSIM4v4delta * Vdsat); - T0 = T1 / T2; - T9 = 2.0 * pParam->BSIM4v4delta; - T3 = T9 / T2; + T0 = T1 / T2; + T9 = 2.0 * pParam->BSIM4v4delta; + T3 = T9 / T2; dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg; dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd; dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb; - if (T1 >= 0.0) - { Vdseff = Vdsat - 0.5 * (T1 + T2); - dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); + if (T1 >= 0.0) + { Vdseff = Vdsat - 0.5 * (T1 + T2); + dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg); dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd); dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); - } - else - { T4 = T9 / (T2 - T1); - T5 = 1.0 - T4; - T6 = Vdsat * T4 / (T2 - T1); - Vdseff = Vdsat * T5; + } + else + { T4 = T9 / (T2 - T1); + T5 = 1.0 - T4; + T6 = Vdsat * T4 / (T2 - T1); + Vdseff = Vdsat * T5; dVdseff_dVg = dVdsat_dVg * T5 + T6 * (dT2_dVg - dT1_dVg); dVdseff_dVd = dVdsat_dVd * T5 + T6 * (dT2_dVd - dT1_dVd); dVdseff_dVb = dVdsat_dVb * T5 + T6 * (dT2_dVb - dT1_dVb); - } + } if (Vds == 0.0) { Vdseff = 0.0; dVdseff_dVg = 0.0; - dVdseff_dVb = 0.0; + dVdseff_dVb = 0.0; } if (Vdseff > Vds) Vdseff = Vds; diffVds = Vds - Vdseff; here->BSIM4v4Vdseff = Vdseff; - - /* Velocity Overshoot */ - if((model->BSIM4v4lambdaGiven) && (model->BSIM4v4lambda > 0.0) ) - { - T1 = Leff * ueff; - T2 = pParam->BSIM4v4lambda / T1; - T3 = -T2 / T1 * Leff; - dT2_dVd = T3 * dueff_dVd; - dT2_dVg = T3 * dueff_dVg; - dT2_dVb = T3 * dueff_dVb; - T5 = 1.0 / (Esat * pParam->BSIM4v4litl); - T4 = -T5 / EsatL; - dT5_dVg = dEsatL_dVg * T4; - dT5_dVd = dEsatL_dVd * T4; - dT5_dVb = dEsatL_dVb * T4; - T6 = 1.0 + diffVds * T5; - dT6_dVg = dT5_dVg * diffVds - dVdseff_dVg * T5; - dT6_dVd = dT5_dVd * diffVds + (1.0 - dVdseff_dVd) * T5; - dT6_dVb = dT5_dVb * diffVds - dVdseff_dVb * T5; - T7 = 2.0 / (T6 * T6 + 1.0); - T8 = 1.0 - T7; - T9 = T6 * T7 * T7; - dT8_dVg = T9 * dT6_dVg; - dT8_dVd = T9 * dT6_dVd; - dT8_dVb = T9 * dT6_dVb; - T10 = 1.0 + T2 * T8; - dT10_dVg = dT2_dVg * T8 + T2 * dT8_dVg; - dT10_dVd = dT2_dVd * T8 + T2 * dT8_dVd; - dT10_dVb = dT2_dVb * T8 + T2 * dT8_dVb; - if(T10 == 1.0) - dT10_dVg = dT10_dVd = dT10_dVb = 0.0; - dEsatL_dVg *= T10; - dEsatL_dVg += EsatL * dT10_dVg; - dEsatL_dVd *= T10; - dEsatL_dVd += EsatL * dT10_dVd; - dEsatL_dVb *= T10; - dEsatL_dVb += EsatL * dT10_dVb; - EsatL *= T10; - here->BSIM4v4EsatL = EsatL; - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + /* Velocity Overshoot */ + if((model->BSIM4v4lambdaGiven) && (model->BSIM4v4lambda > 0.0) ) + { + T1 = Leff * ueff; + T2 = pParam->BSIM4v4lambda / T1; + T3 = -T2 / T1 * Leff; + dT2_dVd = T3 * dueff_dVd; + dT2_dVg = T3 * dueff_dVg; + dT2_dVb = T3 * dueff_dVb; + T5 = 1.0 / (Esat * pParam->BSIM4v4litl); + T4 = -T5 / EsatL; + dT5_dVg = dEsatL_dVg * T4; + dT5_dVd = dEsatL_dVd * T4; + dT5_dVb = dEsatL_dVb * T4; + T6 = 1.0 + diffVds * T5; + dT6_dVg = dT5_dVg * diffVds - dVdseff_dVg * T5; + dT6_dVd = dT5_dVd * diffVds + (1.0 - dVdseff_dVd) * T5; + dT6_dVb = dT5_dVb * diffVds - dVdseff_dVb * T5; + T7 = 2.0 / (T6 * T6 + 1.0); + T8 = 1.0 - T7; + T9 = T6 * T7 * T7; + dT8_dVg = T9 * dT6_dVg; + dT8_dVd = T9 * dT6_dVd; + dT8_dVb = T9 * dT6_dVb; + T10 = 1.0 + T2 * T8; + dT10_dVg = dT2_dVg * T8 + T2 * dT8_dVg; + dT10_dVd = dT2_dVd * T8 + T2 * dT8_dVd; + dT10_dVb = dT2_dVb * T8 + T2 * dT8_dVb; + if(T10 == 1.0) + dT10_dVg = dT10_dVd = dT10_dVb = 0.0; + dEsatL_dVg *= T10; + dEsatL_dVg += EsatL * dT10_dVg; + dEsatL_dVd *= T10; + dEsatL_dVd += EsatL * dT10_dVd; + dEsatL_dVb *= T10; + dEsatL_dVb += EsatL * dT10_dVb; + EsatL *= T10; + here->BSIM4v4EsatL = EsatL; + } + break; + default: break; + } /* Calculate Vasat */ tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; T9 = WVCoxRds * Vgsteff; - T8 = T9 / Vgst2Vtm; + T8 = T9 / Vgst2Vtm; T0 = EsatL + Vdsat + 2.0 * T9 * tmp4; - + T7 = 2.0 * WVCoxRds * tmp4; dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff) - - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm - + Vdsat * dAbulk_dVg); - + - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + + Vdsat * dAbulk_dVg); + dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff - - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); + - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd; - T9 = WVCoxRds * Abulk; - T1 = 2.0 / Lambda - 1.0 + T9; + T9 = WVCoxRds * Abulk; + T1 = 2.0 / Lambda - 1.0 + T9; dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; @@ -1579,8 +1767,16 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; dVasat_dVd = dT0_dVd / T1; - /* Calculate Idl first */ - tmp1 = here->BSIM4v4vtfbphi2; + /* Calculate Idl first */ + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + tmp1 = pParam->BSIM4v4vtfbphi2; + break; + case BSIM4v30: case BSIM4v40: + tmp1 = here->BSIM4v4vtfbphi2; + break; + default: break; + } tmp2 = 2.0e8 * model->BSIM4v4toxp; dT0_dVg = 1.0 / tmp2; T0 = (Vgsteff + tmp1) * dT0_dVg; @@ -1640,15 +1836,15 @@ for (; model != NULL; model = model->BSIM4v4nextModel) /* Calculate degradation factor due to pocket implant */ - if (pParam->BSIM4v4fprout <= 0.0) - { FP = 1.0; - dFP_dVg = 0.0; - } - else - { T9 = pParam->BSIM4v4fprout * sqrt(Leff) / Vgst2Vtm; + if (pParam->BSIM4v4fprout <= 0.0) + { FP = 1.0; + dFP_dVg = 0.0; + } + else + { T9 = pParam->BSIM4v4fprout * sqrt(Leff) / Vgst2Vtm; FP = 1.0 / (1.0 + T9); dFP_dVg = FP * FP * T9 / Vgst2Vtm; - } + } /* Calculate VACLM */ T8 = pParam->BSIM4v4pvag / EsatL; @@ -1669,14 +1865,24 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dPvagTerm_dVd = -T9 * dEsatL_dVd; } - if ((pParam->BSIM4v4pclm > MIN_EXP) && (diffVds > 1.0e-10)) - { T0 = 1.0 + Rds * Idl; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + min_exp_tmp = 0.0; + break; + case BSIM4v30: case BSIM4v40: + min_exp_tmp = MIN_EXP; + break; + default: break; + } + + if ((pParam->BSIM4v4pclm > min_exp_tmp) && (diffVds > 1.0e-10)) + { T0 = 1.0 + Rds * Idl; dT0_dVg = dRds_dVg * Idl + Rds * dIdl_dVg; dT0_dVd = Rds * dIdl_dVd; dT0_dVb = dRds_dVb * Idl + Rds * dIdl_dVb; T2 = Vdsat / Esat; - T1 = Leff + T2; + T1 = Leff + T2; dT1_dVg = (dVdsat_dVg - T2 * dEsatL_dVg / Leff) / Esat; dT1_dVd = (dVdsat_dVd - T2 * dEsatL_dVd / Leff) / Esat; dT1_dVb = (dVdsat_dVb - T2 * dEsatL_dVb / Leff) / Esat; @@ -1701,11 +1907,11 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } /* Calculate VADIBL */ - if (pParam->BSIM4v4thetaRout > MIN_EXP) - { T8 = Abulk * Vdsat; - T0 = Vgst2Vtm * T8; + if (pParam->BSIM4v4thetaRout > min_exp_tmp) + { T8 = Abulk * Vdsat; + T0 = Vgst2Vtm * T8; dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 - + Vgst2Vtm * Vdsat * dAbulk_dVg; + + Vgst2Vtm * Vdsat * dAbulk_dVg; dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; @@ -1714,39 +1920,39 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; dT1_dVd = Abulk * dVdsat_dVd; - T9 = T1 * T1; - T2 = pParam->BSIM4v4thetaRout; + T9 = T1 * T1; + T2 = pParam->BSIM4v4thetaRout; VADIBL = (Vgst2Vtm - T0 / T1) / T2; dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2; dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2; dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2; - T7 = pParam->BSIM4v4pdiblb * Vbseff; - if (T7 >= -0.9) - { T3 = 1.0 / (1.0 + T7); + T7 = pParam->BSIM4v4pdiblb * Vbseff; + if (T7 >= -0.9) + { T3 = 1.0 / (1.0 + T7); VADIBL *= T3; dVADIBL_dVg *= T3; dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->BSIM4v4pdiblb) - * T3; + * T3; dVADIBL_dVd *= T3; - } - else - { T4 = 1.0 / (0.8 + T7); - T3 = (17.0 + 20.0 * T7) * T4; + } + else + { T4 = 1.0 / (0.8 + T7); + T3 = (17.0 + 20.0 * T7) * T4; dVADIBL_dVg *= T3; dVADIBL_dVb = dVADIBL_dVb * T3 - - VADIBL * pParam->BSIM4v4pdiblb * T4 * T4; + - VADIBL * pParam->BSIM4v4pdiblb * T4 * T4; dVADIBL_dVd *= T3; VADIBL *= T3; - } + } dVADIBL_dVg = dVADIBL_dVg * PvagTerm + VADIBL * dPvagTerm_dVg; dVADIBL_dVb = dVADIBL_dVb * PvagTerm + VADIBL * dPvagTerm_dVb; dVADIBL_dVd = dVADIBL_dVd * PvagTerm + VADIBL * dPvagTerm_dVd; VADIBL *= PvagTerm; } - else - { VADIBL = MAX_EXP; + else + { VADIBL = MAX_EXP; dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; } @@ -1762,45 +1968,45 @@ for (; model != NULL; model = model->BSIM4v4nextModel) { T1 = MAX_EXP; dT1_dVd = 0; } - else + else { T1 = exp(T0); dT1_dVd = T1 * pParam->BSIM4v4pditsd; } - if (pParam->BSIM4v4pdits > MIN_EXP) + if (pParam->BSIM4v4pdits > min_exp_tmp) { T2 = 1.0 + model->BSIM4v4pditsl * Leff; VADITS = (1.0 + T2 * T1) / pParam->BSIM4v4pdits; dVADITS_dVg = VADITS * dFP_dVg; dVADITS_dVd = FP * T2 * dT1_dVd / pParam->BSIM4v4pdits; - VADITS *= FP; + VADITS *= FP; } - else + else { VADITS = MAX_EXP; dVADITS_dVg = dVADITS_dVd = 0; } /* Calculate VASCBE */ - if (pParam->BSIM4v4pscbe2 > 0.0) - { if (diffVds > pParam->BSIM4v4pscbe1 * pParam->BSIM4v4litl - / EXP_THRESHOLD) - { T0 = pParam->BSIM4v4pscbe1 * pParam->BSIM4v4litl / diffVds; - VASCBE = Leff * exp(T0) / pParam->BSIM4v4pscbe2; + if (pParam->BSIM4v4pscbe2 > 0.0) + { if (diffVds > pParam->BSIM4v4pscbe1 * pParam->BSIM4v4litl + / EXP_THRESHOLD) + { T0 = pParam->BSIM4v4pscbe1 * pParam->BSIM4v4litl / diffVds; + VASCBE = Leff * exp(T0) / pParam->BSIM4v4pscbe2; T1 = T0 * VASCBE / diffVds; dVASCBE_dVg = T1 * dVdseff_dVg; dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd); dVASCBE_dVb = T1 * dVdseff_dVb; } - else - { VASCBE = MAX_EXP * Leff/pParam->BSIM4v4pscbe2; + else + { VASCBE = MAX_EXP * Leff/pParam->BSIM4v4pscbe2; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; } - } - else - { VASCBE = MAX_EXP; + } + else + { VASCBE = MAX_EXP; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; - } + } - /* Add DIBL to Ids */ + /* Add DIBL to Ids */ T9 = diffVds / VADIBL; T0 = 1.0 + T9; Idsa = Idl * T0; @@ -1813,8 +2019,8 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T9 = diffVds / VADITS; T0 = 1.0 + T9; dIdsa_dVg = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVADITS_dVg) / VADITS; - dIdsa_dVd = T0 * dIdsa_dVd + Idsa - * (1.0 - dVdseff_dVd - T9 * dVADITS_dVd) / VADITS; + dIdsa_dVd = T0 * dIdsa_dVd + Idsa + * (1.0 - dVdseff_dVd - T9 * dVADITS_dVd) / VADITS; dIdsa_dVb = T0 * dIdsa_dVb - Idsa * dVdseff_dVb / VADITS; Idsa *= T0; @@ -1856,10 +2062,10 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dT1_dVd = T3 * (1.0 - dVdseff_dVd); dT1_dVb = -T3 * dVdseff_dVb; } - T4 = Idsa * Vdseff; + T4 = Idsa * Vdseff; Isub = T1 * T4; Gbg = T1 * (dIdsa_dVg * Vdseff + Idsa * dVdseff_dVg) - + T4 * dT1_dVg; + + T4 * dT1_dVg; Gbd = T1 * (dIdsa_dVd * Vdseff + Idsa * dVdseff_dVd) + T4 * dT1_dVd; Gbb = T1 * (dIdsa_dVb * Vdseff + Idsa * dVdseff_dVb) @@ -1880,110 +2086,157 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T0 = 1.0 + T9; Ids = Idsa * T0; - Gm = T0 * dIdsa_dVg - Idsa - * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE; - Gds = T0 * dIdsa_dVd + Idsa - * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; + Gm = T0 * dIdsa_dVg - Idsa + * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE; + Gds = T0 * dIdsa_dVd + Idsa + * (1.0 - dVdseff_dVd - T9 * dVASCBE_dVd) / VASCBE; Gmb = T0 * dIdsa_dVb - Idsa - * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; + * (dVdseff_dVb + T9 * dVASCBE_dVb) / VASCBE; - tmp1 = Gds + Gm * dVgsteff_dVd; - tmp2 = Gmb + Gm * dVgsteff_dVb; - tmp3 = Gm; + tmp1 = Gds + Gm * dVgsteff_dVd; + tmp2 = Gmb + Gm * dVgsteff_dVb; + tmp3 = Gm; Gm = (Ids * dVdseff_dVg + Vdseff * tmp3) * dVgsteff_dVg; Gds = Ids * (dVdseff_dVd + dVdseff_dVg * dVgsteff_dVd) - + Vdseff * tmp1; + + Vdseff * tmp1; Gmb = (Ids * (dVdseff_dVb + dVdseff_dVg * dVgsteff_dVb) - + Vdseff * tmp2) * dVbseff_dVb; + + Vdseff * tmp2) * dVbseff_dVb; cdrain = Ids * Vdseff; - - /* Source End Velocity Limit */ - if((model->BSIM4v4vtlGiven) && (model->BSIM4v4vtl > 0.0) ) { - T12 = 1.0 / Leff / CoxeffWovL; - T11 = T12 / Vgsteff; - T10 = -T11 / Vgsteff; - vs = cdrain * T11; /* vs */ - dvs_dVg = Gm * T11 + cdrain * T10 * dVgsteff_dVg; - dvs_dVd = Gds * T11 + cdrain * T10 * dVgsteff_dVd; - dvs_dVb = Gmb * T11 + cdrain * T10 * dVgsteff_dVb; - T0 = 2 * MM; - T1 = vs / (pParam->BSIM4v4vtl * pParam->BSIM4v4tfactor); - if(T1 > 0.0) - { T2 = 1.0 + exp(T0 * log(T1)); - T3 = (T2 - 1.0) * T0 / vs; - Fsevl = 1.0 / exp(log(T2)/ T0); - dT2_dVg = T3 * dvs_dVg; - dT2_dVd = T3 * dvs_dVd; - dT2_dVb = T3 * dvs_dVb; - T4 = -1.0 / T0 * Fsevl / T2; - dFsevl_dVg = T4 * dT2_dVg; - dFsevl_dVd = T4 * dT2_dVd; - dFsevl_dVb = T4 * dT2_dVb; - } else { - Fsevl = 1.0; - dFsevl_dVg = 0.0; - dFsevl_dVd = 0.0; - dFsevl_dVb = 0.0; + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: + /* Source End Velocity Limit */ + if((model->BSIM4v4vtlGiven) && (model->BSIM4v4vtl > 0.0) ) { + T12 = 1.0 / Leff / CoxeffWovL; + T11 = T12 / Vgsteff; + T10 = -T11 / Vgsteff; + vs = cdrain * T11; /* vs */ + dvs_dVg = Gm * T11 + cdrain * T10 * dVgsteff_dVg; + dvs_dVd = Gds * T11 + cdrain * T10 * dVgsteff_dVd; + dvs_dVb = Gmb * T11 + cdrain * T10 * dVgsteff_dVb; + T0 = 2 * MM; + T1 = vs / (pParam->BSIM4v4vtl * pParam->BSIM4v4tfactor); + T2 = 1.0 + exp(T0 * log(T1)); + if(vs == 0.0) T3 = 0.0; + else T3 = (T2 - 1.0) * T0 / vs; + dT2_dVg = T3 * dvs_dVg; + dT2_dVd = T3 * dvs_dVd; + dT2_dVb = T3 * dvs_dVb; + Fsevl = 1.0 / exp(log(T2)/ T0); + T4 = -1.0 / T0 * Fsevl / T2; + dFsevl_dVg = T4 * dT2_dVg; + dFsevl_dVd = T4 * dT2_dVd; + dFsevl_dVb = T4 * dT2_dVb; + Gm *=Fsevl; + Gm += cdrain * dFsevl_dVg; + Gmb *=Fsevl; + Gmb += cdrain * dFsevl_dVb; + Gds *=Fsevl; + Gds += cdrain * dFsevl_dVd; + + cdrain *= Fsevl; + } + break; + case BSIM4v40: + /* Source End Velocity Limit */ + if((model->BSIM4v4vtlGiven) && (model->BSIM4v4vtl > 0.0) ) { + T12 = 1.0 / Leff / CoxeffWovL; + T11 = T12 / Vgsteff; + T10 = -T11 / Vgsteff; + vs = cdrain * T11; /* vs */ + dvs_dVg = Gm * T11 + cdrain * T10 * dVgsteff_dVg; + dvs_dVd = Gds * T11 + cdrain * T10 * dVgsteff_dVd; + dvs_dVb = Gmb * T11 + cdrain * T10 * dVgsteff_dVb; + T0 = 2 * MM; + T1 = vs / (pParam->BSIM4v4vtl * pParam->BSIM4v4tfactor); + if(T1 > 0.0) + { T2 = 1.0 + exp(T0 * log(T1)); + T3 = (T2 - 1.0) * T0 / vs; + Fsevl = 1.0 / exp(log(T2)/ T0); + dT2_dVg = T3 * dvs_dVg; + dT2_dVd = T3 * dvs_dVd; + dT2_dVb = T3 * dvs_dVb; + T4 = -1.0 / T0 * Fsevl / T2; + dFsevl_dVg = T4 * dT2_dVg; + dFsevl_dVd = T4 * dT2_dVd; + dFsevl_dVb = T4 * dT2_dVb; + } else { + Fsevl = 1.0; + dFsevl_dVg = 0.0; + dFsevl_dVd = 0.0; + dFsevl_dVb = 0.0; + } + Gm *=Fsevl; + Gm += cdrain * dFsevl_dVg; + Gmb *=Fsevl; + Gmb += cdrain * dFsevl_dVb; + Gds *=Fsevl; + Gds += cdrain * dFsevl_dVd; + + cdrain *= Fsevl; + } + break; + default: break; } - Gm *=Fsevl; - Gm += cdrain * dFsevl_dVg; - Gmb *=Fsevl; - Gmb += cdrain * dFsevl_dVb; - Gds *=Fsevl; - Gds += cdrain * dFsevl_dVd; - - cdrain *= Fsevl; - } - here->BSIM4v4gds = Gds; here->BSIM4v4gm = Gm; here->BSIM4v4gmbs = Gmb; here->BSIM4v4IdovVds = Ids; - if( here->BSIM4v4IdovVds <= 1.0e-9) here->BSIM4v4IdovVds = 1.0e-9; + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if( here->BSIM4v4IdovVds <= 1.0e-9) here->BSIM4v4IdovVds = 1.0e-9; + break; + default: break; + } /* Calculate Rg */ if ((here->BSIM4v4rgateMod > 1) || (here->BSIM4v4trnqsMod != 0) || (here->BSIM4v4acnqsMod != 0)) - { T9 = pParam->BSIM4v4xrcrg2 * model->BSIM4v4vtm; + { T9 = pParam->BSIM4v4xrcrg2 * model->BSIM4v4vtm; T0 = T9 * beta; dT0_dVd = (dbeta_dVd + dbeta_dVg * dVgsteff_dVd) * T9; dT0_dVb = (dbeta_dVb + dbeta_dVg * dVgsteff_dVb) * T9; dT0_dVg = dbeta_dVg * T9; - here->BSIM4v4gcrg = pParam->BSIM4v4xrcrg1 * ( T0 + Ids); - here->BSIM4v4gcrgd = pParam->BSIM4v4xrcrg1 * (dT0_dVd + tmp1); + here->BSIM4v4gcrg = pParam->BSIM4v4xrcrg1 * ( T0 + Ids); + here->BSIM4v4gcrgd = pParam->BSIM4v4xrcrg1 * (dT0_dVd + tmp1); here->BSIM4v4gcrgb = pParam->BSIM4v4xrcrg1 * (dT0_dVb + tmp2) - * dVbseff_dVb; + * dVbseff_dVb; here->BSIM4v4gcrgg = pParam->BSIM4v4xrcrg1 * (dT0_dVg + tmp3) - * dVgsteff_dVg; + * dVgsteff_dVg; - if (here->BSIM4v4nf != 1.0) - { here->BSIM4v4gcrg *= here->BSIM4v4nf; - here->BSIM4v4gcrgg *= here->BSIM4v4nf; - here->BSIM4v4gcrgd *= here->BSIM4v4nf; - here->BSIM4v4gcrgb *= here->BSIM4v4nf; - } + if (here->BSIM4v4nf != 1.0) + { here->BSIM4v4gcrg *= here->BSIM4v4nf; + here->BSIM4v4gcrgg *= here->BSIM4v4nf; + here->BSIM4v4gcrgd *= here->BSIM4v4nf; + here->BSIM4v4gcrgb *= here->BSIM4v4nf; + } if (here->BSIM4v4rgateMod == 2) { T10 = here->BSIM4v4grgeltd * here->BSIM4v4grgeltd; - T11 = here->BSIM4v4grgeltd + here->BSIM4v4gcrg; - here->BSIM4v4gcrg = here->BSIM4v4grgeltd * here->BSIM4v4gcrg / T11; + T11 = here->BSIM4v4grgeltd + here->BSIM4v4gcrg; + here->BSIM4v4gcrg = here->BSIM4v4grgeltd * here->BSIM4v4gcrg / T11; T12 = T10 / T11 / T11; here->BSIM4v4gcrgg *= T12; here->BSIM4v4gcrgd *= T12; here->BSIM4v4gcrgb *= T12; } here->BSIM4v4gcrgs = -(here->BSIM4v4gcrgg + here->BSIM4v4gcrgd - + here->BSIM4v4gcrgb); - } + + here->BSIM4v4gcrgb); + } - /* Calculate bias-dependent external S/D resistance */ + /* Calculate bias-dependent external S/D resistance */ if (model->BSIM4v4rdsMod) - { /* Rs(V) */ + { /* Rs(V) */ T0 = vgs - pParam->BSIM4v4vfbsd; T1 = sqrt(T0 * T0 + 1.0e-4); vgs_eff = 0.5 * (T0 + T1); @@ -2013,7 +2266,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dgstot_dvb = T0 * dRs_dvb; dgstot_dvs = -(dgstot_dvg + dgstot_dvb + dgstot_dvd); - /* Rd(V) */ + /* Rd(V) */ T0 = vgd - pParam->BSIM4v4vfbsd; T1 = sqrt(T0 * T0 + 1.0e-4); vgd_eff = 0.5 * (T0 + T1); @@ -2053,13 +2306,13 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4gdtotg = T2 * dgdtot_dvg; here->BSIM4v4gdtots = T2 * dgdtot_dvs; here->BSIM4v4gdtotb = T2 * dgdtot_dvb; - } - else /* WDLiu: for bypass */ - { here->BSIM4v4gstot = here->BSIM4v4gstotd = here->BSIM4v4gstotg = 0.0; - here->BSIM4v4gstots = here->BSIM4v4gstotb = 0.0; - here->BSIM4v4gdtot = here->BSIM4v4gdtotd = here->BSIM4v4gdtotg = 0.0; + } + else /* WDLiu: for bypass */ + { here->BSIM4v4gstot = here->BSIM4v4gstotd = here->BSIM4v4gstotg = 0.0; + here->BSIM4v4gstots = here->BSIM4v4gstotb = 0.0; + here->BSIM4v4gdtot = here->BSIM4v4gdtotd = here->BSIM4v4gdtotg = 0.0; here->BSIM4v4gdtots = here->BSIM4v4gdtotb = 0.0; - } + } /* Calculate GIDL current */ vgs_eff = here->BSIM4v4vgs_eff; @@ -2086,7 +2339,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) Ggidlg = Igidl * dT1_dVg; Igidl *= T1; } - + T4 = vbd * vbd; T5 = -vbd * T4; T6 = pParam->BSIM4v4cgidl + T5; @@ -2115,19 +2368,19 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dT1_dVd = 1.0 / T0; dT1_dVg = -dvgd_eff_dvg * dT1_dVd; T2 = pParam->BSIM4v4bgidl / T1; - if (T2 < 100.0) + if (T2 < 100.0) { Igisl = pParam->BSIM4v4agidl * pParam->BSIM4v4weffCJ * T1 * exp(-T2); T3 = Igisl * (1.0 + T2) / T1; Ggisls = T3 * dT1_dVd; Ggislg = T3 * dT1_dVg; } - else + else { Igisl = pParam->BSIM4v4agidl * pParam->BSIM4v4weffCJ * 3.720075976e-44; Ggisls = Igisl * dT1_dVd; Ggislg = Igisl * dT1_dVg; Igisl *= T1; } - + T4 = vbs * vbs; T5 = -vbs * T4; T6 = pParam->BSIM4v4cgidl + T5; @@ -2146,7 +2399,17 @@ for (; model != NULL; model = model->BSIM4v4nextModel) /* Calculate gate tunneling current */ if ((model->BSIM4v4igcMod != 0) || (model->BSIM4v4igbMod != 0)) - { Vfb = here->BSIM4v4vfbzb; + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + Vfb = pParam->BSIM4v4vfbzb; + break; + case BSIM4v40: + Vfb = here->BSIM4v4vfbzb; + break; + default: break; + } V3 = Vfb - Vgs_eff + Vbseff - DELTA_3; if (Vfb <= 0.0) T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); @@ -2167,20 +2430,20 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T3 = Vgs_eff - Vfbeff - Vbseff - Vgsteff; if (pParam->BSIM4v4k1ox == 0.0) Voxdepinv = dVoxdepinv_dVg = dVoxdepinv_dVd - = dVoxdepinv_dVb = 0.0; + = dVoxdepinv_dVb = 0.0; else if (T3 < 0.0) { Voxdepinv = -T3; dVoxdepinv_dVg = -dVgs_eff_dVg + dVfbeff_dVg + dVgsteff_dVg; dVoxdepinv_dVd = dVgsteff_dVd; dVoxdepinv_dVb = dVfbeff_dVb + 1.0 + dVgsteff_dVb; - } + } else { T1 = sqrt(T0 * T0 + T3); T2 = T0 / T1; Voxdepinv = pParam->BSIM4v4k1ox * (T1 - T0); dVoxdepinv_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - - dVgsteff_dVg); + - dVgsteff_dVg); dVoxdepinv_dVd = -T2 * dVgsteff_dVd; dVoxdepinv_dVb = -T2 * (dVfbeff_dVb + 1.0 + dVgsteff_dVb); } @@ -2192,12 +2455,30 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } if (model->BSIM4v4igcMod) - { T0 = Vtm * pParam->BSIM4v4nigc; - VxNVt = (Vgs_eff - model->BSIM4v4type * here->BSIM4v4vth0) / T0; + { + T0 = Vtm * pParam->BSIM4v4nigc; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + VxNVt = (Vgs_eff - model->BSIM4v4type * pParam->BSIM4v4vth0) / T0; + break; + case BSIM4v30: case BSIM4v40: + VxNVt = (Vgs_eff - model->BSIM4v4type * here->BSIM4v4vth0) / T0; + break; + default: break; + } if (VxNVt > EXP_THRESHOLD) - { Vaux = Vgs_eff - model->BSIM4v4type * here->BSIM4v4vth0; + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Vaux = Vgs_eff - model->BSIM4v4type * pParam->BSIM4v4vth0; + break; + case BSIM4v30: case BSIM4v40: + Vaux = Vgs_eff - model->BSIM4v4type * here->BSIM4v4vth0; + break; + default: break; + } dVaux_dVg = dVgs_eff_dVg; - dVaux_dVd = 0.0; + dVaux_dVd = 0.0; dVaux_dVb = 0.0; } else if (VxNVt < -EXP_THRESHOLD) @@ -2208,7 +2489,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) { ExpVxNVt = exp(VxNVt); Vaux = T0 * log(1.0 + ExpVxNVt); dVaux_dVg = ExpVxNVt / (1.0 + ExpVxNVt); - dVaux_dVd = 0.0; + dVaux_dVd = 0.0; dVaux_dVb = 0.0; dVaux_dVg *= dVgs_eff_dVg; } @@ -2256,7 +2537,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T12 = Vgsteff + 1.0e-20; T13 = T11 / T12 / T12; T14 = -T13 / T12; - Pigcd = T13 * (1.0 - 0.5 * Vdseff / T12); + Pigcd = T13 * (1.0 - 0.5 * Vdseff / T12); dPigcd_dVg = T14 * (2.0 + 0.5 * (dVdseff_dVg * Vgsteff - 3.0 * Vdseff) / T12); dPigcd_dVd = 0.5 * T14 * dVdseff_dVd @@ -2266,12 +2547,23 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dPigcd_dVg *= dVgsteff_dVg; } - T7 = -Pigcd * Vdseff; /* bugfix */ - dT7_dVg = -Vdseff * dPigcd_dVg - Pigcd * dVdseff_dVg; - dT7_dVd = -Vdseff * dPigcd_dVd - Pigcd * dVdseff_dVd + dT7_dVg * dVgsteff_dVd; - dT7_dVb = -Vdseff * dPigcd_dVb - Pigcd * dVdseff_dVb + dT7_dVg * dVgsteff_dVb; - dT7_dVg *= dVgsteff_dVg; - dT7_dVb *= dVbseff_dVb; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T7 = -Pigcd * Vds; + dT7_dVg = -Vds * dPigcd_dVg; + dT7_dVd = -Pigcd - Vds * dPigcd_dVd; + dT7_dVb = -Vds * dPigcd_dVb; + break; + case BSIM4v30: case BSIM4v40: + T7 = -Pigcd * Vdseff; /* bugfix */ + dT7_dVg = -Vdseff * dPigcd_dVg - Pigcd * dVdseff_dVg; + dT7_dVd = -Vdseff * dPigcd_dVd - Pigcd * dVdseff_dVd + dT7_dVg * dVgsteff_dVd; + dT7_dVb = -Vdseff * dPigcd_dVb - Pigcd * dVdseff_dVb + dT7_dVg * dVgsteff_dVb; + dT7_dVg *= dVgsteff_dVg; + dT7_dVb *= dVbseff_dVb; + break; + default: break; + } T8 = T7 * T7 + 2.0e-4; dT8_dVg = 2.0 * T7; dT8_dVd = dT8_dVg * dT7_dVd; @@ -2327,7 +2619,15 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4gIgcdd = dIgcd_dVd; here->BSIM4v4gIgcdb = dIgcd_dVb * dVbseff_dVb; - T0 = vgs - (pParam->BSIM4v4vfbsd + pParam->BSIM4v4vfbsdoff); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + T0 = vgs - pParam->BSIM4v4vfbsd; + break; + case BSIM4v40: + T0 = vgs - (pParam->BSIM4v4vfbsd + pParam->BSIM4v4vfbsdoff); + break; + default: break; + } vgs_eff = sqrt(T0 * T0 + 1.0e-4); dvgs_eff_dvg = T0 / vgs_eff; @@ -2351,14 +2651,14 @@ for (; model != NULL; model = model->BSIM4v4nextModel) else { T6 = exp(T5); dT6_dVg = T6 * T12 * (T3 - 2.0 * T4 * vgs_eff) - * dvgs_eff_dvg; + * dvgs_eff_dvg; } Igs = T11 * T2 * T6; dIgs_dVg = T11 * (T2 * dT6_dVg + T6 * dT2_dVg); dIgs_dVs = -dIgs_dVg; - T0 = vgd - (pParam->BSIM4v4vfbsd + pParam->BSIM4v4vfbsdoff); + T0 = vgd - pParam->BSIM4v4vfbsd; vgd_eff = sqrt(T0 * T0 + 1.0e-4); dvgd_eff_dvg = T0 / vgd_eff; @@ -2392,16 +2692,16 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } else { here->BSIM4v4Igcs = here->BSIM4v4gIgcsg = here->BSIM4v4gIgcsd - = here->BSIM4v4gIgcsb = 0.0; + = here->BSIM4v4gIgcsb = 0.0; here->BSIM4v4Igcd = here->BSIM4v4gIgcdg = here->BSIM4v4gIgcdd - = here->BSIM4v4gIgcdb = 0.0; + = here->BSIM4v4gIgcdb = 0.0; here->BSIM4v4Igs = here->BSIM4v4gIgsg = here->BSIM4v4gIgss = 0.0; here->BSIM4v4Igd = here->BSIM4v4gIgdg = here->BSIM4v4gIgdd = 0.0; } if (model->BSIM4v4igbMod) { T0 = Vtm * pParam->BSIM4v4nigbacc; - T1 = -Vgs_eff + Vbseff + Vfb; + T1 = -Vgs_eff + Vbseff + Vfb; VxNVt = T1 / T0; if (VxNVt > EXP_THRESHOLD) { Vaux = T1; @@ -2415,22 +2715,22 @@ for (; model != NULL; model = model->BSIM4v4nextModel) else { ExpVxNVt = exp(VxNVt); Vaux = T0 * log(1.0 + ExpVxNVt); - dVaux_dVb = ExpVxNVt / (1.0 + ExpVxNVt); + dVaux_dVb = ExpVxNVt / (1.0 + ExpVxNVt); dVaux_dVg = -dVaux_dVb * dVgs_eff_dVg; } - T2 = (Vgs_eff - Vbseff) * Vaux; + T2 = (Vgs_eff - Vbseff) * Vaux; dT2_dVg = dVgs_eff_dVg * Vaux + (Vgs_eff - Vbseff) * dVaux_dVg; dT2_dVb = -Vaux + (Vgs_eff - Vbseff) * dVaux_dVb; T11 = 4.97232e-7 * pParam->BSIM4v4weff - * pParam->BSIM4v4leff * pParam->BSIM4v4ToxRatio; + * pParam->BSIM4v4leff * pParam->BSIM4v4ToxRatio; T12 = -7.45669e11 * model->BSIM4v4toxe; - T3 = pParam->BSIM4v4aigbacc * pParam->BSIM4v4cigbacc + T3 = pParam->BSIM4v4aigbacc * pParam->BSIM4v4cigbacc - pParam->BSIM4v4bigbacc; T4 = pParam->BSIM4v4bigbacc * pParam->BSIM4v4cigbacc; - T5 = T12 * (pParam->BSIM4v4aigbacc + T3 * Voxacc - - T4 * Voxacc * Voxacc); + T5 = T12 * (pParam->BSIM4v4aigbacc + T3 * Voxacc + - T4 * Voxacc * Voxacc); if (T5 > EXP_THRESHOLD) { T6 = MAX_EXP; @@ -2452,7 +2752,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dIgbacc_dVb = T11 * (T2 * dT6_dVb + T6 * dT2_dVb); - T0 = Vtm * pParam->BSIM4v4nigbinv; + T0 = Vtm * pParam->BSIM4v4nigbinv; T1 = Voxdepinv - pParam->BSIM4v4eigbinv; VxNVt = T1 / T0; if (VxNVt > EXP_THRESHOLD) @@ -2468,7 +2768,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) else { ExpVxNVt = exp(VxNVt); Vaux = T0 * log(1.0 + ExpVxNVt); - dVaux_dVg = ExpVxNVt / (1.0 + ExpVxNVt); + dVaux_dVg = ExpVxNVt / (1.0 + ExpVxNVt); dVaux_dVd = dVaux_dVg * dVoxdepinv_dVd; dVaux_dVb = dVaux_dVg * dVoxdepinv_dVb; dVaux_dVg *= dVoxdepinv_dVg; @@ -2515,16 +2815,16 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } else { here->BSIM4v4Igb = here->BSIM4v4gIgbg = here->BSIM4v4gIgbd - = here->BSIM4v4gIgbs = here->BSIM4v4gIgbb = 0.0; + = here->BSIM4v4gIgbs = here->BSIM4v4gIgbb = 0.0; } /* End of Gate current */ - if (here->BSIM4v4nf != 1.0) + if (here->BSIM4v4nf != 1.0) { cdrain *= here->BSIM4v4nf; here->BSIM4v4gds *= here->BSIM4v4nf; here->BSIM4v4gm *= here->BSIM4v4nf; here->BSIM4v4gmbs *= here->BSIM4v4nf; - here->BSIM4v4IdovVds *= here->BSIM4v4nf; - + here->BSIM4v4IdovVds *= here->BSIM4v4nf; + here->BSIM4v4gbbs *= here->BSIM4v4nf; here->BSIM4v4gbgs *= here->BSIM4v4nf; here->BSIM4v4gbds *= here->BSIM4v4nf; @@ -2533,8 +2833,8 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4Igidl *= here->BSIM4v4nf; here->BSIM4v4ggidld *= here->BSIM4v4nf; here->BSIM4v4ggidlg *= here->BSIM4v4nf; - here->BSIM4v4ggidlb *= here->BSIM4v4nf; - + here->BSIM4v4ggidlb *= here->BSIM4v4nf; + here->BSIM4v4Igisl *= here->BSIM4v4nf; here->BSIM4v4ggisls *= here->BSIM4v4nf; here->BSIM4v4ggislg *= here->BSIM4v4nf; @@ -2560,19 +2860,19 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4gIgbg *= here->BSIM4v4nf; here->BSIM4v4gIgbd *= here->BSIM4v4nf; here->BSIM4v4gIgbb *= here->BSIM4v4nf; - } + } here->BSIM4v4ggidls = -(here->BSIM4v4ggidld + here->BSIM4v4ggidlg - + here->BSIM4v4ggidlb); + + here->BSIM4v4ggidlb); here->BSIM4v4ggisld = -(here->BSIM4v4ggisls + here->BSIM4v4ggislg - + here->BSIM4v4ggislb); + + here->BSIM4v4ggislb); here->BSIM4v4gIgbs = -(here->BSIM4v4gIgbg + here->BSIM4v4gIgbd + here->BSIM4v4gIgbb); here->BSIM4v4gIgcss = -(here->BSIM4v4gIgcsg + here->BSIM4v4gIgcsd + here->BSIM4v4gIgcsb); here->BSIM4v4gIgcds = -(here->BSIM4v4gIgcdg + here->BSIM4v4gIgcdd + here->BSIM4v4gIgcdb); - here->BSIM4v4cd = cdrain; + here->BSIM4v4cd = cdrain; if (model->BSIM4v4tnoiMod == 0) @@ -2600,46 +2900,46 @@ for (; model != NULL; model = model->BSIM4v4nextModel) * (Vgsteff - 0.5 * T0 + Abulk * T3); } - /* + /* * BSIM4v4 C-V begins - */ + */ if ((model->BSIM4v4xpart < 0) || (!ChargeComputationNeeded)) - { qgate = qdrn = qsrc = qbulk = 0.0; + { qgate = qdrn = qsrc = qbulk = 0.0; here->BSIM4v4cggb = here->BSIM4v4cgsb = here->BSIM4v4cgdb = 0.0; here->BSIM4v4cdgb = here->BSIM4v4cdsb = here->BSIM4v4cddb = 0.0; here->BSIM4v4cbgb = here->BSIM4v4cbsb = here->BSIM4v4cbdb = 0.0; here->BSIM4v4csgb = here->BSIM4v4cssb = here->BSIM4v4csdb = 0.0; here->BSIM4v4cgbb = here->BSIM4v4csbb = here->BSIM4v4cdbb = here->BSIM4v4cbbb = 0.0; - here->BSIM4v4cqdb = here->BSIM4v4cqsb = here->BSIM4v4cqgb + here->BSIM4v4cqdb = here->BSIM4v4cqsb = here->BSIM4v4cqgb = here->BSIM4v4cqbb = 0.0; here->BSIM4v4gtau = 0.0; goto finished; } - else if (model->BSIM4v4capMod == 0) - { + else if (model->BSIM4v4capMod == 0) + { if (Vbseff < 0.0) - { Vbseff = Vbs; + { Vbseff = Vbs; dVbseff_dVb = 1.0; } - else - { Vbseff = pParam->BSIM4v4phi - Phis; + else + { Vbseff = pParam->BSIM4v4phi - Phis; dVbseff_dVb = -dPhis_dVb; } Vfb = pParam->BSIM4v4vfbcv; - Vth = Vfb + pParam->BSIM4v4phi + pParam->BSIM4v4k1ox * sqrtPhis; + Vth = Vfb + pParam->BSIM4v4phi + pParam->BSIM4v4k1ox * sqrtPhis; Vgst = Vgs_eff - Vth; - dVth_dVb = pParam->BSIM4v4k1ox * dsqrtPhis_dVb; + dVth_dVb = pParam->BSIM4v4k1ox * dsqrtPhis_dVb; dVgst_dVb = -dVth_dVb; - dVgst_dVg = dVgs_eff_dVg; + dVgst_dVg = dVgs_eff_dVg; CoxWL = model->BSIM4v4coxe * pParam->BSIM4v4weffCV * pParam->BSIM4v4leffCV * here->BSIM4v4nf; Arg1 = Vgs_eff - Vbseff - Vfb; if (Arg1 <= 0.0) - { qgate = CoxWL * Arg1; + { qgate = CoxWL * Arg1; qbulk = -qgate; qdrn = 0.0; @@ -2655,18 +2955,18 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4cbdb = 0.0; here->BSIM4v4cbsb = -here->BSIM4v4cgsb; } /* Arg1 <= 0.0, end of accumulation */ - else if (Vgst <= 0.0) - { T1 = 0.5 * pParam->BSIM4v4k1ox; - T2 = sqrt(T1 * T1 + Arg1); - qgate = CoxWL * pParam->BSIM4v4k1ox * (T2 - T1); + else if (Vgst <= 0.0) + { T1 = 0.5 * pParam->BSIM4v4k1ox; + T2 = sqrt(T1 * T1 + Arg1); + qgate = CoxWL * pParam->BSIM4v4k1ox * (T2 - T1); qbulk = -qgate; qdrn = 0.0; - T0 = CoxWL * T1 / T2; - here->BSIM4v4cggb = T0 * dVgs_eff_dVg; - here->BSIM4v4cgdb = 0.0; + T0 = CoxWL * T1 / T2; + here->BSIM4v4cggb = T0 * dVgs_eff_dVg; + here->BSIM4v4cgdb = 0.0; here->BSIM4v4cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg); - + here->BSIM4v4cdgb = 0.0; here->BSIM4v4cddb = 0.0; here->BSIM4v4cdsb = 0.0; @@ -2675,62 +2975,62 @@ for (; model != NULL; model = model->BSIM4v4nextModel) here->BSIM4v4cbdb = 0.0; here->BSIM4v4cbsb = -here->BSIM4v4cgsb; } /* Vgst <= 0.0, end of depletion */ - else - { One_Third_CoxWL = CoxWL / 3.0; + else + { One_Third_CoxWL = CoxWL / 3.0; Two_Third_CoxWL = 2.0 * One_Third_CoxWL; AbulkCV = Abulk0 * pParam->BSIM4v4abulkCVfactor; dAbulkCV_dVb = pParam->BSIM4v4abulkCVfactor * dAbulk0_dVb; - Vdsat = Vgst / AbulkCV; - dVdsat_dVg = dVgs_eff_dVg / AbulkCV; - dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; + Vdsat = Vgst / AbulkCV; + dVdsat_dVg = dVgs_eff_dVg / AbulkCV; + dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV; if (model->BSIM4v4xpart > 0.5) - { /* 0/100 Charge partition model */ - if (Vdsat <= Vds) - { /* saturation region */ - T1 = Vdsat / 3.0; - qgate = CoxWL * (Vgs_eff - Vfb - - pParam->BSIM4v4phi - T1); - T2 = -Two_Third_CoxWL * Vgst; - qbulk = -(qgate + T2); - qdrn = 0.0; + { /* 0/100 Charge partition model */ + if (Vdsat <= Vds) + { /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb + - pParam->BSIM4v4phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.0; - here->BSIM4v4cggb = One_Third_CoxWL * (3.0 - - dVdsat_dVg) * dVgs_eff_dVg; - T2 = -One_Third_CoxWL * dVdsat_dVb; - here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); + here->BSIM4v4cggb = One_Third_CoxWL * (3.0 + - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); here->BSIM4v4cgdb = 0.0; - + here->BSIM4v4cdgb = 0.0; here->BSIM4v4cddb = 0.0; here->BSIM4v4cdsb = 0.0; - here->BSIM4v4cbgb = -(here->BSIM4v4cggb - - Two_Third_CoxWL * dVgs_eff_dVg); - T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); - here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); + here->BSIM4v4cbgb = -(here->BSIM4v4cggb + - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); here->BSIM4v4cbdb = 0.0; - } - else - { /* linear region */ - Alphaz = Vgst / Vdsat; - T1 = 2.0 * Vdsat - Vds; - T2 = Vds / (3.0 * T1); - T3 = T2 * Vds; - T9 = 0.25 * CoxWL; - T4 = T9 * Alphaz; - T7 = 2.0 * Vds - T1 - 3.0 * T3; - T8 = T3 - T1 - 2.0 * Vds; - qgate = CoxWL * (Vgs_eff - Vfb - - pParam->BSIM4v4phi - 0.5 * (Vds - T3)); - T10 = T4 * T8; - qdrn = T4 * T7; - qbulk = -(qgate + qdrn + T10); - + } + else + { /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + T7 = 2.0 * Vds - T1 - 3.0 * T3; + T8 = T3 - T1 - 2.0 * Vds; + qgate = CoxWL * (Vgs_eff - Vfb + - pParam->BSIM4v4phi - 0.5 * (Vds - T3)); + T10 = T4 * T8; + qdrn = T4 * T7; + qbulk = -(qgate + qdrn + T10); + T5 = T3 / T1; here->BSIM4v4cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) - * dVgs_eff_dVg; + * dVgs_eff_dVg; T11 = -CoxWL * T5 * dVdsat_dVb; here->BSIM4v4cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T11 @@ -2742,7 +3042,7 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T8 = T9 * T8; T9 = 2.0 * T4 * (1.0 - 3.0 * T5); here->BSIM4v4cdgb = (T7 * dAlphaz_dVg - T9 - * dVdsat_dVg) * dVgs_eff_dVg; + * dVdsat_dVg) * dVgs_eff_dVg; T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb; here->BSIM4v4cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5); here->BSIM4v4cdsb = -(here->BSIM4v4cdgb + T12 @@ -2750,195 +3050,195 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T9 = 2.0 * T4 * (1.0 + T5); T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg) - * dVgs_eff_dVg; + * dVgs_eff_dVg; T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb; - T12 = T4 * (2.0 * T2 + T5 - 1.0); + T12 = T4 * (2.0 * T2 + T5 - 1.0); T0 = -(T10 + T11 + T12); here->BSIM4v4cbgb = -(here->BSIM4v4cggb - + here->BSIM4v4cdgb + T10); - here->BSIM4v4cbdb = -(here->BSIM4v4cgdb - + here->BSIM4v4cddb + T12); + + here->BSIM4v4cdgb + T10); + here->BSIM4v4cbdb = -(here->BSIM4v4cgdb + + here->BSIM4v4cddb + T12); here->BSIM4v4cbsb = -(here->BSIM4v4cgsb - + here->BSIM4v4cdsb + T0); + + here->BSIM4v4cdsb + T0); } } - else if (model->BSIM4v4xpart < 0.5) - { /* 40/60 Charge partition model */ - if (Vds >= Vdsat) - { /* saturation region */ - T1 = Vdsat / 3.0; - qgate = CoxWL * (Vgs_eff - Vfb - - pParam->BSIM4v4phi - T1); - T2 = -Two_Third_CoxWL * Vgst; - qbulk = -(qgate + T2); - qdrn = 0.4 * T2; + else if (model->BSIM4v4xpart < 0.5) + { /* 40/60 Charge partition model */ + if (Vds >= Vdsat) + { /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb + - pParam->BSIM4v4phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.4 * T2; - here->BSIM4v4cggb = One_Third_CoxWL * (3.0 - - dVdsat_dVg) * dVgs_eff_dVg; - T2 = -One_Third_CoxWL * dVdsat_dVb; - here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); - here->BSIM4v4cgdb = 0.0; - - T3 = 0.4 * Two_Third_CoxWL; + here->BSIM4v4cggb = One_Third_CoxWL * (3.0 + - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); + here->BSIM4v4cgdb = 0.0; + + T3 = 0.4 * Two_Third_CoxWL; here->BSIM4v4cdgb = -T3 * dVgs_eff_dVg; here->BSIM4v4cddb = 0.0; - T4 = T3 * dVth_dVb; + T4 = T3 * dVth_dVb; here->BSIM4v4cdsb = -(T4 + here->BSIM4v4cdgb); - here->BSIM4v4cbgb = -(here->BSIM4v4cggb - - Two_Third_CoxWL * dVgs_eff_dVg); - T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); - here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); + here->BSIM4v4cbgb = -(here->BSIM4v4cggb + - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); here->BSIM4v4cbdb = 0.0; - } - else - { /* linear region */ - Alphaz = Vgst / Vdsat; - T1 = 2.0 * Vdsat - Vds; - T2 = Vds / (3.0 * T1); - T3 = T2 * Vds; - T9 = 0.25 * CoxWL; - T4 = T9 * Alphaz; - qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM4v4phi - - 0.5 * (Vds - T3)); + } + else + { /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM4v4phi + - 0.5 * (Vds - T3)); - T5 = T3 / T1; + T5 = T3 / T1; here->BSIM4v4cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) - * dVgs_eff_dVg; + * dVgs_eff_dVg; tmp = -CoxWL * T5 * dVdsat_dVb; here->BSIM4v4cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); - here->BSIM4v4cgsb = -(here->BSIM4v4cggb - + here->BSIM4v4cgdb + tmp); + here->BSIM4v4cgsb = -(here->BSIM4v4cggb + + here->BSIM4v4cgdb + tmp); - T6 = 1.0 / Vdsat; + T6 = 1.0 / Vdsat; dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); - T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds - + 1.2 * Vds * Vds; - T8 = T2 / T1; - T7 = Vds - T1 - T8 * T6; - qdrn = T4 * T7; - T7 *= T9; - tmp = T8 / T1; - tmp1 = T4 * (2.0 - 4.0 * tmp * T6 - + T8 * (16.0 * Vdsat - 6.0 * Vds)); + T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds + + 1.2 * Vds * Vds; + T8 = T2 / T1; + T7 = Vds - T1 - T8 * T6; + qdrn = T4 * T7; + T7 *= T9; + tmp = T8 / T1; + tmp1 = T4 * (2.0 - 4.0 * tmp * T6 + + T8 * (16.0 * Vdsat - 6.0 * Vds)); here->BSIM4v4cdgb = (T7 * dAlphaz_dVg - tmp1 - * dVdsat_dVg) * dVgs_eff_dVg; + * dVdsat_dVg) * dVgs_eff_dVg; T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb; here->BSIM4v4cddb = T4 * (2.0 - (1.0 / (3.0 * T1 - * T1) + 2.0 * tmp) * T6 + T8 - * (6.0 * Vdsat - 2.4 * Vds)); - here->BSIM4v4cdsb = -(here->BSIM4v4cdgb - + T10 + here->BSIM4v4cddb); + * T1) + 2.0 * tmp) * T6 + T8 + * (6.0 * Vdsat - 2.4 * Vds)); + here->BSIM4v4cdsb = -(here->BSIM4v4cdgb + + T10 + here->BSIM4v4cddb); - T7 = 2.0 * (T1 + T3); - qbulk = -(qgate - T4 * T7); - T7 *= T9; - T0 = 4.0 * T4 * (1.0 - T5); - T12 = (-T7 * dAlphaz_dVg - here->BSIM4v4cdgb - - T0 * dVdsat_dVg) * dVgs_eff_dVg; - T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; - T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) - - here->BSIM4v4cddb; + T7 = 2.0 * (T1 + T3); + qbulk = -(qgate - T4 * T7); + T7 *= T9; + T0 = 4.0 * T4 * (1.0 - T5); + T12 = (-T7 * dAlphaz_dVg - here->BSIM4v4cdgb + - T0 * dVdsat_dVg) * dVgs_eff_dVg; + T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb; + T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5) + - here->BSIM4v4cddb; tmp = -(T10 + T11 + T12); - here->BSIM4v4cbgb = -(here->BSIM4v4cggb - + here->BSIM4v4cdgb + T12); + here->BSIM4v4cbgb = -(here->BSIM4v4cggb + + here->BSIM4v4cdgb + T12); here->BSIM4v4cbdb = -(here->BSIM4v4cgdb - + here->BSIM4v4cddb + T10); + + here->BSIM4v4cddb + T10); here->BSIM4v4cbsb = -(here->BSIM4v4cgsb - + here->BSIM4v4cdsb + tmp); + + here->BSIM4v4cdsb + tmp); } } - else - { /* 50/50 partitioning */ - if (Vds >= Vdsat) - { /* saturation region */ - T1 = Vdsat / 3.0; - qgate = CoxWL * (Vgs_eff - Vfb - - pParam->BSIM4v4phi - T1); - T2 = -Two_Third_CoxWL * Vgst; - qbulk = -(qgate + T2); - qdrn = 0.5 * T2; + else + { /* 50/50 partitioning */ + if (Vds >= Vdsat) + { /* saturation region */ + T1 = Vdsat / 3.0; + qgate = CoxWL * (Vgs_eff - Vfb + - pParam->BSIM4v4phi - T1); + T2 = -Two_Third_CoxWL * Vgst; + qbulk = -(qgate + T2); + qdrn = 0.5 * T2; + + here->BSIM4v4cggb = One_Third_CoxWL * (3.0 + - dVdsat_dVg) * dVgs_eff_dVg; + T2 = -One_Third_CoxWL * dVdsat_dVb; + here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); + here->BSIM4v4cgdb = 0.0; - here->BSIM4v4cggb = One_Third_CoxWL * (3.0 - - dVdsat_dVg) * dVgs_eff_dVg; - T2 = -One_Third_CoxWL * dVdsat_dVb; - here->BSIM4v4cgsb = -(here->BSIM4v4cggb + T2); - here->BSIM4v4cgdb = 0.0; - here->BSIM4v4cdgb = -One_Third_CoxWL * dVgs_eff_dVg; here->BSIM4v4cddb = 0.0; - T4 = One_Third_CoxWL * dVth_dVb; + T4 = One_Third_CoxWL * dVth_dVb; here->BSIM4v4cdsb = -(T4 + here->BSIM4v4cdgb); - here->BSIM4v4cbgb = -(here->BSIM4v4cggb - - Two_Third_CoxWL * dVgs_eff_dVg); - T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); - here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); + here->BSIM4v4cbgb = -(here->BSIM4v4cggb + - Two_Third_CoxWL * dVgs_eff_dVg); + T3 = -(T2 + Two_Third_CoxWL * dVth_dVb); + here->BSIM4v4cbsb = -(here->BSIM4v4cbgb + T3); here->BSIM4v4cbdb = 0.0; - } - else - { /* linear region */ - Alphaz = Vgst / Vdsat; - T1 = 2.0 * Vdsat - Vds; - T2 = Vds / (3.0 * T1); - T3 = T2 * Vds; - T9 = 0.25 * CoxWL; - T4 = T9 * Alphaz; - qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM4v4phi - - 0.5 * (Vds - T3)); + } + else + { /* linear region */ + Alphaz = Vgst / Vdsat; + T1 = 2.0 * Vdsat - Vds; + T2 = Vds / (3.0 * T1); + T3 = T2 * Vds; + T9 = 0.25 * CoxWL; + T4 = T9 * Alphaz; + qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM4v4phi + - 0.5 * (Vds - T3)); - T5 = T3 / T1; + T5 = T3 / T1; here->BSIM4v4cggb = CoxWL * (1.0 - T5 * dVdsat_dVg) - * dVgs_eff_dVg; + * dVgs_eff_dVg; tmp = -CoxWL * T5 * dVdsat_dVb; here->BSIM4v4cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5); - here->BSIM4v4cgsb = -(here->BSIM4v4cggb - + here->BSIM4v4cgdb + tmp); + here->BSIM4v4cgsb = -(here->BSIM4v4cggb + + here->BSIM4v4cgdb + tmp); - T6 = 1.0 / Vdsat; + T6 = 1.0 / Vdsat; dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg); dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb); - T7 = T1 + T3; - qdrn = -T4 * T7; - qbulk = - (qgate + qdrn + qdrn); - T7 *= T9; - T0 = T4 * (2.0 * T5 - 2.0); + T7 = T1 + T3; + qdrn = -T4 * T7; + qbulk = - (qgate + qdrn + qdrn); + T7 *= T9; + T0 = T4 * (2.0 * T5 - 2.0); here->BSIM4v4cdgb = (T0 * dVdsat_dVg - T7 - * dAlphaz_dVg) * dVgs_eff_dVg; - T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; + * dAlphaz_dVg) * dVgs_eff_dVg; + T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb; here->BSIM4v4cddb = T4 * (1.0 - 2.0 * T2 - T5); here->BSIM4v4cdsb = -(here->BSIM4v4cdgb + T12 + here->BSIM4v4cddb); here->BSIM4v4cbgb = -(here->BSIM4v4cggb - + 2.0 * here->BSIM4v4cdgb); + + 2.0 * here->BSIM4v4cdgb); here->BSIM4v4cbdb = -(here->BSIM4v4cgdb - + 2.0 * here->BSIM4v4cddb); + + 2.0 * here->BSIM4v4cddb); here->BSIM4v4cbsb = -(here->BSIM4v4cgsb - + 2.0 * here->BSIM4v4cdsb); + + 2.0 * here->BSIM4v4cdsb); } /* end of linear region */ - } /* end of 50/50 partition */ - } /* end of inversion */ - } /* end of capMod=0 */ - else - { if (Vbseff < 0.0) - { VbseffCV = Vbseff; + } /* end of 50/50 partition */ + } /* end of inversion */ + } /* end of capMod=0 */ + else + { if (Vbseff < 0.0) + { VbseffCV = Vbseff; dVbseffCV_dVb = 1.0; } - else - { VbseffCV = pParam->BSIM4v4phi - Phis; + else + { VbseffCV = pParam->BSIM4v4phi - Phis; dVbseffCV_dVb = -dPhis_dVb; } CoxWL = model->BSIM4v4coxe * pParam->BSIM4v4weffCV - * pParam->BSIM4v4leffCV * here->BSIM4v4nf; + * pParam->BSIM4v4leffCV * here->BSIM4v4nf; /* Seperate VgsteffCV with noff and voffcv */ noff = n * pParam->BSIM4v4noff; @@ -2973,67 +3273,76 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } /* End of VgsteffCV */ - if (model->BSIM4v4capMod == 1) - { Vfb = here->BSIM4v4vfbzb; + if (model->BSIM4v4capMod == 1) + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Vfb = pParam->BSIM4v4vfbzb; + break; + case BSIM4v30: case BSIM4v40: + Vfb = here->BSIM4v4vfbzb; + break; + default: break; + } V3 = Vfb - Vgs_eff + VbseffCV - DELTA_3; - if (Vfb <= 0.0) - T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); - else - T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); + if (Vfb <= 0.0) + T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb); + else + T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb); - T1 = 0.5 * (1.0 + V3 / T0); - Vfbeff = Vfb - 0.5 * (V3 + T0); - dVfbeff_dVg = T1 * dVgs_eff_dVg; - dVfbeff_dVb = -T1 * dVbseffCV_dVb; - Qac0 = CoxWL * (Vfbeff - Vfb); - dQac0_dVg = CoxWL * dVfbeff_dVg; - dQac0_dVb = CoxWL * dVfbeff_dVb; + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = Vfb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + Qac0 = CoxWL * (Vfbeff - Vfb); + dQac0_dVg = CoxWL * dVfbeff_dVg; + dQac0_dVb = CoxWL * dVfbeff_dVb; T0 = 0.5 * pParam->BSIM4v4k1ox; - T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; + T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; if (pParam->BSIM4v4k1ox == 0.0) { T1 = 0.0; T2 = 0.0; } - else if (T3 < 0.0) - { T1 = T0 + T3 / pParam->BSIM4v4k1ox; + else if (T3 < 0.0) + { T1 = T0 + T3 / pParam->BSIM4v4k1ox; T2 = CoxWL; - } - else - { T1 = sqrt(T0 * T0 + T3); + } + else + { T1 = sqrt(T0 * T0 + T3); T2 = CoxWL * T0 / T1; - } + } - Qsub0 = CoxWL * pParam->BSIM4v4k1ox * (T1 - T0); + Qsub0 = CoxWL * pParam->BSIM4v4k1ox * (T1 - T0); dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg); dQsub0_dVd = -T2 * dVgsteff_dVd; - dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb); AbulkCV = Abulk0 * pParam->BSIM4v4abulkCVfactor; dAbulkCV_dVb = pParam->BSIM4v4abulkCVfactor * dAbulk0_dVb; - VdsatCV = Vgsteff / AbulkCV; + VdsatCV = Vgsteff / AbulkCV; - T0 = VdsatCV - Vds - DELTA_4; - dT0_dVg = 1.0 / AbulkCV; - dT0_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; - T1 = sqrt(T0 * T0 + 4.0 * DELTA_4 * VdsatCV); + T0 = VdsatCV - Vds - DELTA_4; + dT0_dVg = 1.0 / AbulkCV; + dT0_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_4 * VdsatCV); dT1_dVg = (T0 + DELTA_4 + DELTA_4) / T1; dT1_dVd = -T0 / T1; dT1_dVb = dT1_dVg * dT0_dVb; - dT1_dVg *= dT0_dVg; - if (T0 >= 0.0) - { VdseffCV = VdsatCV - 0.5 * (T0 + T1); + dT1_dVg *= dT0_dVg; + if (T0 >= 0.0) + { VdseffCV = VdsatCV - 0.5 * (T0 + T1); dVdseffCV_dVg = 0.5 * (dT0_dVg - dT1_dVg); dVdseffCV_dVd = 0.5 * (1.0 - dT1_dVd); dVdseffCV_dVb = 0.5 * (dT0_dVb - dT1_dVb); - } + } else { T3 = (DELTA_4 + DELTA_4) / (T1 - T0); - T4 = 1.0 - T3; - T5 = VdsatCV * T3 / (T1 - T0); - VdseffCV = VdsatCV * T4; + T4 = 1.0 - T3; + T5 = VdsatCV * T3 / (T1 - T0); + VdseffCV = VdsatCV * T4; dVdseffCV_dVg = dT0_dVg * T4 + T5 * (dT1_dVg - dT0_dVg); dVdseffCV_dVd = T5 * (dT1_dVd + 1.0); dVdseffCV_dVb = dT0_dVb * (1.0 - T5) + T5 * dT1_dVb; @@ -3045,123 +3354,177 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dVdseffCV_dVb = 0.0; } - T0 = AbulkCV * VdseffCV; - T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.0e-20); - T2 = VdseffCV / T1; - T3 = T0 * T2; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.0e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; - T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); - T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); - T6 = 12.0 * T2 * T2 * Vgsteff; + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; - qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + break; + case BSIM4v30: + T0 = AbulkCV * VdseffCV; /* bugfix */ + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.0e-20); + T2 = T0 / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2); + T7 = T2 * (2.0 + 6.0 * T2) - 0.5; + T5 = T7 * AbulkCV; + T6 = T7 * VdseffCV; + + qgate = CoxWL * (Vgsteff - 0.5 * T0 + T3); + break; + case BSIM4v40: + T0 = AbulkCV * VdseffCV; + T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.0e-20); + T2 = VdseffCV / T1; + T3 = T0 * T2; + + T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV); + T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5); + T6 = 12.0 * T2 * T2 * Vgsteff; + + qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3); + break; + default: break; + } Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd; Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Cgg1 * dVgsteff_dVb; - Cgg1 *= dVgsteff_dVg; + + Cgg1 * dVgsteff_dVb; + Cgg1 *= dVgsteff_dVg; - T7 = 1.0 - AbulkCV; + T7 = 1.0 - AbulkCV; qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3); - T4 = -T7 * (T4 - 1.0); - T5 = -T7 * T5; - T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); + T4 = -T7 * (T4 - 1.0); + T5 = -T7 * T5; + T6 = -(T7 * T6 + (0.5 * VdseffCV - T3)); Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg); Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd; Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Cbg1 * dVgsteff_dVb; - Cbg1 *= dVgsteff_dVg; + + Cbg1 * dVgsteff_dVb; + Cbg1 *= dVgsteff_dVg; if (model->BSIM4v4xpart > 0.5) - { /* 0/100 Charge petition model */ - T1 = T1 + T1; + { /* 0/100 Charge petition model */ + T1 = T1 + T1; qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0 - - T0 * T0 / T1); - T7 = (4.0 * Vgsteff - T0) / (T1 * T1); - T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); - T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); + - T0 * T0 / T1); + T7 = (4.0 * Vgsteff - T0) / (T1 * T1); + T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1)); + T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7); T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7); Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg); Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Csg * dVgsteff_dVb; - Csg *= dVgsteff_dVg; + + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; } - else if (model->BSIM4v4xpart < 0.5) - { /* 40/60 Charge petition model */ - T1 = T1 / 12.0; - T2 = 0.5 * CoxWL / (T1 * T1); - T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff - * (Vgsteff - 4.0 * T0 / 3.0)) - - 2.0 * T0 * T0 * T0 / 15.0; - qsrc = -T2 * T3; - T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) - + 0.4 * T0 * T0; - T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 - * Vgsteff - 8.0 * T0 / 3.0) - + 2.0 * T0 * T0 / 3.0); - T5 = (qsrc / T1 + T2 * T7) * AbulkCV; - T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); + else if (model->BSIM4v4xpart < 0.5) + { /* 40/60 Charge petition model */ + T1 = T1 / 12.0; + T2 = 0.5 * CoxWL / (T1 * T1); + T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff + * (Vgsteff - 4.0 * T0 / 3.0)) + - 2.0 * T0 * T0 * T0 / 15.0; + qsrc = -T2 * T3; + T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0) + + 0.4 * T0 * T0; + T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0 + * Vgsteff - 8.0 * T0 / 3.0) + + 2.0 * T0 * T0 / 3.0); + T5 = (qsrc / T1 + T2 * T7) * AbulkCV; + T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV); Csg = (T4 + T5 * dVdseffCV_dVg); Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd; Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Csg * dVgsteff_dVb; - Csg *= dVgsteff_dVg; + + Csg * dVgsteff_dVb; + Csg *= dVgsteff_dVg; } - else - { /* 50/50 Charge petition model */ + else + { /* 50/50 Charge petition model */ qsrc = -0.5 * (qgate + qbulk); Csg = -0.5 * (Cgg1 + Cbg1); - Csb = -0.5 * (Cgb1 + Cbb1); - Csd = -0.5 * (Cgd1 + Cbd1); + Csb = -0.5 * (Cgb1 + Cbb1); + Csd = -0.5 * (Cgd1 + Cbd1); } - qgate += Qac0 + Qsub0; - qbulk -= (Qac0 + Qsub0); + qgate += Qac0 + Qsub0; + qbulk -= (Qac0 + Qsub0); qdrn = -(qgate + qbulk + qsrc); - Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; - Cgd = dQsub0_dVd + Cgd1; - Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; + Cgg = dQac0_dVg + dQsub0_dVg + Cgg1; + Cgd = dQsub0_dVd + Cgd1; + Cgb = dQac0_dVb + dQsub0_dVb + Cgb1; - Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; - Cbd = Cbd1 - dQsub0_dVd; - Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; - Cgb *= dVbseff_dVb; - Cbb *= dVbseff_dVb; - Csb *= dVbseff_dVb; + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; here->BSIM4v4cggb = Cgg; - here->BSIM4v4cgsb = -(Cgg + Cgd + Cgb); - here->BSIM4v4cgdb = Cgd; + here->BSIM4v4cgsb = -(Cgg + Cgd + Cgb); + here->BSIM4v4cgdb = Cgd; here->BSIM4v4cdgb = -(Cgg + Cbg + Csg); - here->BSIM4v4cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb - + Csg + Csd + Csb); - here->BSIM4v4cddb = -(Cgd + Cbd + Csd); + here->BSIM4v4cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + + Csg + Csd + Csb); + here->BSIM4v4cddb = -(Cgd + Cbd + Csd); here->BSIM4v4cbgb = Cbg; - here->BSIM4v4cbsb = -(Cbg + Cbd + Cbb); - here->BSIM4v4cbdb = Cbd; - } + here->BSIM4v4cbsb = -(Cbg + Cbd + Cbb); + here->BSIM4v4cbdb = Cbd; + } /* Charge-Thickness capMod (CTM) begins */ - else if (model->BSIM4v4capMod == 2) - { V3 = here->BSIM4v4vfbzb - Vgs_eff + VbseffCV - DELTA_3; - if (here->BSIM4v4vfbzb <= 0.0) - T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * here->BSIM4v4vfbzb); - else - T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * here->BSIM4v4vfbzb); + else if (model->BSIM4v4capMod == 2) + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + V3 = pParam->BSIM4v4vfbzb - Vgs_eff + VbseffCV - DELTA_3; + if (pParam->BSIM4v4vfbzb <= 0.0) + T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * pParam->BSIM4v4vfbzb); + else + T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * pParam->BSIM4v4vfbzb); - T1 = 0.5 * (1.0 + V3 / T0); - Vfbeff = here->BSIM4v4vfbzb - 0.5 * (V3 + T0); - dVfbeff_dVg = T1 * dVgs_eff_dVg; - dVfbeff_dVb = -T1 * dVbseffCV_dVb; + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = pParam->BSIM4v4vfbzb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; - Cox = model->BSIM4v4coxp; - Tox = 1.0e8 * model->BSIM4v4toxp; - T0 = (Vgs_eff - VbseffCV - here->BSIM4v4vfbzb) / Tox; - dT0_dVg = dVgs_eff_dVg / Tox; - dT0_dVb = -dVbseffCV_dVb / Tox; + Cox = model->BSIM4v4coxp; + Tox = 1.0e8 * model->BSIM4v4toxp; + T0 = (Vgs_eff - VbseffCV - pParam->BSIM4v4vfbzb) / Tox; + dT0_dVg = dVgs_eff_dVg / Tox; + dT0_dVb = -dVbseffCV_dVb / Tox; + break; + case BSIM4v30: case BSIM4v40: + V3 = here->BSIM4v4vfbzb - Vgs_eff + VbseffCV - DELTA_3; + if (here->BSIM4v4vfbzb <= 0.0) + T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * here->BSIM4v4vfbzb); + else + T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * here->BSIM4v4vfbzb); + + T1 = 0.5 * (1.0 + V3 / T0); + Vfbeff = here->BSIM4v4vfbzb - 0.5 * (V3 + T0); + dVfbeff_dVg = T1 * dVgs_eff_dVg; + dVfbeff_dVb = -T1 * dVbseffCV_dVb; + + Cox = model->BSIM4v4coxp; + Tox = 1.0e8 * model->BSIM4v4toxp; + T0 = (Vgs_eff - VbseffCV - here->BSIM4v4vfbzb) / Tox; + dT0_dVg = dVgs_eff_dVg / Tox; + dT0_dVb = -dVbseffCV_dVb / Tox; + break; + default: break; + } tmp = T0 * pParam->BSIM4v4acde; if ((-EXP_THRESHOLD < tmp) && (tmp < EXP_THRESHOLD)) @@ -3196,12 +3559,20 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dCoxeff_dVg *= dTcen_dVg; CoxWLcen = CoxWL * Coxeff / model->BSIM4v4coxe; - Qac0 = CoxWLcen * (Vfbeff - here->BSIM4v4vfbzb); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Qac0 = CoxWLcen * (Vfbeff - pParam->BSIM4v4vfbzb); + break; + case BSIM4v30: case BSIM4v40: + Qac0 = CoxWLcen * (Vfbeff - here->BSIM4v4vfbzb); + break; + default: break; + } QovCox = Qac0 / Coxeff; dQac0_dVg = CoxWLcen * dVfbeff_dVg + QovCox * dCoxeff_dVg; - dQac0_dVb = CoxWLcen * dVfbeff_dVb - + QovCox * dCoxeff_dVb; + dQac0_dVb = CoxWLcen * dVfbeff_dVb + + QovCox * dCoxeff_dVb; T0 = 0.5 * pParam->BSIM4v4k1ox; T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff; @@ -3226,24 +3597,32 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb) + QovCox * dCoxeff_dVb; - /* Gate-bias dependent delta Phis begins */ - if (pParam->BSIM4v4k1ox <= 0.0) - { Denomi = 0.25 * pParam->BSIM4v4moin * Vtm; + /* Gate-bias dependent delta Phis begins */ + if (pParam->BSIM4v4k1ox <= 0.0) + { Denomi = 0.25 * pParam->BSIM4v4moin * Vtm; T0 = 0.5 * pParam->BSIM4v4sqrtPhi; - } - else - { Denomi = pParam->BSIM4v4moin * Vtm - * pParam->BSIM4v4k1ox * pParam->BSIM4v4k1ox; + } + else + { Denomi = pParam->BSIM4v4moin * Vtm + * pParam->BSIM4v4k1ox * pParam->BSIM4v4k1ox; T0 = pParam->BSIM4v4k1ox * pParam->BSIM4v4sqrtPhi; - } + } T1 = 2.0 * T0 + Vgsteff; - DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi); - dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff); - /* End of delta Phis */ + DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi); + dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff); + /* End of delta Phis */ Tox += Tox; /* WDLiu: Tcen reevaluated below due to different Vgsteff */ - T0 = (Vgsteff + here->BSIM4v4vtfbphi2) / Tox; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + T0 = (Vgsteff + pParam->BSIM4v4vtfbphi2) / Tox; + break; + case BSIM4v30: case BSIM4v40: + T0 = (Vgsteff + here->BSIM4v4vtfbphi2) / Tox; + break; + default: break; + } tmp = exp(0.7 * log(T0)); T1 = 1.0 + tmp; T2 = 0.7 * tmp / (T0 * Tox); @@ -3253,15 +3632,15 @@ for (; model != NULL; model = model->BSIM4v4nextModel) dTcen_dVb = dTcen_dVg * dVgsteff_dVb; dTcen_dVg *= dVgsteff_dVg; - Ccen = EPSSI / Tcen; - T0 = Cox / (Cox + Ccen); - Coxeff = T0 * Ccen; - T1 = -Ccen / Tcen; - dCoxeff_dVg = T0 * T0 * T1; - dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; - dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; - dCoxeff_dVg *= dTcen_dVg; - CoxWLcen = CoxWL * Coxeff / model->BSIM4v4coxe; + Ccen = EPSSI / Tcen; + T0 = Cox / (Cox + Ccen); + Coxeff = T0 * Ccen; + T1 = -Ccen / Tcen; + dCoxeff_dVg = T0 * T0 * T1; + dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd; + dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb; + dCoxeff_dVg *= dTcen_dVg; + CoxWLcen = CoxWL * Coxeff / model->BSIM4v4coxe; AbulkCV = Abulk0 * pParam->BSIM4v4abulkCVfactor; dAbulkCV_dVb = pParam->BSIM4v4abulkCVfactor * dAbulk0_dVb; @@ -3298,22 +3677,22 @@ for (; model != NULL; model = model->BSIM4v4nextModel) } T0 = AbulkCV * VdseffCV; - T1 = Vgsteff - DeltaPhi; + T1 = Vgsteff - DeltaPhi; T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20); T3 = T0 / T2; T4 = 1.0 - 12.0 * T3 * T3; T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5); - T6 = T5 * VdseffCV / AbulkCV; + T6 = T5 * VdseffCV / AbulkCV; qgate = CoxWLcen * (T1 - T0 * (0.5 - T3)); - QovCox = qgate / Coxeff; - Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) - + T5 * dVdseffCV_dVg); - Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 - * dVgsteff_dVd + QovCox * dCoxeff_dVd; - Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; - Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + QovCox = qgate / Coxeff; + Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg) + + T5 * dVdseffCV_dVg); + Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; T7 = 1.0 - AbulkCV; @@ -3323,90 +3702,90 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T11 = -T7 * T5 / AbulkCV; T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2)); - qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); - QovCox = qbulk / Coxeff; - Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg); - Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1 - * dVgsteff_dVd + QovCox * dCoxeff_dVd; - Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) - + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; - Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; + qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2); + QovCox = qbulk / Coxeff; + Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg); + Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1 + * dVgsteff_dVd + QovCox * dCoxeff_dVd; + Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb) + + Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg; if (model->BSIM4v4xpart > 0.5) - { /* 0/100 partition */ - qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 - - 0.5 * T0 * T0 / T2); - QovCox = qsrc / Coxeff; - T2 += T2; - T3 = T2 * T2; - T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); - T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg); - T5 = T7 * AbulkCV; - T6 = T7 * VdseffCV; + { /* 0/100 partition */ + qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0 + - 0.5 * T0 * T0 / T2); + QovCox = qsrc / Coxeff; + T2 += T2; + T3 = T2 * T2; + T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3); + T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg); + T5 = T7 * AbulkCV; + T6 = T7 * VdseffCV; - Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); - Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd - + QovCox * dCoxeff_dVd; - Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) - + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; - Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg); + Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd + + QovCox * dCoxeff_dVd; + Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb) + + Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; } - else if (model->BSIM4v4xpart < 0.5) - { /* 40/60 partition */ - T2 = T2 / 12.0; - T3 = 0.5 * CoxWLcen / (T2 * T2); - T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 + else if (model->BSIM4v4xpart < 0.5) + { /* 40/60 partition */ + T2 = T2 / 12.0; + T3 = 0.5 * CoxWLcen / (T2 * T2); + T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0 * T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0; - qsrc = -T3 * T4; - QovCox = qsrc / Coxeff; - T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; - T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 - * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); - T6 = AbulkCV * (qsrc / T2 + T3 * T8); - T7 = T6 * VdseffCV / AbulkCV; + qsrc = -T3 * T4; + QovCox = qsrc / Coxeff; + T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0; + T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0 + * T0 / 3.0) + 2.0 * T0 * T0 / 3.0); + T6 = AbulkCV * (qsrc / T2 + T3 * T8); + T7 = T6 * VdseffCV / AbulkCV; - Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg; - Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd - + QovCox * dCoxeff_dVd; - Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb - + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; - Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; + Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg; + Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd + + QovCox * dCoxeff_dVd; + Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb + + T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb; + Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg; } - else - { /* 50/50 partition */ + else + { /* 50/50 partition */ qsrc = -0.5 * qgate; Csg = -0.5 * Cgg1; - Csd = -0.5 * Cgd1; - Csb = -0.5 * Cgb1; + Csd = -0.5 * Cgd1; + Csb = -0.5 * Cgb1; } - qgate += Qac0 + Qsub0 - qbulk; - qbulk -= (Qac0 + Qsub0); + qgate += Qac0 + Qsub0 - qbulk; + qbulk -= (Qac0 + Qsub0); qdrn = -(qgate + qbulk + qsrc); - Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; - Cbd = Cbd1 - dQsub0_dVd; - Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; + Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg; + Cbd = Cbd1 - dQsub0_dVd; + Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb; Cgg = Cgg1 - Cbg; Cgd = Cgd1 - Cbd; Cgb = Cgb1 - Cbb; - Cgb *= dVbseff_dVb; - Cbb *= dVbseff_dVb; - Csb *= dVbseff_dVb; + Cgb *= dVbseff_dVb; + Cbb *= dVbseff_dVb; + Csb *= dVbseff_dVb; here->BSIM4v4cggb = Cgg; - here->BSIM4v4cgsb = -(Cgg + Cgd + Cgb); - here->BSIM4v4cgdb = Cgd; + here->BSIM4v4cgsb = -(Cgg + Cgd + Cgb); + here->BSIM4v4cgdb = Cgd; here->BSIM4v4cdgb = -(Cgg + Cbg + Csg); - here->BSIM4v4cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb - + Csg + Csd + Csb); - here->BSIM4v4cddb = -(Cgd + Cbd + Csd); + here->BSIM4v4cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb + + Csg + Csd + Csb); + here->BSIM4v4cddb = -(Cgd + Cbd + Csd); here->BSIM4v4cbgb = Cbg; - here->BSIM4v4cbsb = -(Cbg + Cbd + Cbb); - here->BSIM4v4cbdb = Cbd; - } /* End of CTM */ + here->BSIM4v4cbsb = -(Cbg + Cbd + Cbb); + here->BSIM4v4cbdb = Cbd; + } /* End of CTM */ } here->BSIM4v4csgb = - here->BSIM4v4cggb - here->BSIM4v4cdgb - here->BSIM4v4cbgb; @@ -3435,26 +3814,26 @@ for (; model != NULL; model = model->BSIM4v4nextModel) T1 = here->BSIM4v4gcrg / CoxWL; /* 1 / tau */ here->BSIM4v4gtau = T1 * ScalingFactor; - if (here->BSIM4v4acnqsMod) + if (here->BSIM4v4acnqsMod) here->BSIM4v4taunet = 1.0 / T1; *(ckt->CKTstate0 + here->BSIM4v4qcheq) = qcheq; if (ckt->CKTmode & MODEINITTRAN) *(ckt->CKTstate1 + here->BSIM4v4qcheq) = *(ckt->CKTstate0 + here->BSIM4v4qcheq); - if (here->BSIM4v4trnqsMod) + if (here->BSIM4v4trnqsMod) { error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qcheq); if (error) return(error); - } + } } -finished: +finished: - /* Calculate junction C-V */ + /* Calculate junction C-V */ if (ChargeComputationNeeded) - { czbd = model->BSIM4v4DunitAreaTempJctCap * here->BSIM4v4Adeff; /* bug fix */ + { czbd = model->BSIM4v4DunitAreaTempJctCap * here->BSIM4v4Adeff; /* bug fix */ czbs = model->BSIM4v4SunitAreaTempJctCap * here->BSIM4v4Aseff; czbdsw = model->BSIM4v4DunitLengthSidewallTempJctCap * here->BSIM4v4Pdeff; czbdswg = model->BSIM4v4DunitLengthGateSidewallTempJctCap @@ -3465,109 +3844,109 @@ finished: MJS = model->BSIM4v4SbulkJctBotGradingCoeff; MJSWS = model->BSIM4v4SbulkJctSideGradingCoeff; - MJSWGS = model->BSIM4v4SbulkJctGateSideGradingCoeff; + MJSWGS = model->BSIM4v4SbulkJctGateSideGradingCoeff; MJD = model->BSIM4v4DbulkJctBotGradingCoeff; MJSWD = model->BSIM4v4DbulkJctSideGradingCoeff; MJSWGD = model->BSIM4v4DbulkJctGateSideGradingCoeff; /* Source Bulk Junction */ - if (vbs_jct == 0.0) - { *(ckt->CKTstate0 + here->BSIM4v4qbs) = 0.0; + if (vbs_jct == 0.0) + { *(ckt->CKTstate0 + here->BSIM4v4qbs) = 0.0; here->BSIM4v4capbs = czbs + czbssw + czbsswg; - } - else if (vbs_jct < 0.0) - { if (czbs > 0.0) - { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBS; - if (MJS == 0.5) + } + else if (vbs_jct < 0.0) + { if (czbs > 0.0) + { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBS; + if (MJS == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJS * log(arg)); - *(ckt->CKTstate0 + here->BSIM4v4qbs) = model->BSIM4v4PhiBS * czbs - * (1.0 - arg * sarg) / (1.0 - MJS); - here->BSIM4v4capbs = czbs * sarg; - } - else - { *(ckt->CKTstate0 + here->BSIM4v4qbs) = 0.0; - here->BSIM4v4capbs = 0.0; - } - if (czbssw > 0.0) - { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBSWS; - if (MJSWS == 0.5) + *(ckt->CKTstate0 + here->BSIM4v4qbs) = model->BSIM4v4PhiBS * czbs + * (1.0 - arg * sarg) / (1.0 - MJS); + here->BSIM4v4capbs = czbs * sarg; + } + else + { *(ckt->CKTstate0 + here->BSIM4v4qbs) = 0.0; + here->BSIM4v4capbs = 0.0; + } + if (czbssw > 0.0) + { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBSWS; + if (MJSWS == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJSWS * log(arg)); *(ckt->CKTstate0 + here->BSIM4v4qbs) += model->BSIM4v4PhiBSWS * czbssw - * (1.0 - arg * sarg) / (1.0 - MJSWS); + * (1.0 - arg * sarg) / (1.0 - MJSWS); here->BSIM4v4capbs += czbssw * sarg; - } - if (czbsswg > 0.0) - { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBSWGS; - if (MJSWGS == 0.5) + } + if (czbsswg > 0.0) + { arg = 1.0 - vbs_jct / model->BSIM4v4PhiBSWGS; + if (MJSWGS == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJSWGS * log(arg)); *(ckt->CKTstate0 + here->BSIM4v4qbs) += model->BSIM4v4PhiBSWGS * czbsswg - * (1.0 - arg * sarg) / (1.0 - MJSWGS); + * (1.0 - arg * sarg) / (1.0 - MJSWGS); here->BSIM4v4capbs += czbsswg * sarg; - } + } } - else - { T0 = czbs + czbssw + czbsswg; - T1 = vbs_jct * (czbs * MJS / model->BSIM4v4PhiBS + czbssw * MJSWS - / model->BSIM4v4PhiBSWS + czbsswg * MJSWGS / model->BSIM4v4PhiBSWGS); + else + { T0 = czbs + czbssw + czbsswg; + T1 = vbs_jct * (czbs * MJS / model->BSIM4v4PhiBS + czbssw * MJSWS + / model->BSIM4v4PhiBSWS + czbsswg * MJSWGS / model->BSIM4v4PhiBSWGS); *(ckt->CKTstate0 + here->BSIM4v4qbs) = vbs_jct * (T0 + 0.5 * T1); here->BSIM4v4capbs = T0 + T1; } /* Drain Bulk Junction */ - if (vbd_jct == 0.0) - { *(ckt->CKTstate0 + here->BSIM4v4qbd) = 0.0; + if (vbd_jct == 0.0) + { *(ckt->CKTstate0 + here->BSIM4v4qbd) = 0.0; here->BSIM4v4capbd = czbd + czbdsw + czbdswg; - } - else if (vbd_jct < 0.0) - { if (czbd > 0.0) - { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBD; - if (MJD == 0.5) + } + else if (vbd_jct < 0.0) + { if (czbd > 0.0) + { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBD; + if (MJD == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJD * log(arg)); - *(ckt->CKTstate0 + here->BSIM4v4qbd) = model->BSIM4v4PhiBD* czbd - * (1.0 - arg * sarg) / (1.0 - MJD); + *(ckt->CKTstate0 + here->BSIM4v4qbd) = model->BSIM4v4PhiBD* czbd + * (1.0 - arg * sarg) / (1.0 - MJD); here->BSIM4v4capbd = czbd * sarg; - } - else - { *(ckt->CKTstate0 + here->BSIM4v4qbd) = 0.0; + } + else + { *(ckt->CKTstate0 + here->BSIM4v4qbd) = 0.0; here->BSIM4v4capbd = 0.0; - } - if (czbdsw > 0.0) - { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBSWD; - if (MJSWD == 0.5) + } + if (czbdsw > 0.0) + { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBSWD; + if (MJSWD == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJSWD * log(arg)); - *(ckt->CKTstate0 + here->BSIM4v4qbd) += model->BSIM4v4PhiBSWD * czbdsw - * (1.0 - arg * sarg) / (1.0 - MJSWD); + *(ckt->CKTstate0 + here->BSIM4v4qbd) += model->BSIM4v4PhiBSWD * czbdsw + * (1.0 - arg * sarg) / (1.0 - MJSWD); here->BSIM4v4capbd += czbdsw * sarg; - } - if (czbdswg > 0.0) - { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBSWGD; - if (MJSWGD == 0.5) + } + if (czbdswg > 0.0) + { arg = 1.0 - vbd_jct / model->BSIM4v4PhiBSWGD; + if (MJSWGD == 0.5) sarg = 1.0 / sqrt(arg); - else + else sarg = exp(-MJSWGD * log(arg)); *(ckt->CKTstate0 + here->BSIM4v4qbd) += model->BSIM4v4PhiBSWGD * czbdswg - * (1.0 - arg * sarg) / (1.0 - MJSWGD); + * (1.0 - arg * sarg) / (1.0 - MJSWGD); here->BSIM4v4capbd += czbdswg * sarg; - } + } } - else - { T0 = czbd + czbdsw + czbdswg; + else + { T0 = czbd + czbdsw + czbdswg; T1 = vbd_jct * (czbd * MJD / model->BSIM4v4PhiBD + czbdsw * MJSWD / model->BSIM4v4PhiBSWD + czbdswg * MJSWGD / model->BSIM4v4PhiBSWGD); *(ckt->CKTstate0 + here->BSIM4v4qbd) = vbd_jct * (T0 + 0.5 * T1); - here->BSIM4v4capbd = T0 + T1; + here->BSIM4v4capbd = T0 + T1; } } @@ -3577,21 +3956,30 @@ finished: */ if ((here->BSIM4v4off == 0) || (!(ckt->CKTmode & MODEINITFIX))) - { if (Check == 1) - { ckt->CKTnoncon++; + { if (Check == 1) + { ckt->CKTnoncon++; #ifndef NEWCONV - } - else + } + else { if (here->BSIM4v4mode >= 0) { Idtot = here->BSIM4v4cd + here->BSIM4v4csub - + here->BSIM4v4Igidl - here->BSIM4v4cbd; + + here->BSIM4v4Igidl - here->BSIM4v4cbd; } else - { Idtot = here->BSIM4v4cd + here->BSIM4v4cbd - here->BSIM4v4Igidl; /* bugfix */ + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Idtot = here->BSIM4v4cd + here->BSIM4v4cbd; + break; + case BSIM4v30: case BSIM4v40: + Idtot = here->BSIM4v4cd + here->BSIM4v4cbd - here->BSIM4v4Igidl; /* bugfix */ + break; + default: break; + } } tol0 = ckt->CKTreltol * MAX(fabs(cdhat), fabs(Idtot)) + ckt->CKTabstol; - tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot)) + tol1 = ckt->CKTreltol * MAX(fabs(cseshat), fabs(Isestot)) + ckt->CKTabstol; tol2 = ckt->CKTreltol * MAX(fabs(cdedhat), fabs(Idedtot)) + ckt->CKTabstol; @@ -3602,20 +3990,30 @@ finished: tol5 = ckt->CKTreltol * MAX(fabs(cgbhat), fabs(Igbtot)) + ckt->CKTabstol; if ((fabs(cdhat - Idtot) >= tol0) || (fabs(cseshat - Isestot) >= tol1) - || (fabs(cdedhat - Idedtot) >= tol2)) + || (fabs(cdedhat - Idedtot) >= tol2)) { ckt->CKTnoncon++; } - else if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4) - || (fabs(cgbhat - Igbtot) >= tol5)) + else if ((fabs(cgshat - Igstot) >= tol3) || (fabs(cgdhat - Igdtot) >= tol4) + || (fabs(cgbhat - Igbtot) >= tol5)) { ckt->CKTnoncon++; } else - { Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd - - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; + { + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd + - here->BSIM4v4Igidl - here->BSIM4v4csub; + break; + case BSIM4v30: case BSIM4v40: + Ibtot = here->BSIM4v4cbs + here->BSIM4v4cbd + - here->BSIM4v4Igidl - here->BSIM4v4Igisl - here->BSIM4v4csub; + break; + default: break; + } tol6 = ckt->CKTreltol * MAX(fabs(cbhat), fabs(Ibtot)) + ckt->CKTabstol; if (fabs(cbhat - Ibtot) > tol6) - { ckt->CKTnoncon++; + { ckt->CKTnoncon++; } } #endif /* NEWCONV */ @@ -3625,8 +4023,8 @@ finished: *(ckt->CKTstate0 + here->BSIM4v4vgs) = vgs; *(ckt->CKTstate0 + here->BSIM4v4vbs) = vbs; *(ckt->CKTstate0 + here->BSIM4v4vbd) = vbd; - *(ckt->CKTstate0 + here->BSIM4v4vges) = vges; - *(ckt->CKTstate0 + here->BSIM4v4vgms) = vgms; + *(ckt->CKTstate0 + here->BSIM4v4vges) = vges; + *(ckt->CKTstate0 + here->BSIM4v4vgms) = vgms; *(ckt->CKTstate0 + here->BSIM4v4vdbs) = vdbs; *(ckt->CKTstate0 + here->BSIM4v4vdbd) = vdbd; *(ckt->CKTstate0 + here->BSIM4v4vsbs) = vsbs; @@ -3636,54 +4034,92 @@ finished: if (!ChargeComputationNeeded) - goto line850; + goto line850; - if (here->BSIM4v4rgateMod == 3) - { - vgdx = vgmd; - vgsx = vgms; - } - else /* For rgateMod == 0, 1 and 2 */ - { - vgdx = vgd; - vgsx = vgs; - } - if (model->BSIM4v4capMod == 0) - { - cgdo = pParam->BSIM4v4cgdo; - qgdo = pParam->BSIM4v4cgdo * vgdx; - cgso = pParam->BSIM4v4cgso; - qgso = pParam->BSIM4v4cgso * vgsx; - } - else /* For both capMod == 1 and 2 */ - { T0 = vgdx + DELTA_1; - T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); - T2 = 0.5 * (T0 - T1); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (model->BSIM4v4capMod == 0) /* code merge -JX */ + { + cgdo = pParam->BSIM4v4cgdo; + qgdo = pParam->BSIM4v4cgdo * vgd; + cgso = pParam->BSIM4v4cgso; + qgso = pParam->BSIM4v4cgso * vgs; + } + else /* For both capMod == 1 and 2 */ + { T0 = vgd + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + + T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgdl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappad); + cgdo = pParam->BSIM4v4cgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->BSIM4v4cgdo + T3) * vgd - T3 * (T2 + + 0.5 * pParam->BSIM4v4ckappad * (T4 - 1.0)); + + T0 = vgs + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgsl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappas); + cgso = pParam->BSIM4v4cgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->BSIM4v4cgso + T3) * vgs - T3 * (T2 + + 0.5 * pParam->BSIM4v4ckappas * (T4 - 1.0)); + } + break; + case BSIM4v40: + if (here->BSIM4v4rgateMod == 3) + { + vgdx = vgmd; + vgsx = vgms; + } + else /* For rgateMod == 0, 1 and 2 */ + { + vgdx = vgd; + vgsx = vgs; + } + if (model->BSIM4v4capMod == 0) + { + cgdo = pParam->BSIM4v4cgdo; + qgdo = pParam->BSIM4v4cgdo * vgdx; + cgso = pParam->BSIM4v4cgso; + qgso = pParam->BSIM4v4cgso * vgsx; + } + else /* For both capMod == 1 and 2 */ + { T0 = vgdx + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); - T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgdl; - T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappad); - cgdo = pParam->BSIM4v4cgdo + T3 - T3 * (1.0 - 1.0 / T4) - * (0.5 - 0.5 * T0 / T1); - qgdo = (pParam->BSIM4v4cgdo + T3) * vgdx - T3 * (T2 - + 0.5 * pParam->BSIM4v4ckappad * (T4 - 1.0)); + + T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgdl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappad); + cgdo = pParam->BSIM4v4cgdo + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgdo = (pParam->BSIM4v4cgdo + T3) * vgdx - T3 * (T2 + + 0.5 * pParam->BSIM4v4ckappad * (T4 - 1.0)); - T0 = vgsx + DELTA_1; - T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); - T2 = 0.5 * (T0 - T1); - T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgsl; - T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappas); - cgso = pParam->BSIM4v4cgso + T3 - T3 * (1.0 - 1.0 / T4) - * (0.5 - 0.5 * T0 / T1); - qgso = (pParam->BSIM4v4cgso + T3) * vgsx - T3 * (T2 - + 0.5 * pParam->BSIM4v4ckappas * (T4 - 1.0)); - } + + T0 = vgsx + DELTA_1; + T1 = sqrt(T0 * T0 + 4.0 * DELTA_1); + T2 = 0.5 * (T0 - T1); + T3 = pParam->BSIM4v4weffCV * pParam->BSIM4v4cgsl; + T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM4v4ckappas); + cgso = pParam->BSIM4v4cgso + T3 - T3 * (1.0 - 1.0 / T4) + * (0.5 - 0.5 * T0 / T1); + qgso = (pParam->BSIM4v4cgso + T3) * vgsx - T3 * (T2 + + 0.5 * pParam->BSIM4v4ckappas * (T4 - 1.0)); + } + break; + default: break; + } - if (here->BSIM4v4nf != 1.0) - { cgdo *= here->BSIM4v4nf; - cgso *= here->BSIM4v4nf; + if (here->BSIM4v4nf != 1.0) + { cgdo *= here->BSIM4v4nf; + cgso *= here->BSIM4v4nf; qgdo *= here->BSIM4v4nf; qgso *= here->BSIM4v4nf; - } + } here->BSIM4v4cgdo = cgdo; here->BSIM4v4qgdo = qgdo; here->BSIM4v4cgso = cgso; @@ -3696,9 +4132,9 @@ line755: if (here->BSIM4v4mode > 0) { if (here->BSIM4v4trnqsMod == 0) { qdrn -= qgdo; - if (here->BSIM4v4rgateMod == 3) - { gcgmgmb = (cgdo + cgso + pParam->BSIM4v4cgbo) * ag0; - gcgmdb = -cgdo * ag0; + if (here->BSIM4v4rgateMod == 3) + { gcgmgmb = (cgdo + cgso + pParam->BSIM4v4cgbo) * ag0; + gcgmdb = -cgdo * ag0; gcgmsb = -cgso * ag0; gcgmbb = -pParam->BSIM4v4cgbo * ag0; @@ -3706,13 +4142,13 @@ line755: gcsgmb = gcgmsb; gcbgmb = gcgmbb; - gcggb = here->BSIM4v4cggb * ag0; + gcggb = here->BSIM4v4cggb * ag0; gcgdb = here->BSIM4v4cgdb * ag0; - gcgsb = here->BSIM4v4cgsb * ag0; + gcgsb = here->BSIM4v4cgsb * ag0; gcgbb = -(gcggb + gcgdb + gcgsb); - gcdgb = here->BSIM4v4cdgb * ag0; - gcsgb = -(here->BSIM4v4cggb + here->BSIM4v4cbgb + gcdgb = here->BSIM4v4cdgb * ag0; + gcsgb = -(here->BSIM4v4cggb + here->BSIM4v4cbgb + here->BSIM4v4cdgb) * ag0; gcbgb = here->BSIM4v4cbgb * ag0; @@ -3720,26 +4156,26 @@ line755: qgmid = qgdo + qgso + qgmb; qbulk -= qgmb; qsrc = -(qgate + qgmid + qbulk + qdrn); - } - else - { gcggb = (here->BSIM4v4cggb + cgdo + cgso + } + else + { gcggb = (here->BSIM4v4cggb + cgdo + cgso + pParam->BSIM4v4cgbo ) * ag0; gcgdb = (here->BSIM4v4cgdb - cgdo) * ag0; gcgsb = (here->BSIM4v4cgsb - cgso) * ag0; gcgbb = -(gcggb + gcgdb + gcgsb); - gcdgb = (here->BSIM4v4cdgb - cgdo) * ag0; + gcdgb = (here->BSIM4v4cdgb - cgdo) * ag0; gcsgb = -(here->BSIM4v4cggb + here->BSIM4v4cbgb + here->BSIM4v4cdgb + cgso) * ag0; gcbgb = (here->BSIM4v4cbgb - pParam->BSIM4v4cgbo) * ag0; - gcdgmb = gcsgmb = gcbgmb = 0.0; + gcdgmb = gcsgmb = gcbgmb = 0.0; qgb = pParam->BSIM4v4cgbo * vgb; qgate += qgdo + qgso + qgb; qbulk -= qgb; qsrc = -(qgate + qbulk + qdrn); - } + } gcddb = (here->BSIM4v4cddb + here->BSIM4v4capbd + cgdo) * ag0; gcdsb = here->BSIM4v4cdsb * ag0; @@ -3753,26 +4189,34 @@ line755: gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb); gcbdb = (here->BSIM4v4cbdb - here->BSIM4v4capbd) * ag0; gcbsb = (here->BSIM4v4cbsb - here->BSIM4v4capbs) * ag0; - gcdbdb = 0.0; gcsbsb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + gcdbdb = 0.0; + break; + case BSIM4v40: + gcdbdb = 0.0; gcsbsb = 0.0; + break; + default: break; + } } else - { gcdbb = -(here->BSIM4v4cddb + here->BSIM4v4cdgb + { gcdbb = -(here->BSIM4v4cddb + here->BSIM4v4cdgb + here->BSIM4v4cdsb) * ag0; gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb) - + here->BSIM4v4capbs * ag0; + + here->BSIM4v4capbs * ag0; gcbdb = here->BSIM4v4cbdb * ag0; gcbsb = here->BSIM4v4cbsb * ag0; gcdbdb = -here->BSIM4v4capbd * ag0; gcsbsb = -here->BSIM4v4capbs * ag0; } - gcbbb = -(gcbdb + gcbgb + gcbsb + gcbgmb); + gcbbb = -(gcbdb + gcbgb + gcbsb + gcbgmb); ggtg = ggtd = ggtb = ggts = 0.0; - sxpart = 0.6; + sxpart = 0.6; dxpart = 0.4; - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; } else { qcheq = here->BSIM4v4qchqs; @@ -3784,7 +4228,7 @@ line755: ggtd = here->BSIM4v4gtd = T0 * here->BSIM4v4gcrgd; ggts = here->BSIM4v4gts = T0 * here->BSIM4v4gcrgs; ggtb = here->BSIM4v4gtb = T0 * here->BSIM4v4gcrgb; - gqdef = ScalingFactor * ag0; + gqdef = ScalingFactor * ag0; gcqgb = here->BSIM4v4cqgb * ag0; gcqdb = here->BSIM4v4cqdb * ag0; @@ -3839,20 +4283,20 @@ line755: gcbgmb = gcgmbb; gcdgb = gcsgb = gcbgb = 0.0; - gcggb = gcgdb = gcgsb = gcgbb = 0.0; + gcggb = gcgdb = gcgsb = gcgbb = 0.0; qgmb = pParam->BSIM4v4cgbo * vgmb; qgmid = qgdo + qgso + qgmb; - qgate = 0.0; + qgate = 0.0; qbulk = -qgmb; - qdrn = -qgdo; + qdrn = -qgdo; qsrc = -(qgmid + qbulk + qdrn); } else { gcggb = (cgdo + cgso + pParam->BSIM4v4cgbo ) * ag0; gcgdb = -cgdo * ag0; gcgsb = -cgso * ag0; - gcgbb = -pParam->BSIM4v4cgbo * ag0; + gcgbb = -pParam->BSIM4v4cgbo * ag0; gcdgb = gcgdb; gcsgb = gcgsb; @@ -3862,7 +4306,7 @@ line755: qgb = pParam->BSIM4v4cgbo * vgb; qgate = qgdo + qgso + qgb; qbulk = -qgb; - qdrn = -qgdo; + qdrn = -qgdo; qsrc = -(qgate + qbulk + qdrn); } @@ -3875,7 +4319,15 @@ line755: gcsbb = -(gcsgb + gcssb + gcsgmb); gcbdb = -here->BSIM4v4capbd * ag0; gcbsb = -here->BSIM4v4capbs * ag0; - gcdbdb = 0.0; gcsbsb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + gcdbdb = 0.0; + break; + case BSIM4v40: + gcdbdb = 0.0; gcsbsb = 0.0; + break; + default: break; + } } else { gcdbb = gcsbb = gcbdb = gcbsb = 0.0; @@ -3888,11 +4340,11 @@ line755: else { if (here->BSIM4v4trnqsMod == 0) { qsrc = qdrn - qgso; - if (here->BSIM4v4rgateMod == 3) - { gcgmgmb = (cgdo + cgso + pParam->BSIM4v4cgbo) * ag0; - gcgmdb = -cgdo * ag0; - gcgmsb = -cgso * ag0; - gcgmbb = -pParam->BSIM4v4cgbo * ag0; + if (here->BSIM4v4rgateMod == 3) + { gcgmgmb = (cgdo + cgso + pParam->BSIM4v4cgbo) * ag0; + gcgmdb = -cgdo * ag0; + gcgmsb = -cgso * ag0; + gcgmbb = -pParam->BSIM4v4cgbo * ag0; gcdgmb = gcgmdb; gcsgmb = gcgmsb; @@ -3912,9 +4364,9 @@ line755: qgmid = qgdo + qgso + qgmb; qbulk -= qgmb; qdrn = -(qgate + qgmid + qbulk + qsrc); - } - else - { gcggb = (here->BSIM4v4cggb + cgdo + cgso + } + else + { gcggb = (here->BSIM4v4cggb + cgdo + cgso + pParam->BSIM4v4cgbo ) * ag0; gcgdb = (here->BSIM4v4cgsb - cgdo) * ag0; gcgsb = (here->BSIM4v4cgdb - cgso) * ag0; @@ -3931,7 +4383,7 @@ line755: qgate += qgdo + qgso + qgb; qbulk -= qgb; qdrn = -(qgate + qbulk + qsrc); - } + } gcddb = (here->BSIM4v4capbd + cgdo - (here->BSIM4v4cgsb + here->BSIM4v4cbsb + here->BSIM4v4cdsb)) * ag0; gcdsb = -(here->BSIM4v4cgdb + here->BSIM4v4cbdb @@ -3940,30 +4392,38 @@ line755: gcsdb = here->BSIM4v4cdsb * ag0; gcssb = (here->BSIM4v4cddb + here->BSIM4v4capbs + cgso) * ag0; - if (!here->BSIM4v4rbodyMod) - { gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb); + if (!here->BSIM4v4rbodyMod) + { gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb); gcsbb = -(gcsgb + gcsdb + gcssb + gcsgmb); gcbdb = (here->BSIM4v4cbsb - here->BSIM4v4capbd) * ag0; gcbsb = (here->BSIM4v4cbdb - here->BSIM4v4capbs) * ag0; - gcdbdb = 0.0; gcsbsb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + gcdbdb = 0.0; + break; + case BSIM4v40: + gcdbdb = 0.0; gcsbsb = 0.0; + break; + default: break; + } } else { gcdbb = -(gcdgb + gcddb + gcdsb + gcdgmb) - + here->BSIM4v4capbd * ag0; + + here->BSIM4v4capbd * ag0; gcsbb = -(here->BSIM4v4cddb + here->BSIM4v4cdgb + here->BSIM4v4cdsb) * ag0; gcbdb = here->BSIM4v4cbsb * ag0; gcbsb = here->BSIM4v4cbdb * ag0; gcdbdb = -here->BSIM4v4capbd * ag0; - gcsbsb = -here->BSIM4v4capbs * ag0; + gcsbsb = -here->BSIM4v4capbs * ag0; } - gcbbb = -(gcbgb + gcbdb + gcbsb + gcbgmb); + gcbbb = -(gcbgb + gcbdb + gcbsb + gcbgmb); ggtg = ggtd = ggtb = ggts = 0.0; - sxpart = 0.4; + sxpart = 0.4; dxpart = 0.6; - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; } else { qcheq = here->BSIM4v4qchqs; @@ -3974,7 +4434,7 @@ line755: ggts = here->BSIM4v4gtd = T0 * here->BSIM4v4gcrgs; ggtd = here->BSIM4v4gts = T0 * here->BSIM4v4gcrgd; ggtb = here->BSIM4v4gtb = T0 * here->BSIM4v4gcrgb; - gqdef = ScalingFactor * ag0; + gqdef = ScalingFactor * ag0; gcqgb = here->BSIM4v4cqgb * ag0; gcqdb = here->BSIM4v4cqsb * ag0; @@ -4064,7 +4524,15 @@ line755: gcsbb = -(gcsgb + gcssb + gcsgmb); gcbdb = -here->BSIM4v4capbd * ag0; gcbsb = -here->BSIM4v4capbs * ag0; - gcdbdb = 0.0; gcsbsb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + gcdbdb = 0.0; + break; + case BSIM4v40: + gcdbdb = 0.0; gcsbsb = 0.0; + break; + default: break; + } } else { gcdbb = gcsbb = gcbdb = gcbsb = 0.0; @@ -4093,8 +4561,8 @@ line755: - *(ckt->CKTstate0 + here->BSIM4v4qbd); *(ckt->CKTstate0 + here->BSIM4v4qs) = qsrc - *(ckt->CKTstate0 + here->BSIM4v4qbs); - if (here->BSIM4v4rgateMod == 3) - *(ckt->CKTstate0 + here->BSIM4v4qgmid) = qgmid; + if (here->BSIM4v4rgateMod == 3) + *(ckt->CKTstate0 + here->BSIM4v4qgmid) = qgmid; if (!here->BSIM4v4rbodyMod) { *(ckt->CKTstate0 + here->BSIM4v4qb) = qbulk @@ -4132,13 +4600,13 @@ line755: } error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qb); - if (error) + if (error) return(error); error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qg); - if (error) + if (error) return(error); error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qd); - if (error) + if (error) return(error); if (here->BSIM4v4rgateMod == 3) @@ -4148,10 +4616,10 @@ line755: if (here->BSIM4v4rbodyMod) { error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qbs); - if (error) + if (error) return(error); error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM4v4qbd); - if (error) + if (error) return(error); } @@ -4169,15 +4637,15 @@ line850: gcggb = gcgdb = gcgsb = gcgbb = 0.0; gcbdb = gcbgb = gcbsb = gcbbb = 0.0; - gcgmgmb = gcgmdb = gcgmsb = gcgmbb = 0.0; - gcdgmb = gcsgmb = gcbgmb = ceqqgmid = 0.0; + gcgmgmb = gcgmdb = gcgmsb = gcgmbb = 0.0; + gcdgmb = gcsgmb = gcbgmb = ceqqgmid = 0.0; gcdbdb = gcsbsb = 0.0; - gqdef = gcqgb = gcqdb = gcqsb = gcqbb = 0.0; + gqdef = gcqgb = gcqdb = gcqsb = gcqbb = 0.0; ggtg = ggtd = ggtb = ggts = 0.0; sxpart = (1.0 - (dxpart = (here->BSIM4v4mode > 0) ? 0.4 : 0.6)); - ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; - dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; + ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0; + dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0; if (here->BSIM4v4trnqsMod) { CoxWL = model->BSIM4v4coxe * pParam->BSIM4v4weffCV * here->BSIM4v4nf @@ -4185,12 +4653,12 @@ line850: T1 = here->BSIM4v4gcrg / CoxWL; here->BSIM4v4gtau = T1 * ScalingFactor; } - else + else here->BSIM4v4gtau = 0.0; goto line900; - + line860: /* Calculate equivalent charge current */ @@ -4200,28 +4668,28 @@ line860: ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs; ceqqd = cqdrn - gcdgb * vgb - gcdgmb * vgmb + (gcddb + gcdbdb) - * vbd - gcdbdb * vbd_jct + gcdsb * vbs; - ceqqb = cqbody - gcbgb * vgb - gcbgmb * vgmb + * vbd - gcdbdb * vbd_jct + gcdsb * vbs; + ceqqb = cqbody - gcbgb * vgb - gcbgmb * vgmb + gcbdb * vbd + gcbsb * vbs; if (here->BSIM4v4rgateMod == 3) ceqqgmid = *(ckt->CKTstate0 + here->BSIM4v4cqgmid) + gcgmdb * vbd + gcgmsb * vbs - gcgmgmb * vgmb; - else - ceqqgmid = 0.0; + else + ceqqgmid = 0.0; if (here->BSIM4v4rbodyMod) { ceqqjs = *(ckt->CKTstate0 + here->BSIM4v4cqbs) + gcsbsb * vbs_jct; - ceqqjd = *(ckt->CKTstate0 + here->BSIM4v4cqbd) + gcdbdb * vbd_jct; + ceqqjd = *(ckt->CKTstate0 + here->BSIM4v4cqbd) + gcdbdb * vbd_jct; } if (here->BSIM4v4trnqsMod) { T0 = ggtg * vgb - ggtd * vbd - ggts * vbs; ceqqg += T0; - T1 = qdef * here->BSIM4v4gtau; + T1 = qdef * here->BSIM4v4gtau; ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd - * vbd - ddxpart_dVs * vbs); + * vbd - ddxpart_dVs * vbs); cqdef = *(ckt->CKTstate0 + here->BSIM4v4cqcdump) - gqdef * qdef; cqcheq = *(ckt->CKTstate0 + here->BSIM4v4cqcheq) - (gcqgb * vgb - gcqdb * vbd - gcqsb * vbs) + T0; @@ -4254,23 +4722,23 @@ line860: line900: if (here->BSIM4v4mode >= 0) - { Gm = here->BSIM4v4gm; + { Gm = here->BSIM4v4gm; Gmbs = here->BSIM4v4gmbs; FwdSum = Gm + Gmbs; RevSum = 0.0; ceqdrn = model->BSIM4v4type * (cdrain - here->BSIM4v4gds * vds - - Gm * vgs - Gmbs * vbs); + - Gm * vgs - Gmbs * vbs); ceqbd = model->BSIM4v4type * (here->BSIM4v4csub + here->BSIM4v4Igidl - (here->BSIM4v4gbds + here->BSIM4v4ggidld) * vds - - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * vgs - - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) * vbs); - ceqbs = model->BSIM4v4type * (here->BSIM4v4Igisl + here->BSIM4v4ggisls * vds - - here->BSIM4v4ggislg * vgd - here->BSIM4v4ggislb * vbd); + - (here->BSIM4v4gbgs + here->BSIM4v4ggidlg) * vgs + - (here->BSIM4v4gbbs + here->BSIM4v4ggidlb) * vbs); + ceqbs = model->BSIM4v4type * (here->BSIM4v4Igisl + here->BSIM4v4ggisls * vds + - here->BSIM4v4ggislg * vgd - here->BSIM4v4ggislb * vbd); gbbdp = -(here->BSIM4v4gbds); - gbbsp = here->BSIM4v4gbds + here->BSIM4v4gbgs + here->BSIM4v4gbbs; - + gbbsp = here->BSIM4v4gbds + here->BSIM4v4gbgs + here->BSIM4v4gbbs; + gbdpg = here->BSIM4v4gbgs; gbdpdp = here->BSIM4v4gbds; gbdpb = here->BSIM4v4gbbs; @@ -4282,13 +4750,13 @@ line900: gbspsp = 0.0; if (model->BSIM4v4igcMod) - { gIstotg = here->BSIM4v4gIgsg + here->BSIM4v4gIgcsg; - gIstotd = here->BSIM4v4gIgcsd; + { gIstotg = here->BSIM4v4gIgsg + here->BSIM4v4gIgcsg; + gIstotd = here->BSIM4v4gIgcsd; gIstots = here->BSIM4v4gIgss + here->BSIM4v4gIgcss; gIstotb = here->BSIM4v4gIgcsb; - Istoteq = model->BSIM4v4type * (here->BSIM4v4Igs + here->BSIM4v4Igcs - - gIstotg * vgs - here->BSIM4v4gIgcsd * vds - - here->BSIM4v4gIgcsb * vbs); + Istoteq = model->BSIM4v4type * (here->BSIM4v4Igs + here->BSIM4v4Igcs + - gIstotg * vgs - here->BSIM4v4gIgcsd * vds + - here->BSIM4v4gIgcsb * vbs); gIdtotg = here->BSIM4v4gIgdg + here->BSIM4v4gIgcdg; gIdtotd = here->BSIM4v4gIgdd + here->BSIM4v4gIgcdd; @@ -4296,12 +4764,12 @@ line900: gIdtotb = here->BSIM4v4gIgcdb; Idtoteq = model->BSIM4v4type * (here->BSIM4v4Igd + here->BSIM4v4Igcd - here->BSIM4v4gIgdg * vgd - here->BSIM4v4gIgcdg * vgs - - here->BSIM4v4gIgcdd * vds - here->BSIM4v4gIgcdb * vbs); - } - else - { gIstotg = gIstotd = gIstots = gIstotb = Istoteq = 0.0; - gIdtotg = gIdtotd = gIdtots = gIdtotb = Idtoteq = 0.0; - } + - here->BSIM4v4gIgcdd * vds - here->BSIM4v4gIgcdb * vbs); + } + else + { gIstotg = gIstotd = gIstots = gIstotb = Istoteq = 0.0; + gIdtotg = gIdtotd = gIdtots = gIdtotb = Idtoteq = 0.0; + } if (model->BSIM4v4igbMod) { gIbtotg = here->BSIM4v4gIgbg; @@ -4320,10 +4788,10 @@ line900: gIgtotd = gIstotd + gIdtotd + gIbtotd ; gIgtots = gIstots + gIdtots + gIbtots; gIgtotb = gIstotb + gIdtotb + gIbtotb; - Igtoteq = Istoteq + Idtoteq + Ibtoteq; - } - else - gIgtotg = gIgtotd = gIgtots = gIgtotb = Igtoteq = 0.0; + Igtoteq = Istoteq + Idtoteq + Ibtoteq; + } + else + gIgtotg = gIgtotd = gIgtots = gIgtotb = Igtoteq = 0.0; if (here->BSIM4v4rgateMod == 2) @@ -4341,10 +4809,10 @@ line900: gcrg = here->BSIM4v4gcrg; } else - ceqgcrg = gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; + ceqgcrg = gcrg = gcrgd = gcrgg = gcrgs = gcrgb = 0.0; } - else - { Gm = -here->BSIM4v4gm; + else + { Gm = -here->BSIM4v4gm; Gmbs = -here->BSIM4v4gmbs; FwdSum = 0.0; RevSum = -(Gm + Gmbs); @@ -4352,15 +4820,15 @@ line900: ceqdrn = -model->BSIM4v4type * (cdrain + here->BSIM4v4gds * vds + Gm * vgd + Gmbs * vbd); - ceqbs = model->BSIM4v4type * (here->BSIM4v4csub + here->BSIM4v4Igisl + ceqbs = model->BSIM4v4type * (here->BSIM4v4csub + here->BSIM4v4Igisl + (here->BSIM4v4gbds + here->BSIM4v4ggisls) * vds - - (here->BSIM4v4gbgs + here->BSIM4v4ggislg) * vgd + - (here->BSIM4v4gbgs + here->BSIM4v4ggislg) * vgd - (here->BSIM4v4gbbs + here->BSIM4v4ggislb) * vbd); - ceqbd = model->BSIM4v4type * (here->BSIM4v4Igidl - here->BSIM4v4ggidld * vds - - here->BSIM4v4ggidlg * vgs - here->BSIM4v4ggidlb * vbs); + ceqbd = model->BSIM4v4type * (here->BSIM4v4Igidl - here->BSIM4v4ggidld * vds + - here->BSIM4v4ggidlg * vgs - here->BSIM4v4ggidlb * vbs); gbbsp = -(here->BSIM4v4gbds); - gbbdp = here->BSIM4v4gbds + here->BSIM4v4gbgs + here->BSIM4v4gbbs; + gbbdp = here->BSIM4v4gbds + here->BSIM4v4gbgs + here->BSIM4v4gbbs; gbdpg = 0.0; gbdpsp = 0.0; @@ -4379,7 +4847,7 @@ line900: gIstotb = here->BSIM4v4gIgcdb; Istoteq = model->BSIM4v4type * (here->BSIM4v4Igs + here->BSIM4v4Igcd - here->BSIM4v4gIgsg * vgs - here->BSIM4v4gIgcdg * vgd - + here->BSIM4v4gIgcdd * vds - here->BSIM4v4gIgcdb * vbd); + + here->BSIM4v4gIgcdd * vds - here->BSIM4v4gIgcdb * vbd); gIdtotg = here->BSIM4v4gIgdg + here->BSIM4v4gIgcsg; gIdtotd = here->BSIM4v4gIgdd + here->BSIM4v4gIgcss; @@ -4459,31 +4927,31 @@ line900: gdtot = gdtotd = gdtotg = gdtots = gdtotb = ceqgdtot = 0.0; } - if (model->BSIM4v4type > 0) + if (model->BSIM4v4type > 0) { ceqjs = (here->BSIM4v4cbs - here->BSIM4v4gbs * vbs_jct); ceqjd = (here->BSIM4v4cbd - here->BSIM4v4gbd * vbd_jct); } - else - { ceqjs = -(here->BSIM4v4cbs - here->BSIM4v4gbs * vbs_jct); + else + { ceqjs = -(here->BSIM4v4cbs - here->BSIM4v4gbs * vbs_jct); ceqjd = -(here->BSIM4v4cbd - here->BSIM4v4gbd * vbd_jct); ceqqg = -ceqqg; ceqqd = -ceqqd; ceqqb = -ceqqb; - ceqgcrg = -ceqgcrg; + ceqgcrg = -ceqgcrg; if (here->BSIM4v4trnqsMod) { cqdef = -cqdef; cqcheq = -cqcheq; - } + } if (here->BSIM4v4rbodyMod) { ceqqjs = -ceqqjs; ceqqjd = -ceqqjd; } - if (here->BSIM4v4rgateMod == 3) - ceqqgmid = -ceqqgmid; - } + if (here->BSIM4v4rgateMod == 3) + ceqqgmid = -ceqqgmid; + } /* @@ -4499,26 +4967,26 @@ line900: if (here->BSIM4v4rgateMod == 2) (*(ckt->CKTrhs + here->BSIM4v4gNodeExt) -= m * ceqgcrg); else if (here->BSIM4v4rgateMod == 3) - (*(ckt->CKTrhs + here->BSIM4v4gNodeMid) -= m * (ceqqgmid + ceqgcrg)); + (*(ckt->CKTrhs + here->BSIM4v4gNodeMid) -= m * (ceqqgmid + ceqgcrg)); if (!here->BSIM4v4rbodyMod) { (*(ckt->CKTrhs + here->BSIM4v4bNodePrime) += m * (ceqbd + ceqbs - ceqjd - ceqjs - ceqqb + Ibtoteq)); - (*(ckt->CKTrhs + here->BSIM4v4sNodePrime) += m * (ceqdrn - ceqbs + ceqjs + (*(ckt->CKTrhs + here->BSIM4v4sNodePrime) += m * (ceqdrn - ceqbs + ceqjs + ceqqg + ceqqb + ceqqd + ceqqgmid - ceqgstot + Istoteq)); } else { (*(ckt->CKTrhs + here->BSIM4v4dbNode) -= m * (ceqjd + ceqqjd)); (*(ckt->CKTrhs + here->BSIM4v4bNodePrime) += m * (ceqbd + ceqbs - ceqqb + Ibtoteq)); (*(ckt->CKTrhs + here->BSIM4v4sbNode) -= m * (ceqjs + ceqqjs)); - (*(ckt->CKTrhs + here->BSIM4v4sNodePrime) += m * (ceqdrn - ceqbs + ceqjs + ceqqd + (*(ckt->CKTrhs + here->BSIM4v4sNodePrime) += m * (ceqdrn - ceqbs + ceqjs + ceqqd + ceqqg + ceqqb + ceqqjd + ceqqjs + ceqqgmid - ceqgstot + Istoteq)); } if (model->BSIM4v4rdsMod) - { (*(ckt->CKTrhs + here->BSIM4v4dNode) -= m * ceqgdtot); - (*(ckt->CKTrhs + here->BSIM4v4sNode) += m * ceqgstot); - } + { (*(ckt->CKTrhs + here->BSIM4v4dNode) -= m * ceqgdtot); + (*(ckt->CKTrhs + here->BSIM4v4sNode) += m * ceqgstot); + } if (here->BSIM4v4trnqsMod) *(ckt->CKTrhs + here->BSIM4v4qNode) += m * (cqcheq - cqdef); @@ -4528,7 +4996,7 @@ line900: * Loading matrix */ - if (!here->BSIM4v4rbodyMod) + if (!here->BSIM4v4rbodyMod) { gjbd = here->BSIM4v4gbd; gjbs = here->BSIM4v4gbs; } @@ -4542,7 +5010,7 @@ line900: else gdpr = gspr = 0.0; - geltd = here->BSIM4v4grgeltd; + geltd = here->BSIM4v4grgeltd; T1 = qdef * here->BSIM4v4gtau; @@ -4550,26 +5018,26 @@ line900: { (*(here->BSIM4v4GEgePtr) += m * geltd); (*(here->BSIM4v4GPgePtr) -= m * geltd); (*(here->BSIM4v4GEgpPtr) -= m * geltd); - (*(here->BSIM4v4GPgpPtr) += m * (gcggb + geltd - ggtg + gIgtotg)); - (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - ggtd + gIgtotd)); - (*(here->BSIM4v4GPspPtr) += m * (gcgsb - ggts + gIgtots)); - (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - ggtb + gIgtotb)); + (*(here->BSIM4v4GPgpPtr) += m * (gcggb + geltd - ggtg + gIgtotg)); + (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - ggtd + gIgtotd)); + (*(here->BSIM4v4GPspPtr) += m * (gcgsb - ggts + gIgtots)); + (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - ggtb + gIgtotb)); } /* WDLiu: gcrg already subtracted from all gcrgg below */ - else if (here->BSIM4v4rgateMod == 2) - { (*(here->BSIM4v4GEgePtr) += m * gcrg); + else if (here->BSIM4v4rgateMod == 2) + { (*(here->BSIM4v4GEgePtr) += m * gcrg); (*(here->BSIM4v4GEgpPtr) += m * gcrgg); (*(here->BSIM4v4GEdpPtr) += m * gcrgd); (*(here->BSIM4v4GEspPtr) += m * gcrgs); - (*(here->BSIM4v4GEbpPtr) += m * gcrgb); + (*(here->BSIM4v4GEbpPtr) += m * gcrgb); (*(here->BSIM4v4GPgePtr) -= m * gcrg); - (*(here->BSIM4v4GPgpPtr) += m * (gcggb - gcrgg - ggtg + gIgtotg)); - (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - gcrgd - ggtd + gIgtotd)); - (*(here->BSIM4v4GPspPtr) += m * (gcgsb - gcrgs - ggts + gIgtots)); - (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - gcrgb - ggtb + gIgtotb)); - } - else if (here->BSIM4v4rgateMod == 3) - { (*(here->BSIM4v4GEgePtr) += m * geltd); + (*(here->BSIM4v4GPgpPtr) += m * (gcggb - gcrgg - ggtg + gIgtotg)); + (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - gcrgd - ggtd + gIgtotd)); + (*(here->BSIM4v4GPspPtr) += m * (gcgsb - gcrgs - ggts + gIgtots)); + (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - gcrgb - ggtb + gIgtotb)); + } + else if (here->BSIM4v4rgateMod == 3) + { (*(here->BSIM4v4GEgePtr) += m * geltd); (*(here->BSIM4v4GEgmPtr) -= m * geltd); (*(here->BSIM4v4GMgePtr) -= m * geltd); (*(here->BSIM4v4GMgmPtr) += m * (geltd + gcrg + gcgmgmb)); @@ -4588,45 +5056,45 @@ line900: (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - gcrgd - ggtd + gIgtotd)); (*(here->BSIM4v4GPspPtr) += m * (gcgsb - gcrgs - ggts + gIgtots)); (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - gcrgb - ggtb + gIgtotb)); - } - else - { (*(here->BSIM4v4GPgpPtr) += m * (gcggb - ggtg + gIgtotg)); - (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - ggtd + gIgtotd)); + } + else + { (*(here->BSIM4v4GPgpPtr) += m * (gcggb - ggtg + gIgtotg)); + (*(here->BSIM4v4GPdpPtr) += m * (gcgdb - ggtd + gIgtotd)); (*(here->BSIM4v4GPspPtr) += m * (gcgsb - ggts + gIgtots)); - (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - ggtb + gIgtotb)); - } + (*(here->BSIM4v4GPbpPtr) += m * (gcgbb - ggtb + gIgtotb)); + } - if (model->BSIM4v4rdsMod) - { (*(here->BSIM4v4DgpPtr) += m * gdtotg); - (*(here->BSIM4v4DspPtr) += m * gdtots); + if (model->BSIM4v4rdsMod) + { (*(here->BSIM4v4DgpPtr) += m * gdtotg); + (*(here->BSIM4v4DspPtr) += m * gdtots); (*(here->BSIM4v4DbpPtr) += m * gdtotb); (*(here->BSIM4v4SdpPtr) += m * gstotd); (*(here->BSIM4v4SgpPtr) += m * gstotg); (*(here->BSIM4v4SbpPtr) += m * gstotb); - } + } (*(here->BSIM4v4DPdpPtr) += m * (gdpr + here->BSIM4v4gds + here->BSIM4v4gbd + T1 * ddxpart_dVd - gdtotd + RevSum + gcddb + gbdpdp + dxpart * ggtd - gIdtotd)); (*(here->BSIM4v4DPdPtr) -= m * (gdpr + gdtot)); (*(here->BSIM4v4DPgpPtr) += m * (Gm + gcdgb - gdtotg + gbdpg - gIdtotg - + dxpart * ggtg + T1 * ddxpart_dVg)); + + dxpart * ggtg + T1 * ddxpart_dVg)); (*(here->BSIM4v4DPspPtr) -= m * (here->BSIM4v4gds + gdtots - dxpart * ggts + gIdtots - - T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp)); + - T1 * ddxpart_dVs + FwdSum - gcdsb - gbdpsp)); (*(here->BSIM4v4DPbpPtr) -= m * (gjbd + gdtotb - Gmbs - gcdbb - gbdpb + gIdtotb - - T1 * ddxpart_dVb - dxpart * ggtb)); + - T1 * ddxpart_dVb - dxpart * ggtb)); (*(here->BSIM4v4DdpPtr) -= m * (gdpr - gdtotd)); (*(here->BSIM4v4DdPtr) += m * (gdpr + gdtot)); (*(here->BSIM4v4SPdpPtr) -= m * (here->BSIM4v4gds + gstotd + RevSum - gcsdb - gbspdp - - T1 * dsxpart_dVd - sxpart * ggtd + gIstotd)); + - T1 * dsxpart_dVd - sxpart * ggtd + gIstotd)); (*(here->BSIM4v4SPgpPtr) += m * (gcsgb - Gm - gstotg + gbspg + sxpart * ggtg - + T1 * dsxpart_dVg - gIstotg)); + + T1 * dsxpart_dVg - gIstotg)); (*(here->BSIM4v4SPspPtr) += m * (gspr + here->BSIM4v4gds + here->BSIM4v4gbs + T1 * dsxpart_dVs - gstots + FwdSum + gcssb + gbspsp + sxpart * ggts - gIstots)); (*(here->BSIM4v4SPsPtr) -= m * (gspr + gstot)); (*(here->BSIM4v4SPbpPtr) -= m * (gjbs + gstotb + Gmbs - gcsbb - gbspb - sxpart * ggtb - - T1 * dsxpart_dVb + gIstotb)); + - T1 * dsxpart_dVb + gIstotb)); (*(here->BSIM4v4SspPtr) -= m * (gspr - gstots)); (*(here->BSIM4v4SsPtr) += m * (gspr + gstot)); @@ -4635,7 +5103,7 @@ line900: (*(here->BSIM4v4BPgpPtr) += m * (gcbgb - here->BSIM4v4gbgs - gIbtotg)); (*(here->BSIM4v4BPspPtr) += m * (gcbsb - gjbs + gbbsp - gIbtots)); (*(here->BSIM4v4BPbpPtr) += m * (gjbd + gjbs + gcbbb - here->BSIM4v4gbbs - - gIbtotb)); + - gIbtotb)); ggidld = here->BSIM4v4ggidld; ggidlg = here->BSIM4v4ggidlg; @@ -4669,7 +5137,7 @@ line900: (*(here->BSIM4v4SPsbPtr) -= m * (here->BSIM4v4gbs - gcsbsb)); (*(here->BSIM4v4DBdpPtr) += m * (gcdbdb - here->BSIM4v4gbd)); - (*(here->BSIM4v4DBdbPtr) += m * (here->BSIM4v4gbd - gcdbdb + (*(here->BSIM4v4DBdbPtr) += m * (here->BSIM4v4gbd - gcdbdb + here->BSIM4v4grbpd + here->BSIM4v4grbdb)); (*(here->BSIM4v4DBbpPtr) -= m * here->BSIM4v4grbpd); (*(here->BSIM4v4DBbPtr) -= m * here->BSIM4v4grbdb); @@ -4677,14 +5145,14 @@ line900: (*(here->BSIM4v4BPdbPtr) -= m * here->BSIM4v4grbpd); (*(here->BSIM4v4BPbPtr) -= m * here->BSIM4v4grbpb); (*(here->BSIM4v4BPsbPtr) -= m * here->BSIM4v4grbps); - (*(here->BSIM4v4BPbpPtr) += m * (here->BSIM4v4grbpd + here->BSIM4v4grbps + (*(here->BSIM4v4BPbpPtr) += m * (here->BSIM4v4grbpd + here->BSIM4v4grbps + here->BSIM4v4grbpb)); - /* WDLiu: (gcbbb - here->BSIM4v4gbbs) already added to BPbpPtr */ + /* WDLiu: (gcbbb - here->BSIM4v4gbbs) already added to BPbpPtr */ (*(here->BSIM4v4SBspPtr) += m * (gcsbsb - here->BSIM4v4gbs)); (*(here->BSIM4v4SBbpPtr) -= m * here->BSIM4v4grbps); (*(here->BSIM4v4SBbPtr) -= m * here->BSIM4v4grbsb); - (*(here->BSIM4v4SBsbPtr) += m * (here->BSIM4v4gbs - gcsbsb + (*(here->BSIM4v4SBsbPtr) += m * (here->BSIM4v4gbs - gcsbsb + here->BSIM4v4grbps + here->BSIM4v4grbsb)); (*(here->BSIM4v4BdbPtr) -= m * here->BSIM4v4grbdb); @@ -4726,7 +5194,7 @@ int BSIM4v4polyDepletion( double T1, T2, T3, T4, T5, T6, T7, T8; /* Poly Gate Si Depletion Effect */ - if ((ngate > 1.0e18) && + if ((ngate > 1.0e18) && (ngate < 1.0e25) && (Vgs > phi)) { T1 = 1.0e6 * CHARGE * EPSSI * ngate / (coxe * coxe); T8 = Vgs - phi; @@ -4737,7 +5205,7 @@ int BSIM4v4polyDepletion( T6 = sqrt(T7 * T7 + 0.224); T5 = 1.12 - 0.5 * (T7 + T6); *Vgs_eff = Vgs - T5; - *dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); + *dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6); } else { *Vgs_eff = Vgs; diff --git a/src/spicelib/devices/bsim4v4/b4v4mpar.c b/src/spicelib/devices/bsim4v4/b4v4mpar.c index 10d6a8bab..4639678bd 100644 --- a/src/spicelib/devices/bsim4v4/b4v4mpar.c +++ b/src/spicelib/devices/bsim4v4/b4v4mpar.c @@ -1,5 +1,5 @@ /**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/ - +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. * File: b4mpar.c of BSIM4.4.0. @@ -18,6 +18,7 @@ #include "ifsim.h" #include "sperror.h" #include "suffix.h" +#include "const.h" int BSIM4v4mParam( diff --git a/src/spicelib/devices/bsim4v4/b4v4noi.c b/src/spicelib/devices/bsim4v4/b4v4noi.c index 7edbddf0d..764b57fb4 100644 --- a/src/spicelib/devices/bsim4v4/b4v4noi.c +++ b/src/spicelib/devices/bsim4v4/b4v4noi.c @@ -1,5 +1,5 @@ /**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/ - +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. * File: b4noi.c of BSIM4.4.0. @@ -18,7 +18,6 @@ #include "cktdefs.h" #include "iferrmsg.h" #include "noisedef.h" -#include "suffix.h" #include "const.h" @@ -36,23 +35,47 @@ BSIM4v4instance *here, double freq, double temp) { struct bsim4SizeDependParam *pParam; -double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq; -double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi; +double cd, esat=0.0, DelClm, EffFreq, N0, Nl, Leff, Leffsq=0.0; +double T0, T1, T2=0.0, T3, T4, T5, T6, T7=0.0, T8, T9, Ssi; pParam = here->pParam; cd = fabs(here->BSIM4v4cd); - Leff = pParam->BSIM4v4leff - 2.0 * model->BSIM4v4lintnoi; - Leffsq = Leff * Leff; - esat = 2.0 * here->BSIM4v4vsattemp / here->BSIM4v4ueff; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + Leff = pParam->BSIM4v4leff - 2.0 * model->BSIM4v4lintnoi; + Leffsq = Leff * Leff; + break; + default: break; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + esat = 2.0 * pParam->BSIM4v4vsattemp / here->BSIM4v4ueff; + break; + case BSIM4v30: case BSIM4v40: + esat = 2.0 * here->BSIM4v4vsattemp / here->BSIM4v4ueff; + break; + default: break; + } if(model->BSIM4v4em<=0.0) DelClm = 0.0; /* flicker noise modified -JX */ else { - T0 = ((((Vds - here->BSIM4v4Vdseff) / pParam->BSIM4v4litl) - + model->BSIM4v4em) / esat); - DelClm = pParam->BSIM4v4litl * log (MAX(T0, N_MINLOG)); + T0 = ((((Vds - here->BSIM4v4Vdseff) / pParam->BSIM4v4litl) + + model->BSIM4v4em) / esat); + DelClm = pParam->BSIM4v4litl * log (MAX(T0, N_MINLOG)); } EffFreq = pow(freq, model->BSIM4v4ef); T1 = CHARGE * CHARGE * CONSTboltz * cd * temp * here->BSIM4v4ueff; - T2 = 1.0e10 * EffFreq * here->BSIM4v4Abulk * model->BSIM4v4coxe * Leffsq; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + T2 = 1.0e10 * EffFreq * here->BSIM4v4Abulk * model->BSIM4v4coxe + * pParam->BSIM4v4leff * pParam->BSIM4v4leff; + break; + case BSIM4v40: + T2 = 1.0e10 * EffFreq * here->BSIM4v4Abulk * model->BSIM4v4coxe * Leffsq; + break; + default: break; + } N0 = model->BSIM4v4coxe * here->BSIM4v4Vgsteff / CHARGE; Nl = model->BSIM4v4coxe * here->BSIM4v4Vgsteff * (1.0 - here->BSIM4v4AbovVgst2Vtm * here->BSIM4v4Vdseff) / CHARGE; @@ -63,7 +86,16 @@ double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi; T5 = model->BSIM4v4oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); T6 = CONSTboltz * temp * cd * cd; - T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4v4weff; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + T7 = 1.0e10 * EffFreq * pParam->BSIM4v4leff + * pParam->BSIM4v4leff * pParam->BSIM4v4weff; + break; + case BSIM4v40: + T7 = 1.0e10 * EffFreq * Leffsq * pParam->BSIM4v4weff; + break; + default: break; + } T8 = model->BSIM4v4oxideTrapDensityA + model->BSIM4v4oxideTrapDensityB * Nl + model->BSIM4v4oxideTrapDensityC * Nl * Nl; T9 = (Nl + here->BSIM4v4nstar) * (Nl + here->BSIM4v4nstar); @@ -89,6 +121,7 @@ double tempInoise; double noizDens[BSIM4v4NSRCS]; double lnNdens[BSIM4v4NSRCS]; + double T0, T1, T2, T5, T10, T11; double Vds, Ssi, Swi; double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare; @@ -100,106 +133,117 @@ int i; /* define the names of the noise sources */ static char *BSIM4v4nNames[BSIM4v4NSRCS] = { /* Note that we have to keep the order */ - ".rd", /* noise due to rd */ - ".rs", /* noise due to rs */ + ".rd", /* noise due to rd */ + ".rs", /* noise due to rs */ ".rg", /* noise due to rgeltd */ ".rbps", /* noise due to rbps */ ".rbpd", /* noise due to rbpd */ ".rbpb", /* noise due to rbpb */ ".rbsb", /* noise due to rbsb */ ".rbdb", /* noise due to rbdb */ - ".id", /* noise due to id */ - ".1overf", /* flicker (1/f) noise */ + ".id", /* noise due to id */ + ".1overf", /* flicker (1/f) noise */ ".igs", /* shot noise due to IGS */ ".igd", /* shot noise due to IGD */ ".igb", /* shot noise due to IGB */ - "" /* total transistor noise */ + "" /* total transistor noise */ }; for (; model != NULL; model = model->BSIM4v4nextModel) { for (here = model->BSIM4v4instances; here != NULL; - here = here->BSIM4v4nextInstance) - { pParam = here->pParam; - switch (operation) - { case N_OPEN: - /* see if we have to to produce a summary report */ - /* if so, name all the noise generators */ + here = here->BSIM4v4nextInstance) + { pParam = here->pParam; + switch (operation) + { case N_OPEN: + /* see if we have to to produce a summary report */ + /* if so, name all the noise generators */ - if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) - { switch (mode) - { case N_DENS: - for (i = 0; i < BSIM4v4NSRCS; i++) - { (void) sprintf(name, "onoise.%s%s", - here->BSIM4v4name, - BSIM4v4nNames[i]); + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { switch (mode) + { case N_DENS: + for (i = 0; i < BSIM4v4NSRCS; i++) + { (void) sprintf(name, "onoise.%s%s", + here->BSIM4v4name, + BSIM4v4nNames[i]); data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, - &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, - NULL); - /* we've added one more plot */ - } - break; - case INT_NOIZ: - for (i = 0; i < BSIM4v4NSRCS; i++) - { (void) sprintf(name, "onoise_total.%s%s", - here->BSIM4v4name, - BSIM4v4nNames[i]); + return(E_NOMEM); + SPfrontEnd->IFnewUid (ckt, + &(data->namelist[data->numPlots++]), + NULL, name, UID_OTHER, + NULL); + /* we've added one more plot */ + } + break; + case INT_NOIZ: + for (i = 0; i < BSIM4v4NSRCS; i++) + { (void) sprintf(name, "onoise_total.%s%s", + here->BSIM4v4name, + BSIM4v4nNames[i]); data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, - &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, - NULL); - /* we've added one more plot */ + return(E_NOMEM); + SPfrontEnd->IFnewUid (ckt, + &(data->namelist[data->numPlots++]), + NULL, name, UID_OTHER, + NULL); + /* we've added one more plot */ - (void) sprintf(name, "inoise_total.%s%s", - here->BSIM4v4name, - BSIM4v4nNames[i]); + (void) sprintf(name, "inoise_total.%s%s", + here->BSIM4v4name, + BSIM4v4nNames[i]); data->namelist = TREALLOC(IFuid, data->namelist, data->numPlots + 1); if (!data->namelist) - return(E_NOMEM); - SPfrontEnd->IFnewUid (ckt, - &(data->namelist[data->numPlots++]), - NULL, name, UID_OTHER, - NULL); - /* we've added one more plot */ - } - break; - } - } - break; - case N_CALC: - m = here->BSIM4v4m; - switch (mode) - { case N_DENS: - if (model->BSIM4v4tnoiMod == 0) - { if (model->BSIM4v4rdsMod == 0) - { gspr = here->BSIM4v4sourceConductance; + return(E_NOMEM); + SPfrontEnd->IFnewUid (ckt, + &(data->namelist[data->numPlots++]), + NULL, name, UID_OTHER, + NULL); + /* we've added one more plot */ + } + break; + } + } + break; + case N_CALC: + m = here->BSIM4v4m; + switch (mode) + { case N_DENS: + if (model->BSIM4v4tnoiMod == 0) + { if (model->BSIM4v4rdsMod == 0) + { gspr = here->BSIM4v4sourceConductance; gdpr = here->BSIM4v4drainConductance; - if (here->BSIM4v4grdsw > 0.0) - tmp = 1.0 / here->BSIM4v4grdsw; /* tmp used below */ - else - tmp = 0.0; - } - else - { gspr = here->BSIM4v4gstot; + if (here->BSIM4v4grdsw > 0.0) + tmp = 1.0 / here->BSIM4v4grdsw; /* tmp used below */ + else + tmp = 0.0; + } + else + { gspr = here->BSIM4v4gstot; gdpr = here->BSIM4v4gdtot; tmp = 0.0; - } - } - else - { T5 = here->BSIM4v4Vgsteff / here->BSIM4v4EsatL; - T5 *= T5; - npart_beta = model->BSIM4v4rnoia * (1.0 + T5 - * model->BSIM4v4tnoia * pParam->BSIM4v4leff); - npart_theta = model->BSIM4v4rnoib * (1.0 + T5 + } + } + else + { T5 = here->BSIM4v4Vgsteff / here->BSIM4v4EsatL; + T5 *= T5; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + npart_beta = 0.577 * (1.0 + T5 + * model->BSIM4v4tnoia * pParam->BSIM4v4leff); + npart_theta = 0.37 * (1.0 + T5 * model->BSIM4v4tnoib * pParam->BSIM4v4leff); + break; + case BSIM4v30: case BSIM4v40: + npart_beta = model->BSIM4v4rnoia * (1.0 + T5 + * model->BSIM4v4tnoia * pParam->BSIM4v4leff); + npart_theta = model->BSIM4v4rnoib * (1.0 + T5 + * model->BSIM4v4tnoib * pParam->BSIM4v4leff); + break; + default: break; + } - if (model->BSIM4v4rdsMod == 0) + if (model->BSIM4v4rdsMod == 0) { gspr = here->BSIM4v4sourceConductance; gdpr = here->BSIM4v4drainConductance; } @@ -208,42 +252,55 @@ int i; gdpr = here->BSIM4v4gdtot; } - if ((*(ckt->CKTstates[0] + here->BSIM4v4vds)) >= 0.0) - gspr = gspr / (1.0 + npart_theta * npart_theta * gspr - / here->BSIM4v4IdovVds); /* bugfix */ - else - gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr - / here->BSIM4v4IdovVds); - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + if ((*(ckt->CKTstates[0] + here->BSIM4v4vds)) >= 0.0) + gspr = gspr * (1.0 + npart_theta * npart_theta * gspr + / here->BSIM4v4IdovVds); + else + gdpr = gdpr * (1.0 + npart_theta * npart_theta * gdpr + / here->BSIM4v4IdovVds); + break; + case BSIM4v30: case BSIM4v40: + if ((*(ckt->CKTstates[0] + here->BSIM4v4vds)) >= 0.0) + gspr = gspr / (1.0 + npart_theta * npart_theta * gspr + / here->BSIM4v4IdovVds); /* bugfix */ + else + gdpr = gdpr / (1.0 + npart_theta * npart_theta * gdpr + / here->BSIM4v4IdovVds); + break; + default: break; + } + } - NevalSrc(&noizDens[BSIM4v4RDNOIZ], - &lnNdens[BSIM4v4RDNOIZ], ckt, THERMNOISE, - here->BSIM4v4dNodePrime, here->BSIM4v4dNode, - gdpr * m); + NevalSrc(&noizDens[BSIM4v4RDNOIZ], + &lnNdens[BSIM4v4RDNOIZ], ckt, THERMNOISE, + here->BSIM4v4dNodePrime, here->BSIM4v4dNode, + gdpr * m); - NevalSrc(&noizDens[BSIM4v4RSNOIZ], - &lnNdens[BSIM4v4RSNOIZ], ckt, THERMNOISE, - here->BSIM4v4sNodePrime, here->BSIM4v4sNode, - gspr * m); + NevalSrc(&noizDens[BSIM4v4RSNOIZ], + &lnNdens[BSIM4v4RSNOIZ], ckt, THERMNOISE, + here->BSIM4v4sNodePrime, here->BSIM4v4sNode, + gspr * m); - if ((here->BSIM4v4rgateMod == 1) || (here->BSIM4v4rgateMod == 2)) - { NevalSrc(&noizDens[BSIM4v4RGNOIZ], + if ((here->BSIM4v4rgateMod == 1) || (here->BSIM4v4rgateMod == 2)) + { NevalSrc(&noizDens[BSIM4v4RGNOIZ], &lnNdens[BSIM4v4RGNOIZ], ckt, THERMNOISE, here->BSIM4v4gNodePrime, here->BSIM4v4gNodeExt, here->BSIM4v4grgeltd * m); - } - else if (here->BSIM4v4rgateMod == 3) - { NevalSrc(&noizDens[BSIM4v4RGNOIZ], + } + else if (here->BSIM4v4rgateMod == 3) + { NevalSrc(&noizDens[BSIM4v4RGNOIZ], &lnNdens[BSIM4v4RGNOIZ], ckt, THERMNOISE, here->BSIM4v4gNodeMid, here->BSIM4v4gNodeExt, here->BSIM4v4grgeltd * m); - } - else - { noizDens[BSIM4v4RGNOIZ] = 0.0; + } + else + { noizDens[BSIM4v4RGNOIZ] = 0.0; lnNdens[BSIM4v4RGNOIZ] = log(MAX(noizDens[BSIM4v4RGNOIZ], N_MINLOG)); - } + } if (here->BSIM4v4rbodyMod) @@ -286,49 +343,49 @@ int i; switch(model->BSIM4v4tnoiMod) - { case 0: - T0 = m * here->BSIM4v4ueff * fabs(here->BSIM4v4qinv); - T1 = T0 * tmp + pParam->BSIM4v4leff + { case 0: + T0 = m * here->BSIM4v4ueff * fabs(here->BSIM4v4qinv); + T1 = T0 * tmp + pParam->BSIM4v4leff * pParam->BSIM4v4leff; - NevalSrc(&noizDens[BSIM4v4IDNOIZ], - &lnNdens[BSIM4v4IDNOIZ], ckt, - THERMNOISE, here->BSIM4v4dNodePrime, + NevalSrc(&noizDens[BSIM4v4IDNOIZ], + &lnNdens[BSIM4v4IDNOIZ], ckt, + THERMNOISE, here->BSIM4v4dNodePrime, here->BSIM4v4sNodePrime, - (T0 / T1) * model->BSIM4v4ntnoi); - break; - case 1: - T0 = m * (here->BSIM4v4gm + here->BSIM4v4gmbs + here->BSIM4v4gds); - T0 *= T0; - igsquare = npart_theta * npart_theta * T0 / here->BSIM4v4IdovVds; - T1 = npart_beta * (here->BSIM4v4gm - + here->BSIM4v4gmbs) + here->BSIM4v4gds; - T2 = T1 * T1 / here->BSIM4v4IdovVds; + (T0 / T1) * model->BSIM4v4ntnoi); + break; + case 1: + T0 = m * (here->BSIM4v4gm + here->BSIM4v4gmbs + here->BSIM4v4gds); + T0 *= T0; + igsquare = npart_theta * npart_theta * T0 / here->BSIM4v4IdovVds; + T1 = npart_beta * (here->BSIM4v4gm + + here->BSIM4v4gmbs) + here->BSIM4v4gds; + T2 = T1 * T1 / here->BSIM4v4IdovVds; NevalSrc(&noizDens[BSIM4v4IDNOIZ], &lnNdens[BSIM4v4IDNOIZ], ckt, THERMNOISE, here->BSIM4v4dNodePrime, here->BSIM4v4sNodePrime, (T2 - igsquare)); break; - } + } - NevalSrc(&noizDens[BSIM4v4FLNOIZ], NULL, - ckt, N_GAIN, here->BSIM4v4dNodePrime, - here->BSIM4v4sNodePrime, (double) 0.0); + NevalSrc(&noizDens[BSIM4v4FLNOIZ], NULL, + ckt, N_GAIN, here->BSIM4v4dNodePrime, + here->BSIM4v4sNodePrime, (double) 0.0); switch(model->BSIM4v4fnoiMod) - { case 0: - noizDens[BSIM4v4FLNOIZ] *= m * model->BSIM4v4kf - * exp(model->BSIM4v4af - * log(MAX(fabs(here->BSIM4v4cd), - N_MINLOG))) - / (pow(data->freq, model->BSIM4v4ef) - * pParam->BSIM4v4leff - * pParam->BSIM4v4leff - * model->BSIM4v4coxe); - break; - case 1: - Vds = *(ckt->CKTstates[0] + here->BSIM4v4vds); - if (Vds < 0.0) - Vds = -Vds; + { case 0: + noizDens[BSIM4v4FLNOIZ] *= m * model->BSIM4v4kf + * exp(model->BSIM4v4af + * log(MAX(fabs(here->BSIM4v4cd), + N_MINLOG))) + / (pow(data->freq, model->BSIM4v4ef) + * pParam->BSIM4v4leff + * pParam->BSIM4v4leff + * model->BSIM4v4coxe); + break; + case 1: + Vds = *(ckt->CKTstates[0] + here->BSIM4v4vds); + if (Vds < 0.0) + Vds = -Vds; Ssi = BSIM4v4Eval1ovFNoise(Vds, model, here, data->freq, ckt->CKTtemp); @@ -336,7 +393,7 @@ int i; * CONSTboltz * ckt->CKTtemp; T11 = pParam->BSIM4v4weff * pParam->BSIM4v4leff * pow(data->freq, model->BSIM4v4ef) * 1.0e10 - * here->BSIM4v4nstar * here->BSIM4v4nstar; + * here->BSIM4v4nstar * here->BSIM4v4nstar; Swi = T10 / T11 * here->BSIM4v4cd * here->BSIM4v4cd; T1 = Swi + Ssi; @@ -344,133 +401,148 @@ int i; noizDens[BSIM4v4FLNOIZ] *= m * (Ssi * Swi) / T1; else noizDens[BSIM4v4FLNOIZ] *= 0.0; - break; - } + break; + } - lnNdens[BSIM4v4FLNOIZ] = - log(MAX(noizDens[BSIM4v4FLNOIZ], N_MINLOG)); + lnNdens[BSIM4v4FLNOIZ] = + log(MAX(noizDens[BSIM4v4FLNOIZ], N_MINLOG)); - if(here->BSIM4v4mode >= 0) { /* bugfix */ - NevalSrc(&noizDens[BSIM4v4IGSNOIZ], - &lnNdens[BSIM4v4IGSNOIZ], ckt, SHOTNOISE, - here->BSIM4v4gNodePrime, here->BSIM4v4sNodePrime, - m * (here->BSIM4v4Igs + here->BSIM4v4Igcs)); - NevalSrc(&noizDens[BSIM4v4IGDNOIZ], - &lnNdens[BSIM4v4IGDNOIZ], ckt, SHOTNOISE, - here->BSIM4v4gNodePrime, here->BSIM4v4dNodePrime, - m * (here->BSIM4v4Igd + here->BSIM4v4Igcd)); - } else { - NevalSrc(&noizDens[BSIM4v4IGSNOIZ], - &lnNdens[BSIM4v4IGSNOIZ], ckt, SHOTNOISE, - here->BSIM4v4gNodePrime, here->BSIM4v4sNodePrime, - m * (here->BSIM4v4Igs + here->BSIM4v4Igcd)); - NevalSrc(&noizDens[BSIM4v4IGDNOIZ], - &lnNdens[BSIM4v4IGDNOIZ], ckt, SHOTNOISE, - here->BSIM4v4gNodePrime, here->BSIM4v4dNodePrime, - m * (here->BSIM4v4Igd + here->BSIM4v4Igcs)); - } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + NevalSrc(&noizDens[BSIM4v4IGSNOIZ], + &lnNdens[BSIM4v4IGSNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4sNodePrime, + m * (here->BSIM4v4Igs + here->BSIM4v4Igcs)); + NevalSrc(&noizDens[BSIM4v4IGDNOIZ], + &lnNdens[BSIM4v4IGDNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4dNodePrime, + m * (here->BSIM4v4Igd + here->BSIM4v4Igcd)); + break; + case BSIM4v30: case BSIM4v40: + if(here->BSIM4v4mode >= 0) { /* bugfix */ + NevalSrc(&noizDens[BSIM4v4IGSNOIZ], + &lnNdens[BSIM4v4IGSNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4sNodePrime, + m * (here->BSIM4v4Igs + here->BSIM4v4Igcs)); + NevalSrc(&noizDens[BSIM4v4IGDNOIZ], + &lnNdens[BSIM4v4IGDNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4dNodePrime, + m * (here->BSIM4v4Igd + here->BSIM4v4Igcd)); + } else { + NevalSrc(&noizDens[BSIM4v4IGSNOIZ], + &lnNdens[BSIM4v4IGSNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4sNodePrime, + m * (here->BSIM4v4Igs + here->BSIM4v4Igcd)); + NevalSrc(&noizDens[BSIM4v4IGDNOIZ], + &lnNdens[BSIM4v4IGDNOIZ], ckt, SHOTNOISE, + here->BSIM4v4gNodePrime, here->BSIM4v4dNodePrime, + m * (here->BSIM4v4Igd + here->BSIM4v4Igcs)); + } + break; + default: break; + } NevalSrc(&noizDens[BSIM4v4IGBNOIZ], &lnNdens[BSIM4v4IGBNOIZ], ckt, SHOTNOISE, here->BSIM4v4gNodePrime, here->BSIM4v4bNodePrime, m * here->BSIM4v4Igb); - noizDens[BSIM4v4TOTNOIZ] = noizDens[BSIM4v4RDNOIZ] - + noizDens[BSIM4v4RSNOIZ] + noizDens[BSIM4v4RGNOIZ] - + noizDens[BSIM4v4RBPSNOIZ] + noizDens[BSIM4v4RBPDNOIZ] - + noizDens[BSIM4v4RBPBNOIZ] - + noizDens[BSIM4v4RBSBNOIZ] + noizDens[BSIM4v4RBDBNOIZ] - + noizDens[BSIM4v4IDNOIZ] + noizDens[BSIM4v4FLNOIZ] + noizDens[BSIM4v4TOTNOIZ] = noizDens[BSIM4v4RDNOIZ] + + noizDens[BSIM4v4RSNOIZ] + noizDens[BSIM4v4RGNOIZ] + + noizDens[BSIM4v4RBPSNOIZ] + noizDens[BSIM4v4RBPDNOIZ] + + noizDens[BSIM4v4RBPBNOIZ] + + noizDens[BSIM4v4RBSBNOIZ] + noizDens[BSIM4v4RBDBNOIZ] + + noizDens[BSIM4v4IDNOIZ] + noizDens[BSIM4v4FLNOIZ] + noizDens[BSIM4v4IGSNOIZ] + noizDens[BSIM4v4IGDNOIZ] + noizDens[BSIM4v4IGBNOIZ]; - lnNdens[BSIM4v4TOTNOIZ] = - log(MAX(noizDens[BSIM4v4TOTNOIZ], N_MINLOG)); + lnNdens[BSIM4v4TOTNOIZ] = + log(MAX(noizDens[BSIM4v4TOTNOIZ], N_MINLOG)); - *OnDens += noizDens[BSIM4v4TOTNOIZ]; + *OnDens += noizDens[BSIM4v4TOTNOIZ]; - if (data->delFreq == 0.0) - { /* if we haven't done any previous - integration, we need to initialize our - "history" variables. - */ + if (data->delFreq == 0.0) + { /* if we haven't done any previous + integration, we need to initialize our + "history" variables. + */ - for (i = 0; i < BSIM4v4NSRCS; i++) - { here->BSIM4v4nVar[LNLSTDENS][i] = - lnNdens[i]; - } + for (i = 0; i < BSIM4v4NSRCS; i++) + { here->BSIM4v4nVar[LNLSTDENS][i] = + lnNdens[i]; + } - /* clear out our integration variables - if it's the first pass - */ - if (data->freq == - ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) - { for (i = 0; i < BSIM4v4NSRCS; i++) - { here->BSIM4v4nVar[OUTNOIZ][i] = 0.0; - here->BSIM4v4nVar[INNOIZ][i] = 0.0; - } - } - } - else - { /* data->delFreq != 0.0, - we have to integrate. - */ - for (i = 0; i < BSIM4v4NSRCS; i++) - { if (i != BSIM4v4TOTNOIZ) - { tempOnoise = Nintegrate(noizDens[i], - lnNdens[i], - here->BSIM4v4nVar[LNLSTDENS][i], - data); - tempInoise = Nintegrate(noizDens[i] - * data->GainSqInv, lnNdens[i] - + data->lnGainInv, - here->BSIM4v4nVar[LNLSTDENS][i] - + data->lnGainInv, data); - here->BSIM4v4nVar[LNLSTDENS][i] = - lnNdens[i]; - data->outNoiz += tempOnoise; - data->inNoise += tempInoise; - if (((NOISEAN*) - ckt->CKTcurJob)->NStpsSm != 0) - { here->BSIM4v4nVar[OUTNOIZ][i] - += tempOnoise; - here->BSIM4v4nVar[OUTNOIZ][BSIM4v4TOTNOIZ] - += tempOnoise; - here->BSIM4v4nVar[INNOIZ][i] - += tempInoise; - here->BSIM4v4nVar[INNOIZ][BSIM4v4TOTNOIZ] - += tempInoise; + /* clear out our integration variables + if it's the first pass + */ + if (data->freq == + ((NOISEAN*) ckt->CKTcurJob)->NstartFreq) + { for (i = 0; i < BSIM4v4NSRCS; i++) + { here->BSIM4v4nVar[OUTNOIZ][i] = 0.0; + here->BSIM4v4nVar[INNOIZ][i] = 0.0; + } + } + } + else + { /* data->delFreq != 0.0, + we have to integrate. + */ + for (i = 0; i < BSIM4v4NSRCS; i++) + { if (i != BSIM4v4TOTNOIZ) + { tempOnoise = Nintegrate(noizDens[i], + lnNdens[i], + here->BSIM4v4nVar[LNLSTDENS][i], + data); + tempInoise = Nintegrate(noizDens[i] + * data->GainSqInv, lnNdens[i] + + data->lnGainInv, + here->BSIM4v4nVar[LNLSTDENS][i] + + data->lnGainInv, data); + here->BSIM4v4nVar[LNLSTDENS][i] = + lnNdens[i]; + data->outNoiz += tempOnoise; + data->inNoise += tempInoise; + if (((NOISEAN*) + ckt->CKTcurJob)->NStpsSm != 0) + { here->BSIM4v4nVar[OUTNOIZ][i] + += tempOnoise; + here->BSIM4v4nVar[OUTNOIZ][BSIM4v4TOTNOIZ] + += tempOnoise; + here->BSIM4v4nVar[INNOIZ][i] + += tempInoise; + here->BSIM4v4nVar[INNOIZ][BSIM4v4TOTNOIZ] + += tempInoise; } - } - } - } - if (data->prtSummary) - { for (i = 0; i < BSIM4v4NSRCS; i++) - { /* print a summary report */ - data->outpVector[data->outNumber++] - = noizDens[i]; - } - } - break; - case INT_NOIZ: - /* already calculated, just output */ - if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) - { for (i = 0; i < BSIM4v4NSRCS; i++) - { data->outpVector[data->outNumber++] - = here->BSIM4v4nVar[OUTNOIZ][i]; - data->outpVector[data->outNumber++] - = here->BSIM4v4nVar[INNOIZ][i]; - } - } - break; - } - break; - case N_CLOSE: - /* do nothing, the main calling routine will close */ - return (OK); - break; /* the plots */ - } /* switch (operation) */ - } /* for here */ + } + } + } + if (data->prtSummary) + { for (i = 0; i < BSIM4v4NSRCS; i++) + { /* print a summary report */ + data->outpVector[data->outNumber++] + = noizDens[i]; + } + } + break; + case INT_NOIZ: + /* already calculated, just output */ + if (((NOISEAN*)ckt->CKTcurJob)->NStpsSm != 0) + { for (i = 0; i < BSIM4v4NSRCS; i++) + { data->outpVector[data->outNumber++] + = here->BSIM4v4nVar[OUTNOIZ][i]; + data->outpVector[data->outNumber++] + = here->BSIM4v4nVar[INNOIZ][i]; + } + } + break; + } + break; + case N_CLOSE: + /* do nothing, the main calling routine will close */ + return (OK); + break; /* the plots */ + } /* switch (operation) */ + } /* for here */ } /* for model */ return(OK); diff --git a/src/spicelib/devices/bsim4v4/b4v4set.c b/src/spicelib/devices/bsim4v4/b4v4set.c index 70ecc8912..a59266ba6 100644 --- a/src/spicelib/devices/bsim4v4/b4v4set.c +++ b/src/spicelib/devices/bsim4v4/b4v4set.c @@ -1,5 +1,5 @@ /**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/ - +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. * File: b4set.c of BSIM4.4.0. @@ -14,15 +14,13 @@ **********/ #include "ngspice.h" -#include "jobdefs.h" /* Needed because the model searches for noise Analysis */ -#include "ftedefs.h" /* " " */ +#include "jobdefs.h" +#include "ftedefs.h" #include "smpdefs.h" #include "cktdefs.h" #include "bsim4v4def.h" #include "const.h" #include "sperror.h" -#include "suffix.h" - #define MAX_EXP 5.834617425e14 #define MIN_EXP 1.713908431e-15 @@ -60,19 +58,19 @@ JOB *job; for( ; model != NULL; model = model->BSIM4v4nextModel ) { /* process defaults of model parameters */ if (!model->BSIM4v4typeGiven) - model->BSIM4v4type = NMOS; + model->BSIM4v4type = NMOS; - if (!model->BSIM4v4mobModGiven) + if (!model->BSIM4v4mobModGiven) model->BSIM4v4mobMod = 0; - else if ((model->BSIM4v4mobMod != 0) && (model->BSIM4v4mobMod != 1) - && (model->BSIM4v4mobMod != 2)) - { model->BSIM4v4mobMod = 0; + else if ((model->BSIM4v4mobMod != 0) && (model->BSIM4v4mobMod != 1) + && (model->BSIM4v4mobMod != 2)) + { model->BSIM4v4mobMod = 0; printf("Warning: mobMod has been set to its default value: 0.\n"); - } + } - if (!model->BSIM4v4binUnitGiven) + if (!model->BSIM4v4binUnitGiven) model->BSIM4v4binUnit = 1; - if (!model->BSIM4v4paramChkGiven) + if (!model->BSIM4v4paramChkGiven) model->BSIM4v4paramChk = 1; if (!model->BSIM4v4dioModGiven) @@ -83,7 +81,7 @@ JOB *job; printf("Warning: dioMod has been set to its default value: 1.\n"); } - if (!model->BSIM4v4capModGiven) + if (!model->BSIM4v4capModGiven) model->BSIM4v4capMod = 2; else if ((model->BSIM4v4capMod != 0) && (model->BSIM4v4capMod != 1) && (model->BSIM4v4capMod != 2)) @@ -93,10 +91,10 @@ JOB *job; if (!model->BSIM4v4rdsModGiven) model->BSIM4v4rdsMod = 0; - else if ((model->BSIM4v4rdsMod != 0) && (model->BSIM4v4rdsMod != 1)) + else if ((model->BSIM4v4rdsMod != 0) && (model->BSIM4v4rdsMod != 1)) { model->BSIM4v4rdsMod = 0; - printf("Warning: rdsMod has been set to its default value: 0.\n"); - } + printf("Warning: rdsMod has been set to its default value: 0.\n"); + } if (!model->BSIM4v4rbodyModGiven) model->BSIM4v4rbodyMod = 0; else if ((model->BSIM4v4rbodyMod != 0) && (model->BSIM4v4rbodyMod != 1)) @@ -122,7 +120,7 @@ JOB *job; if (!model->BSIM4v4geoModGiven) model->BSIM4v4geoMod = 0; - if (!model->BSIM4v4fnoiModGiven) + if (!model->BSIM4v4fnoiModGiven) model->BSIM4v4fnoiMod = 1; else if ((model->BSIM4v4fnoiMod != 0) && (model->BSIM4v4fnoiMod != 1)) { model->BSIM4v4fnoiMod = 1; @@ -136,7 +134,7 @@ JOB *job; } if (!model->BSIM4v4trnqsModGiven) - model->BSIM4v4trnqsMod = 0; + model->BSIM4v4trnqsMod = 0; else if ((model->BSIM4v4trnqsMod != 0) && (model->BSIM4v4trnqsMod != 1)) { model->BSIM4v4trnqsMod = 0; printf("Warning: trnqsMod has been set to its default value: 0.\n"); @@ -160,15 +158,39 @@ JOB *job; { model->BSIM4v4igbMod = 0; printf("Warning: igbMod has been set to its default value: 0.\n"); } - if (!model->BSIM4v4tempModGiven) - model->BSIM4v4tempMod = 0; - else if ((model->BSIM4v4tempMod != 0) && (model->BSIM4v4tempMod != 1)) - { model->BSIM4v4tempMod = 0; - printf("Warning: tempMod has been set to its default value: 0.\n"); + + /* If the user does not provide the model revision, + * we always choose the most recent for this code. + */ + if (!model->BSIM4v4versionGiven) + model->BSIM4v4version = "4.4.0"; + + if ((!strcmp(model->BSIM4v4version, "4.2.1"))||(!strcmp(model->BSIM4v4version, "4.21"))) + model->BSIM4v4intVersion = BSIM4v21; + else if ((!strcmp(model->BSIM4v4version, "4.3.0"))||(!strcmp(model->BSIM4v4version, "4.30"))) + model->BSIM4v4intVersion = BSIM4v30; + else if ((!strcmp(model->BSIM4v4version, "4.4.0"))||(!strcmp(model->BSIM4v4version, "4.40"))) + model->BSIM4v4intVersion = BSIM4v40; + else + model->BSIM4v4intVersion = BSIM4vOLD; + /* BSIM4vOLD is a placeholder for pre 2.1 revision + * This model should not be used for pre 2.1 models. + */ + + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (!model->BSIM4v4tempModGiven) + model->BSIM4v4tempMod = 0; + else if ((model->BSIM4v4tempMod != 0) && (model->BSIM4v4tempMod != 1)) + { model->BSIM4v4tempMod = 0; + printf("Warning: tempMod has been set to its default value: 0.\n"); + } + break; + default: break; } - if (!model->BSIM4v4versionGiven) - model->BSIM4v4version = "4.4.0"; if (!model->BSIM4v4toxrefGiven) model->BSIM4v4toxref = 30.0e-10; if (!model->BSIM4v4toxeGiven) @@ -183,23 +205,23 @@ JOB *job; model->BSIM4v4epsrox = 3.9; if (!model->BSIM4v4cdscGiven) - model->BSIM4v4cdsc = 2.4e-4; /* unit Q/V/m^2 */ + model->BSIM4v4cdsc = 2.4e-4; /* unit Q/V/m^2 */ if (!model->BSIM4v4cdscbGiven) - model->BSIM4v4cdscb = 0.0; /* unit Q/V/m^2 */ - if (!model->BSIM4v4cdscdGiven) - model->BSIM4v4cdscd = 0.0; /* unit Q/V/m^2 */ + model->BSIM4v4cdscb = 0.0; /* unit Q/V/m^2 */ + if (!model->BSIM4v4cdscdGiven) + model->BSIM4v4cdscd = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM4v4citGiven) - model->BSIM4v4cit = 0.0; /* unit Q/V/m^2 */ + model->BSIM4v4cit = 0.0; /* unit Q/V/m^2 */ if (!model->BSIM4v4nfactorGiven) - model->BSIM4v4nfactor = 1.0; + model->BSIM4v4nfactor = 1.0; if (!model->BSIM4v4xjGiven) model->BSIM4v4xj = .15e-6; if (!model->BSIM4v4vsatGiven) - model->BSIM4v4vsat = 8.0e4; /* unit m/s */ + model->BSIM4v4vsat = 8.0e4; /* unit m/s */ if (!model->BSIM4v4atGiven) - model->BSIM4v4at = 3.3e4; /* unit m/s */ + model->BSIM4v4at = 3.3e4; /* unit m/s */ if (!model->BSIM4v4a0Given) - model->BSIM4v4a0 = 1.0; + model->BSIM4v4a0 = 1.0; if (!model->BSIM4v4agsGiven) model->BSIM4v4ags = 0.0; if (!model->BSIM4v4a1Given) @@ -219,9 +241,9 @@ JOB *job; if (!model->BSIM4v4ngateGiven) model->BSIM4v4ngate = 0; /* unit 1/cm3 */ if (!model->BSIM4v4vbmGiven) - model->BSIM4v4vbm = -3.0; + model->BSIM4v4vbm = -3.0; if (!model->BSIM4v4xtGiven) - model->BSIM4v4xt = 1.55e-7; + model->BSIM4v4xt = 1.55e-7; if (!model->BSIM4v4kt1Given) model->BSIM4v4kt1 = -0.11; /* unit V */ if (!model->BSIM4v4kt1lGiven) @@ -229,13 +251,13 @@ JOB *job; if (!model->BSIM4v4kt2Given) model->BSIM4v4kt2 = 0.022; /* No unit */ if (!model->BSIM4v4k3Given) - model->BSIM4v4k3 = 80.0; + model->BSIM4v4k3 = 80.0; if (!model->BSIM4v4k3bGiven) - model->BSIM4v4k3b = 0.0; + model->BSIM4v4k3b = 0.0; if (!model->BSIM4v4w0Given) - model->BSIM4v4w0 = 2.5e-6; + model->BSIM4v4w0 = 2.5e-6; if (!model->BSIM4v4lpe0Given) - model->BSIM4v4lpe0 = 1.74e-7; + model->BSIM4v4lpe0 = 1.74e-7; if (!model->BSIM4v4lpebGiven) model->BSIM4v4lpeb = 0.0; if (!model->BSIM4v4dvtp0Given) @@ -243,23 +265,23 @@ JOB *job; if (!model->BSIM4v4dvtp1Given) model->BSIM4v4dvtp1 = 0.0; if (!model->BSIM4v4dvt0Given) - model->BSIM4v4dvt0 = 2.2; + model->BSIM4v4dvt0 = 2.2; if (!model->BSIM4v4dvt1Given) - model->BSIM4v4dvt1 = 0.53; + model->BSIM4v4dvt1 = 0.53; if (!model->BSIM4v4dvt2Given) - model->BSIM4v4dvt2 = -0.032; /* unit 1 / V */ + model->BSIM4v4dvt2 = -0.032; /* unit 1 / V */ if (!model->BSIM4v4dvt0wGiven) - model->BSIM4v4dvt0w = 0.0; + model->BSIM4v4dvt0w = 0.0; if (!model->BSIM4v4dvt1wGiven) - model->BSIM4v4dvt1w = 5.3e6; + model->BSIM4v4dvt1w = 5.3e6; if (!model->BSIM4v4dvt2wGiven) - model->BSIM4v4dvt2w = -0.032; + model->BSIM4v4dvt2w = -0.032; if (!model->BSIM4v4droutGiven) - model->BSIM4v4drout = 0.56; + model->BSIM4v4drout = 0.56; if (!model->BSIM4v4dsubGiven) - model->BSIM4v4dsub = model->BSIM4v4drout; + model->BSIM4v4dsub = model->BSIM4v4drout; if (!model->BSIM4v4vth0Given) model->BSIM4v4vth0 = (model->BSIM4v4type == NMOS) ? 0.7 : -0.7; if (!model->BSIM4v4euGiven) @@ -273,15 +295,15 @@ JOB *job; if (!model->BSIM4v4ub1Given) model->BSIM4v4ub1 = -1.0e-18; /* unit (m/V)**2 */ if (!model->BSIM4v4ucGiven) - model->BSIM4v4uc = (model->BSIM4v4mobMod == 1) ? -0.0465 : -0.0465e-9; + model->BSIM4v4uc = (model->BSIM4v4mobMod == 1) ? -0.0465 : -0.0465e-9; if (!model->BSIM4v4uc1Given) - model->BSIM4v4uc1 = (model->BSIM4v4mobMod == 1) ? -0.056 : -0.056e-9; + model->BSIM4v4uc1 = (model->BSIM4v4mobMod == 1) ? -0.056 : -0.056e-9; if (!model->BSIM4v4u0Given) model->BSIM4v4u0 = (model->BSIM4v4type == NMOS) ? 0.067 : 0.025; if (!model->BSIM4v4uteGiven) - model->BSIM4v4ute = -1.5; + model->BSIM4v4ute = -1.5; if (!model->BSIM4v4voffGiven) - model->BSIM4v4voff = -0.08; + model->BSIM4v4voff = -0.08; if (!model->BSIM4v4vofflGiven) model->BSIM4v4voffl = 0.0; if (!model->BSIM4v4minvGiven) @@ -294,7 +316,7 @@ JOB *job; model->BSIM4v4pditsd = 0.0; if (!model->BSIM4v4pditslGiven) model->BSIM4v4pditsl = 0.0; - if (!model->BSIM4v4deltaGiven) + if (!model->BSIM4v4deltaGiven) model->BSIM4v4delta = 0.01; if (!model->BSIM4v4rdswminGiven) model->BSIM4v4rdswmin = 0.0; @@ -303,7 +325,7 @@ JOB *job; if (!model->BSIM4v4rswminGiven) model->BSIM4v4rswmin = 0.0; if (!model->BSIM4v4rdswGiven) - model->BSIM4v4rdsw = 200.0; /* in ohm*um */ + model->BSIM4v4rdsw = 200.0; /* in ohm*um */ if (!model->BSIM4v4rdwGiven) model->BSIM4v4rdw = 100.0; if (!model->BSIM4v4rswGiven) @@ -311,43 +333,43 @@ JOB *job; if (!model->BSIM4v4prwgGiven) model->BSIM4v4prwg = 1.0; /* in 1/V */ if (!model->BSIM4v4prwbGiven) - model->BSIM4v4prwb = 0.0; + model->BSIM4v4prwb = 0.0; if (!model->BSIM4v4prtGiven) if (!model->BSIM4v4prtGiven) - model->BSIM4v4prt = 0.0; + model->BSIM4v4prt = 0.0; if (!model->BSIM4v4eta0Given) - model->BSIM4v4eta0 = 0.08; /* no unit */ + model->BSIM4v4eta0 = 0.08; /* no unit */ if (!model->BSIM4v4etabGiven) - model->BSIM4v4etab = -0.07; /* unit 1/V */ + model->BSIM4v4etab = -0.07; /* unit 1/V */ if (!model->BSIM4v4pclmGiven) - model->BSIM4v4pclm = 1.3; /* no unit */ + model->BSIM4v4pclm = 1.3; /* no unit */ if (!model->BSIM4v4pdibl1Given) model->BSIM4v4pdibl1 = 0.39; /* no unit */ if (!model->BSIM4v4pdibl2Given) - model->BSIM4v4pdibl2 = 0.0086; /* no unit */ + model->BSIM4v4pdibl2 = 0.0086; /* no unit */ if (!model->BSIM4v4pdiblbGiven) - model->BSIM4v4pdiblb = 0.0; /* 1/V */ + model->BSIM4v4pdiblb = 0.0; /* 1/V */ if (!model->BSIM4v4pscbe1Given) - model->BSIM4v4pscbe1 = 4.24e8; + model->BSIM4v4pscbe1 = 4.24e8; if (!model->BSIM4v4pscbe2Given) - model->BSIM4v4pscbe2 = 1.0e-5; + model->BSIM4v4pscbe2 = 1.0e-5; if (!model->BSIM4v4pvagGiven) - model->BSIM4v4pvag = 0.0; - if (!model->BSIM4v4wrGiven) + model->BSIM4v4pvag = 0.0; + if (!model->BSIM4v4wrGiven) model->BSIM4v4wr = 1.0; - if (!model->BSIM4v4dwgGiven) + if (!model->BSIM4v4dwgGiven) model->BSIM4v4dwg = 0.0; - if (!model->BSIM4v4dwbGiven) + if (!model->BSIM4v4dwbGiven) model->BSIM4v4dwb = 0.0; if (!model->BSIM4v4b0Given) model->BSIM4v4b0 = 0.0; - if (!model->BSIM4v4b1Given) + if (!model->BSIM4v4b1Given) model->BSIM4v4b1 = 0.0; - if (!model->BSIM4v4alpha0Given) + if (!model->BSIM4v4alpha0Given) model->BSIM4v4alpha0 = 0.0; if (!model->BSIM4v4alpha1Given) model->BSIM4v4alpha1 = 0.0; - if (!model->BSIM4v4beta0Given) + if (!model->BSIM4v4beta0Given) model->BSIM4v4beta0 = 30.0; if (!model->BSIM4v4agidlGiven) model->BSIM4v4agidl = 0.0; @@ -411,25 +433,49 @@ JOB *job; model->BSIM4v4tnoia = 1.5; if (!model->BSIM4v4tnoibGiven) model->BSIM4v4tnoib = 3.5; - if (!model->BSIM4v4rnoiaGiven) - model->BSIM4v4rnoia = 0.577; - if (!model->BSIM4v4rnoibGiven) - model->BSIM4v4rnoib = 0.5164; if (!model->BSIM4v4ntnoiGiven) model->BSIM4v4ntnoi = 1.0; - if (!model->BSIM4v4lambdaGiven) - model->BSIM4v4lambda = 0.0; - if (!model->BSIM4v4vtlGiven) - model->BSIM4v4vtl = 2.0e5; /* unit m/s */ - if (!model->BSIM4v4xnGiven) - model->BSIM4v4xn = 3.0; - if (!model->BSIM4v4lcGiven) - model->BSIM4v4lc = 5.0e-9; - if (!model->BSIM4v4vfbsdoffGiven) - model->BSIM4v4vfbsdoff = 0.0; /* unit v */ - if (!model->BSIM4v4lintnoiGiven) - model->BSIM4v4lintnoi = 0.0; /* unit m */ - + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: + if (!model->BSIM4v4rnoibGiven) + model->BSIM4v4rnoib = 0.37; + break; + case BSIM4v40: + if (!model->BSIM4v4rnoibGiven) + model->BSIM4v4rnoib = 0.5164; + break; + default: break; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (!model->BSIM4v4rnoiaGiven) + model->BSIM4v4rnoia = 0.577; + if (!model->BSIM4v4lambdaGiven) + model->BSIM4v4lambda = 0.0; + if (!model->BSIM4v4vtlGiven) + model->BSIM4v4vtl = 2.0e5; /* unit m/s */ + if (!model->BSIM4v4xnGiven) + model->BSIM4v4xn = 3.0; + if (!model->BSIM4v4lcGiven) + model->BSIM4v4lc = 5.0e-9; + break; + default: break; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (!model->BSIM4v4vfbsdoffGiven) + model->BSIM4v4vfbsdoff = 0.0; /* unit v */ + if (!model->BSIM4v4lintnoiGiven) + model->BSIM4v4lintnoi = 0.0; /* unit m */ + break; + default: break; + } if (!model->BSIM4v4xjbvsGiven) model->BSIM4v4xjbvs = 1.0; /* no unit */ if (!model->BSIM4v4xjbvdGiven) @@ -438,7 +484,6 @@ JOB *job; model->BSIM4v4bvs = 10.0; /* V */ if (!model->BSIM4v4bvdGiven) model->BSIM4v4bvd = model->BSIM4v4bvs; - if (!model->BSIM4v4gbminGiven) model->BSIM4v4gbmin = 1.0e-12; /* in mho */ if (!model->BSIM4v4rbdbGiven) @@ -452,19 +497,19 @@ JOB *job; if (!model->BSIM4v4rbpdGiven) model->BSIM4v4rbpd = 50.0; - if (!model->BSIM4v4cgslGiven) + if (!model->BSIM4v4cgslGiven) model->BSIM4v4cgsl = 0.0; - if (!model->BSIM4v4cgdlGiven) + if (!model->BSIM4v4cgdlGiven) model->BSIM4v4cgdl = 0.0; - if (!model->BSIM4v4ckappasGiven) + if (!model->BSIM4v4ckappasGiven) model->BSIM4v4ckappas = 0.6; if (!model->BSIM4v4ckappadGiven) model->BSIM4v4ckappad = model->BSIM4v4ckappas; - if (!model->BSIM4v4clcGiven) + if (!model->BSIM4v4clcGiven) model->BSIM4v4clc = 0.1e-6; - if (!model->BSIM4v4cleGiven) + if (!model->BSIM4v4cleGiven) model->BSIM4v4cle = 0.6; - if (!model->BSIM4v4vfbcvGiven) + if (!model->BSIM4v4vfbcvGiven) model->BSIM4v4vfbcv = -1.0; if (!model->BSIM4v4acdeGiven) model->BSIM4v4acde = 1.0; @@ -503,17 +548,17 @@ JOB *job; if (!model->BSIM4v4tpbswgGiven) model->BSIM4v4tpbswg = 0.0; - /* Length dependence */ + /* Length dependence */ if (!model->BSIM4v4lcdscGiven) - model->BSIM4v4lcdsc = 0.0; + model->BSIM4v4lcdsc = 0.0; if (!model->BSIM4v4lcdscbGiven) - model->BSIM4v4lcdscb = 0.0; - if (!model->BSIM4v4lcdscdGiven) - model->BSIM4v4lcdscd = 0.0; + model->BSIM4v4lcdscb = 0.0; + if (!model->BSIM4v4lcdscdGiven) + model->BSIM4v4lcdscd = 0.0; if (!model->BSIM4v4lcitGiven) - model->BSIM4v4lcit = 0.0; + model->BSIM4v4lcit = 0.0; if (!model->BSIM4v4lnfactorGiven) - model->BSIM4v4lnfactor = 0.0; + model->BSIM4v4lnfactor = 0.0; if (!model->BSIM4v4lxjGiven) model->BSIM4v4lxj = 0.0; if (!model->BSIM4v4lvsatGiven) @@ -521,7 +566,7 @@ JOB *job; if (!model->BSIM4v4latGiven) model->BSIM4v4lat = 0.0; if (!model->BSIM4v4la0Given) - model->BSIM4v4la0 = 0.0; + model->BSIM4v4la0 = 0.0; if (!model->BSIM4v4lagsGiven) model->BSIM4v4lags = 0.0; if (!model->BSIM4v4la1Given) @@ -541,43 +586,52 @@ JOB *job; if (!model->BSIM4v4lngateGiven) model->BSIM4v4lngate = 0.0; if (!model->BSIM4v4lvbmGiven) - model->BSIM4v4lvbm = 0.0; + model->BSIM4v4lvbm = 0.0; if (!model->BSIM4v4lxtGiven) - model->BSIM4v4lxt = 0.0; + model->BSIM4v4lxt = 0.0; if (!model->BSIM4v4lkt1Given) - model->BSIM4v4lkt1 = 0.0; + model->BSIM4v4lkt1 = 0.0; if (!model->BSIM4v4lkt1lGiven) model->BSIM4v4lkt1l = 0.0; if (!model->BSIM4v4lkt2Given) model->BSIM4v4lkt2 = 0.0; if (!model->BSIM4v4lk3Given) - model->BSIM4v4lk3 = 0.0; + model->BSIM4v4lk3 = 0.0; if (!model->BSIM4v4lk3bGiven) - model->BSIM4v4lk3b = 0.0; + model->BSIM4v4lk3b = 0.0; if (!model->BSIM4v4lw0Given) - model->BSIM4v4lw0 = 0.0; + model->BSIM4v4lw0 = 0.0; if (!model->BSIM4v4llpe0Given) model->BSIM4v4llpe0 = 0.0; - if (!model->BSIM4v4llpebGiven) - model->BSIM4v4llpeb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (!model->BSIM4v4llpebGiven) + model->BSIM4v4llpeb = model->BSIM4v4llpe0; + break; + case BSIM4v40: + if (!model->BSIM4v4llpebGiven) + model->BSIM4v4llpeb = 0.0; + break; + default: break; + } if (!model->BSIM4v4ldvtp0Given) model->BSIM4v4ldvtp0 = 0.0; if (!model->BSIM4v4ldvtp1Given) model->BSIM4v4ldvtp1 = 0.0; if (!model->BSIM4v4ldvt0Given) - model->BSIM4v4ldvt0 = 0.0; + model->BSIM4v4ldvt0 = 0.0; if (!model->BSIM4v4ldvt1Given) - model->BSIM4v4ldvt1 = 0.0; + model->BSIM4v4ldvt1 = 0.0; if (!model->BSIM4v4ldvt2Given) model->BSIM4v4ldvt2 = 0.0; if (!model->BSIM4v4ldvt0wGiven) - model->BSIM4v4ldvt0w = 0.0; + model->BSIM4v4ldvt0w = 0.0; if (!model->BSIM4v4ldvt1wGiven) - model->BSIM4v4ldvt1w = 0.0; + model->BSIM4v4ldvt1w = 0.0; if (!model->BSIM4v4ldvt2wGiven) model->BSIM4v4ldvt2w = 0.0; if (!model->BSIM4v4ldroutGiven) - model->BSIM4v4ldrout = 0.0; + model->BSIM4v4ldrout = 0.0; if (!model->BSIM4v4ldsubGiven) model->BSIM4v4ldsub = 0.0; if (!model->BSIM4v4lvth0Given) @@ -597,9 +651,9 @@ JOB *job; if (!model->BSIM4v4lu0Given) model->BSIM4v4lu0 = 0.0; if (!model->BSIM4v4luteGiven) - model->BSIM4v4lute = 0.0; + model->BSIM4v4lute = 0.0; if (!model->BSIM4v4lvoffGiven) - model->BSIM4v4lvoff = 0.0; + model->BSIM4v4lvoff = 0.0; if (!model->BSIM4v4lminvGiven) model->BSIM4v4lminv = 0.0; if (!model->BSIM4v4lfproutGiven) @@ -608,7 +662,7 @@ JOB *job; model->BSIM4v4lpdits = 0.0; if (!model->BSIM4v4lpditsdGiven) model->BSIM4v4lpditsd = 0.0; - if (!model->BSIM4v4ldeltaGiven) + if (!model->BSIM4v4ldeltaGiven) model->BSIM4v4ldelta = 0.0; if (!model->BSIM4v4lrdswGiven) model->BSIM4v4lrdsw = 0.0; @@ -627,7 +681,7 @@ JOB *job; if (!model->BSIM4v4letabGiven) model->BSIM4v4letab = -0.0; if (!model->BSIM4v4lpclmGiven) - model->BSIM4v4lpclm = 0.0; + model->BSIM4v4lpclm = 0.0; if (!model->BSIM4v4lpdibl1Given) model->BSIM4v4lpdibl1 = 0.0; if (!model->BSIM4v4lpdibl2Given) @@ -639,22 +693,22 @@ JOB *job; if (!model->BSIM4v4lpscbe2Given) model->BSIM4v4lpscbe2 = 0.0; if (!model->BSIM4v4lpvagGiven) - model->BSIM4v4lpvag = 0.0; - if (!model->BSIM4v4lwrGiven) + model->BSIM4v4lpvag = 0.0; + if (!model->BSIM4v4lwrGiven) model->BSIM4v4lwr = 0.0; - if (!model->BSIM4v4ldwgGiven) + if (!model->BSIM4v4ldwgGiven) model->BSIM4v4ldwg = 0.0; - if (!model->BSIM4v4ldwbGiven) + if (!model->BSIM4v4ldwbGiven) model->BSIM4v4ldwb = 0.0; if (!model->BSIM4v4lb0Given) model->BSIM4v4lb0 = 0.0; - if (!model->BSIM4v4lb1Given) + if (!model->BSIM4v4lb1Given) model->BSIM4v4lb1 = 0.0; - if (!model->BSIM4v4lalpha0Given) + if (!model->BSIM4v4lalpha0Given) model->BSIM4v4lalpha0 = 0.0; if (!model->BSIM4v4lalpha1Given) model->BSIM4v4lalpha1 = 0.0; - if (!model->BSIM4v4lbeta0Given) + if (!model->BSIM4v4lbeta0Given) model->BSIM4v4lbeta0 = 0.0; if (!model->BSIM4v4lagidlGiven) model->BSIM4v4lagidl = 0.0; @@ -710,30 +764,43 @@ JOB *job; model->BSIM4v4leu = 0.0; if (!model->BSIM4v4lvfbGiven) model->BSIM4v4lvfb = 0.0; - if (!model->BSIM4v4llambdaGiven) - model->BSIM4v4llambda = 0.0; - if (!model->BSIM4v4lvtlGiven) - model->BSIM4v4lvtl = 0.0; - if (!model->BSIM4v4lxnGiven) - model->BSIM4v4lxn = 0.0; - if (!model->BSIM4v4lvfbsdoffGiven) - model->BSIM4v4lvfbsdoff = 0.0; - - if (!model->BSIM4v4lcgslGiven) + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (!model->BSIM4v4llambdaGiven) + model->BSIM4v4llambda = 0.0; + if (!model->BSIM4v4lvtlGiven) + model->BSIM4v4lvtl = 0.0; + if (!model->BSIM4v4lxnGiven) + model->BSIM4v4lxn = 0.0; + break; + default: break; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (!model->BSIM4v4lvfbsdoffGiven) + model->BSIM4v4lvfbsdoff = 0.0; + break; + default: break; + } + if (!model->BSIM4v4lcgslGiven) model->BSIM4v4lcgsl = 0.0; - if (!model->BSIM4v4lcgdlGiven) + if (!model->BSIM4v4lcgdlGiven) model->BSIM4v4lcgdl = 0.0; - if (!model->BSIM4v4lckappasGiven) + if (!model->BSIM4v4lckappasGiven) model->BSIM4v4lckappas = 0.0; if (!model->BSIM4v4lckappadGiven) model->BSIM4v4lckappad = 0.0; - if (!model->BSIM4v4lclcGiven) + if (!model->BSIM4v4lclcGiven) model->BSIM4v4lclc = 0.0; - if (!model->BSIM4v4lcleGiven) + if (!model->BSIM4v4lcleGiven) model->BSIM4v4lcle = 0.0; - if (!model->BSIM4v4lcfGiven) + if (!model->BSIM4v4lcfGiven) model->BSIM4v4lcf = 0.0; - if (!model->BSIM4v4lvfbcvGiven) + if (!model->BSIM4v4lvfbcvGiven) model->BSIM4v4lvfbcv = 0.0; if (!model->BSIM4v4lacdeGiven) model->BSIM4v4lacde = 0.0; @@ -744,17 +811,17 @@ JOB *job; if (!model->BSIM4v4lvoffcvGiven) model->BSIM4v4lvoffcv = 0.0; - /* Width dependence */ + /* Width dependence */ if (!model->BSIM4v4wcdscGiven) - model->BSIM4v4wcdsc = 0.0; + model->BSIM4v4wcdsc = 0.0; if (!model->BSIM4v4wcdscbGiven) - model->BSIM4v4wcdscb = 0.0; - if (!model->BSIM4v4wcdscdGiven) - model->BSIM4v4wcdscd = 0.0; + model->BSIM4v4wcdscb = 0.0; + if (!model->BSIM4v4wcdscdGiven) + model->BSIM4v4wcdscd = 0.0; if (!model->BSIM4v4wcitGiven) - model->BSIM4v4wcit = 0.0; + model->BSIM4v4wcit = 0.0; if (!model->BSIM4v4wnfactorGiven) - model->BSIM4v4wnfactor = 0.0; + model->BSIM4v4wnfactor = 0.0; if (!model->BSIM4v4wxjGiven) model->BSIM4v4wxj = 0.0; if (!model->BSIM4v4wvsatGiven) @@ -762,7 +829,7 @@ JOB *job; if (!model->BSIM4v4watGiven) model->BSIM4v4wat = 0.0; if (!model->BSIM4v4wa0Given) - model->BSIM4v4wa0 = 0.0; + model->BSIM4v4wa0 = 0.0; if (!model->BSIM4v4wagsGiven) model->BSIM4v4wags = 0.0; if (!model->BSIM4v4wa1Given) @@ -782,43 +849,43 @@ JOB *job; if (!model->BSIM4v4wngateGiven) model->BSIM4v4wngate = 0.0; if (!model->BSIM4v4wvbmGiven) - model->BSIM4v4wvbm = 0.0; + model->BSIM4v4wvbm = 0.0; if (!model->BSIM4v4wxtGiven) - model->BSIM4v4wxt = 0.0; + model->BSIM4v4wxt = 0.0; if (!model->BSIM4v4wkt1Given) - model->BSIM4v4wkt1 = 0.0; + model->BSIM4v4wkt1 = 0.0; if (!model->BSIM4v4wkt1lGiven) model->BSIM4v4wkt1l = 0.0; if (!model->BSIM4v4wkt2Given) model->BSIM4v4wkt2 = 0.0; if (!model->BSIM4v4wk3Given) - model->BSIM4v4wk3 = 0.0; + model->BSIM4v4wk3 = 0.0; if (!model->BSIM4v4wk3bGiven) - model->BSIM4v4wk3b = 0.0; + model->BSIM4v4wk3b = 0.0; if (!model->BSIM4v4ww0Given) - model->BSIM4v4ww0 = 0.0; + model->BSIM4v4ww0 = 0.0; if (!model->BSIM4v4wlpe0Given) model->BSIM4v4wlpe0 = 0.0; if (!model->BSIM4v4wlpebGiven) - model->BSIM4v4wlpeb = 0.0; + model->BSIM4v4wlpeb = model->BSIM4v4wlpe0; if (!model->BSIM4v4wdvtp0Given) model->BSIM4v4wdvtp0 = 0.0; if (!model->BSIM4v4wdvtp1Given) model->BSIM4v4wdvtp1 = 0.0; if (!model->BSIM4v4wdvt0Given) - model->BSIM4v4wdvt0 = 0.0; + model->BSIM4v4wdvt0 = 0.0; if (!model->BSIM4v4wdvt1Given) - model->BSIM4v4wdvt1 = 0.0; + model->BSIM4v4wdvt1 = 0.0; if (!model->BSIM4v4wdvt2Given) model->BSIM4v4wdvt2 = 0.0; if (!model->BSIM4v4wdvt0wGiven) - model->BSIM4v4wdvt0w = 0.0; + model->BSIM4v4wdvt0w = 0.0; if (!model->BSIM4v4wdvt1wGiven) - model->BSIM4v4wdvt1w = 0.0; + model->BSIM4v4wdvt1w = 0.0; if (!model->BSIM4v4wdvt2wGiven) model->BSIM4v4wdvt2w = 0.0; if (!model->BSIM4v4wdroutGiven) - model->BSIM4v4wdrout = 0.0; + model->BSIM4v4wdrout = 0.0; if (!model->BSIM4v4wdsubGiven) model->BSIM4v4wdsub = 0.0; if (!model->BSIM4v4wvth0Given) @@ -838,9 +905,9 @@ JOB *job; if (!model->BSIM4v4wu0Given) model->BSIM4v4wu0 = 0.0; if (!model->BSIM4v4wuteGiven) - model->BSIM4v4wute = 0.0; + model->BSIM4v4wute = 0.0; if (!model->BSIM4v4wvoffGiven) - model->BSIM4v4wvoff = 0.0; + model->BSIM4v4wvoff = 0.0; if (!model->BSIM4v4wminvGiven) model->BSIM4v4wminv = 0.0; if (!model->BSIM4v4wfproutGiven) @@ -849,7 +916,7 @@ JOB *job; model->BSIM4v4wpdits = 0.0; if (!model->BSIM4v4wpditsdGiven) model->BSIM4v4wpditsd = 0.0; - if (!model->BSIM4v4wdeltaGiven) + if (!model->BSIM4v4wdeltaGiven) model->BSIM4v4wdelta = 0.0; if (!model->BSIM4v4wrdswGiven) model->BSIM4v4wrdsw = 0.0; @@ -868,7 +935,7 @@ JOB *job; if (!model->BSIM4v4wetabGiven) model->BSIM4v4wetab = 0.0; if (!model->BSIM4v4wpclmGiven) - model->BSIM4v4wpclm = 0.0; + model->BSIM4v4wpclm = 0.0; if (!model->BSIM4v4wpdibl1Given) model->BSIM4v4wpdibl1 = 0.0; if (!model->BSIM4v4wpdibl2Given) @@ -880,22 +947,22 @@ JOB *job; if (!model->BSIM4v4wpscbe2Given) model->BSIM4v4wpscbe2 = 0.0; if (!model->BSIM4v4wpvagGiven) - model->BSIM4v4wpvag = 0.0; - if (!model->BSIM4v4wwrGiven) + model->BSIM4v4wpvag = 0.0; + if (!model->BSIM4v4wwrGiven) model->BSIM4v4wwr = 0.0; - if (!model->BSIM4v4wdwgGiven) + if (!model->BSIM4v4wdwgGiven) model->BSIM4v4wdwg = 0.0; - if (!model->BSIM4v4wdwbGiven) + if (!model->BSIM4v4wdwbGiven) model->BSIM4v4wdwb = 0.0; if (!model->BSIM4v4wb0Given) model->BSIM4v4wb0 = 0.0; - if (!model->BSIM4v4wb1Given) + if (!model->BSIM4v4wb1Given) model->BSIM4v4wb1 = 0.0; - if (!model->BSIM4v4walpha0Given) + if (!model->BSIM4v4walpha0Given) model->BSIM4v4walpha0 = 0.0; if (!model->BSIM4v4walpha1Given) model->BSIM4v4walpha1 = 0.0; - if (!model->BSIM4v4wbeta0Given) + if (!model->BSIM4v4wbeta0Given) model->BSIM4v4wbeta0 = 0.0; if (!model->BSIM4v4wagidlGiven) model->BSIM4v4wagidl = 0.0; @@ -951,30 +1018,35 @@ JOB *job; model->BSIM4v4weu = 0.0; if (!model->BSIM4v4wvfbGiven) model->BSIM4v4wvfb = 0.0; - if (!model->BSIM4v4wlambdaGiven) - model->BSIM4v4wlambda = 0.0; - if (!model->BSIM4v4wvtlGiven) - model->BSIM4v4wvtl = 0.0; - if (!model->BSIM4v4wxnGiven) - model->BSIM4v4wxn = 0.0; - if (!model->BSIM4v4wvfbsdoffGiven) - model->BSIM4v4wvfbsdoff = 0.0; - - if (!model->BSIM4v4wcgslGiven) + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: + case BSIM4v21: + break; + case BSIM4v40: + if (!model->BSIM4v4wlambdaGiven) + model->BSIM4v4wlambda = 0.0; + if (!model->BSIM4v4wvtlGiven) + model->BSIM4v4wvtl = 0.0; + if (!model->BSIM4v4wxnGiven) + model->BSIM4v4wxn = 0.0; + break; + default: break; + } + if (!model->BSIM4v4wcgslGiven) model->BSIM4v4wcgsl = 0.0; - if (!model->BSIM4v4wcgdlGiven) + if (!model->BSIM4v4wcgdlGiven) model->BSIM4v4wcgdl = 0.0; - if (!model->BSIM4v4wckappasGiven) + if (!model->BSIM4v4wckappasGiven) model->BSIM4v4wckappas = 0.0; if (!model->BSIM4v4wckappadGiven) model->BSIM4v4wckappad = 0.0; - if (!model->BSIM4v4wcfGiven) + if (!model->BSIM4v4wcfGiven) model->BSIM4v4wcf = 0.0; - if (!model->BSIM4v4wclcGiven) + if (!model->BSIM4v4wclcGiven) model->BSIM4v4wclc = 0.0; - if (!model->BSIM4v4wcleGiven) + if (!model->BSIM4v4wcleGiven) model->BSIM4v4wcle = 0.0; - if (!model->BSIM4v4wvfbcvGiven) + if (!model->BSIM4v4wvfbcvGiven) model->BSIM4v4wvfbcv = 0.0; if (!model->BSIM4v4wacdeGiven) model->BSIM4v4wacde = 0.0; @@ -985,17 +1057,17 @@ JOB *job; if (!model->BSIM4v4wvoffcvGiven) model->BSIM4v4wvoffcv = 0.0; - /* Cross-term dependence */ + /* Cross-term dependence */ if (!model->BSIM4v4pcdscGiven) - model->BSIM4v4pcdsc = 0.0; + model->BSIM4v4pcdsc = 0.0; if (!model->BSIM4v4pcdscbGiven) - model->BSIM4v4pcdscb = 0.0; - if (!model->BSIM4v4pcdscdGiven) - model->BSIM4v4pcdscd = 0.0; + model->BSIM4v4pcdscb = 0.0; + if (!model->BSIM4v4pcdscdGiven) + model->BSIM4v4pcdscd = 0.0; if (!model->BSIM4v4pcitGiven) - model->BSIM4v4pcit = 0.0; + model->BSIM4v4pcit = 0.0; if (!model->BSIM4v4pnfactorGiven) - model->BSIM4v4pnfactor = 0.0; + model->BSIM4v4pnfactor = 0.0; if (!model->BSIM4v4pxjGiven) model->BSIM4v4pxj = 0.0; if (!model->BSIM4v4pvsatGiven) @@ -1003,8 +1075,8 @@ JOB *job; if (!model->BSIM4v4patGiven) model->BSIM4v4pat = 0.0; if (!model->BSIM4v4pa0Given) - model->BSIM4v4pa0 = 0.0; - + model->BSIM4v4pa0 = 0.0; + if (!model->BSIM4v4pagsGiven) model->BSIM4v4pags = 0.0; if (!model->BSIM4v4pa1Given) @@ -1024,43 +1096,52 @@ JOB *job; if (!model->BSIM4v4pngateGiven) model->BSIM4v4pngate = 0.0; if (!model->BSIM4v4pvbmGiven) - model->BSIM4v4pvbm = 0.0; + model->BSIM4v4pvbm = 0.0; if (!model->BSIM4v4pxtGiven) - model->BSIM4v4pxt = 0.0; + model->BSIM4v4pxt = 0.0; if (!model->BSIM4v4pkt1Given) - model->BSIM4v4pkt1 = 0.0; + model->BSIM4v4pkt1 = 0.0; if (!model->BSIM4v4pkt1lGiven) model->BSIM4v4pkt1l = 0.0; if (!model->BSIM4v4pkt2Given) model->BSIM4v4pkt2 = 0.0; if (!model->BSIM4v4pk3Given) - model->BSIM4v4pk3 = 0.0; + model->BSIM4v4pk3 = 0.0; if (!model->BSIM4v4pk3bGiven) - model->BSIM4v4pk3b = 0.0; + model->BSIM4v4pk3b = 0.0; if (!model->BSIM4v4pw0Given) - model->BSIM4v4pw0 = 0.0; + model->BSIM4v4pw0 = 0.0; if (!model->BSIM4v4plpe0Given) model->BSIM4v4plpe0 = 0.0; - if (!model->BSIM4v4plpebGiven) - model->BSIM4v4plpeb = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + if (!model->BSIM4v4plpebGiven) + model->BSIM4v4plpeb = model->BSIM4v4plpe0; + break; + case BSIM4v40: + if (!model->BSIM4v4llpebGiven) + model->BSIM4v4plpeb = 0.0; + break; + default: break; + } if (!model->BSIM4v4pdvtp0Given) model->BSIM4v4pdvtp0 = 0.0; if (!model->BSIM4v4pdvtp1Given) model->BSIM4v4pdvtp1 = 0.0; if (!model->BSIM4v4pdvt0Given) - model->BSIM4v4pdvt0 = 0.0; + model->BSIM4v4pdvt0 = 0.0; if (!model->BSIM4v4pdvt1Given) - model->BSIM4v4pdvt1 = 0.0; + model->BSIM4v4pdvt1 = 0.0; if (!model->BSIM4v4pdvt2Given) model->BSIM4v4pdvt2 = 0.0; if (!model->BSIM4v4pdvt0wGiven) - model->BSIM4v4pdvt0w = 0.0; + model->BSIM4v4pdvt0w = 0.0; if (!model->BSIM4v4pdvt1wGiven) - model->BSIM4v4pdvt1w = 0.0; + model->BSIM4v4pdvt1w = 0.0; if (!model->BSIM4v4pdvt2wGiven) model->BSIM4v4pdvt2w = 0.0; if (!model->BSIM4v4pdroutGiven) - model->BSIM4v4pdrout = 0.0; + model->BSIM4v4pdrout = 0.0; if (!model->BSIM4v4pdsubGiven) model->BSIM4v4pdsub = 0.0; if (!model->BSIM4v4pvth0Given) @@ -1080,9 +1161,9 @@ JOB *job; if (!model->BSIM4v4pu0Given) model->BSIM4v4pu0 = 0.0; if (!model->BSIM4v4puteGiven) - model->BSIM4v4pute = 0.0; + model->BSIM4v4pute = 0.0; if (!model->BSIM4v4pvoffGiven) - model->BSIM4v4pvoff = 0.0; + model->BSIM4v4pvoff = 0.0; if (!model->BSIM4v4pminvGiven) model->BSIM4v4pminv = 0.0; if (!model->BSIM4v4pfproutGiven) @@ -1091,7 +1172,7 @@ JOB *job; model->BSIM4v4ppdits = 0.0; if (!model->BSIM4v4ppditsdGiven) model->BSIM4v4ppditsd = 0.0; - if (!model->BSIM4v4pdeltaGiven) + if (!model->BSIM4v4pdeltaGiven) model->BSIM4v4pdelta = 0.0; if (!model->BSIM4v4prdswGiven) model->BSIM4v4prdsw = 0.0; @@ -1110,7 +1191,7 @@ JOB *job; if (!model->BSIM4v4petabGiven) model->BSIM4v4petab = 0.0; if (!model->BSIM4v4ppclmGiven) - model->BSIM4v4ppclm = 0.0; + model->BSIM4v4ppclm = 0.0; if (!model->BSIM4v4ppdibl1Given) model->BSIM4v4ppdibl1 = 0.0; if (!model->BSIM4v4ppdibl2Given) @@ -1122,22 +1203,22 @@ JOB *job; if (!model->BSIM4v4ppscbe2Given) model->BSIM4v4ppscbe2 = 0.0; if (!model->BSIM4v4ppvagGiven) - model->BSIM4v4ppvag = 0.0; - if (!model->BSIM4v4pwrGiven) + model->BSIM4v4ppvag = 0.0; + if (!model->BSIM4v4pwrGiven) model->BSIM4v4pwr = 0.0; - if (!model->BSIM4v4pdwgGiven) + if (!model->BSIM4v4pdwgGiven) model->BSIM4v4pdwg = 0.0; - if (!model->BSIM4v4pdwbGiven) + if (!model->BSIM4v4pdwbGiven) model->BSIM4v4pdwb = 0.0; if (!model->BSIM4v4pb0Given) model->BSIM4v4pb0 = 0.0; - if (!model->BSIM4v4pb1Given) + if (!model->BSIM4v4pb1Given) model->BSIM4v4pb1 = 0.0; - if (!model->BSIM4v4palpha0Given) + if (!model->BSIM4v4palpha0Given) model->BSIM4v4palpha0 = 0.0; if (!model->BSIM4v4palpha1Given) model->BSIM4v4palpha1 = 0.0; - if (!model->BSIM4v4pbeta0Given) + if (!model->BSIM4v4pbeta0Given) model->BSIM4v4pbeta0 = 0.0; if (!model->BSIM4v4pagidlGiven) model->BSIM4v4pagidl = 0.0; @@ -1193,30 +1274,44 @@ JOB *job; model->BSIM4v4peu = 0.0; if (!model->BSIM4v4pvfbGiven) model->BSIM4v4pvfb = 0.0; - if (!model->BSIM4v4plambdaGiven) - model->BSIM4v4plambda = 0.0; - if (!model->BSIM4v4pvtlGiven) - model->BSIM4v4pvtl = 0.0; - if (!model->BSIM4v4pxnGiven) - model->BSIM4v4pxn = 0.0; - if (!model->BSIM4v4pvfbsdoffGiven) - model->BSIM4v4pvfbsdoff = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (!model->BSIM4v4plambdaGiven) + model->BSIM4v4plambda = 0.0; + if (!model->BSIM4v4pvtlGiven) + model->BSIM4v4pvtl = 0.0; + if (!model->BSIM4v4pxnGiven) + model->BSIM4v4pxn = 0.0; + break; + default: break; + } + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (!model->BSIM4v4pvfbsdoffGiven) + model->BSIM4v4pvfbsdoff = 0.0; + break; + default: break; + } - if (!model->BSIM4v4pcgslGiven) + if (!model->BSIM4v4pcgslGiven) model->BSIM4v4pcgsl = 0.0; - if (!model->BSIM4v4pcgdlGiven) + if (!model->BSIM4v4pcgdlGiven) model->BSIM4v4pcgdl = 0.0; - if (!model->BSIM4v4pckappasGiven) + if (!model->BSIM4v4pckappasGiven) model->BSIM4v4pckappas = 0.0; if (!model->BSIM4v4pckappadGiven) model->BSIM4v4pckappad = 0.0; - if (!model->BSIM4v4pcfGiven) + if (!model->BSIM4v4pcfGiven) model->BSIM4v4pcf = 0.0; - if (!model->BSIM4v4pclcGiven) + if (!model->BSIM4v4pclcGiven) model->BSIM4v4pclc = 0.0; - if (!model->BSIM4v4pcleGiven) + if (!model->BSIM4v4pcleGiven) model->BSIM4v4pcle = 0.0; - if (!model->BSIM4v4pvfbcvGiven) + if (!model->BSIM4v4pvfbcvGiven) model->BSIM4v4pvfbcv = 0.0; if (!model->BSIM4v4pacdeGiven) model->BSIM4v4pacde = 0.0; @@ -1226,94 +1321,100 @@ JOB *job; model->BSIM4v4pnoff = 0.0; if (!model->BSIM4v4pvoffcvGiven) model->BSIM4v4pvoffcv = 0.0; - - if (!model->BSIM4v4gamma1Given) - model->BSIM4v4gamma1 = 0.0; - if (!model->BSIM4v4lgamma1Given) - model->BSIM4v4lgamma1 = 0.0; - if (!model->BSIM4v4wgamma1Given) - model->BSIM4v4wgamma1 = 0.0; - if (!model->BSIM4v4pgamma1Given) - model->BSIM4v4pgamma1 = 0.0; - if (!model->BSIM4v4gamma2Given) - model->BSIM4v4gamma2 = 0.0; - if (!model->BSIM4v4lgamma2Given) - model->BSIM4v4lgamma2 = 0.0; - if (!model->BSIM4v4wgamma2Given) - model->BSIM4v4wgamma2 = 0.0; - if (!model->BSIM4v4pgamma2Given) - model->BSIM4v4pgamma2 = 0.0; - if (!model->BSIM4v4vbxGiven) - model->BSIM4v4vbx = 0.0; - if (!model->BSIM4v4lvbxGiven) - model->BSIM4v4lvbx = 0.0; - if (!model->BSIM4v4wvbxGiven) - model->BSIM4v4wvbx = 0.0; - if (!model->BSIM4v4pvbxGiven) - model->BSIM4v4pvbx = 0.0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + if (!model->BSIM4v4gamma1Given) + model->BSIM4v4gamma1 = 0.0; + if (!model->BSIM4v4lgamma1Given) + model->BSIM4v4lgamma1 = 0.0; + if (!model->BSIM4v4wgamma1Given) + model->BSIM4v4wgamma1 = 0.0; + if (!model->BSIM4v4pgamma1Given) + model->BSIM4v4pgamma1 = 0.0; + if (!model->BSIM4v4gamma2Given) + model->BSIM4v4gamma2 = 0.0; + if (!model->BSIM4v4lgamma2Given) + model->BSIM4v4lgamma2 = 0.0; + if (!model->BSIM4v4wgamma2Given) + model->BSIM4v4wgamma2 = 0.0; + if (!model->BSIM4v4pgamma2Given) + model->BSIM4v4pgamma2 = 0.0; + if (!model->BSIM4v4vbxGiven) + model->BSIM4v4vbx = 0.0; + if (!model->BSIM4v4lvbxGiven) + model->BSIM4v4lvbx = 0.0; + if (!model->BSIM4v4wvbxGiven) + model->BSIM4v4wvbx = 0.0; + if (!model->BSIM4v4pvbxGiven) + model->BSIM4v4pvbx = 0.0; + break; + default: break; + } /* unit degree celcius */ - if (!model->BSIM4v4tnomGiven) - model->BSIM4v4tnom = ckt->CKTnomTemp; - if (!model->BSIM4v4LintGiven) + if (!model->BSIM4v4tnomGiven) + model->BSIM4v4tnom = ckt->CKTnomTemp; + if (!model->BSIM4v4LintGiven) model->BSIM4v4Lint = 0.0; - if (!model->BSIM4v4LlGiven) + if (!model->BSIM4v4LlGiven) model->BSIM4v4Ll = 0.0; if (!model->BSIM4v4LlcGiven) model->BSIM4v4Llc = model->BSIM4v4Ll; - if (!model->BSIM4v4LlnGiven) + if (!model->BSIM4v4LlnGiven) model->BSIM4v4Lln = 1.0; - if (!model->BSIM4v4LwGiven) + if (!model->BSIM4v4LwGiven) model->BSIM4v4Lw = 0.0; if (!model->BSIM4v4LwcGiven) model->BSIM4v4Lwc = model->BSIM4v4Lw; - if (!model->BSIM4v4LwnGiven) + if (!model->BSIM4v4LwnGiven) model->BSIM4v4Lwn = 1.0; - if (!model->BSIM4v4LwlGiven) + if (!model->BSIM4v4LwlGiven) model->BSIM4v4Lwl = 0.0; if (!model->BSIM4v4LwlcGiven) model->BSIM4v4Lwlc = model->BSIM4v4Lwl; - if (!model->BSIM4v4LminGiven) + if (!model->BSIM4v4LminGiven) model->BSIM4v4Lmin = 0.0; - if (!model->BSIM4v4LmaxGiven) + if (!model->BSIM4v4LmaxGiven) model->BSIM4v4Lmax = 1.0; - if (!model->BSIM4v4WintGiven) + if (!model->BSIM4v4WintGiven) model->BSIM4v4Wint = 0.0; - if (!model->BSIM4v4WlGiven) + if (!model->BSIM4v4WlGiven) model->BSIM4v4Wl = 0.0; if (!model->BSIM4v4WlcGiven) model->BSIM4v4Wlc = model->BSIM4v4Wl; - if (!model->BSIM4v4WlnGiven) + if (!model->BSIM4v4WlnGiven) model->BSIM4v4Wln = 1.0; - if (!model->BSIM4v4WwGiven) + if (!model->BSIM4v4WwGiven) model->BSIM4v4Ww = 0.0; if (!model->BSIM4v4WwcGiven) model->BSIM4v4Wwc = model->BSIM4v4Ww; - if (!model->BSIM4v4WwnGiven) + if (!model->BSIM4v4WwnGiven) model->BSIM4v4Wwn = 1.0; - if (!model->BSIM4v4WwlGiven) + if (!model->BSIM4v4WwlGiven) model->BSIM4v4Wwl = 0.0; if (!model->BSIM4v4WwlcGiven) model->BSIM4v4Wwlc = model->BSIM4v4Wwl; - if (!model->BSIM4v4WminGiven) + if (!model->BSIM4v4WminGiven) model->BSIM4v4Wmin = 0.0; - if (!model->BSIM4v4WmaxGiven) + if (!model->BSIM4v4WmaxGiven) model->BSIM4v4Wmax = 1.0; - if (!model->BSIM4v4dwcGiven) + if (!model->BSIM4v4dwcGiven) model->BSIM4v4dwc = model->BSIM4v4Wint; - if (!model->BSIM4v4dlcGiven) + if (!model->BSIM4v4dlcGiven) model->BSIM4v4dlc = model->BSIM4v4Lint; - if (!model->BSIM4v4xlGiven) + if (!model->BSIM4v4xlGiven) model->BSIM4v4xl = 0.0; - if (!model->BSIM4v4xwGiven) + if (!model->BSIM4v4xwGiven) model->BSIM4v4xw = 0.0; if (!model->BSIM4v4dlcigGiven) model->BSIM4v4dlcig = model->BSIM4v4Lint; if (!model->BSIM4v4dwjGiven) model->BSIM4v4dwj = model->BSIM4v4dwc; - if (!model->BSIM4v4cfGiven) + if (!model->BSIM4v4cfGiven) model->BSIM4v4cf = 2.0 * model->BSIM4v4epsrox * EPS0 / PI - * log(1.0 + 0.4e-6 / model->BSIM4v4toxe); + * log(1.0 + 0.4e-6 / model->BSIM4v4toxe); if (!model->BSIM4v4xpartGiven) model->BSIM4v4xpart = 0.0; @@ -1377,67 +1478,18 @@ JOB *job; if (!model->BSIM4v4DjctTempExponentGiven) model->BSIM4v4DjctTempExponent = model->BSIM4v4SjctTempExponent; - if (!model->BSIM4v4jtssGiven) - model->BSIM4v4jtss = 0.0; - if (!model->BSIM4v4jtsdGiven) - model->BSIM4v4jtsd = model->BSIM4v4jtss; - if (!model->BSIM4v4jtsswsGiven) - model->BSIM4v4jtssws = 0.0; - if (!model->BSIM4v4jtsswdGiven) - model->BSIM4v4jtsswd = model->BSIM4v4jtssws; - if (!model->BSIM4v4jtsswgsGiven) - model->BSIM4v4jtsswgs = 0.0; - if (!model->BSIM4v4jtsswgdGiven) - model->BSIM4v4jtsswgd = model->BSIM4v4jtsswgs; - if (!model->BSIM4v4njtsGiven) - model->BSIM4v4njts = 20.0; - if (!model->BSIM4v4njtsswGiven) - model->BSIM4v4njtssw = 20.0; - if (!model->BSIM4v4njtsswgGiven) - model->BSIM4v4njtsswg = 20.0; - if (!model->BSIM4v4xtssGiven) - model->BSIM4v4xtss = 0.02; - if (!model->BSIM4v4xtsdGiven) - model->BSIM4v4xtsd = model->BSIM4v4xtss; - if (!model->BSIM4v4xtsswsGiven) - model->BSIM4v4xtssws = 0.02; - if (!model->BSIM4v4jtsswdGiven) - model->BSIM4v4xtsswd = model->BSIM4v4xtssws; - if (!model->BSIM4v4xtsswgsGiven) - model->BSIM4v4xtsswgs = 0.02; - if (!model->BSIM4v4xtsswgdGiven) - model->BSIM4v4xtsswgd = model->BSIM4v4xtsswgs; - if (!model->BSIM4v4tnjtsGiven) - model->BSIM4v4tnjts = 0.0; - if (!model->BSIM4v4tnjtsswGiven) - model->BSIM4v4tnjtssw = 0.0; - if (!model->BSIM4v4tnjtsswgGiven) - model->BSIM4v4tnjtsswg = 0.0; - if (!model->BSIM4v4vtssGiven) - model->BSIM4v4vtss = 10.0; - if (!model->BSIM4v4vtsdGiven) - model->BSIM4v4vtsd = model->BSIM4v4vtss; - if (!model->BSIM4v4vtsswsGiven) - model->BSIM4v4vtssws = 10.0; - if (!model->BSIM4v4vtsswdGiven) - model->BSIM4v4vtsswd = model->BSIM4v4vtssws; - if (!model->BSIM4v4vtsswgsGiven) - model->BSIM4v4vtsswgs = 10.0; - if (!model->BSIM4v4vtsswgdGiven) - model->BSIM4v4vtsswgd = model->BSIM4v4vtsswgs; - if (!model->BSIM4v4oxideTrapDensityAGiven) - { if (model->BSIM4v4type == NMOS) + { if (model->BSIM4v4type == NMOS) model->BSIM4v4oxideTrapDensityA = 6.25e41; else model->BSIM4v4oxideTrapDensityA= 6.188e40; - } + } if (!model->BSIM4v4oxideTrapDensityBGiven) - { if (model->BSIM4v4type == NMOS) + { if (model->BSIM4v4type == NMOS) model->BSIM4v4oxideTrapDensityB = 3.125e26; else model->BSIM4v4oxideTrapDensityB = 1.5e25; - } + } if (!model->BSIM4v4oxideTrapDensityCGiven) model->BSIM4v4oxideTrapDensityC = 8.75e9; if (!model->BSIM4v4emGiven) @@ -1448,68 +1500,72 @@ JOB *job; model->BSIM4v4af = 1.0; if (!model->BSIM4v4kfGiven) model->BSIM4v4kf = 0.0; - - /* stress effect */ - if (!model->BSIM4v4sarefGiven) - model->BSIM4v4saref = 1e-6; /* m */ - if (!model->BSIM4v4sbrefGiven) - model->BSIM4v4sbref = 1e-6; /* m */ - if (!model->BSIM4v4wlodGiven) - model->BSIM4v4wlod = 0; /* m */ - if (!model->BSIM4v4ku0Given) - model->BSIM4v4ku0 = 0; /* 1/m */ - if (!model->BSIM4v4kvsatGiven) - model->BSIM4v4kvsat = 0; - if (!model->BSIM4v4kvth0Given) /* m */ - model->BSIM4v4kvth0 = 0; - if (!model->BSIM4v4tku0Given) - model->BSIM4v4tku0 = 0; - if (!model->BSIM4v4llodku0Given) - model->BSIM4v4llodku0 = 0; - if (!model->BSIM4v4wlodku0Given) - model->BSIM4v4wlodku0 = 0; - if (!model->BSIM4v4llodvthGiven) - model->BSIM4v4llodvth = 0; - if (!model->BSIM4v4wlodvthGiven) - model->BSIM4v4wlodvth = 0; - if (!model->BSIM4v4lku0Given) - model->BSIM4v4lku0 = 0; - if (!model->BSIM4v4wku0Given) - model->BSIM4v4wku0 = 0; - if (!model->BSIM4v4pku0Given) - model->BSIM4v4pku0 = 0; - if (!model->BSIM4v4lkvth0Given) - model->BSIM4v4lkvth0 = 0; - if (!model->BSIM4v4wkvth0Given) - model->BSIM4v4wkvth0 = 0; - if (!model->BSIM4v4pkvth0Given) - model->BSIM4v4pkvth0 = 0; - if (!model->BSIM4v4stk2Given) - model->BSIM4v4stk2 = 0; - if (!model->BSIM4v4lodk2Given) - model->BSIM4v4lodk2 = 1.0; - if (!model->BSIM4v4steta0Given) - model->BSIM4v4steta0 = 0; - if (!model->BSIM4v4lodeta0Given) - model->BSIM4v4lodeta0 = 1.0; - + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + /* stress effect */ + if (!model->BSIM4v4sarefGiven) + model->BSIM4v4saref = 1e-6; /* m */ + if (!model->BSIM4v4sbrefGiven) + model->BSIM4v4sbref = 1e-6; /* m */ + if (!model->BSIM4v4wlodGiven) + model->BSIM4v4wlod = 0; /* m */ + if (!model->BSIM4v4ku0Given) + model->BSIM4v4ku0 = 0; /* 1/m */ + if (!model->BSIM4v4kvsatGiven) + model->BSIM4v4kvsat = 0; + if (!model->BSIM4v4kvth0Given) /* m */ + model->BSIM4v4kvth0 = 0; + if (!model->BSIM4v4tku0Given) + model->BSIM4v4tku0 = 0; + if (!model->BSIM4v4llodku0Given) + model->BSIM4v4llodku0 = 0; + if (!model->BSIM4v4wlodku0Given) + model->BSIM4v4wlodku0 = 0; + if (!model->BSIM4v4llodvthGiven) + model->BSIM4v4llodvth = 0; + if (!model->BSIM4v4wlodvthGiven) + model->BSIM4v4wlodvth = 0; + if (!model->BSIM4v4lku0Given) + model->BSIM4v4lku0 = 0; + if (!model->BSIM4v4wku0Given) + model->BSIM4v4wku0 = 0; + if (!model->BSIM4v4pku0Given) + model->BSIM4v4pku0 = 0; + if (!model->BSIM4v4lkvth0Given) + model->BSIM4v4lkvth0 = 0; + if (!model->BSIM4v4wkvth0Given) + model->BSIM4v4wkvth0 = 0; + if (!model->BSIM4v4pkvth0Given) + model->BSIM4v4pkvth0 = 0; + if (!model->BSIM4v4stk2Given) + model->BSIM4v4stk2 = 0; + if (!model->BSIM4v4lodk2Given) + model->BSIM4v4lodk2 = 1.0; + if (!model->BSIM4v4steta0Given) + model->BSIM4v4steta0 = 0; + if (!model->BSIM4v4lodeta0Given) + model->BSIM4v4lodeta0 = 1.0; + break; + default: break; + } DMCGeff = model->BSIM4v4dmcg - model->BSIM4v4dmcgt; DMCIeff = model->BSIM4v4dmci; DMDGeff = model->BSIM4v4dmdg - model->BSIM4v4dmcgt; - /* + /* * End processing models and begin to loop * through all the instances of the model */ for (here = model->BSIM4v4instances; here != NULL ; - here=here->BSIM4v4nextInstance) - { - if (here->BSIM4v4owner == ARCHme) { - /* allocate a chunk of the state vector */ - here->BSIM4v4states = *states; - *states += BSIM4v4numStates; - } + here=here->BSIM4v4nextInstance) + { /* allocate a chunk of the state vector */ + if ( here->BSIM4v4owner == ARCHme) { + here->BSIM4v4states = *states; + *states += BSIM4v4numStates; + } /* perform the parameter defaulting */ if (!here->BSIM4v4lGiven) here->BSIM4v4l = 5.0e-6; @@ -1539,14 +1595,19 @@ JOB *job; here->BSIM4v4sourcePerimeter = 0.0; if (!here->BSIM4v4sourceSquaresGiven) here->BSIM4v4sourceSquares = 1.0; - - if (!here->BSIM4v4saGiven) - here->BSIM4v4sa = 0.0; - if (!here->BSIM4v4sbGiven) - here->BSIM4v4sb = 0.0; - if (!here->BSIM4v4sdGiven) - here->BSIM4v4sd = 0.0; - + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if (!here->BSIM4v4saGiven) + here->BSIM4v4sa = 0.0; + if (!here->BSIM4v4sbGiven) + here->BSIM4v4sb = 0.0; + if (!here->BSIM4v4sdGiven) + here->BSIM4v4sd = 0.0; + break; + default: break; + } if (!here->BSIM4v4rbdbGiven) here->BSIM4v4rbdb = model->BSIM4v4rbdb; /* in ohm */ if (!here->BSIM4v4rbsbGiven) @@ -1558,22 +1619,22 @@ JOB *job; if (!here->BSIM4v4rbpdGiven) here->BSIM4v4rbpd = model->BSIM4v4rbpd; - + /* Process instance model selectors, some * may override their global counterparts - */ + */ if (!here->BSIM4v4rbodyModGiven) here->BSIM4v4rbodyMod = model->BSIM4v4rbodyMod; else if ((here->BSIM4v4rbodyMod != 0) && (here->BSIM4v4rbodyMod != 1)) { here->BSIM4v4rbodyMod = model->BSIM4v4rbodyMod; printf("Warning: rbodyMod has been set to its global value %d.\n", - model->BSIM4v4rbodyMod); + model->BSIM4v4rbodyMod); } if (!here->BSIM4v4rgateModGiven) here->BSIM4v4rgateMod = model->BSIM4v4rgateMod; else if ((here->BSIM4v4rgateMod != 0) && (here->BSIM4v4rgateMod != 1) - && (here->BSIM4v4rgateMod != 2) && (here->BSIM4v4rgateMod != 3)) + && (here->BSIM4v4rgateMod != 2) && (here->BSIM4v4rgateMod != 3)) { here->BSIM4v4rgateMod = model->BSIM4v4rgateMod; printf("Warning: rgateMod has been set to its global value %d.\n", model->BSIM4v4rgateMod); @@ -1599,15 +1660,6 @@ JOB *job; model->BSIM4v4acnqsMod); } - /* stress effect */ - if (!here->BSIM4v4saGiven) - here->BSIM4v4sa = 0.0; - if (!here->BSIM4v4sbGiven) - here->BSIM4v4sb = 0.0; - if (!here->BSIM4v4sdGiven) - here->BSIM4v4sd = 0.0; - - /* process drain series resistance */ createNode = 0; if ( (model->BSIM4v4rdsMod != 0) @@ -1623,7 +1675,7 @@ JOB *job; } else if (!here->BSIM4v4drainSquaresGiven && (here->BSIM4v4rgeoMod != 0)) { - BSIM4v4RdseffGeo(here->BSIM4v4nf*here->BSIM4v4m, here->BSIM4v4geoMod, + BSIM4v4RdseffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4rgeoMod, here->BSIM4v4min, here->BSIM4v4w, model->BSIM4v4sheetResistance, DMCGeff, DMCIeff, DMDGeff, 0, &Rtot); @@ -1635,24 +1687,11 @@ JOB *job; { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"drain"); if(error) return(error); here->BSIM4v4dNodePrime = tmp->number; - - if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; - if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - -} - } else { here->BSIM4v4dNodePrime = here->BSIM4v4dNode; } - + /* process source series resistance */ createNode = 0; if ( (model->BSIM4v4rdsMod != 0) @@ -1668,7 +1707,7 @@ JOB *job; } else if (!here->BSIM4v4sourceSquaresGiven && (here->BSIM4v4rgeoMod != 0)) { - BSIM4v4RdseffGeo(here->BSIM4v4nf*here->BSIM4v4m, here->BSIM4v4geoMod, + BSIM4v4RdseffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4rgeoMod, here->BSIM4v4min, here->BSIM4v4w, model->BSIM4v4sheetResistance, DMCGeff, DMCIeff, DMDGeff, 1, &Rtot); @@ -1680,18 +1719,6 @@ JOB *job; { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"source"); if(error) return(error); here->BSIM4v4sNodePrime = tmp->number; - - if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; - if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } - } else here->BSIM4v4sNodePrime = here->BSIM4v4sNode; @@ -1700,18 +1727,6 @@ JOB *job; { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"gate"); if(error) return(error); here->BSIM4v4gNodePrime = tmp->number; - - if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; - if (CKTinst2Node(ckt,here,2,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } - } else here->BSIM4v4gNodePrime = here->BSIM4v4gNodeExt; @@ -1723,62 +1738,40 @@ JOB *job; } else here->BSIM4v4gNodeMid = here->BSIM4v4gNodeExt; - + /* internal body nodes for body resistance model */ if (here->BSIM4v4rbodyMod) { if (here->BSIM4v4dbNode == 0) - { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"dbody"); + { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"dbody"); if(error) return(error); here->BSIM4v4dbNode = tmp->number; - - if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; - if (CKTinst2Node(ckt,here,4,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } - } - if (here->BSIM4v4bNodePrime == 0) + } + if (here->BSIM4v4bNodePrime == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"body"); if(error) return(error); here->BSIM4v4bNodePrime = tmp->number; } - if (here->BSIM4v4sbNode == 0) + if (here->BSIM4v4sbNode == 0) { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"sbody"); if(error) return(error); here->BSIM4v4sbNode = tmp->number; } } - else - here->BSIM4v4dbNode = here->BSIM4v4bNodePrime = here->BSIM4v4sbNode - = here->BSIM4v4bNode; + else + here->BSIM4v4dbNode = here->BSIM4v4bNodePrime = here->BSIM4v4sbNode + = here->BSIM4v4bNode; /* NQS node */ - if ((here->BSIM4v4trnqsMod) && (here->BSIM4v4qNode == 0)) - { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"charge"); + if ((here->BSIM4v4trnqsMod) && (here->BSIM4v4qNode == 0)) + { error = CKTmkVolt(ckt,&tmp,here->BSIM4v4name,"charge"); if(error) return(error); here->BSIM4v4qNode = tmp->number; - - if (ckt->CKTcopyNodesets) { - CKTnode *tmpNode; - IFuid tmpName; - if (CKTinst2Node(ckt,here,5,&tmpNode,&tmpName)==OK) { - if (tmpNode->nsGiven) { - tmp->nodeset=tmpNode->nodeset; - tmp->nsGiven=tmpNode->nsGiven; - } - } - } } - else - here->BSIM4v4qNode = 0; + else + here->BSIM4v4qNode = 0; -/* set Sparse Matrix Pointers +/* set Sparse Matrix Pointers * macro to make elements with built-in out-of-memory test */ #define TSTALLOC(ptr,first,second) \ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ @@ -1811,7 +1804,7 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(BSIM4v4SPdpPtr, BSIM4v4sNodePrime, BSIM4v4dNodePrime) TSTALLOC(BSIM4v4QqPtr, BSIM4v4qNode, BSIM4v4qNode) - TSTALLOC(BSIM4v4QbpPtr, BSIM4v4qNode, BSIM4v4bNodePrime) + TSTALLOC(BSIM4v4QbpPtr, BSIM4v4qNode, BSIM4v4bNodePrime) TSTALLOC(BSIM4v4QdpPtr, BSIM4v4qNode, BSIM4v4dNodePrime) TSTALLOC(BSIM4v4QspPtr, BSIM4v4qNode, BSIM4v4sNodePrime) TSTALLOC(BSIM4v4QgpPtr, BSIM4v4qNode, BSIM4v4gNodePrime) @@ -1823,9 +1816,9 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ { TSTALLOC(BSIM4v4GEgePtr, BSIM4v4gNodeExt, BSIM4v4gNodeExt) TSTALLOC(BSIM4v4GEgpPtr, BSIM4v4gNodeExt, BSIM4v4gNodePrime) TSTALLOC(BSIM4v4GPgePtr, BSIM4v4gNodePrime, BSIM4v4gNodeExt) - TSTALLOC(BSIM4v4GEdpPtr, BSIM4v4gNodeExt, BSIM4v4dNodePrime) - TSTALLOC(BSIM4v4GEspPtr, BSIM4v4gNodeExt, BSIM4v4sNodePrime) - TSTALLOC(BSIM4v4GEbpPtr, BSIM4v4gNodeExt, BSIM4v4bNodePrime) + TSTALLOC(BSIM4v4GEdpPtr, BSIM4v4gNodeExt, BSIM4v4dNodePrime) + TSTALLOC(BSIM4v4GEspPtr, BSIM4v4gNodeExt, BSIM4v4sNodePrime) + TSTALLOC(BSIM4v4GEbpPtr, BSIM4v4gNodeExt, BSIM4v4bNodePrime) TSTALLOC(BSIM4v4GMdpPtr, BSIM4v4gNodeMid, BSIM4v4dNodePrime) TSTALLOC(BSIM4v4GMgpPtr, BSIM4v4gNodeMid, BSIM4v4gNodePrime) @@ -1838,7 +1831,7 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(BSIM4v4GEgmPtr, BSIM4v4gNodeExt, BSIM4v4gNodeMid) TSTALLOC(BSIM4v4SPgmPtr, BSIM4v4sNodePrime, BSIM4v4gNodeMid) TSTALLOC(BSIM4v4BPgmPtr, BSIM4v4bNodePrime, BSIM4v4gNodeMid) - } + } if (here->BSIM4v4rbodyMod) { TSTALLOC(BSIM4v4DPdbPtr, BSIM4v4dNodePrime, BSIM4v4dbNode) @@ -1861,12 +1854,12 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ TSTALLOC(BSIM4v4BdbPtr, BSIM4v4bNode, BSIM4v4dbNode) TSTALLOC(BSIM4v4BbpPtr, BSIM4v4bNode, BSIM4v4bNodePrime) TSTALLOC(BSIM4v4BsbPtr, BSIM4v4bNode, BSIM4v4sbNode) - TSTALLOC(BSIM4v4BbPtr, BSIM4v4bNode, BSIM4v4bNode) - } + TSTALLOC(BSIM4v4BbPtr, BSIM4v4bNode, BSIM4v4bNode) + } if (model->BSIM4v4rdsMod) { TSTALLOC(BSIM4v4DgpPtr, BSIM4v4dNode, BSIM4v4gNodePrime) - TSTALLOC(BSIM4v4DspPtr, BSIM4v4dNode, BSIM4v4sNodePrime) + TSTALLOC(BSIM4v4DspPtr, BSIM4v4dNode, BSIM4v4sNodePrime) TSTALLOC(BSIM4v4DbpPtr, BSIM4v4dNode, BSIM4v4bNodePrime) TSTALLOC(BSIM4v4SdpPtr, BSIM4v4sNode, BSIM4v4dNodePrime) TSTALLOC(BSIM4v4SgpPtr, BSIM4v4sNode, BSIM4v4gNodePrime) @@ -1875,14 +1868,14 @@ if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\ } } return(OK); -} +} int BSIM4v4unsetup( GENmodel *inModel, CKTcircuit *ckt) { - +#ifndef HAS_BATCHSIM BSIM4v4model *model; BSIM4v4instance *here; @@ -1906,5 +1899,6 @@ BSIM4v4unsetup( } } } +#endif return OK; } diff --git a/src/spicelib/devices/bsim4v4/b4v4temp.c b/src/spicelib/devices/bsim4v4/b4v4temp.c index bd81cd686..3ee9f86ee 100644 --- a/src/spicelib/devices/bsim4v4/b4v4temp.c +++ b/src/spicelib/devices/bsim4v4/b4v4temp.c @@ -1,5 +1,5 @@ /**** BSIM4.4.0 Released by Xuemei (Jane) Xi 03/04/2004 ****/ - +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** * Copyright 2004 Regents of the University of California. All rights reserved. * File: b4temp.c of BSIM4.4.0. @@ -42,7 +42,6 @@ } - static int BSIM4v4DioIjthVjmEval( double Nvtm, double Ijth, double Isb, double XExpBV, @@ -69,7 +68,7 @@ BSIM4v4instance *here; struct bsim4SizeDependParam *pSizeDependParamKnot, *pLastKnot, *pParam=NULL; double tmp, tmp1, tmp2, tmp3, Eg, Eg0, ni; double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Lnew=0.0, Wnew; -double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0, Tnom; +double delTemp, Temp, TRatio, Inv_L, Inv_W, Inv_LW, Vtm0=0.0, Tnom; double dumPs, dumPd, dumAs, dumAd, PowWeffWr; double DMCGeff, DMCIeff, DMDGeff; double Nvtms, Nvtmd, SourceSatCurrent, DrainSatCurrent; @@ -83,17 +82,17 @@ int Size_Not_Found, i; for (; model != NULL; model = model->BSIM4v4nextModel) { Temp = ckt->CKTtemp; if (model->BSIM4v4SbulkJctPotential < 0.1) - { model->BSIM4v4SbulkJctPotential = 0.1; - fprintf(stderr, "Given pbs is less than 0.1. Pbs is set to 0.1.\n"); - } + { model->BSIM4v4SbulkJctPotential = 0.1; + fprintf(stderr, "Given pbs is less than 0.1. Pbs is set to 0.1.\n"); + } if (model->BSIM4v4SsidewallJctPotential < 0.1) - { model->BSIM4v4SsidewallJctPotential = 0.1; - fprintf(stderr, "Given pbsws is less than 0.1. Pbsws is set to 0.1.\n"); - } + { model->BSIM4v4SsidewallJctPotential = 0.1; + fprintf(stderr, "Given pbsws is less than 0.1. Pbsws is set to 0.1.\n"); + } if (model->BSIM4v4SGatesidewallJctPotential < 0.1) - { model->BSIM4v4SGatesidewallJctPotential = 0.1; - fprintf(stderr, "Given pbswgs is less than 0.1. Pbswgs is set to 0.1.\n"); - } + { model->BSIM4v4SGatesidewallJctPotential = 0.1; + fprintf(stderr, "Given pbswgs is less than 0.1. Pbswgs is set to 0.1.\n"); + } if (model->BSIM4v4DbulkJctPotential < 0.1) { model->BSIM4v4DbulkJctPotential = 0.1; @@ -111,9 +110,9 @@ int Size_Not_Found, i; if ((model->BSIM4v4toxeGiven) && (model->BSIM4v4toxpGiven) && (model->BSIM4v4dtoxGiven) && (model->BSIM4v4toxe != (model->BSIM4v4toxp + model->BSIM4v4dtox))) printf("Warning: toxe, toxp and dtox all given and toxe != toxp + dtox; dtox ignored.\n"); - else if ((model->BSIM4v4toxeGiven) && (!model->BSIM4v4toxpGiven)) - model->BSIM4v4toxp = model->BSIM4v4toxe - model->BSIM4v4dtox; - else if ((!model->BSIM4v4toxeGiven) && (model->BSIM4v4toxpGiven)) + else if ((model->BSIM4v4toxeGiven) && (!model->BSIM4v4toxpGiven)) + model->BSIM4v4toxp = model->BSIM4v4toxe - model->BSIM4v4dtox; + else if ((!model->BSIM4v4toxeGiven) && (model->BSIM4v4toxpGiven)) model->BSIM4v4toxe = model->BSIM4v4toxp + model->BSIM4v4dtox; model->BSIM4v4coxe = model->BSIM4v4epsrox * EPS0 / model->BSIM4v4toxe; @@ -138,33 +137,41 @@ int Size_Not_Found, i; model->pSizeDependParamKnot = NULL; pLastKnot = NULL; - Tnom = model->BSIM4v4tnom; - TRatio = Temp / Tnom; + Tnom = model->BSIM4v4tnom; + TRatio = Temp / Tnom; - model->BSIM4v4vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); + model->BSIM4v4vcrit = CONSTvt0 * log(CONSTvt0 / (CONSTroot2 * 1.0e-14)); model->BSIM4v4factor1 = sqrt(EPSSI / (model->BSIM4v4epsrox * EPS0) * model->BSIM4v4toxe); - Vtm0 = model->BSIM4v4vtm0 = KboQ * Tnom; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + Vtm0 = KboQ * Tnom; + break; + case BSIM4v40: + Vtm0 = model->BSIM4v4vtm0 = KboQ * Tnom; + break; + default: break; + } Eg0 = 1.16 - 7.02e-4 * Tnom * Tnom / (Tnom + 1108.0); ni = 1.45e10 * (Tnom / 300.15) * sqrt(Tnom / 300.15) * exp(21.5565981 - Eg0 / (2.0 * Vtm0)); model->BSIM4v4vtm = KboQ * Temp; Eg = 1.16 - 7.02e-4 * Temp * Temp / (Temp + 1108.0); - if (Temp != Tnom) - { T0 = Eg0 / Vtm0 - Eg / model->BSIM4v4vtm; - T1 = log(Temp / Tnom); - T2 = T0 + model->BSIM4v4SjctTempExponent * T1; - T3 = exp(T2 / model->BSIM4v4SjctEmissionCoeff); - model->BSIM4v4SjctTempSatCurDensity = model->BSIM4v4SjctSatCurDensity - * T3; - model->BSIM4v4SjctSidewallTempSatCurDensity - = model->BSIM4v4SjctSidewallSatCurDensity * T3; + if (Temp != Tnom) + { T0 = Eg0 / Vtm0 - Eg / model->BSIM4v4vtm; + T1 = log(Temp / Tnom); + T2 = T0 + model->BSIM4v4SjctTempExponent * T1; + T3 = exp(T2 / model->BSIM4v4SjctEmissionCoeff); + model->BSIM4v4SjctTempSatCurDensity = model->BSIM4v4SjctSatCurDensity + * T3; + model->BSIM4v4SjctSidewallTempSatCurDensity + = model->BSIM4v4SjctSidewallSatCurDensity * T3; model->BSIM4v4SjctGateSidewallTempSatCurDensity = model->BSIM4v4SjctGateSidewallSatCurDensity * T3; - T2 = T0 + model->BSIM4v4DjctTempExponent * T1; + T2 = T0 + model->BSIM4v4DjctTempExponent * T1; T3 = exp(T2 / model->BSIM4v4DjctEmissionCoeff); model->BSIM4v4DjctTempSatCurDensity = model->BSIM4v4DjctSatCurDensity * T3; @@ -172,11 +179,11 @@ int Size_Not_Found, i; = model->BSIM4v4DjctSidewallSatCurDensity * T3; model->BSIM4v4DjctGateSidewallTempSatCurDensity = model->BSIM4v4DjctGateSidewallSatCurDensity * T3; - } - else - { model->BSIM4v4SjctTempSatCurDensity = model->BSIM4v4SjctSatCurDensity; - model->BSIM4v4SjctSidewallTempSatCurDensity - = model->BSIM4v4SjctSidewallSatCurDensity; + } + else + { model->BSIM4v4SjctTempSatCurDensity = model->BSIM4v4SjctSatCurDensity; + model->BSIM4v4SjctSidewallTempSatCurDensity + = model->BSIM4v4SjctSidewallSatCurDensity; model->BSIM4v4SjctGateSidewallTempSatCurDensity = model->BSIM4v4SjctGateSidewallSatCurDensity; model->BSIM4v4DjctTempSatCurDensity = model->BSIM4v4DjctSatCurDensity; @@ -184,12 +191,12 @@ int Size_Not_Found, i; = model->BSIM4v4DjctSidewallSatCurDensity; model->BSIM4v4DjctGateSidewallTempSatCurDensity = model->BSIM4v4DjctGateSidewallSatCurDensity; - } + } - if (model->BSIM4v4SjctTempSatCurDensity < 0.0) - model->BSIM4v4SjctTempSatCurDensity = 0.0; - if (model->BSIM4v4SjctSidewallTempSatCurDensity < 0.0) - model->BSIM4v4SjctSidewallTempSatCurDensity = 0.0; + if (model->BSIM4v4SjctTempSatCurDensity < 0.0) + model->BSIM4v4SjctTempSatCurDensity = 0.0; + if (model->BSIM4v4SjctSidewallTempSatCurDensity < 0.0) + model->BSIM4v4SjctSidewallTempSatCurDensity = 0.0; if (model->BSIM4v4SjctGateSidewallTempSatCurDensity < 0.0) model->BSIM4v4SjctGateSidewallTempSatCurDensity = 0.0; if (model->BSIM4v4DjctTempSatCurDensity < 0.0) @@ -199,60 +206,60 @@ int Size_Not_Found, i; if (model->BSIM4v4DjctGateSidewallTempSatCurDensity < 0.0) model->BSIM4v4DjctGateSidewallTempSatCurDensity = 0.0; - /* Temperature dependence of D/B and S/B diode capacitance begins */ - delTemp = ckt->CKTtemp - model->BSIM4v4tnom; - T0 = model->BSIM4v4tcj * delTemp; - if (T0 >= -1.0) - { model->BSIM4v4SunitAreaTempJctCap = model->BSIM4v4SunitAreaJctCap *(1.0 + T0); /*bug_fix -JX */ + /* Temperature dependence of D/B and S/B diode capacitance begins */ + delTemp = ckt->CKTtemp - model->BSIM4v4tnom; + T0 = model->BSIM4v4tcj * delTemp; + if (T0 >= -1.0) + { model->BSIM4v4SunitAreaTempJctCap = model->BSIM4v4SunitAreaJctCap *(1.0 + T0); /*bug_fix -JX */ model->BSIM4v4DunitAreaTempJctCap = model->BSIM4v4DunitAreaJctCap *(1.0 + T0); - } - else - { if (model->BSIM4v4SunitAreaJctCap > 0.0) - { model->BSIM4v4SunitAreaTempJctCap = 0.0; - fprintf(stderr, "Temperature effect has caused cjs to be negative. Cjs is clamped to zero.\n"); + } + else + { if (model->BSIM4v4SunitAreaJctCap > 0.0) + { model->BSIM4v4SunitAreaTempJctCap = 0.0; + fprintf(stderr, "Temperature effect has caused cjs to be negative. Cjs is clamped to zero.\n"); } - if (model->BSIM4v4DunitAreaJctCap > 0.0) + if (model->BSIM4v4DunitAreaJctCap > 0.0) { model->BSIM4v4DunitAreaTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjd to be negative. Cjd is clamped to zero.\n"); } - } + } T0 = model->BSIM4v4tcjsw * delTemp; - if (T0 >= -1.0) - { model->BSIM4v4SunitLengthSidewallTempJctCap = model->BSIM4v4SunitLengthSidewallJctCap *(1.0 + T0); + if (T0 >= -1.0) + { model->BSIM4v4SunitLengthSidewallTempJctCap = model->BSIM4v4SunitLengthSidewallJctCap *(1.0 + T0); model->BSIM4v4DunitLengthSidewallTempJctCap = model->BSIM4v4DunitLengthSidewallJctCap *(1.0 + T0); - } - else - { if (model->BSIM4v4SunitLengthSidewallJctCap > 0.0) - { model->BSIM4v4SunitLengthSidewallTempJctCap = 0.0; - fprintf(stderr, "Temperature effect has caused cjsws to be negative. Cjsws is clamped to zero.\n"); - } - if (model->BSIM4v4DunitLengthSidewallJctCap > 0.0) + } + else + { if (model->BSIM4v4SunitLengthSidewallJctCap > 0.0) + { model->BSIM4v4SunitLengthSidewallTempJctCap = 0.0; + fprintf(stderr, "Temperature effect has caused cjsws to be negative. Cjsws is clamped to zero.\n"); + } + if (model->BSIM4v4DunitLengthSidewallJctCap > 0.0) { model->BSIM4v4DunitLengthSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjswd to be negative. Cjswd is clamped to zero.\n"); - } - } + } + } T0 = model->BSIM4v4tcjswg * delTemp; - if (T0 >= -1.0) - { model->BSIM4v4SunitLengthGateSidewallTempJctCap = model->BSIM4v4SunitLengthGateSidewallJctCap *(1.0 + T0); + if (T0 >= -1.0) + { model->BSIM4v4SunitLengthGateSidewallTempJctCap = model->BSIM4v4SunitLengthGateSidewallJctCap *(1.0 + T0); model->BSIM4v4DunitLengthGateSidewallTempJctCap = model->BSIM4v4DunitLengthGateSidewallJctCap *(1.0 + T0); - } - else - { if (model->BSIM4v4SunitLengthGateSidewallJctCap > 0.0) - { model->BSIM4v4SunitLengthGateSidewallTempJctCap = 0.0; - fprintf(stderr, "Temperature effect has caused cjswgs to be negative. Cjswgs is clamped to zero.\n"); - } - if (model->BSIM4v4DunitLengthGateSidewallJctCap > 0.0) + } + else + { if (model->BSIM4v4SunitLengthGateSidewallJctCap > 0.0) + { model->BSIM4v4SunitLengthGateSidewallTempJctCap = 0.0; + fprintf(stderr, "Temperature effect has caused cjswgs to be negative. Cjswgs is clamped to zero.\n"); + } + if (model->BSIM4v4DunitLengthGateSidewallJctCap > 0.0) { model->BSIM4v4DunitLengthGateSidewallTempJctCap = 0.0; fprintf(stderr, "Temperature effect has caused cjswgd to be negative. Cjswgd is clamped to zero.\n"); } - } + } model->BSIM4v4PhiBS = model->BSIM4v4SbulkJctPotential - - model->BSIM4v4tpb * delTemp; + - model->BSIM4v4tpb * delTemp; if (model->BSIM4v4PhiBS < 0.01) - { model->BSIM4v4PhiBS = 0.01; - fprintf(stderr, "Temperature effect has caused pbs to be less than 0.01. Pbs is clamped to 0.01.\n"); - } + { model->BSIM4v4PhiBS = 0.01; + fprintf(stderr, "Temperature effect has caused pbs to be less than 0.01. Pbs is clamped to 0.01.\n"); + } model->BSIM4v4PhiBD = model->BSIM4v4DbulkJctPotential - model->BSIM4v4tpb * delTemp; if (model->BSIM4v4PhiBD < 0.01) @@ -263,9 +270,9 @@ int Size_Not_Found, i; model->BSIM4v4PhiBSWS = model->BSIM4v4SsidewallJctPotential - model->BSIM4v4tpbsw * delTemp; if (model->BSIM4v4PhiBSWS <= 0.01) - { model->BSIM4v4PhiBSWS = 0.01; - fprintf(stderr, "Temperature effect has caused pbsws to be less than 0.01. Pbsws is clamped to 0.01.\n"); - } + { model->BSIM4v4PhiBSWS = 0.01; + fprintf(stderr, "Temperature effect has caused pbsws to be less than 0.01. Pbsws is clamped to 0.01.\n"); + } model->BSIM4v4PhiBSWD = model->BSIM4v4DsidewallJctPotential - model->BSIM4v4tpbsw * delTemp; if (model->BSIM4v4PhiBSWD <= 0.01) @@ -273,12 +280,12 @@ int Size_Not_Found, i; fprintf(stderr, "Temperature effect has caused pbswd to be less than 0.01. Pbswd is clamped to 0.01.\n"); } - model->BSIM4v4PhiBSWGS = model->BSIM4v4SGatesidewallJctPotential + model->BSIM4v4PhiBSWGS = model->BSIM4v4SGatesidewallJctPotential - model->BSIM4v4tpbswg * delTemp; if (model->BSIM4v4PhiBSWGS <= 0.01) - { model->BSIM4v4PhiBSWGS = 0.01; - fprintf(stderr, "Temperature effect has caused pbswgs to be less than 0.01. Pbswgs is clamped to 0.01.\n"); - } + { model->BSIM4v4PhiBSWGS = 0.01; + fprintf(stderr, "Temperature effect has caused pbswgs to be less than 0.01. Pbswgs is clamped to 0.01.\n"); + } model->BSIM4v4PhiBSWGD = model->BSIM4v4DGatesidewallJctPotential - model->BSIM4v4tpbswg * delTemp; if (model->BSIM4v4PhiBSWGD <= 0.01) @@ -295,7 +302,7 @@ int Size_Not_Found, i; { model->BSIM4v4ijthsfwd = 0.1; fprintf(stderr, "Ijthsfwd reset to %g.\n", model->BSIM4v4ijthsfwd); } - if (model->BSIM4v4ijthdrev <= 0.0) + if (model->BSIM4v4ijthdrev <= 0.0) { model->BSIM4v4ijthdrev = 0.1; fprintf(stderr, "Ijthdrev reset to %g.\n", model->BSIM4v4ijthdrev); } @@ -336,38 +343,38 @@ int Size_Not_Found, i; /* loop through all the instances of the model */ for (here = model->BSIM4v4instances; here != NULL; here = here->BSIM4v4nextInstance) - { if (here->BSIM4v4owner != ARCHme) continue; - pSizeDependParamKnot = model->pSizeDependParamKnot; - Size_Not_Found = 1; - while ((pSizeDependParamKnot != NULL) && Size_Not_Found) - { if ((here->BSIM4v4l == pSizeDependParamKnot->Length) - && (here->BSIM4v4w == pSizeDependParamKnot->Width) - && (here->BSIM4v4nf == pSizeDependParamKnot->NFinger)) + { if (here->BSIM4v4owner != ARCHme) continue; + pSizeDependParamKnot = model->pSizeDependParamKnot; + Size_Not_Found = 1; + while ((pSizeDependParamKnot != NULL) && Size_Not_Found) + { if ((here->BSIM4v4l == pSizeDependParamKnot->Length) + && (here->BSIM4v4w == pSizeDependParamKnot->Width) + && (here->BSIM4v4nf == pSizeDependParamKnot->NFinger)) { Size_Not_Found = 0; - here->pParam = pSizeDependParamKnot; - pParam = here->pParam; /*bug-fix */ - } - else - { pLastKnot = pSizeDependParamKnot; - pSizeDependParamKnot = pSizeDependParamKnot->pNext; - } + here->pParam = pSizeDependParamKnot; + pParam = here->pParam; /*bug-fix */ + } + else + { pLastKnot = pSizeDependParamKnot; + pSizeDependParamKnot = pSizeDependParamKnot->pNext; + } } - /* stress effect */ - Ldrn = here->BSIM4v4l; + /* stress effect */ + Ldrn = here->BSIM4v4l; - if (Size_Not_Found) - { pParam = TMALLOC(struct bsim4SizeDependParam, 1); + if (Size_Not_Found) + { pParam = TMALLOC(struct bsim4SizeDependParam, 1); if (pLastKnot == NULL) - model->pSizeDependParamKnot = pParam; + model->pSizeDependParamKnot = pParam; else - pLastKnot->pNext = pParam; + pLastKnot->pNext = pParam; pParam->pNext = NULL; here->pParam = pParam; pParam->Length = here->BSIM4v4l; pParam->Width = here->BSIM4v4w; - pParam->NFinger = here->BSIM4v4nf; + pParam->NFinger = here->BSIM4v4nf; Lnew = here->BSIM4v4l + model->BSIM4v4xl ; Wnew = here->BSIM4v4w / here->BSIM4v4nf + model->BSIM4v4xw; @@ -379,7 +386,15 @@ int Size_Not_Found, i; tmp2 = model->BSIM4v4Llc / T0 + model->BSIM4v4Lwc / T1 + model->BSIM4v4Lwlc / (T0 * T1); pParam->BSIM4v4dlc = model->BSIM4v4dlc + tmp2; - pParam->BSIM4v4dlcig = model->BSIM4v4dlcig; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + pParam->BSIM4v4dlcig = model->BSIM4v4dlcig + tmp2; + break; + case BSIM4v40: + pParam->BSIM4v4dlcig = model->BSIM4v4dlcig; + break; + default: break; + } T2 = pow(Lnew, model->BSIM4v4Wln); T3 = pow(Wnew, model->BSIM4v4Wwn); @@ -393,7 +408,7 @@ int Size_Not_Found, i; pParam->BSIM4v4leff = Lnew - 2.0 * pParam->BSIM4v4dl; if (pParam->BSIM4v4leff <= 0.0) - { IFuid namarray[2]; + { IFuid namarray[2]; namarray[0] = model->BSIM4v4modName; namarray[1] = here->BSIM4v4name; SPfrontEnd->IFerror (ERR_FATAL, @@ -404,7 +419,7 @@ int Size_Not_Found, i; pParam->BSIM4v4weff = Wnew - 2.0 * pParam->BSIM4v4dw; if (pParam->BSIM4v4weff <= 0.0) - { IFuid namarray[2]; + { IFuid namarray[2]; namarray[0] = model->BSIM4v4modName; namarray[1] = here->BSIM4v4name; SPfrontEnd->IFerror (ERR_FATAL, @@ -415,20 +430,18 @@ int Size_Not_Found, i; pParam->BSIM4v4leffCV = Lnew - 2.0 * pParam->BSIM4v4dlc; if (pParam->BSIM4v4leffCV <= 0.0) - { IFuid namarray[2]; + { IFuid namarray[2]; namarray[0] = model->BSIM4v4modName; namarray[1] = here->BSIM4v4name; SPfrontEnd->IFerror (ERR_FATAL, "BSIM4v4: mosfet %s, model %s: Effective channel length for C-V <= 0", - namarray); - fprintf(stderr,"BSIM4v4: mosfet %s, model %s: Effective channel length for C-V <= 0 (Lnew - 2.0*BSIM4v4dlc == %g - 2.0*%g)\n", - model->BSIM4v4modName, here->BSIM4v4name, Lnew, pParam->BSIM4v4dlc ); + namarray); return(E_BADPARM); } pParam->BSIM4v4weffCV = Wnew - 2.0 * pParam->BSIM4v4dwc; if (pParam->BSIM4v4weffCV <= 0.0) - { IFuid namarray[2]; + { IFuid namarray[2]; namarray[0] = model->BSIM4v4modName; namarray[1] = here->BSIM4v4name; SPfrontEnd->IFerror (ERR_FATAL, @@ -449,82 +462,82 @@ int Size_Not_Found, i; } - if (model->BSIM4v4binUnit == 1) - { Inv_L = 1.0e-6 / pParam->BSIM4v4leff; - Inv_W = 1.0e-6 / pParam->BSIM4v4weff; - Inv_LW = 1.0e-12 / (pParam->BSIM4v4leff - * pParam->BSIM4v4weff); - } - else - { Inv_L = 1.0 / pParam->BSIM4v4leff; - Inv_W = 1.0 / pParam->BSIM4v4weff; - Inv_LW = 1.0 / (pParam->BSIM4v4leff - * pParam->BSIM4v4weff); - } - pParam->BSIM4v4cdsc = model->BSIM4v4cdsc - + model->BSIM4v4lcdsc * Inv_L - + model->BSIM4v4wcdsc * Inv_W - + model->BSIM4v4pcdsc * Inv_LW; - pParam->BSIM4v4cdscb = model->BSIM4v4cdscb - + model->BSIM4v4lcdscb * Inv_L - + model->BSIM4v4wcdscb * Inv_W - + model->BSIM4v4pcdscb * Inv_LW; - - pParam->BSIM4v4cdscd = model->BSIM4v4cdscd - + model->BSIM4v4lcdscd * Inv_L - + model->BSIM4v4wcdscd * Inv_W - + model->BSIM4v4pcdscd * Inv_LW; - - pParam->BSIM4v4cit = model->BSIM4v4cit - + model->BSIM4v4lcit * Inv_L - + model->BSIM4v4wcit * Inv_W - + model->BSIM4v4pcit * Inv_LW; - pParam->BSIM4v4nfactor = model->BSIM4v4nfactor - + model->BSIM4v4lnfactor * Inv_L - + model->BSIM4v4wnfactor * Inv_W - + model->BSIM4v4pnfactor * Inv_LW; - pParam->BSIM4v4xj = model->BSIM4v4xj - + model->BSIM4v4lxj * Inv_L - + model->BSIM4v4wxj * Inv_W - + model->BSIM4v4pxj * Inv_LW; - pParam->BSIM4v4vsat = model->BSIM4v4vsat - + model->BSIM4v4lvsat * Inv_L - + model->BSIM4v4wvsat * Inv_W - + model->BSIM4v4pvsat * Inv_LW; - pParam->BSIM4v4at = model->BSIM4v4at - + model->BSIM4v4lat * Inv_L - + model->BSIM4v4wat * Inv_W - + model->BSIM4v4pat * Inv_LW; - pParam->BSIM4v4a0 = model->BSIM4v4a0 - + model->BSIM4v4la0 * Inv_L - + model->BSIM4v4wa0 * Inv_W - + model->BSIM4v4pa0 * Inv_LW; - - pParam->BSIM4v4ags = model->BSIM4v4ags - + model->BSIM4v4lags * Inv_L - + model->BSIM4v4wags * Inv_W - + model->BSIM4v4pags * Inv_LW; - - pParam->BSIM4v4a1 = model->BSIM4v4a1 - + model->BSIM4v4la1 * Inv_L - + model->BSIM4v4wa1 * Inv_W - + model->BSIM4v4pa1 * Inv_LW; - pParam->BSIM4v4a2 = model->BSIM4v4a2 - + model->BSIM4v4la2 * Inv_L - + model->BSIM4v4wa2 * Inv_W - + model->BSIM4v4pa2 * Inv_LW; - pParam->BSIM4v4keta = model->BSIM4v4keta - + model->BSIM4v4lketa * Inv_L - + model->BSIM4v4wketa * Inv_W - + model->BSIM4v4pketa * Inv_LW; - pParam->BSIM4v4nsub = model->BSIM4v4nsub - + model->BSIM4v4lnsub * Inv_L - + model->BSIM4v4wnsub * Inv_W - + model->BSIM4v4pnsub * Inv_LW; - pParam->BSIM4v4ndep = model->BSIM4v4ndep - + model->BSIM4v4lndep * Inv_L - + model->BSIM4v4wndep * Inv_W - + model->BSIM4v4pndep * Inv_LW; + if (model->BSIM4v4binUnit == 1) + { Inv_L = 1.0e-6 / pParam->BSIM4v4leff; + Inv_W = 1.0e-6 / pParam->BSIM4v4weff; + Inv_LW = 1.0e-12 / (pParam->BSIM4v4leff + * pParam->BSIM4v4weff); + } + else + { Inv_L = 1.0 / pParam->BSIM4v4leff; + Inv_W = 1.0 / pParam->BSIM4v4weff; + Inv_LW = 1.0 / (pParam->BSIM4v4leff + * pParam->BSIM4v4weff); + } + pParam->BSIM4v4cdsc = model->BSIM4v4cdsc + + model->BSIM4v4lcdsc * Inv_L + + model->BSIM4v4wcdsc * Inv_W + + model->BSIM4v4pcdsc * Inv_LW; + pParam->BSIM4v4cdscb = model->BSIM4v4cdscb + + model->BSIM4v4lcdscb * Inv_L + + model->BSIM4v4wcdscb * Inv_W + + model->BSIM4v4pcdscb * Inv_LW; + + pParam->BSIM4v4cdscd = model->BSIM4v4cdscd + + model->BSIM4v4lcdscd * Inv_L + + model->BSIM4v4wcdscd * Inv_W + + model->BSIM4v4pcdscd * Inv_LW; + + pParam->BSIM4v4cit = model->BSIM4v4cit + + model->BSIM4v4lcit * Inv_L + + model->BSIM4v4wcit * Inv_W + + model->BSIM4v4pcit * Inv_LW; + pParam->BSIM4v4nfactor = model->BSIM4v4nfactor + + model->BSIM4v4lnfactor * Inv_L + + model->BSIM4v4wnfactor * Inv_W + + model->BSIM4v4pnfactor * Inv_LW; + pParam->BSIM4v4xj = model->BSIM4v4xj + + model->BSIM4v4lxj * Inv_L + + model->BSIM4v4wxj * Inv_W + + model->BSIM4v4pxj * Inv_LW; + pParam->BSIM4v4vsat = model->BSIM4v4vsat + + model->BSIM4v4lvsat * Inv_L + + model->BSIM4v4wvsat * Inv_W + + model->BSIM4v4pvsat * Inv_LW; + pParam->BSIM4v4at = model->BSIM4v4at + + model->BSIM4v4lat * Inv_L + + model->BSIM4v4wat * Inv_W + + model->BSIM4v4pat * Inv_LW; + pParam->BSIM4v4a0 = model->BSIM4v4a0 + + model->BSIM4v4la0 * Inv_L + + model->BSIM4v4wa0 * Inv_W + + model->BSIM4v4pa0 * Inv_LW; + + pParam->BSIM4v4ags = model->BSIM4v4ags + + model->BSIM4v4lags * Inv_L + + model->BSIM4v4wags * Inv_W + + model->BSIM4v4pags * Inv_LW; + + pParam->BSIM4v4a1 = model->BSIM4v4a1 + + model->BSIM4v4la1 * Inv_L + + model->BSIM4v4wa1 * Inv_W + + model->BSIM4v4pa1 * Inv_LW; + pParam->BSIM4v4a2 = model->BSIM4v4a2 + + model->BSIM4v4la2 * Inv_L + + model->BSIM4v4wa2 * Inv_W + + model->BSIM4v4pa2 * Inv_LW; + pParam->BSIM4v4keta = model->BSIM4v4keta + + model->BSIM4v4lketa * Inv_L + + model->BSIM4v4wketa * Inv_W + + model->BSIM4v4pketa * Inv_LW; + pParam->BSIM4v4nsub = model->BSIM4v4nsub + + model->BSIM4v4lnsub * Inv_L + + model->BSIM4v4wnsub * Inv_W + + model->BSIM4v4pnsub * Inv_LW; + pParam->BSIM4v4ndep = model->BSIM4v4ndep + + model->BSIM4v4lndep * Inv_L + + model->BSIM4v4wndep * Inv_W + + model->BSIM4v4pndep * Inv_LW; pParam->BSIM4v4nsd = model->BSIM4v4nsd + model->BSIM4v4lnsd * Inv_L + model->BSIM4v4wnsd * Inv_W @@ -533,70 +546,70 @@ int Size_Not_Found, i; + model->BSIM4v4lphin * Inv_L + model->BSIM4v4wphin * Inv_W + model->BSIM4v4pphin * Inv_LW; - pParam->BSIM4v4ngate = model->BSIM4v4ngate - + model->BSIM4v4lngate * Inv_L - + model->BSIM4v4wngate * Inv_W - + model->BSIM4v4pngate * Inv_LW; - pParam->BSIM4v4gamma1 = model->BSIM4v4gamma1 - + model->BSIM4v4lgamma1 * Inv_L - + model->BSIM4v4wgamma1 * Inv_W - + model->BSIM4v4pgamma1 * Inv_LW; - pParam->BSIM4v4gamma2 = model->BSIM4v4gamma2 - + model->BSIM4v4lgamma2 * Inv_L - + model->BSIM4v4wgamma2 * Inv_W - + model->BSIM4v4pgamma2 * Inv_LW; - pParam->BSIM4v4vbx = model->BSIM4v4vbx - + model->BSIM4v4lvbx * Inv_L - + model->BSIM4v4wvbx * Inv_W - + model->BSIM4v4pvbx * Inv_LW; - pParam->BSIM4v4vbm = model->BSIM4v4vbm - + model->BSIM4v4lvbm * Inv_L - + model->BSIM4v4wvbm * Inv_W - + model->BSIM4v4pvbm * Inv_LW; - pParam->BSIM4v4xt = model->BSIM4v4xt - + model->BSIM4v4lxt * Inv_L - + model->BSIM4v4wxt * Inv_W - + model->BSIM4v4pxt * Inv_LW; + pParam->BSIM4v4ngate = model->BSIM4v4ngate + + model->BSIM4v4lngate * Inv_L + + model->BSIM4v4wngate * Inv_W + + model->BSIM4v4pngate * Inv_LW; + pParam->BSIM4v4gamma1 = model->BSIM4v4gamma1 + + model->BSIM4v4lgamma1 * Inv_L + + model->BSIM4v4wgamma1 * Inv_W + + model->BSIM4v4pgamma1 * Inv_LW; + pParam->BSIM4v4gamma2 = model->BSIM4v4gamma2 + + model->BSIM4v4lgamma2 * Inv_L + + model->BSIM4v4wgamma2 * Inv_W + + model->BSIM4v4pgamma2 * Inv_LW; + pParam->BSIM4v4vbx = model->BSIM4v4vbx + + model->BSIM4v4lvbx * Inv_L + + model->BSIM4v4wvbx * Inv_W + + model->BSIM4v4pvbx * Inv_LW; + pParam->BSIM4v4vbm = model->BSIM4v4vbm + + model->BSIM4v4lvbm * Inv_L + + model->BSIM4v4wvbm * Inv_W + + model->BSIM4v4pvbm * Inv_LW; + pParam->BSIM4v4xt = model->BSIM4v4xt + + model->BSIM4v4lxt * Inv_L + + model->BSIM4v4wxt * Inv_W + + model->BSIM4v4pxt * Inv_LW; pParam->BSIM4v4vfb = model->BSIM4v4vfb + model->BSIM4v4lvfb * Inv_L + model->BSIM4v4wvfb * Inv_W + model->BSIM4v4pvfb * Inv_LW; - pParam->BSIM4v4k1 = model->BSIM4v4k1 - + model->BSIM4v4lk1 * Inv_L - + model->BSIM4v4wk1 * Inv_W - + model->BSIM4v4pk1 * Inv_LW; - pParam->BSIM4v4kt1 = model->BSIM4v4kt1 - + model->BSIM4v4lkt1 * Inv_L - + model->BSIM4v4wkt1 * Inv_W - + model->BSIM4v4pkt1 * Inv_LW; - pParam->BSIM4v4kt1l = model->BSIM4v4kt1l - + model->BSIM4v4lkt1l * Inv_L - + model->BSIM4v4wkt1l * Inv_W - + model->BSIM4v4pkt1l * Inv_LW; - pParam->BSIM4v4k2 = model->BSIM4v4k2 - + model->BSIM4v4lk2 * Inv_L - + model->BSIM4v4wk2 * Inv_W - + model->BSIM4v4pk2 * Inv_LW; - pParam->BSIM4v4kt2 = model->BSIM4v4kt2 - + model->BSIM4v4lkt2 * Inv_L - + model->BSIM4v4wkt2 * Inv_W - + model->BSIM4v4pkt2 * Inv_LW; - pParam->BSIM4v4k3 = model->BSIM4v4k3 - + model->BSIM4v4lk3 * Inv_L - + model->BSIM4v4wk3 * Inv_W - + model->BSIM4v4pk3 * Inv_LW; - pParam->BSIM4v4k3b = model->BSIM4v4k3b - + model->BSIM4v4lk3b * Inv_L - + model->BSIM4v4wk3b * Inv_W - + model->BSIM4v4pk3b * Inv_LW; - pParam->BSIM4v4w0 = model->BSIM4v4w0 - + model->BSIM4v4lw0 * Inv_L - + model->BSIM4v4ww0 * Inv_W - + model->BSIM4v4pw0 * Inv_LW; - pParam->BSIM4v4lpe0 = model->BSIM4v4lpe0 - + model->BSIM4v4llpe0 * Inv_L - + model->BSIM4v4wlpe0 * Inv_W - + model->BSIM4v4plpe0 * Inv_LW; + pParam->BSIM4v4k1 = model->BSIM4v4k1 + + model->BSIM4v4lk1 * Inv_L + + model->BSIM4v4wk1 * Inv_W + + model->BSIM4v4pk1 * Inv_LW; + pParam->BSIM4v4kt1 = model->BSIM4v4kt1 + + model->BSIM4v4lkt1 * Inv_L + + model->BSIM4v4wkt1 * Inv_W + + model->BSIM4v4pkt1 * Inv_LW; + pParam->BSIM4v4kt1l = model->BSIM4v4kt1l + + model->BSIM4v4lkt1l * Inv_L + + model->BSIM4v4wkt1l * Inv_W + + model->BSIM4v4pkt1l * Inv_LW; + pParam->BSIM4v4k2 = model->BSIM4v4k2 + + model->BSIM4v4lk2 * Inv_L + + model->BSIM4v4wk2 * Inv_W + + model->BSIM4v4pk2 * Inv_LW; + pParam->BSIM4v4kt2 = model->BSIM4v4kt2 + + model->BSIM4v4lkt2 * Inv_L + + model->BSIM4v4wkt2 * Inv_W + + model->BSIM4v4pkt2 * Inv_LW; + pParam->BSIM4v4k3 = model->BSIM4v4k3 + + model->BSIM4v4lk3 * Inv_L + + model->BSIM4v4wk3 * Inv_W + + model->BSIM4v4pk3 * Inv_LW; + pParam->BSIM4v4k3b = model->BSIM4v4k3b + + model->BSIM4v4lk3b * Inv_L + + model->BSIM4v4wk3b * Inv_W + + model->BSIM4v4pk3b * Inv_LW; + pParam->BSIM4v4w0 = model->BSIM4v4w0 + + model->BSIM4v4lw0 * Inv_L + + model->BSIM4v4ww0 * Inv_W + + model->BSIM4v4pw0 * Inv_LW; + pParam->BSIM4v4lpe0 = model->BSIM4v4lpe0 + + model->BSIM4v4llpe0 * Inv_L + + model->BSIM4v4wlpe0 * Inv_W + + model->BSIM4v4plpe0 * Inv_LW; pParam->BSIM4v4lpeb = model->BSIM4v4lpeb + model->BSIM4v4llpeb * Inv_L + model->BSIM4v4wlpeb * Inv_W @@ -609,82 +622,82 @@ int Size_Not_Found, i; + model->BSIM4v4ldvtp1 * Inv_L + model->BSIM4v4wdvtp1 * Inv_W + model->BSIM4v4pdvtp1 * Inv_LW; - pParam->BSIM4v4dvt0 = model->BSIM4v4dvt0 - + model->BSIM4v4ldvt0 * Inv_L - + model->BSIM4v4wdvt0 * Inv_W - + model->BSIM4v4pdvt0 * Inv_LW; - pParam->BSIM4v4dvt1 = model->BSIM4v4dvt1 - + model->BSIM4v4ldvt1 * Inv_L - + model->BSIM4v4wdvt1 * Inv_W - + model->BSIM4v4pdvt1 * Inv_LW; - pParam->BSIM4v4dvt2 = model->BSIM4v4dvt2 - + model->BSIM4v4ldvt2 * Inv_L - + model->BSIM4v4wdvt2 * Inv_W - + model->BSIM4v4pdvt2 * Inv_LW; - pParam->BSIM4v4dvt0w = model->BSIM4v4dvt0w - + model->BSIM4v4ldvt0w * Inv_L - + model->BSIM4v4wdvt0w * Inv_W - + model->BSIM4v4pdvt0w * Inv_LW; - pParam->BSIM4v4dvt1w = model->BSIM4v4dvt1w - + model->BSIM4v4ldvt1w * Inv_L - + model->BSIM4v4wdvt1w * Inv_W - + model->BSIM4v4pdvt1w * Inv_LW; - pParam->BSIM4v4dvt2w = model->BSIM4v4dvt2w - + model->BSIM4v4ldvt2w * Inv_L - + model->BSIM4v4wdvt2w * Inv_W - + model->BSIM4v4pdvt2w * Inv_LW; - pParam->BSIM4v4drout = model->BSIM4v4drout - + model->BSIM4v4ldrout * Inv_L - + model->BSIM4v4wdrout * Inv_W - + model->BSIM4v4pdrout * Inv_LW; - pParam->BSIM4v4dsub = model->BSIM4v4dsub - + model->BSIM4v4ldsub * Inv_L - + model->BSIM4v4wdsub * Inv_W - + model->BSIM4v4pdsub * Inv_LW; - pParam->BSIM4v4vth0 = model->BSIM4v4vth0 - + model->BSIM4v4lvth0 * Inv_L - + model->BSIM4v4wvth0 * Inv_W - + model->BSIM4v4pvth0 * Inv_LW; - pParam->BSIM4v4ua = model->BSIM4v4ua - + model->BSIM4v4lua * Inv_L - + model->BSIM4v4wua * Inv_W - + model->BSIM4v4pua * Inv_LW; - pParam->BSIM4v4ua1 = model->BSIM4v4ua1 - + model->BSIM4v4lua1 * Inv_L - + model->BSIM4v4wua1 * Inv_W - + model->BSIM4v4pua1 * Inv_LW; - pParam->BSIM4v4ub = model->BSIM4v4ub - + model->BSIM4v4lub * Inv_L - + model->BSIM4v4wub * Inv_W - + model->BSIM4v4pub * Inv_LW; - pParam->BSIM4v4ub1 = model->BSIM4v4ub1 - + model->BSIM4v4lub1 * Inv_L - + model->BSIM4v4wub1 * Inv_W - + model->BSIM4v4pub1 * Inv_LW; - pParam->BSIM4v4uc = model->BSIM4v4uc - + model->BSIM4v4luc * Inv_L - + model->BSIM4v4wuc * Inv_W - + model->BSIM4v4puc * Inv_LW; - pParam->BSIM4v4uc1 = model->BSIM4v4uc1 - + model->BSIM4v4luc1 * Inv_L - + model->BSIM4v4wuc1 * Inv_W - + model->BSIM4v4puc1 * Inv_LW; + pParam->BSIM4v4dvt0 = model->BSIM4v4dvt0 + + model->BSIM4v4ldvt0 * Inv_L + + model->BSIM4v4wdvt0 * Inv_W + + model->BSIM4v4pdvt0 * Inv_LW; + pParam->BSIM4v4dvt1 = model->BSIM4v4dvt1 + + model->BSIM4v4ldvt1 * Inv_L + + model->BSIM4v4wdvt1 * Inv_W + + model->BSIM4v4pdvt1 * Inv_LW; + pParam->BSIM4v4dvt2 = model->BSIM4v4dvt2 + + model->BSIM4v4ldvt2 * Inv_L + + model->BSIM4v4wdvt2 * Inv_W + + model->BSIM4v4pdvt2 * Inv_LW; + pParam->BSIM4v4dvt0w = model->BSIM4v4dvt0w + + model->BSIM4v4ldvt0w * Inv_L + + model->BSIM4v4wdvt0w * Inv_W + + model->BSIM4v4pdvt0w * Inv_LW; + pParam->BSIM4v4dvt1w = model->BSIM4v4dvt1w + + model->BSIM4v4ldvt1w * Inv_L + + model->BSIM4v4wdvt1w * Inv_W + + model->BSIM4v4pdvt1w * Inv_LW; + pParam->BSIM4v4dvt2w = model->BSIM4v4dvt2w + + model->BSIM4v4ldvt2w * Inv_L + + model->BSIM4v4wdvt2w * Inv_W + + model->BSIM4v4pdvt2w * Inv_LW; + pParam->BSIM4v4drout = model->BSIM4v4drout + + model->BSIM4v4ldrout * Inv_L + + model->BSIM4v4wdrout * Inv_W + + model->BSIM4v4pdrout * Inv_LW; + pParam->BSIM4v4dsub = model->BSIM4v4dsub + + model->BSIM4v4ldsub * Inv_L + + model->BSIM4v4wdsub * Inv_W + + model->BSIM4v4pdsub * Inv_LW; + pParam->BSIM4v4vth0 = model->BSIM4v4vth0 + + model->BSIM4v4lvth0 * Inv_L + + model->BSIM4v4wvth0 * Inv_W + + model->BSIM4v4pvth0 * Inv_LW; + pParam->BSIM4v4ua = model->BSIM4v4ua + + model->BSIM4v4lua * Inv_L + + model->BSIM4v4wua * Inv_W + + model->BSIM4v4pua * Inv_LW; + pParam->BSIM4v4ua1 = model->BSIM4v4ua1 + + model->BSIM4v4lua1 * Inv_L + + model->BSIM4v4wua1 * Inv_W + + model->BSIM4v4pua1 * Inv_LW; + pParam->BSIM4v4ub = model->BSIM4v4ub + + model->BSIM4v4lub * Inv_L + + model->BSIM4v4wub * Inv_W + + model->BSIM4v4pub * Inv_LW; + pParam->BSIM4v4ub1 = model->BSIM4v4ub1 + + model->BSIM4v4lub1 * Inv_L + + model->BSIM4v4wub1 * Inv_W + + model->BSIM4v4pub1 * Inv_LW; + pParam->BSIM4v4uc = model->BSIM4v4uc + + model->BSIM4v4luc * Inv_L + + model->BSIM4v4wuc * Inv_W + + model->BSIM4v4puc * Inv_LW; + pParam->BSIM4v4uc1 = model->BSIM4v4uc1 + + model->BSIM4v4luc1 * Inv_L + + model->BSIM4v4wuc1 * Inv_W + + model->BSIM4v4puc1 * Inv_LW; pParam->BSIM4v4eu = model->BSIM4v4eu + model->BSIM4v4leu * Inv_L + model->BSIM4v4weu * Inv_W + model->BSIM4v4peu * Inv_LW; - pParam->BSIM4v4u0 = model->BSIM4v4u0 - + model->BSIM4v4lu0 * Inv_L - + model->BSIM4v4wu0 * Inv_W - + model->BSIM4v4pu0 * Inv_LW; - pParam->BSIM4v4ute = model->BSIM4v4ute - + model->BSIM4v4lute * Inv_L - + model->BSIM4v4wute * Inv_W - + model->BSIM4v4pute * Inv_LW; - pParam->BSIM4v4voff = model->BSIM4v4voff - + model->BSIM4v4lvoff * Inv_L - + model->BSIM4v4wvoff * Inv_W - + model->BSIM4v4pvoff * Inv_LW; + pParam->BSIM4v4u0 = model->BSIM4v4u0 + + model->BSIM4v4lu0 * Inv_L + + model->BSIM4v4wu0 * Inv_W + + model->BSIM4v4pu0 * Inv_LW; + pParam->BSIM4v4ute = model->BSIM4v4ute + + model->BSIM4v4lute * Inv_L + + model->BSIM4v4wute * Inv_W + + model->BSIM4v4pute * Inv_LW; + pParam->BSIM4v4voff = model->BSIM4v4voff + + model->BSIM4v4lvoff * Inv_L + + model->BSIM4v4wvoff * Inv_W + + model->BSIM4v4pvoff * Inv_LW; pParam->BSIM4v4minv = model->BSIM4v4minv + model->BSIM4v4lminv * Inv_L + model->BSIM4v4wminv * Inv_W @@ -701,14 +714,14 @@ int Size_Not_Found, i; + model->BSIM4v4lpditsd * Inv_L + model->BSIM4v4wpditsd * Inv_W + model->BSIM4v4ppditsd * Inv_LW; - pParam->BSIM4v4delta = model->BSIM4v4delta - + model->BSIM4v4ldelta * Inv_L - + model->BSIM4v4wdelta * Inv_W - + model->BSIM4v4pdelta * Inv_LW; - pParam->BSIM4v4rdsw = model->BSIM4v4rdsw - + model->BSIM4v4lrdsw * Inv_L - + model->BSIM4v4wrdsw * Inv_W - + model->BSIM4v4prdsw * Inv_LW; + pParam->BSIM4v4delta = model->BSIM4v4delta + + model->BSIM4v4ldelta * Inv_L + + model->BSIM4v4wdelta * Inv_W + + model->BSIM4v4pdelta * Inv_LW; + pParam->BSIM4v4rdsw = model->BSIM4v4rdsw + + model->BSIM4v4lrdsw * Inv_L + + model->BSIM4v4wrdsw * Inv_W + + model->BSIM4v4prdsw * Inv_LW; pParam->BSIM4v4rdw = model->BSIM4v4rdw + model->BSIM4v4lrdw * Inv_L + model->BSIM4v4wrdw * Inv_W @@ -717,86 +730,86 @@ int Size_Not_Found, i; + model->BSIM4v4lrsw * Inv_L + model->BSIM4v4wrsw * Inv_W + model->BSIM4v4prsw * Inv_LW; - pParam->BSIM4v4prwg = model->BSIM4v4prwg - + model->BSIM4v4lprwg * Inv_L - + model->BSIM4v4wprwg * Inv_W - + model->BSIM4v4pprwg * Inv_LW; - pParam->BSIM4v4prwb = model->BSIM4v4prwb - + model->BSIM4v4lprwb * Inv_L - + model->BSIM4v4wprwb * Inv_W - + model->BSIM4v4pprwb * Inv_LW; - pParam->BSIM4v4prt = model->BSIM4v4prt - + model->BSIM4v4lprt * Inv_L - + model->BSIM4v4wprt * Inv_W - + model->BSIM4v4pprt * Inv_LW; - pParam->BSIM4v4eta0 = model->BSIM4v4eta0 - + model->BSIM4v4leta0 * Inv_L - + model->BSIM4v4weta0 * Inv_W - + model->BSIM4v4peta0 * Inv_LW; - pParam->BSIM4v4etab = model->BSIM4v4etab - + model->BSIM4v4letab * Inv_L - + model->BSIM4v4wetab * Inv_W - + model->BSIM4v4petab * Inv_LW; - pParam->BSIM4v4pclm = model->BSIM4v4pclm - + model->BSIM4v4lpclm * Inv_L - + model->BSIM4v4wpclm * Inv_W - + model->BSIM4v4ppclm * Inv_LW; - pParam->BSIM4v4pdibl1 = model->BSIM4v4pdibl1 - + model->BSIM4v4lpdibl1 * Inv_L - + model->BSIM4v4wpdibl1 * Inv_W - + model->BSIM4v4ppdibl1 * Inv_LW; - pParam->BSIM4v4pdibl2 = model->BSIM4v4pdibl2 - + model->BSIM4v4lpdibl2 * Inv_L - + model->BSIM4v4wpdibl2 * Inv_W - + model->BSIM4v4ppdibl2 * Inv_LW; - pParam->BSIM4v4pdiblb = model->BSIM4v4pdiblb - + model->BSIM4v4lpdiblb * Inv_L - + model->BSIM4v4wpdiblb * Inv_W - + model->BSIM4v4ppdiblb * Inv_LW; - pParam->BSIM4v4pscbe1 = model->BSIM4v4pscbe1 - + model->BSIM4v4lpscbe1 * Inv_L - + model->BSIM4v4wpscbe1 * Inv_W - + model->BSIM4v4ppscbe1 * Inv_LW; - pParam->BSIM4v4pscbe2 = model->BSIM4v4pscbe2 - + model->BSIM4v4lpscbe2 * Inv_L - + model->BSIM4v4wpscbe2 * Inv_W - + model->BSIM4v4ppscbe2 * Inv_LW; - pParam->BSIM4v4pvag = model->BSIM4v4pvag - + model->BSIM4v4lpvag * Inv_L - + model->BSIM4v4wpvag * Inv_W - + model->BSIM4v4ppvag * Inv_LW; - pParam->BSIM4v4wr = model->BSIM4v4wr - + model->BSIM4v4lwr * Inv_L - + model->BSIM4v4wwr * Inv_W - + model->BSIM4v4pwr * Inv_LW; - pParam->BSIM4v4dwg = model->BSIM4v4dwg - + model->BSIM4v4ldwg * Inv_L - + model->BSIM4v4wdwg * Inv_W - + model->BSIM4v4pdwg * Inv_LW; - pParam->BSIM4v4dwb = model->BSIM4v4dwb - + model->BSIM4v4ldwb * Inv_L - + model->BSIM4v4wdwb * Inv_W - + model->BSIM4v4pdwb * Inv_LW; - pParam->BSIM4v4b0 = model->BSIM4v4b0 - + model->BSIM4v4lb0 * Inv_L - + model->BSIM4v4wb0 * Inv_W - + model->BSIM4v4pb0 * Inv_LW; - pParam->BSIM4v4b1 = model->BSIM4v4b1 - + model->BSIM4v4lb1 * Inv_L - + model->BSIM4v4wb1 * Inv_W - + model->BSIM4v4pb1 * Inv_LW; - pParam->BSIM4v4alpha0 = model->BSIM4v4alpha0 - + model->BSIM4v4lalpha0 * Inv_L - + model->BSIM4v4walpha0 * Inv_W - + model->BSIM4v4palpha0 * Inv_LW; + pParam->BSIM4v4prwg = model->BSIM4v4prwg + + model->BSIM4v4lprwg * Inv_L + + model->BSIM4v4wprwg * Inv_W + + model->BSIM4v4pprwg * Inv_LW; + pParam->BSIM4v4prwb = model->BSIM4v4prwb + + model->BSIM4v4lprwb * Inv_L + + model->BSIM4v4wprwb * Inv_W + + model->BSIM4v4pprwb * Inv_LW; + pParam->BSIM4v4prt = model->BSIM4v4prt + + model->BSIM4v4lprt * Inv_L + + model->BSIM4v4wprt * Inv_W + + model->BSIM4v4pprt * Inv_LW; + pParam->BSIM4v4eta0 = model->BSIM4v4eta0 + + model->BSIM4v4leta0 * Inv_L + + model->BSIM4v4weta0 * Inv_W + + model->BSIM4v4peta0 * Inv_LW; + pParam->BSIM4v4etab = model->BSIM4v4etab + + model->BSIM4v4letab * Inv_L + + model->BSIM4v4wetab * Inv_W + + model->BSIM4v4petab * Inv_LW; + pParam->BSIM4v4pclm = model->BSIM4v4pclm + + model->BSIM4v4lpclm * Inv_L + + model->BSIM4v4wpclm * Inv_W + + model->BSIM4v4ppclm * Inv_LW; + pParam->BSIM4v4pdibl1 = model->BSIM4v4pdibl1 + + model->BSIM4v4lpdibl1 * Inv_L + + model->BSIM4v4wpdibl1 * Inv_W + + model->BSIM4v4ppdibl1 * Inv_LW; + pParam->BSIM4v4pdibl2 = model->BSIM4v4pdibl2 + + model->BSIM4v4lpdibl2 * Inv_L + + model->BSIM4v4wpdibl2 * Inv_W + + model->BSIM4v4ppdibl2 * Inv_LW; + pParam->BSIM4v4pdiblb = model->BSIM4v4pdiblb + + model->BSIM4v4lpdiblb * Inv_L + + model->BSIM4v4wpdiblb * Inv_W + + model->BSIM4v4ppdiblb * Inv_LW; + pParam->BSIM4v4pscbe1 = model->BSIM4v4pscbe1 + + model->BSIM4v4lpscbe1 * Inv_L + + model->BSIM4v4wpscbe1 * Inv_W + + model->BSIM4v4ppscbe1 * Inv_LW; + pParam->BSIM4v4pscbe2 = model->BSIM4v4pscbe2 + + model->BSIM4v4lpscbe2 * Inv_L + + model->BSIM4v4wpscbe2 * Inv_W + + model->BSIM4v4ppscbe2 * Inv_LW; + pParam->BSIM4v4pvag = model->BSIM4v4pvag + + model->BSIM4v4lpvag * Inv_L + + model->BSIM4v4wpvag * Inv_W + + model->BSIM4v4ppvag * Inv_LW; + pParam->BSIM4v4wr = model->BSIM4v4wr + + model->BSIM4v4lwr * Inv_L + + model->BSIM4v4wwr * Inv_W + + model->BSIM4v4pwr * Inv_LW; + pParam->BSIM4v4dwg = model->BSIM4v4dwg + + model->BSIM4v4ldwg * Inv_L + + model->BSIM4v4wdwg * Inv_W + + model->BSIM4v4pdwg * Inv_LW; + pParam->BSIM4v4dwb = model->BSIM4v4dwb + + model->BSIM4v4ldwb * Inv_L + + model->BSIM4v4wdwb * Inv_W + + model->BSIM4v4pdwb * Inv_LW; + pParam->BSIM4v4b0 = model->BSIM4v4b0 + + model->BSIM4v4lb0 * Inv_L + + model->BSIM4v4wb0 * Inv_W + + model->BSIM4v4pb0 * Inv_LW; + pParam->BSIM4v4b1 = model->BSIM4v4b1 + + model->BSIM4v4lb1 * Inv_L + + model->BSIM4v4wb1 * Inv_W + + model->BSIM4v4pb1 * Inv_LW; + pParam->BSIM4v4alpha0 = model->BSIM4v4alpha0 + + model->BSIM4v4lalpha0 * Inv_L + + model->BSIM4v4walpha0 * Inv_W + + model->BSIM4v4palpha0 * Inv_LW; pParam->BSIM4v4alpha1 = model->BSIM4v4alpha1 + model->BSIM4v4lalpha1 * Inv_L + model->BSIM4v4walpha1 * Inv_W + model->BSIM4v4palpha1 * Inv_LW; - pParam->BSIM4v4beta0 = model->BSIM4v4beta0 - + model->BSIM4v4lbeta0 * Inv_L - + model->BSIM4v4wbeta0 * Inv_W - + model->BSIM4v4pbeta0 * Inv_LW; + pParam->BSIM4v4beta0 = model->BSIM4v4beta0 + + model->BSIM4v4lbeta0 * Inv_L + + model->BSIM4v4wbeta0 * Inv_W + + model->BSIM4v4pbeta0 * Inv_LW; pParam->BSIM4v4agidl = model->BSIM4v4agidl + model->BSIM4v4lagidl * Inv_L + model->BSIM4v4wagidl * Inv_W @@ -897,55 +910,76 @@ int Size_Not_Found, i; + model->BSIM4v4lxrcrg2 * Inv_L + model->BSIM4v4wxrcrg2 * Inv_W + model->BSIM4v4pxrcrg2 * Inv_LW; - pParam->BSIM4v4lambda = model->BSIM4v4lambda - + model->BSIM4v4llambda * Inv_L - + model->BSIM4v4wlambda * Inv_W - + model->BSIM4v4plambda * Inv_LW; - pParam->BSIM4v4vtl = model->BSIM4v4vtl - + model->BSIM4v4lvtl * Inv_L - + model->BSIM4v4wvtl * Inv_W - + model->BSIM4v4pvtl * Inv_LW; - pParam->BSIM4v4xn = model->BSIM4v4xn - + model->BSIM4v4lxn * Inv_L - + model->BSIM4v4wxn * Inv_W - + model->BSIM4v4pxn * Inv_LW; - pParam->BSIM4v4vfbsdoff = model->BSIM4v4vfbsdoff - + model->BSIM4v4lvfbsdoff * Inv_L - + model->BSIM4v4wvfbsdoff * Inv_W - + model->BSIM4v4pvfbsdoff * Inv_LW; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: + pParam->BSIM4v4lambda = model->BSIM4v4lambda + + model->BSIM4v4llambda * Inv_L + + model->BSIM4v4wlambda * Inv_W + + model->BSIM4v4plambda * Inv_LW; + pParam->BSIM4v4vtl = model->BSIM4v4vtl + + model->BSIM4v4lvtl * Inv_L + + model->BSIM4v4wvtl * Inv_W + + model->BSIM4v4pvtl * Inv_LW; + pParam->BSIM4v4xn = model->BSIM4v4xn + + model->BSIM4v4lxn * Inv_L + + model->BSIM4v4wxn * Inv_W + + model->BSIM4v4pxn * Inv_LW; + break; + case BSIM4v40: + pParam->BSIM4v4lambda = model->BSIM4v4lambda + + model->BSIM4v4llambda * Inv_L + + model->BSIM4v4wlambda * Inv_W + + model->BSIM4v4plambda * Inv_LW; + pParam->BSIM4v4vtl = model->BSIM4v4vtl + + model->BSIM4v4lvtl * Inv_L + + model->BSIM4v4wvtl * Inv_W + + model->BSIM4v4pvtl * Inv_LW; + pParam->BSIM4v4xn = model->BSIM4v4xn + + model->BSIM4v4lxn * Inv_L + + model->BSIM4v4wxn * Inv_W + + model->BSIM4v4pxn * Inv_LW; + pParam->BSIM4v4vfbsdoff = model->BSIM4v4vfbsdoff + + model->BSIM4v4lvfbsdoff * Inv_L + + model->BSIM4v4wvfbsdoff * Inv_W + + model->BSIM4v4pvfbsdoff * Inv_LW; + break; + default: break; + } - pParam->BSIM4v4cgsl = model->BSIM4v4cgsl - + model->BSIM4v4lcgsl * Inv_L - + model->BSIM4v4wcgsl * Inv_W - + model->BSIM4v4pcgsl * Inv_LW; - pParam->BSIM4v4cgdl = model->BSIM4v4cgdl - + model->BSIM4v4lcgdl * Inv_L - + model->BSIM4v4wcgdl * Inv_W - + model->BSIM4v4pcgdl * Inv_LW; - pParam->BSIM4v4ckappas = model->BSIM4v4ckappas - + model->BSIM4v4lckappas * Inv_L - + model->BSIM4v4wckappas * Inv_W - + model->BSIM4v4pckappas * Inv_LW; + pParam->BSIM4v4cgsl = model->BSIM4v4cgsl + + model->BSIM4v4lcgsl * Inv_L + + model->BSIM4v4wcgsl * Inv_W + + model->BSIM4v4pcgsl * Inv_LW; + pParam->BSIM4v4cgdl = model->BSIM4v4cgdl + + model->BSIM4v4lcgdl * Inv_L + + model->BSIM4v4wcgdl * Inv_W + + model->BSIM4v4pcgdl * Inv_LW; + pParam->BSIM4v4ckappas = model->BSIM4v4ckappas + + model->BSIM4v4lckappas * Inv_L + + model->BSIM4v4wckappas * Inv_W + + model->BSIM4v4pckappas * Inv_LW; pParam->BSIM4v4ckappad = model->BSIM4v4ckappad + model->BSIM4v4lckappad * Inv_L + model->BSIM4v4wckappad * Inv_W + model->BSIM4v4pckappad * Inv_LW; - pParam->BSIM4v4cf = model->BSIM4v4cf - + model->BSIM4v4lcf * Inv_L - + model->BSIM4v4wcf * Inv_W - + model->BSIM4v4pcf * Inv_LW; - pParam->BSIM4v4clc = model->BSIM4v4clc - + model->BSIM4v4lclc * Inv_L - + model->BSIM4v4wclc * Inv_W - + model->BSIM4v4pclc * Inv_LW; - pParam->BSIM4v4cle = model->BSIM4v4cle - + model->BSIM4v4lcle * Inv_L - + model->BSIM4v4wcle * Inv_W - + model->BSIM4v4pcle * Inv_LW; - pParam->BSIM4v4vfbcv = model->BSIM4v4vfbcv - + model->BSIM4v4lvfbcv * Inv_L - + model->BSIM4v4wvfbcv * Inv_W - + model->BSIM4v4pvfbcv * Inv_LW; + pParam->BSIM4v4cf = model->BSIM4v4cf + + model->BSIM4v4lcf * Inv_L + + model->BSIM4v4wcf * Inv_W + + model->BSIM4v4pcf * Inv_LW; + pParam->BSIM4v4clc = model->BSIM4v4clc + + model->BSIM4v4lclc * Inv_L + + model->BSIM4v4wclc * Inv_W + + model->BSIM4v4pclc * Inv_LW; + pParam->BSIM4v4cle = model->BSIM4v4cle + + model->BSIM4v4lcle * Inv_L + + model->BSIM4v4wcle * Inv_W + + model->BSIM4v4pcle * Inv_LW; + pParam->BSIM4v4vfbcv = model->BSIM4v4vfbcv + + model->BSIM4v4lvfbcv * Inv_L + + model->BSIM4v4wvfbcv * Inv_W + + model->BSIM4v4pvfbcv * Inv_LW; pParam->BSIM4v4acde = model->BSIM4v4acde + model->BSIM4v4lacde * Inv_L + model->BSIM4v4wacde * Inv_W @@ -964,95 +998,155 @@ int Size_Not_Found, i; + model->BSIM4v4pvoffcv * Inv_LW; pParam->BSIM4v4abulkCVfactor = 1.0 + pow((pParam->BSIM4v4clc - / pParam->BSIM4v4leffCV), - pParam->BSIM4v4cle); + / pParam->BSIM4v4leffCV), + pParam->BSIM4v4cle); - T0 = (TRatio - 1.0); + T0 = (TRatio - 1.0); - PowWeffWr = pow(pParam->BSIM4v4weffCJ * 1.0e6, pParam->BSIM4v4wr) * here->BSIM4v4nf; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + pParam->BSIM4v4ua = pParam->BSIM4v4ua + pParam->BSIM4v4ua1 * T0; + pParam->BSIM4v4ub = pParam->BSIM4v4ub + pParam->BSIM4v4ub1 * T0; + pParam->BSIM4v4uc = pParam->BSIM4v4uc + pParam->BSIM4v4uc1 * T0; + if (pParam->BSIM4v4u0 > 1.0) + pParam->BSIM4v4u0 = pParam->BSIM4v4u0 / 1.0e4; - T1 = T2 = T3 = T4 = 0.0; - if(model->BSIM4v4tempMod == 0) { - pParam->BSIM4v4ua = pParam->BSIM4v4ua + pParam->BSIM4v4ua1 * T0; - pParam->BSIM4v4ub = pParam->BSIM4v4ub + pParam->BSIM4v4ub1 * T0; - pParam->BSIM4v4uc = pParam->BSIM4v4uc + pParam->BSIM4v4uc1 * T0; - pParam->BSIM4v4vsattemp = pParam->BSIM4v4vsat - pParam->BSIM4v4at * T0; - T10 = pParam->BSIM4v4prt * T0; - if(model->BSIM4v4rdsMod) { - /* External Rd(V) */ - T1 = pParam->BSIM4v4rdw + T10; - T2 = model->BSIM4v4rdwmin + T10; - /* External Rs(V) */ - T3 = pParam->BSIM4v4rsw + T10; - T4 = model->BSIM4v4rswmin + T10; - } - /* Internal Rds(V) in IV */ - pParam->BSIM4v4rds0 = (pParam->BSIM4v4rdsw + T10) - * here->BSIM4v4nf / PowWeffWr; - pParam->BSIM4v4rdswmin = (model->BSIM4v4rdswmin + T10) - * here->BSIM4v4nf / PowWeffWr; - } else { /* tempMod = 1 */ - pParam->BSIM4v4ua = pParam->BSIM4v4ua * (1.0 + pParam->BSIM4v4ua1 * delTemp) ; - pParam->BSIM4v4ub = pParam->BSIM4v4ub * (1.0 + pParam->BSIM4v4ub1 * delTemp); - pParam->BSIM4v4uc = pParam->BSIM4v4uc * (1.0 + pParam->BSIM4v4uc1 * delTemp); - pParam->BSIM4v4vsattemp = pParam->BSIM4v4vsat * (1.0 - pParam->BSIM4v4at * delTemp); - T10 = 1.0 + pParam->BSIM4v4prt * delTemp; - if(model->BSIM4v4rdsMod) { - /* External Rd(V) */ - T1 = pParam->BSIM4v4rdw * T10; - T2 = model->BSIM4v4rdwmin * T10; - /* External Rs(V) */ - T3 = pParam->BSIM4v4rsw * T10; - T4 = model->BSIM4v4rswmin * T10; - } - /* Internal Rds(V) in IV */ - pParam->BSIM4v4rds0 = pParam->BSIM4v4rdsw * T10 * here->BSIM4v4nf / PowWeffWr; - pParam->BSIM4v4rdswmin = model->BSIM4v4rdswmin * T10 * here->BSIM4v4nf / PowWeffWr; + + pParam->BSIM4v4u0temp = pParam->BSIM4v4u0 + * pow(TRatio, pParam->BSIM4v4ute); + pParam->BSIM4v4vsattemp = pParam->BSIM4v4vsat - pParam->BSIM4v4at + * T0; + if (pParam->BSIM4v4eu < 0.0) + { pParam->BSIM4v4eu = 0.0; + printf("Warning: eu has been negative; reset to 0.0.\n"); + } + + + PowWeffWr = pow(pParam->BSIM4v4weffCJ * 1.0e6, pParam->BSIM4v4wr) * here->BSIM4v4nf; + /* External Rd(V) */ + T1 = pParam->BSIM4v4rdw + pParam->BSIM4v4prt * T0; + if (T1 < 0.0) + { T1 = 0.0; + printf("Warning: Rdw at current temperature is negative; set to 0.\n"); + } + T2 = model->BSIM4v4rdwmin + pParam->BSIM4v4prt * T0; + if (T2 < 0.0) + { T2 = 0.0; + printf("Warning: Rdwmin at current temperature is negative; set to 0.\n"); + } + pParam->BSIM4v4rd0 = T1 / PowWeffWr; + pParam->BSIM4v4rdwmin = T2 / PowWeffWr; + + + /* External Rs(V) */ + T1 = pParam->BSIM4v4rsw + pParam->BSIM4v4prt * T0; + if (T1 < 0.0) + { T1 = 0.0; + printf("Warning: Rsw at current temperature is negative; set to 0.\n"); + } + T2 = model->BSIM4v4rswmin + pParam->BSIM4v4prt * T0; + if (T2 < 0.0) + { T2 = 0.0; + printf("Warning: Rswmin at current temperature is negative; set to 0.\n"); + } + pParam->BSIM4v4rs0 = T1 / PowWeffWr; + pParam->BSIM4v4rswmin = T2 / PowWeffWr; + + + /* Internal Rds(V) in IV */ + pParam->BSIM4v4rds0 = (pParam->BSIM4v4rdsw + pParam->BSIM4v4prt * T0) + * here->BSIM4v4nf / PowWeffWr; + pParam->BSIM4v4rdswmin = (model->BSIM4v4rdswmin + pParam->BSIM4v4prt * T0) + * here->BSIM4v4nf / PowWeffWr; + break; + case BSIM4v30: case BSIM4v40: + PowWeffWr = pow(pParam->BSIM4v4weffCJ * 1.0e6, pParam->BSIM4v4wr) * here->BSIM4v4nf; + + T1 = T2 = T3 = T4 = 0.0; + if(model->BSIM4v4tempMod == 0) { + pParam->BSIM4v4ua = pParam->BSIM4v4ua + pParam->BSIM4v4ua1 * T0; + pParam->BSIM4v4ub = pParam->BSIM4v4ub + pParam->BSIM4v4ub1 * T0; + pParam->BSIM4v4uc = pParam->BSIM4v4uc + pParam->BSIM4v4uc1 * T0; + pParam->BSIM4v4vsattemp = pParam->BSIM4v4vsat - pParam->BSIM4v4at * T0; + T10 = pParam->BSIM4v4prt * T0; + if(model->BSIM4v4rdsMod) { + /* External Rd(V) */ + T1 = pParam->BSIM4v4rdw + T10; + T2 = model->BSIM4v4rdwmin + T10; + /* External Rs(V) */ + T3 = pParam->BSIM4v4rsw + T10; + T4 = model->BSIM4v4rswmin + T10; + } + /* Internal Rds(V) in IV */ + pParam->BSIM4v4rds0 = (pParam->BSIM4v4rdsw + T10) + * here->BSIM4v4nf / PowWeffWr; + pParam->BSIM4v4rdswmin = (model->BSIM4v4rdswmin + T10) + * here->BSIM4v4nf / PowWeffWr; + } else { /* tempMod = 1 */ + pParam->BSIM4v4ua = pParam->BSIM4v4ua * (1.0 + pParam->BSIM4v4ua1 * delTemp) ; + pParam->BSIM4v4ub = pParam->BSIM4v4ub * (1.0 + pParam->BSIM4v4ub1 * delTemp); + pParam->BSIM4v4uc = pParam->BSIM4v4uc * (1.0 + pParam->BSIM4v4uc1 * delTemp); + pParam->BSIM4v4vsattemp = pParam->BSIM4v4vsat * (1.0 - pParam->BSIM4v4at * delTemp); + T10 = 1.0 + pParam->BSIM4v4prt * delTemp; + if(model->BSIM4v4rdsMod) { + /* External Rd(V) */ + T1 = pParam->BSIM4v4rdw * T10; + T2 = model->BSIM4v4rdwmin * T10; + /* External Rs(V) */ + T3 = pParam->BSIM4v4rsw * T10; + T4 = model->BSIM4v4rswmin * T10; + } + /* Internal Rds(V) in IV */ + pParam->BSIM4v4rds0 = pParam->BSIM4v4rdsw * T10 * here->BSIM4v4nf / PowWeffWr; + pParam->BSIM4v4rdswmin = model->BSIM4v4rdswmin * T10 * here->BSIM4v4nf / PowWeffWr; + } + if (T1 < 0.0) + { T1 = 0.0; + printf("Warning: Rdw at current temperature is negative; set to 0.\n"); + } + if (T2 < 0.0) + { T2 = 0.0; + printf("Warning: Rdwmin at current temperature is negative; set to 0.\n"); + } + pParam->BSIM4v4rd0 = T1 / PowWeffWr; + pParam->BSIM4v4rdwmin = T2 / PowWeffWr; + if (T3 < 0.0) + { T3 = 0.0; + printf("Warning: Rsw at current temperature is negative; set to 0.\n"); + } + if (T4 < 0.0) + { T4 = 0.0; + printf("Warning: Rswmin at current temperature is negative; set to 0.\n"); + } + pParam->BSIM4v4rs0 = T3 / PowWeffWr; + pParam->BSIM4v4rswmin = T4 / PowWeffWr; + + if (pParam->BSIM4v4u0 > 1.0) + pParam->BSIM4v4u0 = pParam->BSIM4v4u0 / 1.0e4; + + pParam->BSIM4v4u0temp = pParam->BSIM4v4u0 + * pow(TRatio, pParam->BSIM4v4ute); + if (pParam->BSIM4v4eu < 0.0) + { pParam->BSIM4v4eu = 0.0; + printf("Warning: eu has been negative; reset to 0.0.\n"); + } + + /* Source End Velocity Limit */ + if((model->BSIM4v4vtlGiven) && (model->BSIM4v4vtl > 0.0) ) + { + if(model->BSIM4v4lc < 0.0) pParam->BSIM4v4lc = 0.0; + else pParam->BSIM4v4lc = model->BSIM4v4lc ; + T0 = pParam->BSIM4v4leff / (pParam->BSIM4v4xn * pParam->BSIM4v4leff + pParam->BSIM4v4lc); + pParam->BSIM4v4tfactor = (1.0 - T0) / (1.0 + T0 ); + } + break; + default: break; } - if (T1 < 0.0) - { T1 = 0.0; - printf("Warning: Rdw at current temperature is negative; set to 0.\n"); - } - if (T2 < 0.0) - { T2 = 0.0; - printf("Warning: Rdwmin at current temperature is negative; set to 0.\n"); - } - pParam->BSIM4v4rd0 = T1 / PowWeffWr; - pParam->BSIM4v4rdwmin = T2 / PowWeffWr; - if (T3 < 0.0) - { T3 = 0.0; - printf("Warning: Rsw at current temperature is negative; set to 0.\n"); - } - if (T4 < 0.0) - { T4 = 0.0; - printf("Warning: Rswmin at current temperature is negative; set to 0.\n"); - } - pParam->BSIM4v4rs0 = T3 / PowWeffWr; - pParam->BSIM4v4rswmin = T4 / PowWeffWr; - - if (pParam->BSIM4v4u0 > 1.0) - pParam->BSIM4v4u0 = pParam->BSIM4v4u0 / 1.0e4; - - pParam->BSIM4v4u0temp = pParam->BSIM4v4u0 - * pow(TRatio, pParam->BSIM4v4ute); - if (pParam->BSIM4v4eu < 0.0) - { pParam->BSIM4v4eu = 0.0; - printf("Warning: eu has been negative; reset to 0.0.\n"); - } - - /* Source End Velocity Limit */ - if((model->BSIM4v4vtlGiven) && (model->BSIM4v4vtl > 0.0) ) - { - if(model->BSIM4v4lc < 0.0) pParam->BSIM4v4lc = 0.0; - else pParam->BSIM4v4lc = model->BSIM4v4lc ; - T0 = pParam->BSIM4v4leff / (pParam->BSIM4v4xn * pParam->BSIM4v4leff + pParam->BSIM4v4lc); - pParam->BSIM4v4tfactor = (1.0 - T0) / (1.0 + T0 ); - } pParam->BSIM4v4cgdo = (model->BSIM4v4cgdo + pParam->BSIM4v4cf) - * pParam->BSIM4v4weffCV; + * pParam->BSIM4v4weffCV; pParam->BSIM4v4cgso = (model->BSIM4v4cgso + pParam->BSIM4v4cf) - * pParam->BSIM4v4weffCV; + * pParam->BSIM4v4weffCV; pParam->BSIM4v4cgbo = model->BSIM4v4cgbo * pParam->BSIM4v4leffCV * here->BSIM4v4nf; if (!model->BSIM4v4ndepGiven && model->BSIM4v4gamma1Given) @@ -1060,35 +1154,35 @@ int Size_Not_Found, i; pParam->BSIM4v4ndep = 3.01248e22 * T0 * T0; } - pParam->BSIM4v4phi = Vtm0 * log(pParam->BSIM4v4ndep / ni) - + pParam->BSIM4v4phin + 0.4; + pParam->BSIM4v4phi = Vtm0 * log(pParam->BSIM4v4ndep / ni) + + pParam->BSIM4v4phin + 0.4; - pParam->BSIM4v4sqrtPhi = sqrt(pParam->BSIM4v4phi); - pParam->BSIM4v4phis3 = pParam->BSIM4v4sqrtPhi * pParam->BSIM4v4phi; + pParam->BSIM4v4sqrtPhi = sqrt(pParam->BSIM4v4phi); + pParam->BSIM4v4phis3 = pParam->BSIM4v4sqrtPhi * pParam->BSIM4v4phi; pParam->BSIM4v4Xdep0 = sqrt(2.0 * EPSSI / (Charge_q - * pParam->BSIM4v4ndep * 1.0e6)) + * pParam->BSIM4v4ndep * 1.0e6)) * pParam->BSIM4v4sqrtPhi; pParam->BSIM4v4sqrtXdep0 = sqrt(pParam->BSIM4v4Xdep0); pParam->BSIM4v4litl = sqrt(3.0 * pParam->BSIM4v4xj - * model->BSIM4v4toxe); + * model->BSIM4v4toxe); pParam->BSIM4v4vbi = Vtm0 * log(pParam->BSIM4v4nsd - * pParam->BSIM4v4ndep / (ni * ni)); + * pParam->BSIM4v4ndep / (ni * ni)); - if (pParam->BSIM4v4ngate > 0.0) + if (pParam->BSIM4v4ngate > 0.0) { pParam->BSIM4v4vfbsd = Vtm0 * log(pParam->BSIM4v4ngate / pParam->BSIM4v4nsd); - } - else - pParam->BSIM4v4vfbsd = 0.0; + } + else + pParam->BSIM4v4vfbsd = 0.0; pParam->BSIM4v4cdep0 = sqrt(Charge_q * EPSSI - * pParam->BSIM4v4ndep * 1.0e6 / 2.0 - / pParam->BSIM4v4phi); + * pParam->BSIM4v4ndep * 1.0e6 / 2.0 + / pParam->BSIM4v4phi); pParam->BSIM4v4ToxRatio = exp(pParam->BSIM4v4ntox - * log(model->BSIM4v4toxref / model->BSIM4v4toxe)) - / model->BSIM4v4toxe / model->BSIM4v4toxe; + * log(model->BSIM4v4toxref / model->BSIM4v4toxe)) + / model->BSIM4v4toxe / model->BSIM4v4toxe; pParam->BSIM4v4ToxRatioEdge = exp(pParam->BSIM4v4ntox * log(model->BSIM4v4toxref / (model->BSIM4v4toxe * pParam->BSIM4v4poxedge))) @@ -1097,11 +1191,11 @@ int Size_Not_Found, i; pParam->BSIM4v4Aechvb = (model->BSIM4v4type == NMOS) ? 4.97232e-7 : 3.42537e-7; pParam->BSIM4v4Bechvb = (model->BSIM4v4type == NMOS) ? 7.45669e11 : 1.16645e12; pParam->BSIM4v4AechvbEdge = pParam->BSIM4v4Aechvb * pParam->BSIM4v4weff - * pParam->BSIM4v4dlcig * pParam->BSIM4v4ToxRatioEdge; + * pParam->BSIM4v4dlcig * pParam->BSIM4v4ToxRatioEdge; pParam->BSIM4v4BechvbEdge = -pParam->BSIM4v4Bechvb - * model->BSIM4v4toxe * pParam->BSIM4v4poxedge; + * model->BSIM4v4toxe * pParam->BSIM4v4poxedge; pParam->BSIM4v4Aechvb *= pParam->BSIM4v4weff * pParam->BSIM4v4leff - * pParam->BSIM4v4ToxRatio; + * pParam->BSIM4v4ToxRatio; pParam->BSIM4v4Bechvb *= -model->BSIM4v4toxe; @@ -1114,12 +1208,12 @@ int Size_Not_Found, i; if (model->BSIM4v4k1Given || model->BSIM4v4k2Given) - { if (!model->BSIM4v4k1Given) - { fprintf(stdout, "Warning: k1 should be specified with k2.\n"); + { if (!model->BSIM4v4k1Given) + { fprintf(stdout, "Warning: k1 should be specified with k2.\n"); pParam->BSIM4v4k1 = 0.53; } if (!model->BSIM4v4k2Given) - { fprintf(stdout, "Warning: k2 should be specified with k1.\n"); + { fprintf(stdout, "Warning: k2 should be specified with k1.\n"); pParam->BSIM4v4k2 = -0.0186; } if (model->BSIM4v4nsubGiven) @@ -1134,48 +1228,48 @@ int Size_Not_Found, i; fprintf(stdout, "Warning: gamma2 is ignored because k1 or k2 is given.\n"); } else - { if (!model->BSIM4v4vbxGiven) + { if (!model->BSIM4v4vbxGiven) pParam->BSIM4v4vbx = pParam->BSIM4v4phi - 7.7348e-4 * pParam->BSIM4v4ndep - * pParam->BSIM4v4xt * pParam->BSIM4v4xt; - if (pParam->BSIM4v4vbx > 0.0) - pParam->BSIM4v4vbx = -pParam->BSIM4v4vbx; - if (pParam->BSIM4v4vbm > 0.0) + * pParam->BSIM4v4xt * pParam->BSIM4v4xt; + if (pParam->BSIM4v4vbx > 0.0) + pParam->BSIM4v4vbx = -pParam->BSIM4v4vbx; + if (pParam->BSIM4v4vbm > 0.0) pParam->BSIM4v4vbm = -pParam->BSIM4v4vbm; if (!model->BSIM4v4gamma1Given) pParam->BSIM4v4gamma1 = 5.753e-12 - * sqrt(pParam->BSIM4v4ndep) + * sqrt(pParam->BSIM4v4ndep) / model->BSIM4v4coxe; if (!model->BSIM4v4gamma2Given) pParam->BSIM4v4gamma2 = 5.753e-12 - * sqrt(pParam->BSIM4v4nsub) + * sqrt(pParam->BSIM4v4nsub) / model->BSIM4v4coxe; T0 = pParam->BSIM4v4gamma1 - pParam->BSIM4v4gamma2; T1 = sqrt(pParam->BSIM4v4phi - pParam->BSIM4v4vbx) - - pParam->BSIM4v4sqrtPhi; + - pParam->BSIM4v4sqrtPhi; T2 = sqrt(pParam->BSIM4v4phi * (pParam->BSIM4v4phi - - pParam->BSIM4v4vbm)) - pParam->BSIM4v4phi; + - pParam->BSIM4v4vbm)) - pParam->BSIM4v4phi; pParam->BSIM4v4k2 = T0 * T1 / (2.0 * T2 + pParam->BSIM4v4vbm); pParam->BSIM4v4k1 = pParam->BSIM4v4gamma2 - 2.0 - * pParam->BSIM4v4k2 * sqrt(pParam->BSIM4v4phi - - pParam->BSIM4v4vbm); + * pParam->BSIM4v4k2 * sqrt(pParam->BSIM4v4phi + - pParam->BSIM4v4vbm); } - if (pParam->BSIM4v4k2 < 0.0) - { T0 = 0.5 * pParam->BSIM4v4k1 / pParam->BSIM4v4k2; + if (pParam->BSIM4v4k2 < 0.0) + { T0 = 0.5 * pParam->BSIM4v4k1 / pParam->BSIM4v4k2; pParam->BSIM4v4vbsc = 0.9 * (pParam->BSIM4v4phi - T0 * T0); - if (pParam->BSIM4v4vbsc > -3.0) - pParam->BSIM4v4vbsc = -3.0; - else if (pParam->BSIM4v4vbsc < -30.0) - pParam->BSIM4v4vbsc = -30.0; - } - else - { pParam->BSIM4v4vbsc = -30.0; - } - if (pParam->BSIM4v4vbsc > pParam->BSIM4v4vbm) - pParam->BSIM4v4vbsc = pParam->BSIM4v4vbm; + if (pParam->BSIM4v4vbsc > -3.0) + pParam->BSIM4v4vbsc = -3.0; + else if (pParam->BSIM4v4vbsc < -30.0) + pParam->BSIM4v4vbsc = -30.0; + } + else + { pParam->BSIM4v4vbsc = -30.0; + } + if (pParam->BSIM4v4vbsc > pParam->BSIM4v4vbm) + pParam->BSIM4v4vbsc = pParam->BSIM4v4vbm; if (!model->BSIM4v4vfbGiven) { if (model->BSIM4v4vth0Given) @@ -1198,13 +1292,13 @@ int Size_Not_Found, i; pParam->BSIM4v4k2ox = pParam->BSIM4v4k2 * model->BSIM4v4toxe / model->BSIM4v4toxm; - T3 = model->BSIM4v4type * pParam->BSIM4v4vth0 - - pParam->BSIM4v4vfb - pParam->BSIM4v4phi; - T4 = T3 + T3; - T5 = 2.5 * T3; + T3 = model->BSIM4v4type * pParam->BSIM4v4vth0 + - pParam->BSIM4v4vfb - pParam->BSIM4v4phi; + T4 = T3 + T3; + T5 = 2.5 * T3; pParam->BSIM4v4vtfbphi1 = (model->BSIM4v4type == NMOS) ? T4 : T5; - if (pParam->BSIM4v4vtfbphi1 < 0.0) - pParam->BSIM4v4vtfbphi1 = 0.0; + if (pParam->BSIM4v4vtfbphi1 < 0.0) + pParam->BSIM4v4vtfbphi1 = 0.0; pParam->BSIM4v4vtfbphi2 = 4.0 * T3; if (pParam->BSIM4v4vtfbphi2 < 0.0) @@ -1212,21 +1306,21 @@ int Size_Not_Found, i; tmp = sqrt(EPSSI / (model->BSIM4v4epsrox * EPS0) * model->BSIM4v4toxe * pParam->BSIM4v4Xdep0); - T0 = pParam->BSIM4v4dsub * pParam->BSIM4v4leff / tmp; + T0 = pParam->BSIM4v4dsub * pParam->BSIM4v4leff / tmp; if (T0 < EXP_THRESHOLD) - { T1 = exp(T0); - T2 = T1 - 1.0; - T3 = T2 * T2; + { T1 = exp(T0); + T2 = T1 - 1.0; + T3 = T2 * T2; T4 = T3 + 2.0 * T1 * MIN_EXP; pParam->BSIM4v4theta0vb0 = T1 / T4; } else pParam->BSIM4v4theta0vb0 = 1.0 / (MAX_EXP - 2.0); - T0 = pParam->BSIM4v4drout * pParam->BSIM4v4leff / tmp; - if (T0 < EXP_THRESHOLD) - { T1 = exp(T0); - T2 = T1 - 1.0; + T0 = pParam->BSIM4v4drout * pParam->BSIM4v4leff / tmp; + if (T0 < EXP_THRESHOLD) + { T1 = exp(T0); + T2 = T1 - 1.0; T3 = T2 * T2; T4 = T3 + 2.0 * T1 * MIN_EXP; T5 = T1 / T4; @@ -1279,119 +1373,133 @@ int Size_Not_Found, i; pParam->BSIM4v4vfbzb = tmp3 - pParam->BSIM4v4phi - pParam->BSIM4v4k1 * pParam->BSIM4v4sqrtPhi; /* End of vfbzb */ - /* stress effect */ - T0 = pow(Lnew, model->BSIM4v4llodku0); - W_tmp = Wnew + model->BSIM4v4wlod; - T1 = pow(W_tmp, model->BSIM4v4wlodku0); - tmp1 = model->BSIM4v4lku0 / T0 + model->BSIM4v4wku0 / T1 - + model->BSIM4v4pku0 / (T0 * T1); - pParam->BSIM4v4ku0 = 1.0 + tmp1; - - T0 = pow(Lnew, model->BSIM4v4llodvth); - T1 = pow(W_tmp, model->BSIM4v4wlodvth); - tmp1 = model->BSIM4v4lkvth0 / T0 + model->BSIM4v4wkvth0 / T1 - + model->BSIM4v4pkvth0 / (T0 * T1); - pParam->BSIM4v4kvth0 = 1.0 + tmp1; - pParam->BSIM4v4kvth0 = sqrt(pParam->BSIM4v4kvth0*pParam->BSIM4v4kvth0 + DELTA); - - T0 = (TRatio - 1.0); - pParam->BSIM4v4ku0temp = pParam->BSIM4v4ku0 * (1.0 + model->BSIM4v4tku0 *T0) + DELTA; - - Inv_saref = 1.0/(model->BSIM4v4saref + 0.5*Ldrn); - Inv_sbref = 1.0/(model->BSIM4v4sbref + 0.5*Ldrn); - pParam->BSIM4v4inv_od_ref = Inv_saref + Inv_sbref; - pParam->BSIM4v4rho_ref = model->BSIM4v4ku0 / pParam->BSIM4v4ku0temp * pParam->BSIM4v4inv_od_ref; + /* stress effect */ + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + T0 = pow(Lnew, model->BSIM4v4llodku0); + W_tmp = Wnew + model->BSIM4v4wlod; + T1 = pow(W_tmp, model->BSIM4v4wlodku0); + tmp1 = model->BSIM4v4lku0 / T0 + model->BSIM4v4wku0 / T1 + + model->BSIM4v4pku0 / (T0 * T1); + pParam->BSIM4v4ku0 = 1.0 + tmp1; + + T0 = pow(Lnew, model->BSIM4v4llodvth); + T1 = pow(W_tmp, model->BSIM4v4wlodvth); + tmp1 = model->BSIM4v4lkvth0 / T0 + model->BSIM4v4wkvth0 / T1 + + model->BSIM4v4pkvth0 / (T0 * T1); + pParam->BSIM4v4kvth0 = 1.0 + tmp1; + pParam->BSIM4v4kvth0 = sqrt(pParam->BSIM4v4kvth0*pParam->BSIM4v4kvth0 + DELTA); + + T0 = (TRatio - 1.0); + pParam->BSIM4v4ku0temp = pParam->BSIM4v4ku0 * (1.0 + model->BSIM4v4tku0 *T0) + DELTA; + + Inv_saref = 1.0/(model->BSIM4v4saref + 0.5*Ldrn); + Inv_sbref = 1.0/(model->BSIM4v4sbref + 0.5*Ldrn); + pParam->BSIM4v4inv_od_ref = Inv_saref + Inv_sbref; + pParam->BSIM4v4rho_ref = model->BSIM4v4ku0 / pParam->BSIM4v4ku0temp * pParam->BSIM4v4inv_od_ref; + break; + default: break; + } } /* End of SizeNotFound */ /* stress effect */ - if( (here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && - ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) - { Inv_sa = 0; - Inv_sb = 0; - - if (model->BSIM4v4wlod < 0.0) - { fprintf(stderr, "Warning: WLOD = %g is less than 0. Set to 0.0\n",model->BSIM4v4wlod); - model->BSIM4v4wlod = 0.0; - } - if (model->BSIM4v4kvsat < -1.0 ) - { fprintf(stderr, "Warning: KVSAT = %g is too small; Reset to -1.0.\n",model->BSIM4v4kvsat); - model->BSIM4v4kvsat = -1.0; - } - if (model->BSIM4v4kvsat > 1.0) - { fprintf(stderr, "Warning: KVSAT = %g is too big; Reset to 1.0.\n",model->BSIM4v4kvsat); - model->BSIM4v4kvsat = 1.0; - } - - for(i = 0; i < here->BSIM4v4nf; i++){ - T0 = 1.0 / here->BSIM4v4nf / (here->BSIM4v4sa + 0.5*Ldrn + i * (here->BSIM4v4sd +Ldrn)); - T1 = 1.0 / here->BSIM4v4nf / (here->BSIM4v4sb + 0.5*Ldrn + i * (here->BSIM4v4sd +Ldrn)); - Inv_sa += T0; - Inv_sb += T1; - } - Inv_ODeff = Inv_sa + Inv_sb; - rho = model->BSIM4v4ku0 / pParam->BSIM4v4ku0temp * Inv_ODeff; - T0 = (1.0 + rho)/(1.0 + pParam->BSIM4v4rho_ref); - here->BSIM4v4u0temp = pParam->BSIM4v4u0temp * T0; + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + break; + case BSIM4v30: case BSIM4v40: + if( (here->BSIM4v4sa > 0.0) && (here->BSIM4v4sb > 0.0) && + ((here->BSIM4v4nf == 1.0) || ((here->BSIM4v4nf > 1.0) && (here->BSIM4v4sd > 0.0))) ) + { Inv_sa = 0; + Inv_sb = 0; - T1 = (1.0 + model->BSIM4v4kvsat * rho)/(1.0 + model->BSIM4v4kvsat * pParam->BSIM4v4rho_ref); - here->BSIM4v4vsattemp = pParam->BSIM4v4vsattemp * T1; + if (model->BSIM4v4wlod < 0.0) + { fprintf(stderr, "Warning: WLOD = %g is less than 0. Set to 0.0\n",model->BSIM4v4wlod); + model->BSIM4v4wlod = 0.0; + } + if (model->BSIM4v4kvsat < -1.0 ) + { fprintf(stderr, "Warning: KVSAT = %g is too small; Reset to -1.0.\n",model->BSIM4v4kvsat); + model->BSIM4v4kvsat = -1.0; + } + if (model->BSIM4v4kvsat > 1.0) + { fprintf(stderr, "Warning: KVSAT = %g is too big; Reset to 1.0.\n",model->BSIM4v4kvsat); + model->BSIM4v4kvsat = 1.0; + } - OD_offset = Inv_ODeff - pParam->BSIM4v4inv_od_ref; - dvth0_lod = model->BSIM4v4kvth0 / pParam->BSIM4v4kvth0 * OD_offset; - dk2_lod = model->BSIM4v4stk2 / pow(pParam->BSIM4v4kvth0, model->BSIM4v4lodk2) * - OD_offset; - deta0_lod = model->BSIM4v4steta0 / pow(pParam->BSIM4v4kvth0, model->BSIM4v4lodeta0) * - OD_offset; - here->BSIM4v4vth0 = pParam->BSIM4v4vth0 + dvth0_lod; - - if (!model->BSIM4v4vfbGiven && !model->BSIM4v4vth0Given) - here->BSIM4v4vfb = -1.0; - else - here->BSIM4v4vfb = pParam->BSIM4v4vfb + model->BSIM4v4type * dvth0_lod; - here->BSIM4v4vfbzb = pParam->BSIM4v4vfbzb + model->BSIM4v4type * dvth0_lod; - - T3 = model->BSIM4v4type * here->BSIM4v4vth0 - - here->BSIM4v4vfb - pParam->BSIM4v4phi; - T4 = T3 + T3; - T5 = 2.5 * T3; - here->BSIM4v4vtfbphi1 = (model->BSIM4v4type == NMOS) ? T4 : T5; - if (here->BSIM4v4vtfbphi1 < 0.0) - here->BSIM4v4vtfbphi1 = 0.0; - - here->BSIM4v4vtfbphi2 = 4.0 * T3; - if (here->BSIM4v4vtfbphi2 < 0.0) - here->BSIM4v4vtfbphi2 = 0.0; - - here->BSIM4v4k2 = pParam->BSIM4v4k2 + dk2_lod; - if (here->BSIM4v4k2 < 0.0) - { T0 = 0.5 * pParam->BSIM4v4k1 / here->BSIM4v4k2; - here->BSIM4v4vbsc = 0.9 * (pParam->BSIM4v4phi - T0 * T0); - if (here->BSIM4v4vbsc > -3.0) - here->BSIM4v4vbsc = -3.0; - else if (here->BSIM4v4vbsc < -30.0) + for(i = 0; i < here->BSIM4v4nf; i++){ + T0 = 1.0 / here->BSIM4v4nf / (here->BSIM4v4sa + 0.5*Ldrn + i * (here->BSIM4v4sd +Ldrn)); + T1 = 1.0 / here->BSIM4v4nf / (here->BSIM4v4sb + 0.5*Ldrn + i * (here->BSIM4v4sd +Ldrn)); + Inv_sa += T0; + Inv_sb += T1; + } + Inv_ODeff = Inv_sa + Inv_sb; + rho = model->BSIM4v4ku0 / pParam->BSIM4v4ku0temp * Inv_ODeff; + T0 = (1.0 + rho)/(1.0 + pParam->BSIM4v4rho_ref); + here->BSIM4v4u0temp = pParam->BSIM4v4u0temp * T0; + + T1 = (1.0 + model->BSIM4v4kvsat * rho)/(1.0 + model->BSIM4v4kvsat * pParam->BSIM4v4rho_ref); + here->BSIM4v4vsattemp = pParam->BSIM4v4vsattemp * T1; + + OD_offset = Inv_ODeff - pParam->BSIM4v4inv_od_ref; + dvth0_lod = model->BSIM4v4kvth0 / pParam->BSIM4v4kvth0 * OD_offset; + dk2_lod = model->BSIM4v4stk2 / pow(pParam->BSIM4v4kvth0, model->BSIM4v4lodk2) * + OD_offset; + deta0_lod = model->BSIM4v4steta0 / pow(pParam->BSIM4v4kvth0, model->BSIM4v4lodeta0) * + OD_offset; + here->BSIM4v4vth0 = pParam->BSIM4v4vth0 + dvth0_lod; + + if (!model->BSIM4v4vfbGiven && !model->BSIM4v4vth0Given) + here->BSIM4v4vfb = -1.0; + else + here->BSIM4v4vfb = pParam->BSIM4v4vfb + model->BSIM4v4type * dvth0_lod; + here->BSIM4v4vfbzb = pParam->BSIM4v4vfbzb + model->BSIM4v4type * dvth0_lod; + + T3 = model->BSIM4v4type * here->BSIM4v4vth0 + - here->BSIM4v4vfb - pParam->BSIM4v4phi; + T4 = T3 + T3; + T5 = 2.5 * T3; + here->BSIM4v4vtfbphi1 = (model->BSIM4v4type == NMOS) ? T4 : T5; + if (here->BSIM4v4vtfbphi1 < 0.0) + here->BSIM4v4vtfbphi1 = 0.0; + + here->BSIM4v4vtfbphi2 = 4.0 * T3; + if (here->BSIM4v4vtfbphi2 < 0.0) + here->BSIM4v4vtfbphi2 = 0.0; + + here->BSIM4v4k2 = pParam->BSIM4v4k2 + dk2_lod; + if (here->BSIM4v4k2 < 0.0) + { T0 = 0.5 * pParam->BSIM4v4k1 / here->BSIM4v4k2; + here->BSIM4v4vbsc = 0.9 * (pParam->BSIM4v4phi - T0 * T0); + if (here->BSIM4v4vbsc > -3.0) + here->BSIM4v4vbsc = -3.0; + else if (here->BSIM4v4vbsc < -30.0) + here->BSIM4v4vbsc = -30.0; + } + else here->BSIM4v4vbsc = -30.0; + if (here->BSIM4v4vbsc > pParam->BSIM4v4vbm) + here->BSIM4v4vbsc = pParam->BSIM4v4vbm; + here->BSIM4v4k2ox = here->BSIM4v4k2 * model->BSIM4v4toxe + / model->BSIM4v4toxm; + + here->BSIM4v4eta0 = pParam->BSIM4v4eta0 + deta0_lod; + } else { + here->BSIM4v4u0temp = pParam->BSIM4v4u0temp; + here->BSIM4v4vth0 = pParam->BSIM4v4vth0; + here->BSIM4v4vsattemp = pParam->BSIM4v4vsattemp; + here->BSIM4v4vfb = pParam->BSIM4v4vfb; + here->BSIM4v4vfbzb = pParam->BSIM4v4vfbzb; + here->BSIM4v4vtfbphi1 = pParam->BSIM4v4vtfbphi1; + here->BSIM4v4vtfbphi2 = pParam->BSIM4v4vtfbphi2; + here->BSIM4v4k2 = pParam->BSIM4v4k2; + here->BSIM4v4vbsc = pParam->BSIM4v4vbsc; + here->BSIM4v4k2ox = pParam->BSIM4v4k2ox; + here->BSIM4v4eta0 = pParam->BSIM4v4eta0; } - else - here->BSIM4v4vbsc = -30.0; - if (here->BSIM4v4vbsc > pParam->BSIM4v4vbm) - here->BSIM4v4vbsc = pParam->BSIM4v4vbm; - here->BSIM4v4k2ox = here->BSIM4v4k2 * model->BSIM4v4toxe - / model->BSIM4v4toxm; - - here->BSIM4v4eta0 = pParam->BSIM4v4eta0 + deta0_lod; - } else { - here->BSIM4v4u0temp = pParam->BSIM4v4u0temp; - here->BSIM4v4vth0 = pParam->BSIM4v4vth0; - here->BSIM4v4vsattemp = pParam->BSIM4v4vsattemp; - here->BSIM4v4vfb = pParam->BSIM4v4vfb; - here->BSIM4v4vfbzb = pParam->BSIM4v4vfbzb; - here->BSIM4v4vtfbphi1 = pParam->BSIM4v4vtfbphi1; - here->BSIM4v4vtfbphi2 = pParam->BSIM4v4vtfbphi2; - here->BSIM4v4k2 = pParam->BSIM4v4k2; - here->BSIM4v4vbsc = pParam->BSIM4v4vbsc; - here->BSIM4v4k2ox = pParam->BSIM4v4k2ox; - here->BSIM4v4eta0 = pParam->BSIM4v4eta0; + break; + default: break; } here->BSIM4v4cgso = pParam->BSIM4v4cgso; @@ -1423,7 +1531,7 @@ int Size_Not_Found, i; /* * Process geomertry dependent parasitics - */ + */ here->BSIM4v4grgeltd = model->BSIM4v4rshg * (model->BSIM4v4xgw + pParam->BSIM4v4weffCJ / 3.0 / model->BSIM4v4ngcon) / @@ -1433,53 +1541,53 @@ int Size_Not_Found, i; here->BSIM4v4grgeltd = 1.0 / here->BSIM4v4grgeltd; else { here->BSIM4v4grgeltd = 1.0e3; /* mho */ - if (here->BSIM4v4rgateMod != 0) + if (here->BSIM4v4rgateMod != 0) printf("Warning: The gate conductance reset to 1.0e3 mho.\n"); } - DMCGeff = model->BSIM4v4dmcg - model->BSIM4v4dmcgt; + DMCGeff = model->BSIM4v4dmcg - model->BSIM4v4dmcgt; DMCIeff = model->BSIM4v4dmci; DMDGeff = model->BSIM4v4dmdg - model->BSIM4v4dmcgt; - if (here->BSIM4v4sourcePerimeterGiven) - { if (model->BSIM4v4perMod == 0) - here->BSIM4v4Pseff = here->BSIM4v4sourcePerimeter; - else - here->BSIM4v4Pseff = here->BSIM4v4sourcePerimeter - - pParam->BSIM4v4weffCJ * here->BSIM4v4nf; - } - else - BSIM4v4PAeffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4min, + if (here->BSIM4v4sourcePerimeterGiven) + { if (model->BSIM4v4perMod == 0) + here->BSIM4v4Pseff = here->BSIM4v4sourcePerimeter; + else + here->BSIM4v4Pseff = here->BSIM4v4sourcePerimeter + - pParam->BSIM4v4weffCJ * here->BSIM4v4nf; + } + else + BSIM4v4PAeffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4min, pParam->BSIM4v4weffCJ, DMCGeff, DMCIeff, DMDGeff, - &(here->BSIM4v4Pseff), &dumPd, &dumAs, &dumAd); + &(here->BSIM4v4Pseff), &dumPd, &dumAs, &dumAd); if (here->BSIM4v4drainPerimeterGiven) { if (model->BSIM4v4perMod == 0) here->BSIM4v4Pdeff = here->BSIM4v4drainPerimeter; else here->BSIM4v4Pdeff = here->BSIM4v4drainPerimeter - - pParam->BSIM4v4weffCJ * here->BSIM4v4nf; + - pParam->BSIM4v4weffCJ * here->BSIM4v4nf; } else BSIM4v4PAeffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4min, pParam->BSIM4v4weffCJ, DMCGeff, DMCIeff, DMDGeff, - &dumPs, &(here->BSIM4v4Pdeff), &dumAs, &dumAd); + &dumPs, &(here->BSIM4v4Pdeff), &dumAs, &dumAd); if (here->BSIM4v4sourceAreaGiven) here->BSIM4v4Aseff = here->BSIM4v4sourceArea; else BSIM4v4PAeffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4min, pParam->BSIM4v4weffCJ, DMCGeff, DMCIeff, DMDGeff, - &dumPs, &dumPd, &(here->BSIM4v4Aseff), &dumAd); + &dumPs, &dumPd, &(here->BSIM4v4Aseff), &dumAd); if (here->BSIM4v4drainAreaGiven) here->BSIM4v4Adeff = here->BSIM4v4drainArea; else BSIM4v4PAeffGeo(here->BSIM4v4nf, here->BSIM4v4geoMod, here->BSIM4v4min, pParam->BSIM4v4weffCJ, DMCGeff, DMCIeff, DMDGeff, - &dumPs, &dumPd, &dumAs, &(here->BSIM4v4Adeff)); + &dumPs, &dumPd, &dumAs, &(here->BSIM4v4Adeff)); - /* Processing S/D resistance and conductance below */ + /* Processing S/D resistance and conductance below */ if(here->BSIM4v4sNodePrime != here->BSIM4v4sNode) { here->BSIM4v4sourceConductance = 0.0; @@ -1551,52 +1659,52 @@ int Size_Not_Found, i; } else { SourceSatCurrent = here->BSIM4v4Aseff * model->BSIM4v4SjctTempSatCurDensity - + here->BSIM4v4Pseff * model->BSIM4v4SjctSidewallTempSatCurDensity + + here->BSIM4v4Pseff * model->BSIM4v4SjctSidewallTempSatCurDensity + pParam->BSIM4v4weffCJ * here->BSIM4v4nf * model->BSIM4v4SjctGateSidewallTempSatCurDensity; } if (SourceSatCurrent > 0.0) { switch(model->BSIM4v4dioMod) { case 0: - if ((model->BSIM4v4bvs / Nvtms) > EXP_THRESHOLD) - here->BSIM4v4XExpBVS = model->BSIM4v4xjbvs * MIN_EXP; - else - here->BSIM4v4XExpBVS = model->BSIM4v4xjbvs * exp(-model->BSIM4v4bvs / Nvtms); - break; + if ((model->BSIM4v4bvs / Nvtms) > EXP_THRESHOLD) + here->BSIM4v4XExpBVS = model->BSIM4v4xjbvs * MIN_EXP; + else + here->BSIM4v4XExpBVS = model->BSIM4v4xjbvs * exp(-model->BSIM4v4bvs / Nvtms); + break; case 1: BSIM4v4DioIjthVjmEval(Nvtms, model->BSIM4v4ijthsfwd, SourceSatCurrent, - 0.0, &(here->BSIM4v4vjsmFwd)); + 0.0, &(here->BSIM4v4vjsmFwd)); here->BSIM4v4IVjsmFwd = SourceSatCurrent * exp(here->BSIM4v4vjsmFwd / Nvtms); break; case 2: if ((model->BSIM4v4bvs / Nvtms) > EXP_THRESHOLD) { here->BSIM4v4XExpBVS = model->BSIM4v4xjbvs * MIN_EXP; - tmp = MIN_EXP; - } + tmp = MIN_EXP; + } else - { here->BSIM4v4XExpBVS = exp(-model->BSIM4v4bvs / Nvtms); - tmp = here->BSIM4v4XExpBVS; - here->BSIM4v4XExpBVS *= model->BSIM4v4xjbvs; - } + { here->BSIM4v4XExpBVS = exp(-model->BSIM4v4bvs / Nvtms); + tmp = here->BSIM4v4XExpBVS; + here->BSIM4v4XExpBVS *= model->BSIM4v4xjbvs; + } BSIM4v4DioIjthVjmEval(Nvtms, model->BSIM4v4ijthsfwd, SourceSatCurrent, - here->BSIM4v4XExpBVS, &(here->BSIM4v4vjsmFwd)); - T0 = exp(here->BSIM4v4vjsmFwd / Nvtms); + here->BSIM4v4XExpBVS, &(here->BSIM4v4vjsmFwd)); + T0 = exp(here->BSIM4v4vjsmFwd / Nvtms); here->BSIM4v4IVjsmFwd = SourceSatCurrent * (T0 - here->BSIM4v4XExpBVS / T0 - + here->BSIM4v4XExpBVS - 1.0); - here->BSIM4v4SslpFwd = SourceSatCurrent - * (T0 + here->BSIM4v4XExpBVS / T0) / Nvtms; + + here->BSIM4v4XExpBVS - 1.0); + here->BSIM4v4SslpFwd = SourceSatCurrent + * (T0 + here->BSIM4v4XExpBVS / T0) / Nvtms; - T2 = model->BSIM4v4ijthsrev / SourceSatCurrent; - if (T2 < 1.0) - { T2 = 10.0; - fprintf(stderr, "Warning: ijthsrev too small and set to 10 times IsbSat.\n"); - } + T2 = model->BSIM4v4ijthsrev / SourceSatCurrent; + if (T2 < 1.0) + { T2 = 10.0; + fprintf(stderr, "Warning: ijthsrev too small and set to 10 times IsbSat.\n"); + } here->BSIM4v4vjsmRev = -model->BSIM4v4bvs - - Nvtms * log((T2 - 1.0) / model->BSIM4v4xjbvs); - T1 = model->BSIM4v4xjbvs * exp(-(model->BSIM4v4bvs - + here->BSIM4v4vjsmRev) / Nvtms); - here->BSIM4v4IVjsmRev = SourceSatCurrent * (1.0 + T1); + - Nvtms * log((T2 - 1.0) / model->BSIM4v4xjbvs); + T1 = model->BSIM4v4xjbvs * exp(-(model->BSIM4v4bvs + + here->BSIM4v4vjsmRev) / Nvtms); + here->BSIM4v4IVjsmRev = SourceSatCurrent * (1.0 + T1); here->BSIM4v4SslpRev = -SourceSatCurrent * T1 / Nvtms; break; default: @@ -1605,12 +1713,12 @@ int Size_Not_Found, i; } Nvtmd = model->BSIM4v4vtm * model->BSIM4v4DjctEmissionCoeff; - if ((here->BSIM4v4Adeff <= 0.0) && (here->BSIM4v4Pdeff <= 0.0)) + if ((here->BSIM4v4Adeff <= 0.0) && (here->BSIM4v4Pdeff <= 0.0)) { DrainSatCurrent = 1.0e-14; } else { DrainSatCurrent = here->BSIM4v4Adeff * model->BSIM4v4DjctTempSatCurDensity - + here->BSIM4v4Pdeff * model->BSIM4v4DjctSidewallTempSatCurDensity + + here->BSIM4v4Pdeff * model->BSIM4v4DjctSidewallTempSatCurDensity + pParam->BSIM4v4weffCJ * here->BSIM4v4nf * model->BSIM4v4DjctGateSidewallTempSatCurDensity; } @@ -1651,8 +1759,17 @@ int Size_Not_Found, i; { T2 = 10.0; fprintf(stderr, "Warning: ijthdrev too small and set to 10 times IdbSat.\n"); } - here->BSIM4v4vjdmRev = -model->BSIM4v4bvd - - Nvtmd * log((T2 - 1.0) / model->BSIM4v4xjbvd); /* bugfix */ + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + here->BSIM4v4vjdmRev = -model->BSIM4v4bvd + - Nvtms * log((T2 - 1.0) / model->BSIM4v4xjbvd); + break; + case BSIM4v30: case BSIM4v40: + here->BSIM4v4vjdmRev = -model->BSIM4v4bvd + - Nvtmd * log((T2 - 1.0) / model->BSIM4v4xjbvd); /* bugfix */ + break; + default: break; + } T1 = model->BSIM4v4xjbvd * exp(-(model->BSIM4v4bvd + here->BSIM4v4vjdmRev) / Nvtmd); here->BSIM4v4IVjdmRev = DrainSatCurrent * (1.0 + T1); @@ -1663,39 +1780,56 @@ int Size_Not_Found, i; } } - /* GEDL current reverse bias */ - T0 = (TRatio - 1.0); - model->BSIM4v4njtstemp = model->BSIM4v4njts * (1.0 + model->BSIM4v4tnjts * T0); - model->BSIM4v4njtsswtemp = model->BSIM4v4njtssw * (1.0 + model->BSIM4v4tnjtssw * T0); - model->BSIM4v4njtsswgtemp = model->BSIM4v4njtsswg * (1.0 + model->BSIM4v4tnjtsswg * T0); - T7 = Eg0 / model->BSIM4v4vtm * T0; - T9 = model->BSIM4v4xtss * T7; - DEXP(T9, T1); - T9 = model->BSIM4v4xtsd * T7; - DEXP(T9, T2); - T9 = model->BSIM4v4xtssws * T7; - DEXP(T9, T3); - T9 = model->BSIM4v4xtsswd * T7; - DEXP(T9, T4); - T9 = model->BSIM4v4xtsswgs * T7; - DEXP(T9, T5); - T9 = model->BSIM4v4xtsswgd * T7; - DEXP(T9, T6); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: case BSIM4v30: + break; + case BSIM4v40: + /* GEDL current reverse bias */ + T0 = (TRatio - 1.0); + model->BSIM4v4njtstemp = model->BSIM4v4njts * (1.0 + model->BSIM4v4tnjts * T0); + model->BSIM4v4njtsswtemp = model->BSIM4v4njtssw * (1.0 + model->BSIM4v4tnjtssw * T0); + model->BSIM4v4njtsswgtemp = model->BSIM4v4njtsswg * (1.0 + model->BSIM4v4tnjtsswg * T0); + T7 = Eg0 / model->BSIM4v4vtm * T0; + T9 = model->BSIM4v4xtss * T7; + DEXP(T9, T1); + T9 = model->BSIM4v4xtsd * T7; + DEXP(T9, T2); + T9 = model->BSIM4v4xtssws * T7; + DEXP(T9, T3); + T9 = model->BSIM4v4xtsswd * T7; + DEXP(T9, T4); + T9 = model->BSIM4v4xtsswgs * T7; + DEXP(T9, T5); + T9 = model->BSIM4v4xtsswgd * T7; + DEXP(T9, T6); - T10 = pParam->BSIM4v4weffCJ * here->BSIM4v4nf; - here->BSIM4v4SjctTempRevSatCur = T1 * here->BSIM4v4Aseff * model->BSIM4v4jtss; - here->BSIM4v4DjctTempRevSatCur = T2 * here->BSIM4v4Adeff * model->BSIM4v4jtsd; - here->BSIM4v4SswTempRevSatCur = T3 * here->BSIM4v4Pseff * model->BSIM4v4jtssws; - here->BSIM4v4DswTempRevSatCur = T4 * here->BSIM4v4Pdeff * model->BSIM4v4jtsswd; - here->BSIM4v4SswgTempRevSatCur = T5 * T10 * model->BSIM4v4jtsswgs; - here->BSIM4v4DswgTempRevSatCur = T6 * T10 * model->BSIM4v4jtsswgd; - + T10 = pParam->BSIM4v4weffCJ * here->BSIM4v4nf; + here->BSIM4v4SjctTempRevSatCur = T1 * here->BSIM4v4Aseff * model->BSIM4v4jtss; + here->BSIM4v4DjctTempRevSatCur = T2 * here->BSIM4v4Adeff * model->BSIM4v4jtsd; + here->BSIM4v4SswTempRevSatCur = T3 * here->BSIM4v4Pseff * model->BSIM4v4jtssws; + here->BSIM4v4DswTempRevSatCur = T4 * here->BSIM4v4Pdeff * model->BSIM4v4jtsswd; + here->BSIM4v4SswgTempRevSatCur = T5 * T10 * model->BSIM4v4jtsswgs; + here->BSIM4v4DswgTempRevSatCur = T6 * T10 * model->BSIM4v4jtsswgd; + break; + default: break; + } if (BSIM4v4checkModel(model, here, ckt)) { IFuid namarray[2]; namarray[0] = model->BSIM4v4modName; namarray[1] = here->BSIM4v4name; - SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM4.4.0 parameter checking for %s in model %s", namarray); + switch (model->BSIM4v4intVersion) { + case BSIM4vOLD: case BSIM4v21: + SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM4v4.2.1 parameter checking for %s in model %s", namarray); + break; + case BSIM4v30: + SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM4v4.3.0 parameter checking for %s in model %s", namarray); + break; + case BSIM4v40: + SPfrontEnd->IFerror (ERR_FATAL, "Fatal error(s) detected during BSIM4v4.4.0 parameter checking for %s in model %s", namarray); + break; + default: break; + } return(E_BADPARM); } } /* End instance */ diff --git a/src/spicelib/devices/bsim4v4/bsim4v4def.h b/src/spicelib/devices/bsim4v4/bsim4v4def.h index 9e21f2878..f6168f156 100644 --- a/src/spicelib/devices/bsim4v4/bsim4v4def.h +++ b/src/spicelib/devices/bsim4v4/bsim4v4def.h @@ -1,3 +1,4 @@ +/* ngspice multirevision code extension covering 4.2.1 & 4.3.0 & 4.4.0 */ /********** Copyright 2004 Regents of the University of California. All rights reserved. Author: 2000 Weidong Liu. @@ -14,7 +15,7 @@ File: bsim4v4def.h #include "gendefs.h" #include "cktdefs.h" #include "complex.h" -#include "noisedef.h" +#include "noisedef.h" typedef struct sBSIM4v4instance { @@ -37,7 +38,7 @@ typedef struct sBSIM4v4instance int BSIM4v4qNode; double BSIM4v4ueff; - double BSIM4v4thetavth; + double BSIM4v4thetavth; double BSIM4v4von; double BSIM4v4vdsat; double BSIM4v4cgdo; @@ -429,31 +430,31 @@ struct bsim4SizeDependParam double Length; double NFinger; - double BSIM4v4cdsc; - double BSIM4v4cdscb; - double BSIM4v4cdscd; - double BSIM4v4cit; - double BSIM4v4nfactor; + double BSIM4v4cdsc; + double BSIM4v4cdscb; + double BSIM4v4cdscd; + double BSIM4v4cit; + double BSIM4v4nfactor; double BSIM4v4xj; - double BSIM4v4vsat; - double BSIM4v4at; - double BSIM4v4a0; - double BSIM4v4ags; - double BSIM4v4a1; - double BSIM4v4a2; - double BSIM4v4keta; + double BSIM4v4vsat; + double BSIM4v4at; + double BSIM4v4a0; + double BSIM4v4ags; + double BSIM4v4a1; + double BSIM4v4a2; + double BSIM4v4keta; double BSIM4v4nsub; - double BSIM4v4ndep; + double BSIM4v4ndep; double BSIM4v4nsd; double BSIM4v4phin; - double BSIM4v4ngate; - double BSIM4v4gamma1; - double BSIM4v4gamma2; - double BSIM4v4vbx; - double BSIM4v4vbi; - double BSIM4v4vbm; - double BSIM4v4vbsc; - double BSIM4v4xt; + double BSIM4v4ngate; + double BSIM4v4gamma1; + double BSIM4v4gamma2; + double BSIM4v4vbx; + double BSIM4v4vbi; + double BSIM4v4vbm; + double BSIM4v4vbsc; + double BSIM4v4xt; double BSIM4v4phi; double BSIM4v4litl; double BSIM4v4k1; @@ -468,14 +469,14 @@ struct bsim4SizeDependParam double BSIM4v4dvtp1; double BSIM4v4lpe0; double BSIM4v4lpeb; - double BSIM4v4dvt0; - double BSIM4v4dvt1; - double BSIM4v4dvt2; - double BSIM4v4dvt0w; - double BSIM4v4dvt1w; - double BSIM4v4dvt2w; - double BSIM4v4drout; - double BSIM4v4dsub; + double BSIM4v4dvt0; + double BSIM4v4dvt1; + double BSIM4v4dvt2; + double BSIM4v4dvt0w; + double BSIM4v4dvt1w; + double BSIM4v4dvt2w; + double BSIM4v4drout; + double BSIM4v4dsub; double BSIM4v4vth0; double BSIM4v4ua; double BSIM4v4ua1; @@ -490,27 +491,27 @@ struct bsim4SizeDependParam double BSIM4v4minv; double BSIM4v4vfb; double BSIM4v4delta; - double BSIM4v4rdsw; - double BSIM4v4rds0; + double BSIM4v4rdsw; + double BSIM4v4rds0; double BSIM4v4rs0; double BSIM4v4rd0; double BSIM4v4rsw; double BSIM4v4rdw; - double BSIM4v4prwg; - double BSIM4v4prwb; - double BSIM4v4prt; - double BSIM4v4eta0; - double BSIM4v4etab; - double BSIM4v4pclm; - double BSIM4v4pdibl1; - double BSIM4v4pdibl2; - double BSIM4v4pdiblb; + double BSIM4v4prwg; + double BSIM4v4prwb; + double BSIM4v4prt; + double BSIM4v4eta0; + double BSIM4v4etab; + double BSIM4v4pclm; + double BSIM4v4pdibl1; + double BSIM4v4pdibl2; + double BSIM4v4pdiblb; double BSIM4v4fprout; double BSIM4v4pdits; double BSIM4v4pditsd; - double BSIM4v4pscbe1; - double BSIM4v4pscbe2; - double BSIM4v4pvag; + double BSIM4v4pscbe1; + double BSIM4v4pscbe2; + double BSIM4v4pvag; double BSIM4v4wr; double BSIM4v4dwg; double BSIM4v4dwb; @@ -591,14 +592,14 @@ struct bsim4SizeDependParam double BSIM4v4cgdo; double BSIM4v4cgbo; - double BSIM4v4u0temp; - double BSIM4v4vsattemp; - double BSIM4v4sqrtPhi; - double BSIM4v4phis3; - double BSIM4v4Xdep0; - double BSIM4v4sqrtXdep0; + double BSIM4v4u0temp; + double BSIM4v4vsattemp; + double BSIM4v4sqrtPhi; + double BSIM4v4phis3; + double BSIM4v4Xdep0; + double BSIM4v4sqrtXdep0; double BSIM4v4theta0vb0; - double BSIM4v4thetaRout; + double BSIM4v4thetaRout; double BSIM4v4mstar; double BSIM4v4voffcbn; double BSIM4v4rdswmin; @@ -628,12 +629,12 @@ struct bsim4SizeDependParam }; -typedef struct sBSIM4v4model +typedef struct sBSIM4v4model { int BSIM4v4modType; struct sBSIM4v4model *BSIM4v4nextModel; BSIM4v4instance *BSIM4v4instances; - IFuid BSIM4v4modName; + IFuid BSIM4v4modName; int BSIM4v4type; int BSIM4v4mobMod; @@ -653,35 +654,43 @@ typedef struct sBSIM4v4model int BSIM4v4tempMod; int BSIM4v4binUnit; int BSIM4v4paramChk; - char *BSIM4v4version; - double BSIM4v4toxe; + char *BSIM4v4version; + /* The following field is an integer coding + * of BSIM4 Versions. + */ + int BSIM4v4intVersion; +#define BSIM4v40 440 /* BSIM4.4.0 */ +#define BSIM4v30 430 /* BSIM4.3.0 */ +#define BSIM4v21 421 /* BSIM4.2.1 */ +#define BSIM4vOLD 420 /* < BSIM4.2.1 */ + double BSIM4v4toxe; double BSIM4v4toxp; double BSIM4v4toxm; double BSIM4v4dtox; double BSIM4v4epsrox; - double BSIM4v4cdsc; - double BSIM4v4cdscb; - double BSIM4v4cdscd; - double BSIM4v4cit; - double BSIM4v4nfactor; + double BSIM4v4cdsc; + double BSIM4v4cdscb; + double BSIM4v4cdscd; + double BSIM4v4cit; + double BSIM4v4nfactor; double BSIM4v4xj; - double BSIM4v4vsat; - double BSIM4v4at; - double BSIM4v4a0; - double BSIM4v4ags; - double BSIM4v4a1; - double BSIM4v4a2; - double BSIM4v4keta; + double BSIM4v4vsat; + double BSIM4v4at; + double BSIM4v4a0; + double BSIM4v4ags; + double BSIM4v4a1; + double BSIM4v4a2; + double BSIM4v4keta; double BSIM4v4nsub; - double BSIM4v4ndep; + double BSIM4v4ndep; double BSIM4v4nsd; double BSIM4v4phin; - double BSIM4v4ngate; - double BSIM4v4gamma1; - double BSIM4v4gamma2; - double BSIM4v4vbx; - double BSIM4v4vbm; - double BSIM4v4xt; + double BSIM4v4ngate; + double BSIM4v4gamma1; + double BSIM4v4gamma2; + double BSIM4v4vbx; + double BSIM4v4vbm; + double BSIM4v4xt; double BSIM4v4k1; double BSIM4v4kt1; double BSIM4v4kt1l; @@ -694,14 +703,14 @@ typedef struct sBSIM4v4model double BSIM4v4dvtp1; double BSIM4v4lpe0; double BSIM4v4lpeb; - double BSIM4v4dvt0; - double BSIM4v4dvt1; - double BSIM4v4dvt2; - double BSIM4v4dvt0w; - double BSIM4v4dvt1w; - double BSIM4v4dvt2w; - double BSIM4v4drout; - double BSIM4v4dsub; + double BSIM4v4dvt0; + double BSIM4v4dvt1; + double BSIM4v4dvt2; + double BSIM4v4dvt0w; + double BSIM4v4dvt1w; + double BSIM4v4dvt2w; + double BSIM4v4drout; + double BSIM4v4dsub; double BSIM4v4vth0; double BSIM4v4eu; double BSIM4v4ua; @@ -716,7 +725,7 @@ typedef struct sBSIM4v4model double BSIM4v4minv; double BSIM4v4voffl; double BSIM4v4delta; - double BSIM4v4rdsw; + double BSIM4v4rdsw; double BSIM4v4rdswmin; double BSIM4v4rdwmin; double BSIM4v4rswmin; @@ -724,20 +733,20 @@ typedef struct sBSIM4v4model double BSIM4v4rdw; double BSIM4v4prwg; double BSIM4v4prwb; - double BSIM4v4prt; - double BSIM4v4eta0; - double BSIM4v4etab; - double BSIM4v4pclm; - double BSIM4v4pdibl1; - double BSIM4v4pdibl2; + double BSIM4v4prt; + double BSIM4v4eta0; + double BSIM4v4etab; + double BSIM4v4pclm; + double BSIM4v4pdibl1; + double BSIM4v4pdibl2; double BSIM4v4pdiblb; double BSIM4v4fprout; double BSIM4v4pdits; double BSIM4v4pditsd; double BSIM4v4pditsl; - double BSIM4v4pscbe1; - double BSIM4v4pscbe2; - double BSIM4v4pvag; + double BSIM4v4pscbe1; + double BSIM4v4pscbe2; + double BSIM4v4pvag; double BSIM4v4wr; double BSIM4v4dwg; double BSIM4v4dwb; @@ -807,9 +816,9 @@ typedef struct sBSIM4v4model double BSIM4v4xrcrg1; double BSIM4v4xrcrg2; double BSIM4v4lambda; - double BSIM4v4vtl; - double BSIM4v4lc; - double BSIM4v4xn; + double BSIM4v4vtl; + double BSIM4v4lc; + double BSIM4v4xn; double BSIM4v4vfbsdoff; /* S/D flatband offset voltage */ double BSIM4v4lintnoi; /* lint offset for noise calculation */ @@ -861,29 +870,29 @@ typedef struct sBSIM4v4model double BSIM4v4ngcon; /* Length Dependence */ - double BSIM4v4lcdsc; - double BSIM4v4lcdscb; - double BSIM4v4lcdscd; - double BSIM4v4lcit; - double BSIM4v4lnfactor; + double BSIM4v4lcdsc; + double BSIM4v4lcdscb; + double BSIM4v4lcdscd; + double BSIM4v4lcit; + double BSIM4v4lnfactor; double BSIM4v4lxj; - double BSIM4v4lvsat; - double BSIM4v4lat; - double BSIM4v4la0; - double BSIM4v4lags; - double BSIM4v4la1; - double BSIM4v4la2; - double BSIM4v4lketa; + double BSIM4v4lvsat; + double BSIM4v4lat; + double BSIM4v4la0; + double BSIM4v4lags; + double BSIM4v4la1; + double BSIM4v4la2; + double BSIM4v4lketa; double BSIM4v4lnsub; - double BSIM4v4lndep; + double BSIM4v4lndep; double BSIM4v4lnsd; double BSIM4v4lphin; - double BSIM4v4lngate; - double BSIM4v4lgamma1; - double BSIM4v4lgamma2; - double BSIM4v4lvbx; - double BSIM4v4lvbm; - double BSIM4v4lxt; + double BSIM4v4lngate; + double BSIM4v4lgamma1; + double BSIM4v4lgamma2; + double BSIM4v4lvbx; + double BSIM4v4lvbm; + double BSIM4v4lxt; double BSIM4v4lk1; double BSIM4v4lkt1; double BSIM4v4lkt1l; @@ -896,14 +905,14 @@ typedef struct sBSIM4v4model double BSIM4v4ldvtp1; double BSIM4v4llpe0; double BSIM4v4llpeb; - double BSIM4v4ldvt0; - double BSIM4v4ldvt1; - double BSIM4v4ldvt2; - double BSIM4v4ldvt0w; - double BSIM4v4ldvt1w; - double BSIM4v4ldvt2w; - double BSIM4v4ldrout; - double BSIM4v4ldsub; + double BSIM4v4ldvt0; + double BSIM4v4ldvt1; + double BSIM4v4ldvt2; + double BSIM4v4ldvt0w; + double BSIM4v4ldvt1w; + double BSIM4v4ldvt2w; + double BSIM4v4ldrout; + double BSIM4v4ldsub; double BSIM4v4lvth0; double BSIM4v4lua; double BSIM4v4lua1; @@ -917,24 +926,24 @@ typedef struct sBSIM4v4model double BSIM4v4lvoff; double BSIM4v4lminv; double BSIM4v4ldelta; - double BSIM4v4lrdsw; + double BSIM4v4lrdsw; double BSIM4v4lrsw; double BSIM4v4lrdw; double BSIM4v4lprwg; double BSIM4v4lprwb; - double BSIM4v4lprt; - double BSIM4v4leta0; - double BSIM4v4letab; - double BSIM4v4lpclm; - double BSIM4v4lpdibl1; - double BSIM4v4lpdibl2; + double BSIM4v4lprt; + double BSIM4v4leta0; + double BSIM4v4letab; + double BSIM4v4lpclm; + double BSIM4v4lpdibl1; + double BSIM4v4lpdibl2; double BSIM4v4lpdiblb; double BSIM4v4lfprout; double BSIM4v4lpdits; double BSIM4v4lpditsd; - double BSIM4v4lpscbe1; - double BSIM4v4lpscbe2; - double BSIM4v4lpvag; + double BSIM4v4lpscbe1; + double BSIM4v4lpscbe2; + double BSIM4v4lpvag; double BSIM4v4lwr; double BSIM4v4ldwg; double BSIM4v4ldwb; @@ -970,9 +979,9 @@ typedef struct sBSIM4v4model double BSIM4v4lxrcrg1; double BSIM4v4lxrcrg2; double BSIM4v4llambda; - double BSIM4v4lvtl; - double BSIM4v4lxn; - double BSIM4v4lvfbsdoff; + double BSIM4v4lvtl; + double BSIM4v4lxn; + double BSIM4v4lvfbsdoff; /* CV model */ double BSIM4v4lcgsl; @@ -989,29 +998,29 @@ typedef struct sBSIM4v4model double BSIM4v4lmoin; /* Width Dependence */ - double BSIM4v4wcdsc; - double BSIM4v4wcdscb; - double BSIM4v4wcdscd; - double BSIM4v4wcit; - double BSIM4v4wnfactor; + double BSIM4v4wcdsc; + double BSIM4v4wcdscb; + double BSIM4v4wcdscd; + double BSIM4v4wcit; + double BSIM4v4wnfactor; double BSIM4v4wxj; - double BSIM4v4wvsat; - double BSIM4v4wat; - double BSIM4v4wa0; - double BSIM4v4wags; - double BSIM4v4wa1; - double BSIM4v4wa2; - double BSIM4v4wketa; + double BSIM4v4wvsat; + double BSIM4v4wat; + double BSIM4v4wa0; + double BSIM4v4wags; + double BSIM4v4wa1; + double BSIM4v4wa2; + double BSIM4v4wketa; double BSIM4v4wnsub; - double BSIM4v4wndep; + double BSIM4v4wndep; double BSIM4v4wnsd; double BSIM4v4wphin; - double BSIM4v4wngate; - double BSIM4v4wgamma1; - double BSIM4v4wgamma2; - double BSIM4v4wvbx; - double BSIM4v4wvbm; - double BSIM4v4wxt; + double BSIM4v4wngate; + double BSIM4v4wgamma1; + double BSIM4v4wgamma2; + double BSIM4v4wvbx; + double BSIM4v4wvbm; + double BSIM4v4wxt; double BSIM4v4wk1; double BSIM4v4wkt1; double BSIM4v4wkt1l; @@ -1024,14 +1033,14 @@ typedef struct sBSIM4v4model double BSIM4v4wdvtp1; double BSIM4v4wlpe0; double BSIM4v4wlpeb; - double BSIM4v4wdvt0; - double BSIM4v4wdvt1; - double BSIM4v4wdvt2; - double BSIM4v4wdvt0w; - double BSIM4v4wdvt1w; - double BSIM4v4wdvt2w; - double BSIM4v4wdrout; - double BSIM4v4wdsub; + double BSIM4v4wdvt0; + double BSIM4v4wdvt1; + double BSIM4v4wdvt2; + double BSIM4v4wdvt0w; + double BSIM4v4wdvt1w; + double BSIM4v4wdvt2w; + double BSIM4v4wdrout; + double BSIM4v4wdsub; double BSIM4v4wvth0; double BSIM4v4wua; double BSIM4v4wua1; @@ -1045,24 +1054,24 @@ typedef struct sBSIM4v4model double BSIM4v4wvoff; double BSIM4v4wminv; double BSIM4v4wdelta; - double BSIM4v4wrdsw; + double BSIM4v4wrdsw; double BSIM4v4wrsw; double BSIM4v4wrdw; double BSIM4v4wprwg; double BSIM4v4wprwb; - double BSIM4v4wprt; - double BSIM4v4weta0; - double BSIM4v4wetab; - double BSIM4v4wpclm; - double BSIM4v4wpdibl1; - double BSIM4v4wpdibl2; + double BSIM4v4wprt; + double BSIM4v4weta0; + double BSIM4v4wetab; + double BSIM4v4wpclm; + double BSIM4v4wpdibl1; + double BSIM4v4wpdibl2; double BSIM4v4wpdiblb; double BSIM4v4wfprout; double BSIM4v4wpdits; double BSIM4v4wpditsd; - double BSIM4v4wpscbe1; - double BSIM4v4wpscbe2; - double BSIM4v4wpvag; + double BSIM4v4wpscbe1; + double BSIM4v4wpscbe2; + double BSIM4v4wpvag; double BSIM4v4wwr; double BSIM4v4wdwg; double BSIM4v4wdwb; @@ -1098,9 +1107,9 @@ typedef struct sBSIM4v4model double BSIM4v4wxrcrg1; double BSIM4v4wxrcrg2; double BSIM4v4wlambda; - double BSIM4v4wvtl; - double BSIM4v4wxn; - double BSIM4v4wvfbsdoff; + double BSIM4v4wvtl; + double BSIM4v4wxn; + double BSIM4v4wvfbsdoff; /* CV model */ double BSIM4v4wcgsl; @@ -1117,29 +1126,29 @@ typedef struct sBSIM4v4model double BSIM4v4wmoin; /* Cross-term Dependence */ - double BSIM4v4pcdsc; - double BSIM4v4pcdscb; - double BSIM4v4pcdscd; - double BSIM4v4pcit; - double BSIM4v4pnfactor; + double BSIM4v4pcdsc; + double BSIM4v4pcdscb; + double BSIM4v4pcdscd; + double BSIM4v4pcit; + double BSIM4v4pnfactor; double BSIM4v4pxj; - double BSIM4v4pvsat; - double BSIM4v4pat; - double BSIM4v4pa0; - double BSIM4v4pags; - double BSIM4v4pa1; - double BSIM4v4pa2; - double BSIM4v4pketa; + double BSIM4v4pvsat; + double BSIM4v4pat; + double BSIM4v4pa0; + double BSIM4v4pags; + double BSIM4v4pa1; + double BSIM4v4pa2; + double BSIM4v4pketa; double BSIM4v4pnsub; - double BSIM4v4pndep; + double BSIM4v4pndep; double BSIM4v4pnsd; double BSIM4v4pphin; - double BSIM4v4pngate; - double BSIM4v4pgamma1; - double BSIM4v4pgamma2; - double BSIM4v4pvbx; - double BSIM4v4pvbm; - double BSIM4v4pxt; + double BSIM4v4pngate; + double BSIM4v4pgamma1; + double BSIM4v4pgamma2; + double BSIM4v4pvbx; + double BSIM4v4pvbm; + double BSIM4v4pxt; double BSIM4v4pk1; double BSIM4v4pkt1; double BSIM4v4pkt1l; @@ -1152,14 +1161,14 @@ typedef struct sBSIM4v4model double BSIM4v4pdvtp1; double BSIM4v4plpe0; double BSIM4v4plpeb; - double BSIM4v4pdvt0; - double BSIM4v4pdvt1; - double BSIM4v4pdvt2; - double BSIM4v4pdvt0w; - double BSIM4v4pdvt1w; - double BSIM4v4pdvt2w; - double BSIM4v4pdrout; - double BSIM4v4pdsub; + double BSIM4v4pdvt0; + double BSIM4v4pdvt1; + double BSIM4v4pdvt2; + double BSIM4v4pdvt0w; + double BSIM4v4pdvt1w; + double BSIM4v4pdvt2w; + double BSIM4v4pdrout; + double BSIM4v4pdsub; double BSIM4v4pvth0; double BSIM4v4pua; double BSIM4v4pua1; @@ -1178,19 +1187,19 @@ typedef struct sBSIM4v4model double BSIM4v4prdw; double BSIM4v4pprwg; double BSIM4v4pprwb; - double BSIM4v4pprt; - double BSIM4v4peta0; - double BSIM4v4petab; - double BSIM4v4ppclm; - double BSIM4v4ppdibl1; - double BSIM4v4ppdibl2; + double BSIM4v4pprt; + double BSIM4v4peta0; + double BSIM4v4petab; + double BSIM4v4ppclm; + double BSIM4v4ppdibl1; + double BSIM4v4ppdibl2; double BSIM4v4ppdiblb; double BSIM4v4pfprout; double BSIM4v4ppdits; double BSIM4v4ppditsd; - double BSIM4v4ppscbe1; - double BSIM4v4ppscbe2; - double BSIM4v4ppvag; + double BSIM4v4ppscbe1; + double BSIM4v4ppscbe2; + double BSIM4v4ppvag; double BSIM4v4pwr; double BSIM4v4pdwg; double BSIM4v4pdwb; @@ -1227,8 +1236,8 @@ typedef struct sBSIM4v4model double BSIM4v4pxrcrg2; double BSIM4v4plambda; double BSIM4v4pvtl; - double BSIM4v4pxn; - double BSIM4v4pvfbsdoff; + double BSIM4v4pxn; + double BSIM4v4pvfbsdoff; /* CV model */ double BSIM4v4pcgsl; @@ -1336,8 +1345,8 @@ typedef struct sBSIM4v4model /* Pre-calculated constants * move to size-dependent param */ - double BSIM4v4vtm; - double BSIM4v4vtm0; + double BSIM4v4vtm; + double BSIM4v4vtm0; double BSIM4v4coxe; double BSIM4v4coxp; double BSIM4v4cof1; @@ -1365,13 +1374,13 @@ typedef struct sBSIM4v4model double BSIM4v4SunitLengthGateSidewallTempJctCap; double BSIM4v4DunitLengthGateSidewallTempJctCap; - double BSIM4v4oxideTrapDensityA; - double BSIM4v4oxideTrapDensityB; - double BSIM4v4oxideTrapDensityC; - double BSIM4v4em; - double BSIM4v4ef; - double BSIM4v4af; - double BSIM4v4kf; + double BSIM4v4oxideTrapDensityA; + double BSIM4v4oxideTrapDensityB; + double BSIM4v4oxideTrapDensityC; + double BSIM4v4em; + double BSIM4v4ef; + double BSIM4v4af; + double BSIM4v4kf; struct bsim4SizeDependParam *pSizeDependParamKnot; @@ -1413,7 +1422,7 @@ typedef struct sBSIM4v4model unsigned BSIM4v4agsGiven :1; unsigned BSIM4v4a1Given :1; unsigned BSIM4v4a2Given :1; - unsigned BSIM4v4ketaGiven :1; + unsigned BSIM4v4ketaGiven :1; unsigned BSIM4v4nsubGiven :1; unsigned BSIM4v4ndepGiven :1; unsigned BSIM4v4nsdGiven :1; @@ -1436,14 +1445,14 @@ typedef struct sBSIM4v4model unsigned BSIM4v4dvtp1Given :1; unsigned BSIM4v4lpe0Given :1; unsigned BSIM4v4lpebGiven :1; - unsigned BSIM4v4dvt0Given :1; - unsigned BSIM4v4dvt1Given :1; - unsigned BSIM4v4dvt2Given :1; - unsigned BSIM4v4dvt0wGiven :1; - unsigned BSIM4v4dvt1wGiven :1; - unsigned BSIM4v4dvt2wGiven :1; - unsigned BSIM4v4droutGiven :1; - unsigned BSIM4v4dsubGiven :1; + unsigned BSIM4v4dvt0Given :1; + unsigned BSIM4v4dvt1Given :1; + unsigned BSIM4v4dvt2Given :1; + unsigned BSIM4v4dvt0wGiven :1; + unsigned BSIM4v4dvt1wGiven :1; + unsigned BSIM4v4dvt2wGiven :1; + unsigned BSIM4v4droutGiven :1; + unsigned BSIM4v4dsubGiven :1; unsigned BSIM4v4vth0Given :1; unsigned BSIM4v4euGiven :1; unsigned BSIM4v4uaGiven :1; @@ -1457,29 +1466,29 @@ typedef struct sBSIM4v4model unsigned BSIM4v4voffGiven :1; unsigned BSIM4v4vofflGiven :1; unsigned BSIM4v4minvGiven :1; - unsigned BSIM4v4rdswGiven :1; + unsigned BSIM4v4rdswGiven :1; unsigned BSIM4v4rdswminGiven :1; unsigned BSIM4v4rdwminGiven :1; unsigned BSIM4v4rswminGiven :1; unsigned BSIM4v4rswGiven :1; unsigned BSIM4v4rdwGiven :1; - unsigned BSIM4v4prwgGiven :1; - unsigned BSIM4v4prwbGiven :1; - unsigned BSIM4v4prtGiven :1; - unsigned BSIM4v4eta0Given :1; - unsigned BSIM4v4etabGiven :1; - unsigned BSIM4v4pclmGiven :1; - unsigned BSIM4v4pdibl1Given :1; - unsigned BSIM4v4pdibl2Given :1; - unsigned BSIM4v4pdiblbGiven :1; + unsigned BSIM4v4prwgGiven :1; + unsigned BSIM4v4prwbGiven :1; + unsigned BSIM4v4prtGiven :1; + unsigned BSIM4v4eta0Given :1; + unsigned BSIM4v4etabGiven :1; + unsigned BSIM4v4pclmGiven :1; + unsigned BSIM4v4pdibl1Given :1; + unsigned BSIM4v4pdibl2Given :1; + unsigned BSIM4v4pdiblbGiven :1; unsigned BSIM4v4fproutGiven :1; unsigned BSIM4v4pditsGiven :1; unsigned BSIM4v4pditsdGiven :1; unsigned BSIM4v4pditslGiven :1; - unsigned BSIM4v4pscbe1Given :1; - unsigned BSIM4v4pscbe2Given :1; - unsigned BSIM4v4pvagGiven :1; - unsigned BSIM4v4deltaGiven :1; + unsigned BSIM4v4pscbe1Given :1; + unsigned BSIM4v4pscbe2Given :1; + unsigned BSIM4v4pvagGiven :1; + unsigned BSIM4v4deltaGiven :1; unsigned BSIM4v4wrGiven :1; unsigned BSIM4v4dwgGiven :1; unsigned BSIM4v4dwbGiven :1; @@ -1615,7 +1624,7 @@ typedef struct sBSIM4v4model unsigned BSIM4v4lagsGiven :1; unsigned BSIM4v4la1Given :1; unsigned BSIM4v4la2Given :1; - unsigned BSIM4v4lketaGiven :1; + unsigned BSIM4v4lketaGiven :1; unsigned BSIM4v4lnsubGiven :1; unsigned BSIM4v4lndepGiven :1; unsigned BSIM4v4lnsdGiven :1; @@ -1638,14 +1647,14 @@ typedef struct sBSIM4v4model unsigned BSIM4v4ldvtp1Given :1; unsigned BSIM4v4llpe0Given :1; unsigned BSIM4v4llpebGiven :1; - unsigned BSIM4v4ldvt0Given :1; - unsigned BSIM4v4ldvt1Given :1; - unsigned BSIM4v4ldvt2Given :1; - unsigned BSIM4v4ldvt0wGiven :1; - unsigned BSIM4v4ldvt1wGiven :1; - unsigned BSIM4v4ldvt2wGiven :1; - unsigned BSIM4v4ldroutGiven :1; - unsigned BSIM4v4ldsubGiven :1; + unsigned BSIM4v4ldvt0Given :1; + unsigned BSIM4v4ldvt1Given :1; + unsigned BSIM4v4ldvt2Given :1; + unsigned BSIM4v4ldvt0wGiven :1; + unsigned BSIM4v4ldvt1wGiven :1; + unsigned BSIM4v4ldvt2wGiven :1; + unsigned BSIM4v4ldroutGiven :1; + unsigned BSIM4v4ldsubGiven :1; unsigned BSIM4v4lvth0Given :1; unsigned BSIM4v4luaGiven :1; unsigned BSIM4v4lua1Given :1; @@ -1658,25 +1667,25 @@ typedef struct sBSIM4v4model unsigned BSIM4v4luteGiven :1; unsigned BSIM4v4lvoffGiven :1; unsigned BSIM4v4lminvGiven :1; - unsigned BSIM4v4lrdswGiven :1; + unsigned BSIM4v4lrdswGiven :1; unsigned BSIM4v4lrswGiven :1; unsigned BSIM4v4lrdwGiven :1; - unsigned BSIM4v4lprwgGiven :1; - unsigned BSIM4v4lprwbGiven :1; - unsigned BSIM4v4lprtGiven :1; - unsigned BSIM4v4leta0Given :1; - unsigned BSIM4v4letabGiven :1; - unsigned BSIM4v4lpclmGiven :1; - unsigned BSIM4v4lpdibl1Given :1; - unsigned BSIM4v4lpdibl2Given :1; - unsigned BSIM4v4lpdiblbGiven :1; + unsigned BSIM4v4lprwgGiven :1; + unsigned BSIM4v4lprwbGiven :1; + unsigned BSIM4v4lprtGiven :1; + unsigned BSIM4v4leta0Given :1; + unsigned BSIM4v4letabGiven :1; + unsigned BSIM4v4lpclmGiven :1; + unsigned BSIM4v4lpdibl1Given :1; + unsigned BSIM4v4lpdibl2Given :1; + unsigned BSIM4v4lpdiblbGiven :1; unsigned BSIM4v4lfproutGiven :1; unsigned BSIM4v4lpditsGiven :1; unsigned BSIM4v4lpditsdGiven :1; - unsigned BSIM4v4lpscbe1Given :1; - unsigned BSIM4v4lpscbe2Given :1; - unsigned BSIM4v4lpvagGiven :1; - unsigned BSIM4v4ldeltaGiven :1; + unsigned BSIM4v4lpscbe1Given :1; + unsigned BSIM4v4lpscbe2Given :1; + unsigned BSIM4v4lpvagGiven :1; + unsigned BSIM4v4ldeltaGiven :1; unsigned BSIM4v4lwrGiven :1; unsigned BSIM4v4ldwgGiven :1; unsigned BSIM4v4ldwbGiven :1; @@ -1743,7 +1752,7 @@ typedef struct sBSIM4v4model unsigned BSIM4v4wagsGiven :1; unsigned BSIM4v4wa1Given :1; unsigned BSIM4v4wa2Given :1; - unsigned BSIM4v4wketaGiven :1; + unsigned BSIM4v4wketaGiven :1; unsigned BSIM4v4wnsubGiven :1; unsigned BSIM4v4wndepGiven :1; unsigned BSIM4v4wnsdGiven :1; @@ -1766,14 +1775,14 @@ typedef struct sBSIM4v4model unsigned BSIM4v4wdvtp1Given :1; unsigned BSIM4v4wlpe0Given :1; unsigned BSIM4v4wlpebGiven :1; - unsigned BSIM4v4wdvt0Given :1; - unsigned BSIM4v4wdvt1Given :1; - unsigned BSIM4v4wdvt2Given :1; - unsigned BSIM4v4wdvt0wGiven :1; - unsigned BSIM4v4wdvt1wGiven :1; - unsigned BSIM4v4wdvt2wGiven :1; - unsigned BSIM4v4wdroutGiven :1; - unsigned BSIM4v4wdsubGiven :1; + unsigned BSIM4v4wdvt0Given :1; + unsigned BSIM4v4wdvt1Given :1; + unsigned BSIM4v4wdvt2Given :1; + unsigned BSIM4v4wdvt0wGiven :1; + unsigned BSIM4v4wdvt1wGiven :1; + unsigned BSIM4v4wdvt2wGiven :1; + unsigned BSIM4v4wdroutGiven :1; + unsigned BSIM4v4wdsubGiven :1; unsigned BSIM4v4wvth0Given :1; unsigned BSIM4v4wuaGiven :1; unsigned BSIM4v4wua1Given :1; @@ -1786,25 +1795,25 @@ typedef struct sBSIM4v4model unsigned BSIM4v4wuteGiven :1; unsigned BSIM4v4wvoffGiven :1; unsigned BSIM4v4wminvGiven :1; - unsigned BSIM4v4wrdswGiven :1; + unsigned BSIM4v4wrdswGiven :1; unsigned BSIM4v4wrswGiven :1; unsigned BSIM4v4wrdwGiven :1; - unsigned BSIM4v4wprwgGiven :1; - unsigned BSIM4v4wprwbGiven :1; - unsigned BSIM4v4wprtGiven :1; - unsigned BSIM4v4weta0Given :1; - unsigned BSIM4v4wetabGiven :1; - unsigned BSIM4v4wpclmGiven :1; - unsigned BSIM4v4wpdibl1Given :1; - unsigned BSIM4v4wpdibl2Given :1; - unsigned BSIM4v4wpdiblbGiven :1; + unsigned BSIM4v4wprwgGiven :1; + unsigned BSIM4v4wprwbGiven :1; + unsigned BSIM4v4wprtGiven :1; + unsigned BSIM4v4weta0Given :1; + unsigned BSIM4v4wetabGiven :1; + unsigned BSIM4v4wpclmGiven :1; + unsigned BSIM4v4wpdibl1Given :1; + unsigned BSIM4v4wpdibl2Given :1; + unsigned BSIM4v4wpdiblbGiven :1; unsigned BSIM4v4wfproutGiven :1; unsigned BSIM4v4wpditsGiven :1; unsigned BSIM4v4wpditsdGiven :1; - unsigned BSIM4v4wpscbe1Given :1; - unsigned BSIM4v4wpscbe2Given :1; - unsigned BSIM4v4wpvagGiven :1; - unsigned BSIM4v4wdeltaGiven :1; + unsigned BSIM4v4wpscbe1Given :1; + unsigned BSIM4v4wpscbe2Given :1; + unsigned BSIM4v4wpvagGiven :1; + unsigned BSIM4v4wdeltaGiven :1; unsigned BSIM4v4wwrGiven :1; unsigned BSIM4v4wdwgGiven :1; unsigned BSIM4v4wdwbGiven :1; @@ -1871,7 +1880,7 @@ typedef struct sBSIM4v4model unsigned BSIM4v4pagsGiven :1; unsigned BSIM4v4pa1Given :1; unsigned BSIM4v4pa2Given :1; - unsigned BSIM4v4pketaGiven :1; + unsigned BSIM4v4pketaGiven :1; unsigned BSIM4v4pnsubGiven :1; unsigned BSIM4v4pndepGiven :1; unsigned BSIM4v4pnsdGiven :1; @@ -1894,14 +1903,14 @@ typedef struct sBSIM4v4model unsigned BSIM4v4pdvtp1Given :1; unsigned BSIM4v4plpe0Given :1; unsigned BSIM4v4plpebGiven :1; - unsigned BSIM4v4pdvt0Given :1; - unsigned BSIM4v4pdvt1Given :1; - unsigned BSIM4v4pdvt2Given :1; - unsigned BSIM4v4pdvt0wGiven :1; - unsigned BSIM4v4pdvt1wGiven :1; - unsigned BSIM4v4pdvt2wGiven :1; - unsigned BSIM4v4pdroutGiven :1; - unsigned BSIM4v4pdsubGiven :1; + unsigned BSIM4v4pdvt0Given :1; + unsigned BSIM4v4pdvt1Given :1; + unsigned BSIM4v4pdvt2Given :1; + unsigned BSIM4v4pdvt0wGiven :1; + unsigned BSIM4v4pdvt1wGiven :1; + unsigned BSIM4v4pdvt2wGiven :1; + unsigned BSIM4v4pdroutGiven :1; + unsigned BSIM4v4pdsubGiven :1; unsigned BSIM4v4pvth0Given :1; unsigned BSIM4v4puaGiven :1; unsigned BSIM4v4pua1Given :1; @@ -1914,25 +1923,25 @@ typedef struct sBSIM4v4model unsigned BSIM4v4puteGiven :1; unsigned BSIM4v4pvoffGiven :1; unsigned BSIM4v4pminvGiven :1; - unsigned BSIM4v4prdswGiven :1; + unsigned BSIM4v4prdswGiven :1; unsigned BSIM4v4prswGiven :1; unsigned BSIM4v4prdwGiven :1; - unsigned BSIM4v4pprwgGiven :1; - unsigned BSIM4v4pprwbGiven :1; - unsigned BSIM4v4pprtGiven :1; - unsigned BSIM4v4peta0Given :1; - unsigned BSIM4v4petabGiven :1; - unsigned BSIM4v4ppclmGiven :1; - unsigned BSIM4v4ppdibl1Given :1; - unsigned BSIM4v4ppdibl2Given :1; - unsigned BSIM4v4ppdiblbGiven :1; + unsigned BSIM4v4pprwgGiven :1; + unsigned BSIM4v4pprwbGiven :1; + unsigned BSIM4v4pprtGiven :1; + unsigned BSIM4v4peta0Given :1; + unsigned BSIM4v4petabGiven :1; + unsigned BSIM4v4ppclmGiven :1; + unsigned BSIM4v4ppdibl1Given :1; + unsigned BSIM4v4ppdibl2Given :1; + unsigned BSIM4v4ppdiblbGiven :1; unsigned BSIM4v4pfproutGiven :1; unsigned BSIM4v4ppditsGiven :1; unsigned BSIM4v4ppditsdGiven :1; - unsigned BSIM4v4ppscbe1Given :1; - unsigned BSIM4v4ppscbe2Given :1; - unsigned BSIM4v4ppvagGiven :1; - unsigned BSIM4v4pdeltaGiven :1; + unsigned BSIM4v4ppscbe1Given :1; + unsigned BSIM4v4ppscbe2Given :1; + unsigned BSIM4v4ppvagGiven :1; + unsigned BSIM4v4pdeltaGiven :1; unsigned BSIM4v4pwrGiven :1; unsigned BSIM4v4pdwgGiven :1; unsigned BSIM4v4pdwbGiven :1; @@ -2008,7 +2017,7 @@ typedef struct sBSIM4v4model unsigned BSIM4v4SbulkJctGateSideGradingCoeffGiven :1; unsigned BSIM4v4SunitLengthGateSidewallJctCapGiven :1; unsigned BSIM4v4SjctEmissionCoeffGiven :1; - unsigned BSIM4v4SjctTempExponentGiven :1; + unsigned BSIM4v4SjctTempExponentGiven :1; unsigned BSIM4v4DjctSatCurDensityGiven :1; unsigned BSIM4v4DjctSidewallSatCurDensityGiven :1; @@ -2025,13 +2034,13 @@ typedef struct sBSIM4v4model unsigned BSIM4v4DjctEmissionCoeffGiven :1; unsigned BSIM4v4DjctTempExponentGiven :1; - unsigned BSIM4v4oxideTrapDensityAGiven :1; - unsigned BSIM4v4oxideTrapDensityBGiven :1; - unsigned BSIM4v4oxideTrapDensityCGiven :1; - unsigned BSIM4v4emGiven :1; - unsigned BSIM4v4efGiven :1; - unsigned BSIM4v4afGiven :1; - unsigned BSIM4v4kfGiven :1; + unsigned BSIM4v4oxideTrapDensityAGiven :1; + unsigned BSIM4v4oxideTrapDensityBGiven :1; + unsigned BSIM4v4oxideTrapDensityCGiven :1; + unsigned BSIM4v4emGiven :1; + unsigned BSIM4v4efGiven :1; + unsigned BSIM4v4afGiven :1; + unsigned BSIM4v4kfGiven :1; unsigned BSIM4v4LintGiven :1; unsigned BSIM4v4LlGiven :1; @@ -2110,7 +2119,7 @@ typedef struct sBSIM4v4model #define BSIM4v4_GEOMOD 17 #define BSIM4v4_RGEOMOD 18 #define BSIM4v4_NF 19 -#define BSIM4v4_MIN 20 +#define BSIM4v4_MIN 20 #define BSIM4v4_ACNQSMOD 22 #define BSIM4v4_RBDB 23 #define BSIM4v4_RBSB 24 @@ -2136,8 +2145,8 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_RBODYMOD 100 #define BSIM4v4_MOD_CAPMOD 101 #define BSIM4v4_MOD_TRNQSMOD 102 -#define BSIM4v4_MOD_MOBMOD 103 -#define BSIM4v4_MOD_TNOIMOD 104 +#define BSIM4v4_MOD_MOBMOD 103 +#define BSIM4v4_MOD_TNOIMOD 104 #define BSIM4v4_MOD_TOXE 105 #define BSIM4v4_MOD_CDSC 106 #define BSIM4v4_MOD_CDSCB 107 @@ -2149,14 +2158,14 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_A0 113 #define BSIM4v4_MOD_A1 114 #define BSIM4v4_MOD_A2 115 -#define BSIM4v4_MOD_KETA 116 +#define BSIM4v4_MOD_KETA 116 #define BSIM4v4_MOD_NSUB 117 #define BSIM4v4_MOD_NDEP 118 #define BSIM4v4_MOD_NGATE 120 #define BSIM4v4_MOD_GAMMA1 121 #define BSIM4v4_MOD_GAMMA2 122 #define BSIM4v4_MOD_VBX 123 -#define BSIM4v4_MOD_BINUNIT 124 +#define BSIM4v4_MOD_BINUNIT 124 #define BSIM4v4_MOD_VBM 125 #define BSIM4v4_MOD_XT 126 #define BSIM4v4_MOD_K1 129 @@ -2290,7 +2299,7 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_CIGC 261 #define BSIM4v4_MOD_AIGBACC 262 #define BSIM4v4_MOD_BIGBACC 263 -#define BSIM4v4_MOD_CIGBACC 264 +#define BSIM4v4_MOD_CIGBACC 264 #define BSIM4v4_MOD_AIGBINV 265 #define BSIM4v4_MOD_BIGBINV 266 #define BSIM4v4_MOD_CIGBINV 267 @@ -2426,7 +2435,7 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_LAIGC 416 #define BSIM4v4_MOD_LBIGC 417 #define BSIM4v4_MOD_LCIGC 418 -#define BSIM4v4_MOD_LAIGBACC 419 +#define BSIM4v4_MOD_LAIGBACC 419 #define BSIM4v4_MOD_LBIGBACC 420 #define BSIM4v4_MOD_LCIGBACC 421 #define BSIM4v4_MOD_LAIGBINV 422 @@ -2557,7 +2566,7 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_WAIGC 596 #define BSIM4v4_MOD_WBIGC 597 #define BSIM4v4_MOD_WCIGC 598 -#define BSIM4v4_MOD_WAIGBACC 599 +#define BSIM4v4_MOD_WAIGBACC 599 #define BSIM4v4_MOD_WBIGBACC 600 #define BSIM4v4_MOD_WCIGBACC 601 #define BSIM4v4_MOD_WAIGBINV 602 @@ -2694,7 +2703,7 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_PAIGC 776 #define BSIM4v4_MOD_PBIGC 777 #define BSIM4v4_MOD_PCIGC 778 -#define BSIM4v4_MOD_PAIGBACC 779 +#define BSIM4v4_MOD_PAIGBACC 779 #define BSIM4v4_MOD_PBIGBACC 780 #define BSIM4v4_MOD_PCIGBACC 781 #define BSIM4v4_MOD_PAIGBINV 782 @@ -2727,11 +2736,11 @@ typedef struct sBSIM4v4model #define BSIM4v4_MOD_LKVTH0 808 #define BSIM4v4_MOD_WKVTH0 809 #define BSIM4v4_MOD_PKVTH0 810 -#define BSIM4v4_MOD_WLOD 811 -#define BSIM4v4_MOD_STK2 812 -#define BSIM4v4_MOD_LODK2 813 -#define BSIM4v4_MOD_STETA0 814 -#define BSIM4v4_MOD_LODETA0 815 +#define BSIM4v4_MOD_WLOD 811 +#define BSIM4v4_MOD_STK2 812 +#define BSIM4v4_MOD_LODK2 813 +#define BSIM4v4_MOD_STETA0 814 +#define BSIM4v4_MOD_LODETA0 815 #define BSIM4v4_MOD_PLAMBDA 825 #define BSIM4v4_MOD_PVTL 826 @@ -2811,29 +2820,29 @@ typedef struct sBSIM4v4model /* trap-assisted tunneling */ #define BSIM4v4_MOD_JTSS 900 -#define BSIM4v4_MOD_JTSD 901 -#define BSIM4v4_MOD_JTSSWS 902 -#define BSIM4v4_MOD_JTSSWD 903 -#define BSIM4v4_MOD_JTSSWGS 904 -#define BSIM4v4_MOD_JTSSWGD 905 -#define BSIM4v4_MOD_NJTS 906 -#define BSIM4v4_MOD_NJTSSW 907 -#define BSIM4v4_MOD_NJTSSWG 908 -#define BSIM4v4_MOD_XTSS 909 -#define BSIM4v4_MOD_XTSD 910 -#define BSIM4v4_MOD_XTSSWS 911 -#define BSIM4v4_MOD_XTSSWD 912 -#define BSIM4v4_MOD_XTSSWGS 913 -#define BSIM4v4_MOD_XTSSWGD 914 -#define BSIM4v4_MOD_TNJTS 915 -#define BSIM4v4_MOD_TNJTSSW 916 -#define BSIM4v4_MOD_TNJTSSWG 917 +#define BSIM4v4_MOD_JTSD 901 +#define BSIM4v4_MOD_JTSSWS 902 +#define BSIM4v4_MOD_JTSSWD 903 +#define BSIM4v4_MOD_JTSSWGS 904 +#define BSIM4v4_MOD_JTSSWGD 905 +#define BSIM4v4_MOD_NJTS 906 +#define BSIM4v4_MOD_NJTSSW 907 +#define BSIM4v4_MOD_NJTSSWG 908 +#define BSIM4v4_MOD_XTSS 909 +#define BSIM4v4_MOD_XTSD 910 +#define BSIM4v4_MOD_XTSSWS 911 +#define BSIM4v4_MOD_XTSSWD 912 +#define BSIM4v4_MOD_XTSSWGS 913 +#define BSIM4v4_MOD_XTSSWGD 914 +#define BSIM4v4_MOD_TNJTS 915 +#define BSIM4v4_MOD_TNJTSSW 916 +#define BSIM4v4_MOD_TNJTSSWG 917 #define BSIM4v4_MOD_VTSS 918 -#define BSIM4v4_MOD_VTSD 919 -#define BSIM4v4_MOD_VTSSWS 920 -#define BSIM4v4_MOD_VTSSWD 921 -#define BSIM4v4_MOD_VTSSWGS 922 -#define BSIM4v4_MOD_VTSSWGD 923 +#define BSIM4v4_MOD_VTSD 919 +#define BSIM4v4_MOD_VTSSWS 920 +#define BSIM4v4_MOD_VTSSWD 921 +#define BSIM4v4_MOD_VTSSWGS 922 +#define BSIM4v4_MOD_VTSSWGD 923 /* device questions */ #define BSIM4v4_DNODE 945 @@ -2885,9 +2894,9 @@ typedef struct sBSIM4v4model #define BSIM4v4_DRAINCONDUCT 991 #define BSIM4v4_CBDB 992 #define BSIM4v4_CBSB 993 -#define BSIM4v4_CSUB 994 -#define BSIM4v4_QINV 995 -#define BSIM4v4_IGIDL 996 +#define BSIM4v4_CSUB 994 +#define BSIM4v4_QINV 995 +#define BSIM4v4_IGIDL 996 #define BSIM4v4_CSGB 997 #define BSIM4v4_CSDB 998 #define BSIM4v4_CSSB 999 @@ -2896,19 +2905,19 @@ typedef struct sBSIM4v4model #define BSIM4v4_CSBB 1002 #define BSIM4v4_CBBB 1003 #define BSIM4v4_QS 1004 -#define BSIM4v4_IGISL 1005 -#define BSIM4v4_IGS 1006 -#define BSIM4v4_IGD 1007 -#define BSIM4v4_IGB 1008 -#define BSIM4v4_IGCS 1009 -#define BSIM4v4_IGCD 1010 +#define BSIM4v4_IGISL 1005 +#define BSIM4v4_IGS 1006 +#define BSIM4v4_IGD 1007 +#define BSIM4v4_IGB 1008 +#define BSIM4v4_IGCS 1009 +#define BSIM4v4_IGCD 1010 #include "bsim4v4ext.h" extern void BSIM4v4evaluate(double,double,double,BSIM4v4instance*,BSIM4v4model*, - double*,double*,double*, double*, double*, double*, double*, - double*, double*, double*, double*, double*, double*, double*, + double*,double*,double*, double*, double*, double*, double*, + double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, double*, CKTcircuit*); extern int BSIM4v4debug(BSIM4v4model*, BSIM4v4instance*, CKTcircuit*, int); extern int BSIM4v4checkModel(BSIM4v4model*, BSIM4v4instance*, CKTcircuit*);