📄 b3v0ld.c
字号:
EsatL = Esat * Leff; T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; a1 = pParam->BSIM3v0a1; if ((Pmos_factor = a1 * Vgsteff + pParam->BSIM3v0a2) > 1.0) { Pmos_factor = 1.0; a1 = 0.0; } Vgst2Vtm = Vgsteff + 2.0 * Vtm; if ((Rds == 0.0) && (Pmos_factor == 1.0)) { T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm); here->BSIM3v0vdsat = Vdsat = EsatL * Vgst2Vtm * T0; dT0_dVg = -(Abulk * dEsatL_dVg +EsatL*dAbulk_dVg+ 1.0) * T0 * T0; dT0_dVd = -(Abulk * dEsatL_dVd) * T0 * T0; dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T0 * T0; dVdsat_dVg = EsatL * Vgst2Vtm * dT0_dVg + EsatL * T0 + Vgst2Vtm * T0 * dEsatL_dVg; dVdsat_dVd = EsatL * Vgst2Vtm * dT0_dVd + Vgst2Vtm * T0 * dEsatL_dVd; dVdsat_dVb = EsatL * Vgst2Vtm * dT0_dVb + Vgst2Vtm * T0 * dEsatL_dVb; } else { tmp1 = a1 / (Pmos_factor * Pmos_factor); 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; } T0 = 2.0 * Abulk * (Abulk * WVCoxRds - 1.0 + 1.0 / Pmos_factor); dT0_dVg = 2.0 * (Abulk * Abulk * WVCoxRds * tmp2 - Abulk * tmp1 + (2.0 * WVCoxRds * Abulk + 1.0 / Pmos_factor - 1.0) * dAbulk_dVg); dT0_dVb = 2.0 * (Abulk * Abulk * WVCoxRds * (2.0 / Abulk * dAbulk_dVb + tmp3) + (1.0 / Pmos_factor - 1.0) * dAbulk_dVb); dT0_dVd= 0.0; T1 = Vgst2Vtm * (2.0 / Pmos_factor - 1.0) + Abulk * EsatL + 3.0 * Abulk * Vgst2Vtm * WVCoxRds; dT1_dVg = (2.0 / Pmos_factor - 1.0) - 2.0 * Vgst2Vtm * tmp1 + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (Abulk * WVCoxRds + Abulk * Vgst2Vtm * WVCoxRds * tmp2 + Vgst2Vtm * WVCoxRds * dAbulk_dVg); dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb + 3.0 * (Vgst2Vtm * WVCoxRds * dAbulk_dVb + Abulk * Vgst2Vtm * WVCoxRds * tmp3); dT1_dVd = Abulk * dEsatL_dVd; T2 = Vgst2Vtm * (EsatL + 2.0 * Vgst2Vtm * WVCoxRds); dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg + Vgst2Vtm * WVCoxRds * (4.0 + 2.0 * Vgst2Vtm * tmp2); dT2_dVb = Vgst2Vtm * dEsatL_dVb + 2.0 * Vgst2Vtm * WVCoxRds * Vgst2Vtm * tmp3; dT2_dVd = Vgst2Vtm * dEsatL_dVd; T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); here->BSIM3v0vdsat = 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; T4 = T1 - T3; dT4_dVg = - dT1_dVg - dT3_dVg; dT4_dVd = - dT1_dVd - dT3_dVd; dT4_dVb = - dT1_dVb - dT3_dVb; 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; }/* Effective Vds (Vdseff) Calculation */ T1 = Vdsat - Vds - pParam->BSIM3v0delta; dT1_dVg = dVdsat_dVg; dT1_dVd = dVdsat_dVd - 1.0; dT1_dVb = dVdsat_dVb; T2 = sqrt(T1 * T1 + 4.0 * pParam->BSIM3v0delta * Vdsat); T0 = T1 / T2; T3 = 2.0 * pParam->BSIM3v0delta / 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 */ tmp1 = a1 / (Pmos_factor * Pmos_factor); 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; } tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm; T0 = EsatL + Vdsat + 2.0 * WVCoxRds * Vgsteff * tmp4; dT0_dVg = dEsatL_dVg + dVdsat_dVg + 2.0 * WVCoxRds * tmp4 * (1.0 + tmp2 * Vgsteff) - WVCoxRds * Vgsteff / Vgst2Vtm * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm + Vdsat * dAbulk_dVg); dT0_dVb = dEsatL_dVb + dVdsat_dVb + 2.0 * WVCoxRds * tmp4 * tmp3 * Vgsteff - WVCoxRds * Vgsteff / Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); dT0_dVd = dEsatL_dVd + dVdsat_dVd - WVCoxRds * Vgsteff / Vgst2Vtm * Abulk * dVdsat_dVd; T1 = 2.0 / Pmos_factor - 1.0 + WVCoxRds * Abulk; dT1_dVg = -2.0 * tmp1 + WVCoxRds *(Abulk * tmp2+ dAbulk_dVg); dT1_dVb = dAbulk_dVb * WVCoxRds + Abulk * WVCoxRds * tmp3; Vasat = T0 / T1; dVasat_dVg = (dT0_dVg - T0 / T1 * dT1_dVg) / T1; dVasat_dVb = (dT0_dVb - T0 / T1 * dT1_dVb) / T1; dVasat_dVd = dT0_dVd / T1; diffVds = Vds - Vdseff;/* Calculate VACLM */ if (pParam->BSIM3v0pclm > 0.0) { T0 = 1.0 / (pParam->BSIM3v0pclm * Abulk * pParam->BSIM3v0litl); 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; VACLM = T0 * T1 * diffVds; dVACLM_dVg = T0 * dT1_dVg * diffVds - T0 * T1 * dVdseff_dVg + T1 * diffVds * dT0_dVg; dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds - T0 * T1 * dVdseff_dVb; dVACLM_dVd = T0 * dT1_dVd * diffVds + T0 * T1 * (1.0 - dVdseff_dVd); } else { VACLM = MAX_EXP; dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0; }/* Calculate VADIBL */ if (pParam->BSIM3v0thetaRout > 0.0) { T0 = Vgst2Vtm * Abulk * Vdsat; dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + Abulk * Vdsat + Vgst2Vtm * Vdsat * dAbulk_dVg; dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb); dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd; T1 = Vgst2Vtm + Abulk * Vdsat; dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg; dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat; dT1_dVd = Abulk * dVdsat_dVd; T2 = pParam->BSIM3v0thetaRout * (1.0 + pParam->BSIM3v0pdiblb * Vbseff); VADIBL = (Vgst2Vtm - T0 / T1) / T2; dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / (T1 * T1)) / T2; dVADIBL_dVb = ((-dT0_dVb / T1 + T0 * dT1_dVb / (T1 * T1)) - VADIBL * pParam->BSIM3v0thetaRout * pParam->BSIM3v0pdiblb) / T2; dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / (T1 * T1)) / T2; } else { VADIBL = MAX_EXP; dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0; }/* Calculate VA */ T0 = 1.0 + pParam->BSIM3v0pvag * Vgsteff / EsatL; dT0_dVg = pParam->BSIM3v0pvag * (1.0 - Vgsteff * dEsatL_dVg / EsatL) / EsatL; dT0_dVb = -pParam->BSIM3v0pvag * Vgsteff * dEsatL_dVb / EsatL / EsatL; dT0_dVd = -pParam->BSIM3v0pvag * Vgsteff * dEsatL_dVd / EsatL / EsatL; 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 ((diffVds) && ((T0 = pParam->BSIM3v0pscbe1 * pParam->BSIM3v0litl / diffVds) > 0.0) && (T0 < EXP_THRESHOLD)) { VASCBE = Leff * exp(T0) / pParam->BSIM3v0pscbe2; 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->BSIM3v0pscbe2; dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0; }/* Calculate Ids */ CoxWovL = model->BSIM3v0cox * Weff / Leff; beta = ueff * CoxWovL; dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff; dbeta_dVd = CoxWovL * dueff_dVd; dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff; T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm; dT0_dVg = -0.5 * (Abulk * dVdseff_dVg - Abulk * Vdseff / Vgst2Vtm+Vdseff*dAbulk_dVg) / Vgst2Vtm; dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm; dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff) / Vgst2Vtm; fgche1 = Vgsteff * T0; dfgche1_dVg = Vgsteff * dT0_dVg + T0; dfgche1_dVd = Vgsteff * dT0_dVd; dfgche1_dVb = Vgsteff * dT0_dVb; fgche2 = 1.0 + Vdseff / EsatL; dfgche2_dVg = (dVdseff_dVg - Vdseff / EsatL * dEsatL_dVg) / EsatL; dfgche2_dVd = (dVdseff_dVd - Vdseff / EsatL * dEsatL_dVd) / EsatL; dfgche2_dVb = (dVdseff_dVb - Vdseff / EsatL * dEsatL_dVb) / EsatL; gche = beta * fgche1 / fgche2; dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg - gche * dfgche2_dVg) / fgche2; dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd - gche * dfgche2_dVd) / fgche2; dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb - gche * dfgche2_dVb) / fgche2; T0 = 1.0 + gche * Rds; Idl = gche * Vdseff / T0; dIdl_dVg = (gche * dVdseff_dVg + Vdseff * dgche_dVg / T0) / T0 - Idl * gche / T0 * dRds_dVg ; dIdl_dVd = (gche * dVdseff_dVd + Vdseff * dgche_dVd / T0) / T0; dIdl_dVb = (gche * dVdseff_dVb + Vdseff * dgche_dVb / T0 - Idl * dRds_dVb * gche) / T0; T0 = 1.0 + diffVds / Va; Idsa = Idl * T0; dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + diffVds / Va * dVa_dVg) / Va; dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd - diffVds / Va * dVa_dVd) / Va; dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + diffVds / Va * dVa_dVb) / Va; T0 = 1.0 + diffVds / VASCBE; Ids = Idsa * T0; Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + diffVds / VASCBE * dVASCBE_dVg) / VASCBE; Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd - diffVds / VASCBE * dVASCBE_dVd) / VASCBE; Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb + diffVds / VASCBE * dVASCBE_dVb) / VASCBE; Gds += Gm * dVgsteff_dVd; Gmb += Gm * dVgsteff_dVb; Gm *= dVgsteff_dVg; Gmb *= dVbseff_dVb;/* calculate substrate current Isub */ if ((pParam->BSIM3v0alpha0 <= 0.0) || (pParam->BSIM3v0beta0 <= 0.0)) { Isub = Gbd = Gbb = Gbg = 0.0; } else { T2 = pParam->BSIM3v0alpha0 / Leff; if (diffVds<0.0) { diffVds=0.0; Vdseff=Vds; } /* added to avoid the hardwrae problem when Vds=0 */ if ((diffVds != 0.0) && ((T0 = -pParam->BSIM3v0beta0 / diffVds) > -EXP_THRESHOLD)) { T1 = T2 * diffVds * exp(T0); dT1_dVg = T1 / diffVds * (T0 - 1.0) * dVdseff_dVg; dT1_dVd = T1 / diffVds * (1.0 - T0) * (1.0 - dVdseff_dVd); dT1_dVb = T1 / diffVds * (T0 - 1.0) * dVdseff_dVb; } else { T1 = T2 * diffVds * MIN_EXP; dT1_dVg = -T2 * MIN_EXP * dVdseff_dVg; dT1_dVd = T2 * MIN_EXP * (1.0 - dVdseff_dVd); dT1_dVb = -T2 * MIN_EXP * dVdseff_dVb; } Isub = T1 * Idsa; Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg; Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd; Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb; Gbd += Gbg * dVgsteff_dVd; Gbb += Gbg * dVgsteff_dVb; Gbg *= dVgsteff_dVg; Gbg *= dVbseff_dVb; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -