diff --git a/src/spicelib/devices/adms/hicum2/admsva/hicum2.va b/src/spicelib/devices/adms/hicum2/admsva/hicum2.va index 0bc766ee6..63b6581f5 100644 --- a/src/spicelib/devices/adms/hicum2/admsva/hicum2.va +++ b/src/spicelib/devices/adms/hicum2/admsva/hicum2.va @@ -1,26 +1,75 @@ //HICUM Level_2 Version_2.22: A Verilog-A Description +//dw 12/08: Modifications for ngspice and adms suggested by Laurent Lemaitre: +// replaced `define MODEL @(initial_model) by `define MODEL because we have usage of a +// dependent variable for HICTUN_T. +// all V(...) <+ 0.0; are replaced by I(...) < V(...)/`MIN_R; +// variable definition only on start of the module and removing named blocks HICTUN_T +// because handling not correct - wrong scope! + // 01/06: Bug fix and optimization // FCdf1_dw assigned expression (missing in v2.21) // FCa and FCa1 are found to have same expression: FCa is omitted in those cases -// Fca1 written instead of Fca in the expression for FCf_ci -// Thermal node "tnode" is set as external +// FCa1 written instead of FCa in the expression for FCf_ci +// Thermal node "tnode" set as external // zetasct = mg+1-2.5 changed to zetasct = mg-1.5; -// Code optimization: code rearranged to exclude the temperature dependent -// calculation from @(initial_model) within insideADMS (with self-heating ON). -// Temperature update parts are moduled in a separate block. +// Code optimization: Temperature dependent parts are moduled in two separate blocks: +// within @(initial_model) when self-heating is OFF +// outside @(initial_model) when self-heating is ON +// 03/06 : Further fix +// vlim_t,ibcis_t,ibcxs_t,itss_t,iscs_t considered in compatibility block +// ddt() operators are separated in contribution expressions. +// FLCOMP parameter is given different values +// 05/06: +// all if-else blocks marked with begin-end +// unused variables deleted +// all series resistors and RTH are allowed to have a minimum value MIN_R +// only tunelling current source contribution within if-then-else +// 06/06: HICRBI deleted and instead the code changed (hyperbolic smoothing in +// conductivity modulation part) and put in relevant portion of the code. +// 07/06: ddx() operator used to find out capacitances from charges: +// QJMODF,QJMOD,HICJQ changed accordingly +// Lateral NQS effect modified with ddx() operator. +// HICFCT included for downward compatibility reason. +// Few macros are taken inside the code: HICICK, HICAVL, HICTUN (more optimized), +// internal base resistance (Qjci included under conductivity modulation, hyperbolic smoothing used) +// Gmin added at (bi,ei) and (bi,ci) branches. +// 08/06: Units added in the parameter descriptions. + +// ********************************************************************************* +// 06/06: Comment on NODE COLLAPSING: +// Presently this verilog code permits a minimum of 1 milli-Ohm resistance for any +// series resistance as well as for thermal resistance RTH. If any of the resistance +// values drops below this minimum value, the corresponding nodes are shorted with +// zero voltage contribution. We want the model compilers/simulators deal this +// situation in such a manner that the corresponding node is COLLAPSED. +// We expect that the simulators should permit current contribution statement +// for any branch with resistance value more than (or equal to) 1 milli-Ohm without +// any convergence problem. In fact, we wish NOT to have to use a voltage contribution +// statement in our Verilog code, except as an indication for the model compiler/simulator +// to interprete a zero branch voltage as NODE-COLLAPSING action. +// ********************************************************************************** +// ********************************************************************************** +// 06/06: Comment on Implementation of Non-Quasi-Static Effect: +// This code does not have NQS effect implemented yet. Up to now we recommend Weil's +// approach, which is implemented in DEVICE FTN code and built-in v2.1 HICUM model +// inside most of the circuit simulators. Using Verilog, it is not presently possible +// to implement Weil's approach, since there remains hardly any possibility to access +// previous time-step of simulation. Providing C-code will not even serve the purpose, +// since we are not aware of the specific time-steps for various simulators. Instead, +// we recommend the EDA vendors to use their previous implementation (piece of code +// for NQS effect) for this model code in appropriate position, once it is converted +// into C-code by the model compilers. At present only this solution seems feasible. +// ********************************************************************************** -// ddt() terms splitted DW //Default simulator: Spectre `ifdef insideADMS - `define P(p) (*p*) - `define MODEL @(initial_model) + `define MODEL `define NOISE @(noise) `define ATTR(txt) (*txt*) `else - `define P(p) `define MODEL `define NOISE `define ATTR(txt) @@ -35,7 +84,9 @@ `define l_itmax 100 `define TMAX 326.85 `define TMIN -100.0 - +`define LN_EXP_LIMIT 11.0 +`define MIN_R 0.001 +`define Gmin 1.0e-12 //ADS //`include "constants.vams" @@ -47,7 +98,7 @@ `include "discipline.h" -// DEPLETION CAPACITANCE AND CHARGE CALCULATION +// DEPLETION CHARGE CALCULATION // Hyperbolic smoothing used; no punch-through // INPUT: // c_0 : zero-bias capacitance @@ -59,29 +110,22 @@ // VT : thermal voltage // OUTPUT: // Qz : depletion Charge -// C : depletion capacitance (Until ddx() is operative) -`define QCJMODF(c_0,u_d,z,a_j,U_cap,C,Qz)\ +`define QJMODF(c_0,u_d,z,a_j,U_cap,Qz)\ if(c_0 > 0.0) begin\ DFV_f = u_d*(1.0-exp(-ln(a_j)/z));\ - DFC_max = a_j*c_0;\ - DFa = VT;\ - DFv_e = (DFV_f-U_cap)/DFa;\ + DFv_e = (DFV_f-U_cap)/VT;\ DFs_q = sqrt(DFv_e*DFv_e+`DFa_fj);\ DFs_q2 = (DFv_e+DFs_q)*0.5;\ - DFv_j = DFV_f-DFa*DFs_q2;\ - DFdvj_dv = DFs_q2/DFs_q;\ + DFv_j = DFV_f-VT*DFs_q2;\ DFb = ln(1.0-DFv_j/u_d);\ - DFC_j1 = c_0*exp(-z*DFb)*DFdvj_dv;\ - C = DFC_j1+DFC_max*(1.0-DFdvj_dv);\ DFQ_j = c_0*u_d*(1.0-exp(DFb*(1.0-z)))/(1.0-z);\ - Qz = DFQ_j+DFC_max*(U_cap-DFv_j);\ + Qz = DFQ_j+a_j*c_0*(U_cap-DFv_j);\ end else begin\ - C = 0.0;\ Qz = 0.0;\ end -// DEPLETION CAPACITANCE AND CHARGE CALCULATION +// DEPLETION CHARGE CALCULATION CONSIDERING PUNCH THROUGH // smoothing of reverse bias region (punch-through) // and limiting to a_j=Cj,max/Cj0 for forward bias. // Important for base-collector and collector-substrate junction @@ -96,8 +140,7 @@ // VT : thermal voltage // OUTPUT: // Qz : depletion charge -// C : depletion capacitance (Until ddx() is operative) -`define QCJMOD(c_0,u_d,z,a_j,v_pt,U_cap,C,Qz)\ +`define QJMOD(c_0,u_d,z,a_j,v_pt,U_cap,Qz)\ if(c_0 > 0.0) begin\ Dz_r = z/4.0;\ Dv_p = v_pt-u_d;\ @@ -107,21 +150,16 @@ Dv_e = (DV_f-U_cap)/VT;\ if(Dv_e < `Cexp_lim) begin\ De = exp(Dv_e);\ - De_1 = De/(1.0+De);\ Dv_j1 = DV_f-VT*ln(1.0+De);\ end else begin\ - De_1 = 1.0;\ Dv_j1 = U_cap;\ end\ Da = 0.1*Dv_p+4.0*VT;\ Dv_r = (Dv_p+Dv_j1)/Da;\ if(Dv_r < `Cexp_lim) begin\ De = exp(Dv_r);\ - De_2 = De/(1.0+De);\ Dv_j2 = -Dv_p+Da*ln(1.0+De);\ - end\ - else begin\ - De_2 = 1.0;\ + end else begin\ Dv_j2 = Dv_j1;\ end\ Dv_j4 = U_cap-Dv_j1;\ @@ -129,30 +167,25 @@ DCln2 = ln(1.0-Dv_j2/u_d);\ Dz1 = 1.0-z;\ Dzr1 = 1.0-Dz_r;\ - DC_j1 = c_0*exp(DCln2*(-z))*De_1*De_2;\ - DC_j2 = DC_c*exp(DCln1*(-Dz_r))*(1.0-De_2);\ - DC_j3 = DC_max*(1.0-De_1);\ - C = DC_j1+DC_j2+DC_j3;\ DQ_j1 = c_0*(1.0-exp(DCln2*Dz1))/Dz1;\ DQ_j2 = DC_c*(1.0-exp(DCln1*Dzr1))/Dzr1;\ DQ_j3 = DC_c*(1.0-exp(DCln2*Dzr1))/Dzr1;\ Qz = (DQ_j1+DQ_j2-DQ_j3)*u_d+DC_max*Dv_j4;\ end else begin\ - C = 0.0;\ Qz = 0.0;\ end -// DEPLETION CAPACITANCE AND CHARGE CALCULATION SELECTOR: +// DEPLETION CHARGE CALCULATION SELECTOR // Dependent on junction punch-through voltage // Important for collector related junctions -`define HICJCAP(c_0,u_d,z,v_pt,U_cap,C,Qz)\ +`define HICJQ(c_0,u_d,z,v_pt,U_cap,Qz)\ if(v_pt < `VPT_thresh) begin\ - `QCJMOD(c_0,u_d,z,2.4,v_pt,U_cap,C,Qz)\ + `QJMOD(c_0,u_d,z,2.4,v_pt,U_cap,Qz)\ end else begin\ - `QCJMODF(c_0,u_d,z,2.4,U_cap,C,Qz)\ + `QJMODF(c_0,u_d,z,2.4,U_cap,Qz)\ end @@ -182,6 +215,23 @@ end +// NEEDED TO CALCULATE WEIGHTED ICCR COLLECTOR MINORITY CHARGE +// INPUT: +// z : zeta_b or zeta_l +// w : normalized injection width +// OUTPUT: +// hicfcto : output +// dhicfcto_dw : derivative of output wrt w +`define HICFCT(z,lnz,w,hicfcto,dhicfcto_dw)\ + a = z*w;\ + if (a > 1.0e-6) begin\ + hicfcto = (a - lnz)/z;\ + dhicfcto_dw = a / (1.0 + a);\ + end else begin\ + hicfcto = 0.5 * a * w;\ + dhicfcto_dw = a;\ + end + // COLLECTOR CURRENT SPREADING CALCULATION // collector minority charge incl. 2D/3D current spreading (TED 10/96) @@ -221,7 +271,7 @@ FCd_a = 1.0/(1.0-FCf1*latb);\ FCw = FCf1*FCd_a;\ FCdw_daick = -1.0*FCd_a*FCd_a;\ - FClnb = latb*FCw;\ + FClnb = latb*FCw;\ FClnl = latl*FCw;\ FCa1 = FCz*FCw;\ FCda1_dw = FCz;\ @@ -236,9 +286,17 @@ FCdfc_dw = FCf_CT*(FCa1*FCdf1_dw+FCda1_dw*FCf1-FCdf2_dw+FCdf3_dw);\ FCdw_ditf = FCdw_daick*FCdaick_ditf;\ FCdfc_ditf = FCdfc_dw*FCdw_ditf;\ - FCf_CT = FCf_ci;\ - FCdfCT_ditf = FCdfc_ditf;\ - end else begin\ + if(flcomp == 0.0 || flcomp == 2.1) begin\ + `HICFCT(latb,FClnb,FCw,FCf2,FCdf2_dw)\ + `HICFCT(latl,FClnl,FCw,FCf3,FCdf3_dw)\ + FCf_CT = FCf_CT*(FCf2-FCf3);\ + FCdfCT_dw = FCf_CT*(FCdf2_dw-FCdf3_dw);\ + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;\ + end else begin\ + FCf_CT = FCf_ci;\ + FCdfCT_ditf = FCdfc_ditf;\ + end\ + end else begin\ if(latb > 0.01) begin\ FCd_a = 1.0/(1.0+FCa_ck*latb);\ FCw = (1.0-FCa_ck)*FCd_a;\ @@ -255,15 +313,25 @@ FCdfc_dw = 2.0*FCw*(FCz_1+FCz*FCz/3.0)*FCd_f*FCd_f;\ FCdw_ditf = FCdw_daick*FCdaick_ditf;\ FCdfc_ditf = FCdfc_dw*FCdw_ditf;\ - FCf_CT = FCf_ci;\ - FCdfCT_ditf = FCdfc_ditf;\ + if(flcomp == 0.0 || flcomp == 2.1) begin\ + if (FCz > 0.001) begin\ + FCf_CT = 2.0*(FCz_1*ln(FCz_1)-FCz)/(latb*latb*FCz_1);\ + FCdfCT_dw = 2.0*FCw*FCd_f*FCd_f;\ + end else begin\ + FCf_CT = FCw2*(1.0-FCz/3.0)*FCd_f;\ + FCdfCT_dw = 2.0*FCw*(1.0-FCz*FCz/3.0)*FCd_f*FCd_f;\ + end\ + FCdfCT_ditf = FCdfCT_dw*FCdw_ditf;\ + end else begin\ + FCf_CT = FCf_ci;\ + FCdfCT_ditf = FCdfc_ditf;\ + end\ end\ + Q_CT = Q_fC*FCf_CT;\ Q_fC = Q_fC*FCf_ci;\ - Q_CT = Q_fC*FCf_CT;\ T_fC = FFT_pcS*(FCf_ci+Ix*FCdfc_ditf);\ T_cT = FFT_pcS*(FCf_CT+Ix*FCdfCT_ditf); - // TRANSIT-TIME AND STORED MINORITY CHARGE // INPUT: // itf : forward transport current @@ -315,7 +383,6 @@ - // IDEAL DIODE (WITHOUT CAPACITANCE): // conductance calculation not required // INPUT: @@ -345,86 +412,6 @@ end -// CRITICAL CURRENT INDICATING ONSET OF HIGH CURRENT EFFECTS -// INPUT: -// v_c : unsmoothed effective collector voltage -// Orci0_t : reciprocal of low-field epi resistance -// vlim_t : limitation voltage -// Ovpt : reciprocal of punch-through voltage -// IMPLICIT INPUT: -// VT : thermal voltage -// OUTPUT: -// I_CK : critical current -// v_ceff : smoothed effective collector voltage -`define HICICK(v_c,Orci0_t,vlim_t,Ovpt,I_CK,v_ceff)\ - ICKv = v_c/VT;\ - d1 = ICKv-1;\ - v_ceff = (1.0+((d1+sqrt(d1*d1+1.921812))/2))*VT;\ - ICKv = v_ceff/vlim_t;\ - I_CK = v_ceff*Orci0_t/sqrt(1.0+ICKv*ICKv);\ - ICKa = (v_ceff-vlim_t)*Ovpt;\ - I_CK = I_CK*(1.0+(ICKa+sqrt(ICKa*ICKa+1.0e-3))/2.0); - - -// SIMPLE AVALANCHE GENERATION CURRENT -// INPUT: -// itf : forward component of the transfer current -// Ucap : junction voltage -// Cjci : junction capacitance -// IMPLICIT INPUT: -// cjci0_t,vdci_t,qavl_t,favl_t : related to model parameters -// OUTPUT: -// iavl : current generated by avalanche effect -`define HICAVL(itf,Ucap,Cjci,iavl)\ - if(Ucap < 0.0 && favl_t > 0.0 && cjci0_t > 0.0) begin\ - AVLv_bord = vdci_t-Ucap;\ - AVLv_q = qavl_t/Cjci;\ - AVLU0 = qavl_t/cjci0_t;\ - if(AVLv_bord > AVLU0) begin\ - AVLa = favl_t*exp(-AVLv_q/AVLU0);\ - AVLS_avl = AVLa*(AVLU0+(1.0+AVLv_q/AVLU0)*(AVLv_bord-AVLU0));\ - end else begin\ - AVLS_avl = favl_t*AVLv_bord*exp(-AVLv_q/AVLv_bord);\ - end\ - iavl = itf*AVLS_avl;\ - end else begin\ - iavl = 0.0;\ - end - - -// TUNNELING CURRENT FOR EMITTER-BASE BREAKDOWN -// INPUT: -// mostly related to model parameters at different temperature -// vgx, vgy : bandgap voltages -// Cp_t, Ci_t : peripheral and intrinsic c-b junction cap at zero bias -// Vp_t, Vi_t : peripheral and intrinsic c-b built-in potential -// Upp, Uii : peripheral and intrinsic c-b junction voltages -// Cpp, Cii : peripheral and intrinsic c-b capacitances -// IMPLICIT INPUT: -// tunode,cjep0,vdep,zep,cjei0,vdei,zei : model parameters -// OUTPUT: -// Itun : current generated by tunneling effect -`define HICTUN(vgx,vgy,Cp_t,Ci_t,Vp_t,Vi_t,Upp,Uii,Cpp,Cii,Itun) a_eg=vgx/vgy;\ - if(tunode==1.0 && cjep0 > 0.0 && vdep >0.0) begin\ - ab = (Cp_t/cjep0)*sqrt(a_eg)*Vp_t*Vp_t/(vdep*vdep);\ - aa = (vdep/Vp_t)*(cjep0/Cp_t)*pow(a_eg,-1.5);\ - vve = -Upp/Vp_t;\ - cce = Cpp/Cp_t;\ - zex = zep;\ - end else begin\ - ab = (Ci_t/cjei0)*sqrt(a_eg)*Vi_t*Vi_t/(vdei*vdei);\ - aa = (vdei/Vi_t)*(cjei0/Ci_t)*pow(a_eg,-1.5);\ - vve = -Uii/Vi_t;\ - cce = Cii/Ci_t;\ - zex = zei;\ - end\ - ibets_t = ibets*ab;\ - abet_t = abet*aa;\ - pocce = limexp((1-1/zex)*ln(cce));\ - czz = ibets_t*vve*pocce;\ - Itun = czz*limexp(-abet_t/pocce); - - // TEMPERATURE UPDATE OF JUNCTION CAPACITANCE RELATED PARAMETERS // INPUT: @@ -442,7 +429,6 @@ // c_j_t : temperature update of "c_j" // vd_t : temperature update of "vd0" // w_t : temperature update of "w" - `define TMPHICJ(c_j,vd0,z,w,is_al,vgeff,c_j_t,vd_t,w_t)\ if (c_j > 0.0) begin\ vdj0 = 2*vt0*ln(exp(vd0*0.5/vt0)-exp(-0.5*vd0/vt0));\ @@ -450,10 +436,11 @@ vdt = vdjt+2*VT*ln(0.5*(1+sqrt(1+4*exp(-vdjt/VT))));\ vd_t = vdt;\ c_j_t = c_j*exp(z*ln(vd0/vd_t));\ - if (is_al == 1)\ + if (is_al == 1) begin\ w_t = w*vd_t/vd0;\ - else\ + end else begin\ w_t = w;\ + end\ end else begin\ c_j_t = c_j;\ vd_t = vd0;\ @@ -461,59 +448,14 @@ end -//INTERNAL BASE RESISTANCE DEPENDENT ON QP AND INTERNAL BASE CURRENT -// INPUT: -// R_BI0, f_dqr0, F_GEO, f_qi : model parameters at device temperature -// Q_p0, Q_jei, Q_jci, Q_f : different charge components (section 2.1.6) -// ibei : diode current for internal b-e junction -// IMPLICIT INPUT: -// VT : thermal voltage -// OUTPUT: -// R_BI : charge and bias dependent internal base resistance -`define HICRBI(R_BI0,f_dqr0,F_GEO,f_qi,Q_p0,Q_jei,Q_f,ibei,R_BI)\ - if(R_BI0 > 0.0) begin\ - f_QR = (1+f_dqr0)*Q_p0;\ - Qz = Q_jei+Q_f;\ - if(Q_f > 0.0) begin\ - Q_fi = Q_f*f_qi;\ - f_p = (Q_jei+Q_fi)/Qz;\ - end else begin\ - f_p = 1.0;\ - end\ - R_BI = R_BI0*f_QR/(f_QR+Qz);\ - if( ibei > 0.0) begin\ - ETA = R_BI*ibei*F_GEO/VT;\ - if(ETA < 1.0e-6) begin\ - R_BI = R_BI*(1.0-0.5*ETA);\ - end else begin\ - R_BI = R_BI*ln(1.0+ETA)/ETA;\ - end\ - end\ - R_BI = R_BI*f_p;\ - end else begin\ - R_BI = 0.0;\ - end - - - - - module hic2_full (c,b,e,s,tnode); //Node definitions inout c,b,e,s,tnode; -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 tnode `P(info="external temperature node"); -electrical ci `P(info="internal collector node"); -electrical ei `P(info="internal emitter node"); -electrical bp `P(info="internal base node p"); -electrical bi `P(info="internal base node i"); -electrical si `P(info="internal substrate node"); +electrical c,b,e,s,ci,ei,bp,bi,si; +electrical tnode; //Branch definitions branch (b,bp) br_bbp_i; @@ -545,108 +487,108 @@ branch (tnode ) br_sht; //Transfer current -parameter real c10 = 2.0E-30 from [0:1] `ATTR(info="GICCR constant"); -parameter real qp0 = 2.0E-14 from (0:1] `ATTR(info="Zero-bias hole charge"); -parameter real ich = 0.0 from [0:inf) `ATTR(info="High-current correction for 2D and 3D effects"); //`0' signifies infinity +parameter real c10 = 2.0E-30 from [0:1] `ATTR(info="GICCR constant" unit="A^2s"); +parameter real qp0 = 2.0E-14 from (0:1] `ATTR(info="Zero-bias hole charge" unit="Coul"); +parameter real ich = 0.0 from [0:inf) `ATTR(info="High-current correction for 2D and 3D effects" unit="A"); //`0' signifies infinity parameter real hfe = 1.0 from [0:inf] `ATTR(info="Emitter minority charge weighting factor in HBTs"); parameter real hfc = 1.0 from [0:inf] `ATTR(info="Collector minority charge weighting factor in HBTs"); parameter real hjei = 1.0 from [0:100] `ATTR(info="B-E depletion charge weighting factor in HBTs"); parameter real hjci = 1.0 from [0:100] `ATTR(info="B-C depletion charge weighting factor in HBTs"); //Base-Emitter diode currents -parameter real ibeis = 1.0E-18 from [0:1] `ATTR(info="Internal B-E saturation current"); +parameter real ibeis = 1.0E-18 from [0:1] `ATTR(info="Internal B-E saturation current" unit="A"); parameter real mbei = 1.0 from (0:10] `ATTR(info="Internal B-E current ideality factor"); -parameter real ireis = 0.0 from [0:1] `ATTR(info="Internal B-E recombination saturation current"); +parameter real ireis = 0.0 from [0:1] `ATTR(info="Internal B-E recombination saturation current" unit="A"); parameter real mrei = 2.0 from (0:10] `ATTR(info="Internal B-E recombination current ideality factor"); -parameter real ibeps = 0.0 from [0:1] `ATTR(info="Peripheral B-E saturation current"); +parameter real ibeps = 0.0 from [0:1] `ATTR(info="Peripheral B-E saturation current" unit="A"); parameter real mbep = 1.0 from (0:10] `ATTR(info="Peripheral B-E current ideality factor"); -parameter real ireps = 0.0 from [0:1] `ATTR(info="Peripheral B-E recombination saturation current"); +parameter real ireps = 0.0 from [0:1] `ATTR(info="Peripheral B-E recombination saturation current" unit="A"); parameter real mrep = 2.0 from (0:10] `ATTR(info="Peripheral B-E recombination current ideality factor"); parameter real mcf = 1.0 from (0:10] `ATTR(info="Non-ideality factor for III-V HBTs"); //Transit time for excess recombination current at b-c barrier -parameter real tbhrec = 0.0 from [0:inf) `ATTR(info="Base current recombination time constant at B-C barrier for high forward injection"); +parameter real tbhrec = 0.0 from [0:inf) `ATTR(info="Base current recombination time constant at B-C barrier for high forward injection" unit="s"); //Base-Collector diode currents -parameter real ibcis = 1.0E-16 from [0:1.0] `ATTR(info="Internal B-C saturation current"); +parameter real ibcis = 1.0E-16 from [0:1.0] `ATTR(info="Internal B-C saturation current" unit="A"); parameter real mbci = 1.0 from (0:10] `ATTR(info="Internal B-C current ideality factor"); -parameter real ibcxs = 0.0 from [0:1.0] `ATTR(info="External B-C saturation current"); +parameter real ibcxs = 0.0 from [0:1.0] `ATTR(info="External B-C saturation current" unit="A"); parameter real mbcx = 1.0 from (0:10] `ATTR(info="External B-C current ideality factor"); //Base-Emitter tunneling current -parameter real ibets = 0.0 from [0:1] `ATTR(info="B-E tunneling saturation current"); +parameter real ibets = 0.0 from [0:1] `ATTR(info="B-E tunneling saturation current" unit="A"); parameter real abet = 40 from [0:inf) `ATTR(info="Exponent factor for tunneling current"); parameter integer tunode= 1 from [0:1] `ATTR(info="Specifies the base node connection for the tunneling current"); // =1 signifies perimeter node //Base-Collector avalanche current -parameter real favl = 0.0 from [0:inf) `ATTR(info="Avalanche current factor"); -parameter real qavl = 0.0 from [0:inf) `ATTR(info="Exponent factor for avalanche current"); -parameter real alfav = 0.0 `ATTR(info="Relative TC for FAVL"); -parameter real alqav = 0.0 `ATTR(info="Relative TC for QAVL"); +parameter real favl = 0.0 from [0:inf) `ATTR(info="Avalanche current factor" unit="1/V"); +parameter real qavl = 0.0 from [0:inf) `ATTR(info="Exponent factor for avalanche current" unit="Coul"); +parameter real alfav = 0.0 `ATTR(info="Relative TC for FAVL" unit="1/K"); +parameter real alqav = 0.0 `ATTR(info="Relative TC for QAVL" unit="1/K"); //Series resistances -parameter real rbi0 = 0.0 from [0:inf) `ATTR(info="Zero bias internal base resistance"); -parameter real rbx = 0.0 from [0:inf) `ATTR(info="External base series resistance"); +parameter real rbi0 = 0.0 from [0:inf) `ATTR(info="Zero bias internal base resistance" unit="Ohm"); +parameter real rbx = 0.0 from [0:inf) `ATTR(info="External base series resistance" unit="Ohm"); parameter real fgeo = 0.6557 from [0:1] `ATTR(info="Factor for geometry dependence of emitter current crowding"); parameter real fdqr0 = 0.0 from [0:1] `ATTR(info="Correction factor for modulation by B-E and B-C space charge layer"); parameter real fcrbi = 0.0 from [0:1] `ATTR(info="Ratio of HF shunt to total internal capacitance (lateral NQS effect)"); parameter real fqi = 1.0 from [0:1] `ATTR(info="Ration of internal to total minority charge"); -parameter real re = 0.0 from [0:inf) `ATTR(info="Emitter series resistance"); -parameter real rcx = 0.0 from [0:inf) `ATTR(info="External collector series resistance"); +parameter real re = 0.0 from [0:inf) `ATTR(info="Emitter series resistance" unit="Ohm"); +parameter real rcx = 0.0 from [0:inf) `ATTR(info="External collector series resistance" unit="Ohm"); //Substrate transistor -parameter real itss = 0.0 from [0:1.0] `ATTR(info="Substrate transistor transfer saturation current"); +parameter real itss = 0.0 from [0:1.0] `ATTR(info="Substrate transistor transfer saturation current" unit="A"); parameter real msf = 1.0 from (0:10] `ATTR(info="Forward ideality factor of substrate transfer current"); -parameter real iscs = 0.0 from [0:1.0] `ATTR(info="C-S diode saturation current"); +parameter real iscs = 0.0 from [0:1.0] `ATTR(info="C-S diode saturation current" unit="A"); parameter real msc = 1.0 from (0:10] `ATTR(info="Ideality factor of C-S diode current"); -parameter real tsf = 0.0 from [0:inf) `ATTR(info="Transit time for forward operation of substrate transistor"); +parameter real tsf = 0.0 from [0:inf) `ATTR(info="Transit time for forward operation of substrate transistor" unit="s"); //Intra-device substrate coupling -parameter real rsu = 0.0 from [0:inf) `ATTR(info="Substrate series resistance"); -parameter real csu = 0.0 from [0:inf) `ATTR(info="Substrate shunt capacitance"); +parameter real rsu = 0.0 from [0:inf) `ATTR(info="Substrate series resistance" unit="Ohm"); +parameter real csu = 0.0 from [0:inf) `ATTR(info="Substrate shunt capacitance" unit="F"); //Depletion Capacitances -parameter real cjei0 = 1.0E-20 from [0:inf) `ATTR(info="Internal B-E zero-bias depletion capacitance"); -parameter real vdei = 0.9 from (0:10] `ATTR(info="Internal B-E built-in potential"); +parameter real cjei0 = 1.0E-20 from [0:inf) `ATTR(info="Internal B-E zero-bias depletion capacitance" unit="F"); +parameter real vdei = 0.9 from (0:10] `ATTR(info="Internal B-E built-in potential" unit="V"); parameter real zei = 0.5 from (0:1] `ATTR(info="Internal B-E grading coefficient"); parameter real ajei = 2.5 from [1:inf) `ATTR(info="Ratio of maximum to zero-bias value of internal B-E capacitance"); -parameter real cjep0 = 1.0E-20 from [0:inf) `ATTR(info="Peripheral B-E zero-bias depletion capacitance"); -parameter real vdep = 0.9 from (0:10] `ATTR(info="Peripheral B-E built-in potential"); +parameter real cjep0 = 1.0E-20 from [0:inf) `ATTR(info="Peripheral B-E zero-bias depletion capacitance" unit="F"); +parameter real vdep = 0.9 from (0:10] `ATTR(info="Peripheral B-E built-in potential" unit="V"); parameter real zep = 0.5 from (0:1] `ATTR(info="Peripheral B-E grading coefficient"); parameter real ajep = 2.5 from [1:inf) `ATTR(info="Ratio of maximum to zero-bias value of peripheral B-E capacitance"); -parameter real cjci0 = 1.0E-20 from [0:inf) `ATTR(info="Internal B-C zero-bias depletion capacitance"); -parameter real vdci = 0.7 from (0:10] `ATTR(info="Internal B-C built-in potential"); +parameter real cjci0 = 1.0E-20 from [0:inf) `ATTR(info="Internal B-C zero-bias depletion capacitance" unit="F"); +parameter real vdci = 0.7 from (0:10] `ATTR(info="Internal B-C built-in potential" unit="V"); parameter real zci = 0.4 from (0:1] `ATTR(info="Internal B-C grading coefficient"); -parameter real vptci = 100 from (0:100] `ATTR(info="Internal B-C punch-through voltage"); -parameter real cjcx0 = 1.0E-20 from [0:inf) `ATTR(info="External B-C zero-bias depletion capacitance"); -parameter real vdcx = 0.7 from (0:10] `ATTR(info="External B-C built-in potential"); +parameter real vptci = 100 from (0:100] `ATTR(info="Internal B-C punch-through voltage" unit="V"); +parameter real cjcx0 = 1.0E-20 from [0:inf) `ATTR(info="External B-C zero-bias depletion capacitance" unit="F"); +parameter real vdcx = 0.7 from (0:10] `ATTR(info="External B-C built-in potential" unit="V"); parameter real zcx = 0.4 from (0:1] `ATTR(info="External B-C grading coefficient"); -parameter real vptcx = 100 from (0:100] `ATTR(info="External B-C punch-through voltage"); +parameter real vptcx = 100 from (0:100] `ATTR(info="External B-C punch-through voltage" unit="V"); parameter real fbcpar = 0.0 from [0:1] `ATTR(info="Partitioning factor of parasitic B-C cap"); parameter real fbepar = 1.0 from [0:1] `ATTR(info="Partitioning factor of parasitic B-E cap"); -parameter real cjs0 = 0.0 from [0:inf) `ATTR(info="C-S zero-bias depletion capacitance"); -parameter real vds = 0.6 from (0:10] `ATTR(info="C-S built-in potential"); +parameter real cjs0 = 0.0 from [0:inf) `ATTR(info="C-S zero-bias depletion capacitance" unit="F"); +parameter real vds = 0.6 from (0:10] `ATTR(info="C-S built-in potential" unit="V"); parameter real zs = 0.5 from (0:1] `ATTR(info="C-S grading coefficient"); -parameter real vpts = 100 from (0:100] `ATTR(info="C-S punch-through voltage"); +parameter real vpts = 100 from (0:100] `ATTR(info="C-S punch-through voltage" unit="V"); //Diffusion Capacitances -parameter real t0 = 0.0 from [0:inf) `ATTR(info="Low current forward transit time at VBC=0V"); -parameter real dt0h = 0.0 `ATTR(info="Time constant for base and B-C space charge layer width modulation"); -parameter real tbvl = 0.0 from [0:inf) `ATTR(info="Time constant for modelling carrier jam at low VCE"); -parameter real tef0 = 0.0 from [0:inf) `ATTR(info="Neutral emitter storage time"); +parameter real t0 = 0.0 from [0:inf) `ATTR(info="Low current forward transit time at VBC=0V" unit="s"); +parameter real dt0h = 0.0 `ATTR(info="Time constant for base and B-C space charge layer width modulation" unit="s"); +parameter real tbvl = 0.0 from [0:inf) `ATTR(info="Time constant for modelling carrier jam at low VCE" unit="s"); +parameter real tef0 = 0.0 from [0:inf) `ATTR(info="Neutral emitter storage time" unit="s"); parameter real gtfe = 1.0 from (0:10] `ATTR(info="Exponent factor for current dependence of neutral emitter storage time"); -parameter real thcs = 0.0 from [0:inf) `ATTR(info="Saturation time constant at high current densities"); +parameter real thcs = 0.0 from [0:inf) `ATTR(info="Saturation time constant at high current densities" unit="s"); parameter real ahc = 0.1 from (0:10] `ATTR(info="Smoothing factor for current dependence of base and collector transit time"); parameter real fthc = 0.0 from [0:1] `ATTR(info="Partitioning factor for base and collector portion"); -parameter real rci0 = 150 from (0:inf) `ATTR(info="Internal collector resistance at low electric field"); -parameter real vlim = 0.5 from (0:10] `ATTR(info="Voltage separating ohmic and saturation velocity regime"); -parameter real vces = 0.1 from [0:1] `ATTR(info="Internal C-E saturation voltage"); -parameter real vpt = 0.0 from [0:inf] `ATTR(info="Collector punch-through voltage"); // `0' signifies infinity -parameter real tr = 0.0 from [0:inf) `ATTR(info="Storage time for inverse operation"); +parameter real rci0 = 150 from (0:inf) `ATTR(info="Internal collector resistance at low electric field" unit="Ohm"); +parameter real vlim = 0.5 from (0:10] `ATTR(info="Voltage separating ohmic and saturation velocity regime" unit="V"); +parameter real vces = 0.1 from [0:1] `ATTR(info="Internal C-E saturation voltage" unit="V"); +parameter real vpt = 0.0 from [0:inf] `ATTR(info="Collector punch-through voltage" unit="V"); // `0' signifies infinity +parameter real tr = 0.0 from [0:inf) `ATTR(info="Storage time for inverse operation" unit="s"); //Isolation Capacitances -parameter real cbepar = 0.0 from [0:inf) `ATTR(info="Total parasitic B-E capacitance"); -parameter real cbcpar = 0.0 from [0:inf) `ATTR(info="Total parasitic B-C capacitance"); +parameter real cbepar = 0.0 from [0:inf) `ATTR(info="Total parasitic B-E capacitance" unit="F"); +parameter real cbcpar = 0.0 from [0:inf) `ATTR(info="Total parasitic B-C capacitance" unit="F"); //Non-quasi-static Effect parameter real alqf = 0.0 from [0:1] `ATTR(info="Factor for additional delay time of minority charge"); @@ -663,130 +605,106 @@ parameter real latb = 0.0 from [0:inf) `ATTR(info="Scaling factor for colle parameter real latl = 0.0 from [0:inf) `ATTR(info="Scaling factor for collector minority charge in direction of emitter length"); //Temperature dependence -parameter real vgb = 1.17 from (0:10] `ATTR(info="Bandgap voltage extrapolated to 0 K"); -parameter real alt0 = 0.0 `ATTR(info="First order relative TC of parameter T0"); +parameter real vgb = 1.17 from (0:10] `ATTR(info="Bandgap voltage extrapolated to 0 K" unit="V"); +parameter real alt0 = 0.0 `ATTR(info="First order relative TC of parameter T0" unit="1/K"); parameter real kt0 = 0.0 `ATTR(info="Second order relative TC of parameter T0"); parameter real zetaci = 0.0 `ATTR(info="Temperature exponent for RCI0"); -parameter real alvs = 0.0 `ATTR(info="Relative TC of saturation drift velocity"); -parameter real alces = 0.0 `ATTR(info="Relative TC of VCES"); +parameter real alvs = 0.0 `ATTR(info="Relative TC of saturation drift velocity" unit="1/K"); +parameter real alces = 0.0 `ATTR(info="Relative TC of VCES" unit="1/K"); parameter real zetarbi = 0.0 `ATTR(info="Temperature exponent of internal base resistance"); parameter real zetarbx = 0.0 `ATTR(info="Temperature exponent of external base resistance"); parameter real zetarcx = 0.0 `ATTR(info="Temperature exponent of external collector resistance"); parameter real zetare = 0.0 `ATTR(info="Temperature exponent of emitter resistance"); parameter real zetacx = 1.0 `ATTR(info="Temperature exponent of mobility in substrate transistor transit time"); -parameter real vge = 1.17 from (0:10] `ATTR(info="Effective emitter bandgap voltage"); -parameter real vgc = 1.17 from (0:10] `ATTR(info="Effective collector bandgap voltage"); -parameter real vgs = 1.17 from (0:10] `ATTR(info="Effective substrate bandgap voltage"); +parameter real vge = 1.17 from (0:10] `ATTR(info="Effective emitter bandgap voltage" unit="V"); +parameter real vgc = 1.17 from (0:10] `ATTR(info="Effective collector bandgap voltage" unit="V"); +parameter real vgs = 1.17 from (0:10] `ATTR(info="Effective substrate bandgap voltage" unit="V"); parameter real f1vg =-1.02377e-4 `ATTR(info="Coefficient K1 in T-dependent band-gap equation"); parameter real f2vg = 4.3215e-4 `ATTR(info="Coefficient K2 in T-dependent band-gap equation"); parameter real zetact = 3.0 `ATTR(info="Exponent coefficient in transfer current temperature dependence"); parameter real zetabet = 3.5 `ATTR(info="Exponent coefficient in B-E junction current temperature dependence"); -parameter real alb = 0.0 `ATTR(info="Relative TC of forward current gain for V2.1 model"); +parameter real alb = 0.0 `ATTR(info="Relative TC of forward current gain for V2.1 model" unit="1/K"); //Self-Heating parameter integer flsh = 0 from [0:2] `ATTR(info="Flag for turning on and off self-heating effect"); -parameter real rth = 0.0 from [0:inf) `ATTR(info="Thermal resistance"); -parameter real cth = 0.0 from [0:inf) `ATTR(info="Thermal capacitance"); +parameter real rth = 0.0 from [0:inf) `ATTR(info="Thermal resistance" unit="K/W"); +parameter real cth = 0.0 from [0:inf) `ATTR(info="Thermal capacitance" unit="J/W"); //Compatibility with V2.1 -parameter integer flcomp = 0 from [0:1] `ATTR(info="Flag for compatibility with v2.1 model (0=v2.1)"); +parameter real flcomp = 0.0 from [0:inf) `ATTR(info="Flag for compatibility with v2.1 model (0=v2.1)"); //Circuit simulator specific parameters -parameter real tnom = 27.0 `ATTR(info="Temperature at which parameters are specified"); -parameter real dt = 0.0 `ATTR(info="Temperature change w.r.t. chip temperature for particular transistor"); +parameter real tnom = 27.0 `ATTR(info="Temperature at which parameters are specified" unit="C"); +parameter real dt = 0.0 `ATTR(info="Temperature change w.r.t. chip temperature for particular transistor" unit="K"); - //Declaration of variables: begin - + +// +//======================== Transistor model formulation =================== +// + + //Declaration of variables - //Temperature and drift - real VT,Tamb,Tdev,Tnom,qtt0,ln_qtt0,r_VgVT,V_gT,dT,k; - real ireis_t,ibeis_t,ibcxs_t,ibcis_t; - real iscs_t,cje0_t,cjci0_t,cjcx0_t; - real cjs0_t,rci0_t,vlim_t; - real vces_t,thcs_t,tef0_t,rbi_t,rbi0_t; - real rbx_t,rcx_t,re_t,rsu_t,t0_t; - real vdei_t,vdci_t; - real c10_t,cjei0_t,qp0_t; - real vdcx_t,vptcx_t,cjcx01_t,cjcx02_t,vpts_t,itss_t,tsf_t; - real ibeps_t,ireps_t,cjep0_t,ibets_t,abet_t; - real ajei_t,qavl_t,favl_t,vptci_t,vdep_t,ajep_t; + //Temperature and drift + real VT,Tdev,qtt0,ln_qtt0,r_VgVT,V_gT,dT,k; + real ireis_t,ibeis_t,ibcxs_t,ibcis_t,iscs_t,cjci0_t; + real cjs0_t,rci0_t,vlim_t,vces_t,thcs_t,tef0_t,rbi0_t; + real rbx_t,rcx_t,re_t,t0_t,vdei_t,vdci_t,vpts_t,itss_t,tsf_t; + real c10_t,cjei0_t,qp0_t,vdcx_t,vptcx_t,cjcx01_t,cjcx02_t; + real qjcx0_t_i,qjcx0_t_ii,cratio_t; + real ibeps_t,ireps_t,cjep0_t; + real ajei_t,qavl_t,favl_t,ibets_t,abet_t,vptci_t,vdep_t,ajep_t,zetatef; + real k1,k2,dvg0,vge_t,vgb_t,vgbe_t,vds_t,vt0,Tnom,Tamb,a,avs; + real zetabci,zetabcxt,zetasct,vgbe0,mg,vgb_t0,vge_t0,vgbe_t0,vgbc0,vgsc0; + real cbcpar1,cbcpar2,cbepar2,cbepar1,Oich,Ovpt,Otbhrec; - //Band-gap related - real mg,zetabci,zetabcxt,zetasct,zetatef,avs; - real k1,k2,k10,k20,vgbe0,vgbc0,vgsc0,dvg0; - real vgb0,vge0,vgc0,vgs0,vge_t0,vge_t,vgb_t,vgb_t0,vgbe_t,vgbe_t0,vt0; - - //Charge and capacitance for b-c junction - real Qjci,Cjci,Qjcx,Qjcxi,Qjcii,qjcx0_t_i,cbcpar1,cbcpar2,C_1; - real cjcx0_t_ii,cjcx0_t_i,qjcx0_t_ii,cratio_t,Cjcit,cc; - - //Charge and capacitance for b-e junction - real Qjei,Cjei; - real Qjep,Cjep; - - //Transfer and base current, related charges and capacitances - real itf,itr,it,ibei,irei,ibci,ibep,irep,ibh_rec; - real Oich,Orci0_t,Ovpt,Otbhrec,Tf,Tr,VT_f,i_0f,i_0r,a_bpt,Q_0,Q_p,Q_bpt; - real T_f0,Q_fT,Q_bf,T_fT,b_q,Q_fC,T_fC,T_cT,I_Tf1,A,a_h,vds_t; - real Q_pT,l_it,d_Q,d_Q0; - real cbepar1,cbepar2,qrbi; - - //Diffusion charge and critical current - real Qf,Qdei,tf0; - real Qr,Qdci; - real ick; - real vc,vceff; + //Charges, capacitances and currents + real Qjci,Qjei,Qjep; + real it,ibei,irei,ibci,ibep,irep,ibh_rec; + real Qdei,Qdci,qrbi; + real ibet,iavl; + real ijbcx,ijsc,Qjs,HSUM,HSI_Tsu,Qdsu; - //Tunneling current - real ibet; - - //Avalanche current - real iavl; + //Base resistance and self-heating power + real rbi,pterm; - //Base resistance - real rbi; - - //External b-c diode and cap - real ijbcx,cjcx01,cjcx02; - - //Substrate diode and cap - real ijsc,Cjs,Qjs; - - //Substrate Transistor - real HSUM,HSI_Tsu,HSa,HSb,Qdsu; - - //Self heating - real pterm,itnode,qtnode; + //Variables for macro TMPHICJ + real vdj0,vdjt,vdt; + + //Model initialization + real k10,k20,C_1; - //Macro test - real ICKv,ICKa; //HICICK - real AVLS_avl,AVLv_bord,AVLv_q,AVLU0,AVLa;//HICAVL - real vdj0,vdjt,vdt,d1; //TMPHICJ + //Model evaluation + real Cjci,Cjcit,cc,Cjei,Cjep; + real itf,itr,Tf,Tr,VT_f,i_0f,i_0r,a_bpt,Q_0,Q_p,Q_bpt; + real Orci0_t,b_q,Q_fC,T_fC,T_cT,I_Tf1,T_f0,Q_fT,T_fT,Q_bf; + real ICKa,d1; + real A,a_h,Q_pT,d_Q,d_Q0; + real Qf,Cdei,Qr,Cdci,Crbi; + real ick,vc,vceff,cjcx01,cjcx02,HSa,HSb; + integer l_it; + + //Variables for macros real DIOY,le;//HICDIO real FFT_fbS,FFa,FFx,FFs,FFw,FFw_2,FFd_QfB,FFd_TfB,FFT_pcS,FFQ_fC,FFT_fC,FFQ_cT,FFT_cT,FFd_TfE,FFd_QfE,FFa_w;//HICQFF - real FCz,FCw2,FCf1,FCf2,FCf3,FCf_ci,FCz_1;//HICQFC - real FCd_a,FCdaick_ditf,FCa,FCw,FCdw_daick,FCdfc_dw,FCdw_ditf,FCdfc_ditf,FCf_CT,FCdfCT_ditf,FCrt,FCln,FClnl,FClnb,FCda1_dw,FCdf1_dw,FCdf2_dw,FCdf3_dw,FCd_f;//HICQFC - real FCa1,FCa_ck,FCxl,FCxb;//HICQFC - real Dz_r,Dv_p,DV_f,DC_max,DC_c,Da,Dv_e,De,De_1,Dv_j1,Dv_r,De_2,Dv_j2,Dv_j4,DC_j1,DC_j2,DC_j3,DQ_j1,DQ_j2,DQ_j3,DCln1,DCln2,Dz1,Dzr1;//QCJMOD - real DFV_f,DFC_max,DFa,DFv_e,DFv_j,DFb,DFC_j1,DFQ_j,DFdvj_dv,DFs_q,DFs_q2;//QCJMODF - real z,a,a2,a3,r,x;//HICFCI - real f_QR,Qz,f_p,ETA,Q_fi; //HICRBI - real a_eg,aa,ab,vve,cce,pocce,zex,czz; //HICTUN + real FCz,FCw2,FCf1,FCf2,FCf3,FCf_ci,FCz_1,FCa1,FCa_ck,FCxl,FCxb;//HICQFC + real FCd_a,FCdaick_ditf,FCa,FCw,FCdw_daick,FCdfc_dw,FCdw_ditf,FCdfc_ditf,FCf_CT,FCdfCT_ditf,FCrt,FCln,FClnl,FClnb,FCda1_dw,FCdf1_dw,FCdf2_dw,FCdf3_dw,FCd_f,FCdfCT_dw;//HICQFC + real Dz_r,Dv_p,DV_f,DC_max,DC_c,Da,Dv_e,De,De_1,Dv_j1,Dv_r,De_2,Dv_j2,Dv_j4,DQ_j1,DQ_j2,DQ_j3,DCln1,DCln2,Dz1,Dzr1;//QJMOD + real DFV_f,DFv_e,DFv_j,DFb,DFQ_j,DFs_q,DFs_q2;//QJMODF + real z,a2,a3,r,x;//HICFCI + real zb,zl,lnzb,w,hicfcio,dhicfcio_dw; //HICFCT //Noise - real fourkt,twoq,flicker_Pwr; - - - //Declaration of variables: end - -// -//======================== Transistor model formulation =================== -// + real fourkt,twoq,flicker_Pwr; +// don't like it inside named blocks + real a_eg,ab,aa; + + //end of variables + analog begin -`MODEL begin // Model Initialization - +`MODEL begin : Model_initialization + Tnom = tnom+`P_CELSIUS0; Tamb = $temperature; vt0 = `P_K*Tnom /`P_Q; @@ -822,142 +740,371 @@ analog begin //Parasitic b-e capacitance partitioning: No temperature dependence cbepar2 = fbepar*cbepar; cbepar1 = cbepar-cbepar2; - -end // Model initialization:end - -begin // Temperature-dependent model evaluation with provision for self-heating - - // Temperature and resulting parameter drift - Tdev = Tamb+dt+V(br_sht); - // Limit temperature to avoid FPEs in equations - if(Tdev < `TMIN + 273.15) - Tdev = `TMIN + 273.15; - else - if (Tdev > `TMAX + 273.15) - Tdev = `TMAX + 273.15; - - VT = `P_K*Tdev /`P_Q; - dT = Tdev-Tnom; - qtt0 = Tdev/Tnom; - ln_qtt0 = ln(qtt0); - k1 = f1vg*Tdev*ln(Tdev); - k2 = f2vg*Tdev; - vgb_t = vgb+k1+k2; - vge_t = vge+k1+k2; - vgbe_t = (vgb_t+vge_t)/2; + //Avoid devide-by-zero and define infinity other way + //High current correction for 2D and 3D effects + if (ich != 0.0) begin + Oich = 1.0/ich; + end else begin + Oich = 0.0; + end + + //Base current recombination time constant at b-c barrier + if (tbhrec != 0.0) begin + Otbhrec = 1.0/tbhrec; + end else begin + Otbhrec = 0.0; + end + + //Collector punch-through voltage + if(vpt != 0.0) begin + Ovpt = 1.0/vpt; + end else begin + Ovpt = 0.0; + end + + // Temperature and resulting parameter drift + if (flsh==0 || rth < `MIN_R) begin : Thermal_updat_without_self_heating + Tdev = Tamb+dt; + if(Tdev < `TMIN + 273.15) begin + Tdev = `TMIN + 273.15; + end else begin + if (Tdev > `TMAX + 273.15) begin + Tdev = `TMAX + 273.15; + end + end + VT = `P_K*Tdev /`P_Q; + dT = Tdev-Tnom; + qtt0 = Tdev/Tnom; + ln_qtt0 = ln(qtt0); + k1 = f1vg*Tdev*ln(Tdev); + k2 = f2vg*Tdev; + vgb_t = vgb+k1+k2; + vge_t = vge+k1+k2; + vgbe_t = (vgb_t+vge_t)/2; - //Internal b-e junction capacitance - `TMPHICJ(cjei0,vdei,zei,ajei,1,vgbe0,cjei0_t,vdei_t,ajei_t) + //Internal b-e junction capacitance + `TMPHICJ(cjei0,vdei,zei,ajei,1,vgbe0,cjei0_t,vdei_t,ajei_t) - if (flcomp ==0) begin - V_gT = 3.0*VT*ln_qtt0 + vgb*(qtt0-1.0); - r_VgVT = V_gT/VT; - //Internal b-e diode saturation currents - a = mcf*r_VgVT/mbei - alb*dT; - ibeis_t = ibeis*exp(a); - a = mcf*r_VgVT/mrei - alb*dT; - ireis_t = ireis*exp(a); - a = mcf*r_VgVT/mbep - alb*dT; - //Peripheral b-e diode saturation currents - ibeps_t = ibeps*exp(a); - a = mcf*r_VgVT/mrep - alb*dT; - ireps_t = ireps*exp(a); - //Zero bias hole charge - a = vdei_t/vdei; - qp0_t = qp0*(1.0+0.5*zei*(1.0-a)); - //Neutral emitter storage time - a = 1.0+alb*dT; - k = 0.5*(a+sqrt(a*a+0.01)); - tef0_t = tef0*qtt0/k; - end else begin - //Internal b-e diode saturation currents - ibeis_t = ibeis*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); - ireis_t = ireis*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); - //Peripheral b-e diode saturation currents - ibeps_t = ibeps*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); - ireps_t = ireps*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); - //Zero bias hole charge - a = exp(zei*ln(vdei_t/vdei)); - qp0_t = qp0*(2.0-a); - //Neutral emitter storage time - zetatef = zetabet-zetact-0.5; - dvg0 = vgb-vge; - tef0_t = tef0*exp(zetatef*ln_qtt0-dvg0/VT*(qtt0-1)); - end + if (flcomp == 0.0 || flcomp == 2.1) begin + V_gT = 3.0*VT*ln_qtt0 + vgb*(qtt0-1.0); + r_VgVT = V_gT/VT; + //Internal b-e diode saturation currents + a = mcf*r_VgVT/mbei - alb*dT; + ibeis_t = ibeis*exp(a); + a = mcf*r_VgVT/mrei - alb*dT; + ireis_t = ireis*exp(a); + a = mcf*r_VgVT/mbep - alb*dT; + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(a); + a = mcf*r_VgVT/mrep - alb*dT; + ireps_t = ireps*exp(a); + //Internal b-c diode saturation current + a = r_VgVT/mbci; + ibcis_t = ibcis*exp(a); + //External b-c diode saturation currents + a = r_VgVT/mbcx; + ibcxs_t = ibcxs*exp(a); + //Saturation transfer current for substrate transistor + a = r_VgVT/msf; + itss_t = itss*exp(a); + //Saturation current for c-s diode + a = r_VgVT/msc; + iscs_t = iscs*exp(a); + //Zero bias hole charge + a = vdei_t/vdei; + qp0_t = qp0*(1.0+0.5*zei*(1.0-a)); + //Voltage separating ohmic and saturation velocity regime + a = vlim*(1.0-alvs*dT)*exp(zetaci*ln_qtt0); + k = (a-VT)/VT; + if (k < `LN_EXP_LIMIT) begin + vlim_t = VT + VT*ln(1.0+exp(k)); + end else begin + vlim_t = a; + end + //Neutral emitter storage time + a = 1.0+alb*dT; + k = 0.5*(a+sqrt(a*a+0.01)); + tef0_t = tef0*qtt0/k; + end else begin + //Internal b-e diode saturation currents + ibeis_t = ibeis*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireis_t = ireis*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireps_t = ireps*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Internal b-c diode saturation currents + ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + //External b-c diode saturation currents + ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation transfer current for substrate transistor + itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation current for c-s diode + iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + //Zero bias hole charge + a = exp(zei*ln(vdei_t/vdei)); + qp0_t = qp0*(2.0-a); + //Voltage separating ohmic and saturation velocity regime + vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + //Neutral emitter storage time + zetatef = zetabet-zetact-0.5; + dvg0 = vgb-vge; + tef0_t = tef0*exp(zetatef*ln_qtt0-dvg0/VT*(qtt0-1)); + end - //GICCR prefactor - c10_t = c10*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); + //GICCR prefactor + c10_t = c10*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); - // Low-field internal collector resistance - rci0_t = rci0/exp(-zetaci*ln_qtt0); + // Low-field internal collector resistance + rci0_t = rci0*exp(zetaci*ln_qtt0); - //Voltage separating ohmic and saturation velocity regime - vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + //Voltage separating ohmic and saturation velocity regime + //vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); - //Internal c-e saturation voltage - vces_t = vces*(1+alces*dT); + //Internal c-e saturation voltage + vces_t = vces*(1+alces*dT); - //Internal b-c diode saturation current - ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + //Internal b-c diode saturation current + //ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); - //Internal b-c junction capacitance - `TMPHICJ(cjci0,vdci,zci,vptci,0,vgbc0,cjci0_t,vdci_t,vptci_t) + //Internal b-c junction capacitance + `TMPHICJ(cjci0,vdci,zci,vptci,0,vgbc0,cjci0_t,vdci_t,vptci_t) - //Low-current forward transit time - t0_t = t0*(1+alt0*dT+kt0*dT*dT); + //Low-current forward transit time + t0_t = t0*(1+alt0*dT+kt0*dT*dT); - //Saturation time constant at high current densities - thcs_t = thcs*exp((zetaci-1)*ln_qtt0); - + //Saturation time constant at high current densities + thcs_t = thcs*exp((zetaci-1)*ln_qtt0); - //Avalanche caurrent factors - favl_t = favl*exp(alfav*dT); - qavl_t = qavl*exp(alqav*dT); + //Avalanche caurrent factors + favl_t = favl*exp(alfav*dT); + qavl_t = qavl*exp(alqav*dT); - //Zero bias internal base resistance - rbi0_t = rbi0*exp(zetarbi*ln_qtt0); + //Zero bias internal base resistance + rbi0_t = rbi0*exp(zetarbi*ln_qtt0); - //Peripheral b-e junction capacitance - `TMPHICJ(cjep0,vdep,zep,ajep,1,vgbe0,cjep0_t,vdep_t,ajep_t) + //Peripheral b-e junction capacitance + `TMPHICJ(cjep0,vdep,zep,ajep,1,vgbe0,cjep0_t,vdep_t,ajep_t) + + //Tunneling current factors + if (V(br_bpei) < 0.0 || V(br_biei) < 0.0) begin // : HICTUN_T +// real a_eg,ab,aa; + ab = 1.0; + aa = 1.0; + a_eg=vgbe_t0/vgbe_t; + if(tunode==1 && cjep0 > 0.0 && vdep >0.0) begin + ab = (cjep0_t/cjep0)*sqrt(a_eg)*vdep_t*vdep_t/(vdep*vdep); + aa = (vdep/vdep_t)*(cjep0/cjep0_t)*pow(a_eg,-1.5); + end else if (tunode==0 && cjei0 > 0.0 && vdei >0.0) begin + ab = (cjei0_t/cjei0)*sqrt(a_eg)*vdei_t*vdei_t/(vdei*vdei); + aa = (vdei/vdei_t)*(cjei0/cjei0_t)*pow(a_eg,-1.5); + end + ibets_t = ibets*ab; + abet_t = abet*aa; + end - //Temperature mapping for tunneling current is done inside HICTUN + //Temperature mapping for tunneling current is done inside HICTUN - `TMPHICJ(1.0,vdcx,zcx,vptcx,0,vgbc0,cratio_t,vdcx_t,vptcx_t) - cjcx01_t=cratio_t*cjcx01; - cjcx02_t=cratio_t*cjcx02; + `TMPHICJ(1.0,vdcx,zcx,vptcx,0,vgbc0,cratio_t,vdcx_t,vptcx_t) + cjcx01_t=cratio_t*cjcx01; + cjcx02_t=cratio_t*cjcx02; - //External b-c diode saturation currents - ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + //External b-c diode saturation currents + //ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + + //Constant external series resistances + rcx_t = rcx*exp(zetarcx*ln_qtt0); + rbx_t = rbx*exp(zetarbx*ln_qtt0); + re_t = re*exp(zetare*ln_qtt0); - //Constant external series resistances - rcx_t = rcx*exp(zetarcx*ln_qtt0); - rbx_t = rbx*exp(zetarbx*ln_qtt0); - re_t = re*exp(zetare*ln_qtt0); + //Forward transit time in substrate transistor + tsf_t = tsf*exp((zetacx-1.0)*ln_qtt0); + + //Capacitance for c-s junction + `TMPHICJ(cjs0,vds,zs,vpts,0,vgsc0,cjs0_t,vds_t,vpts_t) + + end // of Thermal_update_without_self_heating + +end //of Model_initialization + + if (flsh!=0 && rth >= `MIN_R) begin : Thermal_update_with_self_heating + Tdev = Tamb+dt+V(br_sht); + // Limit temperature to avoid FPEs in equations + if(Tdev < `TMIN + 273.15) begin + Tdev = `TMIN + 273.15; + end else begin + if (Tdev > `TMAX + 273.15) begin + Tdev = `TMAX + 273.15; + end + end + VT = `P_K*Tdev /`P_Q; + dT = Tdev-Tnom; + qtt0 = Tdev/Tnom; + ln_qtt0 = ln(qtt0); + k1 = f1vg*Tdev*ln(Tdev); + k2 = f2vg*Tdev; + vgb_t = vgb+k1+k2; + vge_t = vge+k1+k2; + vgbe_t = (vgb_t+vge_t)/2; + + //Internal b-e junction capacitance + `TMPHICJ(cjei0,vdei,zei,ajei,1,vgbe0,cjei0_t,vdei_t,ajei_t) + + if (flcomp == 0.0 || flcomp == 2.1) begin + V_gT = 3.0*VT*ln_qtt0 + vgb*(qtt0-1.0); + r_VgVT = V_gT/VT; + //Internal b-e diode saturation currents + a = mcf*r_VgVT/mbei - alb*dT; + ibeis_t = ibeis*exp(a); + a = mcf*r_VgVT/mrei - alb*dT; + ireis_t = ireis*exp(a); + a = mcf*r_VgVT/mbep - alb*dT; + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(a); + a = mcf*r_VgVT/mrep - alb*dT; + ireps_t = ireps*exp(a); + //Internal b-c diode saturation current + a = r_VgVT/mbci; + ibcis_t = ibcis*exp(a); + //External b-c diode saturation currents + a = r_VgVT/mbcx; + ibcxs_t = ibcxs*exp(a); + //Saturation transfer current for substrate transistor + a = r_VgVT/msf; + itss_t = itss*exp(a); + //Saturation current for c-s diode + a = r_VgVT/msc; + iscs_t = iscs*exp(a); + //Zero bias hole charge + a = vdei_t/vdei; + qp0_t = qp0*(1.0+0.5*zei*(1.0-a)); + //Voltage separating ohmic and saturation velocity regime + a = vlim*(1.0-alvs*dT)*exp(zetaci*ln_qtt0); + k = (a-VT)/VT; + if (k < `LN_EXP_LIMIT) begin + vlim_t = VT + VT*ln(1.0+exp(k)); + end else begin + vlim_t = a; + end + //Neutral emitter storage time + a = 1.0+alb*dT; + k = 0.5*(a+sqrt(a*a+0.01)); + tef0_t = tef0*qtt0/k; + end else begin + //Internal b-e diode saturation currents + ibeis_t = ibeis*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireis_t = ireis*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Peripheral b-e diode saturation currents + ibeps_t = ibeps*exp(zetabet*ln_qtt0+vge/VT*(qtt0-1)); + ireps_t = ireps*exp(0.5*mg*ln_qtt0+0.5*vgbe0/VT*(qtt0-1)); + //Internal b-c diode saturation currents + ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); + //External b-c diode saturation currents + ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation transfer current for substrate transistor + itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); + //Saturation current for c-s diode + iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + //Zero bias hole charge + a = exp(zei*ln(vdei_t/vdei)); + qp0_t = qp0*(2.0-a); + //Voltage separating ohmic and saturation velocity regime + vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + //Neutral emitter storage time + zetatef = zetabet-zetact-0.5; + dvg0 = vgb-vge; + tef0_t = tef0*exp(zetatef*ln_qtt0-dvg0/VT*(qtt0-1)); + end - //Forward transit time in substrate transistor - tsf_t = tsf*exp((zetacx-1.0)*ln_qtt0); + //GICCR prefactor + c10_t = c10*exp(zetact*ln_qtt0+vgb/VT*(qtt0-1)); + + // Low-field internal collector resistance + rci0_t = rci0*exp(zetaci*ln_qtt0); + + //Voltage separating ohmic and saturation velocity regime + //vlim_t = vlim*exp((zetaci-avs)*ln_qtt0); + + //Internal c-e saturation voltage + vces_t = vces*(1+alces*dT); - //Saturation transfer current for substrate transistor - itss_t = itss*exp(zetasct*ln_qtt0+vgc/VT*(qtt0-1)); - //Saturation current for c-s diode - iscs_t = iscs*exp(zetasct*ln_qtt0+vgs/VT*(qtt0-1)); + //Internal b-c diode saturation current + //ibcis_t = ibcis*exp(zetabci*ln_qtt0+vgc/VT*(qtt0-1)); - //Capacitance for c-s junction - `TMPHICJ(cjs0,vds,zs,vpts,0,vgsc0,cjs0_t,vds_t,vpts_t) + //Internal b-c junction capacitance + `TMPHICJ(cjci0,vdci,zci,vptci,0,vgbc0,cjci0_t,vdci_t,vptci_t) + + //Low-current forward transit time + t0_t = t0*(1+alt0*dT+kt0*dT*dT); -end // Temperature update:end + //Saturation time constant at high current densities + thcs_t = thcs*exp((zetaci-1)*ln_qtt0); - -begin //Bias-dependent model evaluation + //Avalanche caurrent factors + favl_t = favl*exp(alfav*dT); + qavl_t = qavl*exp(alqav*dT); + + //Zero bias internal base resistance + rbi0_t = rbi0*exp(zetarbi*ln_qtt0); + + + //Peripheral b-e junction capacitance + `TMPHICJ(cjep0,vdep,zep,ajep,1,vgbe0,cjep0_t,vdep_t,ajep_t) + + //Tunneling current factors + if (V(br_bpei) < 0.0 || V(br_biei) < 0.0) begin // : HICTUN_T +// real a_eg,ab,aa; + ab = 1.0; + aa = 1.0; + a_eg=vgbe_t0/vgbe_t; + if(tunode==1 && cjep0 > 0.0 && vdep >0.0) begin + ab = (cjep0_t/cjep0)*sqrt(a_eg)*vdep_t*vdep_t/(vdep*vdep); + aa = (vdep/vdep_t)*(cjep0/cjep0_t)*pow(a_eg,-1.5); + end else if (tunode==0 && cjei0 > 0.0 && vdei >0.0) begin + ab = (cjei0_t/cjei0)*sqrt(a_eg)*vdei_t*vdei_t/(vdei*vdei); + aa = (vdei/vdei_t)*(cjei0/cjei0_t)*pow(a_eg,-1.5); + end + ibets_t = ibets*ab; + abet_t = abet*aa; + end + + + //Temperature mapping for tunneling current is done inside HICTUN + + `TMPHICJ(1.0,vdcx,zcx,vptcx,0,vgbc0,cratio_t,vdcx_t,vptcx_t) + cjcx01_t=cratio_t*cjcx01; + cjcx02_t=cratio_t*cjcx02; + + + //External b-c diode saturation currents + //ibcxs_t = ibcxs*exp(zetabcxt*ln_qtt0+vgc/VT*(qtt0-1)); + + + //Constant external series resistances + rcx_t = rcx*exp(zetarcx*ln_qtt0); + rbx_t = rbx*exp(zetarbx*ln_qtt0); + re_t = re*exp(zetare*ln_qtt0); + + //Forward transit time in substrate transistor + tsf_t = tsf*exp((zetacx-1.0)*ln_qtt0); + + //Capacitance for c-s junction + `TMPHICJ(cjs0,vds,zs,vpts,0,vgsc0,cjs0_t,vds_t,vpts_t) + + + end //of Thermal_update_with_self_heating + + +begin : Model_evaluation + //Intrinsic transistor //Internal base currents across b-e junction `HICDIO(ibeis,ibeis_t,mbei,V(br_biei),ibei) @@ -968,25 +1115,6 @@ begin //Bias-dependent model evaluation //Inverse of low-field internal collector resistance: needed in HICICK Orci0_t = 1.0/rci0_t; - //Avoid devide-by-zer and define infinity other way - //High current correction for 2D and 3D effects - if (ich != 0.0) - Oich = 1.0/ich; - else - Oich = 0.0; - - //Base current recombination time constant at b-c barrier - if (tbhrec != 0.0) - Otbhrec = 1.0/tbhrec; - else - Otbhrec = 0.0; - - //Collector punch-through voltage - if(vpt != 0.0) - Ovpt = 1.0/vpt; - else - Ovpt = 0.0; - //Initialization //Transfer current, minority charges and transit times @@ -996,8 +1124,10 @@ begin //Bias-dependent model evaluation i_0r = c10_t * limexp(V(br_bici)/VT); //Internal b-e and b-c junction capacitances and charges - `QCJMODF(cjei0_t,vdei_t,zei,ajei_t,V(br_biei),Cjei,Qjei) - `HICJCAP(cjci0_t,vdci_t,zci,vptci_t,V(br_bici),Cjci,Qjci) + `QJMODF(cjei0_t,vdei_t,zei,ajei_t,V(br_biei),Qjei) + Cjei = ddx(Qjei,V(bi)); + `HICJQ(cjci0_t,vdci_t,zci,vptci_t,V(br_bici),Qjci) + Cjci = ddx(Qjci,V(bi)); //Hole charge at low bias a_bpt = 0.05; @@ -1007,18 +1137,38 @@ begin //Bias-dependent model evaluation Q_0 = Q_bpt*(1+(b_q +sqrt(b_q*b_q+1.921812))/2); //Transit time calculation at low current density - `QCJMODF(cjci0_t,vdci_t,zci,2.4,V(br_bici),Cjcit,d1) - if(Cjcit > 0.0) + if(cjci0_t > 0.0) begin : CJMODF + real cV_f,cv_e,cs_q,cs_q2,cv_j,cdvj_dv; + cV_f = vdci_t*(1.0-exp(-ln(2.4)/zci)); + cv_e = (cV_f-V(br_bici))/VT; + cs_q = sqrt(cv_e*cv_e+1.921812); + cs_q2 = (cv_e+cs_q)*0.5; + cv_j = cV_f-VT*cs_q2; + cdvj_dv = cs_q2/cs_q; + Cjcit = cjci0_t*exp(-zci*ln(1.0-cv_j/vdci_t))*cdvj_dv+2.4*cjci0_t*(1.0-cdvj_dv); + end else begin + Cjcit = 0.0; + end + if(Cjcit > 0.0) begin cc = cjci0_t/Cjcit; - else + end else begin cc = 1.0; + end T_f0 = t0_t+dt0h*(cc-1.0)+tbvl*(1/cc-1.0); //Effective collector voltage vc = V(br_ciei)-vces_t; //Critical current for onset of high-current effects - `HICICK(vc,Orci0_t,vlim_t,Ovpt,ick,vceff) + begin : HICICK + a = vc/VT; + d1 = a-1; + vceff = (1.0+((d1+sqrt(d1*d1+1.921812))/2))*VT; + a = vceff/vlim_t; + ick = vceff*Orci0_t/sqrt(1.0+a*a); + ICKa = (vceff-vlim_t)*Ovpt; + ick = ick*(1.0+0.5*(ICKa+sqrt(ICKa*ICKa+1.0e-3))); + end //Initial formulation of forward and reverse component of transfer current Q_p = Q_0; @@ -1030,7 +1180,7 @@ begin //Bias-dependent model evaluation a_h = Oich*I_Tf1; itf = I_Tf1*(1.0+a_h); itr = i_0r/Q_p; - + //Initial formulation of forward transit time, diffusion, GICCR and excess b-c charge Q_bf = 0.0; Tf = T_f0; @@ -1057,18 +1207,20 @@ begin //Bias-dependent model evaluation Qf = T_f0*itf; `HICQFF(itf,ick,Tf,Qf,T_fT,Q_fT,Q_bf) Qr = Tr*itr; - if(Oich == 0.0) + if(Oich == 0.0) begin a = 1.0+(T_fT*itf+Qr)/Q_pT; - else + end else begin a = 1.0+(T_fT*I_Tf1*(1.0+2.0*a_h)+Qr)/Q_pT; + end d_Q = -(Q_pT-(Q_0+Q_fT+Qr))/a; //Limit maximum change of Q_pT a = abs(0.3*Q_pT); if(abs(d_Q) > a) begin - if (d_Q>=0) + if (d_Q>=0) begin d_Q = a; - else + end else begin d_Q = -a; + end end Q_pT = Q_pT+d_Q; l_it = l_it+1; @@ -1092,20 +1244,20 @@ begin //Bias-dependent model evaluation it = itf-itr; /* - //NQS Effect - - + // NQS Effect:Please incert here the hand-coded Weil's approach after getting + // C-code from the model compilers. */ - //Diffusion charges for further use Qdei = Qf; Qdci = Qr; //High-frequency emitter current crowding (lateral NQS) - //Currently not accurate: using ddx() operator may provide right formulation - qrbi = fcrbi*(Qjei+Qdei+Qjci+Qdci); + Cdei = ddx(Qdei,V(bi)); + Cdci = ddx(Qdci,V(bi)); + Crbi = fcrbi*(Cjei+Cjci+Cdei+Cdci); + qrbi = Crbi*V(br_bpbi_v); //HICCR: end @@ -1113,39 +1265,110 @@ begin //Bias-dependent model evaluation `HICDIO(ibcis,ibcis_t,mbci,V(br_bici),ibci) //Avalanche current - `HICAVL(itf,V(br_bici),Cjci,iavl) + if((V(br_bici) < 0.0) && (favl_t > 0.0) && (cjci0_t > 0.0)) begin : HICAVL + real v_bord,v_q,U0,av,avl,S_avl; + v_bord = vdci_t-V(br_bici); + v_q = qavl_t/Cjci; + U0 = qavl_t/cjci0_t; + if(v_bord > U0) begin + av = favl_t*exp(-v_q/U0); + avl = av*(U0+(1.0+v_q/U0)*(v_bord-U0)); + end else begin + avl = favl_t*v_bord*exp(-v_q/v_bord); + end + iavl = itf*avl; + end else begin + iavl = 0.0; + end //Excess base current from recombination at the b-c barrier ibh_rec = Q_bf*Otbhrec; //Internal base resistance - `HICRBI(rbi0_t,fdqr0,fgeo,fqi,qp0_t,Qjei,Qf,ibei,rbi) + if(rbi0_t > 0.0) begin : HICRBI + real Qz_nom,f_QR,f_p,ETA,Qz0,fQz; + // Consideration of conductivity modulation + // To avoid convergence problem hyperbolic smoothing used + f_QR = (1+fdqr0)*qp0_t; + Qz0 = Qjei+Qjci+Qf; + Qz_nom = 1+Qz0/f_QR; + fQz = 0.5*(Qz_nom+sqrt(Qz_nom*Qz_nom+0.01)); + rbi = rbi0_t/fQz; + // Consideration of emitter current crowding + if( ibei > 0.0) begin + ETA = rbi*ibei*fgeo/VT; + if(ETA < 1.0e-6) begin + rbi = rbi*(1.0-0.5*ETA); + end else begin + rbi = rbi*ln(1.0+ETA)/ETA; + end + end + // Consideration of peripheral charge + if(Qf > 0.0) begin + rbi = rbi*(Qjei+Qf*fqi)/(Qjei+Qf); + end + end else begin + rbi = 0.0; + end //Base currents across peripheral b-e junction `HICDIO(ibeps,ibeps_t,mbep,V(br_bpei),ibep) `HICDIO(ireps,ireps_t,mrep,V(br_bpei),irep) //Peripheral b-e junction capacitance and charge - `QCJMODF(cjep0_t,vdep_t,zep,ajep_t,V(br_bpei),Cjep,Qjep) + //Following module may be replaced by calling QJMODF + //if ddx() produces correct results for Cjep using that macro. + if (cjep0_t >0.0) begin : QJEP + real V_f,v_e,s_q,s_q2,v_j,Q_j; + V_f = vdep_t*(1.0-exp(-ln(ajep_t)/zep)); + v_e = (V_f-V(br_bpei))/VT; + s_q = sqrt(v_e*v_e+1.921812); + s_q2 = (v_e+s_q)*0.5; + v_j = V_f-VT*s_q2; + Q_j = cjep0_t*vdep_t*(1.0-exp(ln(1.0-v_j/vdep_t)*(1.0-zep)))/(1.0-zep); + Qjep = Q_j+ajep_t*cjep0_t*(V(br_bpei)-v_j); + end else begin + Qjep = 0.0; + end + + //`QJMODF(cjep0_t,vdep_t,zep,ajep_t,V(br_bpei),Qjep) + Cjep = ddx(Qjep,V(bp)); + + + //Tunelling current + if (V(br_bpei) <0.0 || V(br_biei) < 0.0) begin : HICTUN + real pocce,czz; + if(tunode==1 && cjep0_t > 0.0 && vdep_t >0.0) begin + pocce = exp((1-1/zep)*ln(Cjep/cjep0_t)); + czz = -(V(br_bpei)/vdep_t)*ibets_t*pocce; + ibet = czz*exp(-abet_t/pocce); + end else if (tunode==0 && cjei0_t > 0.0 && vdei_t >0.0) begin + pocce = exp((1-1/zei)*ln(Cjei/cjei0_t)); + czz = -(V(br_biei)/vdei_t)*ibets_t*pocce; + ibet = czz*exp(-abet_t/pocce); + end else begin + ibet = 0.0; + end + end else begin + ibet = 0.0; + end - //Tunneling current - `HICTUN(vgbe_t0,vgbe_t,cjep0_t,cjei0_t,vdep_t,vdei_t,V(br_bpei),V(br_biei),Cjep,Cjei,ibet) //Depletion capacitance and charge at peripheral b-c junction (bp,ci) - `HICJCAP(cjcx02_t,vdcx_t,zcx,vptcx_t,V(br_bpci),cjcx0_t_ii,qjcx0_t_ii) + `HICJQ(cjcx02_t,vdcx_t,zcx,vptcx_t,V(br_bpci),qjcx0_t_ii) //Base currents across peripheral b-c junction (bp,ci) `HICDIO(ibcxs,ibcxs_t,mbcx,V(br_bpci),ijbcx) //Depletion capacitance and charge at external b-c junction (b,ci) - `HICJCAP(cjcx01_t,vdcx_t,zcx,vptcx_t,V(br_bci),cjcx0_t_i,qjcx0_t_i) + `HICJQ(cjcx01_t,vdcx_t,zcx,vptcx_t,V(br_bci),qjcx0_t_i) //Depletion substrate capacitance and charge at s-c junction (si,ci) - `HICJCAP(cjs0_t,vds_t,zs,vpts_t,V(br_sici),Cjs,Qjs) + `HICJQ(cjs0_t,vds_t,zs,vpts_t,V(br_sici),Qjs) //Parasitic substrate transistor transfer current and diffusion charge - HSUM = msf*VT; - if(itss > 0.0) begin + if(itss > 0.0) begin : Sub_Transfer + HSUM = msf*VT; HSa = limexp(V(br_bpci)/HSUM); HSb = limexp(V(br_sici)/HSUM); HSI_Tsu = itss_t*(HSa-HSb); @@ -1163,53 +1386,59 @@ begin //Bias-dependent model evaluation `HICDIO(iscs,iscs_t,msc,V(br_sici),ijsc) //Self-heating calculation - if (flsh == 1 && rth > 0.0) begin + if (flsh == 1 && rth >= `MIN_R) begin pterm = V(br_ciei)*it + (vdci_t-V(br_bici))*iavl; - end else if (flsh == 2 && rth > 0.0) begin + end else if (flsh == 2 && rth >= `MIN_R) begin pterm = V(br_ciei)*it + (vdci_t-V(br_bici))*iavl + ibei*V(br_biei) + ibci*V(br_bici) + ibep*V(br_bpei) + ijbcx*V(br_bpci) + ijsc*V(br_sici); - if (rbi > 0.0) begin + if (rbi >= `MIN_R) begin pterm = pterm + V(br_bpbi_i)*V(br_bpbi_i)/rbi; end - if (re_t > 0.0) begin + if (re_t >= `MIN_R) begin pterm = pterm + V(br_eie_i)*V(br_eie_i)/re_t; end - if (rcx_t > 0.0) begin + if (rcx_t >= `MIN_R) begin pterm = pterm + V(br_cic_i)*V(br_cic_i)/rcx_t; end - if (rbx_t > 0.0) begin + if (rbx_t >= `MIN_R) begin pterm = pterm + V(br_bbp_i)*V(br_bbp_i)/rbx_t; end end -end //Bias-dependent model evaluation - -begin //Define branch sources +end //of Model_evaluation +begin : Load_sources + + I(br_biei) <+ `Gmin*V(br_biei); + I(br_bici) <+ `Gmin*V(br_bici); + I(br_bci) <+ ddt(qjcx0_t_i); I(br_bci) <+ ddt(cbcpar1*V(br_bci)); I(br_bpci) <+ ddt(cbcpar2*V(br_bpci)); - if (rbx > 0.0) begin + if (rbx >= `MIN_R) begin I(br_bbp_i) <+ V(br_bbp_i)/rbx_t; end else begin - V(br_bbp_v) <+ 0.0; +//dw V(br_bbp_v) <+ 0.0; + I(br_bbp_i) <+ V(br_bbp_i)/`MIN_R; end - if(rbi0 > 0.0) begin + if(rbi0 >= `MIN_R) begin I(br_bpbi_i) <+ V(br_bpbi_i)/rbi; I(br_bpbi_i) <+ ddt(qrbi); end else begin - V(br_bpbi_v) <+ 0.0; +//dw V(br_bpbi_v) <+ 0.0; + I(br_bpbi_i) <+ V(br_bpbi_i)/`MIN_R; end if (tunode==1.0) begin - I(br_bpei) <+ -ibet+ibep+irep; - I(br_bpei) <+ ddt(Qjep); - I(br_biei) <+ ibei+irei+ibh_rec; - I(br_biei) <+ ddt(Qdei+Qjei); + I(br_bpei) <+ -ibet; end else begin - I(br_bpei) <+ ibep+irep; - I(br_bpei) <+ ddt(Qjep); - I(br_biei) <+ -ibet+ibei+irei+ibh_rec; - I(br_biei) <+ ddt(Qdei+Qjei); + I(br_biei) <+ -ibet; end + I(br_bpei) <+ ibep; + I(br_bpei) <+ irep; + I(br_bpei) <+ ddt(Qjep); + I(br_biei) <+ ibei; + I(br_biei) <+ irei; + I(br_biei) <+ ibh_rec; + I(br_biei) <+ ddt(Qdei+Qjei); I(br_bpsi) <+ HSI_Tsu; I(br_bpci) <+ ijbcx; I(br_bpci) <+ ddt(qjcx0_t_ii+Qdsu); @@ -1220,45 +1449,72 @@ begin //Define branch sources I(br_sici) <+ ijsc; I(br_sici) <+ ddt(Qjs); I(br_ciei) <+ it; - if (rcx > 0.0) begin + if (rcx >= `MIN_R) begin I(br_cic_i) <+ V(br_cic_i)/rcx_t; end else begin - V(br_cic_v) <+ 0.0; +//dw V(br_cic_v) <+ 0.0; + I(br_cic_i) <+ V(br_cic_i)/`MIN_R; end - if (re > 0.0) begin + if (re >= `MIN_R) begin I(br_eie_i) <+ V(br_eie_i)/re_t; end else begin - V(br_eie_v) <+ 0.0; +//dw V(br_eie_v) <+ 0.0; + I(br_eie_i) <+ V(br_eie_i)/`MIN_R; end - if(rsu > 0.0) begin + if(rsu >= `MIN_R) begin I(br_sis_i) <+ V(br_sis_i)/rsu; I(br_sis_i) <+ ddt(csu*V(br_sis_i)); end else begin - V(br_sis_v) <+ 0.0; +//dw V(br_sis_v) <+ 0.0; + I(br_sis_i) <+ V(br_sis_i)/`MIN_R; end - if(flsh == 0 || rth == 0.0) begin - V(br_sht) <+ 0.0; + + // Following code is an intermediate solution (if branch contribution is not supported): + // ****************************************** + if(flsh == 0 || rth < `MIN_R) begin + I(br_sht) <+ V(br_sht)/`MIN_R; end else begin I(br_sht) <+ V(br_sht)/rth-pterm; I(br_sht) <+ ddt(cth*V(br_sht)); end -end //Define branch source + // ****************************************** + + // For simulators having no problem with V(br_sht) <+ 0.0 + // with external thermal node, follwing code may be used. + // Note that external thermal node should remain accessible + // even without self-heating. + // ******************************************** + // if(flsh == 0 || rth < `MIN_R) begin + // V(br_sht) <+ 0.0; + // end else begin + // I(br_sht) <+ V(br_sht)/rth-pterm; + // I(br_sht) <+ ddt(cth*V(br_sht)); + // end + // ******************************************** + +end //of Load_sources + -`NOISE begin //Define noise sources +`NOISE begin : Noise_sources //Thermal noise fourkt = 4.0 * `P_K * Tdev; - if(rbx > 0.0) + if(rbx >= `MIN_R) begin I(br_bbp_i) <+ white_noise(fourkt/rbx_t, "thermal"); - if(rbi0 > 0.0) + end + if(rbi0 >= `MIN_R) begin I(br_bpbi_i) <+ white_noise(fourkt/rbi, "thermal"); - if(rcx > 0.0) + end + if(rcx >= `MIN_R) begin I(br_cic_i) <+ white_noise(fourkt/rcx_t, "thermal"); - if(re > 0.0) + end + if(re >= `MIN_R) begin I(br_eie_i) <+ white_noise(fourkt/re_t, "thermal"); - if(rsu > 0.0) + end + if(rsu >= `MIN_R) begin I(br_sis_i) <+ white_noise(fourkt/rsu, "thermal"); + end //Flicker noise : Fully correlated between the perimeter and internal base-node flicker_Pwr = kf*pow((ibei+ibep),af); @@ -1269,25 +1525,18 @@ end //Define branch source end //Shot noise - - twoq = 2.0 * `P_Q; + twoq = 2.0 * `P_Q; I(br_ciei) <+ white_noise(twoq*it, "shot"); I(br_cibi) <+ white_noise(twoq*iavl, "shot"); - - I(br_biei) <+ white_noise(twoq*ibei, "shot"); - - I(br_bici) <+ white_noise(twoq*abs(ibci), "shot"); - - I(br_bpei) <+ white_noise(twoq*ibep, "shot"); - - I(br_bpci) <+ white_noise(twoq*abs(ijbcx), "shot"); - - I(br_sici) <+ white_noise(twoq*abs(ijsc), "shot"); - - + I(br_biei) <+ white_noise(twoq*ibei, "shot"); + I(br_bici) <+ white_noise(twoq*abs(ibci), "shot"); + I(br_bpei) <+ white_noise(twoq*ibep, "shot"); + I(br_bpci) <+ white_noise(twoq*abs(ijbcx), "shot"); + I(br_sici) <+ white_noise(twoq*abs(ijsc), "shot"); + //Correlated noise not yet implemented -end //Define noise sources +end //of Noise_sources end //analog endmodule