private BSIM2 CreateMosfet(string name, string drain, string gate, string source, string bulk, double w, double l, string model) { var e = new BSIM2(name, drain, gate, source, bulk); e.SetParameter("w", w); e.SetParameter("l", l); e.Model = model; return(e); }
/// <summary> /// This routine evaluates the drain current, its derivatives and the /// charges associated with the gate,bulk and drain terminal /// using the B2(Berkeley Short-Channel IGFET Model) Equations. /// </summary> /// <param name="bsim2"></param> /// <param name="Vds"></param> /// <param name="Vbs"></param> /// <param name="Vgs"></param> /// <param name="gm"></param> /// <param name="gds"></param> /// <param name="gmb"></param> /// <param name="qg"></param> /// <param name="qb"></param> /// <param name="qd"></param> /// <param name="cgg"></param> /// <param name="cgd"></param> /// <param name="cgs"></param> /// <param name="cbg"></param> /// <param name="cbd"></param> /// <param name="cbs"></param> /// <param name="cdg"></param> /// <param name="cdd"></param> /// <param name="cds"></param> /// <param name="Ids"></param> /// <param name="von"></param> /// <param name="vdsat"></param> /// <param name="ckt"></param> public static void B2evaluate(this BSIM2 bsim2, double Vds, double Vbs, double Vgs, out double gm, out double gds, out double gmb, out double qg, out double qb, out double qd, out double cgg, out double cgd, out double cgs, out double cbg, out double cbd, out double cbs, out double cdg, out double cdd, out double cds, out double Ids, out double von, out double vdsat, Circuit ckt) { var model = bsim2.Model as BSIM2Model; double Vth, Vdsat = 0.0; double Phisb, T1s, Eta, Gg, Aa, Inv_Aa, U1, U1s, Vc, Kk, SqrtKk; double dPhisb_dVb, dT1s_dVb, dVth_dVb, dVth_dVd, dAa_dVb, dVc_dVd; double dVc_dVg, dVc_dVb, dKk_dVc, dVdsat_dVd = 0.0, dVdsat_dVg = 0.0, dVdsat_dVb = 0.0; double dUvert_dVg, dUvert_dVd, dUvert_dVb, Inv_Kk; double dUtot_dVd, dUtot_dVb, dUtot_dVg, Ai, Bi, Vghigh, Vglow, Vgeff, Vof; double Vbseff, Vgst, Vgdt, Qbulk, Utot; double T0, T1, T2, T3, T4, T5, Arg1, Arg2, Exp0 = 0.0; double tmp, tmp1, tmp2, tmp3, Uvert, Beta1, Beta2, Beta0, dGg_dVb, Exp1 = 0.0; double T6, T7, T8, T9, n = 0.0, ExpArg, ExpArg1; double Beta, dQbulk_dVb, dVgdt_dVg, dVgdt_dVd; double dVbseff_dVb, Ua, Ub, dVgdt_dVb, dQbulk_dVd; double Con1, Con3, Con4, SqrVghigh, SqrVglow, CubVghigh, CubVglow; double delta, Coeffa, Coeffb, Coeffc, Coeffd, Inv_Uvert, Inv_Utot; double Inv_Vdsat, tanh, Sqrsech, dBeta1_dVb, dU1_dVd, dU1_dVg, dU1_dVb; double Betaeff, FR, dFR_dVd, dFR_dVg, dFR_dVb, Betas, Beta3, Beta4; double dBeta_dVd, dBeta_dVg, dBeta_dVb, dVgeff_dVg, dVgeff_dVd, dVgeff_dVb; double dCon3_dVd, dCon3_dVb, dCon4_dVd, dCon4_dVb, dCoeffa_dVd, dCoeffa_dVb; double dCoeffb_dVd, dCoeffb_dVb, dCoeffc_dVd, dCoeffc_dVb; double dCoeffd_dVd, dCoeffd_dVb; bool ChargeComputationNeeded; int valuetypeflag; /* added 3/19/90 JSD */ if (ckt.Method != null || (ckt.State.Domain == State.DomainTypes.Time && ckt.State.UseDC && ckt.State.UseIC) || ckt.State.UseSmallSignal) { ChargeComputationNeeded = true; } else { ChargeComputationNeeded = false; } if (Vbs < model.B2vbb2) { Vbs = model.B2vbb2; } if (Vgs > model.B2vgg2) { Vgs = model.B2vgg2; } if (Vds > model.B2vdd2) { Vds = model.B2vdd2; } /* Threshold Voltage. */ if (Vbs <= 0.0) { Phisb = bsim2.pParam.B2phi - Vbs; dPhisb_dVb = -1.0; T1s = Math.Sqrt(Phisb); dT1s_dVb = -0.5 / T1s; } else { tmp = bsim2.pParam.B2phi / (bsim2.pParam.B2phi + Vbs); Phisb = bsim2.pParam.B2phi * tmp; dPhisb_dVb = -tmp * tmp; T1s = bsim2.pParam.Phis3 / (bsim2.pParam.B2phi + 0.5 * Vbs); dT1s_dVb = -0.5 * T1s * T1s / bsim2.pParam.Phis3; } Eta = bsim2.pParam.B2eta0 + bsim2.pParam.B2etaB * Vbs; Ua = bsim2.pParam.B2ua0 + bsim2.pParam.B2uaB * Vbs; Ub = bsim2.pParam.B2ub0 + bsim2.pParam.B2ubB * Vbs; U1s = bsim2.pParam.B2u10 + bsim2.pParam.B2u1B * Vbs; Vth = bsim2.pParam.B2vfb + bsim2.pParam.B2phi + bsim2.pParam.B2k1 * T1s - bsim2.pParam.B2k2 * Phisb - Eta * Vds; dVth_dVd = -Eta; dVth_dVb = bsim2.pParam.B2k1 * dT1s_dVb + bsim2.pParam.B2k2 - bsim2.pParam.B2etaB * Vds; Vgst = Vgs - Vth; tmp = 1.0 / (1.744 + 0.8364 * Phisb); Gg = 1.0 - tmp; dGg_dVb = 0.8364 * tmp * tmp * dPhisb_dVb; T0 = Gg / T1s; tmp1 = 0.5 * T0 * bsim2.pParam.B2k1; Aa = 1.0 + tmp1; dAa_dVb = (Aa - 1.0) * (dGg_dVb / Gg - dT1s_dVb / T1s); Inv_Aa = 1.0 / Aa; Vghigh = bsim2.pParam.B2vghigh; Vglow = bsim2.pParam.B2vglow; if ((Vgst >= Vghigh) || (bsim2.pParam.B2n0 == 0.0)) { Vgeff = Vgst; dVgeff_dVg = 1.0; dVgeff_dVd = -dVth_dVd; dVgeff_dVb = -dVth_dVb; } else { Vof = bsim2.pParam.B2vof0 + bsim2.pParam.B2vofB * Vbs + bsim2.pParam.B2vofD * Vds; n = bsim2.pParam.B2n0 + bsim2.pParam.B2nB / T1s + bsim2.pParam.B2nD * Vds; tmp = 0.5 / (n * model.B2Vtm); ExpArg1 = -Vds / model.B2Vtm; ExpArg1 = Math.Max(ExpArg1, -30.0); Exp1 = Math.Exp(ExpArg1); tmp1 = 1.0 - Exp1; tmp1 = Math.Max(tmp1, 1.0e-18); tmp2 = 2.0 * Aa * tmp1; if (Vgst <= Vglow) { ExpArg = Vgst * tmp; ExpArg = Math.Max(ExpArg, -30.0); Exp0 = Math.Exp(0.5 * Vof + ExpArg); Vgeff = Math.Sqrt(tmp2) * model.B2Vtm * Exp0; T0 = n * model.B2Vtm; dVgeff_dVg = Vgeff * tmp; dVgeff_dVd = dVgeff_dVg * (n / tmp1 * Exp1 - dVth_dVd - Vgst * bsim2.pParam.B2nD / n + T0 * bsim2.pParam.B2vofD); dVgeff_dVb = dVgeff_dVg * (bsim2.pParam.B2vofB * T0 - dVth_dVb + bsim2.pParam.B2nB * Vgst / (n * T1s * T1s) * dT1s_dVb + T0 * Inv_Aa * dAa_dVb); } else { ExpArg = Vglow * tmp; ExpArg = Math.Max(ExpArg, -30.0); Exp0 = Math.Exp(0.5 * Vof + ExpArg); Vgeff = Math.Sqrt(2.0 * Aa * (1.0 - Exp1)) * model.B2Vtm * Exp0; Con1 = Vghigh; Con3 = Vgeff; Con4 = Con3 * tmp; SqrVghigh = Vghigh * Vghigh; SqrVglow = Vglow * Vglow; CubVghigh = Vghigh * SqrVghigh; CubVglow = Vglow * SqrVglow; T0 = 2.0 * Vghigh; T1 = 2.0 * Vglow; T2 = 3.0 * SqrVghigh; T3 = 3.0 * SqrVglow; T4 = Vghigh - Vglow; T5 = SqrVghigh - SqrVglow; T6 = CubVghigh - CubVglow; T7 = Con1 - Con3; delta = (T1 - T0) * T6 + (T2 - T3) * T5 + (T0 * T3 - T1 * T2) * T4; delta = 1.0 / delta; Coeffb = (T1 - Con4 * T0) * T6 + (Con4 * T2 - T3) * T5 + (T0 * T3 - T1 * T2) * T7; Coeffc = (Con4 - 1.0) * T6 + (T2 - T3) * T7 + (T3 - Con4 * T2) * T4; Coeffd = (T1 - T0) * T7 + (1.0 - Con4) * T5 + (Con4 * T0 - T1) * T4; Coeffa = SqrVghigh * (Coeffc + Coeffd * T0); Vgeff = (Coeffa + Vgst * (Coeffb + Vgst * (Coeffc + Vgst * Coeffd))) * delta; dVgeff_dVg = (Coeffb + Vgst * (2.0 * Coeffc + 3.0 * Vgst * Coeffd)) * delta; T7 = Con3 * tmp; T8 = dT1s_dVb * bsim2.pParam.B2nB / (T1s * T1s * n); T9 = n * model.B2Vtm; dCon3_dVd = T7 * (n * Exp1 / tmp1 - Vglow * bsim2.pParam.B2nD / n + T9 * bsim2.pParam.B2vofD); dCon3_dVb = T7 * (T9 * Inv_Aa * dAa_dVb + Vglow * T8 + T9 * bsim2.pParam.B2vofB); dCon4_dVd = tmp * dCon3_dVd - T7 * bsim2.pParam.B2nD / n; dCon4_dVb = tmp * dCon3_dVb + T7 * T8; dCoeffb_dVd = dCon4_dVd * (T2 * T5 - T0 * T6) + dCon3_dVd * (T1 * T2 - T0 * T3); dCoeffc_dVd = dCon4_dVd * (T6 - T2 * T4) + dCon3_dVd * (T3 - T2); dCoeffd_dVd = dCon4_dVd * (T0 * T4 - T5) + dCon3_dVd * (T0 - T1); dCoeffa_dVd = SqrVghigh * (dCoeffc_dVd + dCoeffd_dVd * T0); dVgeff_dVd = -dVgeff_dVg * dVth_dVd + (dCoeffa_dVd + Vgst * (dCoeffb_dVd + Vgst * (dCoeffc_dVd + Vgst * dCoeffd_dVd))) * delta; dCoeffb_dVb = dCon4_dVb * (T2 * T5 - T0 * T6) + dCon3_dVb * (T1 * T2 - T0 * T3); dCoeffc_dVb = dCon4_dVb * (T6 - T2 * T4) + dCon3_dVb * (T3 - T2); dCoeffd_dVb = dCon4_dVb * (T0 * T4 - T5) + dCon3_dVb * (T0 - T1); dCoeffa_dVb = SqrVghigh * (dCoeffc_dVb + dCoeffd_dVb * T0); dVgeff_dVb = -dVgeff_dVg * dVth_dVb + (dCoeffa_dVb + Vgst * (dCoeffb_dVb + Vgst * (dCoeffc_dVb + Vgst * dCoeffd_dVb))) * delta; } } if (Vgeff > 0.0) { Uvert = 1.0 + Vgeff * (Ua + Vgeff * Ub); Uvert = Math.Max(Uvert, 0.2); Inv_Uvert = 1.0 / Uvert; T8 = Ua + 2.0 * Ub * Vgeff; dUvert_dVg = T8 * dVgeff_dVg; dUvert_dVd = T8 * dVgeff_dVd; dUvert_dVb = T8 * dVgeff_dVb + Vgeff * (bsim2.pParam.B2uaB + Vgeff * bsim2.pParam.B2ubB); T8 = U1s * Inv_Aa * Inv_Uvert; Vc = T8 * Vgeff; T9 = Vc * Inv_Uvert; dVc_dVg = T8 * dVgeff_dVg - T9 * dUvert_dVg; dVc_dVd = T8 * dVgeff_dVd - T9 * dUvert_dVd; dVc_dVb = T8 * dVgeff_dVb + bsim2.pParam.B2u1B * Vgeff * Inv_Aa * Inv_Uvert - Vc * Inv_Aa * dAa_dVb - T9 * dUvert_dVb; tmp2 = Math.Sqrt(1.0 + 2.0 * Vc); Kk = 0.5 * (1.0 + Vc + tmp2); Inv_Kk = 1.0 / Kk; dKk_dVc = 0.5 + 0.5 / tmp2; SqrtKk = Math.Sqrt(Kk); T8 = Inv_Aa / SqrtKk; Vdsat = Vgeff * T8; Vdsat = Math.Max(Vdsat, 1.0e-18); Inv_Vdsat = 1.0 / Vdsat; T9 = 0.5 * Vdsat * Inv_Kk * dKk_dVc; dVdsat_dVd = T8 * dVgeff_dVd - T9 * dVc_dVd; dVdsat_dVg = T8 * dVgeff_dVg - T9 * dVc_dVg; dVdsat_dVb = T8 * dVgeff_dVb - T9 * dVc_dVb - Vdsat * Inv_Aa * dAa_dVb; Beta0 = bsim2.pParam.B2beta0 + bsim2.pParam.B2beta0B * Vbs; Betas = bsim2.pParam.B2betas0 + bsim2.pParam.B2betasB * Vbs; Beta2 = bsim2.pParam.B2beta20 + bsim2.pParam.B2beta2B * Vbs + bsim2.pParam.B2beta2G * Vgs; Beta3 = bsim2.pParam.B2beta30 + bsim2.pParam.B2beta3B * Vbs + bsim2.pParam.B2beta3G * Vgs; Beta4 = bsim2.pParam.B2beta40 + bsim2.pParam.B2beta4B * Vbs + bsim2.pParam.B2beta4G * Vgs; Beta1 = Betas - (Beta0 + model.B2vdd * (Beta3 - model.B2vdd * Beta4)); T0 = Vds * Beta2 * Inv_Vdsat; T0 = Math.Min(T0, 30.0); T1 = Math.Exp(T0); T2 = T1 * T1; T3 = T2 + 1.0; tanh = (T2 - 1.0) / T3; Sqrsech = 4.0 * T2 / (T3 * T3); Beta = Beta0 + Beta1 * tanh + Vds * (Beta3 - Beta4 * Vds); T4 = Beta1 * Sqrsech * Inv_Vdsat; T5 = model.B2vdd * tanh; dBeta_dVd = Beta3 - 2.0 * Beta4 * Vds + T4 * (Beta2 - T0 * dVdsat_dVd); dBeta_dVg = T4 * (bsim2.pParam.B2beta2G * Vds - T0 * dVdsat_dVg) + bsim2.pParam.B2beta3G * (Vds - T5) - bsim2.pParam.B2beta4G * (Vds * Vds - model.B2vdd * T5); dBeta1_dVb = bsim2.pParam.Arg; dBeta_dVb = bsim2.pParam.B2beta0B + dBeta1_dVb * tanh + Vds * (bsim2.pParam.B2beta3B - Vds * bsim2.pParam.B2beta4B) + T4 * (bsim2.pParam.B2beta2B * Vds - T0 * dVdsat_dVb); if (Vgst > Vglow) { if (Vds <= Vdsat) /* triode region */ { T3 = Vds * Inv_Vdsat; T4 = T3 - 1.0; T2 = 1.0 - bsim2.pParam.B2u1D * T4 * T4; U1 = U1s * T2; Utot = Uvert + U1 * Vds; Utot = Math.Max(Utot, 0.5); Inv_Utot = 1.0 / Utot; T5 = 2.0 * U1s * bsim2.pParam.B2u1D * Inv_Vdsat * T4; dU1_dVd = T5 * (T3 * dVdsat_dVd - 1.0); dU1_dVg = T5 * T3 * dVdsat_dVg; dU1_dVb = T5 * T3 * dVdsat_dVb + bsim2.pParam.B2u1B * T2; dUtot_dVd = dUvert_dVd + U1 + Vds * dU1_dVd; dUtot_dVg = dUvert_dVg + Vds * dU1_dVg; dUtot_dVb = dUvert_dVb + Vds * dU1_dVb; tmp1 = (Vgeff - 0.5 * Aa * Vds); tmp3 = tmp1 * Vds; Betaeff = Beta * Inv_Utot; Ids = Betaeff * tmp3; T6 = Ids / Betaeff * Inv_Utot; gds = T6 * (dBeta_dVd - Betaeff * dUtot_dVd) + Betaeff * (tmp1 + (dVgeff_dVd - 0.5 * Aa) * Vds); gm = T6 * (dBeta_dVg - Betaeff * dUtot_dVg) + Betaeff * Vds * dVgeff_dVg; gmb = T6 * (dBeta_dVb - Betaeff * dUtot_dVb) + Betaeff * Vds * (dVgeff_dVb - 0.5 * Vds * dAa_dVb); } else /* Saturation */ { tmp1 = Vgeff * Inv_Aa * Inv_Kk; tmp3 = 0.5 * Vgeff * tmp1; Betaeff = Beta * Inv_Uvert; Ids = Betaeff * tmp3; T0 = Ids / Betaeff * Inv_Uvert; T1 = Betaeff * Vgeff * Inv_Aa * Inv_Kk; T2 = Ids * Inv_Kk * dKk_dVc; if (bsim2.pParam.B2ai0 != 0.0) { Ai = bsim2.pParam.B2ai0 + bsim2.pParam.B2aiB * Vbs; Bi = bsim2.pParam.B2bi0 + bsim2.pParam.B2biB * Vbs; T5 = Bi / (Vds - Vdsat); T5 = Math.Min(T5, 30.0); T6 = Math.Exp(-T5); FR = 1.0 + Ai * T6; T7 = T5 / (Vds - Vdsat); T8 = (1.0 - FR) * T7; dFR_dVd = T8 * (dVdsat_dVd - 1.0); dFR_dVg = T8 * dVdsat_dVg; dFR_dVb = T8 * dVdsat_dVb + T6 * (bsim2.pParam.B2aiB - Ai * bsim2.pParam.B2biB / (Vds - Vdsat)); gds = (T0 * (dBeta_dVd - Betaeff * dUvert_dVd) + T1 * dVgeff_dVd - T2 * dVc_dVd) * FR + Ids * dFR_dVd; gm = (T0 * (dBeta_dVg - Betaeff * dUvert_dVg) + T1 * dVgeff_dVg - T2 * dVc_dVg) * FR + Ids * dFR_dVg; gmb = (T0 * (dBeta_dVb - Betaeff * dUvert_dVb) + T1 * dVgeff_dVb - T2 * dVc_dVb - Ids * Inv_Aa * dAa_dVb) * FR + Ids * dFR_dVb; Ids *= FR; } else { gds = T0 * (dBeta_dVd - Betaeff * dUvert_dVd) + T1 * dVgeff_dVd - T2 * dVc_dVd; gm = T0 * (dBeta_dVg - Betaeff * dUvert_dVg) + T1 * dVgeff_dVg - T2 * dVc_dVg; gmb = T0 * (dBeta_dVb - Betaeff * dUvert_dVb) + T1 * dVgeff_dVb - T2 * dVc_dVb - Ids * Inv_Aa * dAa_dVb; } } /* end of Saturation */ } else { T0 = Exp0 * Exp0; T1 = Exp1; Ids = Beta * model.B2Vtm * model.B2Vtm * T0 * (1.0 - T1); T2 = Ids / Beta; T4 = n * model.B2Vtm; T3 = Ids / T4; if ((Vds > Vdsat) && bsim2.pParam.B2ai0 != 0.0) { Ai = bsim2.pParam.B2ai0 + bsim2.pParam.B2aiB * Vbs; Bi = bsim2.pParam.B2bi0 + bsim2.pParam.B2biB * Vbs; T5 = Bi / (Vds - Vdsat); T5 = Math.Min(T5, 30.0); T6 = Math.Exp(-T5); FR = 1.0 + Ai * T6; T7 = T5 / (Vds - Vdsat); T8 = (1.0 - FR) * T7; dFR_dVd = T8 * (dVdsat_dVd - 1.0); dFR_dVg = T8 * dVdsat_dVg; dFR_dVb = T8 * dVdsat_dVb + T6 * (bsim2.pParam.B2aiB - Ai * bsim2.pParam.B2biB / (Vds - Vdsat)); } else { FR = 1.0; dFR_dVd = 0.0; dFR_dVg = 0.0; dFR_dVb = 0.0; } gds = (T2 * dBeta_dVd + T3 * (bsim2.pParam.B2vofD * T4 - dVth_dVd - bsim2.pParam.B2nD * Vgst / n) + Beta * model.B2Vtm * T0 * T1) * FR + Ids * dFR_dVd; gm = (T2 * dBeta_dVg + T3) * FR + Ids * dFR_dVg; gmb = (T2 * dBeta_dVb + T3 * (bsim2.pParam.B2vofB * T4 - dVth_dVb + bsim2.pParam.B2nB * Vgst / (n * T1s * T1s) * dT1s_dVb)) * FR + Ids * dFR_dVb; Ids *= FR; } } else { Ids = 0.0; gm = 0.0; gds = 0.0; gmb = 0.0; } /* Some Limiting of DC Parameters */ gds = Math.Max(gds, 1.0e-20); if ((model.B2channelChargePartitionFlag > 1) || ((!ChargeComputationNeeded) && (model.B2channelChargePartitionFlag > -5))) { qg = 0.0; qd = 0.0; qb = 0.0; cgg = 0.0; cgs = 0.0; cgd = 0.0; cdg = 0.0; cds = 0.0; cdd = 0.0; cbg = 0.0; cbs = 0.0; cbd = 0.0; goto finished; } else { if (Vbs < 0.0) { Vbseff = Vbs; dVbseff_dVb = 1.0; } else { Vbseff = bsim2.pParam.B2phi - Phisb; dVbseff_dVb = -dPhisb_dVb; } Arg1 = Vgs - Vbseff - bsim2.pParam.B2vfb; Arg2 = Arg1 - Vgst; Qbulk = bsim2.pParam.One_Third_CoxWL * Arg2; dQbulk_dVb = bsim2.pParam.One_Third_CoxWL * (dVth_dVb - dVbseff_dVb); dQbulk_dVd = bsim2.pParam.One_Third_CoxWL * dVth_dVd; if (Arg1 <= 0.0) { qg = bsim2.pParam.CoxWL * Arg1; qb = -(qg); qd = 0.0; cgg = bsim2.pParam.CoxWL; cgd = 0.0; cgs = -cgg * (1.0 - dVbseff_dVb); cdg = 0.0; cdd = 0.0; cds = 0.0; cbg = -bsim2.pParam.CoxWL; cbd = 0.0; cbs = -cgs; } else if (Vgst <= 0.0) { T2 = Arg1 / Arg2; T3 = T2 * T2 * (bsim2.pParam.CoxWL - bsim2.pParam.Two_Third_CoxWL * T2); qg = bsim2.pParam.CoxWL * Arg1 * (1.0 - T2 * (1.0 - T2 / 3.0)); qb = -(qg); qd = 0.0; cgg = bsim2.pParam.CoxWL * (1.0 - T2 * (2.0 - T2)); tmp = T3 * dVth_dVb - (cgg + T3) * dVbseff_dVb; cgd = T3 * dVth_dVd; cgs = -(cgg + cgd + tmp); cdg = 0.0; cdd = 0.0; cds = 0.0; cbg = -cgg; cbd = -cgd; cbs = -cgs; } else { if (Vgst < bsim2.pParam.B2vghigh) { Uvert = 1.0 + Vgst * (Ua + Vgst * Ub); Uvert = Math.Max(Uvert, 0.2); Inv_Uvert = 1.0 / Uvert; dUvert_dVg = Ua + 2.0 * Ub * Vgst; dUvert_dVd = -dUvert_dVg * dVth_dVd; dUvert_dVb = -dUvert_dVg * dVth_dVb + Vgst * (bsim2.pParam.B2uaB + Vgst * bsim2.pParam.B2ubB); T8 = U1s * Inv_Aa * Inv_Uvert; Vc = T8 * Vgst; T9 = Vc * Inv_Uvert; dVc_dVg = T8 - T9 * dUvert_dVg; dVc_dVd = -T8 * dVth_dVd - T9 * dUvert_dVd; dVc_dVb = -T8 * dVth_dVb + bsim2.pParam.B2u1B * Vgst * Inv_Aa * Inv_Uvert - Vc * Inv_Aa * dAa_dVb - T9 * dUvert_dVb; tmp2 = Math.Sqrt(1.0 + 2.0 * Vc); Kk = 0.5 * (1.0 + Vc + tmp2); Inv_Kk = 1.0 / Kk; dKk_dVc = 0.5 + 0.5 / tmp2; SqrtKk = Math.Sqrt(Kk); T8 = Inv_Aa / SqrtKk; Vdsat = Vgst * T8; T9 = 0.5 * Vdsat * Inv_Kk * dKk_dVc; dVdsat_dVd = -T8 * dVth_dVd - T9 * dVc_dVd; dVdsat_dVg = T8 - T9 * dVc_dVg; dVdsat_dVb = -T8 * dVth_dVb - T9 * dVc_dVb - Vdsat * Inv_Aa * dAa_dVb; } if (Vds >= Vdsat) { /* saturation region */ cgg = bsim2.pParam.Two_Third_CoxWL; cgd = -cgg * dVth_dVd + dQbulk_dVd; tmp = -cgg * dVth_dVb + dQbulk_dVb; cgs = -(cgg + cgd + tmp); cbg = 0.0; cbd = -dQbulk_dVd; cbs = dQbulk_dVd + dQbulk_dVb; cdg = -0.4 * cgg; tmp = -cdg * dVth_dVb; cdd = -cdg * dVth_dVd; cds = -(cdg + cdd + tmp); qb = -Qbulk; qg = bsim2.pParam.Two_Third_CoxWL * Vgst + Qbulk; qd = cdg * Vgst; } else { /* linear region */ T7 = Vds / Vdsat; T8 = Vgst / Vdsat; T6 = T7 * T8; T9 = 1.0 - T7; Vgdt = Vgst * T9; T0 = Vgst / (Vgst + Vgdt); T1 = Vgdt / (Vgst + Vgdt); T5 = T0 * T1; T2 = 1.0 - T1 + T5; T3 = 1.0 - T0 + T5; dVgdt_dVg = T9 + T6 * dVdsat_dVg; dVgdt_dVd = T6 * dVdsat_dVd - T8 - T9 * dVth_dVd; dVgdt_dVb = T6 * dVdsat_dVb - T9 * dVth_dVb; qg = bsim2.pParam.Two_Third_CoxWL * (Vgst + Vgdt - Vgdt * T0) + Qbulk; qb = -Qbulk; qd = -bsim2.pParam.One_Third_CoxWL * (0.2 * Vgdt + 0.8 * Vgst + Vgdt * T1 + 0.2 * T5 * (Vgdt - Vgst)); cgg = bsim2.pParam.Two_Third_CoxWL * (T2 + T3 * dVgdt_dVg); tmp = dQbulk_dVb + bsim2.pParam.Two_Third_CoxWL * (T3 * dVgdt_dVb - T2 * dVth_dVb); cgd = bsim2.pParam.Two_Third_CoxWL * (T3 * dVgdt_dVd - T2 * dVth_dVd) + dQbulk_dVd; cgs = -(cgg + cgd + tmp); T2 = 0.8 - 0.4 * T1 * (2.0 * T1 + T0 + T0 * (T1 - T0)); T3 = 0.2 + T1 + T0 * (1.0 - 0.4 * T0 * (T1 + 3.0 * T0)); cdg = -bsim2.pParam.One_Third_CoxWL * (T2 + T3 * dVgdt_dVg); tmp = bsim2.pParam.One_Third_CoxWL * (T2 * dVth_dVb - T3 * dVgdt_dVb); cdd = bsim2.pParam.One_Third_CoxWL * (T2 * dVth_dVd - T3 * dVgdt_dVd); cds = -(cdg + tmp + cdd); cbg = 0.0; cbd = -dQbulk_dVd; cbs = dQbulk_dVd + dQbulk_dVb; } } } finished: /* returning Values to Calling Routine */ valuetypeflag = (int)model.B2channelChargePartitionFlag; switch (valuetypeflag) { case 0: Ids = Math.Max(Ids, 1e-50); break; case -1: Ids = Math.Max(Ids, 1e-50); break; case -2: Ids = gm; break; case -3: Ids = gds; break; case -4: Ids = 1.0 / gds; break; case -5: Ids = gmb; break; case -6: Ids = qg / 1.0e-12; break; case -7: Ids = qb / 1.0e-12; break; case -8: Ids = qd / 1.0e-12; break; case -9: Ids = -(qb + qg + qd) / 1.0e-12; break; case -10: Ids = cgg / 1.0e-12; break; case -11: Ids = cgd / 1.0e-12; break; case -12: Ids = cgs / 1.0e-12; break; case -13: Ids = -(cgg + cgd + cgs) / 1.0e-12; break; case -14: Ids = cbg / 1.0e-12; break; case -15: Ids = cbd / 1.0e-12; break; case -16: Ids = cbs / 1.0e-12; break; case -17: Ids = -(cbg + cbd + cbs) / 1.0e-12; break; case -18: Ids = cdg / 1.0e-12; break; case -19: Ids = cdd / 1.0e-12; break; case -20: Ids = cds / 1.0e-12; break; case -21: Ids = -(cdg + cdd + cds) / 1.0e-12; break; case -22: Ids = -(cgg + cdg + cbg) / 1.0e-12; break; case -23: Ids = -(cgd + cdd + cbd) / 1.0e-12; break; case -24: Ids = -(cgs + cds + cbs) / 1.0e-12; break; default: Ids = Math.Max(Ids, 1.0e-50); break; } von = Vth; vdsat = Vdsat; }