Merge branch 'pre-master' of ssh://git.code.sf.net/p/ngspice/ngspice into pre-master
This commit is contained in:
commit
e6f81f0b61
|
|
@ -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
|
||||
Loading…
Reference in New Issue