improve veriloga compatibility
This commit is contained in:
parent
5366f946eb
commit
0155d0722b
|
|
@ -3,28 +3,18 @@
|
||||||
// (revision II) available at http://legwww.epfl.ch/ekv.
|
// (revision II) available at http://legwww.epfl.ch/ekv.
|
||||||
// contribution of Ivan Riis Nielsen 11/2006, modified by Dietmar Warning 01/2009
|
// contribution of Ivan Riis Nielsen 11/2006, modified by Dietmar Warning 01/2009
|
||||||
|
|
||||||
//Default simulator: Spectre
|
`define P(txt) (*txt*)
|
||||||
|
`define PGIVEN(p) $param_given(p)
|
||||||
`ifdef insideADMS
|
`ifdef insideADMS
|
||||||
`define P(txt) (*txt*)
|
|
||||||
`define PGIVEN(p) $given(p)
|
|
||||||
`define INITIAL_MODEL @(initial_model)
|
`define INITIAL_MODEL @(initial_model)
|
||||||
`define INSTANCE @(initial_instance)
|
`define INSTANCE @(initial_instance)
|
||||||
`define NOISE @(noise)
|
`define NOISE @(noise)
|
||||||
`else
|
`else
|
||||||
`define P(txt) (txt)
|
|
||||||
`define PGIVEN(p) p
|
|
||||||
`define INITIAL_MODEL
|
`define INITIAL_MODEL
|
||||||
`define INSTANCE
|
`define INSTANCE
|
||||||
`define NOISE
|
`define NOISE
|
||||||
`endif
|
`endif
|
||||||
|
|
||||||
//ADS
|
|
||||||
//`include "constants.vams"
|
|
||||||
//`include "disciplines.vams"
|
|
||||||
//`include "compact.vams"
|
|
||||||
|
|
||||||
//Spectre
|
|
||||||
`include "constants.h"
|
`include "constants.h"
|
||||||
`include "discipline.h"
|
`include "discipline.h"
|
||||||
|
|
||||||
|
|
@ -34,6 +24,8 @@
|
||||||
`define EPSSI `P_EPS0*11.7
|
`define EPSSI `P_EPS0*11.7
|
||||||
`define EPSOX `P_EPS0*3.9
|
`define EPSOX `P_EPS0*3.9
|
||||||
`define TREF 300.15
|
`define TREF 300.15
|
||||||
|
`define MIN_R 0.001
|
||||||
|
`define VEXLIM 200.0
|
||||||
|
|
||||||
`define SQR(x) ((x)*(x))
|
`define SQR(x) ((x)*(x))
|
||||||
|
|
||||||
|
|
@ -41,311 +33,324 @@
|
||||||
`define EG(temp) (1.16-0.000702*`SQR(temp)/(temp+1108))
|
`define EG(temp) (1.16-0.000702*`SQR(temp)/(temp+1108))
|
||||||
`define NI(temp) (1.45e16*(temp/`TREF)*exp(`EG(`TREF)/(2*`VT(`TREF))-`EG(temp)/(2*`VT(temp))))
|
`define NI(temp) (1.45e16*(temp/`TREF)*exp(`EG(`TREF)/(2*`VT(`TREF))-`EG(temp)/(2*`VT(temp))))
|
||||||
|
|
||||||
|
`define y_fv(fv,y)\
|
||||||
`define oneThird 3.3333333333333333e-01
|
if (fv > -0.35) begin \
|
||||||
|
z0 = 2.0/(1.3 + fv - ln(fv+1.6));\
|
||||||
// Constants needed in safe exponential function (called "expl")
|
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));\
|
||||||
`define se05 2.3025850929940458e+02
|
y = (1.0 + fv + ln(z1)) / (2.0 + z1);\
|
||||||
`define ke05 1.0e-100
|
|
||||||
`define ke05inv 1.0e100
|
|
||||||
|
|
||||||
// P3 3rd order polynomial expansion of exp()
|
|
||||||
`define P3(u) (1.0 + (u) * (1.0 + 0.5 * ((u) * (1.0 + (u) * `oneThird))))
|
|
||||||
|
|
||||||
// expl exp() with 3rd order polynomial extrapolation
|
|
||||||
// to avoid overflows and underflows and retain C-3 continuity
|
|
||||||
`define expl(x, res) \
|
|
||||||
if (abs(x) < `se05) begin\
|
|
||||||
res = exp(x); \
|
|
||||||
end else begin \
|
|
||||||
if ((x) < -`se05) begin\
|
|
||||||
res = `ke05 / `P3(-`se05 - (x)); \
|
|
||||||
end else begin\
|
|
||||||
res = `ke05inv * `P3((x) - `se05); \
|
|
||||||
end \
|
end \
|
||||||
end
|
else if (fv > -15) begin \
|
||||||
|
tmp = exp(-fv);\
|
||||||
|
z0 = 1.55 + tmp;\
|
||||||
|
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));\
|
||||||
|
y = (1.0 + fv + ln(z1)) / (2.0 + z1);\
|
||||||
|
end \
|
||||||
|
else if (fv > -23.0) begin \
|
||||||
|
tmp = exp(-fv);\
|
||||||
|
y = 1.0 / (2.0 + tmp);\
|
||||||
|
end \
|
||||||
|
else begin \
|
||||||
|
tmp = exp(fv);\
|
||||||
|
y = tmp + 1.0e-64;\
|
||||||
|
end
|
||||||
|
|
||||||
|
`define expLin(result, x)\
|
||||||
|
if (x < `VEXLIM)\
|
||||||
|
result = exp(x);\
|
||||||
|
else begin\
|
||||||
|
result = exp(`VEXLIM) * (1.0 + (x - `VEXLIM));\
|
||||||
|
end
|
||||||
|
|
||||||
module ekv (d,g,s,b);
|
module ekv (d,g,s,b);
|
||||||
|
|
||||||
// Node definitions
|
// Node definitions
|
||||||
|
|
||||||
inout d,g,s,b;
|
inout d,g,s,b; // external nodes
|
||||||
electrical d,g,s,b,di,si;
|
electrical d,g,s,b; // external nodes
|
||||||
|
electrical dp,sp; // internal nodes
|
||||||
// Model parameters
|
|
||||||
|
|
||||||
parameter integer nmos=1 from [0:1] `P(info="MOS type : nmos:0");
|
|
||||||
parameter integer pmos=1 from [0:1] `P(info="MOS type : pmos:0");
|
|
||||||
parameter integer MTYPE=(nmos==0 ? (pmos==0 ? 0 : 1) : (pmos==0 ? -1 : 1));
|
|
||||||
parameter real TNOM=27 from (-273.15:inf)
|
|
||||||
`P(info="Nominal temperature [degC]");
|
|
||||||
parameter real IMAX=1 from (0:inf)
|
|
||||||
`P(info="Maximum forward junction current before linearization [A]");
|
|
||||||
|
|
||||||
// - intrinsic model (optional, section 4.2.1)
|
|
||||||
parameter real TOX=0 from [0:inf)
|
|
||||||
`P(info="Oxide thickness [m]");
|
|
||||||
parameter real NSUB=0 from [0:inf)
|
|
||||||
`P(info="Channel doping [cm^-3]");
|
|
||||||
parameter real VFB=1001.0 from (-inf:inf) // use 1001V as "not specified"
|
|
||||||
`P(info="Flat-band voltage [V]");
|
|
||||||
parameter real UO=0 from [0:inf)
|
|
||||||
`P(info="Low-field mobility [cm^2/Vs]");
|
|
||||||
parameter real VMAX=0 from [0:inf)
|
|
||||||
`P(info="Saturation velocity [m/s]");
|
|
||||||
parameter real THETA=0 from [0:inf)
|
|
||||||
`P(info="Mobility reduction coefficient [V^-1]");
|
|
||||||
|
|
||||||
// - intrinsic model (process related, section 4.1)
|
|
||||||
parameter real COX=((TOX>0) ? (`EPSOX/TOX) : 0.7m) from [0:inf)
|
|
||||||
`P(info="Oxide capacitance [F/m^2]");
|
|
||||||
parameter real XJ=0.1u from [1n:inf)
|
|
||||||
`P(info="Junction depth [m]");
|
|
||||||
parameter real DL=0 from (-inf:inf)
|
|
||||||
`P(info="Length correction [m]");
|
|
||||||
parameter real DW=0 from (-inf:inf)
|
|
||||||
`P(info="Width correction [m]");
|
|
||||||
|
|
||||||
// - intrinsic model (basic, section 4.2)
|
|
||||||
parameter real GAMMA=((NSUB>0) ? (sqrt(2*`P_Q*`EPSSI*NSUB*1e6)/COX) : 1) from [0:inf)
|
|
||||||
`P(info="Body effect parameter [V^0.5]");
|
|
||||||
parameter real PHI=((NSUB>0) ? (2*`VT((TNOM+273.15))*ln(max(NSUB,1)*1e6/`NI((TNOM+273.15)))) : 0.7) from [0.1:inf)
|
|
||||||
`P(info="Bulk Fermi potential (*2) [V]");
|
|
||||||
parameter real VTO=((VFB<1000.0) ? (VFB+MTYPE*(PHI+GAMMA*sqrt(PHI))) : 0.5) from (-inf:inf)
|
|
||||||
`P(info="Long-channel threshold voltage [V]");
|
|
||||||
parameter real KP=((UO>0) ? (UO*1e-4*COX) : 50u) from (0:inf)
|
|
||||||
`P(info="Transconductance parameter [A/V^2]");
|
|
||||||
parameter real UCRIT=(((VMAX>0) && (UO>0)) ? (VMAX/(UO*1e-4)) : 2e6 ) from [100k:inf)
|
|
||||||
`P(info="Longitudinal critical field [V/m]");
|
|
||||||
parameter real E0=((THETA>0) ? 0 : 1e12) from [100k:inf)
|
|
||||||
`P(info="Mobility reduction coefficient [V/m]");
|
|
||||||
|
|
||||||
// - intrinsic model (channel length modulation and charge sharing, section 4.3)
|
|
||||||
parameter real LAMBDA=0.5 from [0:inf)
|
|
||||||
`P(info="Depletion length coefficient (CLM)");
|
|
||||||
parameter real WETA=0.25 from (-inf:inf)
|
|
||||||
`P(info="Narrow-channel effect coefficient");
|
|
||||||
parameter real LETA=0.1 from (-inf:inf)
|
|
||||||
`P(info="Short-channel effect coefficient");
|
|
||||||
|
|
||||||
// - intrinsic model (reverse short channel effect, section 4.4)
|
|
||||||
parameter real Q0=0 from (-inf:inf)
|
|
||||||
`P(info="RSCE peak charge density [C/m^2]");
|
|
||||||
parameter real LK=0.29u from [10n:inf)
|
|
||||||
`P(info="RSCE characteristic length [m]");
|
|
||||||
|
|
||||||
// - intrinsic model (impact ionization, section 4.5)
|
|
||||||
parameter real IBA=0 from (-inf:inf)
|
|
||||||
`P(info="First impact ionization coefficient [m^-1]");
|
|
||||||
parameter real IBB=3e8 from [1e8:inf)
|
|
||||||
`P(info="Second impact ionization coefficient [V/m]");
|
|
||||||
parameter real IBN=1 from [0.1:inf)
|
|
||||||
`P(info="Saturation voltage factor for impact ionization");
|
|
||||||
|
|
||||||
// - intrinsic model (temperature, section 4.6)
|
|
||||||
parameter real TCV=1m from (-inf:inf)
|
|
||||||
`P(info="Threshold voltage TC [V/K]");
|
|
||||||
parameter real BEX=-1.5 from (-inf:inf)
|
|
||||||
`P(info="Mobility temperature exponent");
|
|
||||||
parameter real UCEX=0.8 from (-inf:inf)
|
|
||||||
`P(info="Longitudinal critical field temperature exponent");
|
|
||||||
parameter real IBBT=9e-4 from (-inf:inf)
|
|
||||||
`P(info="Temperature coefficient for IBB [K^-1]");
|
|
||||||
|
|
||||||
// - intrinsic model (matching, section 4.7)
|
|
||||||
parameter real AVTO=0 from (-inf:inf)
|
|
||||||
`P(info="Area related VTO mismatch parameter [Vm]");
|
|
||||||
parameter real AKP=0 from (-inf:inf)
|
|
||||||
`P(info="Area related KP mismatch parameter [m]");
|
|
||||||
parameter real AGAMMA=0 from (-inf:inf)
|
|
||||||
`P(info="Area related GAMMA mismatch parameter [V^0.5*m]");
|
|
||||||
|
|
||||||
// - intrinsic model (flicker noise, section 4.8)
|
|
||||||
parameter real KF=0 from [0:inf)
|
|
||||||
`P(info="Flicker noise coefficient");
|
|
||||||
parameter real AF=1 from (-inf:inf)
|
|
||||||
`P(info="Flicker noise exponent");
|
|
||||||
|
|
||||||
// - intrinsic model (setup, section 4.9)
|
|
||||||
parameter real NQS=0 from [0:1]
|
|
||||||
`P(info="Non-quasi-static operation switch");
|
|
||||||
parameter real SATLIM=exp(4) from (0:inf)
|
|
||||||
`P(info="Saturation limit (if/ir)");
|
|
||||||
parameter real XQC=0.4 from [0:1]
|
|
||||||
`P(info="Charge/capacitance model selector");
|
|
||||||
|
|
||||||
// - external parasitic parameters
|
|
||||||
parameter real HDIF=0 from [0:inf)
|
|
||||||
`P(info="S/D diffusion length (/2) [m]");
|
|
||||||
parameter real RSH=0 from [0:inf)
|
|
||||||
`P(info="S/D sheet resistance [ohm]");
|
|
||||||
parameter real JS=0 from [0:inf)
|
|
||||||
`P(info="S/D junction saturation current density [A/m^2]");
|
|
||||||
parameter real JSW=0 from [0:inf)
|
|
||||||
`P(info="S/D junction sidewall saturation current density [A/m]");
|
|
||||||
parameter real XTI=0 from [0:inf)
|
|
||||||
`P(info="S/D diode saturation current temperature exponent");
|
|
||||||
parameter real N=1 from [0.5:10]
|
|
||||||
`P(info="S/D diode emission coefficient");
|
|
||||||
parameter real CJ=0 from [0:inf)
|
|
||||||
`P(info="S/D zero-bias junction capacitance per area [F/m^2]");
|
|
||||||
parameter real CJSW=0 from [0:inf)
|
|
||||||
`P(info="S/D zero-bias junction capacitance per perimeter [F/m]");
|
|
||||||
parameter real PB=0.8 from (0:inf)
|
|
||||||
`P(info="S/D bottom junction builtin potential [V]");
|
|
||||||
parameter real PBSW=PB from (0:inf)
|
|
||||||
`P(info="S/D sidewall junction builtin potential [V]");
|
|
||||||
parameter real MJ=0.5 from (0:inf)
|
|
||||||
`P(info="S/D bottom junction grading coefficient");
|
|
||||||
parameter real MJSW=0.333 from (0:inf)
|
|
||||||
`P(info="S/D sidewall junction grading coefficient");
|
|
||||||
parameter real FC=0.5 from (0:inf)
|
|
||||||
`P(info="S/D bottom junction forward-bias threshold");
|
|
||||||
parameter real FCSW=FC from (0:inf)
|
|
||||||
`P(info="S/D sidewall junction forward-bias threshold");
|
|
||||||
parameter real CGSO=0 from [0:inf)
|
|
||||||
`P(info="Gate-source overlap capacitance per width [F/m]");
|
|
||||||
parameter real CGDO=0 from [0:inf)
|
|
||||||
`P(info="Gate-drain overlap capacitance per width [F/m]");
|
|
||||||
parameter real CGBO=0 from [0:inf)
|
|
||||||
`P(info="Gate-bulk overlap capacitance per length [F/m]");
|
|
||||||
|
|
||||||
|
branch (dp,sp) dpsp;
|
||||||
|
branch (dp,b) dpb;
|
||||||
|
branch (sp,b) spb;
|
||||||
|
branch (g,dp) gpdp;
|
||||||
|
branch (g,sp) gpsp;
|
||||||
|
branch (g,b) gb;
|
||||||
|
branch (d,dp) ddp;
|
||||||
|
branch (s,sp) ssp;
|
||||||
|
|
||||||
// Instance parameters
|
// Instance parameters
|
||||||
|
|
||||||
// - intrinsic model
|
// - intrinsic model
|
||||||
parameter real L=10u from [0:inf]
|
parameter real l=10e-6 from [0:inf) `P(type="instance" info="Drawn length [m]" units="m");
|
||||||
`P(type="instance" info="Drawn length [m]" unit="m");
|
parameter real w=10e-6 from [0:inf) `P(type="instance" info="Drawn width [m]" units="m");
|
||||||
parameter real W=10u from [0:inf]
|
parameter real m=1.0 from [1:inf) `P(type="instance" info="Parallel multiplier" units="m");
|
||||||
`P(type="instance" info="Drawn width [m]" unit="m");
|
parameter real ns=1.0 from [1:inf) `P(type="instance" info="Series multiplier" units="m");
|
||||||
parameter real M=1 from [0:inf]
|
parameter real dtemp = 0.0 from (-inf:inf) `P(type="instance" info="Difference sim. temp and device temp" units="C");
|
||||||
`P(type="instance" info="Parallel multiplier" unit="m");
|
|
||||||
// parameter real N=1 from [0:inf]
|
|
||||||
// `P(type="instance" info="Series multiplier" unit="m");
|
|
||||||
|
|
||||||
// - external parasitics
|
// - external parasitics
|
||||||
parameter real AD=((HDIF>0) ? (2*HDIF*W) : 0) from [0:inf)
|
parameter real ad=0.0 from [0:inf) `P(type="instance" info="Drain area" units="m^2");
|
||||||
`P(info="Drain area [m^2]" type="instance");
|
parameter real as=0.0 from [0:inf) `P(type="instance" info="Source area" units="m^2");
|
||||||
parameter real AS=((HDIF>0) ? (2*HDIF*W) : 0) from [0:inf)
|
parameter real pd=0.0 from [0:inf) `P(type="instance" info="Drain perimeter" units="m");
|
||||||
`P(info="Source area [m^2]" type="instance");
|
parameter real ps=0.0 from [0:inf) `P(type="instance" info="Source perimeter" units="m");
|
||||||
parameter real PD=((HDIF>0) ? (4*HDIF+2*W) : 0) from [0:inf)
|
parameter real nrd=0.0 from [0:inf) `P(type="instance" info="Drain no. squares");
|
||||||
`P(info="Drain perimeter [m]" type="instance");
|
parameter real nrs=0.0 from [0:inf) `P(type="instance" info="Source no. squares");
|
||||||
parameter real PS=((HDIF>0) ? (4*HDIF+2*W) : 0) from [0:inf)
|
|
||||||
`P(info="Source perimeter [m]" type="instance");
|
|
||||||
parameter real NRD=((HDIF>0) ? (HDIF/W) : 0) from [0:inf)
|
|
||||||
`P(info="Drain no. squares" type="instance");
|
|
||||||
parameter real NRS=((HDIF>0) ? (HDIF/W) : 0) from [0:inf)
|
|
||||||
`P(info="Source no. squares" type="instance");
|
|
||||||
parameter real RS=((RSH>0) ? (RSH*NRS) : 0) from [0:inf)
|
|
||||||
`P(info="Source resistance [ohms]" type="instance");
|
|
||||||
parameter real RD=((RSH>0) ? (RSH*NRD) : 0) from [0:inf)
|
|
||||||
`P(info="Drain resistance [ohms]" type="instance");
|
|
||||||
|
|
||||||
|
// Model parameters
|
||||||
|
|
||||||
|
parameter integer nmos=1 from [0:1] `P(info="MOS channel type");
|
||||||
|
parameter integer pmos=1 from [0:1] `P(info="MOS channel type");
|
||||||
|
parameter integer type=1 from [-1:1] exclude 0;
|
||||||
|
parameter real tnom=27.0 from [-273.15:inf) `P(info="Nominal temperature" units="C");
|
||||||
|
parameter real imax=1.0 from [0:inf) `P(info="Maximum forward junction current before linearization" units="A");
|
||||||
|
|
||||||
|
// - intrinsic model (optional, section 4.2.1)
|
||||||
|
parameter real tox=0.0 from [0:inf) `P(info="Oxide thickness" units="m");
|
||||||
|
parameter real nsub=0.0 from [0:inf) `P(info="Channel doping" units="cm^-3");
|
||||||
|
parameter real vfb=-1.0 from (-inf:inf) `P(info="Flat-band voltage" units="V");
|
||||||
|
|
||||||
|
parameter real uo=0.0 from [0:inf) `P(info="Low-field mobility" units="cm^2/Vs");
|
||||||
|
parameter real vmax=0.0 from [0:inf) `P(info="Saturation velocity" units="m/s");
|
||||||
|
parameter real theta=0.0 from [0:inf) `P(info="Mobility reduction coefficient" units="V^-1");
|
||||||
|
|
||||||
|
// - intrinsic model (process related, section 4.1)
|
||||||
|
parameter real cox=0.7e-3 from [1e-6:inf) `P(info="Oxide capacitance" units="F/m^2");
|
||||||
|
parameter real xj=0.1e-6 from [1n:inf) `P(info="Junction depth" units="m");
|
||||||
|
parameter real dl=0.0 from (-inf:inf) `P(info="Length correction" units="m");
|
||||||
|
parameter real dw=0.0 from (-inf:inf) `P(info="Width correction" units="m");
|
||||||
|
|
||||||
|
// - intrinsic model (basic, section 4.2)
|
||||||
|
parameter real gamma=0.7 from [0:inf) `P(info="Body effect parameter" units="V^0.5");
|
||||||
|
parameter real phi=0.5 from [0.1:inf) `P(info="Bulk Fermi potential (*2)" units="V");
|
||||||
|
parameter real vto=0.5 from (-inf:inf) `P(info="Long-channel threshold voltage" units="V");
|
||||||
|
parameter real kp=20e-6 from [0.0:inf) `P(info="Transconductance parameter" units="A/V^2");
|
||||||
|
parameter real ucrit=1.0e+6 from [100e+3:inf) `P(info="Longitudinal critical field" units="V/m");
|
||||||
|
parameter real e0=1.0e-9 from [1e-12:inf) `P(info="Mobility reduction coefficient" units="V/m");
|
||||||
|
|
||||||
|
// - intrinsic model (channel length modulation and charge sharing, section 4.3)
|
||||||
|
parameter real lambda=0.5 from [0:inf) `P(info="Depletion length coefficient (CLM)");
|
||||||
|
parameter real weta=0.25 from (-inf:inf) `P(info="Narrow-channel effect coefficient");
|
||||||
|
parameter real leta=0.1 from (-inf:inf) `P(info="Short-channel effect coefficient");
|
||||||
|
|
||||||
|
// - intrinsic model (reverse short channel effect, section 4.4)
|
||||||
|
parameter real q0=0.0 from (-inf:inf) `P(info="RSCE peak charge density" units="C/m^2");
|
||||||
|
parameter real lk=0.29e-6 from [10n:inf) `P(info="RSCE characteristic length" units="m");
|
||||||
|
|
||||||
|
// - intrinsic model (impact ionization, section 4.5)
|
||||||
|
parameter real iba=0.0 from (-inf:inf) `P(info="First impact ionization coefficient" units="m^-1");
|
||||||
|
parameter real ibb=3e8 from [1e8:inf) `P(info="Second impact ionization coefficient" units="V/m");
|
||||||
|
parameter real ibn=1.0 from [0.1:inf) `P(info="Saturation voltage factor for impact ionization");
|
||||||
|
|
||||||
|
// - intrinsic model (temperature, section 4.6)
|
||||||
|
parameter real tcv=1e-3 from (-inf:inf) `P(info="Threshold voltage TC" units="V/deg");
|
||||||
|
parameter real bex=-1.5 from (-inf:inf) `P(info="Mobility temperature exponent");
|
||||||
|
parameter real ucex=0.8 from (-inf:inf) `P(info="Longitudinal critical field temperature exponent");
|
||||||
|
parameter real ibbt=9e-4 from (-inf:inf) `P(info="Temperature coefficient for ibb" units="K^-1");
|
||||||
|
|
||||||
|
// - intrinsic model (matching, section 4.7)
|
||||||
|
parameter real avto=0.0 from (-inf:inf) `P(info="Area related vto mismatch parameter" units="Vm");
|
||||||
|
parameter real akp=0.0 from (-inf:inf) `P(info="Area related kp mismatch parameter" units="m");
|
||||||
|
parameter real agamma=0.0 from (-inf:inf) `P(info="Area related gamma mismatch parameter" units="V^0.5*m");
|
||||||
|
|
||||||
|
// - intrinsic model (flicker noise, section 4.8)
|
||||||
|
parameter real kf=0.0 from [0:inf) `P(info="Flicker noise coefficient");
|
||||||
|
parameter real af=1.0 from (-inf:inf) `P(info="Flicker noise exponent");
|
||||||
|
|
||||||
|
// - external parasitic parameters
|
||||||
|
parameter real hdif=0.0 from [0:inf) `P(info="S/D diffusion length (/2)" units="m");
|
||||||
|
parameter real rsh=0.0 from [0:inf) `P(info="S/D sheet resistance" units="Ohm");
|
||||||
|
parameter real js=0.0 from [0:inf) `P(info="S/D junction saturation current density" units="A/m^2");
|
||||||
|
parameter real jsw=0.0 from [0:inf) `P(info="S/D junction sidewall saturation current density" units="A/m");
|
||||||
|
parameter real xti=0.0 from [0:inf) `P(info="S/D diode saturation current temperature exponent");
|
||||||
|
parameter real n=1 from [0.5:10] `P(info="S/D diode emission coefficient");
|
||||||
|
parameter real cj=0.0 from [0:inf) `P(info="S/D zero-bias junction capacitance per area" units="F/m^2");
|
||||||
|
parameter real cjsw=0.0 from [0:inf) `P(info="S/D zero-bias junction capacitance per perimeter" units="F/m");
|
||||||
|
parameter real pb=0.8 from (0:inf) `P(info="S/D bottom junction builtin potential" units="V");
|
||||||
|
parameter real pbsw=pb from (0:inf) `P(info="S/D sidewall junction builtin potential" units="V");
|
||||||
|
parameter real mj=0.5 from (0:inf) `P(info="S/D bottom junction grading coefficient");
|
||||||
|
parameter real mjsw=0.333 from (0:inf) `P(info="S/D sidewall junction grading coefficient");
|
||||||
|
parameter real fc=0.5 from (0:inf) `P(info="S/D bottom junction forward-bias threshold");
|
||||||
|
parameter real fcsw=fc from (0:inf) `P(info="S/D sidewall junction forward-bias threshold");
|
||||||
|
parameter real cgso=1.5e-10 from [0:inf) `P(info="Gate-source overlap capacitance per width" units="F/m");
|
||||||
|
parameter real cgdo=1.5e-10 from [0:inf) `P(info="Gate-drain overlap capacitance per width" units="F/m");
|
||||||
|
parameter real cgbo=4.0e-10 from [0:inf) `P(info="Gate-bulk overlap capacitance per length" units="F/m");
|
||||||
|
|
||||||
// Declaration of variables
|
// Declaration of variables
|
||||||
integer mode;
|
integer mode, MOStype;
|
||||||
real lc,isat_s,vexp_s,gexp_s,isat_d,vexp_d,gexp_d,fact,
|
real lc,isat_s,vexp_s,gexp_s,isat_d,vexp_d,gexp_d,fact,
|
||||||
weff,leff,np,ns,lmin,rd,rs,ceps,ca,xsi,dvrsce,
|
weff,leff,lmin,RDeff,RSeff,ceps,ca,xsi,dvrsce,
|
||||||
tempk,vt,sqrt_A,vto_a,kp_a,gamma_a,ucrit,phi,ibb,vc,qb0,
|
TempK,Vt,sqrt_A,vto_a,kp_a,gamma_a,ucrit_a,phi_a,ibb_a,vc,qb0,
|
||||||
vg,vd,vs,tmp,vgprime,vp0,vsprime,vdprime,gamma0,gammaprime,vp,n,ifwd,
|
vg,vd,vs,tmp,vgprime,vp0,vsprime,vdprime,gamma0,gammaprime,vp,nslope,ifwd,
|
||||||
vdss,vdssprime,dv,vds,vip,dl,lprime,leq,irprime,irev,beta0,nau,
|
vdss,vdssprime,dv,vds,vip,dl_a,lprime,leq,irprime,irev,beta0,nau,
|
||||||
nq,xf,xr,qd,qs,qi,qb,qg,beta0prime,beta,vpprime,is,ids,vib,
|
nq,xf,xr,qd,qs,qi,qb,qg,beta0prime,beta,vpprime,is,ids,vib,
|
||||||
idb,ibdj,ibsj,coxt,qdt,qst,qgt,qbt,
|
idb,ibdj,ibsj,coxt,qdt,qst,qdtx,qstx,qgt,qjs,qjd,
|
||||||
cbs0,cbs0sw,cbs,cbd0,cbd0sw,cbd,
|
cbs0,cbs0sw,cbs,cbd0,cbd0sw,cbd,v_bp_dp, v_bp_sp,
|
||||||
fv,z0,z1,y;
|
fv,z0,z1,y;
|
||||||
|
|
||||||
real cgso,cgdo,cgbo;
|
real ADeff, ASeff, PDeff, PSeff;
|
||||||
|
real cgso_s,cgdo_s,cgbo_s;
|
||||||
|
real gmin, TnomK;
|
||||||
|
real cox_p, gamma_p, phi_p, kp_p, vto_p, ucrit_p;
|
||||||
|
|
||||||
analog begin
|
analog begin
|
||||||
|
|
||||||
`INITIAL_MODEL begin // Model Initialization
|
gmin = $simparam("gmin");
|
||||||
|
|
||||||
lc = sqrt(`EPSSI/COX*XJ);
|
`INITIAL_MODEL // Model Initialization
|
||||||
|
begin
|
||||||
|
if (`PGIVEN(nmos)) begin
|
||||||
|
MOStype = `NMOS;
|
||||||
|
end else if (`PGIVEN(pmos)) begin
|
||||||
|
MOStype = `PMOS;
|
||||||
|
end else begin
|
||||||
|
MOStype = (`PGIVEN(type)) ? type : `NMOS;
|
||||||
|
end
|
||||||
|
|
||||||
|
//$strobe("MOStype %d", MOStype);
|
||||||
|
|
||||||
|
if (`PGIVEN(cox)) begin
|
||||||
|
cox_p = cox;
|
||||||
|
end else begin
|
||||||
|
cox_p = (tox>0) ? (`EPSOX/tox) : 0.7e-3;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (`PGIVEN(gamma)) begin
|
||||||
|
gamma_p = gamma;
|
||||||
|
end else begin
|
||||||
|
gamma_p = (nsub>0) ? (sqrt(2*`P_Q*`EPSSI*nsub*1e+6)/cox_p) : 0.7;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (`PGIVEN(phi)) begin
|
||||||
|
phi_p = phi;
|
||||||
|
end else begin
|
||||||
|
phi_p = (nsub>0) ? (2*`VT(tnom+273.15)*ln(nsub*1e+6/`NI(tnom+273.15))) : 0.5;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (`PGIVEN(kp)) begin
|
||||||
|
kp_p = kp;
|
||||||
|
end else begin
|
||||||
|
kp_p = (uo>0) ? (uo*1e-4*cox_p) : 20e-6;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (`PGIVEN(vto)) begin
|
||||||
|
vto_p = vto;
|
||||||
|
end else begin
|
||||||
|
vto_p = (`PGIVEN(vfb)) ? (vfb+phi_p+gamma_p*sqrt(phi_p)) : 0.5;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (`PGIVEN(ucrit)) begin
|
||||||
|
ucrit_p = ucrit;
|
||||||
|
end else begin
|
||||||
|
ucrit_p = (vmax>0 && uo>0) ? (vmax/(uo*1e-4)) : 100e+3;
|
||||||
|
end
|
||||||
|
|
||||||
|
lc = sqrt(`EPSSI/cox_p*xj);
|
||||||
|
|
||||||
end // INITIAL_MODEL
|
end // INITIAL_MODEL
|
||||||
|
|
||||||
`INSTANCE begin // temperature independent device initialization
|
`INSTANCE // temperature independent device initialization
|
||||||
|
begin
|
||||||
weff = W+DW;
|
weff = w+dw;
|
||||||
leff = L+DL;
|
leff = l+dl;
|
||||||
|
|
||||||
np = M;
|
|
||||||
ns = 1;
|
|
||||||
|
|
||||||
// eq. 54
|
// eq. 54
|
||||||
lmin = 0.1*ns*leff;
|
lmin = 0.1*ns*leff;
|
||||||
|
|
||||||
rs = ns/np*RS;
|
if (hdif > 0) begin
|
||||||
rd = ns/np*RD;
|
RSeff = ns/m*rsh*hdif/weff;
|
||||||
|
RDeff = ns/m*rsh*hdif/weff;
|
||||||
|
ADeff = 2*hdif*weff;
|
||||||
|
ASeff = 2*hdif*weff;
|
||||||
|
PDeff = 4*hdif+2*weff;
|
||||||
|
PSeff = 4*hdif+2*weff;
|
||||||
|
end else begin
|
||||||
|
RSeff = ns/m*rsh*nrs;
|
||||||
|
RDeff = ns/m*rsh*nrd;
|
||||||
|
ADeff = ad;
|
||||||
|
ASeff = as;
|
||||||
|
PDeff = pd;
|
||||||
|
PSeff = ps;
|
||||||
|
end
|
||||||
|
if (RDeff < `MIN_R) begin
|
||||||
|
RDeff = `MIN_R;
|
||||||
|
end
|
||||||
|
if (RSeff < `MIN_R) begin
|
||||||
|
RSeff = `MIN_R;
|
||||||
|
end
|
||||||
|
|
||||||
ceps = 4*22e-3*22e-3;
|
ceps = 4*22e-3*22e-3;
|
||||||
ca = 0.028;
|
ca = 0.028;
|
||||||
xsi = ca*(10*leff/LK-1);
|
xsi = ca*(10*leff/lk-1);
|
||||||
dvrsce = 2*Q0/COX/`SQR(1+0.5*(xsi+sqrt(xsi*xsi+ceps)));
|
dvrsce = 2*q0/cox_p/`SQR(1+0.5*(xsi+sqrt(xsi*xsi+ceps)));
|
||||||
|
|
||||||
coxt = np*ns*COX*weff*leff;
|
coxt = m*ns*cox_p*weff*leff;
|
||||||
|
|
||||||
|
cbs0 = m*ns*cj*ASeff;
|
||||||
|
cbd0 = m*ns*cj*ADeff;
|
||||||
|
cbs0sw = m*ns*cjsw*PSeff;
|
||||||
|
cbd0sw = m*ns*cjsw*PDeff;
|
||||||
|
|
||||||
|
cgso_s = m*ns*cgso*weff;
|
||||||
|
cgdo_s = m*ns*cgdo*weff;
|
||||||
|
cgbo_s = m*ns*cgbo*leff;
|
||||||
|
|
||||||
end // temperature independent
|
end // temperature independent
|
||||||
|
|
||||||
`INSTANCE begin // temperature dependent device initialization
|
`INSTANCE // temperature dependent device initialization
|
||||||
tempk = $temperature;
|
begin
|
||||||
vt = `VT(tempk);
|
if (dtemp > 0.0) begin
|
||||||
|
TempK = $temperature + dtemp;
|
||||||
|
end else begin
|
||||||
|
TempK = $temperature;
|
||||||
|
end
|
||||||
|
|
||||||
sqrt_A = sqrt(np*weff*ns*leff);
|
TnomK = tnom + 273.15;
|
||||||
|
|
||||||
vto_a = MTYPE*(VTO+TCV*(tempk-(TNOM+273.15)))+AVTO/sqrt_A;
|
Vt = `VT(TempK);
|
||||||
kp_a = KP*pow(tempk/(TNOM+273.15),BEX)*(1+AKP/sqrt_A);
|
|
||||||
gamma_a = GAMMA+AGAMMA/sqrt_A;
|
|
||||||
ucrit = UCRIT*pow(tempk/(TNOM+273.15),UCEX);
|
|
||||||
phi = PHI*tempk/(TNOM+273.15)-3*vt*ln(tempk/(TNOM+273.15))-`EG(TNOM+273.15)*tempk/(TNOM+273.15)+`EG(tempk);
|
|
||||||
ibb = IBB*(1+IBBT*(tempk-(TNOM+273.15)));
|
|
||||||
|
|
||||||
vc = ucrit*ns*leff;
|
sqrt_A = sqrt(m*weff*ns*leff);
|
||||||
|
|
||||||
|
vto_a = MOStype*(vto_p+tcv*(TempK-TnomK))+avto/sqrt_A;
|
||||||
|
kp_a = m*kp_p*pow(TempK/TnomK,bex)*(1+akp/sqrt_A);
|
||||||
|
gamma_a = gamma_p+agamma/sqrt_A;
|
||||||
|
ucrit_a = ucrit_p*pow(TempK/TnomK,ucex);
|
||||||
|
phi_a = phi_p*TempK/TnomK-3*Vt*ln(TempK/TnomK)-`EG(TnomK)*TempK/TnomK+`EG(TempK);
|
||||||
|
ibb_a = ibb*(1+ibbt*(TempK-TnomK));
|
||||||
|
|
||||||
|
vc = ucrit_a*ns*leff;
|
||||||
|
|
||||||
// eq. 60
|
// eq. 60
|
||||||
qb0 = gamma_a*sqrt(phi);
|
qb0 = gamma_a*sqrt(phi_a);
|
||||||
|
|
||||||
fact = (`EG(TNOM+273.15)/`VT(TNOM+273.15)-`EG(tempk)/vt) * pow(tempk/(TNOM+273.15),XTI);
|
fact = (`EG(TnomK)/`VT(TnomK)-`EG(TempK)/Vt) * pow(TempK/TnomK,xti);
|
||||||
`expl(fact,tmp)
|
`expLin(tmp,fact)
|
||||||
isat_s = np*ns*(JS*AS+JSW*PS)*tmp;
|
isat_s = m*ns*(js*ASeff+jsw*PSeff)*tmp;
|
||||||
isat_d = np*ns*(JS*AD+JSW*PD)*tmp;
|
isat_d = m*ns*(js*ADeff+jsw*PDeff)*tmp;
|
||||||
|
|
||||||
if (isat_s>0) begin
|
if (isat_s>0) begin
|
||||||
vexp_s = vt*ln(IMAX/isat_s+1);
|
vexp_s = Vt*ln(imax/isat_s+1);
|
||||||
gexp_s = (IMAX+isat_s)/vt;
|
gexp_s = (imax+isat_s)/Vt;
|
||||||
end else begin
|
end else begin
|
||||||
vexp_s = -1e9;
|
vexp_s = -1e9;
|
||||||
gexp_s = 0;
|
gexp_s = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (isat_d>0) begin
|
if (isat_d>0) begin
|
||||||
vexp_d = vt*ln(IMAX/isat_d+1);
|
vexp_d = Vt*ln(imax/isat_d+1);
|
||||||
gexp_d = (IMAX+isat_d)/vt;
|
gexp_d = (imax+isat_d)/Vt;
|
||||||
end else begin
|
end else begin
|
||||||
vexp_d = -1e9;
|
vexp_d = -1e9;
|
||||||
gexp_d = 0;
|
gexp_d = 0;
|
||||||
end
|
end
|
||||||
|
|
||||||
cbs0 = np*ns*CJ*AS;
|
|
||||||
cbd0 = np*ns*CJ*AD;
|
|
||||||
cbs0sw = np*ns*CJSW*PS;
|
|
||||||
cbd0sw = np*ns*CJSW*PD;
|
|
||||||
|
|
||||||
cgso = np*ns*CGSO*weff;
|
|
||||||
cgdo = np*ns*CGDO*weff;
|
|
||||||
cgbo = np*ns*CGBO*leff;
|
|
||||||
|
|
||||||
end // temperature dependent
|
end // temperature dependent
|
||||||
|
|
||||||
|
|
||||||
begin //Bias-dependent model evaluation
|
begin //Bias-dependent model evaluation
|
||||||
|
|
||||||
vg = MTYPE*V(g,b);
|
vg = MOStype*V(gb);
|
||||||
vd = MTYPE*V(di,b);
|
vd = MOStype*V(dpb);
|
||||||
vs = MTYPE*V(si,b);
|
vs = MOStype*V(spb);
|
||||||
// $strobe("vg=%e vd=%e vs=%e",vg,vd,vs);
|
// $strobe("MOStype %d vg=%e vd=%e vs=%e",MOStype,vg,vd,vs);
|
||||||
|
|
||||||
if (vd>=vs)
|
if (vd>=vs)
|
||||||
mode = 1;
|
mode = 1;
|
||||||
|
|
@ -357,137 +362,80 @@ module ekv (d,g,s,b);
|
||||||
end
|
end
|
||||||
|
|
||||||
// eq. 33
|
// eq. 33
|
||||||
vgprime = vg-vto_a-dvrsce+phi+gamma_a*sqrt(phi);
|
vgprime = vg-vto_a-dvrsce+phi_a+gamma_a*sqrt(phi_a);
|
||||||
// eq. 35
|
// eq. 35
|
||||||
vsprime = 0.5*(vs+phi+sqrt(`SQR(vs+phi)+16*`SQR(vt)));
|
vsprime = 0.5*(vs+phi_a+sqrt(`SQR(vs+phi_a)+16*`SQR(Vt)));
|
||||||
vdprime = 0.5*(vd+phi+sqrt(`SQR(vd+phi)+16*`SQR(vt)));
|
vdprime = 0.5*(vd+phi_a+sqrt(`SQR(vd+phi_a)+16*`SQR(Vt)));
|
||||||
// $strobe("vgprime=%e vdprime=%e vsprime=%e",vgprime,vdprime,vsprime);
|
// $strobe("vgprime=%e vdprime=%e vsprime=%e",vgprime,vdprime,vsprime);
|
||||||
// eq. 34
|
// eq. 34
|
||||||
if (vgprime>=0) begin
|
if (vgprime>=0) begin
|
||||||
vp0 = vgprime-phi-gamma_a*(sqrt(vgprime+0.25*`SQR(gamma_a))-0.5*gamma_a);
|
vp0 = vgprime-phi_a-gamma_a*(sqrt(vgprime+0.25*`SQR(gamma_a))-0.5*gamma_a);
|
||||||
// eq. 36
|
// eq. 36
|
||||||
gamma0 = gamma_a-`EPSSI/COX*(LETA/leff*(sqrt(vsprime)+sqrt(vdprime))-3*WETA/weff*sqrt(vp0+phi));
|
gamma0 = gamma_a-`EPSSI/cox_p*(leta/leff*(sqrt(vsprime)+sqrt(vdprime))-3*weta/weff*sqrt(vp0+phi_a));
|
||||||
end else begin
|
end else begin
|
||||||
vp0 = -phi;
|
vp0 = -phi_a;
|
||||||
// eq. 36 - skipped sqrt(vp0+phi) here, it produces inf on derivative
|
// eq. 36 - skipped sqrt(vp0+phi_a) here, it produces inf on derivative
|
||||||
gamma0 = gamma_a-`EPSSI/COX*(LETA/leff*(sqrt(vsprime)+sqrt(vdprime)) );
|
gamma0 = gamma_a-`EPSSI/cox_p*(leta/leff*(sqrt(vsprime)+sqrt(vdprime)) );
|
||||||
end
|
end
|
||||||
// eq. 37
|
// eq. 37
|
||||||
gammaprime = 0.5*(gamma0+sqrt(`SQR(gamma0)+0.1*vt));
|
gammaprime = 0.5*(gamma0+sqrt(`SQR(gamma0)+0.1*Vt));
|
||||||
// eq. 38
|
// eq. 38
|
||||||
if (vgprime>=0)
|
if (vgprime>=0) begin
|
||||||
vp = vgprime-phi-gammaprime*(sqrt(vgprime+0.25*`SQR(gammaprime))-0.5*gammaprime);
|
vp = vgprime-phi_a-gammaprime*(sqrt(vgprime+0.25*`SQR(gammaprime))-0.5*gammaprime);
|
||||||
else
|
end else begin
|
||||||
vp = -phi;
|
vp = -phi_a;
|
||||||
|
end
|
||||||
// $strobe("vp0=%e vp=%e gamma0=%e gammaprime=%e",vp0,vp,gamma0,gammaprime);
|
// $strobe("vp0=%e vp=%e gamma0=%e gammaprime=%e",vp0,vp,gamma0,gammaprime);
|
||||||
// eq. 39
|
// eq. 39
|
||||||
n = 1+gamma_a*0.5/sqrt(vp+phi+4*vt);
|
nslope = 1+gamma_a*0.5/sqrt(vp+phi_a+4*Vt);
|
||||||
|
|
||||||
// Forward current (43-44)
|
// Forward current (43-44)
|
||||||
fv=(vp-vs)/vt;
|
fv=(vp-vs)/Vt;
|
||||||
|
|
||||||
if (fv > -0.35) begin
|
`y_fv(fv,y)
|
||||||
z0 = 2.0/(1.3 + fv - ln(fv+1.6));
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -15) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
z0 = 1.55 + tmp;
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -23.0) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
y = 1.0 / (2.0 + tmp);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
`expl(fv,tmp)
|
|
||||||
y = tmp + 1.0e-64;
|
|
||||||
end
|
|
||||||
|
|
||||||
ifwd = y*(1.0 + y);
|
ifwd = y*(1.0 + y);
|
||||||
z0 = 1;
|
|
||||||
z1 = 1;
|
|
||||||
|
|
||||||
// eq. 46
|
// eq. 46
|
||||||
vdss = vc*(sqrt(0.25+vt/vc*sqrt(ifwd))-0.5);
|
vdss = vc*(sqrt(0.25+Vt/vc*sqrt(ifwd))-0.5);
|
||||||
// eq. 47
|
// eq. 47
|
||||||
vdssprime = vc*(sqrt(0.25+vt/vc*(sqrt(ifwd)-0.75*ln(ifwd)))-0.5)+vt*(ln(0.5*vc/vt)-0.6);
|
vdssprime = vc*(sqrt(0.25+Vt/vc*(sqrt(ifwd)-0.75*ln(ifwd)))-0.5)+Vt*(ln(0.5*vc/Vt)-0.6);
|
||||||
// $strobe("ifwd=%e vdss=%e vdssprime=%e",ifwd,vdss,vdssprime);
|
// $strobe("ifwd=%e vdss=%e vdssprime=%e",ifwd,vdss,vdssprime);
|
||||||
// eq. 48
|
// eq. 48
|
||||||
dv = 4*vt*sqrt(LAMBDA*(sqrt(ifwd)-vdss/vt)+1.0/64);
|
dv = 4*Vt*sqrt(lambda*(sqrt(ifwd)-vdss/Vt)+1.0/64);
|
||||||
// eq. 49
|
// eq. 49
|
||||||
vds = 0.5*(vd-vs);
|
vds = 0.5*(vd-vs);
|
||||||
// eq. 50
|
// eq. 50
|
||||||
vip = sqrt(`SQR(vdss)+`SQR(dv))-sqrt(`SQR(vds-vdss)+`SQR(dv));
|
vip = sqrt(`SQR(vdss)+`SQR(dv))-sqrt(`SQR(vds-vdss)+`SQR(dv));
|
||||||
// eq. 52
|
// eq. 52
|
||||||
dl = LAMBDA*lc*ln(1+(vds-vip)/(lc*ucrit));
|
dl_a = lambda*lc*ln(1+(vds-vip)/(lc*ucrit_a));
|
||||||
|
|
||||||
// eq. 53
|
// eq. 53
|
||||||
lprime = ns*leff-dl+(vds+vip)/ucrit;
|
lprime = ns*leff-dl_a+(vds+vip)/ucrit_a;
|
||||||
// eq. 55
|
// eq. 55
|
||||||
leq = 0.5*(lprime+sqrt(`SQR(lprime)+`SQR(lmin)));
|
leq = 0.5*(lprime+sqrt(`SQR(lprime)+`SQR(lmin)));
|
||||||
|
|
||||||
// eq. 56
|
// eq. 56
|
||||||
fv=(vp-vds-vs-sqrt(`SQR(vdssprime)+`SQR(dv))+sqrt(`SQR(vds-vdssprime)+`SQR(dv)))/vt;
|
fv=(vp-vds-vs-sqrt(`SQR(vdssprime)+`SQR(dv))+sqrt(`SQR(vds-vdssprime)+`SQR(dv)))/Vt;
|
||||||
|
|
||||||
if (fv > -0.35) begin
|
`y_fv(fv,y)
|
||||||
z0 = 2.0/(1.3 + fv - ln(fv+1.6));
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -15) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
z0 = 1.55 + tmp;
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -23.0) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
y = 1.0 / (2.0 + tmp);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
`expl(fv,tmp)
|
|
||||||
y = tmp + 1.0e-64;
|
|
||||||
end
|
|
||||||
|
|
||||||
irprime = y*(1.0 + y);
|
irprime = y*(1.0 + y);
|
||||||
z0 = 1;
|
|
||||||
z1 = 1;
|
|
||||||
|
|
||||||
// eq. 57
|
// eq. 57
|
||||||
fv=(vp-vd)/vt;
|
fv=(vp-vd)/Vt;
|
||||||
|
|
||||||
if (fv > -0.35) begin
|
`y_fv(fv,y)
|
||||||
z0 = 2.0/(1.3 + fv - ln(fv+1.6));
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -15) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
z0 = 1.55 + tmp;
|
|
||||||
z1 = (2.0 + z0) / (1.0 + fv + ln(z0));
|
|
||||||
y = (1.0 + fv + ln(z1)) / (2.0 + z1);
|
|
||||||
end
|
|
||||||
else if (fv > -23.0) begin
|
|
||||||
`expl(-fv,tmp)
|
|
||||||
y = 1.0 / (2.0 + tmp);
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
`expl(fv,tmp)
|
|
||||||
y = tmp + 1.0e-64;
|
|
||||||
end
|
|
||||||
|
|
||||||
irev = y*(1.0 + y);
|
irev = y*(1.0 + y);
|
||||||
|
|
||||||
// eq. 58
|
// eq. 58
|
||||||
beta0 = kp_a*np*weff/leq;
|
beta0 = kp_a*weff/leq;
|
||||||
// eq. 59
|
// eq. 59
|
||||||
nau = (5+MTYPE)/12.0;
|
nau = (5+MOStype)/12.0;
|
||||||
|
|
||||||
// eq. 69
|
// eq. 69
|
||||||
nq = 1+0.5*gamma_a/sqrt(vp+phi+1e-6);
|
nq = 1+0.5*gamma_a/sqrt(vp+phi_a+1e-6);
|
||||||
|
|
||||||
// eq. 70
|
// eq. 70
|
||||||
xf = sqrt(0.25+ifwd);
|
xf = sqrt(0.25+ifwd);
|
||||||
|
|
@ -500,35 +448,36 @@ module ekv (d,g,s,b);
|
||||||
// eq. 74
|
// eq. 74
|
||||||
qi = qs+qd;
|
qi = qs+qd;
|
||||||
// eq. 75
|
// eq. 75
|
||||||
if (vgprime>=0)
|
if (vgprime>=0) begin
|
||||||
qb = (-gamma_a*sqrt(vp+phi+1e-6))/vt-(nq-1)/nq*qi;
|
qb = (-gamma_a*sqrt(vp+phi_a+1e-6))/Vt-(nq-1)/nq*qi;
|
||||||
else
|
end else begin
|
||||||
qb = -vgprime/vt;
|
qb = -vgprime/Vt;
|
||||||
|
end
|
||||||
// eq. 76 (qox removed since it is assumed to be zero)
|
// eq. 76 (qox removed since it is assumed to be zero)
|
||||||
qg = -qi-qb;
|
qg = -qi-qb;
|
||||||
|
|
||||||
if (E0!=0) begin
|
if (e0!=0) begin
|
||||||
// eq. 61
|
// eq. 61
|
||||||
beta0prime = beta0*(1+COX/(E0*`EPSSI)*qb0);
|
beta0prime = beta0*(1+cox_p/(e0*`EPSSI)*qb0);
|
||||||
// eq. 62
|
// eq. 62
|
||||||
beta = beta0prime/(1+COX/(E0*`EPSSI)*vt*abs(qb+nau*qi));
|
beta = beta0prime/(1+cox_p/(e0*`EPSSI)*Vt*abs(qb+nau*qi));
|
||||||
end else begin
|
end else begin
|
||||||
// eq. 63
|
// eq. 63
|
||||||
vpprime = 0.5*(vp+sqrt(`SQR(vp)+2*`SQR(vt)));
|
vpprime = 0.5*(vp+sqrt(`SQR(vp)+2*`SQR(Vt)));
|
||||||
// eq. 64
|
// eq. 64
|
||||||
beta = beta0/(1+THETA*vpprime);
|
beta = beta0/(1+theta*vpprime);
|
||||||
end // else: !if(e0!=0)
|
end // else: !if(e0!=0)
|
||||||
// eq. 65
|
// eq. 65
|
||||||
is = 2*n*beta*`SQR(vt);
|
is = 2*nslope*beta*`SQR(Vt);
|
||||||
// $strobe("beta0=%e beta0prime=%e beta=%e E0=%e qb0=%e qb=%e qi=%e",beta0,beta0prime,beta,E0,qb0,qb,qi);
|
// $strobe("beta0=%e beta0prime=%e beta=%e e0=%e qb0=%e qb=%e qi=%e",beta0,beta0prime,beta,e0,qb0,qb,qi);
|
||||||
// eq. 66
|
// eq. 66
|
||||||
ids = is*(ifwd-irprime);
|
ids = is*(ifwd-irprime);
|
||||||
// eq. 67
|
// eq. 67
|
||||||
vib = vd-vs-IBN*2*vdss;
|
vib = vd-vs-ibn*2*vdss;
|
||||||
// eq. 68
|
// eq. 68
|
||||||
if (vib>0) begin
|
if (vib>0) begin
|
||||||
`expl((-ibb*lc)/vib,tmp)
|
`expLin(tmp,(-ibb_a*lc)/vib)
|
||||||
idb = ids*IBA/ibb*vib*tmp;
|
idb = ids*iba/ibb_a*vib*tmp;
|
||||||
end else
|
end else
|
||||||
idb = 0;
|
idb = 0;
|
||||||
// $strobe("ids=%e idb=%e",ids,idb);
|
// $strobe("ids=%e idb=%e",ids,idb);
|
||||||
|
|
@ -536,9 +485,9 @@ module ekv (d,g,s,b);
|
||||||
if (mode>1) begin
|
if (mode>1) begin
|
||||||
if (isat_s>0) begin
|
if (isat_s>0) begin
|
||||||
if (-vs>vexp_s)
|
if (-vs>vexp_s)
|
||||||
ibsj = IMAX+gexp_s*(-vs-vexp_s);
|
ibsj = imax+gexp_s*(-vs-vexp_s);
|
||||||
else begin
|
else begin
|
||||||
`expl(-vs/(N*vt),tmp)
|
`expLin(tmp,-vs/(n*Vt))
|
||||||
ibsj = isat_s*(tmp-1);
|
ibsj = isat_s*(tmp-1);
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
|
@ -546,9 +495,9 @@ module ekv (d,g,s,b);
|
||||||
|
|
||||||
if (isat_d>0) begin
|
if (isat_d>0) begin
|
||||||
if (-vd>vexp_d)
|
if (-vd>vexp_d)
|
||||||
ibdj = IMAX+gexp_d*(-vd-vexp_d);
|
ibdj = imax+gexp_d*(-vd-vexp_d);
|
||||||
else begin
|
else begin
|
||||||
`expl(-vd/(N*vt),tmp)
|
`expLin(tmp,-vd/(n*Vt))
|
||||||
ibdj = isat_d*(tmp-1);
|
ibdj = isat_d*(tmp-1);
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
|
@ -557,9 +506,9 @@ module ekv (d,g,s,b);
|
||||||
end else begin // if (mode>1)
|
end else begin // if (mode>1)
|
||||||
if (isat_s>0) begin
|
if (isat_s>0) begin
|
||||||
if (-vd>vexp_s)
|
if (-vd>vexp_s)
|
||||||
ibsj = IMAX+gexp_s*(-vd-vexp_s);
|
ibsj = imax+gexp_s*(-vd-vexp_s);
|
||||||
else begin
|
else begin
|
||||||
`expl(-vd/(N*vt),tmp)
|
`expLin(tmp,-vd/(n*Vt))
|
||||||
ibsj = isat_s*(tmp-1);
|
ibsj = isat_s*(tmp-1);
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
|
@ -567,9 +516,9 @@ module ekv (d,g,s,b);
|
||||||
|
|
||||||
if (isat_d>0) begin
|
if (isat_d>0) begin
|
||||||
if (-vs>vexp_d)
|
if (-vs>vexp_d)
|
||||||
ibdj = IMAX+gexp_d*(-vs-vexp_d);
|
ibdj = imax+gexp_d*(-vs-vexp_d);
|
||||||
else begin
|
else begin
|
||||||
`expl(-vs/(N*vt),tmp)
|
`expLin(tmp,-vs/(n*Vt))
|
||||||
ibdj = isat_d*(tmp-1);
|
ibdj = isat_d*(tmp-1);
|
||||||
end
|
end
|
||||||
end else
|
end else
|
||||||
|
|
@ -577,78 +526,88 @@ module ekv (d,g,s,b);
|
||||||
|
|
||||||
end // else: !if(mode>1)
|
end // else: !if(mode>1)
|
||||||
|
|
||||||
qdt = coxt*vt*qd;
|
qdt = coxt*Vt*qd;
|
||||||
qst = coxt*vt*qs;
|
qst = coxt*Vt*qs;
|
||||||
qgt = coxt*vt*qg;
|
qgt = coxt*Vt*qg;
|
||||||
qbt = coxt*vt*qb;
|
// qbt = coxt*Vt*qb;
|
||||||
|
|
||||||
cbs = 0;
|
cbs = 0;
|
||||||
cbd = 0;
|
cbd = 0;
|
||||||
|
v_bp_dp = MOStype*V(b,dp);
|
||||||
|
v_bp_sp = MOStype*V(b,sp);
|
||||||
if (cbs0>0) begin
|
if (cbs0>0) begin
|
||||||
if (MTYPE*V(b,si)>FC*PB)
|
if (v_bp_sp>fc*pb) begin
|
||||||
cbs = cbs+cbs0/pow(1-FC,MJ)*(1+MJ*(MTYPE*V(b,si)-PB*FC))/(PB*(1-FC));
|
cbs = cbs+cbs0/pow(1-fc,mj)*(1+mj*(v_bp_sp-pb*fc))/(pb*(1-fc));
|
||||||
else
|
end else begin
|
||||||
cbs = cbs+cbs0/pow(1-MTYPE*V(b,si),MJ);
|
cbs = cbs+cbs0/pow(1-v_bp_sp,mj);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if (cbd0>0) begin
|
if (cbd0>0) begin
|
||||||
if (MTYPE*V(b,di)>FC*PB)
|
if (v_bp_dp>fc*pb) begin
|
||||||
cbd = cbd+cbd0/pow(1-FC,MJ)*(1+MJ*(MTYPE*V(b,di)-PB*FC))/(PB*(1-FC));
|
cbd = cbd+cbd0/pow(1-fc,mj)*(1+mj*(v_bp_dp-pb*fc))/(pb*(1-fc));
|
||||||
else
|
end else begin
|
||||||
cbd = cbd+cbd0/pow(1-MTYPE*V(b,di),MJ);
|
cbd = cbd+cbd0/pow(1-v_bp_dp,mj);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if (cbs0sw>0) begin
|
if (cbs0sw>0) begin
|
||||||
if (MTYPE*V(b,si)>FCSW*PBSW)
|
if (v_bp_sp>fcsw*pbsw) begin
|
||||||
cbs = cbs+cbs0sw/pow(1-FCSW,MJSW)*(1+MJSW*(MTYPE*V(b,si)-PBSW*FCSW))/(PBSW*(1-FCSW));
|
cbs = cbs+cbs0sw/pow(1-fcsw,mjsw)*(1+mjsw*(v_bp_sp-pbsw*fcsw))/(pbsw*(1-fcsw));
|
||||||
else
|
end else begin
|
||||||
cbs = cbs+cbs0sw/pow(1-MTYPE*V(b,si),MJSW);
|
cbs = cbs+cbs0sw/pow(1-v_bp_sp,mjsw);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if (cbd0sw>0) begin
|
if (cbd0sw>0) begin
|
||||||
if (MTYPE*V(b,di)>FCSW*PBSW)
|
if (v_bp_dp>fcsw*pbsw) begin
|
||||||
cbd = cbd+cbd0sw/pow(1-FCSW,MJSW)*(1+MJSW*(MTYPE*V(b,di)-PBSW*FCSW))/(PBSW*(1-FCSW));
|
cbd = cbd+cbd0sw/pow(1-fcsw,mjsw)*(1+mjsw*(v_bp_dp-pbsw*fcsw))/(pbsw*(1-fcsw));
|
||||||
else
|
end else begin
|
||||||
cbd = cbd+cbd0sw/pow(1-MTYPE*V(b,di),MJSW);
|
cbd = cbd+cbd0sw/pow(1-v_bp_dp,mjsw);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end //Bias-dependent model evaluation
|
end //Bias-dependent model evaluation
|
||||||
|
|
||||||
begin //Define branch sources
|
begin //Define branch sources
|
||||||
|
|
||||||
I(di,si) <+ MTYPE*mode*ids;
|
I(dpsp) <+ MOStype*mode*ids;
|
||||||
if (mode>0) begin
|
I(dpsp) <+ gmin*V(dpsp);
|
||||||
I(di,b) <+ MTYPE*idb;
|
|
||||||
|
|
||||||
I(di,g) <+ MTYPE*ddt(qdt);
|
if (mode>0) begin
|
||||||
I(si,g) <+ MTYPE*ddt(qst);
|
I(dpb) <+ MOStype*idb;
|
||||||
|
I(dpb) <+ gmin*V(dpb);
|
||||||
|
|
||||||
|
qdtx = qdt;
|
||||||
|
qstx = qst;
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
I(si,b) <+ MTYPE*idb;
|
I(spb) <+ MOStype*idb;
|
||||||
|
I(spb) <+ gmin*V(spb);
|
||||||
|
|
||||||
I(si,g) <+ MTYPE*ddt(qdt);
|
qdtx = qst;
|
||||||
I(di,g) <+ MTYPE*ddt(qst);
|
qstx = qdt;
|
||||||
|
|
||||||
end // else: !if(mode>0)
|
end // else: !if(mode>0)
|
||||||
|
|
||||||
I(b,si) <+ MTYPE*ibsj;
|
I(dpb) <+ MOStype*ddt(qdtx);
|
||||||
I(b,di) <+ MTYPE*ibdj;
|
I(spb) <+ MOStype*ddt(qstx);
|
||||||
|
I(gb) <+ MOStype*ddt(qgt);
|
||||||
|
//$strobe("V(dpb): %e qdtx=%e V(spb): %e qstx=%e V(gb): %e qgt: %e" ,V(dpb),qdtx,V(spb),qstx,V(gb),qgt);
|
||||||
|
|
||||||
I(b,g) <+ MTYPE*ddt(qbt);
|
I(b,sp) <+ MOStype*ibsj;
|
||||||
|
I(b,dp) <+ MOStype*ibdj;
|
||||||
|
|
||||||
I(g,si) <+ cgso*ddt(V(g,si));
|
qjs = cbs * v_bp_sp;
|
||||||
I(g,di) <+ cgdo*ddt(V(g,di));
|
qjd = cbd * v_bp_dp;
|
||||||
I(g,b) <+ cgbo*ddt(V(g,b));
|
I(b,sp) <+ MOStype*ddt(qjs);
|
||||||
|
I(b,dp) <+ MOStype*ddt(qjd);
|
||||||
|
//$strobe("v_bp_sp: %e cbs=%e v_bp_dp: %e cbd=%e" ,v_bp_sp,cbs,v_bp_dp,cbd);
|
||||||
|
|
||||||
if (RD>0)
|
I(gpsp) <+ ddt(cgso_s*V(gpsp));
|
||||||
I(d,di) <+ V(d,di)/rd;
|
I(gpdp) <+ ddt(cgdo_s*V(gpdp));
|
||||||
else
|
I(gb) <+ ddt(cgbo_s*V(gb)) + gmin*V(dpsp);
|
||||||
V(d,di) <+ 0.0;
|
//$strobe("V(gpsp): %e cgso_s=%e V(gpdp): %e cgdo_s=%e V(gb): %e cgbo_s: %e" ,V(gpsp),cgso_s,V(gpdp),cgdo_s,V(gb),cgbo_s);
|
||||||
if (RS>0)
|
|
||||||
I(s,si) <+ V(s,si)/rs;
|
|
||||||
else
|
|
||||||
V(s,si) <+ 0.0;
|
|
||||||
|
|
||||||
I(b,si) <+ cbs*ddt(V(b,si));
|
I(ddp) <+ V(ddp)/RDeff;
|
||||||
I(b,di) <+ cbd*ddt(V(b,di));
|
I(ssp) <+ V(ssp)/RSeff;
|
||||||
|
|
||||||
end // begin
|
end // begin
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue