/// <summary> /// Generate a BSIM3 model /// </summary> /// <param name="name">Name of the parameter</param> /// <param name="type">Type of the parameter</param> /// <param name="version">Version of the parameter</param> /// <returns></returns> public static ICircuitObject GenerateBSIM3Model(CircuitIdentifier name, string type, string version) { double v = 3.3; switch (version) { case null: case "3.3.0": v = 3.3; break; case "3.2.4": v = 3.24; break; default: if (!double.TryParse(version, System.Globalization.NumberStyles.Float, System.Globalization.CultureInfo.InvariantCulture, out v)) { throw new Exception("Unsupported version \"" + version + "\""); } break; } if (Math.Abs(v - 3.3) < 1e-12) { var b3v30 = new BSIM3v30Model(name); switch (type) { case "nmos": b3v30.SetNMOS(true); break; case "pmos": b3v30.SetPMOS(true); break; default: throw new Exception("Invalid type \"" + type + "\""); } return(b3v30); } else if (Math.Abs(v - 3.24) < 1e-12) { var b3v24 = new BSIM3v24Model(name); switch (type) { case "nmos": b3v24.SetNMOS(true); break; case "pmos": b3v24.SetPMOS(true); break; default: throw new Exception("Invalid type \"" + type + "\""); } return(b3v24); } else { throw new Exception("Unrecognized version \"" + v.ToString() + "\""); } }
/// <summary> /// Calculate noise in strong inversion /// </summary> /// <param name="Vds"></param> /// <param name="model"></param> /// <param name="here"></param> /// <param name="freq"></param> /// <param name="temp"></param> /// <returns></returns> private double StrongInversionNoiseEval(double Vds, BSIM3v30Model model, BSIM3v30 here, double freq, double temp) { double cd, esat, DelClm, EffFreq, N0, Nl, Leff, Leffsq; double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ssi; cd = Math.Abs(here.BSIM3cd); Leff = here.pParam.BSIM3leff - 2.0 * model.BSIM3lintnoi; Leffsq = Leff * Leff; esat = 2.0 * here.pParam.BSIM3vsattemp / here.BSIM3ueff; if (model.BSIM3em <= 0.0) { DelClm = 0.0; } else { T0 = ((((Vds - here.BSIM3Vdseff) / here.pParam.BSIM3litl) + model.BSIM3em) / esat); DelClm = here.pParam.BSIM3litl * Math.Log(Math.Max(T0, 1e-38)); } EffFreq = Math.Pow(freq, model.BSIM3ef); T1 = Circuit.CHARGE * Circuit.CHARGE * 8.62e-5 * cd * temp * here.BSIM3ueff; T2 = 1.0e8 * EffFreq * here.BSIM3Abulk * model.BSIM3cox * Leffsq; N0 = model.BSIM3cox * here.BSIM3Vgsteff / Circuit.CHARGE; Nl = model.BSIM3cox * here.BSIM3Vgsteff * (1.0 - here.BSIM3AbovVgst2Vtm * here.BSIM3Vdseff) / Circuit.CHARGE; T3 = model.BSIM3oxideTrapDensityA * Math.Log(Math.Max(((N0 + 2.0e14) / (Nl + 2.0e14)), 1e-38)); T4 = model.BSIM3oxideTrapDensityB * (N0 - Nl); T5 = model.BSIM3oxideTrapDensityC * 0.5 * (N0 * N0 - Nl * Nl); T6 = 8.62e-5 * temp * cd * cd; T7 = 1.0e8 * EffFreq * Leffsq * here.pParam.BSIM3weff; T8 = model.BSIM3oxideTrapDensityA + model.BSIM3oxideTrapDensityB * Nl + model.BSIM3oxideTrapDensityC * Nl * Nl; T9 = (Nl + 2.0e14) * (Nl + 2.0e14); Ssi = T1 / T2 * (T3 + T4 + T5) + T6 / T7 * DelClm * T8 / T9; return(Ssi); }
/// <summary> /// Gets or sets the device model /// </summary> public void SetModel(BSIM3v30Model model) => Model = model;