The MEXTRAM Bipolar Model level 504 in Verilog-A (Original Version 504.6)

This commit is contained in:
dwarning 2006-02-16 09:25:19 +00:00
parent 2afbcfd070
commit cf88f14383
8 changed files with 1145 additions and 0 deletions

View File

@ -0,0 +1,10 @@
Verilog-A implementation of the Philips Mextram (level 504.6) model.
Copyright (c) 2002-2005 Delft University of Technology (TUD).
All rights reserved.
Permission to modify the code and to distribute modified code is
granted, provided the file with the copyright notice is retained,
and a notice that the code was modified is included.

View File

@ -0,0 +1,35 @@
`include "frontdef.inc"
`define SUBSTRATE
module bjt504_va (c, b, e, s);
// External ports
inout c, b, e, s;
electrical e, b, c, s;
// Internal nodes
electrical e1, b1, b2, c1, c2;
electrical noi; // For correlated noise implementation
`include "parameters.inc"
`include "variables.inc"
analog begin
`ifdef insideADMS
@(initial_model) begin
`else
@(initial_step or initial_step("static")) begin
`endif
`include "initialize.inc"
`include "tscaling.inc"
end // initial_step
`include "evaluate.inc"
end // analog
endmodule

View File

@ -0,0 +1,519 @@
// 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);
Vb1c1 = TYPE * V(b1, c1);
Vbc1 = TYPE * V(b, c1);
`ifdef SUBSTRATE
Vsc1 = TYPE * V(s, c1);
`endif
Vc1c2 = TYPE * V(c1, c2);
Vee1 = TYPE * V(e, e1);
Vbb1 = TYPE * V(b, b1);
Vcc1 = TYPE * V(c, c1);
Vbe = TYPE * V(b, e);
Vbc = TYPE * V(b, c);
// Exponential bias terms
`expLin(eVb2c2,Vb2c2 * VtINV)
`expLin(eVb2e1,Vb2e1 * VtINV)
`expLin(eVb1e1,Vb1e1 * VtINV)
`expLin(eVb1c1,Vb1c1 * VtINV)
`expLin(eVb1b2,Vb1b2 * VtINV)
`expLin(eVbc1,Vbc1 * VtINV)
`ifdef SUBSTRATE
`expLin(eVsc1,Vsc1 * VtINV)
`endif
`expLin(eVbc1VDC,(Vbc1 - VDC_T) * VtINV)
`expLin(eVb1c1VDC,(Vb1c1 - 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);
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);
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);
Vte = VDE_T / (1.0 - PE) * (1.0 - pow(1.0 - Vje / VDE_T, 1.0 - PE)) +
`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) + GMIN * Vb2e1;
`expLin(tmpExp,0.5 * Vb1c1 * VtINV)
Ib3 = IBR_TM * (eVb1c1 - 1.0) /
(tmpExp + exp(0.5 * VLR * VtINV)) +
GMIN * Vb1c1;
// Iex, Isub (XIex, XIsub)
g1 = If0 * eVb1c1;
g2 = 4.0 * eVb1c1VDC;
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);
`ifdef SUBSTRATE
Isub = 2.0 * ISS_TM * (eVb1c1 - 1.0) /
(1.0 + sqrt(1.0 + 4.0 * (IS_TM / IKS_TM) * eVb1c1));
Isf = ISS_TM * (eVsc1 - 1.0);
`endif
XIex =0.0;
`ifdef SUBSTRATE
XIsub = 0.0;
`endif
if (EXMOD == 1) begin
Iex = Iex * Xext1;
`ifdef SUBSTRATE
Isub = Isub * Xext1;
`endif
Xg1 = If0 * eVbc1;
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 * (eVbc1 - 1.0) /
(1.0 + sqrt(1.0 + 4.0 * IS_T / IKS_T * eVbc1));
Vex_bias = XEXT * (IS_TM / BRI_T + ISS_TM) * RCC_TM;
`else
XIMsub = 0.0;
Vex_bias = XEXT * (IS_TM / BRI_T) * RCC_TM;
`endif
Vex = Vt * (2.0 - ln( Vex_bias * VtINV));
vdif = Vbc1 - Vex;
`max_hyp0(VBex, vdif, 0.11);
Fex = VBex /(Vex_bias + (XIMex + XIMsub) * RCC_TM + VBex);
XIex = Fex * XIMex;
`ifdef SUBSTRATE
XIsub = Fex * XIMsub;
`endif
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
`ifdef SELFHEATING
// Power dissipation
if (eVb2c2star > 0.0)
Vb2c2star = Vt * ln(eVb2c2star);
else
Vb2c2star = Vb2c2;
power = In * (Vb2e1 - Vb2c2star) +
Ic1c2 * (Vb2c2star - Vb2c1) -
Iavl * Vb2c2star +
Vee1 * Vee1 / RE_TM +
Vcc1 * Vcc1 / RCC_TM +
Vbb1 * Vbb1 / RBC_TM +
Ib1b2 * Vb1b2 +
(Ib1 + Ib2) * Vb2e1 +
Ib1_s * Vb1e1 +
`ifdef SUBSTRATE
(Iex + Isub + Ib3) * Vb1c1 +
(XIex + XIsub) * Vbc1 -
(XIsub + Isub - Isf) * Vsc1;
`else
(Iex + Ib3) * Vb1c1 + XIex * Vbc1;
`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 / 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, Vb1c1, Vfc, a_VDC);
Vtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - Vjcex / VDC_T, 1.0 - PC)) +
bjc * (Vb1c1 - Vjcex);
Qtex = CJC_TM * ((1.0 - XP_T) * Vtexv + XP_T * Vb1c1) *
(1.0 - XCJC) * (1.0 - XEXT);
`min_logexp(XVjcex, Vbc1, Vfc, a_VDC);
XVtexv = VDC_T / (1.0 - PC) * (1.0 - pow(1.0 - XVjcex / VDC_T, 1.0 - PC)) +
bjc * (Vbc1 - XVjcex);
XQtex = CJC_TM * ((1.0 - XP_T) * XVtexv + XP_T * Vbc1) *
(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));
`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 * eVbc1VDC;
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 / 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 / 3.0 + Qbc_qs;
Qbe = 2.0 * Qbe_qs / 3.0;
end
else
begin
Qbe = Qbe_qs;
Qbc = Qbc_qs;
end
// Add branch current contributions
// Static currents
I(c1, c2) <+ TYPE * Ic1c2;
I(c2, e1) <+ TYPE * In;
I(b1, e1) <+ TYPE * Ib1_s;
I(b2, e1) <+ TYPE * (Ib1 + Ib2);
I(b1, c1) <+ TYPE * (Ib3 + Iex);
I(b, c1) <+ TYPE * XIex;
`ifdef SUBSTRATE
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(c, c1) <+ TYPE * Vcc1 / RCC_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;
`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));
I(b1, c1) <+ ddt(TYPE * (Qtex + Qex));
I(b, c1) <+ ddt(TYPE * (XQtex + XQex));
`ifdef SUBSTRATE
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
// Noise sources
`NOISE begin
// Thermal noise
common = 4.0 * `KB * Tk;
powerREC = common / RE_TM; // Emitter resistance
powerRBC = common / RBC_TM; // Base resistance
powerRCC = common / RCC_TM; // Collector resistance
powerRBV = common / Rb2 * (4.0 * eVb1b2 + 5.0) / 3.0; // Variable base resistance
// Collector current shot noise
powerCCS = 2.0 * `QQ * (If + Ir) / qBI;
// Forward base current shot noise and 1/f noise
powerFBCS = 2.0 * `QQ * (abs(Ib1) + abs(Ib2));
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;
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(c, c1) <+ white_noise(powerRCC); // "collector 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, c1) <+ white_noise(powerRBCS); // "bas_col_reve"
I(b1, c1) <+ flicker_noise(powerRBC1f, 1); // "bas_col_reve"
I(b1, c1) <+ white_noise(powerExCS); // "Ext_bas_col"
I(b1, c1) <+ flicker_noise(powerExC1f, 1); // "Ext_bas_col"
I(b, c1) <+ white_noise(powerExCSMOD); // "Ext_bas_col"
I(b, c1) <+ flicker_noise(powerExC1fMOD, 1); // "Ext_bas_col"
`ifdef SUBSTRATE
I(b1, s) <+ white_noise(powerSubsCS_B1S); // "bas_sub_current"
I(b, s) <+ white_noise(powerSubsCS_BS); // "bas_sub_current"
`endif
end // Noise sources

View File

@ -0,0 +1,72 @@
// 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
`define KB 1.3806226e-23
`define QQ 1.6021918e-19
`define KBdivQQ 8.61708691805812512584e-5
`define VDLOW 0.05
`define AJE 3.0
`define AJC 2.0
`define AJS 2.0
`define VEXLIM 200.0
// 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
// 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
`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
`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
`define expLin(result, x)\
if (x < `VEXLIM)\
result = exp(x);\
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

View File

@ -0,0 +1,33 @@
// Initialze 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;
`endif
CBEO_M = CBEO * MULT;
CBCO_M = CBCO * MULT;
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)));

View File

@ -0,0 +1,183 @@
// 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");
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");
parameter real RE = 5.0 from [1.0u:inf)
`ATTR(info="Emitter resistance");
parameter real RBC = 23.0 from [1.0u:inf)
`ATTR(info="Constant part of the base resistance");
parameter real RBV = 18.0 from [1.0u:inf)
`ATTR(info="Zero-bias value of the variable part of the base resistance");
parameter real RCC = 12.0 from [1.0u:inf)
`ATTR(info="Constant part of the collector resistance");
parameter real RCV = 150.0 from [1.0u:inf)
`ATTR(info="Resistance of the un-modulated epilayer");
parameter real SCRCV = 1250.0 from [1.0u: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");
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 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 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");
`ifdef SUBSTRATE
parameter real ISS = 48.0a from [0.0:inf)
`ATTR(info="Base-substrate 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");
`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");
`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-12 from (0:1e-10]
`ATTR(info="Minimum conductance");

View File

@ -0,0 +1,139 @@
// 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);
`else
Vdt = 0.0;
`endif
// Temperature variables
Trk = TREF + `C2K;
`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;
// 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
CJE_T = CJE * pow(VDE / VDE_T, PE);
`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
RE_T = RE * pow(tN, AE);
RBV_T = RBV * pow(tN, AB - AQBO);
RBC_T = RBC * pow(tN, AEX);
RCC_T = RCC * pow(tN, AC);
RCV_T = RCV * pow(tN, AEPI);
// Current gains
BF_T = BF * pow(tN, AE - AB - AQBO) * exp(-DVGBF * VdtINV);
BRI_T = BRI * exp(-DVGBR * VdtINV);
// Currents and voltages
IS_T = IS * pow(tN, 4.0 - AB - AQBO + DAIS) * exp(-VGB * VdtINV);
IK_T = IK * pow(tN, 1.0 - AB);
IBF_T = IBF * pow(tN, 6.0 - 2.0 * MLF) * exp(-VGJ * VdtINV / MLF);
IBR_T = IBR * tN * tN * exp(-VGC * VdtINV / 2.0);
VEF_T = VEF * pow(tN, AQBO) * CJCscaleINV;
VER_T = VER * pow(tN, AQBO) * pow(VDE / VDE_T, -PE);
`ifdef SUBSTRATE
ISS_T = ISS * pow(tN, 4.0 - AS) * exp(-VGS * VdtINV);
if (ISS_T > 0.0)
IKS_T = IKS * pow(tN, 1.0 - AS) * (IS_T / IS) * (ISS / ISS_T);
else
IKS_T = IKS * pow(tN, 1.0 - AS);
`endif
// Transit times
TAUE_T = TAUE * pow(tN, AB - 2.0) * exp(-DVGTE * VdtINV);
TAUB_T = TAUB * pow(tN, AQBO + AB - 1.0);
TEPI_T = TEPI * pow(tN, AEPI - 1.0);
TAUR_T = TAUR * (TAUB_T + TEPI_T) / (TAUB + TEPI);
// Avalanche constant
Tk300 = Tk - 300.0;
BnT = Bn * (1.0 + 7.2e-4 * Tk300 - 1.6e-6 * Tk300 * Tk300);
// Heterojunction features
DEG_T = DEG * pow(tN, AQBO);
`ifdef SELFHEATING
// Tempearature 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;
IHC_M = IHC * MULT;
`ifdef SUBSTRATE
ISS_TM = ISS_T * MULT;
IKS_TM = IKS_T * MULT;
`endif
CJE_TM = CJE_T * MULT;
CJC_TM = CJC_T * MULT;
`ifdef SUBSTRATE
CJS_TM = CJS_T * MULT;
`endif
RE_TM = RE_T * invMULT;
RBC_TM = RBC_T * invMULT;
RBV_TM = RBV_T * invMULT;
RCC_TM = RCC_T * invMULT;
RCV_TM = RCV_T * invMULT;
`ifdef SELFHEATING
RTH_Tamb_M = RTH_Tamb * invMULT;
`endif

View File

@ -0,0 +1,154 @@
// Declaration of variables
// Model constants
real An, Bn;
// Temperature scaling variables
real Tk, Trk, tN, Tki, 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, RCC_T, RCV_T;
real BF_T, BRI_T;
real IS_T, IK_T, IBF_T, IBR_T, VEF_T, VER_T;
real TAUE_T, TAUB_T, TEPI_T, TAUR_T;
real BnT, DEG_T, Tk300;
`ifdef SELFHEATING
real RTH_Tamb;
`endif
`ifdef SUBSTRATE
real UdsT, VDS_T, CJS_T, ISS_T, IKS_T;
`endif
// MULT - scaling variables
real invMULT;
real IS_TM, IK_TM, IBF_TM, IBR_TM, IHC_M;
real CJE_TM, CJC_TM;
real RE_TM, RBC_TM, RBV_TM, RCC_TM, RCV_TM, SCRCV_M;
real KF_M, KFN_M;
`ifdef SELFHEATING
real RTH_Tamb_M, CTH_M;
`endif
`ifdef SUBSTRATE
real ISS_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, 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, Isub;
real g1, g2, pWex, nBex;
real Xg1, XnBex, XIMex, XIMsub, Vex, VBex, Fex, XIex;
`ifdef SUBSTRATE
real 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;
`ifdef SELFHEATING
real Vb2c2star, power;
`endif
// 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;
`ifdef SUBSTRATE
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 Vb2c1, Vb2c2, Vb2e1, Vb1e1, Vb1b2, Vb1c1, Vc1c2;
real Vsc1, Vee1, Vbb1, Vbc1, Vcc1, Vbe, Vbc;
real eVb2c2, eVb2e1, eVb1e1, eVb1b2, eVb1c1, eVbc1, eVsc1;
real eVb1c1VDC, eVb2c2VDC, eVbc1VDC, eVb2c1VDC;
// Help variables
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;
`endif
// Noise variables
real common;
real powerREC, powerRBC, powerRCC, powerRBV;
real powerCCS;
real powerFBCS, powerFBC1fB1, exponentFBC1fB2, powerFBC1fB2;
real powerEBSCS, powerEBSC1f;
real powerRBCS, powerRBC1f;
real powerExCS, powerExCSMOD, powerExC1f, powerExC1fMOD;
`ifdef SUBSTRATE
real powerSubsCS_B1S, powerSubsCS_BS;
`endif
//real twoqIavl, powerCCS_A, powerFBCS_A, powerAVL_B2C2;
real twoqIavl, cor_exp_1, cor_exp_2, powerCCS_A;