From 2a2497ec6286a6ec4f0ed513476374b59ff8435d Mon Sep 17 00:00:00 2001 From: dwarning Date: Sat, 30 Jul 2011 15:58:11 +0000 Subject: [PATCH] update va code from version 504.7 to 504.9.1 --- ChangeLog | 4 + .../devices/adms/mextram/admsva/evaluate.inc | 86 +++++++++--- .../devices/adms/mextram/admsva/frontdef.inc | 5 +- .../adms/mextram/admsva/initialize.inc | 43 +++++- .../devices/adms/mextram/admsva/mextram.va | 9 -- .../devices/adms/mextram/admsva/opinfo.inc | 25 +++- .../devices/adms/mextram/admsva/opvars.inc | 33 ++++- .../adms/mextram/admsva/parameters.inc | 31 +++-- .../devices/adms/mextram/admsva/tscaling.inc | 124 +++++++++++++----- .../devices/adms/mextram/admsva/variables.inc | 46 +++++-- 10 files changed, 320 insertions(+), 86 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6b9b0a992..f54fdb2d0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2011-07-30 Dietmar Warning + * adms/ekv/admsva/ekv.va: semicolon after macro expl was wrong + * adms/mextram/admsva: update va code from version 504.7 to 504.9.1 + 2011-07-27 Holger Vogt * inpcom.c: nested parens, line 2963 ff * cmutil.c: inlude ngspice.h for NaN diff --git a/src/spicelib/devices/adms/mextram/admsva/evaluate.inc b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc index 121a8e300..76b9184af 100644 --- a/src/spicelib/devices/adms/mextram/admsva/evaluate.inc +++ b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc @@ -152,8 +152,11 @@ Vsc3 = Vsc4 - Vc3c4 ; Vfe = VDE_T * (1.0 - pow(`AJE , -1.0 / PE)); a_VDE = 0.1 * VDE_T; - `min_logexp(Vje, Vb2e1, Vfe, a_VDE); - Vte = VDE_T / (1.0 - PE) * (1.0 - pow(1.0 - Vje / VDE_T, 1.0 - PE)) + + `min_logexp(Vje, Vb2e1, Vfe, a_VDE); + +// RvdT, November 2008, E0BE to be re-used in EB- Zener tunnel model: + E0BE = pow(1.0 - Vje * inv_VDE_T, 1.0 - PE) ; + Vte = VDE_T / (1.0 - PE) * (1.0 - E0BE) + `AJE * (Vb2e1 - Vje); // Effective collector junction capacitance bias @@ -208,7 +211,32 @@ Vsc3 = Vsc4 - Vc3c4 ; Ib3 = IBR_TM * (eVb1c4 - 1.0) / (tmpExp + exp(0.5 * VLR * VtINV)) + _circuit_gmin * Vb1c4; - + +// begin RvdT, November 2008, MXT504.8_alpha + +// Base-emitter tunneling current +// max E-field E0BE calculated in BE depletion charge model: + + if (IZEB > 0.0 && NZEB > 0.0 && Vb2e1 < 0) + begin + + `expLin(eZEB, nZEB_T * (1 - (pow2_2mPE/(2.0*E0BE)))) +// Force all derivatives at Vb2e1=0 to zero by using in DZEB a +// modified dE0BE expression for E0BE: + x = Vb2e1 * inv_VDE_T ; + dE0BE = pow(- x, -2.0-PE)*(PE*(1-PE*PE-3*x*(PE-1))-6*x*x*(PE-1+x)) * `one_sixth ; + `expLin(edZEB, Vb2e1 * pow2_2mPE * nZEB_T / (VGZEB_T * dE0BE )) + DZEB = - Vb2e1 - VGZEB_T * dE0BE * (1 - edZEB) / (pow2_2mPE * nZEB_T) ; + Izteb = 2.0 * IZEB_TM * DZEB * E0BE * eZEB * inv_VDE_T * pow2_PEm2 ; + end + else + begin + DZEB = 0 ; + Izteb = 0 ; + end + +// end RvdT, November 2008, MXT504.8_alpha + // Iex, Isub (XIex, XIsub) g1 = If0 * eVb1c4; @@ -220,7 +248,21 @@ Vsc3 = Vsc4 - Vc3c4 ; `ifdef SUBSTRATE Isub = 2.0 * ISS_TM * (eVb1c4 - 1.0) / (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); - Isf = ISS_TM * (eVsc1 - 1.0); +// until504.8: Isf = ISS_TM * (eVsc1 - 1.0); +// New 504.9: + +if (ICSS < 0.0) +// this clause is to implement backwards compatibility + begin + Isf = ISS_TM * (eVsc1 - 1.0); + end + else + begin + Isf = ICSS_TM * (eVsc1 - 1.0); + end + +// End: New 504.9. + `endif XIex =0.0; @@ -341,8 +383,10 @@ Vsc3 = Vsc4 - Vc3c4 ; Vc3c4 * Vc3c4 * GCCex_TM + Vc4c1 * Vc4c1 * GCCin_TM + Vbb1 * Vbb1 / RBC_TM + - Ib1b2 * Vb1b2 + - (Ib1 + Ib2) * Vb2e1 + + Ib1b2 * Vb1b2 + +// 504.8: Nov. 2008, RvdT, TU_Delft: Zener current contribution added: +// Izteb > 0 for Vb2e1 < 0, hence the minus sign: + (Ib1 + Ib2 - Izteb) * Vb2e1 + Ib1_s * Vb1e1 + `ifdef SUBSTRATE (Iex + Ib3) * Vb1c4 + XIex * Vbc3 + @@ -361,7 +405,7 @@ Vsc3 = Vsc4 - Vc3c4 ; Qte = (1.0 - XCJE) * CJE_TM * Vte; `min_logexp(Vje_s, Vb1e1, Vfe, a_VDE); Qte_s = XCJE * CJE_TM * (VDE_T / (1.0 - PE) * - (1.0 - pow(1.0 - Vje_s / VDE_T, 1.0 - PE)) + + (1.0 - pow(1.0 - Vje_s * inv_VDE_T, 1.0 - PE)) + `AJE * (Vb1e1 - Vje_s)); Qtc = XCJC * CJC_TM * Vtc; @@ -413,7 +457,7 @@ Vsc3 = Vsc4 - Vc3c4 ; Qb1b2 = 0.0; if (EXPHI == 1) begin - dVteVje = pow(1.0 - Vje / VDE_T, -PE) - `AJE; + dVteVje = pow(1.0 - Vje * inv_VDE_T, -PE) - `AJE; Vb2e1Vfe = (Vb2e1 - Vfe) / a_VDE; if (Vb2e1Vfe < 0.0) dVjeVb2e1 = 1.0 / (1.0 + exp(Vb2e1Vfe)); @@ -430,8 +474,8 @@ Vsc3 = Vsc4 - Vc3c4 ; Qb1b2 = 0.2 * Vb1b2 * (dQteVb2e1 + dQbeVb2e1 + dQeVb2e1); - Qbc = Qbe_qs / 3.0 + Qbc_qs; - Qbe = 2.0 * Qbe_qs / 3.0; + Qbc = Qbe_qs * `one_third + Qbc_qs; + Qbe = 2.0 * Qbe_qs * `one_third ; end else begin @@ -446,7 +490,10 @@ Vsc3 = Vsc4 - Vc3c4 ; I(c1, c2) <+ TYPE * Ic1c2; I(c2, e1) <+ TYPE * In; I(b1, e1) <+ TYPE * Ib1_s; - I(b2, e1) <+ TYPE * (Ib1 + Ib2); +// begin RvdT, 28-10-2008, MXT504.8_alpha +// contribution tunnel current added + I(b2, e1) <+ TYPE * (Ib1 + Ib2 - Izteb); + `ifdef SUBSTRATE I(b1, s) <+ TYPE * Isub; I(b, s) <+ TYPE * XIsub; @@ -547,13 +594,14 @@ else powerRCCxx = common * GCCxx_TM; // Collector resistance powerRCCex = common * GCCex_TM; // Collector resistance powerRCCin = common * GCCin_TM; // Collector resistance - powerRBV = common / Rb2 * (4.0 * eVb1b2 + 5.0) / 3.0; // Variable base resistance + powerRBV = common / Rb2 * (4.0 * eVb1b2 + 5.0) * `one_third ; // Variable base resistance // Collector current shot noise powerCCS = 2.0 * `QQ * (If + Ir) / qBI; // Forward base current shot noise and 1/f noise - powerFBCS = 2.0 * `QQ * (abs(Ib1) + abs(Ib2)); +// 504.8, Nov. 2008, RvdT, TU-Delft: added Zener current to shot noise + powerFBCS = 2.0 * `QQ * (abs(Ib1) + abs(Ib2) + abs(Izteb)); powerFBC1fB1 = (1.0 - XIBI) * pow((abs(Ib1) / (1 - XIBI)), AF) * KF_M; exponentFBC1fB2 = (2.0 * (MLF - 1.0)) + (AF * (2.0 - MLF)); powerFBC1fB2 = KFN_M * pow(abs(Ib2), exponentFBC1fB2); @@ -606,12 +654,12 @@ else I(b2, e1) <+ flicker_noise(powerFBC1fB2, 1); // "bas_emi_forw" I(e1, b1) <+ white_noise(powerEBSCS); // "emi_bas_side" I(e1, b1) <+ flicker_noise(powerEBSC1f, 1); // "emi_bas_side" - I(b1, c1) <+ white_noise(powerRBCS); // "bas_col_reve" - I(b1, c1) <+ flicker_noise(powerRBC1f, 1); // "bas_col_reve" - I(b1, c1) <+ white_noise(powerExCS); // "Ext_bas_col" - I(b1, c1) <+ flicker_noise(powerExC1f, 1); // "Ext_bas_col" - I(b, c1) <+ white_noise(powerExCSMOD); // "Ext_bas_col" - I(b, c1) <+ flicker_noise(powerExC1fMOD, 1); // "Ext_bas_col" + I(b1, c4) <+ white_noise(powerRBCS); // "bas_col_reve" + I(b1, c4) <+ flicker_noise(powerRBC1f, 1); // "bas_col_reve" + I(b1, c4) <+ white_noise(powerExCS); // "Ext_bas_col" + I(b1, c4) <+ flicker_noise(powerExC1f, 1); // "Ext_bas_col" + I(b, c3) <+ white_noise(powerExCSMOD); // "Ext_bas_col" + I(b, c3) <+ flicker_noise(powerExC1fMOD, 1); // "Ext_bas_col" `ifdef SUBSTRATE I(b1, s) <+ white_noise(powerSubsCS_B1S); // "bas_sub_current" I(b, s) <+ white_noise(powerSubsCS_BS); // "bas_sub_current" diff --git a/src/spicelib/devices/adms/mextram/admsva/frontdef.inc b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc index e6ec301db..23e418c11 100644 --- a/src/spicelib/devices/adms/mextram/admsva/frontdef.inc +++ b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc @@ -8,7 +8,9 @@ `define C2K 273.15 `define KB 1.3806226e-23 `define QQ 1.6021918e-19 -`define KBdivQQ 8.61708691805812512584e-5 +`define KBdivQQ 8.61708691805812512584e-5 +`define one_third 0.33333333333333333333 +`define one_sixth 0.16666666666666666667 `define VDLOW 0.05 `define AJE 3.0 `define AJC 2.0 @@ -80,4 +82,3 @@ else\ result = vlim + ln(1.0 + (x - vlim));\ result=result - diff --git a/src/spicelib/devices/adms/mextram/admsva/initialize.inc b/src/spicelib/devices/adms/mextram/admsva/initialize.inc index 4f4e03bfc..1b80c2949 100644 --- a/src/spicelib/devices/adms/mextram/admsva/initialize.inc +++ b/src/spicelib/devices/adms/mextram/admsva/initialize.inc @@ -1,6 +1,6 @@ // Initialze model constants - // Impact ionization constants (NPN - PNP) + // Impact ionization constants (NPN - PNP) if (TYPE == 1) begin @@ -31,3 +31,44 @@ Xext1 = 1.0 - XEXT; KF_M = KF * pow(MULT, 1.0 - AF); KFN_M = KFN * pow(MULT, 1.0 - (2.0 * (MLF - 1.0) + AF * (2.0 - MLF))); +// begin: RvdT, November 2008 ; Zener tunneling current model + + pow2_2mPE = pow(2.0, 2.0 - PE); + pow2_PEm2 = 1.0 / pow2_2mPE; + +// Reference Temperature expressed in Kelvin: + Trk = TREF + `C2K; + +// begin: RvdT, November 2008 ; Zener tunneling current model +// +// Comment added March 2009: this assumes VGZEBOK as a model parameter. +// +// Bandgap for Zener tunnel current model at reference temperature in eV: +// VGZEB_Tr = VGZEBOK - AVGEB*Trk*Trk / (Trk + TVGEB) ; +// `max_logexp(VGZEB_Tr, VGZEBOK - AVGEB*Trk*Trk / (Trk + TVGEB), 0.05, 0.1) ; +// end: RvdT, November 2008 + +// begin: RvdT March 2009: +// to decrease parameter interdependency, +// use VGZEB as a parameter, instead of VGZEBOK: +// VGZEB : bandgap for Zener tunneling at T = Tref, +// VGZEBOK : bandgap for Zener tunneling at T = 0 K. +// `max_logexp(VGZEBOK, VGZEB + AVGEB*Trk*Trk / (Trk + TVGEB), 0.05, 0.1); +//dw can't expand the macro `max_logexp here - using the code + _x = VGZEB + AVGEB*Trk*Trk / (Trk + TVGEB); + _x0 = 0.05; + _a = 0.1; + _dxa = (_x - _x0) / (_a); + if (_x < _x0) + VGZEBOK = _x0 + _a * ln(1.0 + exp(_dxa)); + else + VGZEBOK = _x + _a * ln(1.0 + exp(-_dxa)); + + VGZEB_Tr = VGZEB; +// end: RvdT March 2009: use VGZEB as a parameter, instead of VGZEBOK: + + inv_VGZEB_Tr = 1.0 / VGZEB_Tr; + + inv_VDE = 1.0 / VDE; + +// end: RvdT, November 2008 ; Zener tunneling current model diff --git a/src/spicelib/devices/adms/mextram/admsva/mextram.va b/src/spicelib/devices/adms/mextram/admsva/mextram.va index 2421525aa..cb16e76aa 100644 --- a/src/spicelib/devices/adms/mextram/admsva/mextram.va +++ b/src/spicelib/devices/adms/mextram/admsva/mextram.va @@ -36,17 +36,8 @@ module bjt504_va (c, b, e, s, dt); analog begin -//`ifdef insideADMS -// @(initial_model) begin -//`else -// @(initial_step or initial_step("static")) begin -//`endif - `include "initialize.inc" `include "tscaling.inc" - -// end // initial_step - `include "evaluate.inc" `include "opinfo.inc" diff --git a/src/spicelib/devices/adms/mextram/admsva/opinfo.inc b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc index 7554c61ad..6b93b6b0a 100644 --- a/src/spicelib/devices/adms/mextram/admsva/opinfo.inc +++ b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc @@ -6,8 +6,22 @@ begin // The external currents and the current gain OP_ic = I(); // External DC collector current OP_ib = I(); // External DC base Current +OP_betadc = OP_ic / OP_ib; // External DC Current gain -OP_betadc = OP_ic / OP_ib; // External DC Current gain +// begin added in MXT 504.9: +OP_ie = I(); // External DC emitter current +OP_vbe = V(b, e); // External base-emitter bias +OP_vce = V(c, e); // External collector-emitter bias +OP_vbc = V(b, c); // External base-collector bias + +`ifdef SUBSTRATE +OP_is = I(); // External DC emitter current +OP_vse = V(s, e); // External substrate-emitter bias +OP_vbs = V(b, s); // External base-substrate bias +OP_vsc = V(s, c); // External substrate-collector bias +`endif + +// end added in MXT 504.9: // The internal voltage differences OP_vb2e1 = Vb2e1; // Internal base-emiter bias @@ -27,6 +41,11 @@ OP_ic1c2 = Ic1c2; // Epilayer current OP_ib1b2 = Ib1b2; // Pinched-base current OP_ib1 = Ib1; // Ideal forward base current OP_sib1 = Ib1_s; // Ideal side-wall base current +// +// 504.8, RvdT, TU-Delft April. 2009: +// +OP_izteb = Izteb ; // Zener tunneling current +// OP_ib2 = Ib2; // Non-ideal forward base current OP_ib3 = Ib3; // Non-ideal reverse base current OP_iavl = Iavl; // Avalanche current @@ -35,7 +54,7 @@ OP_xiex = XIex; // Extrinsic reverse base current `ifdef SUBSTRATE OP_isub = Isub; // Substrate current OP_xisub = XIsub; // Substrate current -OP_isf = Isf; // Substrate failure current +OP_isf = Isf; // Substrate-collector current `endif OP_ire = - Vee1 / RE_TM; // Current through emiter resistance OP_irbc = Vbb1 / RBC_TM; // Current through constant base resistance @@ -108,7 +127,7 @@ OP_rcbli = RCCin_TM; // Extrinsic buried layer resistance `ifdef SUBSTRATE OP_gs = ddx(Isub, V(b)) + ddx(Isub, V(b1)); // Conductance parasitic PNP transitor OP_xgs = ddx(XIsub, V(b)) ; // Conductance parasitic PNP transistor -OP_gsf = ddx(Isf, V(s)) ; // Conductance substrate failure current +OP_gsf = ddx(Isf, V(s)) ; // Conductance substrate-collector current `endif diff --git a/src/spicelib/devices/adms/mextram/admsva/opvars.inc b/src/spicelib/devices/adms/mextram/admsva/opvars.inc index e6a68b09e..f2f927a36 100644 --- a/src/spicelib/devices/adms/mextram/admsva/opvars.inc +++ b/src/spicelib/devices/adms/mextram/admsva/opvars.inc @@ -7,6 +7,22 @@ `OPP(OP_ib, A, External DC base current) `OPP(OP_betadc, , External DC current gain Ic/Ib) +// begin added in MXT 504.9: +`OPP(OP_ie, A, External DC emitter current) + +// The external biases +`OPP(OP_vbe, V, External base-emitter bias) +`OPP(OP_vce, V, External collector-emitter bias) +`OPP(OP_vbc, V, External base-collector bias) + +`ifdef SUBSTRATE +`OPP(OP_is, A, External DC substrate current) +`OPP(OP_vse, V, External substrate-emitter bias) +`OPP(OP_vbs, V, External base-substrate bias) +`OPP(OP_vsc, V, External substrate-collector bias) +`endif + +// end added in MXT 504.9 // The internal biases `OPP(OP_vb2e1, V, Internal base-emitter bias) `OPP(OP_vb2c2, V, Internal base-collector bias) @@ -22,15 +38,22 @@ `OPP(OP_ib1b2, A, Pinched-base current) `OPP(OP_ib1, A, Ideal forward base current) `OPP(OP_sib1, A, Ideal side-wall base current) +// +// 504.8, RvdT, TU-Delft April. 2009, Zener tunneling current: +// +`OPP(OP_izteb, A, Zener tunneling current in the emitter base junction) +// `OPP(OP_ib2, A, Non-ideal forward base current) `OPP(OP_ib3, A, Non-ideal reverse base current) `OPP(OP_iavl, A, Avalanche current) `OPP(OP_iex, A, Extrinsic reverse base current) `OPP(OP_xiex, A, Extrinsic reverse base current) +`ifdef SUBSTRATE `OPP(OP_isub, A, Substrate current) `OPP(OP_xisub, A, Substrate current) `OPP(OP_isf, A, Substrate failure current) +`endif `OPP(OP_ire, A, Current through emitter resistance) `OPP(OP_irbc, A, Current through constant base resistance) `OPP(OP_ircblx, A, Current through extrinsic buried layer resistance) @@ -50,7 +73,9 @@ `OPP(OP_xqtex, C, Extrinsic base-collector depletion charge) `OPP(OP_qex, C, Extrinsic base-collector diffusion charge) `OPP(OP_xqex, C, Extrinsic base-collector diffusion charge) +`ifdef SUBSTRATE `OPP(OP_qts, C, Collector-substrate depletion charge) +`endif //Small signal equivalent circuit conductances and resistances `OPP(OP_gx, S, Forward transconductance) @@ -76,10 +101,11 @@ `OPP(OP_rcc, Ohm, Collector contact resistance) `OPP(OP_rcblx, Ohm, Extrinsic buried layer resistance) `OPP(OP_rcbli, Ohm, Intrinsic buried layer resistance) +`ifdef SUBSTRATE `OPP(OP_gs, S, Conductance parasistic PNP transistor) `OPP(OP_xgs, S, Conductance parasistic PNP transistor) `OPP(OP_gsf, S, Conductance substrate failure current) - +`endif //Small signal equivalent circuit capacitances `OPP(OP_scbe, F, Capacitance sidewall b-e junction) `OPP(OP_cbex, F, Capacitance floor b-e junction) @@ -94,8 +120,9 @@ `OPP(OP_cb1b2x, F, Cross-capacitance AC current crowding) `OPP(OP_cb1b2y, F, Cross-capacitance AC current crowding) `OPP(OP_cb1b2z, F, Cross-capacitance AC current crowding) +`ifdef SUBSTRATE `OPP(OP_cts, F, Capacitance s-c junction) - +`endif //Approximate small signal equivalent circuit `OPP(OP_gm, S,transconductance) `OPP(OP_beta, , Current amplification) @@ -113,7 +140,9 @@ `OPP(OP_vb2c2star, V, Physical value of internal base-collector bias) //self-heating +`ifdef SELFHEATING `OPP(OP_pdiss, W, Dissipation) +`endif `OPP(OP_tk, K, Actual temperature) //help variables diff --git a/src/spicelib/devices/adms/mextram/admsva/parameters.inc b/src/spicelib/devices/adms/mextram/admsva/parameters.inc index 8ec3c9210..2d83a9029 100644 --- a/src/spicelib/devices/adms/mextram/admsva/parameters.inc +++ b/src/spicelib/devices/adms/mextram/admsva/parameters.inc @@ -29,6 +29,12 @@ parameter real MLF = 2.0 from [0.1:inf) `ATTR(info="Non-ideality factor of the non-ideal forward base current"); parameter real XIBI = 0.0 from [0.0:1.0] `ATTR(info="Part of ideal base current that belongs to the sidewall"); +// begin: RvdT, November 2008, BE tunneling current parameters: +parameter real IZEB = 0.0 from [0.0:inf) + `ATTR(info="Pre-factor of emitter-base Zener tunneling current"); +parameter real NZEB = 22.0 from [0.0:inf) + `ATTR(info="Coefficient of emitter-base Zener tunneling current"); +// end: RvdT, November 2008, EB tunneling current parameters: parameter real BRI = 7.0 from [1.0e-4:inf) `ATTR(info="Ideal reverse current gain"); parameter real IBR = 1.0f from [0.0:inf) @@ -88,10 +94,9 @@ parameter real MC = 0.5 from [0.0:1.0) parameter real XCJC = 32.0m from [0.0:1.0] `ATTR(info="Fraction of CB depletion capacitance under the emitter"); // RvdT, 30-11-2007: introduced RCBLX and RCBLI: -//dw clipped to 1m and default to 1 Ohm as long adms-ngspice has no working node-collapsing -parameter real RCBLX = 1.0 from [1.0m:inf) +parameter real RCBLX = 0.0 from [0.0:inf) `ATTR(info="Resistance Collector Buried Layer eXtrinsic"); -parameter real RCBLI = 1.0 from [1.0m:inf) +parameter real RCBLI = 0.0 from [0.0:inf) `ATTR(info="Resistance Collector Buried Layer Intrinsic"); parameter real CBCO = 0.0 from [0.0:inf) `ATTR(info="Collector-base overlap capacitance"); @@ -137,6 +142,12 @@ parameter real VGC = 1.18 from [0.1:inf) `ATTR(info="Band-gap voltage of the collector"); parameter real VGJ = 1.15 from [0.1:inf) `ATTR(info="Band-gap voltage recombination emitter-base junction"); +parameter real VGZEB = 1.15 from [0.1:inf) + `ATTR(info="Band-gap voltage at Tref of Zener effect emitter-base junction"); +parameter real AVGEB = 4.73e-4 from (-inf:inf) + `ATTR(info="Temperature coefficient band-gap voltage for Zener effect emitter-base junction"); +parameter real TVGEB = 636.0 from [0.0:inf) + `ATTR(info="Temperature coefficient band-gap voltage for Zener effect emitter-base junction"); parameter real DVGTE = 0.05 `ATTR(info="Band-gap voltage difference of emitter stored charge"); parameter real DAIS = 0.0 @@ -153,7 +164,9 @@ parameter integer KAVL = 0 from [0:1] `ifdef SUBSTRATE parameter real ISS = 48.0a from [0.0:inf) - `ATTR(info="Base-substrate saturation current"); + `ATTR(info="Base-substrate saturation current"); +parameter real ICSS = -1.0 from (-inf:inf) + `ATTR(info="Collector-substrate ideal saturation current"); parameter real IKS = 250.0u from [1.0p:inf) `ATTR(info="Base-substrate high injection knee current"); parameter real CJS = 315.0f from [0:inf) @@ -165,7 +178,9 @@ parameter real PS = 0.34 from (0.01:0.99) parameter real VGS = 1.20 from [0.1:inf) `ATTR(info="band-gap voltage of the substrate"); parameter real AS = 1.58 - `ATTR(info="Substrate temperature coefficient"); + `ATTR(info="Substrate temperature coefficient"); +parameter real ASUB = 2.0 + `ATTR(info="Temperature coefficient for mobility of minorities in the substrate"); `endif `ifdef SELFHEATING @@ -189,6 +204,6 @@ parameter integer TYPE = 1 from [-1:1] `else parameter integer TYPE = 1 from [-1:1] exclude 0; `endif -//parameter real GMIN = 1.0e-12 from (0:1e-10] -// `ATTR(info="Minimum conductance"); -// +parameter real GMIN = 1.0e-13 from (0:1e-10] + `ATTR(info="Minimum conductance"); + diff --git a/src/spicelib/devices/adms/mextram/admsva/tscaling.inc b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc index 3112f7455..345cfc32a 100644 --- a/src/spicelib/devices/adms/mextram/admsva/tscaling.inc +++ b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc @@ -14,7 +14,7 @@ `endif // Temperature variables - Trk = TREF + `C2K; + `ifdef insideADMS Tk = Trk + DTA + Vdt; @@ -29,9 +29,17 @@ Vtr = `KBdivQQ * Trk; VtINV = 1.0 / Vt; VtrINV = 1.0 / Vtr; - VdtINV = VtINV - VtrINV; - - // Depletion capacitances + VdtINV = VtINV - VtrINV; + + lntN = ln(tN) ; + + // begin: RvdT, November 2008, "Zener tunneling model" +// VGZEB_T = VGZEBOK - AVGEB*Tk*Tk / (Tk + TVGEB) ; + `max_logexp(VGZEB_T, VGZEBOK - AVGEB*Tk*Tk / (Tk + TVGEB), 0.05, 0.1) ; + + // end: RvdT, November 2008, "Zener tunneling model" + + // Depletion capacitances UdeT = -3.0 * Vt * ln(tN) + VDE * tN + (1.0 - tN) * VGB; `max_logexp(VDE_T, `VDLOW, UdeT, Vt); @@ -43,8 +51,9 @@ UdsT = -3.0 * Vt * ln(tN) + VDS * tN + (1.0 - tN) * VGS; `max_logexp(VDS_T, `VDLOW, UdsT, Vt); `endif - - CJE_T = CJE * pow(VDE / VDE_T, PE); + inv_VDE_T = 1.0 / VDE_T ; + CJE_T_div_CJE = pow(VDE * inv_VDE_T, PE); + CJE_T = CJE * CJE_T_div_CJE ; `ifdef SUBSTRATE CJS_T = CJS * pow(VDS / VDS_T, PS); @@ -57,45 +66,80 @@ XP_T = XP * CJCscaleINV; // Resistances - - RE_T = RE * pow(tN, AE); - RBV_T = RBV * pow(tN, AB - AQBO); - RBC_T = RBC * pow(tN, AEX); + +// RvdT, November 2008: +// Instead of the following definition +// RE_T = RE * pow(tN, AE); +// we use, here, and in all following powers of tN, +// the following computationally cheaper implementation: + RE_T = RE * exp(lntN * AE); +// This is based on the observation that exp() is faster than pow(). +// Acknowledgement due to Geoffrey Coram. + + RBV_T = RBV * exp(lntN * (AB - AQBO)); + RBC_T = RBC * exp(lntN * AEX); // RvdT, 30-11-2007: new collector resistances RCCxx_T, RCCex_T, RCCin_T - RCCxx_T = RCC * pow(tN, AC); - RCCex_T = RCBLX * pow(tN, ACBL); - RCCin_T = RCBLI * pow(tN, ACBL); + RCCxx_T = RCC * exp(lntN * AC); + RCCex_T = RCBLX * exp(lntN * ACBL); + RCCin_T = RCBLI * exp(lntN * ACBL); - RCV_T = RCV * pow(tN, AEPI); + RCV_T = RCV * exp(lntN * AEPI); // Current gains - BF_T = BF * pow(tN, AE - AB - AQBO) * exp(-DVGBF * VdtINV); + BF_T = BF * exp(lntN * (AE - AB - AQBO)) * exp(-DVGBF * VdtINV); BRI_T = BRI * exp(-DVGBR * VdtINV); // Currents and voltages - IS_T = IS * pow(tN, 4.0 - AB - AQBO + DAIS) * exp(-VGB * VdtINV); - IK_T = IK * pow(tN, 1.0 - AB); - IBF_T = IBF * pow(tN, 6.0 - 2.0 * MLF) * exp(-VGJ * VdtINV / MLF); + IS_T = IS * exp(lntN * (4.0 - AB - AQBO + DAIS)) * exp(-VGB * VdtINV); + IK_T = IK * exp(lntN * (1.0 - AB)); + IBF_T = IBF * exp(lntN * (6.0 - 2.0 * MLF)) * exp(-VGJ * VdtINV / MLF); IBR_T = IBR * tN * tN * exp(-VGC * VdtINV / 2.0); - VEF_T = VEF * pow(tN, AQBO) * CJCscaleINV; - VER_T = VER * pow(tN, AQBO) * pow(VDE / VDE_T, -PE); + +// begin RvdT, November 2008, MXT504.8_alpha +// T-scaling BE tunneling: +// + x = pow(VGZEB_T * inv_VGZEB_Tr, -0.5) ; +// y = pow(VDE_T * inv_VDE, PE) ; +// more efficient, because we need both y and 1.0 / y: + y = 1.0 / CJE_T_div_CJE ; +// definition: +// nZEB_T = NZEB* pow(VGZEB_T/VGZEB_Tr, 1.5) * pow(VDE_T / VDE, PE-1) ; +// more efficient implementation: +// nZEB_T = NZEB* VGZEB_T * VGZEB_T * x * y * VDE /(VDE_T*VGZEB_Tr*VGZEB_Tr) ; + nZEB_T = NZEB* VGZEB_T * VGZEB_T * x * y * VDE * inv_VDE_T*inv_VGZEB_Tr*inv_VGZEB_Tr ; + +// definition: +// IZEB_T = IZEB* pow(VGZEB_T/VGZEB_Tr, -0.5) * pow(VDE_T / VDE, 2-PE) * exp(NZEB-nZEB_T); +// more efficient implementation: + IZEB_T = IZEB* x * VDE_T * VDE_T * inv_VDE * inv_VDE * CJE_T_div_CJE * exp(NZEB-nZEB_T) ; +// +// end RvdT, November 2008, MXT504.8_alpha + + x = exp(lntN * AQBO) ; + VEF_T = VEF * x * CJCscaleINV; +// VER_T = VER * x * pow(VDE / VDE_T, -PE); + VER_T = VER * x * y; `ifdef SUBSTRATE - ISS_T = ISS * pow(tN, 4.0 - AS) * exp(-VGS * VdtINV); + ISS_T = ISS * exp(lntN * (4.0 - AS)) * exp(-VGS * VdtINV); +// New 504.9: + ICSS_T = ICSS * exp(lntN * (3.5 - 0.5 * ASUB)) * exp(-VGS * VdtINV); +// End New 504.9. + if ((ISS_T > 0.0)) - IKS_T = IKS * pow(tN, 1.0 - AS) * (IS_T / IS) * (ISS / ISS_T); + IKS_T = IKS * exp(lntN * (1.0 - AS)) * (IS_T / IS) * (ISS / ISS_T); else - IKS_T = IKS * pow(tN, 1.0 - AS); + IKS_T = IKS * exp(lntN * (1.0 - AS)); `endif // Transit times - TAUE_T = TAUE * pow(tN, AB - 2.0) * exp(-DVGTE * VdtINV); - TAUB_T = TAUB * pow(tN, AQBO + AB - 1.0); - TEPI_T = TEPI * pow(tN, AEPI - 1.0); + TAUE_T = TAUE * exp(lntN * (AB - 2.0)) * exp(-DVGTE * VdtINV); + TAUB_T = TAUB * exp(lntN * (AQBO + AB - 1.0)); + TEPI_T = TEPI * exp(lntN * (AEPI - 1.0)); TAUR_T = TAUR * (TAUB_T + TEPI_T) / (TAUB + TEPI); // Avalanche constant @@ -113,7 +157,7 @@ // Heterojunction features - DEG_T = DEG * pow(tN, AQBO); + DEG_T = DEG * exp(lntN * AQBO); `ifdef SELFHEATING // Tempearature scaling of the thermal resistance @@ -127,13 +171,29 @@ IK_TM = IK_T * MULT; IBF_TM = IBF_T * MULT; IBR_TM = IBR_T * MULT; - IHC_M = IHC * MULT; +// RvdT: November 2008, Zener tunneling parameters + IZEB_TM = IZEB_T * MULT ; + +// end Zener tunneling parameters + + + + + IHC_M = IHC * MULT; `ifdef SUBSTRATE - ISS_TM = ISS_T * MULT; - IKS_TM = IKS_T * MULT; + ISS_TM = ISS_T * MULT; +// New: 504.9 + ICSS_TM = ICSS_T * MULT; + IKS_TM = IKS_T * MULT; `endif - CJE_TM = CJE_T * MULT; - CJC_TM = CJC_T * MULT; + CJE_TM = CJE_T * MULT; + CJC_TM = CJC_T * MULT; + +// begin RvdT, 28-10-2008, MXT504.8_alpha +// Base-emitter tunneling current Mult scaling: +// BTJE_TM = BTJE_T * MULT; +// end RvdT, 28-10-2008, MXT504.8_alpha + `ifdef SUBSTRATE CJS_TM = CJS_T * MULT; diff --git a/src/spicelib/devices/adms/mextram/admsva/variables.inc b/src/spicelib/devices/adms/mextram/admsva/variables.inc index 10608d0cd..85c5d32da 100644 --- a/src/spicelib/devices/adms/mextram/admsva/variables.inc +++ b/src/spicelib/devices/adms/mextram/admsva/variables.inc @@ -1,5 +1,7 @@ // Declaration of variables +real _x, _x0, _a, _dxa; + real _circuit_gmin; // Model constants @@ -8,7 +10,7 @@ real An, Bn; // Temperature scaling variables -real Tk, Trk, tN, Tki, Tamb; +real Tk, Trk, tN, Tamb; real Vt, Vtr, VtINV, VtrINV, VdtINV; real Vdt; @@ -23,7 +25,16 @@ real RCCxx_T, RCCex_T, RCCin_T; real BF_T, BRI_T; real IS_T, IK_T, IBF_T, IBR_T, VEF_T, VER_T; - + +// RvdT: November 2008, Zener tunneling parameters and variables: +real Izteb, IZEB_T, E0BE, dE0BE,nZEB_T, pow2_2mPE, pow2_PEm2, inv_VDE, inv_VDE_T; +real eZEB, edZEB, DZEB, VGZEB_T, VGZEB_Tr, inv_VGZEB_Tr, CJE_T_div_CJE ; + +// RvdT: March 2009, Zener tunneling parameters and variables: +real VGZEBOK; + +// end Zener tunneling parameters + real TAUE_T, TAUB_T, TEPI_T, TAUR_T; real BnT, DEG_T, Tk300; @@ -32,13 +43,21 @@ real RTH_Tamb; `endif `ifdef SUBSTRATE -real UdsT, VDS_T, CJS_T, ISS_T, IKS_T; +real UdsT, VDS_T, CJS_T, ISS_T, ICSS_T, IKS_T; `endif // MULT - scaling variables real invMULT; -real IS_TM, IK_TM, IBF_TM, IBR_TM, IHC_M; +real IS_TM, IK_TM, IBF_TM, IBR_TM, IHC_M; +// RvdT: November 2008, Zener tunneling parameters +real IZEB_TM ; + +// end Zener tunneling parameters + + + + real CJE_TM, CJC_TM; real RE_TM, RBC_TM, RBV_TM, RCV_TM, SCRCV_M; @@ -55,7 +74,7 @@ real RTH_Tamb_M, CTH_M; `endif `ifdef SUBSTRATE -real ISS_TM, IKS_TM, CJS_TM; +real ISS_TM, ICSS_TM, IKS_TM, CJS_TM; `endif @@ -81,12 +100,12 @@ real q0I, q1I, qBI, Ir, If, In; real Xext1; real Ib1, Ib1_s, Ib2, Ib3; -real Ibf0, Iex, Isub; +real Ibf0, Iex; real g1, g2, pWex, nBex; real Xg1, XnBex, XIMex, XIMsub, Vex, VBex, Fex, XIex; `ifdef SUBSTRATE -real XIsub, Isf; +real Isub, XIsub, Isf; `endif // Distributed base effects variables @@ -103,7 +122,7 @@ real lambda, Gem, Gmax, Iavl; real Icap_IHC; `ifdef SELFHEATING -real power; +real Tki, power; `endif // Charges and capacitances variables @@ -130,13 +149,20 @@ real Vb2c1, Vb2c2, Vb2e1, Vb1e1, Vb1b2, Vb1c4, Vc1c2; real Vc3c4, Vc4c1; // RvdT, 25-02-2008: new variables Vsc3, Vsc4 `ifdef SUBSTRATE -real Vsc1, Vsc3, Vsc4; +real Vsc1, Vsc3, Vsc4, eVsc1; `endif real Vee1, Vbb1, Vbc3, Vcc3, Vbe, Vbc; -real eVb2c2, eVb2e1, eVb1e1, eVb1b2, eVb1c4, eVbc3, eVsc1; +real eVb2c2, eVb2e1, eVb1e1, eVb1b2, eVb1c4, eVbc3; real eVb1c4VDC, eVb2c2VDC, eVbc3VDC, eVb2c1VDC; // Help variables + +// RvdT, November 2008, lntN introduced to speed up T-scaling: +// Acknowledgements due to Geoffrey Coram +real lntN ; + +// RvdT, November 2008 variables for local use; may be re-used globally: +real x, y ; real dxa, sqr_arg; real eps2, x2;