The HICUM Level0 Bipolar Model in Verilog-A (Original Version 1.1 - only VT0 changed to Vt0)

This commit is contained in:
dwarning 2006-02-16 09:22:06 +00:00
parent acfefe4da2
commit 2afbcfd070
1 changed files with 782 additions and 0 deletions

View File

@ -0,0 +1,782 @@
// HICUM Level_0: A Verilog-A description
// (A simplified version of HICUM Level2 model for BJT)
// ## It is modified after the first version of HICUM/L0 code ##
// Changed VT0 in Vt0 to prevent conflict in compiled C version. DW
//Default simulator: Spectre
`ifdef insideADMS
`define P(p) (*p*)
`define PGIVEN(p) $given(p)
`define INITIAL_MODEL @(initial_model)
`else
`define P(p)
`define PGIVEN(p) p
`define INITIAL_MODEL @(initial_step)
`endif
//ADS
//`include "constants.vams"
//`include "disciplines.vams"
//`include "compact.vams"
//Spectre
`include "constants.h"
`include "discipline.h"
`define NPN +1
`define PNP -1
`define EXPLIM 80.0
`define INF 1.0e6
`define TMAX 326.85
`define TMIN -100.0
// Depletion Charge and capacitance
// Use of ddx() operator would help omit this macro
`define QCJMOD(vj,cj0,vd,z,vpt,aj,qjf,cjf)\
if(cj0 > 0.0) begin\
zr = z/4.0;\
vp = vpt-vd;\
vf = vd*(1.0-exp(-ln(aj)/z));\
cmax = aj*cj0;\
cr = cj0*exp((z-zr)*ln(vd/vpt));\
a = VT;\
ve = (vf-vj)/a;\
if (ve <= `EXPLIM) begin\
ex1 = exp(ve);\
ee1 = 1.0+ex1;\
e1 = ex1/ee1;\
vj1 = vf-a*ln(ee1);\
end else begin\
e1 = 1.0;\
vj1 = vj;\
end\
a = 0.1*vp+4.0*VT;\
vr = (vp+vj1)/a;\
if (vr <= `EXPLIM) begin\
ex1 = exp(vr);\
ee1 = 1.0+ex1;\
e2 = ex1/ee1;\
vj2 = -vp+a*ln(ee1);\
end else begin\
e2 = 1.0;\
vj2 = vj1;\
end\
vj4 = vj-vj1;\
ez = 1.0-z;\
ezr = 1.0-zr;\
vdj1 = ln(1.0-vj1/vd);\
vdj2 = ln(1.0-vj2/vd);\
qj1 = cj0*(1.0-exp(vdj2*ez))/ez;\
qj2 = cr*(1.0-exp(vdj1*ezr))/ezr;\
qj3 = cr*(1.0-exp(vdj2*ezr))/ezr;\
qjf = (qj1+qj2-qj3)*vd+cmax*vj4;\
cj1 = cj0*exp(vdj2*(-z))*e1*e2;\
cj2 = cr*exp(vdj1*(-zr))*(1.0-e2);\
cj3 = cmax*(1.0-e1);\
cjf = cj1+cj2+cj3;\
end else begin\
qjf = 0.0;\
cjf = 0.0;\
end
// Depletion Charge
`define QJMOD(vj,cj0,vd,z,vpt,aj,qjf)\
if(cj0 > 0.0) begin\
zr = z/4.0;\
vp = vpt-vd;\
vf = vd*(1.0-exp(-ln(aj)/z));\
cmax = aj*cj0;\
cr = cj0*exp((z-zr)*ln(vd/vpt));\
a = VT;\
ve = (vf-vj)/a;\
if (ve <= `EXPLIM) begin\
ex1 = exp(ve);\
ee1 = 1.0+ex1;\
e1 = ex1/(ee1);\
vj1 = vf-a*ln(ee1);\
end else begin\
e1 = 1.0;\
vj1 = vj;\
end\
a = 0.1*vp+4.0*VT;\
vr = (vp+vj1)/a;\
if (vr <= `EXPLIM) begin\
ex1 = exp(vr);\
ee1 = 1.0+ex1;\
e2 = ex1/(ee1);\
vj2 = -vp+a*ln(ee1);\
end else begin\
e2 = 1.0;\
vj2 = vj1;\
end\
vj4 = vj-vj1;\
ez = 1.0-z;\
ezr = 1.0-zr;\
vdj1 = ln(1.0-vj1/vd);\
vdj2 = ln(1.0-vj2/vd);\
qj1 = cj0*(1.0-exp(vdj2*ez))/ez;\
qj2 = cr*(1.0-exp(vdj1*ezr))/ezr;\
qj3 = cr*(1.0-exp(vdj2*ezr))/ezr;\
qjf = (qj1+qj2-qj3)*vd+cmax*vj4;\
end else begin\
qjf = 0.0;\
end
//Temperature dependence of depletion capacitance parameters
`define TMPHICJ(cj0,vd,z,aj,vg,cj0_t,vd_t,aj_t)\
arg = 0.5*vd/Vt0;\
vdj0 = 2*Vt0*ln(exp(arg)-exp(-arg));\
vdjt = vdj0*qtt0+vg*(1-qtt0)-mg*VT*ln_qtt0;\
vd_t = vdjt+2*VT*ln(0.5*(1+sqrt(1+4*exp(-vdjt/VT))));\
cj0_t = cj0*exp(z*ln(vd/vd_t));\
aj_t = aj*vd_t/vd;
//Limiting exponential
`define LIN_EXP(le, arg)\
if(arg > 80) begin\
le = (1 + ((arg) - 80));\
arg = 80;\
end else begin\
le=1;\
end\
le = le*limexp(arg);
// IDEAL DIODE (WITHOUT CAPACITANCE):
// conductance not calculated
// INPUT:
// IS, IST : saturation currents (model parameter related)
// UM1 : ideality factor
// U : branch voltage
// IMPLICIT INPUT:
// VT : thermal voltage
// OUTPUT:
// Iz : diode current
`define HICDIO(IS,IST,UM1,U,Iz)\
DIOY = U/(UM1*VT);\
if (IS > 0.0) begin\
if (DIOY > 80) begin\
le = (1 + ((DIOY) - 80));\
DIOY = 80;\
end else begin\
le = 1;\
end\
le = le*limexp(DIOY);\
Iz = IST*(le-1.0);\
if(DIOY <= -14.0) begin\
Iz = -IST;\
end\
end else begin\
Iz = 0.0;\
end
module hic0_full (c,b,e,s);
//Node definitions
inout c,b,e,s;
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 ci `P(info="internal collector node");
electrical bi `P(info="internal base node");
electrical ei `P(info="internal emitter node");
electrical tnode `P(info="local temperature rise node");
branch (ci,c) irescx;
branch (ci,c) vrescx;
branch (ei,e) iresex;
branch (ei,e) vresex;
branch (b,bi) irescb;
branch (b,bi) vrescb;
//
// Parameter initialization with default values
// Collector current
parameter real is = 1.0e-16 from [0:1] `P(spice:name="is" info="(Modified) saturation current" m:factor="yes" unit="A");
parameter real mcf = 1.00 from (0:10] `P(spice:name="mcf" info="Non-ideality coefficient of forward collector current");
parameter real mcr = 1.00 from (0:10] `P(spice:name="mcr" info="Non-ideality coefficient of reverse collector current");
parameter real vef = `INF from (0:`INF] `P(spice:name="vef" info="forward Early voltage (normalization volt.)" unit="V" default:value="infinity");
parameter real iqf = `INF from (0:`INF] `P(spice:name="iqf" info="forward d.c. high-injection toll-off current" unit="A" m:factor="yes" default:value="infinity");
parameter real iqr = `INF from (0:`INF] `P(spice:name="iqr" info="inverse d.c. high-injection roll-off current" unit="A" m:factor="yes" default:value="infinity");
parameter real iqfh = `INF from (0:`INF] `P(spice:name="iqfh" info="high-injection correction current" unit="A" m:factor="yes");
parameter real tfh = `INF from (0:`INF] `P(spice:name="tfh" info="high-injection correction factor" test:value="2e-9" m:factor="yes");
// Base current
parameter real ibes = 1e-18 from [0:1] `P(spice:name="ibes" info="BE saturation current" unit="A" m:factor="yes");
parameter real mbe = 1.0 from (0:10] `P(spice:name="mbe" info="BE non-ideality factor");
parameter real ires = 0.0 from [0:1] `P(spice:name="ires" info="BE recombination saturation current" test:value="1e-16" unit="A" m:factor="yes");
parameter real mre = 2.0 from (0:10] `P(spice:name="mre" info="BE recombination non-ideality factor");
parameter real ibcs = 0.0 from [0:1] `P(spice:name="ibcs" info="BC saturation current" test:value="1e-16" unit="A" m:factor="yes");
parameter real mbc = 1.0 from (0:10] `P(spice:name="mbc" info="BC non-ideality factor");
// BE depletion cap
parameter real cje0 = 1.0e-20 from (0:`INF) `P(spice:name="cje0" info="Zero-bias BE depletion capacitance" unit="F" test:value="2e-14" m:factor="yes");
parameter real vde = 0.9 from (0:10] `P(spice:name="vde" info="BE built-in voltage" unit="V");
parameter real ze = 0.5 from (0:1] `P(spice:name="ze" info="BE exponent factor");
parameter real aje = 2.5 from [1:`INF) `P(spice:name="aje" info="Ratio of maximum to zero-bias value");
// Transit time
parameter real t0 = 0.0 from [0:`INF) `P(spice:name="t0" info="low current transit time at Vbici=0" test:value="5e-12" unit="s");
parameter real dt0h = 0.0; // from [0:`INF) `P(spice:name="dt0h" info="Base width modulation contribution" test:value="2e-12" unit="s");
parameter real tbvl = 0.0 from [0:`INF) `P(spice:name="tbvl" info="SCR width modulation contribution" test:value="4e-12" unit="s");
parameter real tef0 = 0.0 from [0:`INF) `P(spice:name="tef0" info="Storage time in neutral emitter" test:value="1e-12" unit="s");
parameter real gte = 1.0 from (0:10] `P(spice:name="gte" info="Exponent factor for emmiter transit time");
parameter real thcs = 0.0 from [0:`INF) `P(spice:name="thcs" info="Saturation time at high current densities" test:value="3e-11" unit="s");
parameter real ahc = 0.1 from (0:10] `P(spice:name="ahc" info="Smoothing facor for current dependence");
parameter real tr = 0.0 from [0:`INF) `P(spice:name="tr" info="Storage time at inverse operation" unit="s");
// Critical current
parameter real rci0 = 150 from (0:`INF) `P(spice:name="rci0" info="Low-field collector resistance under emitter" test:value="50" unit="Ohm" m:inverse_factor="yes");
parameter real vlim = 0.5 from (0:10] `P(spice:name="vlim" info="Voltage dividing ohmic and satur.region" unit="V");
parameter real vpt = 100 from (0:100] `P(spice:name="vpt" info="Punch-through voltage" test:value="10" unit="V" default="infinity");
parameter real vces = 0.1 from [0:1] `P(spice:name="vces" info="Saturation voltage" unit="V");
// BC depletion cap intern
parameter real cjci0 = 1.0e-20 from (0:`INF) `P(spice:name="cjci0" info="Total zero-bias BC depletion capacitance" test:value="1e-15" unit="F" m:factor="yes");
parameter real vdci = 0.7 from (0:10] `P(spice:name="vdci" info="BC built-in voltage" test:value="0.7" unit="V");
parameter real zci = 0.333 from (0:1] `P(spice:name="zci" info="BC exponent factor" test:value="0.4");
parameter real vptci = 100 from (0:100] `P(spice:name="vptci" info="Punch-through voltage of BC junction" test:value="50" unit="V");
// BC depletion cap extern
parameter real cjcx0 = 1.0e-20 from [0:`INF) `P(spice:name="cjcx0" info="Zero-bias external BC depletion capacitance" unit="F" test:value="1e-15" m:factor="yes");
parameter real vdcx = 0.7 from (0:10] `P(spice:name="vdcx" info="External BC built-in voltage" unit="V");
parameter real zcx = 0.333 from (0:1] `P(spice:name="zcx" info="External BC exponent factor");
parameter real vptcx = 100 from (0:100] `P(spice:name="vptcx" info="Punch-through voltage" unit="V" test:value="5.0" default="infinity");
parameter real fbc = 1.0 from [0:1] `P(spice:name="fbc" info="Split factor = Cjci0/Cjc0" test:value="0.5");
// Base resistance
parameter real rbi0 = 0.0 from [0:`INF) `P(spice:name="rbi0" info="Internal base resistance at zero-bias" test:value="100" unit="Ohm" m:inverse_factor="yes");
parameter real vr0e = 2.5 from (0:`INF] `P(spice:name="vr0e" info="forward Early voltage (normalization volt.)" unit="V");
parameter real vr0c = `INF from (0:`INF] `P(spice:name="vr0c" info="forward Early voltage (normalization volt.)" unit="V" default="infinity" test:value="25.0");
parameter real fgeo = 0.656 from [0:1] `P(spice:name="fgeo" info="Geometry factor" test:value="0.73");
// Series resistances
parameter real rbx = 0.0 from [0:`INF) `P(spice:name="rbx" info="External base series resistance" test:value="8.8" unit="Ohm" m:inverse_factor="yes");
parameter real rcx = 0.0 from [0:`INF) `P(spice:name="rcx" info="Emitter series resistance" test:value="12.5" unit="Ohm" m:inverse_factor="yes");
parameter real re = 0.0 from [0:`INF) `P(spice:name="re" info="External collector series resistance" test:value="9.16" unit="Ohm" m:inverse_factor="yes");
// Substrate diode current and cap
parameter real iscs = 0.0 from [0:1.0] `P(spice:name="iscs" info="SC saturation current" unit="A" test:value="1e-17" m:factor="yes");
parameter real msc = 1.0 from (0:10] `P(spice:name="msc" info="SC non-ideality factor");
parameter real cjs0 = 1.0e-20 from [0:`INF) `P(spice:name="cjs0" info="Zero-bias SC depletion capacitance" unit="F" test:value="1e-15" m:factor="yes");
parameter real vds = 0.3 from (0:10] `P(spice:name="vds" info="SC built-in voltage" unit="V");
parameter real zs = 0.3 from (0:1] `P(spice:name="zs" info="External SC exponent factor");
parameter real vpts = 100 from (0:100] `P(spice:name="vpts" info="SC punch-through voltage" unit="V" test:value="5.0" default="infinity");
// Parasitic caps
parameter real cbcpar = 0.0 from [0:`INF) `P(spice:name="cbcpar" info="Collector-base isolation (overlap) capacitance" unit="F" m:factor="yes" test:value="1e-15");
parameter real cbepar = 0.0 from [0:`INF) `P(spice:name="cbepar" info="Emitter-base oxide capacitance" unit="F" m:factor="yes" test:value="2e-15");
// BC avalanche current
parameter real eavl = 0.0 from [0:inf) `P(spice:name="eavl" info="Exponent factor" test:value="1e-14");
parameter real kavl = 0.0 from [0:`INF) `P(spice:name="kavl" info="Prefactor" test:value="1.19");
// Flicker noise
parameter real kf = 0.0 from [0:`INF) `P(spice:name="kf" info="flicker noise coefficient" unit="M^(1-AF)");
parameter real af = 2.0 from (0:10] `P(spice:name="af" info="flicker noise exponent factor");
// Temperature dependance
parameter real vgb = 1.2 from (0:10] `P(spice:name="vgb" info="Bandgap-voltage" unit="V" test:value="1.17");
parameter real vge = 1.17 from (0:10] `P(spice:name="vge" info="Effective emitter bandgap-voltage" unit="V" test:value="1.07");
parameter real vgc = 1.17 from (0:10] `P(spice:name="vgc" info="Effective collector bandgap-voltage" unit="V" test:value="1.14");
parameter real vgs = 1.17 from (0:10] `P(spice:name="vgs" info="Effective substrate bandgap-voltage" unit="V" test:value="1.17");
parameter real f1vg =-1.02377e-4 `P(spice:name="f1vg" info="Coefficient K1 in T-dependent bandgap equation" unit="V/K");
parameter real f2vg = 4.3215e-4 `P(spice:name="f2vg" info="Coefficient K2 in T-dependent bandgap equation" unit="V/K");
parameter real alt0 = 0.0 `P(spice:name="alt0" info="Frist-order TC of tf0" unit="1/K");
parameter real kt0 = 0.0 `P(spice:name="kt0" info="Second-order TC of tf0" unit="1/K^2");
parameter real zetact = 3.0 `P(spice:name="zetact" info="Exponent coefficient in transfer current temperature dependence" test:value="3.5");
parameter real zetabet = 3.5 `P(spice:name="zetabet" info="Exponent coefficient in BE junction current temperature dependence" test:value="4.0");
parameter real zetaci = 0.0 `P(spice:name="zetaci" info="TC of epi-collector diffusivity" test:value="1.6");
parameter real alvs = 0.0 `P(spice:name="alvs" info="Relative TC of satur.drift velocity" unit="1/K" test:value="1e-3");
parameter real alces = 0.0 `P(spice:name="alces" info="Relative TC of vces" unit="1/K" test:value="4e-4");
parameter real zetarbi = 0.0 `P(spice:name="zetarbi" info="TC of internal base resistance" test:value="0.6");
parameter real zetarbx = 0.0 `P(spice:name="zetarbx" info="TC of external base resistance" test:value="0.2");
parameter real zetarcx = 0.0 `P(spice:name="zetarcx" info="TC of external collector resistance" test:value="0.2");
parameter real zetare = 0.0 `P(spice:name="zetare" info="TC of emitter resistances");
parameter real alkav = 0.0 `P(spice:name="alkav" info="TC of avalanche prefactor" unit="1/K");
parameter real aleav = 0.0 `P(spice:name="aleav" info="TC of avalanche exponential factor" unit="1/K");
// Self-heating
parameter real rth = 0.0 from [0:`INF) `P(spice:name="rth" info="Thermal resistance" test:value="200.0" unit="K/W" m:inverse_factor="yes");
parameter real cth = 0.0 from [0:`INF) `P(spice:name="cth" info="Thermal capacitance" test:value="0.1" unit="Ws/K" m:factor="yes");
// Transistor type
parameter integer npn = 1 from [0:1] `P(spice:isflag="yes" info="model type flag for npn" );
parameter integer pnp = 0 from [0:1] `P(info="model type flag for pnp" );
//Circuit simulator specific parameters
parameter real tnom = 27 `P(spice:name="tnom" info="Temperature for which parameters are valid" unit="C");
parameter real dt = 0.0 `P(spice:name="dt" type="instance" info="Temperature change for particular transistor" unit="K");
// Declaration of the variables: begin
real HICUMtype `P(spice:name="type" info="Device type from npn or pnp flags" unit="no" ask="yes");
// QCJMOD
real cj0,vd,z,aj;
real zr,vp;
real cmax,cr,ve;
real ee1,ez,ezr,vdj1,vdj2,ex1,vr,vj1,vj2,vj4;
real qj1,qj2,qj3,qjf;
//Cjfun *** VT, removed: BA
real cj1,cj2,cj3,cjf;
//cjtfun *** tnom,VT,mg,Vt0, removed: BA
real vg;
real vdj0,vdjt,cj0_t,vd_t,aj_t;
// temperature and drift
real VT,Tamb,Tdev,Tnom,dT,qtt0,ln_qtt0;
real vde_t,vdci_t,vdcx_t,vds_t;
real is_t,ires_t,ibes_t,ibcs_t;
real iscs_t,cje0_t,cjci0_t,cjcx0_t;
real cjs0_t,rci0_t,vlim_t;
real vces_t,thcs_t,tef0_t,rbi0_t;
real rbx_t,rcx_t,re_t,t0_t,eavl_t,kavl_t;
real aje_t,ajci_t,ajcx_t,ajs_t;
// bc charge and cap
real qjci `P(ask="yes" info="B-C internal junction charge" unit="C");
real qjcx,qjcii,cjcii,qjcxi,qjciii; //cjcx
real cjci0_t_ii,cjcx0_t_ii,cjcx0_t_i;
// be junction
real qjei `P(ask="yes" info="B-E internal junction charge" unit="C");
real cjei `P(ask="yes" info="B-E internal junction capacitance" unit="F");
real vf,vj,x,y,e1,e2;
// transfer and internal base current
real cc,qj_2,facl;
real tf0,ickf,ickr,itfi,itri,qm;
real qpt,itf,itr;
real it `P(ask="yes" info="Transfer Current" unit="A");
real ibe,ire,ibi;
real itfl,itrl,al,s3l,wl,d_qfh;
// be diffusion charge
real qf,qf0,dqfh,dqef;
real dtef,dtfh,tf,ick;
real vc,vceff,s3,w,a,tww;
// bc diffusion charge
real qr;
// avalanche current source
real v_bord,a_iavl,lncc;
// base resistance
real rb,ri,eta,fac_ri,rbi,qje;
// substrate diode and cap
real qjs;
// self heating
real pterm;
// new for temperature dependence
real mg,zetabci,zetasct,zetatef,avs;
real k1,k2,vgbe,vgbc,vgsc,dvg;
real xvf,xvf2,dvj,uvc,Vt0;
// noise
real flicker_Pwr,fourkt,twoq;
// LIN_EXP
real le,arg,le1,arg1,le2,arg2;
//HICDIO
real IS,IST,UM1,U,Iz,DIOY;
// branch voltages
real Vbci,Vbici,Vbiei,Vciei,Vsci,Veie,Vbbi,Vcic,Vbe,Vrth, Vrth_ext;
//Output to be seen
real ijbc `P(ask="yes" info="Base-collector diode current" unit="A");
real iavl `P(ask="yes" info="Avalanche current" unit="A");
real ijsc `P(ask="yes" info="Substrate-collector diode current" unit="A");
real Ieei `P(ask="yes" info="Current through external to internal emitter node" unit="A");
real Icci `P(ask="yes" info="Current through external to internal collector node" unit="A");
real Ibbi `P(ask="yes" info="Current through external to internal base node" unit="A");
real Ibici `P(ask="yes" info="Base-collector diode current minus the avalanche current" unit="A");
real ijbe `P(ask="yes" info="Base-emitter diode current" unit="A");
real Qbci,Qbe,Qbici,Qbiei;
//Declaration of the variables: end
//
//======================== calculation of the transistor ===================
//
analog begin
// assign voltages with regard to transistor type
`INITIAL_MODEL
begin
if (`PGIVEN(npn))
HICUMtype = `NPN;
else if (`PGIVEN(pnp))
HICUMtype = `PNP;
else
HICUMtype = `NPN;
end
Vbci = HICUMtype*V(b,ci);
Vbici = HICUMtype*V(bi,ci);
Vbiei = HICUMtype*V(bi,ei);
Vciei = HICUMtype*V(ci,ei);
Vsci = HICUMtype*V(s,ci);
Veie = V(vresex);
Vcic = V(vrescx);
Vbbi = V(vrescb);
Vbe = HICUMtype*V(b,e);
Vrth = V(tnode);
//
// temperature and resulting parameter drift
//
Tnom = tnom+273.15;
Tamb = $temperature;
Tdev = Tamb+dt+Vrth; // selfheating instead dT later possible
// Limit temperature to avoid FPE's in equations
if(Tdev < `TMIN + 273.15)
Tdev = `TMIN + 273.15;
else
if (Tdev > `TMAX + 273.15)
Tdev = `TMAX + 273.15;
Vt0 = `P_K*Tnom /`P_Q;
VT = `P_K*Tdev /`P_Q;
dT = Tdev-Tnom;
qtt0 = Tdev/Tnom;
ln_qtt0 = ln(qtt0);
k1 = f1vg*Tnom;
k2 = f2vg*Tnom+k1*ln(Tnom);
avs = alvs*Tnom;
vgbe = (vgb+vge)/2;
vgbc = (vgb+vgc)/2;
vgsc = (vgs+vgc)/2;
mg = 3-`P_Q*f1vg/`P_K;
zetabci = mg+1-zetaci;
zetasct = mg-1.5; //+1-m_upS with m_upS=2.5
is_t = is*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1));
ibes_t = ibes*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1));
ires_t = ires*exp(0.5*mg*ln_qtt0+0.5*vgbe/VT*(qtt0-1));
ibcs_t = ibcs*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1));
iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1));
`TMPHICJ(cje0,vde,ze,aje,vgbe,cje0_t,vde_t,aje_t)
`TMPHICJ(cjci0,vdci,zci,2.4,vgbc,cjci0_t,vdci_t,ajci_t)
`TMPHICJ(cjcx0,vdcx,zcx,2.4,vgbc,cjcx0_t,vdcx_t,ajcx_t)
`TMPHICJ(cjs0,vds,zs,2.4,vgsc,cjs0_t,vds_t,ajs_t)
rci0_t = rci0*exp(zetaci*ln_qtt0);
vlim_t = vlim*exp((zetaci-avs)*ln_qtt0);
vces_t = vces*(1+alces*dT);
t0_t = t0*(1+alt0*dT+kt0*dT*dT);
thcs_t = thcs*exp((zetaci-1)*ln_qtt0);
zetatef = zetabet-zetact-0.5;
dvg = vgb-vge;
tef0_t = tef0*exp(zetatef*ln_qtt0-dvg/VT*(qtt0-1));
rbx_t = rbx*exp(zetarbx*ln_qtt0);
rcx_t = rcx*exp(zetarcx*ln_qtt0);
rbi0_t = rbi0*exp(zetarbi*ln_qtt0);
re_t = re*exp(zetare*ln_qtt0);
eavl_t = eavl*exp(aleav*dT);
kavl_t = kavl*exp(alkav*dT);
//
// Calculation of intrinsic transistor elements
//
// BC charge and cap (internal and external)
// The cjcx0 value is used to switch between one (cjcx0=0) and two bc parameter sets
// 1. For one parameter set only the internal bc set is partitioned by fbc
// 2. For two independent sets only the external set is partitioned by fbc
if (cjcx0_t==0) begin
cjci0_t_ii = cjci0_t*fbc; // zero bias internal portion
qjcxi = 0;
cjcx0_t_i = cjci0_t*(1-fbc); // zero bias external portion
`QJMOD(Vbci,cjcx0_t_i,vdci_t,zci,vptci,ajci_t,qjcx)
end else begin
cjci0_t_ii = cjci0_t; // zero bias internal portion
cjcx0_t_ii = cjcx0_t*fbc;
`QJMOD(Vbici,cjcx0_t_ii,vdcx_t,zcx,vptcx,ajcx_t,qjcxi);
cjcx0_t_i = cjcx0_t*(1-fbc); // zero bias external portion
`QJMOD(Vbci,cjcx0_t_i,vdcx_t,zcx,vptcx,ajcx_t,qjcx)
end
`QJMOD(Vbici,cjci0_t_ii,vdci_t,zci,vptci,ajci_t,qjci)
qjcii = qjci+qjcxi;
//Internal bc cap without punch through for cc
`QCJMOD(Vbici,cjci0_t_ii,vdci_t,zci,100,ajci_t,qjciii,cjcii)
// cjcii = ddx(qjciii,Vbici); //cap needful only here: ddx() not supported
//Internal be cap and charge
// Preprocessing
vf = vde_t*(1-exp(-ln(aje_t)/ze));
// Smoothing terms
xvf = (vf-Vbiei)/VT;
xvf2 = sqrt(xvf*xvf+1.921812);
vj = vf-VT*0.5*(xvf+xvf2);
dvj = 0.5*(xvf+xvf2)/xvf2;
// BE cap
cjei = cje0_t*exp(-ze*ln(1-vj/vde_t))*dvj+aje_t*cje0_t*(1-dvj);
// Preprocessing
x = 1-ze;
y = 1-exp(x*ln(1-vj/vde_t));
// BE charge
qjei = cje0_t*vde_t/x*y+aje_t*cje0_t*(Vbiei-vj);
// Critical current: ick
vc = Vciei-vces_t;
uvc = vc/VT-1;
vceff = VT*(1+0.5*(uvc+sqrt(uvc*uvc+1.921812)));
x = (vceff-vlim_t)/vpt;
ick = vceff*(1+0.5*(x+sqrt(x*x+1e-3)))/rci0_t/sqrt(1+vceff*vceff/vlim_t/vlim_t);
// Transfer current
// Normalized BC cap and carge
cc = cjci0_t_ii/cjcii;
qjci = qjci/cjci0_t_ii;
qj_2 = (1+qjci/vef)/2;
// Minority charge transit time
tf0 = t0_t+dt0h*(cc-1)+tbvl*(1/cc-1);
// DC critical currents
ickf = iqf;
ickr = iqr;
// Ideal transfer currents
arg1 = Vbiei/(mcf*VT);
`LIN_EXP(le1,arg1)
itfi=is_t*le1;
arg2 = Vbici/(mcr*VT);
`LIN_EXP(le2,arg2)
itri=is_t*le2;
// Normalized minority charge
qm = (itfi/ickf+itri/ickr);
// Normalized total hole charge
qpt = qj_2+sqrt((qj_2)*(qj_2)+qm);
if (qpt<=1e-20)
qpt=1e-20;
// Low transfer current
itfl = itfi/qpt;
itrl = itri/qpt;
// Normalized injection width with low transfer current
// and normalized charge component
if (itfl<=1e-20)
itfl = 1e-20;
al = 1-ick/itfl;
s3l = sqrt(al*al+ahc);
wl = (al+s3l)/(1+sqrt(1+ahc));
d_qfh = (wl*wl+tfh*itfl/ick)*itfl/iqfh;
// Transfer current
facl = 1/(1+d_qfh/qpt);
itf = itfl*facl;
itr = itrl*facl;
if (itf<=1e-20)
itf = 1e-20;
it = itf-itr;
// BE diffusion charge
// Calculation of low-current portion
qf0 = tf0*itf;
// Current dependent component
a = 1-ick/itf;
s3 = sqrt(a*a+ahc);
w = (a+s3)/(1+sqrt(1+ahc));
tww = thcs_t*w*w;
dqfh = tww*itf;
dtfh = tww*(1+2*ick/itf/s3);
// Emitter component
dtef = tef0_t*exp(gte*ln(itf/ick));
dqef = dtef*itf/(gte+1.0);
// Total minority charge and transit time
qf = qf0+dqef+dqfh;
tf = tf0+dtfh+dtef;
// BC diffusion charge
qr = tr*itr;
// Internal base current
// BE diode
`HICDIO(ibes,ibes_t,mbe,Vbiei,ibe)
`HICDIO(ires,ires_t,mre,Vbiei,ire)
ijbe = ibe+ire;
// BC diode
`HICDIO(ibcs,ibcs_t,mbc,Vbici,ijbc)
// Total base current
ibi = ijbe+ijbc;
// Avalanche current
v_bord = eavl_t*vdci_t;
if (Vbici < 0) begin
if (vdci_t-Vbici>v_bord) begin
a_iavl = kavl_t/vdci_t*exp(-cc);
iavl = itf*a_iavl*(v_bord+(1+cc)*(vdci_t-Vbici-v_bord));
end else begin
lncc = ln(1/cc);
iavl = kavl_t*itf*exp(-1/zci*lncc-eavl_t*exp((1/zci-1)*lncc));
end
end else begin
iavl = 0;
end
//
// Additional elements for external transistor
//
// Base resistance
qje = qjei/cje0_t;
ri = rbi0_t/(1+qje/vr0e+itf/ickf+itr/ickr+qjci/vr0c);
if (ibi > 0.0) begin
eta = fgeo*ri*ibi/VT;
if (eta < 1e-6) begin
fac_ri=1-eta/2;
end else begin
fac_ri=ln(eta+1)/eta;
end
end else begin
fac_ri = 1.0;
end
rbi = ri*fac_ri;
rb = rbi+rbx_t;
// Substrate diode and cap and charge
`HICDIO(iscs,iscs_t,msc,Vsci,ijsc)
`QJMOD(Vsci,cjs0_t,vds_t,zs,vpts,ajs_t,qjs); // aj=2.4 assumed
// Self heating
if (rth > 0.0) begin
pterm = it*Vciei+iavl*(vdci_t-Vbici);
end
//
// Compute branch sources
//
Ibici = ijbc - iavl;
Qbci = cbcpar*Vbci;
Qbe = cbepar*Vbe;
Qbici = qjcii+qr;
Qbiei = qjei+qf;
ijsc = HICUMtype*ijsc;
qjs = HICUMtype*qjs;
qjcx = HICUMtype*qjcx;
Qbci = HICUMtype*Qbci;
Qbe = HICUMtype*Qbe;
Ibici = HICUMtype*Ibici;
Qbici = HICUMtype*Qbici;
ijbe = HICUMtype*ijbe;
Qbiei = HICUMtype*Qbiei;
it = HICUMtype*it;
//
// Define branch sources
//
I(s,ci) <+ ijsc `P(spectre:gmin="add" spectre:pwl_passive="1e10");
I(s,ci) <+ ddt(qjs);
I(b,ci) <+ ddt(qjcx);
I(b,ci) <+ ddt(Qbci);
I(b,e) <+ ddt(Qbe);
if (re > 0.0) begin
I(iresex) <+ Veie/re_t `P(spectre:gmin="add");
end else begin
V(vresex) <+ 0.0;
end
if (rcx > 0.0) begin
I(irescx) <+ Vcic/rcx_t `P(spectre:gmin="add");
end else begin
V(vrescx) <+ 0.0;
end
if (rbi0 > 0.0 || rbx > 0.0) begin
I(irescb) <+ Vbbi/rb `P(spectre:gmin="add");
end else begin
V(vrescb) <+ 0.0;
end
I(bi,ci) <+ Ibici `P(spectre:gmin="add" spectre:pwl_sat_current="IMAX" spectre:pwl_sat_cond="imax/0.025" spectre:pwl_rev_current="imax" spectre:pwl_rev_cond="IMAX/0.025");
I(bi,ci) <+ ddt(Qbici);
I(bi,ei) <+ ijbe `P(spectre:gmin="add" spectre:pwl_fwd_current="IBEIS*exp(25.0)" spectre:pwl_fwd_node="bi" spectre:pwl_fwd_cond="IBEIS*exp(25.0)/0.025" spectre:pwl_sat_current="IMAX" spectre:pwl_sat_cond="IMAX/0.025" spectre:pwl_passive="1e10");
I(bi,ei) <+ ddt(Qbiei);
I(ci,ei) <+ it `P(spectre:pwl_fwd_current="IS*exp(25.0)" spectre:pwl_fwd_node="bi" spectre:pwl_fwd_cond="IS*exp(25.0)/0.025" spectre:pwl_rev_current="IMAX" spectre:pwl_rev_cond="IMAX/0.025" spectre:pwl_passive="1e10");
if(rth == 0) begin
V(tnode) <+ 0.0;
end else begin
I(tnode) <+ Vrth/rth-pterm `P(spectre:gmin="add");
I(tnode) <+ ddt(cth*Vrth);
end
// Noise sources
// Thermal noise
fourkt = 4.0 * `P_K * Tdev;
if(rbx > 0.0 || rbi0 > 0.0)
I(irescb) <+ white_noise(fourkt/rb);
if(rcx > 0.0)
I(irescx) <+ white_noise(fourkt/rcx_t);
if(re > 0.0)
I(iresex) <+ white_noise(fourkt/re_t);
// Shot noise
twoq = 2.0 * `P_Q;
I(bi,ei) <+ white_noise(twoq*ijbe);
I(ci,ei) <+ white_noise(twoq*it);
// Flicker noise
flicker_Pwr = kf*pow(ijbe,af);
I(bi,ei) <+ flicker_noise(flicker_Pwr,1.0);
end // analog
endmodule