diff --git a/src/spicelib/devices/adms/hicum0/admsva/hicumL0V1p11.va b/src/spicelib/devices/adms/hicum0/admsva/hicumL0V1p11.va new file mode 100644 index 000000000..68920b5f8 --- /dev/null +++ b/src/spicelib/devices/adms/hicum0/admsva/hicumL0V1p11.va @@ -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