From 8ce89a2b80cc94de99a4c7c4637459234e6091e6 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 14 Dec 2020 12:20:43 +0100 Subject: [PATCH] update version and improve veriloga compatibility --- .../adms/mextram/admsva/COPYRIGHT_NOTICE | 40 - .../admsva/IP_NOTICE_DISCLAIMER_LICENSE | 48 + .../devices/adms/mextram/admsva/bjt504t.va | 71 +- .../devices/adms/mextram/admsva/evaluate.inc | 1170 ++++++++--------- .../devices/adms/mextram/admsva/frontdef.inc | 164 ++- .../adms/mextram/admsva/initialize.inc | 110 +- .../devices/adms/mextram/admsva/noise.inc | 145 ++ .../devices/adms/mextram/admsva/opinfo.inc | 73 +- .../devices/adms/mextram/admsva/opvars.inc | 10 +- .../adms/mextram/admsva/parameters.inc | 314 ++--- .../devices/adms/mextram/admsva/tscaling.inc | 333 +++-- .../devices/adms/mextram/admsva/variables.inc | 242 ++-- 12 files changed, 1394 insertions(+), 1326 deletions(-) delete mode 100644 src/spicelib/devices/adms/mextram/admsva/COPYRIGHT_NOTICE create mode 100644 src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE create mode 100644 src/spicelib/devices/adms/mextram/admsva/noise.inc diff --git a/src/spicelib/devices/adms/mextram/admsva/COPYRIGHT_NOTICE b/src/spicelib/devices/adms/mextram/admsva/COPYRIGHT_NOTICE deleted file mode 100644 index 09d01075d..000000000 --- a/src/spicelib/devices/adms/mextram/admsva/COPYRIGHT_NOTICE +++ /dev/null @@ -1,40 +0,0 @@ -Verilog-A implementation of the Mextram Bipolar Transistor Model, -including variants of the Mextram model released by Delft University. - -Copyright (c) 2006 Delft University of Technology -Licensed under the Educational Community License version 1.0 - - -This Original Work, including software, source code, documents, or other related items, -is being provided by the copyright holder(s) subject to the terms of the Educational -Community License. By obtaining, using and/or copying this Original Work, you agree that -you have read, understand, and will comply with the following terms and conditions of -the Educational Community License: - -Permission to use, copy, modify, merge, publish, distribute, and sublicense this Original -Work and its documentation, with or without modification, for any purpose, and without fee -or royalty to the copyright holder(s) is hereby granted, provided that you include the -following on ALL copies of the Original Work or portions thereof, including modifications -or derivatives, that you make: - -The full text of the Educational Community License in a location viewable to users of the -redistributed or derivative work. - -Any pre-existing intellectual property disclaimers, notices, or terms and conditions. - -Notice of any changes or modifications to the Original Work, including the date the -changes were made. - -Any modifications of the Original Work must be distributed in such a manner as to avoid -any confusion with the Original Work of the copyright holders. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR -PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE -FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -The name and trademarks of copyright holder(s) may NOT be used in advertising or publicity -pertaining to the Original or Derivative Works without specific, written prior permission. -Title to copyright in the Original Work and any associated documentation will at all times -remain with the copyright holders. diff --git a/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE b/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE new file mode 100644 index 000000000..60ba5752b --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/IP_NOTICE_DISCLAIMER_LICENSE @@ -0,0 +1,48 @@ +// Copyright (c) 2000-2007, NXP Semiconductors +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University + +INTELLECTUAL PROPERTY NOTICE, DISCLAIMER AND LICENSE + +The Mextram model and documentation presented at this website, +denoted as the Model, +has been developed by NXP Semiconductors until 2007, +Delft University of Technology from 2007 to 2014, +and Auburn University since April 2015. + +The Model is distributed as is, completely without any expressed +or implied warranty or service support. +NXP Semiconductors, Delft University of Technology, +Auburn University and their employees are not liable for +the condition or performance of the Model. + +NXP Semiconductors, Delft University of Technology, +Auburn University own +the copyright and grant users a perpetual, +irrevocable, worldwide, non-exclusive, royalty-free +license with respect to the Model as set forth below. + +NXP Semiconductors, Delft University of Technology, Auburn University +hereby disclaim all implied warranties. + +NXP Semiconductors, Delft University of Technology, Auburn University +grant the users the right to modify, copy, and +redistribute the Model and documentation, +both within the user's organization and externally, +subject to the following restrictions + +1. The users agree not to charge for the code +itself but may charge for additions, extensions, or support. + +2. In any product based on the Model, the users agree to acknowledge +NXP Semiconductors, Delft University of Technology, Auburn University +that developed the Model. This acknowledgment +shall appear in the product documentation. + +3. The users agree to obey all restrictions governing redistribution +or export of the Model. + +4. The users agree to reproduce any copyright notice which appears +on the Model on any copy or modification of such made available +to others. + diff --git a/src/spicelib/devices/adms/mextram/admsva/bjt504t.va b/src/spicelib/devices/adms/mextram/admsva/bjt504t.va index 5e5bbea38..7f428a170 100644 --- a/src/spicelib/devices/adms/mextram/admsva/bjt504t.va +++ b/src/spicelib/devices/adms/mextram/admsva/bjt504t.va @@ -1,46 +1,47 @@ -`include "frontdef.inc" -`define SELFHEATING -`define SUBSTRATE - -module bjt504tva (c, b, e, s, dt); +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. -`ifdef insideADMS - `define P(p) (*p*) -`else - `define P(p) -`endif +`include "frontdef.inc" +`define SELFHEATING +`define SUBSTRATE - // External ports - inout c, b, e, s, dt; - - electrical c `P(info="external collector node"); - electrical b `P(info="external base node"); - electrical e `P(info="external emitter node"); - electrical s `P(info="external substrate node"); - electrical dt `P(info="external thermal node"); - - // Internal nodes - electrical c1 `P(info="internal collector node 1"); - electrical e1 `P(info="internal emitter node"); - electrical b1 `P(info="internal base node 1"); - electrical b2 `P(info="internal base node 2"); - electrical c2 `P(info="internal collector node 2"); - electrical c3 `P(info="internal collector node 3"); - electrical c4 `P(info="internal collector node 4"); - // For correlated noise implementation - electrical noi `P(info="internal noise node"); +module bjt504tva (c, b, e, s, dt); + + // External ports +inout c, b, e, s, dt; + +electrical c `P(info="external collector node"); +electrical b `P(info="external base node"); +electrical e `P(info="external emitter node"); +electrical s `P(info="external substrate node"); +electrical dt `P(info="external thermal node"); + +// Internal nodes +electrical c1 `P(info="internal collector node 1"); +electrical e1 `P(info="internal emitter node"); +electrical b1 `P(info="internal base node 1"); +electrical b2 `P(info="internal base node 2"); +electrical c2 `P(info="internal collector node 2"); +electrical c3 `P(info="internal collector node 3"); +electrical c4 `P(info="internal collector node 4"); +// For correlated noise implementation +electrical noi `P(info="internal noise node"); `include "parameters.inc" `include "variables.inc" `include "opvars.inc" -analog begin - -`include "initialize.inc" +analog begin +`include "initialize.inc" `include "tscaling.inc" `include "evaluate.inc" +`include "noise.inc" `include "opinfo.inc" - -end // analog -endmodule +// The following can be used to print OP-info to std out: +// `include "op_print.inc" + +end // analog +endmodule diff --git a/src/spicelib/devices/adms/mextram/admsva/evaluate.inc b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc index 76b9184af..98304fa11 100644 --- a/src/spicelib/devices/adms/mextram/admsva/evaluate.inc +++ b/src/spicelib/devices/adms/mextram/admsva/evaluate.inc @@ -1,704 +1,636 @@ -// Evaluate model equations - -begin // Currents and sharges -// Nodal biases - - Vb2c1 = TYPE * V(b2, c1); - Vb2c2 = TYPE * V(b2, c2); - Vb2e1 = TYPE * V(b2, e1); - Vb1e1 = TYPE * V(b1, e1); - Vb1b2 = TYPE * V(b1, b2); -`ifdef SUBSTRATE - Vsc1 = TYPE * V(s, c1); -`endif - Vc1c2 = TYPE * V(c1, c2); - Vee1 = TYPE * V(e, e1); - Vbb1 = TYPE * V(b, b1); - Vbe = TYPE * V(b, e); - Vbc = TYPE * V(b, c); +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. -/* RvdT, 03-12-2007, voltage differences +// Evaluate model equations + +begin // Currents and charges +// Nodal biases + + Vb2c1 = TYPE * V(b2, c1); + Vb2c2 = TYPE * V(b2, c2); + Vb2e1 = TYPE * V(b2, e1); + Vb1e1 = TYPE * V(b1, e1); + Vb1b2 = TYPE * V(b1, b2); +`ifdef SUBSTRATE + Vsc1 = TYPE * V(s, c1); +`endif + Vc1c2 = TYPE * V(c1, c2); + Vee1 = TYPE * V(e, e1); + Vbb1 = TYPE * V(b, b1); + Vbe = TYPE * V(b, e); + Vbc = TYPE * V(b, c); + +/* RvdT, 03-12-2007, voltage differences associated with distributed parasitic collector. Evaluated taking values of resistances into account: - in case of vanishing resistance corresponding node + in case of vanishing resistance corresponding node is not addressed: */ -if (RCBLX > 0.0) - begin - if (RCBLI > 0.0) + if (RCBLX > 0.0) begin - Vc4c1 = TYPE * V(c4, c1); - Vc3c4 = TYPE * V(c3, c4); + if (RCBLI > 0.0) + begin + Vc4c1 = TYPE * V(c4, c1); + Vc3c4 = TYPE * V(c3, c4); + end + else + begin + Vc4c1 = 0 ; + Vc3c4 = TYPE * V(c3, c1); + end end - else + else begin - Vc4c1 = 0 ; - Vc3c4 = TYPE * V(c3, c1); + if (RCBLI > 0.0) + begin + Vc4c1 = TYPE * V(c4, c1); + Vc3c4 = 0 ; + end + else + begin + Vc4c1 = 0 ; + Vc3c4 = 0 ; + end end - end -else - begin - if (RCBLI > 0.0) - begin - Vc4c1 = TYPE * V(c4, c1); - Vc3c4 = 0 ; - end - else - begin - Vc4c1 = 0 ; - Vc3c4 = 0 ; - end - end - Vb1c4 = Vb1b2 + Vb2c2 - Vc1c2 - Vc4c1 ; - Vcc3 = - Vbc + Vbb1 + Vb1c4 - Vc3c4 ; - Vbc3 = Vbc + Vcc3 ; + Vb1c4 = Vb1b2 + Vb2c2 - Vc1c2 - Vc4c1 ; + Vcc3 = - Vbc + Vbb1 + Vb1c4 - Vc3c4 ; + Vbc3 = Vbc + Vcc3 ; `ifdef SUBSTRATE -Vsc4 = Vsc1 - Vc4c1 ; -Vsc3 = Vsc4 - Vc3c4 ; + Vsc4 = Vsc1 - Vc4c1 ; + Vsc3 = Vsc4 - Vc3c4 ; `endif -// Exponential bias terms - - `expLin(eVb2c2,Vb2c2 * VtINV) - `expLin(eVb2e1,Vb2e1 * VtINV) - `expLin(eVb1e1,Vb1e1 * VtINV) - `expLin(eVb1c4,Vb1c4 * VtINV) - `expLin(eVb1b2,Vb1b2 * VtINV) - `expLin(eVbc3,Vbc3 * VtINV) +// Exponential bias terms + + `expLin(eVb2c2,Vb2c2 * VtINV) + `expLin(eVb2e1,Vb2e1 * VtINV) + `expLin(eVb1e1,Vb1e1 * VtINV) + `expLin(eVb1c4,Vb1c4 * VtINV) + `expLin(eVb1b2,Vb1b2 * VtINV) + `expLin(eVbc3,Vbc3 * VtINV) `ifdef SUBSTRATE - `expLin(eVsc1,Vsc1 * VtINV) + `expLin(eVsc1,Vsc1 * VtINV) +// RvdT MXT504.10, new: eVsc3, eVsc4 + `expLin(eVsc3,Vsc3 * VtINV) + `expLin(eVsc4,Vsc4 * VtINV) `endif - - `expLin(eVbc3VDC,(Vbc3 - VDC_T) * VtINV) - `expLin(eVb1c4VDC,(Vb1c4 - VDC_T) * VtINV) - `expLin(eVb2c2VDC,(Vb2c2 - VDC_T) * VtINV) - `expLin(eVb2c1VDC,(Vb2c1 - VDC_T) * VtINV) - -// Governing equations - - // Epilayer model - - K0 = sqrt(1.0 + 4.0 * eVb2c2VDC); - Kw = sqrt(1.0 + 4.0 * eVb2c1VDC); - pW = 2.0 * eVb2c1VDC / (1.0 + Kw); - if (pW < `TEN_M40) pW = 0; - Ec = Vt * (K0 - Kw - ln((K0 + 1.0) / (Kw + 1.0)) ); - Ic1c2 = (Ec + Vc1c2) / RCV_TM + _circuit_gmin * Vc1c2; - - if (Ic1c2 > 0.0) begin - - `linLog(tmpV,Vb2c1,100.0); - Vqs_th = VDC_T + 2.0 * Vt * - ln(0.5 * Ic1c2 * RCV_TM * VtINV + 1.0) - tmpV; - eps_VDC = 0.2 * VDC_T; - `max_hyp0(Vqs, Vqs_th, eps_VDC); - Iqs = Vqs * (Vqs + IHC_M * SCRCV_M) / (SCRCV_M * (Vqs + IHC_M * RCV_TM)); - - Ic1c2_Iqs = Ic1c2 / Iqs; - `max_logexp(alpha1, Ic1c2_Iqs, 1.0, AXI); - alpha = alpha1 / (1.0 + AXI * ln(1.0 + exp(-1.0 / AXI))); - vyi = Vqs / (IHC_M * SCRCV_M); - yi = (1.0 + sqrt(1.0 + 4.0 * alpha * vyi * (1.0 + vyi))) / - (2.0 * alpha * (1.0 + vyi)); - - xi_w = 1.0 - yi / (1.0 + pW * yi); - gp0 = 0.5 * Ic1c2 * RCV_TM * xi_w * VtINV; - - gp0_help = 2.0 * gp0 + pW * (pW + gp0 + 1.0); - gp02 = 0.5 * (gp0 - 1.0); - sqr_arg = gp02 * gp02 + gp0_help; - if (gp0 >= 1.0) - p0star = gp02 + sqrt(sqr_arg); - else - p0star = gp0_help / (sqrt(sqr_arg) - gp02); - if (p0star < `TEN_M40) p0star = 0.0; - - - eVb2c2star = p0star * (p0star + 1.0) * exp(VDC_T * VtINV); - B1 = 0.5 * SCRCV_M * (Ic1c2 - IHC_M); - B2 = SCRCV_M * RCV_TM * IHC_M * Ic1c2; - Vxi0 = B1 + sqrt(B1 * B1 + B2); - Vch = VDC_T * (0.1 + 2.0 * Ic1c2 / (Ic1c2 + Iqs)); - Icap = IHC_M * Ic1c2 / (IHC_M + Ic1c2); - Icap_IHC = IHC_M / (IHC_M + Ic1c2); - - end else begin - - p0star = 2.0 * eVb2c2VDC / (1.0 + K0); - eVb2c2star = eVb2c2; - if ((abs(Vc1c2) < 1.0e-5 * Vt) || - (abs(Ec) < `TEN_M40 * Vt * (K0 + Kw))) - begin - pav = 0.5 * (p0star + pW); - xi_w = pav / (pav + 1.0); + + `expLin(eVbc3VDC,(Vbc3 - VDC_T) * VtINV) + `expLin(eVb1c4VDC,(Vb1c4 - VDC_T) * VtINV) + `expLin(eVb2c2VDC,(Vb2c2 - VDC_T) * VtINV) + `expLin(eVb2c1VDC,(Vb2c1 - VDC_T) * VtINV) + +// Governing equations + +// Epilayer model + + K0 = sqrt(1.0 + 4.0 * eVb2c2VDC); + Kw = sqrt(1.0 + 4.0 * eVb2c1VDC); + pW = 2.0 * eVb2c1VDC / (1.0 + Kw); + // if (pW < `TEN_M40) pW = 0; + Ec = Vt * (K0 - Kw - ln((K0 + 1.0) / (Kw + 1.0)) ); + Ic1c2 = (Ec + Vc1c2) / RCV_TM; + + if (Ic1c2 > 0.0) begin + + `linLog(tmpV,Vb2c1,100.0); + Vqs_th = VDC_T + 2.0 * Vt * + ln(0.5 * Ic1c2 * RCV_TM * VtINV + 1.0) - tmpV; + eps_VDC = 0.2 * VDC_T; + `max_hyp0(Vqs, Vqs_th, eps_VDC); + Iqs = Vqs * (Vqs + IHC_M * SCRCV_M) / (SCRCV_M * (Vqs + IHC_M * RCV_TM)); + + Ic1c2_Iqs = Ic1c2 / Iqs; + `max_logexp(alpha1, Ic1c2_Iqs, 1.0, AXI); + alpha = alpha1 / (1.0 + AXI * ln(1.0 + exp(-1.0 / AXI))); + vyi = Vqs / (IHC_M * SCRCV_M); + yi = (1.0 + sqrt(1.0 + 4.0 * alpha * vyi * (1.0 + vyi))) / + (2.0 * alpha * (1.0 + vyi)); + + //xi_w = 1.0 - yi / (1.0 + pW * yi); + // Niu 5/23/2015, fixes numerical discontinuity at forward/reverse transition, see "Epi layer model improvement of smoothness at I=0" + xi_w = (1.0 - yi + pW * yi) / (1.0 + pW * yi); + gp0 = 0.5 * Ic1c2 * RCV_TM * xi_w * VtINV; + + gp0_help = 2.0 * gp0 + pW * (pW + gp0 + 1.0); + gp02 = 0.5 * (gp0 - 1.0); + sqr_arg = gp02 * gp02 + gp0_help; + if (gp0 >= 1.0) + p0star = gp02 + sqrt(sqr_arg); + else + p0star = gp0_help / (sqrt(sqr_arg) - gp02); + // if (p0star < `TEN_M40) p0star = 0.0; + + + eVb2c2star = p0star * (p0star + 1.0) * exp(VDC_T * VtINV); + B1 = 0.5 * SCRCV_M * (Ic1c2 - IHC_M); + B2 = SCRCV_M * RCV_TM * IHC_M * Ic1c2; + Vxi0 = B1 + sqrt(B1 * B1 + B2); + Vch = VDC_T * (0.1 + 2.0 * Ic1c2 / (Ic1c2 + Iqs)); + Icap = IHC_M * Ic1c2 / (IHC_M + Ic1c2); + Icap_IHC = IHC_M / (IHC_M + Ic1c2); + + end else begin + + Iqs = 0.0 ; + p0star = 2.0 * eVb2c2VDC / (1.0 + K0); + eVb2c2star = eVb2c2; + if ((abs(Vc1c2) < 1.0e-5 * Vt) || + (abs(Ec) < `TEN_M40 * Vt * (K0 + Kw))) + begin + pav = 0.5 * (p0star + pW); + xi_w = pav / (pav + 1.0); + end + else + begin + xi_w = Ec / (Ec + Vb2c2 - Vb2c1); end - else - begin - xi_w = Ec / (Ec + Vb2c2 - Vb2c1); - end - - Vxi0 = Vc1c2; - Vch = 0.1 * VDC_T; - Icap = Ic1c2; - Icap_IHC = 1.0 - Icap / IHC_M; - - end - - // Effective emitter junction capacitance bias - - Vfe = VDE_T * (1.0 - pow(`AJE , -1.0 / PE)); - a_VDE = 0.1 * VDE_T; - `min_logexp(Vje, Vb2e1, Vfe, a_VDE); + Vxi0 = Vc1c2; + Vch = 0.1 * VDC_T; + Icap = Ic1c2; + Icap_IHC = 1.0 - Icap / IHC_M; + + end + + // Effective emitter junction capacitance bias + + Vfe = VDE_T * (1.0 - pow(`AJE , -1.0 / PE)); + a_VDE = 0.1 * VDE_T; + `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 + + Vjunc = Vb2c1 + Vxi0; + bjc = (`AJC - XP_T) / (1.0 - XP_T); + Vfc = VDC_T * (1.0 - pow(bjc, -1.0 / PC)); + `min_logexp(Vjc, Vjunc, Vfc, Vch); + fI = pow(Icap_IHC, MC); + Vcv = VDC_T / (1.0 - PC) * (1.0 - fI * pow(1.0 - Vjc / VDC_T, 1.0 - PC)) + + fI * bjc * (Vjunc - Vjc); + Vtc = (1.0 - XP_T) * Vcv + XP_T * Vb2c1; + + // Transfer current + + If0 = 4.0 * IS_TM / IK_TM; + f1 = If0 * eVb2e1; + n0 = f1 / (1.0 + sqrt(1.0 + f1)); + f2 = If0 * eVb2c2star; + nB = f2 / (1.0 + sqrt(1.0 + f2)); + + if (DEG == 0.0) + q0I = 1.0 + Vte / VER_T + Vtc / VEF_T; + else + begin + termE = (Vte / VER_T + 1.0) * DEG_T * VtINV; + termC = -Vtc / VEF_T * DEG_T * VtINV; + q0I = (exp(termE) - exp(termC)) / + (exp(DEG_T * VtINV) - 1.0); + end + + `max_hyp0(q1I, q0I, 0.1); + qBI = q1I * (1.0 + 0.5 * (n0 + nB)); + + Ir = IS_TM * eVb2c2star; + If = IS_TM * eVb2e1; + In = (If - Ir) / qBI; + + // Base and substrate current(s) + + Ibf0 = IS_TM / BF_T; + if (XREC == 0.0) + Ib1 = (1.0 - XIBI) * Ibf0 * (eVb2e1 - 1.0); + else + Ib1 = (1.0 - XIBI) * Ibf0 * ((1.0 - XREC) * (eVb2e1 - 1.0) + + XREC * (eVb2e1 + eVb2c2star - 2.0) * (1.0 + Vtc / VEF_T)); + + Ib1_s = XIBI * Ibf0 * (eVb1e1 - 1.0); + `expLin(tmpExp,Vb2e1 * VtINV / MLF) + Ib2 = IBF_TM * (tmpExp - 1.0) + my_gmin * Vb2e1; + `expLin(tmpExp,0.5 * Vb1c4 * VtINV) + Ib3 = IBR_TM * (eVb1c4 - 1.0) / + (tmpExp + exp(0.5 * VLR * VtINV)) + + my_gmin * Vb1c4; -// 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 - - Vjunc = Vb2c1 + Vxi0; - bjc = (`AJC - XP_T) / (1.0 - XP_T); - Vfc = VDC_T * (1.0 - pow(bjc, -1.0 / PC)); - `min_logexp(Vjc, Vjunc, Vfc, Vch); - fI = pow(Icap_IHC, MC); - Vcv = VDC_T / (1.0 - PC) * (1.0 - fI * pow(1.0 - Vjc / VDC_T, 1.0 - PC)) + - fI * bjc * (Vjunc - Vjc); - Vtc = (1.0 - XP_T) * Vcv + XP_T * Vb2c1; - - // Transfer current - - If0 = 4.0 * IS_TM / IK_TM; - f1 = If0 * eVb2e1; - n0 = f1 / (1.0 + sqrt(1.0 + f1)); - f2 = If0 * eVb2c2star; - nB = f2 / (1.0 + sqrt(1.0 + f2)); - - if (DEG == 0.0) - q0I = 1.0 + Vte / VER_T + Vtc / VEF_T; - else - begin - termE = (Vte / VER_T + 1.0) * DEG_T * VtINV; - termC = -Vtc / VEF_T * DEG_T * VtINV; - q0I = (exp(termE) - exp(termC)) / - (exp(DEG_T * VtINV) - 1.0); - end - - `max_hyp0(q1I, q0I, 0.1); - qBI = q1I * (1.0 + 0.5 * (n0 + nB)); - - Ir = IS_TM * eVb2c2star; - If = IS_TM * eVb2e1; - In = (If - Ir) / qBI; - - // Base and substrate current(s) - - Ibf0 = IS_TM / BF_T; - if (XREC == 0.0) - Ib1 = (1.0 - XIBI) * Ibf0 * (eVb2e1 - 1.0); - else - Ib1 = (1.0 - XIBI) * Ibf0 * ((1.0 - XREC) * (eVb2e1 - 1.0) + - XREC * (eVb2e1 + eVb2c2star - 2.0) * (1.0 + Vtc / VEF_T)); - - Ib1_s = XIBI * Ibf0 * (eVb1e1 - 1.0); - `expLin(tmpExp,Vb2e1 * VtINV / MLF) - Ib2 = IBF_TM * (tmpExp - 1.0) + _circuit_gmin * Vb2e1; - `expLin(tmpExp,0.5 * Vb1c4 * VtINV) - 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 + 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 + 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; - g2 = 4.0 * eVb1c4VDC; - nBex = g1 / (1.0 + sqrt(1.0 + g1)); - pWex = g2 / (1.0 + sqrt(1.0 + g2)); - Iex = (1.0 / BRI_T) * (0.5 * IK_TM * nBex - IS_TM); + // Iex, Isub (XIex, XIsub) + g1 = If0 * eVb1c4; + g2 = 4.0 * eVb1c4VDC; + +// nBex until and including MXT 504.9: +// nBex = g1 / (1.0 + sqrt(1.0 + g1)); +// nBex since MXT 504.10.1: Ackn. Jos Peters, Geoffrey Coram + nBex = (g1 - If0) / (1.0 + sqrt(1.0 + g1)); + pWex = g2 / (1.0 + sqrt(1.0 + g2)); +/* Iex until and including MXT 504.9: + Iex = (1.0 / BRI_T) * (0.5 * IK_TM * nBex - IS_TM); +*/ +// Iex since MXT 504.10: RvdT@TUDelft Q1, 2011: + Iex = IK_TM * nBex / (2.0 * BRI_T) ; `ifdef SUBSTRATE - Isub = 2.0 * ISS_TM * (eVb1c4 - 1.0) / - (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); -// until504.8: Isf = ISS_TM * (eVsc1 - 1.0); +// RvdT MXT504.10, new term: eVsc4 + if (EXSUB == 1.0) + Isub = 2.0 * ISS_TM * (eVb1c4 - eVsc4) / + (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); + else + Isub = 2.0 * ISS_TM * (eVb1c4 - 1.0) / + (1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c4)); + +// until504.8: Isf = ISS_TM * (eVsc1 - 1.0); // New 504.9: -if (ICSS < 0.0) + 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 + 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; + + XIex =0.0; `ifdef SUBSTRATE - XIsub = 0.0; + XIsub = 0.0; `endif - if (EXMOD == 1) - begin - - Iex = Iex * Xext1; - -`ifdef SUBSTRATE - Isub = Isub * Xext1; -`endif - - Xg1 = If0 * eVbc3; - XnBex = Xg1 / (1.0 + sqrt(1.0 + Xg1)); - XIMex = XEXT * (0.5 * IK_TM * XnBex - IS_TM) / BRI_T; - -`ifdef SUBSTRATE - XIMsub = XEXT * 2.0 * ISS_TM * (eVbc3 - 1.0) / - (1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc3)); - Vex_bias = XEXT * (IS_TM / BRI_T + ISS_TM) * RCCxx_TM; -`else - XIMsub = 0.0; - Vex_bias = XEXT * (IS_TM / BRI_T) * RCCxx_TM; -`endif - - Vex = Vt * (2.0 - ln( Vex_bias * VtINV)); - vdif = Vbc3 - Vex; - `max_hyp0(VBex, vdif, 0.11); - - Fex = VBex /(Vex_bias + (XIMex + XIMsub) * RCCxx_TM + VBex); - XIex = Fex * XIMex; - -`ifdef SUBSTRATE - XIsub = Fex * XIMsub; -`endif - end - else +/* begin: RvdT, Q4 2012, Mextram 504.11: added EXMOD=2 option: */ + if (EXMOD == 1 || EXMOD == 2) begin - Fex = 0; - XnBex = 0 ; + + Iex = Iex * Xext1; + +`ifdef SUBSTRATE + Isub = Isub * Xext1; +`endif + + Xg1 = If0 * eVbc3; +// XnBex until and including MXT 504.9: +// XnBex = Xg1 / (1.0 + sqrt(1.0 + Xg1)); +// XnBex in MXT 504.10.1: Ackn. Jos Peters, Geoffrey Coram: + XnBex = (Xg1 - If0) / (1.0 + sqrt(1.0 + Xg1)); +/* XIMex until and including MXT 504.9: + XIMex = XEXT * (0.5 * IK_TM * XnBex - IS_TM) / BRI_T; +*/ +// XIMex in MXT 504.10: RvdT@TUDelft Q1, 2011: + XIMex = XEXT * 0.5 * IK_TM * XnBex / BRI_T; + +`ifdef SUBSTRATE +// RvdT MXT504.10, new term: eVsc3 + if (EXSUB == 1.0) + XIMsub = XEXT * 2.0 * ISS_TM * (eVbc3 - eVsc3) / + (1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc3)); + else + XIMsub = XEXT * 2.0 * ISS_TM * (eVbc3 - 1.0) / + (1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc3)); +`else + XIMsub = 0.0; +`endif + + if (EXMOD == 1) + begin +`ifdef SUBSTRATE + Vex_bias = XEXT * (IS_TM / BRI_T + ISS_TM) * RCCxx_TM; +`else + Vex_bias = XEXT * (IS_TM / BRI_T) * RCCxx_TM; +`endif + Vex = Vt * (2.0 - ln( Vex_bias * VtINV)); + vdif = Vbc3 - Vex; + `max_hyp0(VBex, vdif, 0.11); + Fex = VBex /(Vex_bias + (XIMex + XIMsub) * RCCxx_TM + VBex); + end + else + begin + Vex = 0.0 ; + vdif = 0.0 ; + VBex = 0.0 ; + Fex = 1.0 ; + end + +/* end: RvdT, Q4, 2012, Mextram 504.11: added EXMOD=2 option: */ + + XIex = Fex * XIMex; + +`ifdef SUBSTRATE + XIsub = Fex * XIMsub; +`endif + end + else + begin + Fex = 0; + XnBex = 0 ; end - // Variable base resistance - - q0Q = 1.0 + Vte / VER_T + Vtc / VEF_T; - `max_hyp0(q1Q, q0Q, 0.1); - qBQ = q1Q * (1.0 + 0.5 * (n0 + nB)); - - Rb2 = 3.0 * RBV_TM / qBQ; - Ib1b2 = (2.0 * Vt * (eVb1b2 - 1.0) + Vb1b2) / Rb2 + _circuit_gmin * Vb1b2; - - // Weak-avalanche current - - Iavl = 0.0; - Gem = 0.0; - if ((Ic1c2 > 0.0) && (Vb2c1 < VDC_T)) begin - - dEdx0 = 2.0 * VAVL / (WAVL * WAVL); - sqr_arg = (VDC_T - Vb2c1) / Icap_IHC; - xd = sqrt(2.0 * sqr_arg / dEdx0); - if (EXAVL == 0.0) - Weff = WAVL; - else - begin - xi_w1 = 1.0 - 0.5 * xi_w; - Weff = WAVL * xi_w1 * xi_w1; - end - Wd = xd * Weff / sqrt(xd * xd + Weff * Weff); - Eav = (VDC_T - Vb2c1) / Wd; - E0 = Eav + 0.5 * Wd * dEdx0 * Icap_IHC; - - if (EXAVL == 0) - Em = E0; - else - begin - SHw = 1.0 + 2.0 * SFH * (1.0 + 2.0 * xi_w); - Efi = (1.0 + SFH) / (1.0 + 2.0 * SFH); - Ew = Eav - 0.5 * Wd * dEdx0 * (Efi - Ic1c2 / (IHC_M * SHw)); - sqr_arg = (Ew - E0) * (Ew - E0) + 0.1 * Eav * Eav * Icap / IHC_M; - Em = 0.5 * (Ew + E0 + sqrt(sqr_arg)); - end - - EmEav_Em = (Em - Eav) / Em; - if (abs(EmEav_Em) > `TEN_M07) - begin - lambda = 0.5 * Wd / EmEav_Em; - Gem = An / BnT * Em * lambda * - (exp(-BnT / Em) - exp(-BnT / Em * (1.0 + Weff / lambda)) ); - end - else - Gem = An * Weff * exp(-BnT / Em); - - Gmax = Vt / (Ic1c2 * (RBC_TM + Rb2)) + qBI / BF_T + - RE_TM / (RBC_TM + Rb2); - Iavl = Ic1c2 * Gem / (Gem +Gem / Gmax + 1.0); - end + // Variable base resistance + + q0Q = 1.0 + Vte / VER_T + Vtc / VEF_T; + `max_hyp0(q1Q, q0Q, 0.1); + qBQ = q1Q * (1.0 + 0.5 * (n0 + nB)); + + Rb2 = 3.0 * RBV_TM / qBQ; + Ib1b2 = (2.0 * Vt * (eVb1b2 - 1.0) + Vb1b2) / Rb2; + + // Weak-avalanche current + + Iavl = 0.0; + Gem = 0.0; + if ((Ic1c2 > 0.0) && (Vb2c1 < VDC_T)) begin + + dEdx0 = 2.0 * VAVL / (WAVL * WAVL); + sqr_arg = (VDC_T - Vb2c1) / Icap_IHC; + xd = sqrt(2.0 * sqr_arg / dEdx0); + if (EXAVL == 0.0) + Weff = WAVL; + else + begin + xi_w1 = 1.0 - 0.5 * xi_w; + Weff = WAVL * xi_w1 * xi_w1; + end + Wd = xd * Weff / sqrt(xd * xd + Weff * Weff); + Eav = (VDC_T - Vb2c1) / Wd; + E0 = Eav + 0.5 * Wd * dEdx0 * Icap_IHC; + + if (EXAVL == 0) + Em = E0; + else + begin + SHw = 1.0 + 2.0 * SFH * (1.0 + 2.0 * xi_w); + Efi = (1.0 + SFH) / (1.0 + 2.0 * SFH); + Ew = Eav - 0.5 * Wd * dEdx0 * (Efi - Ic1c2 / (IHC_M * SHw)); + sqr_arg = (Ew - E0) * (Ew - E0) + 0.1 * Eav * Eav * Icap / IHC_M; + Em = 0.5 * (Ew + E0 + sqrt(sqr_arg)); + end + + EmEav_Em = (Em - Eav) / Em; + if (abs(EmEav_Em) > `TEN_M07) + begin + lambda = 0.5 * Wd / EmEav_Em; + Gem = An / BnT * Em * lambda * + (exp(-BnT / Em) - exp(-BnT / Em * (1.0 + Weff / lambda)) ); + end + else + Gem = An * Weff * exp(-BnT / Em); + + Gmax = Vt / (Ic1c2 * (RBC_TM + Rb2)) + qBI / BF_T + + RE_TM / (RBC_TM + Rb2); + Iavl = Ic1c2 * Gem / (Gem +Gem / Gmax + 1.0); + end + + if (eVb2c2star > 0.0) + Vb2c2star = Vt * ln(eVb2c2star); + else + Vb2c2star = Vb2c2; - if (eVb2c2star > 0.0) - Vb2c2star = Vt * ln(eVb2c2star); - else - Vb2c2star = Vb2c2; - `ifdef SELFHEATING - // Power dissipation - +// Power dissipation + // RvdT 03-12-2007, modified power equation due to distribution collector resistance - power = In * (Vb2e1 - Vb2c2star) + - Ic1c2 * (Vb2c2star - Vb2c1) - - Iavl * Vb2c2star + - Vee1 * Vee1 / RE_TM + - Vcc3 * Vcc3 * GCCxx_TM + - Vc3c4 * Vc3c4 * GCCex_TM + - Vc4c1 * Vc4c1 * GCCin_TM + - Vbb1 * Vbb1 / RBC_TM + + power_dis = In * (Vb2e1 - Vb2c2star) + + Ic1c2 * (Vb2c2star - Vb2c1) - + Iavl * Vb2c2star + + Vee1 * Vee1 / RE_TM + + Vcc3 * Vcc3 * GCCxx_TM + + Vc3c4 * Vc3c4 * GCCex_TM + + Vc4c1 * Vc4c1 * GCCin_TM + + Vbb1 * Vbb1 / RBC_TM + 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 + + (Ib1 + Ib2 - Izteb) * Vb2e1 + + Ib1_s * Vb1e1 + `ifdef SUBSTRATE - (Iex + Ib3) * Vb1c4 + XIex * Vbc3 + - Isub * (Vb1c4 - Vsc4) + - XIsub * (Vbc3 - Vsc3) + - Isf * Vsc1; + (Iex + Ib3) * Vb1c4 + XIex * Vbc3 + + Isub * (Vb1c4 - Vsc4) + + XIsub * (Vbc3 - Vsc3) + + Isf * Vsc1; `else - (Iex + Ib3) * Vb1c4 + XIex * Vbc3; + (Iex + Ib3) * Vb1c4 + XIex * Vbc3; +`endif + `endif - -`endif - // Charges - - 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 * inv_VDE_T, 1.0 - PE)) + - `AJE * (Vb1e1 - Vje_s)); - - Qtc = XCJC * CJC_TM * Vtc; - Qb0 = TAUB_T * IK_TM; - Qbe_qs = 0.5 * Qb0 * n0 * q1Q; - Qbc_qs = 0.5 * Qb0 * nB * q1Q; - - a_VDC = 0.1 * VDC_T; - `min_logexp(Vjcex, Vb1c4, Vfc, a_VDC); - Vtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - Vjcex / VDC_T, 1.0 - PC)) + - bjc * (Vb1c4 - Vjcex); - Qtex = CJC_TM * ((1.0 - XP_T) * Vtexv + XP_T * Vb1c4) * - (1.0 - XCJC) * (1.0 - XEXT); - - `min_logexp(XVjcex, Vbc3, Vfc, a_VDC); - XVtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - XVjcex / VDC_T, 1.0 - PC)) + - bjc * (Vbc3 - XVjcex); - XQtex = CJC_TM * ((1.0 - XP_T) * XVtexv + XP_T * Vbc3) * - (1.0 - XCJC) * XEXT; - + // Charges + + 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 * inv_VDE_T, 1.0 - PE)) + + `AJE * (Vb1e1 - Vje_s)); + + Qtc = XCJC * CJC_TM * Vtc; + Qb0 = TAUB_T * IK_TM; + Qbe_qs = 0.5 * Qb0 * n0 * q1Q; + Qbc_qs = 0.5 * Qb0 * nB * q1Q; + + a_VDC = 0.1 * VDC_T; + `min_logexp(Vjcex, Vb1c4, Vfc, a_VDC); + Vtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - Vjcex / VDC_T, 1.0 - PC)) + + bjc * (Vb1c4 - Vjcex); + Qtex = CJC_TM * ((1.0 - XP_T) * Vtexv + XP_T * Vb1c4) * + (1.0 - XCJC) * (1.0 - XEXT); + + `min_logexp(XVjcex, Vbc3, Vfc, a_VDC); + XVtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - XVjcex / VDC_T, 1.0 - PC)) + + bjc * (Vbc3 - XVjcex); + XQtex = CJC_TM * ((1.0 - XP_T) * XVtexv + XP_T * Vbc3) * + (1.0 - XCJC) * XEXT; + `ifdef SUBSTRATE - a_VDS = 0.1 * VDS_T; - Vfs = VDS_T * (1.0 - pow(`AJS , -1.0 / PS)); - `min_logexp(Vjs, Vsc1, Vfs, a_VDS); - Qts = CJS_TM * (VDS_T / (1.0 - PS) * - (1.0 - pow(1.0 - Vjs / VDS_T, 1.0 - PS)) + `AJS * (Vsc1 - Vjs)); + a_VDS = 0.1 * VDS_T; + Vfs = VDS_T * (1.0 - pow(`AJS , -1.0 / PS)); + `min_logexp(Vjs, Vsc1, Vfs, a_VDS); + Qts = CJS_TM * (VDS_T / (1.0 - PS) * + (1.0 - pow(1.0 - Vjs / VDS_T, 1.0 - PS)) + `AJS * (Vsc1 - Vjs)); `endif - - Qe0 = TAUE_T * IK_TM * pow(IS_TM / IK_TM, 1.0 / MTAU); - `expLin(tmpExp,Vb2e1 / (MTAU * Vt)) - Qe = Qe0 * (tmpExp - 1.0); - - Qepi0 = 4.0 * TEPI_T * Vt / RCV_TM; - Qepi = 0.5 * Qepi0 * xi_w * (p0star + pW + 2.0); - - Qex = TAUR_T * 0.5 * (Qb0 * nBex + Qepi0 * pWex) / (TAUB_T + TEPI_T); - XQex = 0.0; - - if (EXMOD == 1) begin - - Qex = Qex * (1.0 - XEXT); - Xg2 = 4.0 * eVbc3VDC; - XpWex = Xg2 / (1.0 + sqrt(1.0 + Xg2)); - XQex = 0.5 * Fex * XEXT * TAUR_T * - (Qb0 * XnBex + Qepi0 * XpWex) / (TAUB_T + TEPI_T); - - end - - Qb1b2 = 0.0; - if (EXPHI == 1) - begin - 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)); - else - dVjeVb2e1 = exp(- Vb2e1Vfe) / (1.0 + exp(- Vb2e1Vfe)); - - dVteVb2e1 = dVteVje * dVjeVb2e1 + `AJE; - dQteVb2e1 = (1.0 - XCJE) * CJE_TM * dVteVb2e1; - - dn0Vb2e1 = If0 * eVb2e1 * VtINV * (0.5 / sqrt(1.0 + f1)); - dQbeVb2e1 = 0.5 * Qb0 * q1Q * dn0Vb2e1; - - dQeVb2e1 = (Qe + Qe0) / (MTAU * Vt); - - Qb1b2 = 0.2 * Vb1b2 * (dQteVb2e1 + dQbeVb2e1 + dQeVb2e1); - - Qbc = Qbe_qs * `one_third + Qbc_qs; - Qbe = 2.0 * Qbe_qs * `one_third ; - end + + Qe0 = TAUE_T * IK_TM * pow(IS_TM / IK_TM, 1.0 / MTAU); + `expLin(tmpExp,Vb2e1 / (MTAU * Vt)) + + // Niu Q2, 2016, for fixing reverse VBE noise when KE=1, KC=1, + // Previous Qe_qs causes unphysically large noise correlation time constant tau_n + Qe_qs = Qe0 * tmpExp; + + Qepi0 = 4.0 * TEPI_T * Vt / RCV_TM; + Qepi = 0.5 * Qepi0 * xi_w * (p0star + pW + 2.0); + + Qex = TAUR_T * 0.5 * (Qb0 * nBex + Qepi0 * pWex) / (TAUB_T + TEPI_T); + XQex = 0.0; + + if (EXMOD == 1) begin + + Qex = Qex * (1.0 - XEXT); + Xg2 = 4.0 * eVbc3VDC; + XpWex = Xg2 / (1.0 + sqrt(1.0 + Xg2)); + XQex = 0.5 * Fex * XEXT * TAUR_T * + (Qb0 * XnBex + Qepi0 * XpWex) / (TAUB_T + TEPI_T); + + end + + Qb1b2 = 0.0; + if (EXPHI == 1) + begin + 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)); + else + dVjeVb2e1 = exp(- Vb2e1Vfe) / (1.0 + exp(- Vb2e1Vfe)); + + dVteVb2e1 = dVteVje * dVjeVb2e1 + `AJE; + dQteVb2e1 = (1.0 - XCJE) * CJE_TM * dVteVb2e1; + + dn0Vb2e1 = If0 * eVb2e1 * VtINV * (0.5 / sqrt(1.0 + f1)); + dQbeVb2e1 = 0.5 * Qb0 * q1Q * dn0Vb2e1; + + // Niu, Q2 2016. Modified to fix reverse VBE noise problem. + dQeVb2e1 = Qe_qs / (MTAU * Vt); + + Qb1b2 = 0.2 * Vb1b2 * (dQteVb2e1 + dQbeVb2e1 + dQeVb2e1); + + Qe = (1 - KE) * Qe_qs; + Qbe_qs_eff = Qbe_qs + KE * Qe_qs; + Qbc = XQB * Qbe_qs_eff + Qbc_qs; + Qbe = (1 - XQB) * Qbe_qs_eff; + + end else - begin + begin Qbe = Qbe_qs; Qbc = Qbc_qs; - end - + Qe = Qe_qs; + end -// Add branch current contributions - - // Static currents - I(c1, c2) <+ TYPE * Ic1c2; - I(c2, e1) <+ TYPE * In; - I(b1, e1) <+ TYPE * Ib1_s; + +// Add branch current contributions + + // Static currents + I(c1, c2) <+ TYPE * Ic1c2; + I(c2, e1) <+ TYPE * In; + I(b1, e1) <+ TYPE * Ib1_s; // begin RvdT, 28-10-2008, MXT504.8_alpha // contribution tunnel current added - I(b2, e1) <+ TYPE * (Ib1 + Ib2 - Izteb); + I(b2, e1) <+ TYPE * (Ib1 + Ib2 - Izteb); `ifdef SUBSTRATE - I(b1, s) <+ TYPE * Isub; - I(b, s) <+ TYPE * XIsub; - I(s, c1) <+ TYPE * Isf; + I(b1, s) <+ TYPE * Isub; + I(b, s) <+ TYPE * XIsub; + I(s, c1) <+ TYPE * Isf; `endif - I(b1, b2) <+ TYPE * Ib1b2; - I(b2, c2) <+ TYPE * (-1.0 * Iavl); - I(e, e1) <+ TYPE * Vee1 / RE_TM; - I(b, b1) <+ TYPE * Vbb1 / RBC_TM; + I(b1, b2) <+ TYPE * Ib1b2; + I(b2, c2) <+ TYPE * (-1.0 * Iavl); + I(e, e1) <+ TYPE * Vee1 / RE_TM; + I(b, b1) <+ TYPE * Vbb1 / RBC_TM; `ifdef SELFHEATING - // Electrical equivalent for the thermal network - I(dt) <+ V(dt) / RTH_Tamb_M; - I(dt) <+ ddt(CTH_M * V(dt)); - I(dt) <+ -1.0 * power; + // Electrical equivalent for the thermal network + I(dt) <+ V(dt) / RTH_Tamb_M; + I(dt) <+ ddt(CTH_M * V(dt)); + I(dt) <+ -1.0 * power_dis; `endif - - // Electrical equivalent for the correlated noise - I(noi, e1) <+ V(noi, e1); - cor_exp_1 = sqrt(1.0 + 2.0 * Gem) * V(noi,e1); - I(b2, e1) <+ cor_exp_1; - cor_exp_2 = (2.0 + 2.0 * Gem) / sqrt(1.0 + 2.0 * Gem) * V(noi, e1); - I(e1, c2) <+ cor_exp_2; - - // Dynamic currents - I(b2, e1) <+ ddt(TYPE * (Qte + Qbe + Qe)); - I(b1, e1) <+ ddt(TYPE * (Qte_s)); - I(b2, c2) <+ ddt(TYPE * (Qtc + Qbc + Qepi)); + + + // Dynamic currents + I(b2, e1) <+ ddt(TYPE * (Qte + Qbe + Qe)); + I(b1, e1) <+ ddt(TYPE * (Qte_s)); + I(b2, c2) <+ ddt(TYPE * (Qtc + Qbc + Qepi)); `ifdef SUBSTRATE - I(s, c1) <+ ddt(TYPE * Qts); + I(s, c1) <+ ddt(TYPE * Qts); `endif - I(b1, b2) <+ ddt(TYPE * Qb1b2); - I(b, e) <+ ddt(TYPE * CBEO_M * Vbe); - I(b, c) <+ ddt(TYPE * CBCO_M * Vbc); - - end // Currents and charges + I(b1, b2) <+ ddt(TYPE * Qb1b2); + I(b, e) <+ ddt(TYPE * CBEO_M * Vbe); + I(b, c) <+ ddt(TYPE * CBCO_M * Vbc); + +end // Currents and charges /* RvdT, Delft Univ. Tech. 03-12-2007. Distribution of parasitic collector resistance. -This construct supports the case +This construct supports the case RCBLI = 0.0 and or RCBLX = 0.0 . It is up to the compiler to adjust the circuit topology and perform a node-collapse in such cases. */ if (RCBLX > 0.0) - begin - I(b, c3) <+ TYPE * XIex; - I(c, c3) <+ TYPE * Vcc3 * GCCxx_TM ; - I(b, c3) <+ ddt(TYPE * (XQtex + XQex)); - if (RCBLI > 0.0) - begin - I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; - I(b1, c4) <+ TYPE * (Ib3 + Iex); - I(c3, c4) <+ TYPE * Vc3c4 * GCCex_TM ; - I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); - end - else - begin - V(c4, c1) <+ 0.0 ; - I(b1, c1) <+ TYPE * (Ib3 + Iex); - I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); - I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; - end - end +begin + I(b, c3) <+ TYPE * XIex; + I(c, c3) <+ TYPE * Vcc3 * GCCxx_TM ; + I(b, c3) <+ ddt(TYPE * (XQtex + XQex)); + if (RCBLI > 0.0) + begin + I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; + I(b1, c4) <+ TYPE * (Ib3 + Iex); + I(c3, c4) <+ TYPE * Vc3c4 * GCCex_TM ; + I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); + end + else + begin + V(c4, c1) <+ 0.0 ; + I(b1, c1) <+ TYPE * (Ib3 + Iex); + I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); + I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; + end +end else - begin - V(c3, c4) <+ 0 ; - if (RCBLI > 0.0) - begin - I(b, c4) <+ TYPE * XIex; - I(c, c4) <+ TYPE * Vcc3 * GCCxx_TM ; - I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; - I(b1, c4) <+ TYPE * (Ib3 + Iex); - I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); - I(b, c4) <+ ddt(TYPE * (XQtex + XQex)); - end - else - begin - I(b, c1) <+ TYPE * XIex; - I(c, c1) <+ TYPE * Vcc3 * GCCxx_TM ; - V(c4, c1) <+ 0.0 ; - I(b1, c1) <+ TYPE * (Ib3 + Iex); - I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); - I(b, c1) <+ ddt(TYPE * (XQtex + XQex)); - I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; - end - end - -// Noise sources - -`NOISE begin - - // Thermal noise - common = 4.0 * `KB * Tk; - powerREC = common / RE_TM; // Emitter resistance - powerRBC = common / RBC_TM; // Base resistance - // RvdT, 03-12-2007: distributed collector resistance - 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) * `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 -// 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); - - // Emitter-base sidewall current shot and 1/f noise - powerEBSCS = 2.0 * `QQ * abs(Ib1_s); - if (XIBI == 0) - powerEBSC1f = 0.0; - else - powerEBSC1f = KF_M * XIBI * pow((abs(Ib1_s / XIBI)), AF); - - // Reverse base current shot noise and 1/f noise - powerRBCS = 2.0 * `QQ * abs(Ib3); - powerRBC1f = KF_M * pow(abs(Ib3), AF); - - // Extrinsic current shot noise and 1/f noise - powerExCS = 2.0 * `QQ * abs(Iex); - powerExC1f = KF_M * (1 - (EXMOD * XEXT)) * - pow((abs(Iex) / (1 - (EXMOD * XEXT))), AF); - powerExCSMOD = 2.0 * `QQ * abs(XIex) * EXMOD; - if (XEXT == 0.0) - powerExC1fMOD = 0.0; - else - powerExC1fMOD = KF_M * EXMOD * XEXT * pow((abs(XIex) / XEXT), AF); - -`ifdef SUBSTRATE - // Substrate current shot noise (between nodes B1 and S, resp. B and S) - powerSubsCS_B1S = 2.0 * `QQ * abs(Isub); - powerSubsCS_BS = 2.0 * `QQ * abs(XIsub); -`endif - - - // Noise due to the avalanche - // twoqIavl = KAVL * 2.0 * `QQ * Iavl; - twoqIavl = KAVL*Gem*powerCCS; - powerCCS_A = powerCCS + twoqIavl * (3.0 + 2.0 * Gem - - (2.0 + 2.0 * Gem)*(2.0 + 2.0 * Gem)/(1.0 + 2.0 * Gem) ); - - // Add noise sources - I(e, e1) <+ white_noise(powerREC); // "emitter resistance" - I(b, b1) <+ white_noise(powerRBC); // "base resistance" - - I(b1, b2) <+ white_noise(powerRBV); // "variable baseresistance" - - I(noi, e1) <+ white_noise(twoqIavl); // "avalanche" - I(c2, e1) <+ white_noise(powerCCS_A); // "col_emi_shot" - I(b2, e1) <+ white_noise(powerFBCS); // "bas_emi_forw" - - I(b2, e1) <+ flicker_noise(powerFBC1fB1, 1); // "bas_emi_forw" - 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, 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" -`endif - -/* RvdT, Delft University of Technology 03-12-2007, -Noise voltage associated with distributed parasitic collector. -In case of vanishing resistance corresponding node -is not addressed: */ - - // RvdT, 31-01-2007: distributed collector resistance - -if (RCBLX > 0.0) - begin - if (RCBLI > 0.0) - begin /* all branches exist */ - I(c, c3) <+ white_noise(powerRCCxx); // "collector plug resistance" - I(c3, c4) <+ white_noise(powerRCCex); // "extrinsic collector BL resistance" - I(c4, c1) <+ white_noise(powerRCCin); // "intrinsic collector BL resistance" +begin + V(c3, c4) <+ 0 ; + if (RCBLI > 0.0) + begin + I(b, c4) <+ TYPE * XIex; + I(c, c4) <+ TYPE * Vcc3 * GCCxx_TM ; + I(c4, c1) <+ TYPE * Vc4c1 * GCCin_TM; + I(b1, c4) <+ TYPE * (Ib3 + Iex); + I(b1, c4) <+ ddt(TYPE * (Qtex + Qex)); + I(b, c4) <+ ddt(TYPE * (XQtex + XQex)); end - else - begin /* only Rcblx exists */ - I(c, c3) <+ white_noise(powerRCCxx); // "collector plug resistance" - I(c3, c1) <+ white_noise(powerRCCex); // "extrinsic collector BL resistance" + else + begin + I(b, c1) <+ TYPE * XIex; + I(c, c1) <+ TYPE * Vcc3 * GCCxx_TM ; + V(c4, c1) <+ 0.0 ; + I(b1, c1) <+ TYPE * (Ib3 + Iex); + I(b1, c1) <+ ddt(TYPE * (Qtex + Qex)); + I(b, c1) <+ ddt(TYPE * (XQtex + XQex)); + I(c3, c1) <+ TYPE * Vc3c4 * GCCex_TM ; end - end -else - begin - if (RCBLI > 0.0) - begin /* only Rcbli exists */ - I(c, c4) <+ white_noise(powerRCCxx); // "collector plug resistance" - I(c4, c1) <+ white_noise(powerRCCin); // "intrinsic collector BL resistance" - end - else - begin /* neither Rcblx nor Rcbli exists */ - I(c, c1) <+ white_noise(powerRCCxx); // "collector plug resistance" - end - end - - -end // Noise sources +end diff --git a/src/spicelib/devices/adms/mextram/admsva/frontdef.inc b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc index 23e418c11..68f3d7bd2 100644 --- a/src/spicelib/devices/adms/mextram/admsva/frontdef.inc +++ b/src/spicelib/devices/adms/mextram/admsva/frontdef.inc @@ -1,8 +1,13 @@ -// Front definitions +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. -`include "discipline.h" - -// Numerical, physical and model constants +// Front definitions + +`include "discipline.h" + +// Numerical, physical and model constants `define TEN_M40 1.0e-40 `define TEN_M07 1.0e-7 `define C2K 273.15 @@ -15,70 +20,111 @@ `define AJE 3.0 `define AJC 2.0 `define AJS 2.0 -`define VEXLIM 200.0 +`define VEXLIM 400.0 `define PI 3.1415926 // Desriptions and units `ifdef __VAMS_COMPACT_MODELING__ - `define OPP(nam,uni,des) (* desc="des", units="uni" *) real nam; - `define PAR(des,uni) (* desc="des", units="uni" *) parameter real - `define PAI(des,uni) (* desc="des", units="uni" *) parameter integer + `define OPP(nam,uni,des) (* desc="des", units="uni" *) real nam; + `define PAR(des,uni) (* desc="des", units="uni" *) parameter real + `define PAI(des,uni) (* desc="des", units="uni" *) parameter integer `else - `define OPP(nam,uni,des) - `define PAR(des,uni) parameter real - `define PAI(des,uni) parameter integer -`endif - -// ADMS specific definitions -`ifdef insideADMS - `define MODEL @(initial_model) - `define INSTANCE @(initial_instance) - `define NOISE @(noise) - `define ATTR(txt) (*txt*) -`else - `define MODEL - `define INSTANCE - `define NOISE - `define ATTR(txt) -`endif + `define OPP(nam,uni,des) + `define PAR(des,uni) parameter real + `define PAI(des,uni) parameter integer +`endif -// Smooth limitting functions +`define PGIVEN $param_given + +// ADMS specific definitions +`ifdef insideADMS + `define P(p) (*p*) + `define MODEL @(initial_model) + `define INSTANCE @(initial_instance) + `define NOISE @(noise) +`else + `define P(p) + `define MODEL + `define INSTANCE + `define NOISE +`endif + +// Smooth limitting functions `define max_hyp0(result, x, epsilon)\ - eps2 = epsilon * epsilon;\ - x2 = x * x;\ - if (x < 0.0)\ - result = 0.5 * eps2 / (sqrt(x2 + eps2) - x);\ - else\ - result = 0.5 * (sqrt(x2 + eps2) + x);\ - result=result - + eps2 = epsilon * epsilon;\ + x2 = x * x;\ + if (x < 0.0)\ + result = 0.5 * eps2 / (sqrt(x2 + eps2) - x);\ + else\ + result = 0.5 * (sqrt(x2 + eps2) + x);\ + result=result + `define min_logexp(result, x, x0, a)\ - dxa = (x - x0) / (a);\ - if (x < x0)\ - result = x - a * ln(1.0 + exp(dxa));\ - else\ - result = x0 - a * ln(1.0 + exp(-dxa));\ - result=result - + dxa = (x - x0) / (a);\ + if (x < x0)\ + result = x - a * ln(1.0 + exp(dxa));\ + else\ + result = x0 - a * ln(1.0 + exp(-dxa));\ + result=result + `define max_logexp(result, x, x0, a)\ - dxa = (x - x0) / (a);\ - if (x < x0)\ - result = x0 + a * ln(1.0 + exp(dxa));\ - else\ - result = x + a * ln(1.0 + exp(-dxa));\ - result=result - + dxa = (x - x0) / (a);\ + if (x < x0)\ + result = x0 + a * ln(1.0 + exp(dxa));\ + else\ + result = x + a * ln(1.0 + exp(-dxa));\ + result=result + `define expLin(result, x)\ - if (x < `VEXLIM)\ - result = exp(x);\ - else begin\ - expl = exp(`VEXLIM);\ - result = expl * (1.0 + (x - `VEXLIM));\ - end + if (x < `VEXLIM) begin\ + result = exp(x);\ + end else begin\ + expl = exp(`VEXLIM);\ + result = expl * (1.0 + (x - `VEXLIM));\ + end `define linLog(result, x, vlim)\ - if (x < vlim)\ - result = x;\ - else\ - result = vlim + ln(1.0 + (x - vlim));\ - result=result + if (x < vlim)\ + result = x;\ + else\ + result = vlim + ln(1.0 + (x - vlim));\ + result=result + +// Macros for the model/instance parameters +// +// MPRxx model parameter real +// MPIxx model parameter integer +// || +// cc closed lower bound, closed upper bound +// oo open lower bound, open upper bound +// co closed lower bound, open upper bound +// oc open lower bound, closed upper bound +// cz closed lower bound=0, open upper bound=inf +// oz open lower bound=0, open upper bound=inf +// nb no bounds +// ex no bounds with exclude +// sw switch(integer only, values 0=false and 1=true) +// ty switch(integer only, values -1=p-type and +1=n-type) +// +// +`define MPRnb(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def ; +`define MPRex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter real nam=def exclude exc ; +`define MPRcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr] ; +`define MPRoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr) ; +`define MPRco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from[lwr:upr) ; +`define MPRoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter real nam=def from(lwr:upr] ; +`define MPRcz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from[ 0:inf); +`define MPRoz(nam,def,uni, des) (*units=uni, desc=des*) parameter real nam=def from( 0:inf); + +`define MPInb(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def ; +`define MPIex(nam,def,uni,exc, des) (*units=uni, desc=des*) parameter integer nam=def exclude exc ; +`define MPIcc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr] ; +`define MPIoo(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr) ; +`define MPIco(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from[lwr:upr) ; +`define MPIoc(nam,def,uni,lwr,upr,des) (*units=uni, desc=des*) parameter integer nam=def from(lwr:upr] ; +`define MPIcz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0:inf); +`define MPIoz(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from( 0:inf); + +`define MPIsw(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ 0: 1] ; +`define MPIty(nam,def,uni, des) (*units=uni, desc=des*) parameter integer nam=def from[ -1: 1] exclude 0 ; + diff --git a/src/spicelib/devices/adms/mextram/admsva/initialize.inc b/src/spicelib/devices/adms/mextram/admsva/initialize.inc index 1b80c2949..4ec600711 100644 --- a/src/spicelib/devices/adms/mextram/admsva/initialize.inc +++ b/src/spicelib/devices/adms/mextram/admsva/initialize.inc @@ -1,74 +1,88 @@ -// Initialze model constants +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. - // Impact ionization constants (NPN - PNP) - -if (TYPE == 1) begin - - An = 7.03e7; - Bn = 1.23e8; - -end else begin - - An = 1.58e8; - Bn = 2.04e8; - -end - -Xext1 = 1.0 - XEXT; +if (`PGIVEN(GMIN)) + my_gmin = GMIN; +else + my_gmin = $simparam("gmin"); - // Temperature independent MULT scaling +// Initialize model constants + + // Impact ionization constants (NPN - PNP) + +if (TYPE == 1) begin + + An = 7.03e7; + Bn = 1.23e8; + +end else begin + + An = 1.58e8; + Bn = 2.04e8; + +end + +Xext1 = 1.0 - XEXT; + + // Temperature independent MULT scaling `ifdef SELFHEATING - CTH_M = CTH * MULT; + CTH_M = CTH * MULT; `endif - CBEO_M = CBEO * MULT; - CBCO_M = CBCO * MULT; +CBEO_M = CBEO * MULT; +CBCO_M = CBCO * MULT; - invMULT = 1.0 / MULT; - SCRCV_M = SCRCV * invMULT; +invMULT = 1.0 / MULT; +SCRCV_M = SCRCV * invMULT; - KF_M = KF * pow(MULT, 1.0 - AF); - KFN_M = KFN * pow(MULT, 1.0 - (2.0 * (MLF - 1.0) + AF * (2.0 - MLF))); +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 +// begin: RvdT, November 2008; Zener tunneling current model - pow2_2mPE = pow(2.0, 2.0 - PE); - pow2_PEm2 = 1.0 / pow2_2mPE; +pow2_2mPE = pow(2.0, 2.0 - PE); +pow2_PEm2 = 1.0 / pow2_2mPE; // Reference Temperature expressed in Kelvin: - Trk = TREF + `C2K; +Trk = TREF + `C2K; +// Ambient Temperature expressed in Kelvin: +Tamb = $temperature + DTA; -// begin: RvdT, November 2008 ; Zener tunneling current model + +// begin: RvdT, November 2008; Zener tunneling current model // -// Comment added March 2009: this assumes VGZEBOK as a model parameter. +// 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 +// 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: +// 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)); +//`max_logexp(VGZEBOK, VGZEB + AVGEB*Trk*Trk / (Trk + TVGEB), 0.05, 0.1); +//dw admsXml 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; +VGZEB_Tr = VGZEB; // end: RvdT March 2009: use VGZEB as a parameter, instead of VGZEBOK: - inv_VGZEB_Tr = 1.0 / VGZEB_Tr; +inv_VGZEB_Tr = 1.0 / VGZEB_Tr; - inv_VDE = 1.0 / VDE; +inv_VDE = 1.0 / VDE; + +// end: RvdT, November 2008; Zener tunneling current model -// end: RvdT, November 2008 ; Zener tunneling current model diff --git a/src/spicelib/devices/adms/mextram/admsva/noise.inc b/src/spicelib/devices/adms/mextram/admsva/noise.inc new file mode 100644 index 000000000..d6b960904 --- /dev/null +++ b/src/spicelib/devices/adms/mextram/admsva/noise.inc @@ -0,0 +1,145 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Noise sources + +`NOISE begin + + // Thermal noise + common = 4.0 * `KB * Tk; + powerREC = common / RE_TM; // Emitter resistance + powerRBC = common / RBC_TM; // Base resistance + 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) * `one_third ; // Variable base resistance + + // Main current shot noise + In_N = (If + Ir) / qBI; + powerCCS = 2.0 * `QQ * abs(In_N); + + // Weak-avalanche current shot noise + if (KAVL > 0) begin + Gem_N = abs(Iavl / In_N); + end else begin + Gem_N = 0.0; + end + + powerIIS = 2.0 * `QQ * Iavl * (Gem_N + 1); + + // Transit time for noise + if (In_N > 0.0) begin + Taub_N = (Qbe + Qbc) / In_N; + end else begin + Taub_N = TAUB_T * q1Q * qBI; + end + + // RF correlation noise model switch + if (KC == 1) begin + // use charge partition for noise transit time + taun = XQB * Taub_N; + end else if (KC == 2) begin + // use fraction of transit time for noise transit time + taun = FTAUN * Taub_N; + end else begin // KC == 0 + // no correlation noise + taun = 0; + end + + // Forward base current shot noise and 1/f 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); + + // Emitter-base sidewall current shot and 1/f noise + powerEBSCS = 2.0 * `QQ * abs(Ib1_s); + if (XIBI == 0) + powerEBSC1f = 0.0; + else + powerEBSC1f = KF_M * XIBI * pow((abs(Ib1_s / XIBI)), AF); + + // Reverse base current shot noise and 1/f noise + powerRBCS = 2.0 * `QQ * abs(Ib3); + powerRBC1f = KF_M * pow(abs(Ib3), AF); + + // Extrinsic current shot noise and 1/f noise + powerExCS = 2.0 * `QQ * abs(Iex); + powerExC1f = KF_M * (1 - (EXMOD * XEXT)) * + pow((abs(Iex) / (1 - (EXMOD * XEXT))), AF); + powerExCSMOD = 2.0 * `QQ * abs(XIex) * EXMOD; + if (XEXT == 0.0) + powerExC1fMOD = 0.0; + else + powerExC1fMOD = KF_M * EXMOD * XEXT * pow((abs(XIex) / XEXT), AF); + +`ifdef SUBSTRATE + // Substrate current shot noise (between nodes B1 and S, resp. B and S) + powerSubsCS_B1S = 2.0 * `QQ * abs(Isub); + powerSubsCS_BS = 2.0 * `QQ * abs(XIsub); +`endif + + // Reference un-correlated current shot noise sources + I(noi) <+ white_noise(powerCCS, "un-correlated current shot noise"); + I(noi) <+ V(noi); + + // Implementing correlated noise sources + I(b2, e1) <+ taun * ddt(V(noi)); + I(c2, b2) <+ Gem_N * V(noi); + I(c2, e1) <+ V(noi); + + // Implementing un-correlated noise sources + I(c2, b2) <+ white_noise(powerIIS, "un-correlated noise"); + I(b2, e1) <+ white_noise(powerFBCS, "un-correlated noise"); + + // Add noise sources + I(e, e1) <+ white_noise(powerREC, "emitter resistance"); + I(b, b1) <+ white_noise(powerRBC, "base resistance"); + I(b1, b2) <+ white_noise(powerRBV, "variable base resistance"); + I(b2, e1) <+ flicker_noise(powerFBC1fB1, 1, "bas_emi_forw"); + 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, 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"); +`endif + + if (RCBLX > 0.0) + begin + if (RCBLI > 0.0) + begin /* all branches exist */ + I(c, c3) <+ white_noise(powerRCCxx, "collector plug resistance"); + I(c3, c4) <+ white_noise(powerRCCex, "extrinsic collector BL resistance"); + I(c4, c1) <+ white_noise(powerRCCin, "intrinsic collector BL resistance"); + end + else + begin /* only Rcblx exists */ + I(c, c3) <+ white_noise(powerRCCxx, "collector plug resistance"); + I(c3, c1) <+ white_noise(powerRCCex, "extrinsic collector BL resistance"); + end + end + else + begin + if (RCBLI > 0.0) + begin /* only Rcbli exists */ + I(c, c4) <+ white_noise(powerRCCxx, "collector plug resistance"); + I(c4, c1) <+ white_noise(powerRCCin, "intrinsic collector BL resistance"); + end + else + begin /* neither Rcblx nor Rcbli exists */ + I(c, c1) <+ white_noise(powerRCCxx, "collector plug resistance"); + end + end + +end // Noise + diff --git a/src/spicelib/devices/adms/mextram/admsva/opinfo.inc b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc index 6b93b6b0a..21df4b289 100644 --- a/src/spicelib/devices/adms/mextram/admsva/opinfo.inc +++ b/src/spicelib/devices/adms/mextram/admsva/opinfo.inc @@ -1,31 +1,45 @@ -// Evaluate the operating point (outout) variables -begin +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Evaluate the operating point (output) variables +begin `ifdef __VAMS_COMPACT_MODELING__ + // 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 + +if (OP_ib == 0) + begin + OP_betadc = 0.0 ; + end +else + begin + OP_betadc = OP_ic / OP_ib; // External DC Current gain + end // begin added in MXT 504.9: -OP_ie = I(); // External DC emitter current +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 + 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 -OP_vb2c2 = Vb2c2; // Internal base-emiter bias +OP_vb2c2 = Vb2c2; // Internal base-emiter bias OP_vb2c1 = Vb2c1; // Internal base-collector bias including epilayer OP_vb1c1 = Vb1b2 + Vb2c1; // External base-collector bias without contact resistances @@ -42,7 +56,7 @@ 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: +// 504.8, RvdT, TU-Delft April. 2009: // OP_izteb = Izteb ; // Zener tunneling current // @@ -52,9 +66,9 @@ OP_iavl = Iavl; // Avalanche current OP_iex = Iex; // Extrinsic reverse base current OP_xiex = XIex; // Extrinsic reverse base current `ifdef SUBSTRATE -OP_isub = Isub; // Substrate current -OP_xisub = XIsub; // Substrate current -OP_isf = Isf; // Substrate-collector current + OP_isub = Isub; // Substrate current + OP_xisub = XIsub; // Substrate 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 @@ -70,14 +84,14 @@ OP_sqte = Qte_s; // Sidewall base-emiter depletion charge OP_qbe = Qbe; // Base-emiter diffusion charge OP_qbc = Qbc; // Base-collector diffusion charge OP_qtc = Qtc; // Base-colector depletion charge -OP_qepi = Qepi; // Epilayer diffusion charge +OP_qepi = Qepi; // Epilayer diffusion charge OP_qb1b2 = Qb1b2; // AC current crowding charge OP_qtex = Qtex; // Extrinsic base-collector depletion charge OP_xqtex = XQtex; // Extrinsic base-collector depletion charge OP_qex = Qex; // Extrinsic base-collector diffusion charge OP_xqex = XQex; // Extrinsic base-collector diffusion charge `ifdef SUBSTRATE -OP_qts = Qts; // Collector substrate depletion charge + OP_qts = Qts; // Collector substrate depletion charge `endif // Small signal equivalent circuit conductances and resistances @@ -125,13 +139,12 @@ 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-collector current + 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-collector current `endif - // Small signal equivalent circuit capacitances OP_scbe = - ddx(Qte_s, V(e)) - ddx(Qte_s, V(e1)); // Capacitance sidewall b-e junction @@ -148,12 +161,12 @@ OP_cbcy = - ddx(Qtc + Qbc + Qepi, V(c2)); // Capacitance floor b-c junction OP_cbcz = - ddx(Qtc + Qbc + Qepi, V(c1)); // Capacitance floor b-c junction // Capacitance extrinsic b-c junction : -OP_cbcex = ddx(Qtex + Qex,V(e)) - + ddx(Qtex + Qex,V(b1 )) - + ddx(Qtex + Qex,V(b2)) - + ddx(Qtex + Qex,V(e1)) +OP_cbcex = ddx(Qtex + Qex,V(e)) + + ddx(Qtex + Qex,V(b1 )) + + ddx(Qtex + Qex,V(b2)) + + ddx(Qtex + Qex,V(e1)) + ddx(Qtex + Qex,V(c2)) ; - + // Capacitance extrinsic b-c junction : OP_xcbcex = ddx(XQtex + XQex, V(b)) ; @@ -164,20 +177,20 @@ OP_cb1b2y = - ddx(Qb1b2, V(c2)); // Cross-capacitance AC current crowding OP_cb1b2z = - ddx(Qb1b2, V(c1)) ; // Cross-capacitance AC current crowding `ifdef SUBSTRATE -OP_cts = ddx(Qts, V(s)) ; // Capacitance s-c junction + OP_cts = ddx(Qts, V(s)) ; // Capacitance s-c junction `endif // Approximate small signal equivalent circuit dydx = (OP_gx - OP_gmux) / (OP_grcvy + OP_gmuy - OP_gy); dydz = (OP_gz - OP_grcvz - OP_gmuz) / (OP_grcvy + OP_gmuy - OP_gy); -gpi = OP_sgpi + OP_gpix + OP_gmux + OP_gpiz + OP_gmuz + +gpi = OP_sgpi + OP_gpix + OP_gmux + OP_gpiz + OP_gmuz + (OP_gpiy + OP_gmuy) * (dydx + dydz); OP_gm = (OP_grcvy * (OP_gx - OP_gmux + // Transconductance - OP_gz - OP_gmuz) - OP_grcvz * + OP_gz - OP_gmuz) - OP_grcvz * (OP_gy - OP_gmuy)) / (OP_grcvy + OP_gmuy - OP_gy); OP_beta = OP_gm / gpi; // Current amplification OP_gout = ((OP_gy - OP_gmuy) * OP_grcvz - // Output conductance - (OP_gz - OP_gmuz) * OP_grcvy) / + (OP_gz - OP_gmuz) * OP_grcvy) / (OP_grcvy + OP_gmuy - OP_gy); OP_gmu = OP_gpiz + OP_gmuz + (OP_gpiy + OP_gmuy) * dydz + // Feedback transconductance OP_gmuex + OP_xgmuex; @@ -208,7 +221,7 @@ rz = alpha_ft * rx; ry = (1.0 - OP_grcvz * rz) / OP_grcvy; rb1b2 = gammax * rx + gammay * ry + gammaz * rz; rex = rz + rb1b2 - OP_rcbli; -xrex = rex + RBC_TM * ((gbfx + OP_gmux) * rx + (gbfy + OP_gmuy) * ry + +xrex = rz + rb1b2 + RBC_TM * ((gbfx + OP_gmux) * rx + (gbfy + OP_gmuy) * ry + (gbfz + OP_gmuz) * rz) - OP_rcbli - OP_rcblx; taut = OP_scbe * (rx + rb1b2) + (OP_cbex + OP_cbcx) * rx + (OP_cbey + OP_cbcy) * @@ -222,7 +235,7 @@ OP_vb2c2star = Vb2c2star; // Physical value of internal base-collector b //self-heating `ifdef SELFHEATING -OP_pdiss = power; // Dissipation + OP_pdiss = power_dis; // Dissipation `endif OP_tk = Tk; // Actual temperature diff --git a/src/spicelib/devices/adms/mextram/admsva/opvars.inc b/src/spicelib/devices/adms/mextram/admsva/opvars.inc index f2f927a36..e892da1d6 100644 --- a/src/spicelib/devices/adms/mextram/admsva/opvars.inc +++ b/src/spicelib/devices/adms/mextram/admsva/opvars.inc @@ -1,3 +1,8 @@ +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + // // Operation point (output) variables // @@ -102,8 +107,8 @@ `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_gs, S, Conductance parasitic PNP transistor) +`OPP(OP_xgs, S, Conductance parasitic PNP transistor) `OPP(OP_gsf, S, Conductance substrate failure current) `endif //Small signal equivalent circuit capacitances @@ -149,4 +154,3 @@ real dydx, dydz, gpi; real gammax, gammay, gammaz, gbfx, gbfy, gbfz, alpha_ft; real rx, ry, rz, rb1b2, rex, xrex, taut; - diff --git a/src/spicelib/devices/adms/mextram/admsva/parameters.inc b/src/spicelib/devices/adms/mextram/admsva/parameters.inc index 2d83a9029..f6660f46b 100644 --- a/src/spicelib/devices/adms/mextram/admsva/parameters.inc +++ b/src/spicelib/devices/adms/mextram/admsva/parameters.inc @@ -1,209 +1,115 @@ -// Mextram parameters - -parameter integer LEVEL = 504 from [504:505) - `ATTR(info="Model level"); -parameter real TREF = 25.0 from [-273.0:inf) - `ATTR(info="Reference temperature"); -parameter real DTA = 0.0 - `ATTR(info="Difference between the local and global ambient temperatures"); -parameter integer EXMOD = 1 from [0:1] - `ATTR(info="Flag for extended modeling of the reverse current gain"); -parameter integer EXPHI = 1 from [0:1] - `ATTR(info="Flag for the distributed high-frequency effects in transient"); -parameter integer EXAVL = 0 from [0:1] - `ATTR(info="Flag for extended modeling of avalanche currents"); - -parameter real IS = 22.0a from (0.0:inf) - `ATTR(info="Collector-emitter saturation current"); -parameter real IK = 0.1 from [1.0p:inf) - `ATTR(info="Collector-emitter high injection knee current"); -parameter real VER = 2.5 from [0.01:inf) - `ATTR(info="Reverse Early voltage"); -parameter real VEF = 44.0 from [0.01:inf) - `ATTR(info="Forward Early voltage"); -parameter real BF = 215.0 from [0.1m:inf) - `ATTR(info="Ideal forward current gain"); -parameter real IBF = 2.7f from [0.0:inf) - `ATTR(info="Saturation current of the non-ideal forward base current"); -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) - `ATTR(info="Saturation current of the non-ideal reverse base current"); -parameter real VLR = 0.2 - `ATTR(info="Cross-over voltage of the non-ideal reverse base current"); -parameter real XEXT = 0.63 from [0.0:1.0] - `ATTR(info="Part of currents and charges that belong to extrinsic region"); - -parameter real WAVL = 1.1u from [1.0n:inf) - `ATTR(info="Epilayer thickness used in weak-avalanche model"); -parameter real VAVL = 3.0 from [0.01:inf) - `ATTR(info="Voltage determining curvature of avalanche current"); -parameter real SFH = 0.3 from [0.0:inf) - `ATTR(info="Current spreading factor of avalanche model when EXAVL=1"); -// RvdT, 22-02-2008: for MXT 504.7 -// increased lower clipping values RE, RBC, RBV, RCC, RCV, SCRCV -// from 1u to 1m: -parameter real RE = 5.0 from [1.0m:inf) - `ATTR(info="Emitter resistance"); -parameter real RBC = 23.0 from [1.0m:inf) - `ATTR(info="Constant part of the base resistance"); -parameter real RBV = 18.0 from [1.0m:inf) - `ATTR(info="Zero-bias value of the variable part of the base resistance"); -parameter real RCC = 12.0 from [1.0m:inf) - `ATTR(info="Constant part of the collector resistance"); -parameter real RCV = 150.0 from [1.0m:inf) - `ATTR(info="Resistance of the un-modulated epilayer"); -parameter real SCRCV = 1250.0 from [1.0m:inf) - `ATTR(info="Space charge resistance of the epilayer"); -parameter real IHC = 4.0m from [1.0p:inf) - `ATTR(info="Critical current for velocity saturation in the epilayer"); -parameter real AXI = 0.3 from [0.02:inf) - `ATTR(info="Smoothness parameter for the onset of quasi-saturation"); - -parameter real CJE = 73.0f from [0.0:inf) - `ATTR(info="Zero-bias emitter-base depletion capacitance"); -parameter real VDE = 0.95 from [0.05:inf) - `ATTR(info="Emitter-base diffusion voltage"); -parameter real PE = 0.4 from [0.01:0.99) - `ATTR(info="Emitter-base grading coefficient"); -parameter real XCJE = 0.4 from [0.0:1.0] - `ATTR(info="Sidewall fraction of the emitter-base depletion capacitance"); -parameter real CBEO = 0.0 from [0.0:inf) - `ATTR(info="Emitter-base overlap capacitance"); - -parameter real CJC = 78.0f from [0.0:inf) - `ATTR(info="Zero-bias collector-base depletion capacitance"); -parameter real VDC = 0.68 from [0.05:inf) - `ATTR(info="Collector-base diffusion voltage"); -parameter real PC = 0.5 from [0.01:0.99) - `ATTR(info="Collector-base grading coefficient"); -parameter real XP = 0.35 from [0.0:0.99) - `ATTR(info="Constant part of Cjc"); -parameter real MC = 0.5 from [0.0:1.0) - `ATTR(info="Coefficient for current modulation of CB depletion capacitance"); -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: -parameter real RCBLX = 0.0 from [0.0:inf) - `ATTR(info="Resistance Collector Buried Layer eXtrinsic"); -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"); - -parameter real MTAU = 1.0 from [0.1:inf) - `ATTR(info="Non-ideality factor of the emitter stored charge"); -parameter real TAUE = 2.0p from [0.0:inf) - `ATTR(info="Minimum transit time of stored emitter charge"); -parameter real TAUB = 4.2p from (0.0:inf) - `ATTR(info="Transit time of stored base sharge"); -parameter real TEPI = 41.0p from [0.0:inf) - `ATTR(info="Transit time of stored epilayer charge"); -parameter real TAUR = 520.0p from [0.0:inf) - `ATTR(info="Transit time of reverse extrinsic stored base charge"); - -parameter real DEG = 0.0 - `ATTR(info="Bandgap difference over the base"); -parameter real XREC = 0.0 from [0.0:inf) - `ATTR(info="Pre-factor of the recombination part of Ib1"); - -parameter real AQBO = 0.3 - `ATTR(info="Temperature coefficient of the zero-bias base charge"); -parameter real AE = 0.0 - `ATTR(info="Temperature coefficient of the resistivity of the emitter"); -parameter real AB = 1.0 - `ATTR(info="Temperature coefficient of the resistivity of the base"); -parameter real AEPI = 2.5 - `ATTR(info="Temperature coefficient of the resistivity of the epilayer"); -parameter real AEX = 0.62 - `ATTR(info="Temperature coefficient of the resistivity of the extrinsic base"); -parameter real AC = 2.0 - `ATTR(info="Temperature coefficient of the resistivity of the collector contact"); -// RvdT, 30-01-2007: introduced ACBL -parameter real ACBL = 2.0 from [0.0:inf) - `ATTR(info="Temperature coefficient of the resistivity of the collector buried layer"); -parameter real DVGBF = 50.0m - `ATTR(info="Band-gap voltage difference of the forward current gain"); -parameter real DVGBR = 45.0m - `ATTR(info="Band-gap voltage difference of the reverse current gain"); -parameter real VGB = 1.17 from [0.1:inf) - `ATTR(info="Band-gap voltage of the base"); -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 - `ATTR(info="Fine tuning of temperature dependence of C-E saturation current"); - -parameter real AF = 2.0 from [0.01:inf) - `ATTR(info="Exponent of the Flicker-noise"); -parameter real KF = 20.0p from [0.0:inf) - `ATTR(info="Flicker-noise coefficient of the ideal base current"); -parameter real KFN = 20.0p from [0.0:inf) - `ATTR(info="Flicker-noise coefficient of the non-ideal base current"); -parameter integer KAVL = 0 from [0:1] - `ATTR(info="Switch for white noise contribution due to avalanche"); +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. -`ifdef SUBSTRATE -parameter real ISS = 48.0a from [0.0:inf) - `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) - `ATTR(info="Zero-bias collector-substrate depletion capacitance"); -parameter real VDS = 0.62 from (0.05:inf) - `ATTR(info="Collector-substrate diffusion voltage"); -parameter real PS = 0.34 from (0.01:0.99) - `ATTR(info="Collector-substrate grading coefficient"); -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"); -parameter real ASUB = 2.0 - `ATTR(info="Temperature coefficient for mobility of minorities in the substrate"); +// Mextram parameters +`MPIco( LEVEL ,504 ,"" ,504 ,505 ,"Model level" ) +`MPRco( TREF ,25.0 ,"" ,-273.0 ,inf ,"Reference temperature" ) +`MPRnb( DTA ,0.0 ,"" ,"Difference between the local and global ambient temperatures" ) +`MPIcc( EXMOD ,1 ,"" ,0 ,2 ,"Flag for extended modeling of the reverse current gain" ) +`MPIcc( EXPHI ,1 ,"" ,0 ,1 ,"Flag for the distributed high-frequency effects in transient" ) +`MPIcc( EXAVL ,0 ,"" ,0 ,1 ,"Flag for extended modeling of avalanche currents" ) + +`ifdef SUBSTRATE +`MPIcc( EXSUB ,0 ,"" ,0 ,1 ,"Flag for extended modelling of substrate currents" ) `endif - + +`MPRoo( IS ,22.0a ,"" ,0.0 ,inf ,"Collector-emitter saturation current" ) +`MPRco( IK ,0.1 ,"" ,1.0p ,inf ,"Collector-emitter high injection knee current" ) +`MPRco( VER ,2.5 ,"" ,0.01 ,inf ,"Reverse Early voltage" ) +`MPRco( VEF ,44.0 ,"" ,0.01 ,inf ,"Forward Early voltage" ) +`MPRco( BF ,215.0 ,"" ,0.1m ,inf ,"Ideal forward current gain" ) +`MPRco( IBF ,2.7f ,"" ,0.0 ,inf ,"Saturation current of the non-ideal forward base current" ) +`MPRco( MLF ,2.0 ,"" ,0.1 ,inf ,"Non-ideality factor of the non-ideal forward base current" ) +`MPRcc( XIBI ,0.0 ,"" ,0.0 ,1.0 ,"Part of ideal base current that belongs to the sidewall" ) +`MPRco( IZEB ,0.0 ,"" ,0.0 ,inf ,"Pre-factor of emitter-base Zener tunneling current" ) +`MPRco( NZEB ,22.0 ,"" ,0.0 ,inf ,"Coefficient of emitter-base Zener tunneling current" ) +`MPRco( BRI ,7.0 ,"" ,1.0e-4 ,inf ,"Ideal reverse current gain" ) +`MPRco( IBR ,1.0f ,"" ,0.0 ,inf ,"Saturation current of the non-ideal reverse base current" ) +`MPRnb( VLR ,0.2 ,"" ,"Cross-over voltage of the non-ideal reverse base current" ) +`MPRcc( XEXT ,0.63 ,"" ,0.0 ,1.0 ,"Part of currents and charges that belong to extrinsic region" ) +`MPRco( WAVL ,1.1u ,"" ,1.0n ,inf ,"Epilayer thickness used in weak-avalanche model" ) +`MPRco( VAVL ,3.0 ,"" ,0.01 ,inf ,"Voltage determining curvature of avalanche current" ) +`MPRco( SFH ,0.3 ,"" ,0.0 ,inf ,"Current spreading factor of avalanche model when EXAVL=1" ) +`MPRco( RE ,5.0 ,"" ,1.0m ,inf ,"Emitter resistance" ) +`MPRco( RBC ,23.0 ,"" ,1.0m ,inf ,"Constant part of the base resistance" ) +`MPRco( RBV ,18.0 ,"" ,1.0m ,inf ,"Zero-bias value of the variable part of the base resistance" ) +`MPRco( RCC ,12.0 ,"" ,1.0m ,inf ,"Constant part of the collector resistance" ) +`MPRco( RCV ,150.0 ,"" ,1.0m ,inf ,"Resistance of the un-modulated epilayer" ) +`MPRco( SCRCV ,1250.0 ,"" ,1.0m ,inf ,"Space charge resistance of the epilayer" ) +`MPRco( IHC ,4.0m ,"" ,1.0p ,inf ,"Critical current for velocity saturation in the epilayer" ) +`MPRco( AXI ,0.3 ,"" ,0.02 ,inf ,"Smoothness parameter for the onset of quasi-saturation" ) +`MPRco( CJE ,73.0f ,"" ,0.0 ,inf ,"Zero-bias emitter-base depletion capacitance" ) +`MPRco( VDE ,0.95 ,"" ,0.05 ,inf ,"Emitter-base diffusion voltage" ) +`MPRco( PE ,0.4 ,"" ,0.01 ,0.99 ,"Emitter-base grading coefficient" ) +`MPRcc( XCJE ,0.4 ,"" ,0.0 ,1.0 ,"Sidewall fraction of the emitter-base depletion capacitance" ) +`MPRco( CBEO ,0.0 ,"" ,0.0 ,inf ,"Emitter-base overlap capacitance" ) +`MPRco( CJC ,78.0f ,"" ,0.0 ,inf ,"Zero-bias collector-base depletion capacitance" ) +`MPRco( VDC ,0.68 ,"" ,0.05 ,inf ,"Collector-base diffusion voltage" ) +`MPRco( PC ,0.5 ,"" ,0.01 ,0.99 ,"Collector-base grading coefficient" ) +`MPRco( XP ,0.35 ,"" ,0.0 ,0.99 ,"Constant part of Cjc" ) +`MPRco( MC ,0.5 ,"" ,0.0 ,1.0 ,"Coefficient for current modulation of CB depletion capacitance" ) +`MPRcc( XCJC ,32.0m ,"" ,0.0 ,1.0 ,"Fraction of CB depletion capacitance under the emitter" ) +`MPRco( RCBLX ,0.001 ,"" ,0.001 ,inf ,"Resistance Collector Buried Layer eXtrinsic" ) +`MPRco( RCBLI ,0.001 ,"" ,0.001 ,inf ,"Resistance Collector Buried Layer Intrinsic" ) +`MPRco( CBCO ,0.0 ,"" ,0.0 ,inf ,"Collector-base overlap capacitance" ) +`MPRco( MTAU ,1.0 ,"" ,0.1 ,inf ,"Non-ideality factor of the emitter stored charge" ) +`MPRco( TAUE ,2.0p ,"" ,0.0 ,inf ,"Minimum transit time of stored emitter charge" ) +`MPRoo( TAUB ,4.2p ,"" ,0.0 ,inf ,"Transit time of stored base charge" ) +`MPRco( TEPI ,41.0p ,"" ,0.0 ,inf ,"Transit time of stored epilayer charge" ) +`MPRco( TAUR ,520.0p ,"" ,0.0 ,inf ,"Transit time of reverse extrinsic stored base charge" ) +`MPRnb( DEG ,0.0 ,"" ,"Bandgap difference over the base" ) +`MPRco( XREC ,0.0 ,"" ,0.0 ,inf ,"Pre-factor of the recombination part of Ib1" ) +`MPRcc( XQB ,`one_third ,"" ,0.0 ,1.0 ,"Emitter-fraction of base diffusion charge" ) +`MPRnb( AQBO ,0.3 ,"" ,"Temperature coefficient of the zero-bias base charge" ) +`MPRnb( AE ,0.0 ,"" ,"Temperature coefficient of the resistivity of the emitter" ) +`MPRnb( AB ,1.0 ,"" ,"Temperature coefficient of the resistivity of the base" ) +`MPRnb( AEPI ,2.5 ,"" ,"Temperature coefficient of the resistivity of the epilayer" ) +`MPRnb( AEX ,0.62 ,"" ,"Temperature coefficient of the resistivity of the extrinsic base" ) +`MPRnb( AC ,2.0 ,"" ,"Temperature coefficient of the resistivity of the collector contact" ) +`MPRco( ACBL ,2.0 ,"" ,0.0 ,inf ,"Temperature coefficient of the resistivity of the collector buried layer" ) +`MPRnb( DVGBF ,50.0m ,"" ,"Band-gap voltage difference of the forward current gain" ) +`MPRnb( DVGBR ,45.0m ,"" ,"Band-gap voltage difference of the reverse current gain" ) +`MPRco( VGB ,1.17 ,"" ,0.1 ,inf ,"Band-gap voltage of the base" ) +`MPRco( VGC ,1.18 ,"" ,0.1 ,inf ,"Band-gap voltage of the collector" ) +`MPRco( VGJ ,1.15 ,"" ,0.1 ,inf ,"Band-gap voltage recombination emitter-base junction" ) +`MPRco( VGZEB ,1.15 ,"" ,0.1 ,inf ,"Band-gap voltage at Tref of Zener effect emitter-base junction" ) +`MPRoo( AVGEB ,4.73e-4 ,"" ,-inf ,inf ,"Temperature coefficient band-gap voltage for Zener effect emitter-base junction" ) +`MPRco( TVGEB ,636.0 ,"" ,0.0 ,inf ,"Temperature coefficient band-gap voltage for Zener effect emitter-base junction" ) +`MPRnb( DVGTE ,0.05 ,"" ,"Band-gap voltage difference of emitter stored charge" ) +`MPRnb( DAIS ,0.0 ,"" ,"Fine tuning of temperature dependence of C-E saturation current" ) +`MPRco( AF ,2.0 ,"" ,0.01 ,inf ,"Exponent of the Flicker-noise" ) +`MPRco( KF ,20.0p ,"" ,0.0 ,inf ,"Flicker-noise coefficient of the ideal base current" ) +`MPRco( KFN ,20.0p ,"" ,0.0 ,inf ,"Flicker-noise coefficient of the non-ideal base current" ) +`MPIcc( KAVL ,0 ,"" ,0 ,1 ,"Switch for white noise contribution due to avalanche" ) +`MPIcc( KC ,0 ,"" ,0 ,2 ,"Switch for RF correlation noise model selection" ) +`MPRcc( KE ,0.0 ,"" ,0.0 ,1.0 ,"Fraction of QE in excess phase shift" ) +`MPRcc( FTAUN ,0.0 ,"" ,0.0 ,1.0 ,"Fraction of noise transit time to total transit time" ) + +`ifdef SUBSTRATE +`MPRco( ISS ,48.0a ,"" ,0.0 ,inf ,"Base-substrate saturation current" ) +`MPRoo( ICSS ,-1.0 ,"" ,-inf ,inf ,"Collector-substrate ideal saturation current" ) +`MPRco( IKS ,250.0u ,"" ,1.0p ,inf ,"Base-substrate high injection knee current" ) +`MPRco( CJS ,315.0f ,"" ,0.0 ,inf ,"Zero-bias collector-substrate depletion capacitance" ) +`MPRoo( VDS ,0.62 ,"" ,0.05 ,inf ,"Collector-substrate diffusion voltage" ) +`MPRoo( PS ,0.34 ,"" ,0.01 ,0.99 ,"Collector-substrate grading coefficient" ) +`MPRco( VGS ,1.20 ,"" ,0.1 ,inf ,"Band-gap voltage of the substrate" ) +`MPRnb( AS ,1.58 ,"" ,"Substrate temperature coefficient" ) +`MPRnb( ASUB ,2.0 ,"" ,"Temperature coefficient for mobility of minorities in the substrate" ) +`endif + `ifdef SELFHEATING -parameter real RTH = 300.0 from (0.0:inf) - `ATTR(info="Thermal resistance"); -parameter real CTH = 3.0n from [0.0:inf) - `ATTR(info="Thermal capacitance"); -parameter real ATH = 0.0 - `ATTR(info="Temperature coefficient of the thermal resistance"); +`MPRoo( RTH ,300.0 ,"" ,0.0 ,inf ,"Thermal resistance" ) +`MPRco( CTH ,3.0n ,"" ,0.0 ,inf ,"Thermal capacitance" ) +`MPRnb( ATH ,0.0 ,"" ,"Temperature coefficient of the thermal resistance" ) `endif -parameter real MULT = 1.0 from (0.0:inf) - `ATTR(info="Multiplication factor"); - -// Non-standard (additional) model parameters -// (introduced for the users' convenience) - -`ifdef insideADMS -parameter integer TYPE = 1 from [-1:1] - `ATTR(info="Flag for NPN (1) or PNP (-1) transistor type"); -`else -parameter integer TYPE = 1 from [-1:1] exclude 0; -`endif -parameter real GMIN = 1.0e-13 from (0:1e-10] - `ATTR(info="Minimum conductance"); - +`MPRoo( MULT ,1.0 ,"" ,0.0 ,inf ,"Multiplication factor" ) +`MPIty( TYPE ,1 ,"" ,"Flag for NPN (1) or PNP (-1) transistor type" ) +`MPRoc( GMIN ,1.0e-13 ,"" ,0.0 ,1e-10 ,"Minimum conductance" ) + + + + + diff --git a/src/spicelib/devices/adms/mextram/admsva/tscaling.inc b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc index 345cfc32a..8e5519867 100644 --- a/src/spicelib/devices/adms/mextram/admsva/tscaling.inc +++ b/src/spicelib/devices/adms/mextram/admsva/tscaling.inc @@ -1,193 +1,188 @@ -// Temperature scaling of parameters - - // The excess transistor temperature due to the self-heating +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Temperature scaling of parameters + + // The excess transistor temperature due to the self-heating `ifdef SELFHEATING - Tki = V(dt); - // *** Convergence related smoothing *** - if (Tki < 0.0) begin - Tki = - ln(1.0 - Tki); - end - `linLog(Vdt, Tki, 200.0); -// `min_logexp(Vdt, Tki, 200.0, 10.0); + Tki = V(dt); + // *** Convergence related smoothing *** + if (Tki < 0.0) begin + Tki = - ln(1.0 - Tki); + end + `linLog(Vdt, Tki, 200.0); +// `min_logexp(Vdt, Tki, 200.0, 10.0); `else - Vdt = 0.0; + Vdt = 0.0; `endif - - // Temperature variables - -`ifdef insideADMS - Tk = Trk + DTA + Vdt; - Tamb = Trk + DTA; -`else - Tk = $temperature + DTA + Vdt; - Tamb = $temperature + DTA; -`endif - - tN = Tk / Trk; - Vt = `KBdivQQ * Tk; - Vtr = `KBdivQQ * Trk; - VtINV = 1.0 / Vt; - VtrINV = 1.0 / Vtr; - VdtINV = VtINV - VtrINV; + // Temperature variables +Tk = Tamb + Vdt; - lntN = ln(tN) ; +tN = Tk / Trk; +Vt = `KBdivQQ * Tk; +Vtr = `KBdivQQ * Trk; +VtINV = 1.0 / Vt; +VtrINV = 1.0 / Vtr; +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) ; +`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); - - UdcT = -3.0 * Vt * ln(tN) + VDC * tN + (1.0 - tN) * VGC; - `max_logexp(VDC_T, `VDLOW, UdcT, Vt); - -`ifdef SUBSTRATE - UdsT = -3.0 * Vt * ln(tN) + VDS * tN + (1.0 - tN) * VGS; - `max_logexp(VDS_T, `VDLOW, UdsT, Vt); -`endif - inv_VDE_T = 1.0 / VDE_T ; - CJE_T_div_CJE = pow(VDE * inv_VDE_T, PE); - CJE_T = CJE * CJE_T_div_CJE ; + // Depletion capacitances + +UdeT = -3.0 * Vt * ln(tN) + VDE * tN + (1.0 - tN) * VGB; +`max_logexp(VDE_T, `VDLOW, UdeT, Vt); + +UdcT = -3.0 * Vt * ln(tN) + VDC * tN + (1.0 - tN) * VGC; +`max_logexp(VDC_T, `VDLOW, UdcT, Vt); `ifdef SUBSTRATE - CJS_T = CJS * pow(VDS / VDS_T, PS); + UdsT = -3.0 * Vt * ln(tN) + VDS * tN + (1.0 - tN) * VGS; + `max_logexp(VDS_T, `VDLOW, UdsT, Vt); `endif - - CJCscale = ((1.0 - XP) * pow(VDC / VDC_T, PC) + XP); - CJCscaleINV = 1.0 / CJCscale; - - CJC_T = CJC * CJCscale; - XP_T = XP * CJCscaleINV; - - // Resistances +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); +`endif + +CJCscale = ((1.0 - XP) * pow(VDC / VDC_T, PC) + XP); +CJCscaleINV = 1.0 / CJCscale; + +CJC_T = CJC * CJCscale; +XP_T = XP * CJCscaleINV; + + // Resistances // 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); +// 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); +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 * exp(lntN * AC); - RCCex_T = RCBLX * exp(lntN * ACBL); - RCCin_T = RCBLI * exp(lntN * ACBL); +RCCxx_T = RCC * exp(lntN * AC); +RCCex_T = RCBLX * exp(lntN * ACBL); +RCCin_T = RCBLI * exp(lntN * ACBL); + +RCV_T = RCV * exp(lntN * AEPI); + +// Current gains + +BF_T = BF * exp(lntN * (AE - AB - AQBO)) * exp(-DVGBF * VdtINV); +BRI_T = BRI * exp(-DVGBR * VdtINV); + +// Currents and voltages + +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); - RCV_T = RCV * exp(lntN * AEPI); - - // Current gains - - BF_T = BF * exp(lntN * (AE - AB - AQBO)) * exp(-DVGBF * VdtINV); - BRI_T = BRI * exp(-DVGBR * VdtINV); - - // Currents and voltages - - 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); - // begin RvdT, November 2008, MXT504.8_alpha // T-scaling BE tunneling: // - x = pow(VGZEB_T * inv_VGZEB_Tr, -0.5) ; +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 ; +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 ; +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) ; +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; +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 * exp(lntN * (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); + 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 * exp(lntN * (1.0 - AS)) * (IS_T / IS) * (ISS / ISS_T); - else - IKS_T = IKS * exp(lntN * (1.0 - AS)); + if ((ISS_T > 0.0)) + IKS_T = IKS * exp(lntN * (1.0 - AS)) * (IS_T / IS) * (ISS / ISS_T); + else + IKS_T = IKS * exp(lntN * (1.0 - AS)); `endif - - // Transit times - - 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 - - Tk300 = Tk - 300.0; + + // Transit times + +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 + +Tk300 = Tk - 300.0; // RvdT, 15-02-2008: prevent division by zero and overflow at high temperatures: - if (Tk < 525.0) - begin - BnT = Bn * (1.0 + 7.2e-4 * Tk300 - 1.6e-6 * Tk300 * Tk300) ; - end - else - begin - BnT = Bn * 1.081 ; - end - - // Heterojunction features - - DEG_T = DEG * exp(lntN * AQBO); - +if (Tk < 525.0) +begin + BnT = Bn * (1.0 + 7.2e-4 * Tk300 - 1.6e-6 * Tk300 * Tk300) ; +end +else +begin + BnT = Bn * 1.081 ; +end + + // Heterojunction features + +DEG_T = DEG * exp(lntN * AQBO); + `ifdef SELFHEATING - // Tempearature scaling of the thermal resistance - - RTH_Tamb = RTH * pow(Tamb / Trk, ATH); + // Temperature scaling of the thermal resistance + + RTH_Tamb = RTH * pow(Tamb / Trk, ATH); `endif - -// MULT - scaling - - IS_TM = IS_T * MULT; - IK_TM = IK_T * MULT; - IBF_TM = IBF_T * MULT; - IBR_TM = IBR_T * MULT; + +// MULT - scaling + +IS_TM = IS_T * MULT; +IK_TM = IK_T * MULT; +IBF_TM = IBF_T * MULT; +IBR_TM = IBR_T * MULT; // RvdT: November 2008, Zener tunneling parameters - IZEB_TM = IZEB_T * MULT ; +IZEB_TM = IZEB_T * MULT ; -// end Zener tunneling parameters - +// end Zener tunneling parameters - - IHC_M = IHC * MULT; +IHC_M = IHC * MULT; `ifdef SUBSTRATE - ISS_TM = ISS_T * MULT; + ISS_TM = ISS_T * MULT; // New: 504.9 - ICSS_TM = ICSS_T * MULT; - IKS_TM = IKS_T * MULT; + 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: @@ -196,47 +191,47 @@ `ifdef SUBSTRATE - CJS_TM = CJS_T * MULT; + CJS_TM = CJS_T * MULT; `endif - - RE_TM = RE_T * invMULT; - RBC_TM = RBC_T * invMULT; - RBV_TM = RBV_T * invMULT; + +RE_TM = RE_T * invMULT; +RBC_TM = RBC_T * invMULT; +RBV_TM = RBV_T * invMULT; // RvdT, 30-01-2007: new collector resistances: - RCCxx_TM = RCCxx_T * invMULT; - RCCex_TM = RCCex_T * invMULT; - RCCin_TM = RCCin_T * invMULT; - RCV_TM = RCV_T * invMULT; - +RCCxx_TM = RCCxx_T * invMULT; +RCCex_TM = RCCex_T * invMULT; +RCCin_TM = RCCin_T * invMULT; +RCV_TM = RCV_T * invMULT; + // RvdT, 03-12-2007: new collector conductances - if (RCC > 0.0) - begin - GCCxx_TM = 1.0 / RCCxx_TM ; - end - else - begin - GCCxx_TM = 0 ; - end +if (RCC > 0.0) +begin + GCCxx_TM = 1.0 / RCCxx_TM ; +end +else +begin + GCCxx_TM = 0 ; +end - if (RCBLX > 0.0) - begin - GCCex_TM = 1.0 / RCCex_TM ; - end - else - begin - GCCex_TM = 0 ; - end +if (RCBLX > 0.0) +begin + GCCex_TM = 1.0 / RCCex_TM ; +end +else +begin + GCCex_TM = 0 ; +end - if (RCBLI > 0.0) - begin - GCCin_TM = 1.0 / RCCin_TM ; - end - else - begin - GCCin_TM = 0 ; - end +if (RCBLI > 0.0) +begin + GCCin_TM = 1.0 / RCCin_TM ; +end +else +begin + GCCin_TM = 0 ; +end `ifdef SELFHEATING - RTH_Tamb_M = RTH_Tamb * invMULT; + RTH_Tamb_M = RTH_Tamb * invMULT; `endif diff --git a/src/spicelib/devices/adms/mextram/admsva/variables.inc b/src/spicelib/devices/adms/mextram/admsva/variables.inc index 85c5d32da..2298390e2 100644 --- a/src/spicelib/devices/adms/mextram/admsva/variables.inc +++ b/src/spicelib/devices/adms/mextram/admsva/variables.inc @@ -1,30 +1,33 @@ -// Declaration of variables +// Copyright (c) 2000-2007, NXP Semiconductor +// Copyright (c) 2007-2014, Delft University of Technology +// Copyright (c) 2015, Auburn University +// All rights reserved, see IP_NOTICE_DISCLAIMER_LICENSE for further information. + +// Declaration of variables real _x, _x0, _a, _dxa; -real _circuit_gmin; +// Model constants -// Model constants - -real An, Bn; - -// Temperature scaling variables - -real Tk, Trk, tN, Tamb; -real Vt, Vtr, VtINV, VtrINV, VdtINV; +real An, Bn; + +// Temperature scaling variables + +real Tk, Trk, tN, Tamb; +real Vt, Vtr, VtINV, VtrINV, VdtINV; real Vdt; - -real UdeT, VDE_T, UdcT, VDC_T; -real CJE_T, CJC_T, XP_T; -real CJCscale, CJCscaleINV; - -real RE_T, RBV_T, RBC_T, RCV_T; + +real UdeT, VDE_T, UdcT, VDC_T; +real CJE_T, CJC_T, XP_T; +real CJCscale, CJCscaleINV; + +real RE_T, RBV_T, RBC_T, RCV_T; // RvdT: 30-01-2007, new collector resistances: 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; +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; @@ -33,129 +36,128 @@ 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 +// end Zener tunneling parameters + +real TAUE_T, TAUB_T, TEPI_T, TAUR_T; +real BnT, DEG_T, Tk300; -real TAUE_T, TAUB_T, TEPI_T, TAUR_T; -real BnT, DEG_T, Tk300; - `ifdef SELFHEATING -real RTH_Tamb; +real RTH_Tamb; `endif `ifdef SUBSTRATE -real UdsT, VDS_T, CJS_T, ISS_T, ICSS_T, IKS_T; +real UdsT, VDS_T, CJS_T, ISS_T, ICSS_T, IKS_T; `endif -// MULT - scaling variables - -real invMULT; +// MULT - scaling variables + +real invMULT; real IS_TM, IK_TM, IBF_TM, IBR_TM, IHC_M; // RvdT: November 2008, Zener tunneling parameters real IZEB_TM ; -// end Zener tunneling parameters +// end Zener tunneling parameters - -real CJE_TM, CJC_TM; - -real RE_TM, RBC_TM, RBV_TM, RCV_TM, SCRCV_M; + +real CJE_TM, CJC_TM; + +real RE_TM, RBC_TM, RBV_TM, RCV_TM, SCRCV_M; // RvdT: 30-01-2007, new collector resistances: real RCCxx_TM, RCCex_TM, RCCin_TM; // RvdT: 03-12-2007, new collector conductances: real GCCxx_TM, GCCex_TM, GCCin_TM; -real KF_M, KFN_M; +real KF_M, KFN_M; `ifdef SELFHEATING real RTH_Tamb_M, CTH_M; `endif - + `ifdef SUBSTRATE real ISS_TM, ICSS_TM, IKS_TM, CJS_TM; `endif -// Epilayer model variables - -real K0, Kw, pW, Ec, Ic1c2; -real Vqs_th, Vqs, Iqs; -real alpha, vyi, yi, xi_w, xi_w1; -real gp0, gp02, p0star, Vb2c2star, eVb2c2star; -real B1, B2, Vxi0, Vch, Icap, pav; - -// Effective emitter and collector junction bias variables - -real Vfe, Vje, Vte; -real Vjunc, bjc, Vfc, Vjc, fI, Vcv, Vtc; - -// Transfer current variables - -real If0, f1, f2, n0, nB; -real q0I, q1I, qBI, Ir, If, In; - -// Base and substrate current(s) variables - +// Epilayer model variables + +real K0, Kw, pW, Ec, Ic1c2; +real Vqs_th, Vqs, Iqs; +real alpha, vyi, yi, xi_w, xi_w1; +real gp0, gp02, p0star, Vb2c2star, eVb2c2star; +real B1, B2, Vxi0, Vch, Icap, pav; + +// Effective emitter and collector junction bias variables + +real Vfe, Vje, Vte; +real Vjunc, bjc, Vfc, Vjc, fI, Vcv, Vtc; + +// Transfer current variables + +real If0, f1, f2, n0, nB; +real q0I, q1I, qBI, Ir, If, In; + +// Base and substrate current(s) variables + real Xext1; -real Ib1, Ib1_s, Ib2, Ib3; -real Ibf0, Iex; -real g1, g2, pWex, nBex; -real Xg1, XnBex, XIMex, XIMsub, Vex, VBex, Fex, XIex; +real Ib1, Ib1_s, Ib2, Ib3; +real Ibf0, Iex; +real g1, g2, pWex, nBex; +real Xg1, XnBex, XIMex, XIMsub, Vex, VBex, Fex, XIex; `ifdef SUBSTRATE real Isub, XIsub, Isf; `endif - -// Distributed base effects variables - -real q0Q, q1Q, qBQ, Rb2, Ib1b2; -real dVteVb2e1, dVteVje, dVjeVb2e1; -real dQteVb2e1, dQbeVb2e1, dQeVb2e1; -real dn0Vb2e1; - -// Weak-avalanche current variables - -real dEdx0, xd, Weff, Wd, Eav, E0, Em, SHw, Efi, Ew; -real lambda, Gem, Gmax, Iavl; -real Icap_IHC; - + +// Distributed base effects variables + +real q0Q, q1Q, qBQ, Rb2, Ib1b2; +real dVteVb2e1, dVteVje, dVjeVb2e1; +real dQteVb2e1, dQbeVb2e1, dQeVb2e1; +real dn0Vb2e1; + +// Weak-avalanche current variables + +real dEdx0, xd, Weff, Wd, Eav, E0, Em, SHw, Efi, Ew; +real lambda, Gem, Gmax, Iavl; +real Icap_IHC; + `ifdef SELFHEATING -real Tki, power; +real Tki, power_dis; `endif - -// Charges and capacitances variables - -real Qte, Vje_s, Qte_s; -real Qtc; -real Qb0, Qbe, Qbc, Qb1b2; + +// Charges and capacitances variables + +real Qte, Vje_s, Qte_s; +real Qtc; +real Qb0, Qbe, Qbc, Qb1b2; real Qbe_qs, Qbc_qs; -real Vjcex, Vtexv, Qtex, XVjcex, XVtexv, XQtex; +real Vjcex, Vtexv, Qtex, XVjcex, XVtexv, XQtex; `ifdef SUBSTRATE -real Vfs, Vjs, Qts; +real Vfs, Vjs, Qts; `endif -real Qe0, Qe; -real Qepi0, Qepi, Xg2, XpWex, XQex; -real Qex; -real CBEO_M, CBCO_M; - -// Biases and exponential terms variables - +real Qe0, Qe; +real Qe_qs; +real Qepi0, Qepi, Xg2, XpWex, XQex; +real Qex; +real CBEO_M, CBCO_M; + +// Biases and exponential terms variables + real Vb2c1, Vb2c2, Vb2e1, Vb1e1, Vb1b2, Vb1c4, Vc1c2; -// RvdT, 30-01-2007: new variables Vc3c4, Vc4c1 real Vc3c4, Vc4c1; -// RvdT, 25-02-2008: new variables Vsc3, Vsc4 `ifdef SUBSTRATE -real Vsc1, Vsc3, Vsc4, eVsc1; +real Vsc1, Vsc3, Vsc4, eVsc1, eVsc3, eVsc4; `endif -real Vee1, Vbb1, Vbc3, Vcc3, Vbe, Vbc; -real eVb2c2, eVb2e1, eVb1e1, eVb1b2, eVb1c4, eVbc3; -real eVb1c4VDC, eVb2c2VDC, eVbc3VDC, eVb2c1VDC; - -// Help variables +real Vee1, Vbb1, Vbc3, Vcc3, Vbe, Vbc; +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 @@ -163,35 +165,37 @@ real lntN ; // RvdT, November 2008 variables for local use; may be re-used globally: real x, y ; - -real dxa, sqr_arg; -real eps2, x2; -real alpha1, vdif, Ic1c2_Iqs, gp0_help; -real EmEav_Em, Vb2e1Vfe, termE, termC; -real Vex_bias; -real eps_VDC, a_VDE, a_VDC; + +real dxa, sqr_arg; +real eps2, x2; +real alpha1, vdif, Ic1c2_Iqs, gp0_help; +real EmEav_Em, Vb2e1Vfe, termE, termC; +real Vex_bias; +real eps_VDC, a_VDE, a_VDC; real expl, tmpExp, tmpV; `ifdef SUBSTRATE -real a_VDS; +real a_VDS; `endif - -// Noise variables - -real common; -real powerREC, powerRBC, powerRCCxx, powerRCCex, powerRCCin, powerRBV; -real powerCCS; -real powerFBCS, powerFBC1fB1, exponentFBC1fB2, powerFBC1fB2; -real powerEBSCS, powerEBSC1f; -real powerRBCS, powerRBC1f; -real powerExCS, powerExCSMOD, powerExC1f, powerExC1fMOD; + +// Noise variables +real common; +real powerREC, powerRBC, powerRCCxx, powerRCCex, powerRCCin, powerRBV; +real powerCCS; +real powerFBCS, powerFBC1fB1, exponentFBC1fB2, powerFBC1fB2; +real powerEBSCS, powerEBSC1f; +real powerRBCS, powerRBC1f; +real powerExCS, powerExCSMOD, powerExC1f, powerExC1fMOD; +real powerIIS; `ifdef SUBSTRATE -real powerSubsCS_B1S, powerSubsCS_BS; +real powerSubsCS_B1S, powerSubsCS_BS; `endif -//real twoqIavl, powerCCS_A, powerFBCS_A, powerAVL_B2C2; -real twoqIavl, cor_exp_1, cor_exp_2, powerCCS_A; - +// noise correlation help variables +real In_N, Gem_N, Taub_N, taun, Qbe_qs_eff; + +real my_gmin; +