📄 b3soipdld.c
字号:
dn_dVd = dT4_dVd; } else /* avoid discontinuity problems caused by T4 */ { T0 = 1.0 / (3.0 + 8.0 * T4); n = (1.0 + 3.0 * T4) * T0; T0 *= T0; dn_dVb = T0 * dT4_dVb; dn_dVd = T0 * dT4_dVd; }/* Effective Vgst (Vgsteff) Calculation */ Vgst = Vgs_eff - Vth; dVgst_dVg = dVgs_eff_dVg; dVgst_dVd = -dVth_dVd; dVgst_dVb = -dVth_dVb; T10 = 2.0 * n * Vtm; VgstNVt = Vgst / T10; ExpArg = (2.0 * pParam->B3SOIPDvoff - Vgst) / T10; /* MCJ: Very small Vgst */ if (VgstNVt > EXPL_THRESHOLD) { Vgsteff = Vgst; /* T0 is dVgsteff_dVbseff */ T0 = -dVth_dVb; dVgsteff_dVg = dVgs_eff_dVg; dVgsteff_dVd = -dVth_dVd; dVgsteff_dVb = T0 * dVbseff_dVb; if (selfheat) dVgsteff_dT = -dVth_dT; else dVgsteff_dT = 0.0; } else if (ExpArg > EXPL_THRESHOLD) { T0 = (Vgst - pParam->B3SOIPDvoff) / (n * Vtm); ExpVgst = exp(T0); Vgsteff = Vtm * pParam->B3SOIPDcdep0 / model->B3SOIPDcox * ExpVgst; T3 = Vgsteff / (n * Vtm) ; /* T1 is dVgsteff_dVbseff */ T1 = -T3 * (dVth_dVb + T0 * Vtm * dn_dVb); dVgsteff_dVg = T3 * dVgs_eff_dVg; dVgsteff_dVd = -T3 * (dVth_dVd + T0 * Vtm * dn_dVd); dVgsteff_dVb = T1 * dVbseff_dVb; if (selfheat) dVgsteff_dT = -T3 * (dVth_dT + T0 * dVtm_dT * n) + Vgsteff / Temp; else dVgsteff_dT = 0.0; } else { ExpVgst = exp(VgstNVt); T1 = T10 * log(1.0 + ExpVgst); dT1_dVg = ExpVgst / (1.0 + ExpVgst); dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb) + T1 / n * dn_dVb; dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd) + T1 / n * dn_dVd; T3 = (1.0 / Temp); if (selfheat) dT1_dT = -dT1_dVg * (dVth_dT + Vgst * T3) + T1 * T3; else dT1_dT = 0.0; dT2_dVg = -model->B3SOIPDcox / (Vtm * pParam->B3SOIPDcdep0) * exp(ExpArg); T2 = 1.0 - T10 * dT2_dVg; dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd) + (T2 - 1.0) / n * dn_dVd; dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb) + (T2 - 1.0) / n * dn_dVb; if (selfheat) dT2_dT = -dT2_dVg * (dVth_dT - ExpArg * T10 * T3); else dT2_dT = 0.0; Vgsteff = T1 / T2; T3 = T2 * T2; /* T4 is dVgsteff_dVbseff */ T4 = (T2 * dT1_dVb - T1 * dT2_dVb) / T3; dVgsteff_dVb = T4 * dVbseff_dVb; dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg; dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3; if (selfheat) dVgsteff_dT = (T2 * dT1_dT - T1 * dT2_dT) / T3; else dVgsteff_dT = 0.0; } Vgst2Vtm = Vgsteff + 2.0 * Vtm; if (selfheat) dVgst2Vtm_dT = 2.0 * dVtm_dT; else dVgst2Vtm_dT = 0.0; here->B3SOIPDVgsteff = Vgsteff; /* v2.2.3 bug fix *//* Calculate Effective Channel Geometry */ T9 = sqrtPhis - sqrtPhi; Weff = pParam->B3SOIPDweff - (2.0 - here->B3SOIPDnbc) * (pParam->B3SOIPDdwg * Vgsteff + pParam->B3SOIPDdwb * T9); dWeff_dVg = -(2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwg; dWeff_dVb = -(2.0 - here->B3SOIPDnbc) * pParam->B3SOIPDdwb * 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; dWeff_dVg *= T0; dWeff_dVb *= T0; } T0 = pParam->B3SOIPDprwg * Vgsteff + pParam->B3SOIPDprwb * T9; if (T0 >= -0.9) { Rds = rds0 * (1.0 + T0); dRds_dVg = rds0 * pParam->B3SOIPDprwg; dRds_dVb = rds0 * pParam->B3SOIPDprwb * dsqrtPhis_dVb; if (selfheat && (Rds!=0.0)) dRds_dT = (1.0 + T0) * drds0_dT; else dRds_dT = 0.0; } else /* to avoid the discontinuity problem due to prwg and prwb*/ { T1 = 1.0 / (17.0 + 20.0 * T0); Rds = rds0 * (0.8 + T0) * T1; T1 *= T1; dRds_dVg = rds0 * pParam->B3SOIPDprwg * T1; dRds_dVb = rds0 * pParam->B3SOIPDprwb * dsqrtPhis_dVb * T1; if (selfheat && (Rds!=0.0)) dRds_dT = (0.8 + T0) * T1 * drds0_dT; else dRds_dT = 0.0; } here->B3SOIPDrds = Rds; /* v2.2.3 bug fix *//* Calculate Abulk */ if (pParam->B3SOIPDa0 == 0.0) { Abulk0 = Abulk = 1.0; dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; } else { T10 = pParam->B3SOIPDketa * Vbsh; if (T10 >= -0.9) { T11 = 1.0 / (1.0 + T10); dT11_dVb = -pParam->B3SOIPDketa * T11 * T11 * dVbsh_dVb; } else { /* added to avoid the problems caused by Keta */ T12 = 1.0 / (0.8 + T10); T11 = (17.0 + 20.0 * T10) * T12; dT11_dVb = -pParam->B3SOIPDketa * T12 * T12 * dVbsh_dVb; } T10 = pParam->B3SOIPDphi + pParam->B3SOIPDketas; T13 = (Vbsh * T11) / T10; dT13_dVb = (Vbsh * dT11_dVb + T11 * dVbsh_dVb) / T10; /* limit 1/sqrt(1-T13) to 6, starting at T13=0.96 */ if (T13 < 0.96) { T14 = 1 / sqrt(1-T13); T10 = 0.5 * T14 / (1-T13); dT14_dVb = T10 * dT13_dVb; } else { T11 = 1.0 / (1.0 - 1.043406*T13); T14 = (6.00167 - 6.26044 * T13) * T11; T10 = 0.001742 * T11 * T11; dT14_dVb = T10 * dT13_dVb; } T10 = 0.5 * pParam->B3SOIPDk1eff / sqrt(pParam->B3SOIPDphi + pParam->B3SOIPDketas); T1 = T10 * T14; dT1_dVb = T10 * dT14_dVb; T9 = sqrt(model->B3SOIPDxj * Xdep); tmp1 = Leff + 2.0 * T9; T5 = Leff / tmp1; tmp2 = pParam->B3SOIPDa0 * T5; tmp3 = pParam->B3SOIPDweff + pParam->B3SOIPDb1; tmp4 = pParam->B3SOIPDb0 / tmp3; T2 = tmp2 + tmp4; dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; T6 = T5 * T5; T7 = T5 * T6; Abulk0 = 1 + T1 * T2; dAbulk0_dVb = T1 * dT2_dVb + T2 * dT1_dVb; T8 = pParam->B3SOIPDags * pParam->B3SOIPDa0 * T7; dAbulk_dVg = -T1 * T8; Abulk = Abulk0 + dAbulk_dVg * Vgsteff; dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb + 3.0 * T1 * dT2_dVb / tmp2); } if (Abulk0 < 0.01) { T9 = 1.0 / (3.0 - 200.0 * Abulk0); Abulk0 = (0.02 - Abulk0) * T9; dAbulk0_dVb *= T9 * T9; } if (Abulk < 0.01) { T9 = 1.0 / (3.0 - 200.0 * Abulk); Abulk = (0.02 - Abulk) * T9; dAbulk_dVb *= T9 * T9; }/* Mobility calculation */ if (model->B3SOIPDmobMod == 1) { T0 = Vgsteff + Vth + Vth; T2 = ua + uc * Vbseff; T3 = T0 / model->B3SOIPDtox; T5 = T3 * (T2 + ub * T3); dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIPDtox; dDenomi_dVd = dDenomi_dVg * 2 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2 * dVth_dVb + uc * T3 ; if (selfheat) dDenomi_dT = dDenomi_dVg * 2 * dVth_dT + (dua_dT + Vbseff * duc_dT + dub_dT * T3 ) * T3; else dDenomi_dT = 0.0; } else if (model->B3SOIPDmobMod == 2) { T5 = Vgsteff / model->B3SOIPDtox * (ua + uc * Vbseff + ub * Vgsteff / model->B3SOIPDtox); dDenomi_dVg = (ua + uc * Vbseff + 2.0 * ub * Vgsteff / model->B3SOIPDtox) / model->B3SOIPDtox; dDenomi_dVd = 0.0; dDenomi_dVb = Vgsteff * uc / model->B3SOIPDtox ; if (selfheat) dDenomi_dT = Vgsteff / model->B3SOIPDtox * (dua_dT + Vbseff * duc_dT + dub_dT * Vgsteff / model->B3SOIPDtox); else dDenomi_dT = 0.0; } else /* mobMod == 3 */ { T0 = Vgsteff + Vth + Vth; T2 = 1.0 + uc * Vbseff; T3 = T0 / model->B3SOIPDtox; T4 = T3 * (ua + ub * T3); T5 = T4 * T2; dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 / model->B3SOIPDtox; dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd; dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + uc * T4 ; if (selfheat) dDenomi_dT = dDenomi_dVg * 2.0 * dVth_dT + (dua_dT + dub_dT * T3) * T3 * T2 + T4 * Vbseff * duc_dT; else dDenomi_dT = 0.0; } 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; if (selfheat) dDenomi_dT *= T9; else dDenomi_dT = 0.0; } here->B3SOIPDueff = ueff = u0temp / Denomi; T9 = -ueff / Denomi; dueff_dVg = T9 * dDenomi_dVg; dueff_dVd = T9 * dDenomi_dVd; dueff_dVb = T9 * dDenomi_dVb; if (selfheat) dueff_dT = T9 * dDenomi_dT + du0temp_dT / Denomi; else dueff_dT = 0.0;/* Saturation Drain Voltage Vdsat */ WVCox = Weff * vsattemp * model->B3SOIPDcox; WVCoxRds = WVCox * Rds; /* dWVCoxRds_dT = WVCox * dRds_dT + Weff * model->B3SOIPDcox * Rds * dvsattemp_dT; */ Esat = 2.0 * vsattemp / ueff; EsatL = Esat * Leff; T0 = -EsatL /ueff; dEsatL_dVg = T0 * dueff_dVg; dEsatL_dVd = T0 * dueff_dVd; dEsatL_dVb = T0 * dueff_dVb; if (selfheat) dEsatL_dT = T0 * dueff_dT + EsatL / vsattemp * dvsattemp_dT; else dEsatL_dT = 0.0; /* Sqrt() */ a1 = pParam->B3SOIPDa1; if (a1 == 0.0) { Lambda = pParam->B3SOIPDa2; 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->B3SOIPDa2; T1 = T0 - pParam->B3SOIPDa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * T0); Lambda = pParam->B3SOIPDa2 + T0 - 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->B3SOIPDa1 * (1.0 + T1 / T2); } else { T1 = pParam->B3SOIPDa2 + pParam->B3SOIPDa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * pParam->B3SOIPDa2); Lambda = 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->B3SOIPDa1 * (1.0 + T1 / T2); } here->B3SOIPDAbovVgst2Vtm = Abulk /Vgst2Vtm; /* v2.2.3 bug fix */ 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 + EsatL * dAbulk_dVb) * T1; if (selfheat) dT0_dT = -(Abulk * dEsatL_dT + dVgst2Vtm_dT) * T1; else dT0_dT = 0.0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -