Browse Source
The HICUM Level0 Bipolar Model in Verilog-A (Original Version 1.1 - only VT0 changed to Vt0)
pre-master-46
The HICUM Level0 Bipolar Model in Verilog-A (Original Version 1.1 - only VT0 changed to Vt0)
pre-master-46
1 changed files with 782 additions and 0 deletions
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue