📄 b3v1sld.c
字号:
if (T2 >= -0.9) { T0 = 1.0 / (1.0 + T2); dT0_dVb = -pParam->BSIM3v1Sketa * T0 * T0; } else /* added to avoid the problems caused by Keta */ { T1 = 1.0 / (0.8 + T2); T0 = (17.0 + 20.0 * T2) * T1; dT0_dVb = -pParam->BSIM3v1Sketa * 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;/* Mobility calculation */ if (model->BSIM3v1SmobMod == 1) { T0 = Vgsteff + Vth + Vth; T2 = pParam->BSIM3v1Sua + pParam->BSIM3v1Suc * Vbseff; T3 = T0 / model->BSIM3v1Stox; T5 = T3 * (T2 + pParam->BSIM3v1Sub * T3); dDenomi_dVg = (T2 + 2.0 * pParam->BSIM3v1Sub * T3) / model->BSIM3v1Stox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3v1Suc * T3; } else if (model->BSIM3v1SmobMod == 2) { T5 = Vgsteff / model->BSIM3v1Stox * (pParam->BSIM3v1Sua + pParam->BSIM3v1Suc * Vbseff + pParam->BSIM3v1Sub * Vgsteff / model->BSIM3v1Stox); dDenomi_dVg = (pParam->BSIM3v1Sua + pParam->BSIM3v1Suc * Vbseff + 2.0 * pParam->BSIM3v1Sub * Vgsteff / model->BSIM3v1Stox) / model->BSIM3v1Stox; dDenomi_dVd = 0.0; dDenomi_dVb = Vgsteff * pParam->BSIM3v1Suc / model->BSIM3v1Stox; } else { T0 = Vgsteff + Vth + Vth; T2 = 1.0 + pParam->BSIM3v1Suc * Vbseff; T3 = T0 / model->BSIM3v1Stox; T4 = T3 * (pParam->BSIM3v1Sua + pParam->BSIM3v1Sub * T3); T5 = T4 * T2; dDenomi_dVg = (pParam->BSIM3v1Sua + 2.0 * pParam->BSIM3v1Sub * T3) * T2 / model->BSIM3v1Stox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3v1Suc * T4; } if (T5 >= -0.8) { Denomi = 1.0 + T5; } else /* Added to avoid the discontinuity problem caused by ua and ub*/ { 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->BSIM3v1Sueff = ueff = pParam->BSIM3v1Su0temp / Denomi; T9 = -ueff / Denomi; dueff_dVg = T9 * dDenomi_dVg; dueff_dVd = T9 * dDenomi_dVd; dueff_dVb = T9 * dDenomi_dVb;/* Saturation Drain Voltage Vdsat */ WVCox = Weff * pParam->BSIM3v1Svsattemp * model->BSIM3v1Scox; WVCoxRds = WVCox * Rds; Esat = 2.0 * pParam->BSIM3v1Svsattemp / ueff; EsatL = Esat * Leff; T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; /* Sqrt() */ a1 = pParam->BSIM3v1Sa1; if (a1 == 0.0) { Lambda = pParam->BSIM3v1Sa2; dLambda_dVg = 0.0; } else if (a1 > 0.0)/* Added to avoid the discontinuity problem caused by a1 and a2 (Lambda) */ { T0 = 1.0 - pParam->BSIM3v1Sa2; T1 = T0 - pParam->BSIM3v1Sa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * T0); Lambda = pParam->BSIM3v1Sa2 + T0 - 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->BSIM3v1Sa1 * (1.0 + T1 / T2); } else { T1 = pParam->BSIM3v1Sa2 + pParam->BSIM3v1Sa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * pParam->BSIM3v1Sa2); Lambda = 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->BSIM3v1Sa1 * (1.0 + T1 / T2); } Vgst2Vtm = Vgsteff + 2.0 * Vtm; if (Rds > 0) { tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff; tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff; } 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; 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; 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; } else { tmp1 = dLambda_dVg / (Lambda * Lambda); T9 = Abulk * WVCoxRds; T8 = Abulk * T9; T7 = Vgst2Vtm * T9; T6 = Vgst2Vtm * WVCoxRds; 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); dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3) + (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); dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + 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); dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3); dT2_dVd = Vgst2Vtm * dEsatL_dVd; T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); Vdsat = (T1 - T3) / T0; dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg)) / T3; dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd)) / T3; dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb)) / T3; dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2 - 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; dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0; } here->BSIM3v1Svdsat = Vdsat;/* Effective Vds (Vdseff) Calculation */ T1 = Vdsat - Vds - pParam->BSIM3v1Sdelta; dT1_dVg = dVdsat_dVg; dT1_dVd = dVdsat_dVd - 1.0; dT1_dVb = dVdsat_dVb; T2 = sqrt(T1 * T1 + 4.0 * pParam->BSIM3v1Sdelta * Vdsat); T0 = T1 / T2; T3 = 2.0 * pParam->BSIM3v1Sdelta / 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; 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); /* Calculate VAsat */ tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; T9 = WVCoxRds * Vgsteff; 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); dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff - 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; dT1_dVg = -2.0 * tmp1 + WVCoxRds * (Abulk * tmp2 + dAbulk_dVg); dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3; Vasat = T0 / T1; dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1; dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1; dVasat_dVd = dT0_dVd / T1; if (Vdseff > Vds) Vdseff = Vds; /* This code is added to fixed the problem caused by computer precision when Vds is very close to Vdseff. */ diffVds = Vds - Vdseff;/* Calculate VACLM */ if ((pParam->BSIM3v1Spclm > 0.0) && (diffVds > 1.0e-10)) { T0 = 1.0 / (pParam->BSIM3v1Spclm * Abulk * pParam->BSIM3v1Slitl); dT0_dVb = -T0 / Abulk * dAbulk_dVb; dT0_dVg = -T0 / Abulk * dAbulk_dVg; T2 = Vgsteff / EsatL; T1 = Leff * (Abulk + T2); dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg); dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL); dT1_dVd = -T2 * dEsatL_dVd / Esat; T9 = T0 * T1; VACLM = T9 * diffVds; dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg + T1 * diffVds * dT0_dVg; dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds - T9 * dVdseff_dVb; dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd); } else { VACLM = MAX_EXP; dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; }/* Calculate VADIBL */ if (pParam->BSIM3v1SthetaRout > 0.0) { T8 = Abulk * Vdsat; T0 = Vgst2Vtm * T8; dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8 + Vgst2Vtm * Vdsat * dAbulk_dVg; dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; T1 = Vgst2Vtm + T8; dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; dT1_dVd = Abulk * dVdsat_dVd; T9 = T1 * T1; T2 = pParam->BSIM3v1SthetaRout; 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->BSIM3v1Spdiblb * Vbseff; if (T7 >= -0.9) { T3 = 1.0 / (1.0 + T7); VADIBL *= T3; dVADIBL_dVg *= T3; dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->BSIM3v1Spdiblb) * T3; dVADIBL_dVd *= T3; } else/* Added to avoid the discontinuity problem caused by pdiblcb */ { T4 = 1.0 / (0.8 + T7); T3 = (17.0 + 20.0 * T7) * T4; dVADIBL_dVg *= T3; dVADIBL_dVb = dVADIBL_dVb * T3 - VADIBL * pParam->BSIM3v1Spdiblb * T4 * T4; dVADIBL_dVd *= T3; VADIBL *= T3; } } else { VADIBL = MAX_EXP; dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; }/* Calculate VA */ T8 = pParam->BSIM3v1Spvag / EsatL; T9 = T8 * Vgsteff; if (T9 > -0.9) { T0 = 1.0 + T9; dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL); dT0_dVb = -T9 * dEsatL_dVb / EsatL; dT0_dVd = -T9 * dEsatL_dVd / EsatL; } else /* Added to avoid the discontinuity problems caused by pvag */ { T1 = 1.0 / (17.0 + 20.0 * T9); T0 = (0.8 + T9) * T1; T1 *= T1; dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1; T9 *= T1 / EsatL; dT0_dVb = -T9 * dEsatL_dVb; dT0_dVd = -T9 * dEsatL_dVd; } tmp1 = VACLM * VACLM; tmp2 = VADIBL * VADIBL; tmp3 = VACLM + VADIBL; T1 = VACLM * VADIBL / tmp3; tmp3 *= tmp3; dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3; dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3; dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3; Va = Vasat + T0 * T1; dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg; dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd; dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb;/* Calculate VASCBE */ if (pParam->BSIM3v1Spscbe2 > 0.0) { if (diffVds > pParam->BSIM3v1Spscbe1 * pParam->BSIM3v1Slitl / EXP_THRESHOLD) { T0 = pParam->BSIM3v1Spscbe1 * pParam->BSIM3v1Slitl / diffVds; VASCBE = Leff * exp(T0) / pParam->BSIM3v1Spscbe2; T1 = T0 * VASCBE / diffVds;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -