diff --git a/examples/osdi/EKV2.6/ekv26_mod.va b/examples/osdi/EKV2.6/ekv26_mod.va deleted file mode 100644 index e386a9608..000000000 --- a/examples/osdi/EKV2.6/ekv26_mod.va +++ /dev/null @@ -1,922 +0,0 @@ -/* -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