/* EKV MOS model version 2.6 rev.15 with documentation at: http://ekv.epfl.ch Matthias Bucher, Christophe Lallement, Christian Enz, Fabien Theodoloz, Francois Krummenacher Electronics Laboratories, Swiss Federal Institute of Technology Lausanne, Switzerland This Verilog-A was developed by Wladek Grabinski with modifications by Tiburon Design Automation (www.tiburon-da.com). This software has been provided pursuant to a License Agreement containing restrictions on its use. It may not be copied or distributed in any form or medium, disclosed to third parties, reverse engineered or used in any manner not provided for in said License Agreement except with the prior written authorization. Licensed under the Educational Community License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://opensource.org/licenses/ECL-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. $RCSfile: ekv.va,v $ $Revision: 1.9 $ $Date: 2003/12/17 01:20:10 $ $RCSfile: ekv.va,v $ $Revision: 2.6.15 $ $Date: 2020/05/29 11:50:10 $ */ /* `include "disciplines.vams" `include "constants.vams" `include "compact.vams" */ // Macros for the model/instance parameters // // MPRxx model parameter real // MPIxx model parameter integer // IPRxx instance parameter real // IPIxx instance parameter integer // || // cc closed lower bound, closed upper bound // oo open lower bound, open upper bound // co closed lower bound, open upper bound // oc open lower bound, closed upper bound // cz closed lower bound=0, open upper bound=inf // oz open lower bound=0, open upper bound=inf // nb no bounds // ex no bounds with exclude // sw switch(integer only, values 0=false and 1=true) // ty switch(integer only, values -1=p-type and +1=n-type) // // IPM instance parameter mFactor(multiplicity, implicit for LRM 2.2) // OPP operating point parameter, includes units and description for printing `define OPP(nam,uni,des) (* units=uni, desc=des *) real nam; `define OPM(nam,uni,des) (* units=uni, desc=des, multiplicity="multiply" *) real nam; `define OPD(nam,uni,des) (* units=uni, desc=des, multiplicity="divide" *) real nam; `define MPRnb(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def; `define MPRex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter real nam=def exclude exc; `define MPRcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr]; `define MPRoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr); `define MPRco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from[lwr:upr); `define MPRoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter real nam=def from(lwr:upr]; `define MPRcz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from[ 0:inf); `define MPRoz(nam,def,uni, des) (* units=uni, desc=des *) parameter real nam=def from( 0:inf); `define MPInb(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def; `define MPIex(nam,def,uni,exc, des) (* units=uni, desc=des *) parameter integer nam=def exclude exc; `define MPIcc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr]; `define MPIoo(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr); `define MPIco(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from[lwr:upr); `define MPIoc(nam,def,uni,lwr,upr,des) (* units=uni, desc=des *) parameter integer nam=def from(lwr:upr]; `define MPIcz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0:inf); `define MPIoz(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from( 0:inf); `define MPIsw(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ 0: 1]; `define MPIty(nam,def,uni, des) (* units=uni, desc=des *) parameter integer nam=def from[ -1: 1] exclude 0; `define IPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def; `define IPRex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def exclude exc; `define IPRcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr]; `define IPRoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr); `define IPRco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[lwr:upr); `define IPRoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from(lwr:upr]; `define IPRcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from[ 0:inf); `define IPRoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def from( 0:inf); `define IPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def; `define IPIex(nam,def,uni,exc, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def exclude exc; `define IPIcc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr]; `define IPIoo(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr); `define IPIco(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[lwr:upr); `define IPIoc(nam,def,uni,lwr,upr,des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from(lwr:upr]; `define IPIcz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from[ 0:inf); `define IPIoz(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def from( 0:inf); `define BPRco(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[lwr : upr); `define BPRoz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from(0.0 : inf); `define BPRcz(nam, def, uni, des) (* units = uni, type = "instance", desc = des *) parameter real nam = def from[0.0 : inf); `define BPIcc(nam, def, uni, lwr, upr, des) (* units = uni, type = "instance", desc = des *) parameter integer nam = def from[lwr : upr]; `define BPInb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter integer nam=def; `define BPRnb(nam,def,uni, des) (* units=uni, type = "instance", desc=des *) parameter real nam=def; // includes: in case we do not want to include any other file [AB:040902] // we can just add the following section in this file // AB: i hope this may help our code to be easily transported //---------------------------------------- // from disciplines.h we need: // Electrical // Current in amperes nature Current units = "A"; access = I; idt_nature = Charge; `ifdef CURRENT_ABSTOL abstol = `CURRENT_ABSTOL; `else abstol = 1e-12; `endif endnature // Charge in coulombs nature Charge units = "coul"; access = Q; ddt_nature = Current; `ifdef CHARGE_ABSTOL abstol = `CHARGE_ABSTOL; `else abstol = 1e-14; `endif endnature // Potential in volts nature Voltage units = "V"; access = V; idt_nature = Flux; `ifdef VOLTAGE_ABSTOL abstol = `VOLTAGE_ABSTOL; `else abstol = 1e-6; `endif endnature // Flux in Webers nature Flux units = "Wb"; access = Phi; ddt_nature = Voltage; `ifdef FLUX_ABSTOL abstol = `FLUX_ABSTOL; `else abstol = 1e-9; `endif endnature // Conservative discipline discipline electrical potential Voltage; flow Current; enddiscipline // Signal flow disciplines discipline voltage potential Voltage; enddiscipline discipline current potential Current; enddiscipline //from constants.h we need `define C_EPSSIL 1.03594314e-10 `define C_EPSOX 34.5e-12 `define C_QE 1.602e-19 `define C_K 1.3807e-23 `define P_K 1.3806226e-23 `define P_EPS0 8.85418792394420013968e-12 `define P_CELSIUS0 273.15 `define POS_MIN 1.0E-6 `define SQRT2 1.4142135623730950488016887242097 `define ONE3RD 0.33333333333333333333333333333333 `define ONESQRT2 0.70710678118654752440084436210485 //if any other constant is needed it may be copied from the constants.h and be put above. //------------------------------------------ end of includes `define FWD 1 `define REV -1 // AB 040902 `define NOT_GIVEN -1.0e21 `define DEFAULT_TNOM 25 module ekv_va(d,g,s,b); // %%DEVICE_CLASS=MOS(NMOS:TYPE=1,PMOS:TYPE=-1)%% // Node definitions inout d,g,s,b; // external nodes electrical d,g,s,b; // external nodes // Branch definitions branch (d,s) ds; branch (d,b) db; branch (s,b) sb; branch (g,b) gb; // * Local variables real tmp1, tmp2, tmp3; // temporary variables real VGprime, GAMMAprime;// short and narrow channel effect real VP, VPprime; // pinch-off voltage real if_, ir, irprime; // normalized currents real VDSS, VDSSprime;// saturation voltage real deltaL, Leq; // channel length reduction real beta; // transconductance factor real n; // slope factor real Ispec; // specific current real Vt; // k*T/q real gm, gms, gmbs, gds; real isub, Isub; real inv_Vt, Vt_01, Vt_2, Vt_4, Vt_Vt, Vt_Vt_2, Vt_Vt_16; real eps_COX, eps_COX_W, eps_COX_L; real Lc, Lc_LAMBDA, IBN_2, T0, T1, eta_qi; real inv_UCRIT, Lc_UCRIT, Lc_IBB, IBA_IBB; integer Mode; real WETA_W, LETA_L; real E0_Q_1, AWL; real T, KP_Weff; real Eg, refEg, deltaT, ratioT, Tnom; real VTO_T, VTO_S, KP_T, UCRIT_T, IBB_T, PHI_T, GAMMA_S; real sqrt_Lprime_Lmin; real GAMMAstar, sqrt_GAMMAstar; real big_sqrt_VP; real big_sqrt_VP0, VP0; real PHI_VD, PHI_VS; real sqrt_PHI; real sqrt_PHI_VP, sqrt_PHI_VD, sqrt_PHI_VS; real sqrt_PHI_VD_Vt, sqrt_PHI_VS_Vt; real Vds, deltaV_2, Vip; real VDSS_sqrt, sqrt_VDSS_deltaV, sqrt_Vds_VDSS_deltaV; real VDSSprime_sqrt, sqrt_VDSSprime_deltaV, sqrt_Vds_VDSSprime_deltaV; real if_ir; real sqrt_if, sqrt_ir, sqrt_irprime; real dif_dv, dir_dv, dirprime_dv; // Charge related variables real sif, sir, sif2, sir2, sif3, sir3; real sif_sir_2; real qi, qb; real QD, QS, QI, QB, QG; real VP_PHI_eps, sqrt_PHI_VP_2, WLCox; real n_Vt_COX, n_1, n_1_n; // Variables used for derivatives computation real dVP_dVD, dVP_dVG, dVP_dVS; real dif_dVD, dif_dVS, dif_dVG; real dir_dVD, dir_dVS, dir_dVG; real dVDSS_dVD, dVDSS_dVG, dVDSS_dVS; real ddeltaV_dVD, ddeltaV_dVG, ddeltaV_dVS; real dVip_dVD, dVip_dVG, dVip_dVS; real dVDSSprime_dVD, dVDSSprime_dVG, dVDSSprime_dVS; real dirprime_dVD, dirprime_dVG, dirprime_dVS; real dLeq_dVD, dLeq_dVG, dLeq_dVS; real dbeta_dVD, dbeta_dVG, dbeta_dVS; real VGstar, sqrt_VGstar; real VG, VD, VS; real Von, Vdsat, Id, Ibd; real Gn; real GAMMA_sqrt_PHI, Lmin, Lprime, T0_GAMMA_1, THETA_VP_1, Vc; real Vdsprime, Vt_Vc, dGAMMAprime_dVD, dGAMMAprime_dVG, dGAMMAprime_dVS; real dVPprime_dVD, dVPprime_dVG, dVPprime_dVS, ddeltaL_dVD, ddeltaL_dVG; real ddeltaL_dVS, dn_dVD, dn_dVG, dn_dVS; real log_Vc_Vt, sqrt_PHI_VP0, sqrt_VP_Vt; real Lc_IBB_Vib, Vib, dIsub_factor, exp_ib; real inv_Vib, sqrt_PHI_VP2_2; real V0, deltaVFB, vL; real dQI_dVD, dQI_dVS, dQI_dVG; real dQB_dVD, dQB_dVS, dQB_dVG; real Leff, Weff; real RSeff, RDeff; real yk, z0, zk; real EPSOX, epssil; real ddt_QD, ddt_QS; //DIODES realted variables [AB: 040902] real as_i, ad_i, ps_i, pd_i, v_di_b, v_si_b; real temp_arg, tmp0; real js_t, jsw_t, jswg_t; real pb_t, pbsw_t, pbswg_t; real cj_t, cjsw_t, cjswg_t; real njts_t, njtssw_t, njtsswg_t; real is_d, arg_d, is_s, arg_s; real f_breakdown_d, f_breakdown_s, idb_tun, isb_tun; real csb_d, cssw_d, csswg_d; real csb_s, cssw_s, csswg_s; real qjd, qjs; // parameter definitions parameter integer TYPE = 1 from [-1:1] exclude 0; // NMOS=1, PMOS=-1 parameter integer Noise = 1 from [0:1]; // Set to zero to prevent noise calculation parameter real Trise = 0.0 from [-inf:inf]; // Difference sim. temp and device temp [C deg] // parameter real Temp = -`NOT_GIVEN from [`P_CELSIUS0:inf]; // Device temp [C] //AB: the parameter name Temp is not working for no obvious reason; changed to TEMP parameter real TEMP = -`NOT_GIVEN from [`P_CELSIUS0:inf]; // Device temp [C] parameter real TNOM = -`NOT_GIVEN; // Temperature [C] // Instance parameters // - intrinsic model `IPRoz( L ,1.0e-5 ,"m" ,"Length" ) `IPRoz( W ,1.0e-5 ,"m" ,"Total width including fingers" ) `IPIco( M ,1 ,"" ,1 ,inf ,"Parallel multiplier" ) `IPIco( NS ,1 ,"" ,1 ,inf ,"Series multiplier" ) `BPRnb( DTEMP ,0.0 ,"K" ,"Offset of device temperature" ) // - external parasitics `IPRcz( AS ,0.0 ,"m^2" ,"Source-to-substrate junction area" ) `IPRcz( AD ,0.0 ,"m^2" ,"Drain-to-substrate junction area" ) `IPRcz( PS ,0.0 ,"m" ,"Source-to-substrate junction perimeter" ) `IPRcz( PD ,0.0 ,"m" ,"Drain-to-substrate junction perimeter" ) `IPRcz( NRS ,1.0 ,"" ,"Number of squares in source" ) `IPRcz( NRD ,1.0 ,"" ,"Number of squares in drain" ) // *** Process related parameters parameter real COX = 2.0E-3 from [0.0:inf]; // Gate oxide capacitance per unit area [F] parameter real XJ = 300E-9 from [0.0:inf]; // Junction depth [m] //*** Threshold voltage/substrate effect parameters (long-channel) parameter real VTO = 0.5 from [-inf:inf]; // Long-channel threshold voltage [V] parameter real TCV = 1.0e-3; // Threshold voltage temperature coefficient [V/K] parameter real GAMMA = 0.7 from [0.0:inf]; // Body effect parameter parameter real PHI = 0.5 from [0.2:inf]; // Bulk Fermi potential [V] //*** Mobility parameters (long-channel) *** parameter real KP = 150E-6 from [0.0:inf]; // Transconductance parameter [A/V/V] parameter real BEX = -1.5; // Mobility temperature exponent parameter real THETA = 0.0 from [0.0:inf]; // Mobility reduction coefficient [1/V] parameter real E0 = 1.0E8; // Mobility reduction coefficient [V/m] //*** Velocity sat./channel length mod. parameters (short-channel) parameter real UCRIT = 2.0E6 from [0.0:inf]; // Longitudinal critical field [V/m] parameter real UCEX = 0.8; // Longitudinal critical field temperature exponent parameter real LAMBDA = 0.8 from [0.0:inf]; // Depletion length coefficient (channel length modulation) //*** Process related parameters parameter real DL = -0.01E-6; // Channel width correction [m] parameter real DW = -0.01E-6; // Channel length correction [m] //*** Threshold voltage/substrate effect parameter (narrow-channel) parameter real WETA = 0.2 from [0.0:inf]; // Narrow-channel effect coefficient //*** Threshold voltage/substrate effect parameters (short-channel) parameter real LETA = 0.3 from [0.0:inf]; // Short-channel effect coefficient parameter real Q0 = 230E-6 from [0.0:inf]; // Reverse short channel effect peak charge density parameter real LK = 0.4E-6 from [0.0:inf]; // Reverse short channel effect characteristic length [m] //*** Substrate current parameters parameter real IBA = 5.0E8 from [0.0:inf]; // First impact ionization coefficient [1/m] parameter real IBB = 4.0E8 from [0.0:inf]; // Second impact ionization coefficient [V/m] parameter real IBBT = 9.0e-4; // Temperature coefficient for IBB [1/K] parameter real IBN = 1.0 from [0.0:inf]; // Saturation voltage factor for impact ionization //*** Series resistance parameters parameter real RSH = 0.0 from [0.0:inf]; // Sheet resistance [Ohms] parameter real HDIF = 0.5E-6 from [0.0:inf]; // Sheet resistance multipler //*** for MC analysis fk 25/05/97 parameter real AVTO = 1E-6 from [0.0:inf]; // Area related threshold voltage mismatch parameter [Vm] parameter real AKP = 1E-6 from [0.0:inf]; // Area related gain mismatch parameter [m] parameter real AGAMMA = 1E-6 from [0.0:inf]; // Area related body effect mismatch parameter [sqr(V) m] parameter real AF = 1.0 from (0:inf); // Flicker noise exponent parameter real KF = 0.0 from [0:inf); // Flicker noise coefficient //*** JUNCTION DRAIN-BULK AND SOURCE-BULK AREA, CURRENT, CAPACITANCE [AB:040902] parameter real xd_n = 1.0 from [0.0:inf); parameter real xd_js = 1.0E-09 from [0.0:inf); parameter real xd_jsw = 1.0E-12 from [0.0:inf); parameter real xd_jswg = 1.0E-12 from [0.0:inf); parameter real xd_mj = 0.900 from [0.0:1.0]; parameter real xd_mjsw = 0.700 from [0.0:1.0]; parameter real xd_mjswg = 0.700 from [0.0:1.0]; parameter real xd_pb = 0.800 from (0.0:inf); parameter real xd_pbsw = 0.600 from (0.0:inf); parameter real xd_pbswg = 0.600 from (0.0:inf); parameter real xd_cj = 1.0E-09 from [0.0:inf); parameter real xd_cjsw = 1.0E-12 from [0.0:inf); parameter real xd_cjswg = 1.0E-12 from [0.0:inf); parameter real xd_gmin = 0.0 from [0.0:inf); parameter real xd_xjbv = 0.0 from [0.0:inf); parameter real xd_bv = 10.0 from [0.0:inf); parameter real xd_njts = 1.0 from [0.0:inf); parameter real xd_njtssw = 1.0 from [0.0:inf); parameter real xd_njtsswg = 1.0 from [0.0:inf); parameter real xd_vts = 0.0 from [0.0:inf); parameter real xd_vtssw = 0.0 from [0.0:inf); parameter real xd_vtsswg = 0.0 from [0.0:inf); parameter real tp_xti = 3.0 from (-inf:inf); parameter real tp_cj = 0.0 from (-inf:inf); parameter real tp_cjsw = 0.0 from (-inf:inf); parameter real tp_cjswg = 0.0 from (-inf:inf); parameter real tp_pb = 0.0 from (-inf:inf); parameter real tp_pbsw = 0.0 from (-inf:inf); parameter real tp_pbswg = 0.0 from (-inf:inf); parameter real tp_njts = 0.0 from [0.0:inf); parameter real tp_njtssw = 0.0 from [0.0:inf); parameter real tp_njtsswg = 0.0 from [0.0:inf); analog begin // Set constant EPSOX = 3.9 * `P_EPS0; epssil = 11.7 * `P_EPS0; Ibd = 0.0; // The following are necessary to prevent memory states being reserved: THETA_VP_1 = 0.0; VPprime = 0.0; sqrt_VP_Vt = 0.0; // Geometry, voltage and temperature independent model variables eps_COX = epssil/COX; Lc = sqrt(eps_COX*XJ); Lc_LAMBDA = Lc * LAMBDA; eps_COX_W = 3.0 * eps_COX * WETA; eps_COX_L = eps_COX * LETA; IBN_2 = IBN + IBN; T0 = COX / (epssil*E0); V0 = (Q0+Q0) / COX; eta_qi = TYPE > 0 ? 0.5 : 0.3333333333333; /* Model working variables, geometry and voltage independent, * which need to be updated after temperature change * EKV model internal variables depending on temperature. */ /* If Temp is explicitly specified, use that value otherwise use Tckt+Trise */ if (TEMP == -`NOT_GIVEN) //AB: 040902 Temp -> TEMP T = $temperature + Trise; else T = TEMP + `P_CELSIUS0; //AB: 040902 Temp -> TEMP if (TNOM == -`NOT_GIVEN) Tnom = `DEFAULT_TNOM + `P_CELSIUS0; else Tnom = TNOM + `P_CELSIUS0; Vt = $vt(T); Vt_01 = 0.1 * Vt; inv_Vt = 1.0 / Vt; Vt_2 = Vt + Vt; Vt_4 = Vt_2 + Vt_2; Vt_Vt = Vt * Vt; Vt_Vt_2 = Vt_Vt + Vt_Vt; Vt_Vt_16 = 16.0 * Vt_Vt; Eg = 1.16 - 7.02e-4 * T * T / (T + 1108.0); refEg = 1.16 - (7.02e-4*Tnom*Tnom) / (Tnom + 1108.0); deltaT = T - Tnom; ratioT = T / Tnom; VTO_T = VTO - TCV * deltaT; KP_T = KP * pow(ratioT, BEX); UCRIT_T = UCRIT * pow(ratioT, UCEX); IBB_T = IBB * (1.0 + IBBT * deltaT); PHI_T = PHI * ratioT - 3.0 * Vt * ln(ratioT) - refEg * ratioT + Eg; // !! mb 99/07/30 prevents PHI from becoming smaller than 0.2 tmp1 = 0.2; tmp2 = PHI_T - tmp1; PHI_T = 0.5*(tmp2 + sqrt(tmp2*tmp2 + Vt*Vt)) + tmp1; sqrt_PHI = sqrt(PHI_T); inv_UCRIT = 1.0/UCRIT_T; Lc_UCRIT = Lc * UCRIT_T; Lc_IBB = Lc * IBB_T; IBA_IBB = IBA / IBB_T; /* VTO, KP and GAMMA with variation for MC analysis if required. * The default value for model parameters AVTO, AKP and AGAMMA * is set to 1e-6 to allow meaningful sensitivity analysis. Only * the deviation from this value has to be taken into account */ // wg: for userc.c and verilog implementations Leff = L + DL; // wg: for userc.c and verilog implementations Weff = W + DW; Vc = UCRIT_T*Leff; // NOTE: use L if necessary log_Vc_Vt = Vt*(ln(0.5*Vc*inv_Vt)-0.6); // mb 98/02/05 (r1) // de-normalization AWL = 1.0/sqrt(Weff*Leff); if (TYPE > 0) VTO_S = ((AVTO != 1e-6) ? AWL*(AVTO - 1e-6) + VTO_T : VTO_T); else VTO_S = ((AVTO != 1e-6) ? AWL*(1e-6 - AVTO) - VTO_T: -VTO_T); KP_Weff = Weff * ((AKP != 1e-6) ? KP_T*(1 + (AKP - 1e-6)*AWL) : KP_T); GAMMA_S = ((AGAMMA !=1e-6) ? GAMMA + (AGAMMA - 1e-6)*AWL : GAMMA); GAMMA_sqrt_PHI = GAMMA_S*sqrt_PHI; /* ************************************ * STATIC MODEL EQUATIONS * *************************************/ // VGprime: if (V0 == 0.0) deltaVFB = 0.0; // else begin : VGprime //AB: 040902 VGPrime is also a variable and else begin : VGprime_block //AB: 040902 VGPrime -> VGprime_block real sqv; // mb 99/03/26 corrected for multiple device number vL = 0.28 * (Leff/(LK*NS) - 0.1); sqv = 1.0 / (1.0 + 0.5*(vL + sqrt(vL*vL + 1.936e-3))); deltaVFB = V0 * sqv * sqv; end VG = TYPE * V(g,b); // wg 22/04/08 corrected for device TYPE VS = TYPE * V(s,b); VD = TYPE * V(d,b); if (VD - VS < 0) begin Mode = `REV; T1 = VS; VS = VD; VD = T1; end else Mode = `FWD; // VGB = VGS - VBS; // VBD = VBS - VDS; VGstar = VG - VTO_S - deltaVFB + PHI_T + GAMMA_sqrt_PHI; sqrt_VGstar = sqrt(VGstar*VGstar + 2.0*Vt_Vt_16); VGprime = 0.5*(VGstar + sqrt_VGstar); // Pinch-off voltage VP, limited to VP >= -PHI PHI_VS = PHI_T+VS; sqrt_PHI_VS_Vt = sqrt(PHI_VS*PHI_VS+Vt_Vt_16); sqrt_PHI_VS = sqrt(0.5*(PHI_VS+sqrt_PHI_VS_Vt)); PHI_VD = PHI_T+VD; sqrt_PHI_VD_Vt = sqrt(PHI_VD*PHI_VD+Vt_Vt_16); sqrt_PHI_VD = sqrt(0.5*(PHI_VD+sqrt_PHI_VD_Vt)); WETA_W = eps_COX_W * M / Weff; LETA_L = eps_COX_L * NS / Leff; // mb: symmetric version of GAMMAprime necessary with charges model big_sqrt_VP0 = sqrt(VGprime + 0.25*GAMMA_S*GAMMA_S); VP0 = VGprime - PHI_T - GAMMA_S*(big_sqrt_VP0 - 0.5*GAMMA_S); sqrt_PHI_VP0 = sqrt(VP0+PHI_T+Vt_01); GAMMAstar = GAMMA_S - LETA_L * (sqrt_PHI_VS+sqrt_PHI_VD) + WETA_W * sqrt_PHI_VP0; // keep GAMMAprime from becoming negative sqrt_GAMMAstar = sqrt(GAMMAstar*GAMMAstar+Vt_01); GAMMAprime = 0.5*(GAMMAstar+sqrt_GAMMAstar); big_sqrt_VP = sqrt(VGprime+0.25*GAMMAprime*GAMMAprime); VP = VGprime-PHI_T-GAMMAprime*(big_sqrt_VP-0.5*GAMMAprime); // Forward normalized current: tmp1 = (VP - VS) * inv_Vt; if (tmp1 > -0.35) begin z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6)); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -15.0) begin z0 = 1.55 + exp(-tmp1); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -23.0) begin yk = 1.0/(2.0 + exp(-tmp1)); end else begin yk = exp(tmp1) + 1E-64; end end end if_ = yk*(1.0 + yk); sqrt_if = sqrt(if_); dif_dv = yk; // Saturation voltage: Vt_Vc = Vt / Vc; VDSS_sqrt = sqrt(0.25+sqrt_if*Vt_Vc); VDSS = Vc*(VDSS_sqrt-0.5); Vds = 0.5*(VD-VS); deltaV_2 = Vt_Vt_16*(LAMBDA*(sqrt_if- VDSS*inv_Vt)+15.625e-3); sqrt_VDSS_deltaV = sqrt(VDSS*VDSS+deltaV_2); sqrt_Vds_VDSS_deltaV = sqrt((Vds-VDSS)*(Vds-VDSS)+deltaV_2); Vip = sqrt_VDSS_deltaV-sqrt_Vds_VDSS_deltaV; VDSSprime_sqrt = sqrt(0.25+(sqrt_if-0.75*ln(if_))*Vt_Vc); VDSSprime = Vc*(VDSSprime_sqrt-0.5)+log_Vc_Vt; // Reverse normalized current: Vdsprime = Vds-VDSSprime; // mb 97/07/18 introduced Vdsprime sqrt_VDSSprime_deltaV = sqrt(VDSSprime*VDSSprime+deltaV_2); sqrt_Vds_VDSSprime_deltaV = sqrt(Vdsprime*Vdsprime+deltaV_2); tmp1 = (VP-Vds-VS-sqrt_VDSSprime_deltaV+ sqrt_Vds_VDSSprime_deltaV)*inv_Vt; // include -> Charge F(x) interpolate function if (tmp1 > -0.35) begin z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6)); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -15.0) begin z0 = 1.55 + exp(-tmp1); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -23.0) begin yk = 1.0/(2.0 + exp(-tmp1)); end else begin yk = exp(tmp1) + 1E-64; end end end irprime = yk*(1.0 + yk); sqrt_irprime = sqrt(irprime); dirprime_dv = yk; /* Channel length modulation & mobility reduction due * to longitudinal field */ deltaL = Lc_LAMBDA*ln(1.0+(Vds-Vip)/Lc_UCRIT); Lprime = Leff-deltaL+(Vds+Vip)*inv_UCRIT; Lmin = 0.1*Leff; sqrt_Lprime_Lmin = sqrt(Lprime*Lprime+Lmin*Lmin); Leq = 0.5*(Lprime+sqrt_Lprime_Lmin); // Transconductance factor: // Mobility reduction due to vertical field // Reverse normalized current: // ratioV_ir tmp1 = (VP - VD) * inv_Vt; if (tmp1 > -0.35) begin z0 = 2.0/(1.3 + tmp1 - ln(tmp1 + 1.6)); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -15.0) begin z0 = 1.55 + exp(-tmp1); zk = (2.0 + z0)/(1.0 + tmp1 + ln(z0)); yk = (1.0 + tmp1 + ln(zk))/(2.0 + zk); end else begin if (tmp1 > -23.0) begin yk = 1.0/(2.0 + exp(-tmp1)); end else begin yk = exp(tmp1) + 1E-64; end end end ir = yk*(1.0 + yk); sqrt_ir = sqrt(ir); dir_dv = yk; sif2 = 0.25+if_; sir2 = 0.25+ir; sif = sqrt(sif2); sir = sqrt(sir2); sif_sir_2 = (sif+sir)*(sif+sir); VP_PHI_eps = VP+PHI_T+1.0e-6; sqrt_PHI_VP_2 = 2.0*sqrt(VP_PHI_eps); n_1 = GAMMA_S/sqrt_PHI_VP_2; n_1_n = GAMMA_S/(sqrt_PHI_VP_2 + GAMMA_S); // Normalized inversion charge (qi=QI/WLCox) qi = -(1.0+n_1)*Vt*((0.66666666+0.66666666)* (sir2+sir*sif+sif2)/(sif+sir) - 1.0); // Normalized depletion charge (qb=QB/WLCox), for depletion to inversion qb = -0.5*GAMMA_S*sqrt_PHI_VP_2 - n_1_n*qi; if (E0 == 0.0) begin /* NOTE: this version of the simple mobility model from prior * versions of the EKV model is reinstated. * In case E0 is *not* specified, this * simple mobility model is used according to THETA, if specified. * VPprime: * mb eliminated discontinuity of derivative of 1+THETA*VP */ sqrt_VP_Vt = sqrt(VP*VP + Vt_Vt_2); VPprime = 0.5 * (VP + sqrt_VP_Vt); THETA_VP_1 = 1.0+THETA*VPprime; beta = KP_Weff / (Leq * THETA_VP_1); // mb 97/07/18 end else begin /* new model for mobility reduction, linked to the charges model * mb 98/10/11 (r10) introduced fabs(Eeff) (jpm) * E0_Q_1 = 1.0 + T0 * abs(qb+eta_qi*qi); */ if ((qb + eta_qi*qi) > 0.0) E0_Q_1 = 1.0 + T0*(qb + eta_qi*qi); else E0_Q_1 = 1.0 - T0*(qb + eta_qi*qi); T0_GAMMA_1 = 1.0 + T0*GAMMA_sqrt_PHI; beta = KP_Weff * T0_GAMMA_1 / (Leq * E0_Q_1); end /* Slope factor: mb introduced new formula to avoid divergence * of n for VP->-PHI */ sqrt_PHI_VP = sqrt(PHI_T+VP+Vt_4); // mb 95/12/19 introduced Vt_4 n = 1.0 + GAMMA_S/(2.0*sqrt_PHI_VP); // Drain current: if_ir = if_-irprime; Ispec = Vt_Vt_2 * n * beta; Id = Ispec * if_ir; /* Return threshold voltage * Von = Vth(Vs) = Vto + Gamma*(sqrt(Phi + Vsb)-sqrt(Phi)) */ Von = VTO_S + GAMMAprime*(sqrt_PHI_VS - sqrt_PHI); // Return saturation voltage (estimate) Vdsat = Vt * (2.0*sqrt_if + 4.0); // Return equivalent conductance for thermal noise calculation Gn = beta * abs(qi); /* Pinch-off voltage derivatives: * mb 97/09/14 symmetric version of GAMMAprime necessary with * charges model * mb 99/05/10 (r12) New VGprime formulation (REVISION III) allows * VP derivatives to be expressed with a single equation */ tmp1 = GAMMAprime / (sqrt_GAMMAstar+sqrt_GAMMAstar); tmp2 = VGprime/sqrt_VGstar; // dVGprime_dVG dGAMMAprime_dVD = -LETA_L * tmp1 * sqrt_PHI_VD / sqrt_PHI_VD_Vt; dGAMMAprime_dVS = -LETA_L * tmp1 * sqrt_PHI_VS / sqrt_PHI_VS_Vt; dGAMMAprime_dVG = WETA_W * tmp1 * (big_sqrt_VP0-0.5*GAMMA_S) / (big_sqrt_VP0*sqrt_PHI_VP0) * tmp2; tmp3 = (VP+PHI_T) / big_sqrt_VP; dVP_dVD = -tmp3 * dGAMMAprime_dVD; dVP_dVS = -tmp3 * dGAMMAprime_dVS; dVP_dVG = -tmp3 * dGAMMAprime_dVG + (1.0 - GAMMAprime/(big_sqrt_VP+big_sqrt_VP)) * tmp2; // Forward normalized current derivatives: tmp1 = dif_dv * inv_Vt; // mb 95/08/28, 97/04/21 dif_dVD = tmp1 * dVP_dVD; dif_dVS = tmp1 * (dVP_dVS-1.0); dif_dVG = tmp1 * dVP_dVG; // Saturation voltage derivatives: tmp1 = Vt / (4.0*VDSS_sqrt*sqrt_if); dVDSS_dVD = tmp1 * dif_dVD; dVDSS_dVS = tmp1 * dif_dVS; dVDSS_dVG = tmp1 * dif_dVG; // deltaV derivatives: tmp1 = (Vt_4+Vt_4) * LAMBDA; tmp2 = Vt / (sqrt_if+sqrt_if); ddeltaV_dVD = tmp1 * (dif_dVD*tmp2 - dVDSS_dVD); ddeltaV_dVS = tmp1 * (dif_dVS*tmp2 - dVDSS_dVS); ddeltaV_dVG = tmp1 * (dif_dVG*tmp2 - dVDSS_dVG); // Vip derivatives: tmp1 = 1.0 / sqrt_VDSS_deltaV; tmp2 = 1.0 / sqrt_Vds_VDSS_deltaV; tmp3 = Vds-VDSS; dVip_dVD = (VDSS*dVDSS_dVD + ddeltaV_dVD) * tmp1 - (tmp3 * (0.5-dVDSS_dVD) + ddeltaV_dVD) * tmp2; dVip_dVS = (VDSS*dVDSS_dVS + ddeltaV_dVS) * tmp1 - (tmp3 * (-0.5-dVDSS_dVS) + ddeltaV_dVS) * tmp2; dVip_dVG = (VDSS*dVDSS_dVG + ddeltaV_dVG) * tmp1 - (tmp3 * -dVDSS_dVG + ddeltaV_dVG) * tmp2; // VDSSprime derivatives: tmp1 = Vt * (sqrt_if-1.5)/(4.0*VDSSprime_sqrt*if_); dVDSSprime_dVD = tmp1 * dif_dVD; dVDSSprime_dVS = tmp1 * dif_dVS; dVDSSprime_dVG = tmp1 * dif_dVG; // Reverse normalized current derivatives: tmp1 = dirprime_dv * inv_Vt; // mb 95/08/28, 97/04/21 tmp2 = 1.0 / sqrt_VDSSprime_deltaV; // mb 97/04/21 tmp3 = 1.0 / sqrt_Vds_VDSSprime_deltaV; dirprime_dVD = tmp1 * (dVP_dVD-0.5 - (VDSSprime*dVDSSprime_dVD+ddeltaV_dVD) * tmp2 + (Vdsprime*(0.5-dVDSSprime_dVD)+ddeltaV_dVD) * tmp3); dirprime_dVS = tmp1 * (dVP_dVS-0.5 - (VDSSprime*dVDSSprime_dVS+ddeltaV_dVS) * tmp2 + (Vdsprime*(-0.5-dVDSSprime_dVS)+ddeltaV_dVS) * tmp3); dirprime_dVG = tmp1*(dVP_dVG - (VDSSprime*dVDSSprime_dVG+ddeltaV_dVG) * tmp2 + (Vdsprime*(-dVDSSprime_dVG)+ddeltaV_dVG) * tmp3); // Channel length modulation & mobility reduction derivatives: // deltaL derivatives: tmp1 = Lc_LAMBDA / (Lc_UCRIT+Vds-Vip); ddeltaL_dVD = tmp1 * (0.5-dVip_dVD); ddeltaL_dVS = tmp1 * (-0.5-dVip_dVS); ddeltaL_dVG = -tmp1 * dVip_dVG; // Leq derivatives: tmp1 = 1.0 / sqrt_Lprime_Lmin; // in fact dLeq_dVX/Leq dLeq_dVD = tmp1 * (-ddeltaL_dVD + (0.5+dVip_dVD)*inv_UCRIT); dLeq_dVS = tmp1 * (-ddeltaL_dVS + (-0.5+dVip_dVS)*inv_UCRIT); dLeq_dVG = tmp1 * (-ddeltaL_dVG + dVip_dVG*inv_UCRIT); // Transconductance factor derivatives: tmp1 = dir_dv*inv_Vt; dir_dVD = tmp1 * (dVP_dVD-1.0); dir_dVS = tmp1 * dVP_dVS; dir_dVG = tmp1 * dVP_dVG; tmp1 = -(1.0+n_1)*Vt*0.66666666/sif_sir_2; tmp2 = tmp1*(sif+2.0*sir); tmp3 = tmp1*(sir+2.0*sif); tmp1 = -n_1*qi/((2.0+n_1+n_1)*VP_PHI_eps); dQI_dVD = tmp1 * dVP_dVD + tmp2 * dif_dVD + tmp3 * dir_dVD; dQI_dVS = tmp1 * dVP_dVS + tmp2 * dif_dVS + tmp3 * dir_dVS; dQI_dVG = tmp1 * dVP_dVG + tmp2 * dif_dVG + tmp3 * dir_dVG; tmp1 = (1.0+n_1)-qi/(2.0*(1.0+n_1)*VP_PHI_eps); dQB_dVD = -n_1_n * (tmp1 * dVP_dVD + dQI_dVD); dQB_dVS = -n_1_n * (tmp1 * dVP_dVS + dQI_dVS); dQB_dVG = -n_1_n * (tmp1 * dVP_dVG + dQI_dVG); if (E0 == 0.0) begin tmp1 = THETA * VPprime / (THETA_VP_1 * sqrt_VP_Vt); // VPprime derivatives: dVPprime_dVD = tmp1 * dVP_dVD; dVPprime_dVS = tmp1 * dVP_dVS; dVPprime_dVG = tmp1 * dVP_dVG; dbeta_dVD = -dLeq_dVD - dVPprime_dVD; // in fact dbeta_dVX / beta dbeta_dVS = -dLeq_dVS - dVPprime_dVS; dbeta_dVG = -dLeq_dVG - dVPprime_dVG; end else begin tmp1 = T0 / E0_Q_1; dbeta_dVD = -dLeq_dVD + tmp1 * (dQB_dVD+eta_qi*dQI_dVD); dbeta_dVS = -dLeq_dVS + tmp1 * (dQB_dVS+eta_qi*dQI_dVS); dbeta_dVG = -dLeq_dVG + tmp1 * (dQB_dVG+eta_qi*dQI_dVG); end // Slope factor derivatives: tmp1 = -GAMMA_S/(4.0*n*sqrt_PHI_VP*(PHI_T+VP+Vt_4));// mb 95/12/19 dn_dVD = tmp1 * dVP_dVD; dn_dVS = tmp1 * dVP_dVS; dn_dVG = tmp1 * dVP_dVG; // Transconductances: gds = Ispec*((dn_dVD + dbeta_dVD)*if_ir + dif_dVD - dirprime_dVD); gms = -Ispec*((dn_dVS + dbeta_dVS)*if_ir + dif_dVS - dirprime_dVS); gm = Ispec*((dn_dVG + dbeta_dVG)*if_ir + dif_dVG - dirprime_dVG); gmbs = gms - gm - gds; // S/D resistance corrections including W and DW RSeff = (RSH*HDIF)/(Weff-DW); RDeff = (RSH*HDIF)/(Weff-DW); tmp1 = 1.0/(1.0 + gms*RSeff + gds*RDeff); Id = Id*tmp1; /****** Impact ionization current ****** * mb 95/12/19 introduced impact ionization * This current component is flowing from the intrinsic drain terminal * to the bulk (for NMOS) in parallel with the junction current. * The simulator should also take into account the corresponding * conductances. */ // Substrate current: Vib = VD-VS-IBN_2*VDSS; if ((Vib > 0.0) && (IBA_IBB > 0.0)) begin inv_Vib = 1.0/Vib; Lc_IBB_Vib = -Lc_IBB*inv_Vib; if (Lc_IBB_Vib < -35.0) // math precision check Lc_IBB_Vib = -35.0; exp_ib = exp(Lc_IBB_Vib); isub = IBA_IBB*Vib*exp_ib; Isub = isub*Id; dIsub_factor = Isub*inv_Vib*(1.0-Lc_IBB_Vib); end else begin Lc_IBB_Vib = 0.0; Isub = 0.0; end // END: substrate current computation Ibd = Ibd - Isub; // --- Charge calculations --- WLCox = Weff * Leff * COX; sif3 = sif*sif2; sir3 = sir*sir2; tmp1 = sqrt(PHI_T + 0.5 * VP); sqrt_PHI_VP2_2 = tmp1+tmp1; n_Vt_COX = (1.0 + GAMMAprime/sqrt_PHI_VP2_2) * Vt*WLCox; QD = -n_Vt_COX*(0.266666666*(3.0*sir3+6.0*sir2*sif+4.0* sir*sif2+2.0*sif3)/sif_sir_2 - 0.5); QS = -n_Vt_COX*(0.266666666*(3.0*sif3+6.0*sif2*sir+4.0* sif*sir2+2.0*sir3)/sif_sir_2 - 0.5); QI = QS + QD; QB = WLCox * (-0.5*GAMMAprime*sqrt_PHI_VP_2 + VGprime - VGstar) - QI*GAMMAprime/(GAMMAprime+sqrt_PHI_VP2_2); QG = -QI -QB; I(ds) <+ TYPE * Mode * Id; // wg 22/04/08 corrected for device TYPE ddt_QD = ddt(QD); ddt_QS = ddt(QS); if (Mode == `FWD) begin I(db) <+ TYPE * ddt_QD; // wg 22/04/08 corrected for device TYPE I(sb) <+ TYPE * ddt_QS; I(db) <+ TYPE * Isub; end else begin I(sb) <+ TYPE * ddt_QD; // wg 22/04/08 corrected for device TYPE I(db) <+ TYPE * ddt_QS; I(sb) <+ TYPE * Isub; end I(gb) <+ TYPE * ddt(QG); // wg 22/04/08 corrected for device TYPE // if (Noise) begin : Noise //AB: 040902 Noise is also a variable and if (Noise) begin : Noise_block //AB: 040902 Noise -> Noise_block real S_flicker, S_thermal; S_thermal = 4 * `P_K * T * Gn; S_flicker = KF * gm * gm / (Weff * NS * Leff * COX); I(ds) <+ white_noise(S_thermal, "thermal") + flicker_noise(S_flicker, AF, "flicker"); end /////////////////////////////////// //EXTRINSIC PART: JUNCTION DIODES// /////////////////////////////////// //diode area and perimeter computation if ((AS == 0.0) && (HDIF>0.0)) as_i = 2.0*HDIF*Weff; else as_i = AS; if ((PS == 0.0) && (HDIF>0.0)) ps_i = 4.0*HDIF+1.0*Weff; else ps_i = PS; if ((AD == 0.0) && (HDIF>0.0)) ad_i = 2.0*HDIF*Weff; else ad_i = AD; if ((PD == 0.0) && (HDIF>0.0)) pd_i = 4.0*HDIF+1.0*Weff; else pd_i = PD; //temperature update for diodes temp_arg = exp((refEg/$vt(Tnom) - Eg/Vt + tp_xti*ln(ratioT))/xd_n); js_t = xd_js*temp_arg; jsw_t = xd_jsw*temp_arg; jswg_t = xd_jswg*temp_arg; pb_t = xd_pb - tp_pb*deltaT; pbsw_t = xd_pbsw - tp_pbsw*deltaT; pbswg_t = xd_pbswg - tp_pbswg*deltaT; cj_t = xd_cj*(1.0+tp_cj*deltaT); cjsw_t = xd_cjsw*(1.0+tp_cjsw*deltaT); cjswg_t = xd_cjswg*(1.0+tp_cjswg*deltaT); njts_t = xd_njts*(1.0+(ratioT-1.0)*tp_njts); njtssw_t = xd_njtssw*(1.0+(ratioT-1.0)*tp_njtssw); njtsswg_t = xd_njtsswg*(1.0+(ratioT-1.0)*tp_njtsswg); //DC v_di_b = TYPE*V(d,b); v_si_b = TYPE*V(s,b); //DRAIN - BULK is_d = js_t*ad_i+jsw_t*pd_i+jswg_t*Weff; arg_d = -v_di_b*ratioT/(Vt*xd_n); if (arg_d < -40.0) arg_d = -40.0; tmp0 = (-v_di_b+xd_bv)*ratioT/(Vt*xd_n); if (tmp0>70) f_breakdown_d = 1.0; else f_breakdown_d = 1.0 + xd_xjbv*exp(-tmp0); // TRAP-ASSISTED TUNNELING CURRENT idb_tun = -Weff*jswg_t*(exp(v_di_b*ratioT/(Vt*njtsswg_t) * xd_vtsswg/max(xd_vtsswg+v_di_b,1.0e-3))-1.0); idb_tun = idb_tun - pd_i*jsw_t*(exp(v_di_b*ratioT/(Vt*njtssw_t) * xd_vtssw/max(xd_vtssw+v_di_b,1.0e-3))-1.0); idb_tun = idb_tun - ad_i*js_t*(exp(v_di_b*ratioT/(Vt*njts_t) * xd_vts/max(xd_vts+v_di_b,1.0e-3))-1.0); I(d,b) <+ (is_d * (1.0 - exp(arg_d))*f_breakdown_d+v_di_b*xd_gmin + idb_tun)*TYPE*M; //SOURCE - BULK is_s = js_t*as_i+jsw_t*ps_i+jswg_t*Weff; arg_s = -v_si_b*ratioT/(Vt*xd_n); if (arg_s < -40.0) arg_s = -40.0; tmp0 = (-v_si_b+xd_bv)*ratioT/(Vt*xd_n); if (tmp0>70) f_breakdown_s = 1.0; else f_breakdown_s = 1.0 + xd_xjbv*exp(-tmp0); // TRAP-ASSISTED TUNNELING CURRENT isb_tun = -Weff*jswg_t*(exp(v_si_b*ratioT/(Vt*njtsswg_t) * xd_vtsswg/max(xd_vtsswg+v_si_b,1.0e-3))-1.0); isb_tun = isb_tun - ps_i*jsw_t*(exp(v_si_b*ratioT/(Vt*njtssw_t) * xd_vtssw/max(xd_vtssw+v_si_b,1.0e-3))-1.0); isb_tun = isb_tun - as_i*js_t*(exp(v_si_b*ratioT/(Vt*njts_t) * xd_vts/max(xd_vts+v_si_b,1.0e-3))-1.0); I(s,b) <+ (is_s * (1.0 - exp(arg_s))*f_breakdown_s+v_si_b*xd_gmin + isb_tun)*TYPE*M; //AC //DRAIN - BULK if (v_di_b>0.0) begin csb_d = cj_t * ad_i * exp(-xd_mj*ln(1.0+v_di_b/pb_t)); cssw_d = cjsw_t * pd_i * exp(-xd_mjsw*ln(1.0+v_di_b/pbsw_t)); csswg_d = cjswg_t * Weff * exp(-xd_mjswg*ln(1.0+v_di_b/pbswg_t)); end else begin csb_d = cj_t * ad_i * (1.0 - xd_mj*v_di_b/pb_t); cssw_d = cjsw_t * pd_i * (1.0 - xd_mjsw*v_di_b/pbsw_t); csswg_d = cjswg_t * Weff * (1.0 - xd_mjswg*v_di_b/pbswg_t); end qjd = (csb_d+cssw_d+csswg_d) * v_di_b; I(d,b) <+ ddt(qjd)*TYPE*M; //SOURCE - BULK if (v_si_b>0.0) begin csb_s = cj_t * as_i * exp(-xd_mj*ln(1.0+v_si_b/pb_t)); cssw_s = cjsw_t * ps_i * exp(-xd_mjsw*ln(1.0+v_si_b/pbsw_t)); csswg_s = cjswg_t * Weff * exp(-xd_mjswg*ln(1.0+v_si_b/pbswg_t)); end else begin csb_s = cj_t * as_i * (1.0 - xd_mj*v_si_b/pb_t); cssw_s = cjsw_t * ps_i * (1.0 - xd_mjsw*v_si_b/pbsw_t); csswg_s = cjswg_t * Weff * (1.0 - xd_mjswg*v_si_b/pbswg_t); end qjs = (csb_s+cssw_s+csswg_s) * v_si_b; I(s,b) <+ ddt(qjs)*TYPE*M; //END OF DIODES end endmodule