diff --git a/src/spicelib/devices/bsim4/b4check.c b/src/spicelib/devices/bsim4/b4check.c index 343055f32..2d067272f 100644 --- a/src/spicelib/devices/bsim4/b4check.c +++ b/src/spicelib/devices/bsim4/b4check.c @@ -48,9 +48,9 @@ FILE *fplog; fprintf(fplog, "\n"); fprintf(fplog, "++++++++++ BSIM4 PARAMETER CHECKING BELOW ++++++++++\n"); - if ((strcmp(model->BSIM4version, "4.8.0")) && (strcmp(model->BSIM4version, "4.80")) && (strcmp(model->BSIM4version, "4.8"))) - { fprintf(fplog, "Warning: This model is BSIM4.8.0; you specified a wrong version number.\n"); - printf("Warning: This model is BSIM4.8.0; you specified a wrong version number.\n"); + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81")) && (strcmp(model->BSIM4version, "4.8"))) + { fprintf(fplog, "Warning: This model is BSIM4.8.1; you specified a deviating version number.\n"); + printf("Warning: This model is BSIM4.8.1; you specified a deviating version number.\n"); } fprintf(fplog, "Model = %s\n", model->BSIM4modName); @@ -772,42 +772,72 @@ FILE *fplog; printf("Warning: cgbo = %g is negative. Set to zero.\n", model->BSIM4cgbo); model->BSIM4cgbo = 0.0; } + if (model->BSIM4tnoiMod == 1){ + printf("Warning: TNOIMOD=1 is not supported and may be removed from future version.\n"); + } + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) { /* v4.7 */ - if (model->BSIM4tnoiMod == 1 || model->BSIM4tnoiMod == 2) { - if (model->BSIM4tnoia < 0.0) { - fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); - printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); - model->BSIM4tnoia = 0.0; - } - if (model->BSIM4tnoib < 0.0) { - fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); - printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); - model->BSIM4tnoib = 0.0; - } - if (model->BSIM4rnoia < 0.0) { - fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); - printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); - model->BSIM4rnoia = 0.0; - } - if (model->BSIM4rnoib < 0.0) { - fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); - printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); - model->BSIM4rnoib = 0.0; + if (model->BSIM4tnoiMod == 1 || model->BSIM4tnoiMod == 2) { + if (model->BSIM4tnoia < 0.0) { + fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); + printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); + model->BSIM4tnoia = 0.0; + } + if (model->BSIM4tnoib < 0.0) { + fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); + printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); + model->BSIM4tnoib = 0.0; + } + if (model->BSIM4rnoia < 0.0) { + fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); + printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); + model->BSIM4rnoia = 0.0; + } + if (model->BSIM4rnoib < 0.0) { + fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); + printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); + model->BSIM4rnoib = 0.0; + } } - } - /* v4.7 */ - if (model->BSIM4tnoiMod == 2) { - if (model->BSIM4tnoic < 0.0) { - fprintf(fplog, "Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); - printf("Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); - model->BSIM4tnoic = 0.0; + /* v4.7 */ + if (model->BSIM4tnoiMod == 2) { + if (model->BSIM4tnoic < 0.0) { + fprintf(fplog, "Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); + printf("Warning: tnoic = %g is negative. Set to zero.\n", model->BSIM4tnoic); + model->BSIM4tnoic = 0.0; + } + if (model->BSIM4rnoic < 0.0) { + fprintf(fplog, "Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); + printf("Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); + model->BSIM4rnoic = 0.0; + } } - if (model->BSIM4rnoic < 0.0) { - fprintf(fplog, "Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); - printf("Warning: rnoic = %g is negative. Set to zero.\n", model->BSIM4rnoic); - model->BSIM4rnoic = 0.0; + } + else + { + if (model->BSIM4tnoiMod == 1){ + if (model->BSIM4tnoia < 0.0) { + fprintf(fplog, "Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); + printf("Warning: tnoia = %g is negative. Set to zero.\n", model->BSIM4tnoia); + model->BSIM4tnoia = 0.0; + } + if (model->BSIM4tnoib < 0.0) { + fprintf(fplog, "Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); + printf("Warning: tnoib = %g is negative. Set to zero.\n", model->BSIM4tnoib); + model->BSIM4tnoib = 0.0; + } + if (model->BSIM4rnoia < 0.0) { + fprintf(fplog, "Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); + printf("Warning: rnoia = %g is negative. Set to zero.\n", model->BSIM4rnoia); + model->BSIM4rnoia = 0.0; + } + if (model->BSIM4rnoib < 0.0) { + fprintf(fplog, "Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); + printf("Warning: rnoib = %g is negative. Set to zero.\n", model->BSIM4rnoib); + model->BSIM4rnoib = 0.0; + } } } diff --git a/src/spicelib/devices/bsim4/b4noi.c b/src/spicelib/devices/bsim4/b4noi.c index 40a044efc..e6c115356 100644 --- a/src/spicelib/devices/bsim4/b4noi.c +++ b/src/spicelib/devices/bsim4/b4noi.c @@ -99,7 +99,7 @@ double tempInoise; double noizDens[BSIM4NSRCS]; double lnNdens[BSIM4NSRCS]; -double T0, T1, T2, T3, T4, T5, T6, T7, T8, T10, T11; +double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11; double Vds, Ssi, Swi; double tmp=0.0, gdpr, gspr, npart_theta=0.0, npart_beta=0.0, igsquare, bodymode; @@ -407,45 +407,113 @@ double m; T8 = here->BSIM4Vgsteff / here->BSIM4EsatL; T8 *= T8; - npart_c = model->BSIM4rnoic * (1.0 + T8 - * model->BSIM4tnoic * Leff); - ctnoi = epsilon / sqrt(gamma * delta) - * (2.5316 * npart_c); - - npart_beta = model->BSIM4rnoia * (1.0 + T8 - * model->BSIM4tnoia * Leff); - npart_theta = model->BSIM4rnoib * (1.0 + T8 - * model->BSIM4tnoib * Leff); - gamma = gamma * (3.0 * npart_beta * npart_beta); - delta = delta * (3.75 * npart_theta * npart_theta); - - GammaGd0 = gamma * here->BSIM4noiGd0; - C0 = here->BSIM4Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV; - T0 = C0 / here->BSIM4noiGd0; - sigrat = T0 * sqrt(delta / gamma); + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) { + npart_c = model->BSIM4rnoic * (1.0 + T8 + * model->BSIM4tnoic * Leff); + ctnoi = epsilon / sqrt(gamma * delta) + * (2.5316 * npart_c); + + npart_beta = model->BSIM4rnoia * (1.0 + T8 + * model->BSIM4tnoia * Leff); + npart_theta = model->BSIM4rnoib * (1.0 + T8 + * model->BSIM4tnoib * Leff); + gamma = gamma * (3.0 * npart_beta * npart_beta); + delta = delta * (3.75 * npart_theta * npart_theta); + + GammaGd0 = gamma * here->BSIM4noiGd0; + C0 = here->BSIM4Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV; + T0 = C0 / here->BSIM4noiGd0; + sigrat = T0 * sqrt(delta / gamma); + } + else + { + npart_c = model->BSIM4rnoic * (1.0 + T8 + * model->BSIM4tnoic * Leff); + /* Limits added for rnoia, rnoib, rnoic, tnoia, tnoib and tnoic in BSIM4.8.1 */ + T9 = gamma * delta ; + if (T9 > 0) + ctnoi = epsilon / sqrt( gamma * delta) * (2.5316 * npart_c); + else + ctnoi = 1.0 ; + if (ctnoi > 1) + ctnoi=1; + if (ctnoi < 0) + ctnoi=0; + + npart_beta = model->BSIM4rnoia * (1.0 + T8 + * model->BSIM4tnoia * Leff); + npart_theta = model->BSIM4rnoib * (1.0 + T8 + * model->BSIM4tnoib * Leff); + gamma = gamma * (3.0 * npart_beta * npart_beta); + delta = delta * (3.75 * npart_theta * npart_theta); + + GammaGd0 = gamma * here->BSIM4noiGd0; + C0 = here->BSIM4Coxeff * pParam->BSIM4weffCV * here->BSIM4nf * pParam->BSIM4leffCV; + T0 = C0 / here->BSIM4noiGd0; + + if (gamma > 0 && delta > 0) + sigrat = T0 * sqrt(delta / gamma); + else + sigrat = 0.0; + } } + switch(model->BSIM4tnoiMod) { case 0: - T0 = here->BSIM4ueff * fabs(here->BSIM4qinv); - T1 = T0 * tmp + pParam->BSIM4leff - * pParam->BSIM4leff; - NevalSrc(&noizDens[BSIM4IDNOIZ], - &lnNdens[BSIM4IDNOIZ], ckt, - THERMNOISE, here->BSIM4dNodePrime, - here->BSIM4sNodePrime, - (T0 / T1) * model->BSIM4ntnoi * m); + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) { + T0 = here->BSIM4ueff * fabs(here->BSIM4qinv); + T1 = T0 * tmp + pParam->BSIM4leff + * pParam->BSIM4leff; + NevalSrc(&noizDens[BSIM4IDNOIZ], + &lnNdens[BSIM4IDNOIZ], ckt, + THERMNOISE, here->BSIM4dNodePrime, + here->BSIM4sNodePrime, + (T0 / T1) * model->BSIM4ntnoi * m); + } + else + { + T0 = here->BSIM4ueff * fabs(here->BSIM4qinv); + T1 = T0 * tmp + pParam->BSIM4leff + * pParam->BSIM4leff; + NevalSrc(&noizDens[BSIM4IDNOIZ], + &lnNdens[BSIM4IDNOIZ], ckt, + THERMNOISE, here->BSIM4dNodePrime, + here->BSIM4sNodePrime, + (T0 / T1) * model->BSIM4ntnoi * m); + + noizDens[BSIM4CORLNOIZ] = 0.0; + lnNdens[BSIM4CORLNOIZ] = log(MAX(noizDens[BSIM4CORLNOIZ], N_MINLOG)); + } break; case 1: - T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds; - T0 *= T0; - igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds; - T1 = npart_beta * (here->BSIM4gm - + here->BSIM4gmbs) + here->BSIM4gds; - T2 = T1 * T1 / here->BSIM4IdovVds; - NevalSrc(&noizDens[BSIM4IDNOIZ], - &lnNdens[BSIM4IDNOIZ], ckt, - THERMNOISE, here->BSIM4dNodePrime, - here->BSIM4sNodePrime, (T2 - igsquare) * m); + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) { + T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds; + T0 *= T0; + igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds; + T1 = npart_beta * (here->BSIM4gm + + here->BSIM4gmbs) + here->BSIM4gds; + T2 = T1 * T1 / here->BSIM4IdovVds; + NevalSrc(&noizDens[BSIM4IDNOIZ], + &lnNdens[BSIM4IDNOIZ], ckt, + THERMNOISE, here->BSIM4dNodePrime, + here->BSIM4sNodePrime, (T2 - igsquare) * m); + } + else + { + T0 = here->BSIM4gm + here->BSIM4gmbs + here->BSIM4gds; + T0 *= T0; + igsquare = npart_theta * npart_theta * T0 / here->BSIM4IdovVds; + T1 = npart_beta * (here->BSIM4gm + + here->BSIM4gmbs) + here->BSIM4gds; + T2 = T1 * T1 / here->BSIM4IdovVds; + NevalSrc(&noizDens[BSIM4IDNOIZ], + &lnNdens[BSIM4IDNOIZ], ckt, + THERMNOISE, here->BSIM4dNodePrime, + here->BSIM4sNodePrime, (T2 - igsquare) * m); + + noizDens[BSIM4CORLNOIZ] = 0.0; + lnNdens[BSIM4CORLNOIZ] = log(MAX(noizDens[BSIM4CORLNOIZ], N_MINLOG)); + } break; case 2: T2 = GammaGd0; diff --git a/src/spicelib/devices/bsim4/b4set.c b/src/spicelib/devices/bsim4/b4set.c index fa445937d..7691735de 100644 --- a/src/spicelib/devices/bsim4/b4set.c +++ b/src/spicelib/devices/bsim4/b4set.c @@ -210,7 +210,7 @@ BSIM4instance **InstArray; } if (!model->BSIM4versionGiven) - model->BSIM4version = copy("4.8.0"); + model->BSIM4version = copy("4.8.1"); if (!model->BSIM4toxrefGiven) model->BSIM4toxref = 30.0e-10; if (!model->BSIM4eotGiven) @@ -348,18 +348,31 @@ BSIM4instance **InstArray; model->BSIM4eu = (model->BSIM4type == NMOS) ? 1.67 : 1.0; if (!model->BSIM4ucsGiven) model->BSIM4ucs = (model->BSIM4type == NMOS) ? 1.67 : 1.0; - if (!model->BSIM4uaGiven) - model->BSIM4ua = ((model->BSIM4mobMod == 2)) ? 1.0e-15 : 1.0e-9; /* unit m/V */ + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) + { + if (!model->BSIM4uaGiven) + model->BSIM4ua = ((model->BSIM4mobMod == 2)) ? 1.0e-15 : 1.0e-9; /* unit m/V */ + if (!model->BSIM4ucGiven) + model->BSIM4uc = (model->BSIM4mobMod == 1) ? -0.0465 : -0.0465e-9; + if (!model->BSIM4uc1Given) + model->BSIM4uc1 = (model->BSIM4mobMod == 1) ? -0.056 : -0.056e-9; + } + else + { + if (!model->BSIM4uaGiven) + model->BSIM4ua = ((model->BSIM4mobMod == 2 || model->BSIM4mobMod == 6)) ? 1.0e-15 : 1.0e-9; /* unit m/V */ + /*printf("warning:ua=%g",model->BSIM4ua);*/ + if (!model->BSIM4ucGiven) + model->BSIM4uc = (model->BSIM4mobMod == 1 || model->BSIM4mobMod == 5) ? -0.0465 : -0.0465e-9; + if (!model->BSIM4uc1Given) + model->BSIM4uc1 = (model->BSIM4mobMod == 1 || model->BSIM4mobMod == 5) ? -0.056 : -0.056e-9; + } if (!model->BSIM4ua1Given) model->BSIM4ua1 = 1.0e-9; /* unit m/V */ if (!model->BSIM4ubGiven) model->BSIM4ub = 1.0e-19; /* unit (m/V)**2 */ if (!model->BSIM4ub1Given) model->BSIM4ub1 = -1.0e-18; /* unit (m/V)**2 */ - if (!model->BSIM4ucGiven) - model->BSIM4uc = (model->BSIM4mobMod == 1) ? -0.0465 : -0.0465e-9; - if (!model->BSIM4uc1Given) - model->BSIM4uc1 = (model->BSIM4mobMod == 1) ? -0.056 : -0.056e-9; if (!model->BSIM4udGiven) model->BSIM4ud = 0.0; /* unit m**(-2) */ if (!model->BSIM4ud1Given) diff --git a/src/spicelib/devices/bsim4/b4temp.c b/src/spicelib/devices/bsim4/b4temp.c index 9b71b127d..b1e1bb37b 100644 --- a/src/spicelib/devices/bsim4/b4temp.c +++ b/src/spicelib/devices/bsim4/b4temp.c @@ -1349,10 +1349,32 @@ int Size_Not_Found, i; / pParam->BSIM4poxedge / pParam->BSIM4poxedge; pParam->BSIM4Aechvb = (model->BSIM4type == NMOS) ? 4.97232e-7 : 3.42537e-7; pParam->BSIM4Bechvb = (model->BSIM4type == NMOS) ? 7.45669e11 : 1.16645e12; - pParam->BSIM4AechvbEdgeS = pParam->BSIM4Aechvb * pParam->BSIM4weff - * model->BSIM4dlcig * pParam->BSIM4ToxRatioEdge; - pParam->BSIM4AechvbEdgeD = pParam->BSIM4Aechvb * pParam->BSIM4weff - * model->BSIM4dlcigd * pParam->BSIM4ToxRatioEdge; + + if ((strcmp(model->BSIM4version, "4.8.1")) && (strcmp(model->BSIM4version, "4.81"))) + { + pParam->BSIM4AechvbEdgeS = pParam->BSIM4Aechvb * pParam->BSIM4weff + * model->BSIM4dlcig * pParam->BSIM4ToxRatioEdge; + pParam->BSIM4AechvbEdgeD = pParam->BSIM4Aechvb * pParam->BSIM4weff + * model->BSIM4dlcigd * pParam->BSIM4ToxRatioEdge; + } + else + { + if (model->BSIM4dlcig < 0.0) + { + printf("Warning: dlcig = %g is negative. Set to zero.\n", model->BSIM4dlcig); + model->BSIM4dlcig = 0.0; + } + pParam->BSIM4AechvbEdgeS = pParam->BSIM4Aechvb * pParam->BSIM4weff + * model->BSIM4dlcig * pParam->BSIM4ToxRatioEdge; + if (model->BSIM4dlcigd < 0.0) + { + printf("Warning: dlcigd = %g is negative. Set to zero.\n", model->BSIM4dlcigd); + model->BSIM4dlcigd = 0.0; + } + pParam->BSIM4AechvbEdgeD = pParam->BSIM4Aechvb * pParam->BSIM4weff + * model->BSIM4dlcigd * pParam->BSIM4ToxRatioEdge; + } + pParam->BSIM4BechvbEdge = -pParam->BSIM4Bechvb * toxe * pParam->BSIM4poxedge; pParam->BSIM4Aechvb *= pParam->BSIM4weff * pParam->BSIM4leff @@ -2289,8 +2311,6 @@ int Size_Not_Found, i; /* Calculate n */ tmp1 = epssub / pParam->BSIM4Xdep0; - here->BSIM4nstar = Vtmeot / Charge_q * - (model->BSIM4coxe + tmp1 + pParam->BSIM4cit); tmp2 = pParam->BSIM4nfactor * tmp1; tmp3 = (tmp2 + pParam->BSIM4cdsc * Theta0 + pParam->BSIM4cit) / model->BSIM4coxe; if (tmp3 >= -0.5) @@ -2337,7 +2357,7 @@ int Size_Not_Found, i; niter++; } while ((niter<=4)&&(ABS(toxpf-toxpi)>1e-12)); here->BSIM4toxp = toxpf; - here->BSIM4coxp = epsrox * EPS0 / model->BSIM4toxp; + here->BSIM4coxp = epsrox * EPS0 / here->BSIM4toxp; } else { here->BSIM4toxp = model->BSIM4toxp; here->BSIM4coxp = model->BSIM4coxp; @@ -2345,7 +2365,7 @@ int Size_Not_Found, i; if (BSIM4checkModel(model, here, ckt)) { - SPfrontEnd->IFerrorf (ERR_FATAL, "Fatal error(s) detected during BSIM4.6.0 parameter checking for %s in model %s", model->BSIM4modName, here->BSIM4name); + SPfrontEnd->IFerrorf (ERR_FATAL, "Fatal error(s) detected during BSIM4.8.1 parameter checking for %s in model %s", model->BSIM4modName, here->BSIM4name); return(E_BADPARM); } } /* End instance */ diff --git a/tests/bsim4/nmos/qaSpec b/tests/bsim4/nmos/qaSpec index 05a676db9..081a0dcd2 100644 --- a/tests/bsim4/nmos/qaSpec +++ b/tests/bsim4/nmos/qaSpec @@ -15,12 +15,12 @@ // `ifdef spice -nTypeSelectionArguments nmos level=14 version=4.8.0 -pTypeSelectionArguments pmos level=14 version=4.8.0 +nTypeSelectionArguments nmos level=14 version=4.5.0 +pTypeSelectionArguments pmos level=14 version=4.5.0 `endif `ifdef ngspice -nTypeSelectionArguments nmos level=14 version=4.8.0 -pTypeSelectionArguments pmos level=14 version=4.8.0 +nTypeSelectionArguments nmos level=14 version=4.8.1 +pTypeSelectionArguments pmos level=14 version=4.8.1 `endif `ifdef hspice nTypeSelectionArguments nmos level=54 version=4.7 diff --git a/tests/bsim4/pmos/qaSpec b/tests/bsim4/pmos/qaSpec index 81cb0f83c..55d305b00 100644 --- a/tests/bsim4/pmos/qaSpec +++ b/tests/bsim4/pmos/qaSpec @@ -15,12 +15,12 @@ // `ifdef spice -nTypeSelectionArguments pmos level=14 version=4.8.0 -pTypeSelectionArguments nmos level=14 version=4.8.0 +nTypeSelectionArguments pmos level=14 version=4.5.0 +pTypeSelectionArguments nmos level=14 version=4.5.0 `endif `ifdef ngspice -nTypeSelectionArguments pmos level=14 version=4.8.0 -pTypeSelectionArguments nmos level=14 version=4.8.0 +nTypeSelectionArguments pmos level=14 version=4.8.1 +pTypeSelectionArguments nmos level=14 version=4.8.1 `endif `ifdef hspice nTypeSelectionArguments pmos level=54 version=4.7