📄 b3soifdld.c
字号:
/* Calculate Effective Channel Geometry */ T9 = sqrtPhis - sqrtPhi; Weff = pParam->B3SOIFDweff - 2.0 * (pParam->B3SOIFDdwg * Vgsteff + pParam->B3SOIFDdwb * T9); dWeff_dVg = -2.0 * pParam->B3SOIFDdwg; dWeff_dVb = -2.0 * pParam->B3SOIFDdwb * 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->B3SOIFDprwg * Vgsteff + pParam->B3SOIFDprwb * T9; if (T0 >= -0.9) { Rds = rds0 * (1.0 + T0); dRds_dVg = rds0 * pParam->B3SOIFDprwg; dRds_dVb = rds0 * pParam->B3SOIFDprwb * dsqrtPhis_dVb; if (selfheat) 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->B3SOIFDprwg * T1; dRds_dVb = rds0 * pParam->B3SOIFDprwb * dsqrtPhis_dVb * T1; if (selfheat) dRds_dT = (0.8 + T0) * T1 * drds0_dT; else dRds_dT = 0.0; }/* Calculate Abulk */ if (pParam->B3SOIFDa0 == 0.0) { Abulk0 = Abulk = dAbulk0_dVb = dAbulk_dVg = dAbulk_dVb = 0.0; } else { T1 = 0.5 * pParam->B3SOIFDk1 / sqrtPhi; T9 = sqrt(model->B3SOIFDxj * Xdep); tmp1 = Leff + 2.0 * T9; T5 = Leff / tmp1; tmp2 = pParam->B3SOIFDa0 * T5; tmp3 = pParam->B3SOIFDweff + pParam->B3SOIFDb1; tmp4 = pParam->B3SOIFDb0 / tmp3; T2 = tmp2 + tmp4; dT2_dVb = -T9 * tmp2 / tmp1 / Xdep * dXdep_dVb; T6 = T5 * T5; T7 = T5 * T6; Abulk0 = T1 * T2; dAbulk0_dVb = T1 * dT2_dVb; T8 = pParam->B3SOIFDags * pParam->B3SOIFDa0 * T7; dAbulk_dVg = -T1 * T8; Abulk = Abulk0 + dAbulk_dVg * Vgsteff; dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * 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; } T2 = pParam->B3SOIFDketa * Vbseff; if (T2 >= -0.9) { T0 = 1.0 / (1.0 + T2); dT0_dVb = -pParam->B3SOIFDketa * 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->B3SOIFDketa * 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; Abulk += 1; Abulk0 += 1;/* Prepare Abeff */ T0 = pParam->B3SOIFDabp * Vgst2Vtm; T1 = 1 - Vcs / T0 - DELT_Xcsat; T2 = sqrt(T1 * T1 + DELT_Xcsat * DELT_Xcsat); T3 = 1 - 0.5 * (T1 + T2); T5 = -0.5 * (1 + T1 / T2); dT1_dVg = Vcs / Vgst2Vtm / T0; dT3_dVg = T5 * dT1_dVg; dT1_dVc = - 1 / T0; dT3_dVc = T5 * dT1_dVc; Xcsat = pParam->B3SOIFDmxc * T3 * T3 + (1 - pParam->B3SOIFDmxc)*T3; T4 = 2 * pParam->B3SOIFDmxc * T3 + (1 - pParam->B3SOIFDmxc); dXcsat_dVg = T4 * dT3_dVg; dXcsat_dVc = T4 * dT3_dVc; Abeff = Xcsat * Abulk + (1 - Xcsat) * model->B3SOIFDadice; T0 = Xcsat * dAbulk_dVg + Abulk * dXcsat_dVg; dAbeff_dVg = T0 - model->B3SOIFDadice * dXcsat_dVg; dAbeff_dVb = Xcsat * dAbulk_dVb; dAbeff_dVc = (Abulk - model->B3SOIFDadice) * dXcsat_dVc; here->B3SOIFDabeff = Abeff;/* Mobility calculation */ if (model->B3SOIFDmobMod == 1) { T0 = Vgsteff + Vth + Vth; T2 = ua + uc * Vbseff; T3 = T0 / model->B3SOIFDtox; T5 = T3 * (T2 + ub * T3); dDenomi_dVg = (T2 + 2.0 * ub * T3) / model->B3SOIFDtox; 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->B3SOIFDmobMod == 2) { T5 = Vgsteff / model->B3SOIFDtox * (ua + uc * Vbseff + ub * Vgsteff / model->B3SOIFDtox); dDenomi_dVg = (ua + uc * Vbseff + 2.0 * ub * Vgsteff / model->B3SOIFDtox) / model->B3SOIFDtox; dDenomi_dVd = 0.0; dDenomi_dVb = Vgsteff * uc / model->B3SOIFDtox ; if (selfheat) dDenomi_dT = Vgsteff / model->B3SOIFDtox * (dua_dT + Vbseff * duc_dT + dub_dT * Vgsteff / model->B3SOIFDtox); else dDenomi_dT = 0.0; } else /* mobMod == 3 */ { T0 = Vgsteff + Vth + Vth; T2 = 1.0 + uc * Vbseff; T3 = T0 / model->B3SOIFDtox; T4 = T3 * (ua + ub * T3); T5 = T4 * T2; dDenomi_dVg = (ua + 2.0 * ub * T3) * T2 / model->B3SOIFDtox; 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->B3SOIFDueff = 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->B3SOIFDcox; WVCoxRds = WVCox * Rds; /* dWVCoxRds_dT = WVCox * dRds_dT + Weff * model->B3SOIFDcox * 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->B3SOIFDa1; if (a1 == 0.0) { Lambda = pParam->B3SOIFDa2; 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->B3SOIFDa2; T1 = T0 - pParam->B3SOIFDa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * T0); Lambda = pParam->B3SOIFDa2 + T0 - 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->B3SOIFDa1 * (1.0 + T1 / T2); } else { T1 = pParam->B3SOIFDa2 + pParam->B3SOIFDa1 * Vgsteff - 0.0001; T2 = sqrt(T1 * T1 + 0.0004 * pParam->B3SOIFDa2); Lambda = 0.5 * (T1 + T2); dLambda_dVg = 0.5 * pParam->B3SOIFDa1 * (1.0 + T1 / T2); } 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 / (Abeff * EsatL + Vgst2Vtm); tmp1 = 0.0; T1 = T0 * T0; T2 = Vgst2Vtm * T0; T3 = EsatL * Vgst2Vtm; Vdsat = T3 * T0; dT0_dVg = -(Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 1.0) * T1; dT0_dVd = -(Abeff * dEsatL_dVd) * T1; dT0_dVb = -(Abeff * dEsatL_dVb + EsatL * dAbeff_dVb) * T1; dT0_dVc = 0.0; if (selfheat) dT0_dT = -(Abeff * dEsatL_dT + dVgst2Vtm_dT) * T1; else dT0_dT = 0.0; 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_dVc = 0.0; if (selfheat) dVdsat_dT = T3 * dT0_dT + T2 * dEsatL_dT + EsatL * T0 * dVgst2Vtm_dT; else dVdsat_dT = 0.0; } else { tmp1 = dLambda_dVg / (Lambda * Lambda); T9 = Abeff * WVCoxRds; T8 = Abeff * T9; T7 = Vgst2Vtm * T9; T6 = Vgst2Vtm * WVCoxRds; T0 = 2.0 * Abeff * (T9 - 1.0 + 1.0 / Lambda); dT0_dVg = 2.0 * (T8 * tmp2 - Abeff * tmp1 + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg);/* dT0_dVb = 2.0 * (T8 * tmp3 this is equivalent to one below, but simpler + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbeff_dVg); */ dT0_dVb = 2.0 * (T8 * (2.0 / Abeff * dAbeff_dVb + tmp3) + (1.0 / Lambda - 1.0) * dAbeff_dVb); dT0_dVd = 0.0; dT0_dVc = 0.0; if (selfheat) { tmp4 = dRds_dT / Rds + dvsattemp_dT / vsattemp; dT0_dT = 2.0 * T8 * tmp4; } else tmp4 = dT0_dT = 0.0; T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abeff * EsatL + 3.0 * T7; dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1 + Abeff * dEsatL_dVg + EsatL * dAbeff_dVg + 3.0 * (T9 + T7 * tmp2 + T6 * dAbeff_dVg); dT1_dVb = Abeff * dEsatL_dVb + EsatL * dAbeff_dVb + 3.0 * (T6 * dAbeff_dVb + T7 * tmp3); dT1_dVd = Abeff * dEsatL_dVd; dT1_dVc = 0.0; if (selfheat) { tmp4 += dVgst2Vtm_dT / Vgst2Vtm; dT1_dT = (2.0 / Lambda - 1.0) * dVgst2Vtm_dT + Abeff * dEsatL_dT + 3.0 * T7 * tmp4; } else dT1_dT = 0.0; 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; if (selfheat) dT2_dT = Vgst2Vtm * dEsatL_dT + EsatL * dVgst2Vtm_dT + 2.0 * T6 * (dVgst2Vtm_dT + Vgst2Vtm * tmp4); else dT2_dT = 0.0; T3 = sqrt(T1 * T1 - 2.0 * T0 * T2); Vdsat = (T1 - T3) / T0; 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; dVdsat_dVc = 0.0; if (selfheat) dVdsat_dT = (dT1_dT - (T1 * dT1_dT - dT0_dT * T2 - T0 * dT2_dT) / T3 - Vdsat * dT0_dT) / T0; else dVdsat_dT = 0.0; } here->B3SOIFDvdsat = Vdsat;/* Vdsatii for impact ionization */ if (pParam->B3SOIFDaii > 0.0) { if (pParam->B3SOIFDcii != 0.0) { T0 = pParam->B3SOIFDcii / sqrt(3.0) + pParam->B3SOIFDdii; /* Hard limit Vds to T0 => T4 i.e. limit T0 to 3.0 */ T1 = Vds - T0 - 0.1; T2 = sqrt(T1 * T1 + 0.4); T3 =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -