You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

8240 lines
276 KiB

/***********************************************************************
HiSIM (Hiroshima University STARC IGFET Model)
Copyright (C) 2014 Hiroshima University & STARC
MODEL NAME : HiSIM
( VERSION : 2 SUBVERSION : 8 REVISION : 0 )
FILE : hsm2eval.c
Date : 2014.6.5
released by
Hiroshima University &
Semiconductor Technology Academic Research Center (STARC)
***********************************************************************/
/**********************************************************************
The following source code, and all copyrights, trade secrets or other
intellectual property rights in and to the source code in its entirety,
is owned by the Hiroshima University and the STARC organization.
All users need to follow the "HiSIM2 Distribution Statement and
Copyright Notice" attached to HiSIM2 model.
-----HiSIM2 Distribution Statement and Copyright Notice--------------
Software is distributed as is, completely without warranty or service
support. Hiroshima University or STARC and its employees are not liable
for the condition or performance of the software.
Hiroshima University and STARC own the copyright and grant users a perpetual,
irrevocable, worldwide, non-exclusive, royalty-free license with respect
to the software as set forth below.
Hiroshima University and STARC hereby disclaim all implied warranties.
Hiroshima University and STARC grant the users the right to modify, copy,
and redistribute the software and documentation, both within the user's
organization and externally, subject to the following restrictions
1. The users agree not to charge for Hiroshima University and STARC code
itself but may charge for additions, extensions, or support.
2. In any product based on the software, the users agree to acknowledge
Hiroshima University and STARC that developed the software. This
acknowledgment shall appear in the product documentation.
3. The users agree to reproduce any copyright notice which appears on
the software on any copy or modification of such made available
to others."
*************************************************************************/
/*********************************************************************
* Memorandum on programming
*
* (1) Bias (x: b|d|g)
* . vxs : Input argument.
* . Vxse: External bias taking account device type (pMOS->nMOS).
* . Vxsc: Confined bias within a specified region.
* . Vxs : Internal bias.
* . Y_dVxs denotes the partial derivative of Y w.r.t. Vxs.
*
* (2) Device Mode
* . Normal mode (Vds>0 for nMOS) is assumed.
* . In case of reverse mode, parent routines have to properly
* transform or interchange inputs and outputs except ones
* related to junction diodes, which are regarded as being
* fixed to the nodal S/D.
*
* (3) Modification for symmetry at Vds=0
* . Vxsz: Modified bias. (x: b|d|g)
* . Ps0z: Modified Ps0.
* . The following variables are calculated as a function of
* modified biases or potential.
* Tox, Cox, (-- with quantum effect)
* Vth*, dVth*, dPpg, Igate, Igidl, Igisl.
* . The following variables are calculated using a transform
* function.
* Lred
*
* (4) Zones and Cases (terminology)
*
* Chi:=beta*(Ps0-Vbs)= 0 3 5
*
* Zone: A | D1 | D2 | D3
* |
* (accumulation)|(depletion)
* |
* Vgs = Vgs_fb Vth
* / /
* Case: Nonconductive / Conductive
* /
* VgVt:=Qn0/Cox= VgVt_small
*
* . Ids is regarded as zero in zone-A.
* . Procedure to calculate Psl and dependent variables is
* omitted in the nonconductive case. Ids and Qi are regarded
* as zero in this case.
*
*********************************************************************/
/*===========================================================*
* Preamble.
*=================*/
/*---------------------------------------------------*
* Header files.
*-----------------*/
#include "ngspice/ngspice.h"
#ifdef __STDC__
/* #include <ieeefp.h> */
#endif
#include "ngspice/cktdefs.h"
/*-----------------------------------*
* HiSIM macros
*-----------------*/
#include "hisim2.h"
#include "hsm2evalenv.h"
/*-----------------------------------*
* HiSIM constants
*-----------------*/
#define C_sce_dlt (1.0e-2)
#define C_gidl_delta 0.5
#define C_PSLK_DELTA 1e-3 /* delta for Pslk smoothing */
#define C_PSLK_SHIFT 1.0 /* constant value for temporary shift */
#define C_IDD_MIN 1.0e-15
/*===========================================================*
* pow
*=================*/
#ifdef POW_TO_EXP_AND_LOG
#define Fn_Pow( x , y ) ( (x==0.0) ? 0.0 : exp( (y) * log( x ) ) )
#else
#define Fn_Pow( x , y ) ( (x==0.0) ? 0.0 : pow( x , y ) )
#endif
/*===========================================================*
* Exp() for PGD.
* - ExpLim(-3)=0
*=================*/
#define Fn_ExpLim( y , x , dx ) { \
if ( (x) < -3.0 ) { \
dx = 0.0 ; \
y = 0.0 ; \
} else if ( (x) < 0.0 ) { \
dx = 1.0 + (x) * ( 2 * (1.0/3.0) + (x) * 3 * (1.0/27.0) ) ; \
y = 1.0 + (x) * ( 1.0 + (x) * ( (1.0/3.0) + (x) * (1.0/27.0) ) ) ; \
} else { \
dx = 1.0 + (x) * ( 2 * (1.0/3.0) + (x) * ( 3 * 0.0402052934513951 \
+ (x) * 4 * 0.148148111111111 ) ) ; \
y = 1.0 + (x) * ( 1.0 + (x) * ( (1.0/3.0) + (x) * ( 0.0402052934513951 \
+ (x) * 0.148148111111111 ) ) ) ; \
} \
}
/*===========================================================*
* Ceiling, smoothing functions.
*=================*/
/*---------------------------------------------------*
* smoothUpper: ceiling.
* y = xmax - 0.5 ( arg + sqrt( arg^2 + 4 xmax delta ) )
* arg = xmax - x - delta
*-----------------*/
#define Fn_SU( y , x , xmax , delta , dx ) { \
double TMF1, TMF2; \
TMF1 = ( xmax ) - ( x ) - ( delta ) ; \
TMF2 = 4.0 * ( xmax ) * ( delta) ; \
TMF2 = TMF2 > 0.0 ? TMF2 : - ( TMF2 ) ; \
TMF2 = sqrt ( TMF1 * TMF1 + TMF2 ) ; \
dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \
y = ( xmax ) - 0.5 * ( TMF1 + TMF2 ) ; \
}
#define Fn_SU2( y , x , xmax , delta , dy_dx , dy_dxmax ) { \
double TMF1, TMF2; \
TMF1 = ( xmax ) - ( x ) - ( delta ) ; \
TMF2 = 4.0 * ( xmax ) * ( delta) ; \
TMF2 = TMF2 > 0.0 ? TMF2 : - ( TMF2 ) ; \
TMF2 = sqrt ( TMF1 * TMF1 + TMF2 ) ; \
dy_dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \
dy_dxmax = 0.5 * ( 1.0 - ( TMF1 + 2.0 * delta ) / TMF2 ) ; \
y = ( xmax ) - 0.5 * ( TMF1 + TMF2 ) ; \
}
/*---------------------------------------------------*
* smoothLower: flooring.
* y = xmin + 0.5 ( arg + sqrt( arg^2 + 4 xmin delta ) )
* arg = x - xmin - delta
*-----------------*/
#define Fn_SL( y , x , xmin , delta , dx ) { \
double TMF1, TMF2; \
TMF1 = ( x ) - ( xmin ) - ( delta ) ; \
TMF2 = 4.0 * ( xmin ) * ( delta ) ; \
TMF2 = TMF2 > 0.0 ? TMF2 : - ( TMF2 ) ; \
TMF2 = sqrt ( TMF1 * TMF1 + TMF2 ) ; \
dx = 0.5 * ( 1.0 + TMF1 / TMF2 ) ; \
y = ( xmin ) + 0.5 * ( TMF1 + TMF2 ) ; \
}
/*---------------------------------------------------*
* smoothZero: flooring to zero.
* y = 0.5 ( x + sqrt( x^2 + 4 delta^2 ) )
*-----------------*/
#define Fn_SZ( y , x , delta , dx ) { \
double TMF2; \
TMF2 = sqrt ( ( x ) * ( x ) + 4.0 * ( delta ) * ( delta) ) ; \
dx = 0.5 * ( 1.0 + ( x ) / TMF2 ) ; \
y = 0.5 * ( ( x ) + TMF2 ) ; \
if( y < 0.0 ) { y=0.0; dx=0.0; } \
}
#if 0
/*---------------------------------------------------*
* smoothZero: flooring to zero.
* y = 0.5 ( x + sqrt( x^2 + 4 delta^2 ) )
*-----------------*/
static double smoothZero
(
double x,
double delta,
double *dx
)
{
double sqr = sqrt ( x * x + 4.0 * delta * delta) ;
if (dx) *dx = 0.5 * ( 1.0 + x / sqr ) ;
return 0.5 * ( x + sqr ) ;
}
/*---------------------------------------------------*
* CeilingPow: ceiling for positive x, flooring for negative x.
* y = x * xmax / ( x^{2m} + xmax^{2m} )^{1/(2m)}
* note:
* - xmax has to be positive.
* - -xmax < y < xmax.
* - dy/dx|_{x=0} = 1.
*-----------------*/
static double CeilingPow
(
double x,
double xmax,
int pw,
double *dx
)
{
double x2 = x * x ;
double xmax2 = xmax * xmax ;
double xp = 1.0 , xmp = 1.0 ;
int m , mm ;
double arg , dnm ;
double result ;
for ( m = 0 ; m < pw ; m ++ ) {
xp *= x2 ;
xmp *= xmax2 ;
}
arg = xp + xmp ;
dnm = arg ;
if ( pw == 1 || pw == 2 || pw == 4 || pw == 8 ) {
if ( pw == 1 ) {
mm = 1 ;
} else if ( pw == 2 ) {
mm = 2 ;
} else if ( pw == 4 ) {
mm = 3 ;
} else if ( pw == 8 ) {
mm = 4 ;
}
for ( m = 0 ; m < mm ; m ++ ) {
dnm = sqrt( dnm ) ;
}
} else {
dnm = pow( dnm , 1.0 / ( 2.0 * pw ) ) ;
}
dnm = 1.0 / dnm ;
result = x * xmax * dnm ;
(*dx) = xmax * xmp * dnm / arg ;
return result ;
}
#endif
/*---------------------------------------------------*
* CeilingPow: ceiling for positive x, flooring for negative x.
* y = x * xmax / ( x^{2m} + xmax^{2m} )^{1/(2m)}
* note:
* - xmax has to be positive.
* - -xmax < y < xmax.
* - dy/dx|_{x=0} = 1.
*-----------------*/
#define Fn_CP( y , x , xmax , pw , dx ) { \
double x2 = (x) * (x) ; \
double xmax2 = (xmax) * (xmax) ; \
double xp = 1.0 , xmp = 1.0 ; \
int m , mm ; \
double arg_cp , dnm ; \
for ( m = 0 ; m < pw ; m ++ ) { xp *= x2 ; xmp *= xmax2 ; } \
arg_cp = xp + xmp ; \
dnm = arg_cp ; \
if ( pw == 1 || pw == 2 || pw == 4 || pw == 8 ) { \
if ( pw == 1 ) { mm = 1 ; \
} else if ( pw == 2 ) { mm = 2 ; \
} else if ( pw == 4 ) { mm = 3 ; \
} else if ( pw == 8 ) { mm = 4 ; } \
for ( m = 0 ; m < mm ; m ++ ) { dnm = sqrt( dnm ) ; } \
} else { dnm = Fn_Pow( dnm , 1.0 / ( 2.0 * pw ) ) ; } \
dnm = 1.0 / dnm ; \
y = (x) * (xmax) * dnm ; \
dx = (xmax) * xmp * dnm / arg_cp ; \
}
#define Fn_SU_CP2( y , x , xmax , delta , pw , dx , dxmax ) { \
if(x > xmax - delta && delta >= 0.0) { \
double TMF0, TMF1; \
TMF1 = x - xmax + delta ; \
Fn_CP( TMF0 , TMF1 , delta , pw , dx ) \
y = xmax - delta + TMF0 ; \
dx = dx ; \
dxmax = 1.0-dx ; \
} else { \
y = x ; \
dx = 1.0 ; \
dxmax = 0.0 ; \
} \
}
#define Fn_CP2( y , x , xmax , pw , dx , dxmax ) { \
double x2 = (x) * (x) ; \
double xmax2 = (xmax) * (xmax) ; \
double xp = 1.0 , xmp = 1.0 ; \
int m =0, mm =0; \
double arg_cp2 =0.0, dnm =0.0; \
for ( m = 0 ; m < pw ; m ++ ) { xp *= x2 ; xmp *= xmax2 ; } \
arg_cp2 = xp + xmp ; \
dnm = arg_cp2 ; \
if ( pw == 1 || pw == 2 || pw == 4 || pw == 8 ) { \
if ( pw == 1 ) { mm = 1 ; \
} else if ( pw == 2 ) { mm = 2 ; \
} else if ( pw == 4 ) { mm = 3 ; \
} else if ( pw == 8 ) { mm = 4 ; } \
for ( m = 0 ; m < mm ; m ++ ) { dnm = sqrt( dnm ) ; } \
} else { dnm = Fn_Pow( dnm , 1.0 / ( 2.0 * pw ) ) ; } \
dnm = 1.0 / dnm ; \
y = (x) * (xmax) * dnm ; \
dx = (xmax) * xmp * dnm / arg_cp2 ; \
dxmax = (x) * xp * dnm / arg_cp2 ; \
}
#define Fn_SU_CP3( y , x , xmax , delta , pw , dx , dxmax , ddelta ) { \
if(x > xmax - delta && delta >= 0.0) { \
double TMF0, TMF1; \
TMF1 = x - xmax + delta ; \
Fn_CP2( TMF0 , TMF1 , delta , pw , dx , ddelta ) \
y = xmax - delta + TMF0 ; \
dx = dx ; \
dxmax = 1.0-dx ; \
ddelta = -1.0+dx+ddelta; \
} else { \
y = x ; \
dx = 1.0 ; \
dxmax = 0.0 ; \
ddelta = 0.0 ; \
} \
}
#define Fn_SU_CP( y , x , xmax , delta , pw , dx ) { \
if(x > xmax - delta && delta >= 0.0) { \
double TMF0, TMF1; \
TMF1 = x - xmax + delta ; \
Fn_CP( TMF0 , TMF1 , delta , pw , dx ) \
y = xmax - delta + TMF0 ; \
dx = dx ; \
} else { \
y = x ; \
dx = 1.0 ; \
} \
}
#define Fn_SL_CP2( y , x , xmin , delta , pw , dx , dxmin) { \
if(x < xmin + delta && delta >= 0.0) { \
double TMF0, TMF1; \
TMF1 = xmin + delta - x ; \
Fn_CP( TMF0 , TMF1 , delta , pw , dx ) \
y = xmin + delta - TMF0 ; \
dx = dx ; \
dxmin = 1.0-dx ; \
} else { \
y = x ; \
dx = 1.0 ; \
dxmin = 0.0 ; \
} \
}
#define Fn_SL_CP( y , x , xmin , delta , pw , dx ) { \
if(x < xmin + delta && delta >= 0.0) { \
double TMF0, TMF1; \
TMF1 = xmin + delta - x ; \
Fn_CP( TMF0 , TMF1 , delta , pw , dx ) \
y = xmin + delta - TMF0 ; \
dx = dx ; \
} else { \
y = x ; \
dx = 1.0 ; \
} \
}
/*===========================================================*
* Functions for symmetry.
*=================*/
/*---------------------------------------------------*
* Declining function using a polynomial.
*-----------------*/
#define Fn_DclPoly4( y , x , dx ) { \
double TMF2, TMF3, TMF4; \
TMF2 = (x) * (x) ; \
TMF3 = TMF2 * (x) ; \
TMF4 = TMF2 * TMF2 ; \
y = 1.0 / ( 1.0 + (x) + TMF2 + TMF3 + TMF4 ) ; \
dx = - ( 1.0 + 2.0 * (x) + 3.0 * TMF2 + 4.0 * TMF3 ) * y * y ; \
}
/*---------------------------------------------------*
* "smoothUpper" uasing a polynomial
*-----------------*/
#define Fn_SUPoly4( y , x , xmax , dx ) { \
double TMF1; \
TMF1 = (x) / xmax ; \
Fn_DclPoly4( y , TMF1 , dx ) ; \
y = xmax * ( 1.0 - y ) ; \
dx = - dx ; \
}
#define Fn_SUPoly4m( y , x , xmax , dx , dxmax ) { \
double TMF0, TMF1; \
TMF1 = (x) / xmax ; \
Fn_DclPoly4( TMF0 , TMF1 , dx ) ; \
y = xmax * ( 1.0 - TMF0 ) ; \
dxmax = 1.0 - TMF0 + TMF1 * dx ; \
dx = - dx ; \
}
/*---------------------------------------------------*
* SymAdd: evaluate additional term for symmetry.
*-----------------*/
#define Fn_SymAdd( y , x , add0 , dx ) \
{ \
double TMF1, TMF2, TMF3; \
TMF1 = 2.0 * ( x ) / ( add0 ) ; \
TMF2 = 1.0 + TMF1 * ( (1.0/2) + TMF1 * ( (1.0/6) \
+ TMF1 * ( (1.0/24) + TMF1 * ( (1.0/120) \
+ TMF1 * ( (1.0/720) + TMF1 * (1.0/5040) ) ) ) ) ) ; \
TMF3 = (1.0/2) + TMF1 * ( (1.0/3) \
+ TMF1 * ( (1.0/8) + TMF1 * ( (1.0/30) \
+ TMF1 * ( (1.0/144) + TMF1 * (1.0/840) ) ) ) ) ; \
y = add0 / TMF2 ; \
dx = - 2.0 * TMF3 / ( TMF2 * TMF2 ) ; \
}
/*===========================================================*
* Function hsm2evaluate.
*=================*/
int HSM2evaluate
(
double vds,
double vgs,
double vbs,
double vbs_jct,
double vbd_jct,
HSM2instance *here,
HSM2model *model,
CKTcircuit *ckt
)
{
HSM2binningParam *pParam = &here->pParam ;
HSM2modelMKSParam *modelMKS = &model->modelMKS ;
/*-----------------------------------*
* Constants for Smoothing functions
*---------------*/
const double vth_dlt = 1.0e-3 ;
/* const double cclmmdf = 1.0e-2 ;*/
const double cclmmdf = 1.0e-1 ;
const double qme_dlt = 1.0e-4 ;
const double eef_dlt = 1.0e-2 * C_m2cm ;
const double sti2_dlt = 2.0e-3 ;
const double pol_dlt = 5.0e-2 ;
//const double psia_dlt = 1.0e-3 ;
//const double psia2_dlt = 5.0e-3 ;
const double psisti_dlt = 5.0e-3 ;
//const double jct_dlt = 1.0e-2 ;
/*---------------------------------------------------*
* Local variables.
*-----------------*/
/* Constants ----------------------- */
const int lp_s0_max = 20 ;
const int lp_sl_max = 20 ;
const int lp_se_max = 150 ;
int lp_bs_max = 10 ;
const double Ids_tol = 1.0e-10 ;
const double Ids_maxvar = 1.0e-1 ;
const double dP_max = 0.1e0 ;
const double ps_conv = 5.0e-13 ;
const double ps_conv2 = 1.0e-10 ;
/* double ps_conv = 1.0e-13 ;*/
const double gs_conv = 1.0e-8 ;
const double mini_current = 1.0e-15 ;
/** depletion **/
const double znbd3 = 3.0e0 ;
const double znbd5 = 5.0e0 ;
const double cn_nc3 = C_SQRT_2 / 108e0 ;
/* 5-degree, contact:Chi=5 */
const double cn_nc51 = 0.707106781186548 ; /* sqrt(2)/2 */
const double cn_nc52 = -0.117851130197758 ; /* -sqrt(2)/12 */
const double cn_nc53 = 0.0178800506338833 ; /* (187 - 112*sqrt(2))/1600 */
const double cn_nc54 = -0.00163730162779191 ; /* (-131 + 88*sqrt(2))/4000 */
const double cn_nc55 = 6.36964918866352e-5 ; /* (1509-1040*sqrt(2))/600000 */
/** inversion **/
/* 3-degree polynomial approx for ( exp[Chi]-1 )^{1/2} */
const double cn_im53 = 2.9693154855770998e-1 ;
const double cn_im54 = -7.0536542840097616e-2 ;
const double cn_im55 = 6.1152888951331797e-3 ;
/** initial guess **/
const double c_ps0ini_2 = 8.0e-4 ;
const double c_pslini_1 = 0.3e0 ;
const double c_pslini_2 = 3.0e-2 ;
const double VgVt_small = 1.0e-12 ;
const double Vbs_min = -10.5e0 ;
const double epsm10 = 10.0e0 * C_EPS_M ;
const double small = 1.0e-50 ;
const double small2 = 1.0e-12 ; /* for Qover */
double Vbs_max = 0.8e0 ;
double Vbs_bnd = 0.4e0 ; /* start point of positive Vbs bending */
double Gdsmin = 0.0 ;
double Gjmin = ckt->CKTgmin ;
/* Internal flags --------------------*/
int flg_err = 0 ; /* error level */
int flg_rsrd = 0 ; /* Flag for bias loop accounting Rs and Rd */
int flg_iprv = 0 ; /* Flag for initial guess of Ids */
int flg_pprv = 0 ; /* Flag for initial guesses of Ps0 and Pds */
int flg_noqi =0; /* Flag for the cases regarding Qi=Qd=0 */
int flg_vbsc = 0 ; /* Flag for Vbs confining */
int flg_info = 0 ;
int flg_conv = 0 ; /* Flag for Poisson loop convergence */
int flg_qme = 0 ; /* Flag for QME */
/* flag for NQS calculation */
int flg_nqs=0 ;
/* Important Variables in HiSIM -------*/
/* external bias */
double Vbse =0.0, Vdse =0.0, Vgse =0.0 ;
/* confine bias */
double Vbsc =0.0, Vdsc =0.0, Vgsc =0.0 ;
double Vbsc_dVbse =1.0, Vbsc_dVbse_dVbs =0.0 ;
/* internal bias */
double Vbs =0.0, Vds =0.0, Vgs =0.0, Vdb =0.0, Vsb =0.0 ;
double Vbs_dVbse = 1.0 , Vbs_dVdse = 0.0 , Vbs_dVgse = 0.0 ;
double Vds_dVbse = 0.0 , Vds_dVdse = 1.0 , Vds_dVgse = 0.0 ;
double Vgs_dVbse = 0.0 , Vgs_dVdse = 0.0 , Vgs_dVgse = 1.0 ;
double Vgp =0.0 ;
double Vgp_dVbs =0.0, Vgp_dVds =0.0, Vgp_dVgs =0.0 ;
double Vgs_fb =0.0 ;
/* Ps0 : surface potential at the source side */
double Ps0 =0.0 ;
double Ps0_dVbs =0.0, Ps0_dVds =0.0, Ps0_dVgs =0.0 ;
double Ps0_ini =0.0, Ps0_iniA =0.0, Ps0_iniB =0.0 ;
/* Psl : surface potential at the drain side */
double Psl =0.0 ;
double Psl_dVbs =0.0, Psl_dVds =0.0, Psl_dVgs =0.0 ;
double Psl_lim =0.0, dPlim =0.0 ;
/* Pds := Psl - Ps0 */
double Pds = 0.0 , Pdsz = 0.0 ;
double Pds_dVbs = 0.0, Pds_dVds = 0.0 , Pds_dVgs = 0.0 ;
double Pdsz_dVbs = 0.0, Pdsz_dVds = 0.0 , Pdsz_dVgs = 0.0 ;
double Pds_ini =0.0 ;
double Pds_max =0.0 ;
/* iteration numbers of Ps0 and Psl equations. */
int lp_s0 = 0 , lp_sl = 0 ;
/* Xi0 := beta * ( Ps0 - Vbs ) - 1. */
double Xi0 =0.0 ;
double Xi0_dVbs =0.0, Xi0_dVds =0.0, Xi0_dVgs =0.0 ;
double Xi0p12 =0.0 ;
double Xi0p12_dVbs =0.0, Xi0p12_dVds =0.0, Xi0p12_dVgs =0.0 ;
double Xi0p32 =0.0 ;
/* Xil := beta * ( Psl - Vbs ) - 1. */
double Xilp12 =0.0 ;
double Xilp32 =0.0 ;
double Xil =0.0 ;
/* modified bias and potential for sym.*/
double Vbsz =0.0, Vdsz =0.0, Vgsz =0.0 ;
double Vbsz_dVbs =0.0, Vbsz_dVds =0.0 ;
double Vdsz_dVds =0.0, Vdsz_dVbs =0.0 ;
double Vgsz_dVgs =0.0, Vgsz_dVbs =0.0, Vgsz_dVds =0.0 ;
double Vzadd =0.0, Vzadd_dVds =0.0, Vzadd_dVbs =0.0 ;
double Ps0z =0.0, Ps0z_dVbs =0.0, Ps0z_dVds =0.0, Ps0z_dVgs =0.0 ;
double Pzadd =0.0, Pzadd_dVbs =0.0, Pzadd_dVds =0.0, Pzadd_dVgs =0.0 ;
double Vgpz = 0.0 , Vgpz_dVbs = 0.0 , Vgpz_dVds = 0.0 , Vgpz_dVgs = 0.0 ; /* (tmp) */
/* IBPC */
double dVbsIBPC =0.0, dVbsIBPC_dVbs =0.0, dVbsIBPC_dVds =0.0, dVbsIBPC_dVgs =0.0 ;
double betaWL =0.0, betaWL_dVbs =0.0, betaWL_dVds =0.0, betaWL_dVgs =0.0 ;
double Xi0p32_dVbs =0.0, Xi0p32_dVds =0.0, Xi0p32_dVgs =0.0 ;
double Xil_dVbs =0.0, Xil_dVds =0.0, Xil_dVgs =0.0 ;
double Xilp12_dVbs =0.0, Xilp12_dVds =0.0, Xilp12_dVgs =0.0 ;
double Xilp32_dVbs =0.0, Xilp32_dVds =0.0, Xilp32_dVgs =0.0 ;
double dG3 =0.0, dG3_dVbs =0.0, dG3_dVds =0.0, dG3_dVgs =0.0 ;
double dG4 =0.0, dG4_dVbs =0.0, dG4_dVds =0.0, dG4_dVgs =0.0 ;
double dIdd =0.0, dIdd_dVbs =0.0, dIdd_dVds =0.0, dIdd_dVgs =0.0 ;
/* Chi := beta * ( Ps{0/l} - Vbs ) */
double Chi =0.0 ;
double Chi_dVbs =0.0, Chi_dVds =0.0, Chi_dVgs =0.0 ;
/* Rho := beta * ( Psl - Vds ) */
double Rho =0.0 ;
/* threshold voltage */
double Vth =0.0 ;
double Vth0 =0.0 ;
double Vth0_dVb =0.0, Vth0_dVd =0.0, Vth0_dVg =0.0 ;
/* variation of threshold voltage */
double dVth =0.0 ;
double dVth_dVb =0.0, dVth_dVd =0.0, dVth_dVg =0.0 ;
double dVth0 =0.0 ;
double dVth0_dVb =0.0, dVth0_dVd =0.0, dVth0_dVg =0.0 ;
double dVthSC =0.0 ;
double dVthSC_dVb =0.0, dVthSC_dVd =0.0, dVthSC_dVg =0.0 ;
double Pb20b =0.0 ;
double Pb20b_dVg =0.0, Pb20b_dVb =0.0, Pb20b_dVd =0.0 ;
double dVthW =0.0 ;
double dVthW_dVb =0.0, dVthW_dVd =0.0, dVthW_dVg =0.0 ;
/* Alpha and related parameters */
double Alpha =0.0 ;
double Alpha_dVbs =0.0, Alpha_dVds =0.0, Alpha_dVgs =0.0 ;
double Achi =0.0 ;
double Achi_dVbs =0.0, Achi_dVds =0.0, Achi_dVgs =0.0 ;
double VgVt = 0.0 ;
double VgVt_dVbs = 0.0, VgVt_dVds = 0.0, VgVt_dVgs = 0.0 ;
double Pslsat = 0.0 ;
double Vdsat = 0.0 ;
double VdsatS = 0.0 ;
double VdsatS_dVbs = 0.0, VdsatS_dVds = 0.0, VdsatS_dVgs = 0.0 ;
double Delta =0.0 ;
/* Q_B and capacitances */
double Qb =0.0, Qb_dVbs =0.0, Qb_dVds =0.0, Qb_dVgs =0.0 ;
double Qb_dVbse =0.0, Qb_dVdse =0.0, Qb_dVgse =0.0 ;
double Qbu = 0.0 , Qbu_dVbs = 0.0 , Qbu_dVds = 0.0 , Qbu_dVgs = 0.0 ;
/* Q_I and capacitances */
double Qi =0.0, Qi_dVbs =0.0, Qi_dVds =0.0, Qi_dVgs =0.0 ;
double Qi_dVbse =0.0, Qi_dVdse =0.0, Qi_dVgse =0.0 ;
double Qiu = 0.0 , Qiu_dVbs = 0.0 , Qiu_dVds = 0.0 , Qiu_dVgs = 0.0 ;
/* Q_D and capacitances */
double Qd =0.0, Qd_dVbs =0.0, Qd_dVds =0.0, Qd_dVgs =0.0 ;
double Qd_dVbse =0.0, Qd_dVdse =0.0, Qd_dVgse =0.0 ;
double qd_dVgse=0.0, qd_dVdse=0.0, qd_dVbse=0.0, qd_dVsse =0.0 ;
/* channel current */
double Ids =0.0 ;
double Ids_dVbs =0.0, Ids_dVds =0.0, Ids_dVgs =0.0 ;
double Ids_dVbse =0.0, Ids_dVdse =0.0, Ids_dVgse =0.0 ;
double Ids0 =0.0 ;
double Ids0_dVbs =0.0, Ids0_dVds =0.0, Ids0_dVgs =0.0 ;
/* STI */
double dVthSCSTI =0.0 ;
double dVthSCSTI_dVg =0.0, dVthSCSTI_dVd =0.0, dVthSCSTI_dVb =0.0 ;
double Vgssti =0.0 ;
double Vgssti_dVbs =0.0, Vgssti_dVds =0.0, Vgssti_dVgs =0.0 ;
double costi0 =0.0, costi1 =0.0, costi3 =0.0 ;
double costi4 =0.0, costi5 =0.0, costi6 =0.0, costi7 =0.0 ;
double costi3_dVb =0.0, costi3_dVd=0.0, costi3_dVg =0.0 ;
double costi3_dVb_c3 =0.0, costi3_dVd_c3=0.0, costi3_dVg_c3 =0.0 ;
double Psasti =0.0 ;
double Psasti_dVbs =0.0, Psasti_dVds =0.0, Psasti_dVgs =0.0 ;
double Psbsti =0.0 ;
double Psbsti_dVbs =0.0, Psbsti_dVds =0.0, Psbsti_dVgs =0.0 ;
double Psab =0.0 ;
double Psab_dVbs =0.0, Psab_dVds =0.0, Psab_dVgs =0.0 ;
double Psti =0.0 ;
double Psti_dVbs =0.0, Psti_dVds =0.0, Psti_dVgs =0.0 ;
double sq1sti =0.0 ;
double sq1sti_dVbs =0.0, sq1sti_dVds =0.0, sq1sti_dVgs =0.0 ;
double sq2sti =0.0 ;
double sq2sti_dVbs =0.0, sq2sti_dVds =0.0, sq2sti_dVgs =0.0 ;
double Qn0sti =0.0 ;
double Qn0sti_dVbs =0.0, Qn0sti_dVds =0.0, Qn0sti_dVgs =0.0 ;
double Idssti =0.0 ;
double Idssti_dVbs =0.0, Idssti_dVds =0.0, Idssti_dVgs =0.0 ;
/* constants */
double beta =0.0, beta_inv =0.0 ;
double beta2 =0.0 ;
double Pb2 =0.0 ;
double Pb20 =0.0 ;
double Pb2c =0.0 ;
double Vfb =0.0 ;
double c_eox =0.0 ;
double Leff=0.0, Weff =0.0 ;
double q_Nsub =0.0 ;
/* PART-1 */
/* Accumulation zone */
double Psa =0.0 ;
double Psa_dVbs =0.0, Psa_dVds =0.0, Psa_dVgs =0.0 ;
/* CLM*/
double Psdl =0.0, Psdl_dVbs =0.0, Psdl_dVds =0.0, Psdl_dVgs =0.0 ;
double Lred =0.0, Lred_dVbs =0.0, Lred_dVds =0.0, Lred_dVgs =0.0 ;
double Lch =0.0, Lch_dVbs =0.0, Lch_dVds =0.0, Lch_dVgs =0.0 ;
double Wd =0.0, Wd_dVbs =0.0, Wd_dVds =0.0, Wd_dVgs =0.0 ;
double Aclm =0.0 ;
/* Pocket Implant */
double Vthp=0.0, Vthp_dVb=0.0, Vthp_dVd=0.0, Vthp_dVg =0.0 ;
double dVthLP=0.0, dVthLP_dVb=0.0, dVthLP_dVd=0.0, dVthLP_dVg =0.0 ;
double bs12=0.0, bs12_dVb=0.0, bs12_dVd =0.0, bs12_dVg =0.0 ;
double Qbmm=0.0, Qbmm_dVb=0.0, Qbmm_dVd =0.0, Qbmm_dVg =0.0 ;
double dqb=0.0, dqb_dVb=0.0, dqb_dVg=0.0, dqb_dVd =0.0 ;
double Vdx=0.0, Vdx2 =0.0 ;
double Vdx_dVbs =0.0, Vdx2_dVbs =0.0 ;
double Pbsum=0.0, sqrt_Pbsum =0.0 ;
double Pbsum_dVb=0.0, Pbsum_dVd=0.0, Pbsum_dVg =0.0 ;
/* Poly-Depletion Effect */
const double pol_b = 1.0 ;
double dPpg =0.0, dPpg_dVb =0.0, dPpg_dVd =0.0, dPpg_dVg =0.0;
/* Quantum Effect */
double Tox =0.0, Tox_dVb =0.0, Tox_dVd =0.0, Tox_dVg =0.0 ;
double dTox =0.0, dTox_dVb =0.0, dTox_dVd =0.0, dTox_dVg =0.0 ;
double Cox =0.0, Cox_dVb =0.0, Cox_dVd =0.0, Cox_dVg =0.0 ;
double Cox_inv =0.0, Cox_inv_dVb =0.0, Cox_inv_dVd =0.0, Cox_inv_dVg =0.0 ;
double Tox0 =0.0, Cox0 =0.0, Cox0_inv =0.0 ;
double Vthq=0.0, Vthq_dVb =0.0, Vthq_dVd =0.0 ;
/* Igate , Igidl , Igisl */
const double igate_dlt = 1.0e-2 ;
double Psdlz =0.0, Psdlz_dVbs =0.0, Psdlz_dVds =0.0, Psdlz_dVgs =0.0 ;
double Egp12 =0.0, Egp32 =0.0 ;
double E1 =0.0, E1_dVb =0.0, E1_dVd =0.0, E1_dVg =0.0 ;
double Qb0Cox =0.0, Qb0Cox_dVb =0.0, Qb0Cox_dVd =0.0, Qb0Cox_dVg =0.0 ;
double Etun =0.0, Etun_dVbs =0.0, Etun_dVds =0.0, Etun_dVgs =0.0 ;
double Egidl =0.0, Egidl_dVb =0.0, Egidl_dVd =0.0, Egidl_dVg =0.0 ;
double Egisl =0.0, Egisl_dVb =0.0, Egisl_dVd =0.0, Egisl_dVg =0.0 ;
double Igate =0.0, Igate_dVbs =0.0, Igate_dVds =0.0, Igate_dVgs =0.0 ;
double Igate_dVbse =0.0, Igate_dVdse =0.0, Igate_dVgse =0.0 ;
double Igs =0.0, Igd =0.0, Igb =0.0 ;
double Igs_dVbs =0.0, Igs_dVds =0.0, Igs_dVgs =0.0 ;
double Igs_dVbse =0.0, Igs_dVdse =0.0, Igs_dVgse =0.0 ;
double Igd_dVbs =0.0, Igd_dVds =0.0, Igd_dVgs =0.0 ;
double Igd_dVbse =0.0, Igd_dVdse =0.0, Igd_dVgse =0.0 ;
double Igb_dVbs =0.0, Igb_dVds =0.0, Igb_dVgs =0.0 ;
double Igb_dVbse =0.0, Igb_dVdse =0.0, Igb_dVgse =0.0 ;
double Igidl =0.0, Igidl_dVbs =0.0, Igidl_dVds =0.0, Igidl_dVgs =0.0 ;
double Igidl_dVbse =0.0, Igidl_dVdse =0.0, Igidl_dVgse =0.0 ;
double Igisl =0.0, Igisl_dVbs =0.0, Igisl_dVds =0.0, Igisl_dVgs =0.0 ;
double Igisl_dVbse =0.0, Igisl_dVdse =0.0, Igisl_dVgse =0.0 ;
/* connecting function */
double FD2 =0.0, FD2_dVbs =0.0, FD2_dVds =0.0, FD2_dVgs =0.0 ;
double FMDVDS =0.0, FMDVDS_dVbs =0.0, FMDVDS_dVds =0.0, FMDVDS_dVgs =0.0 ;
double cnst0 =0.0, cnst1 =0.0 ;
double cnstCoxi =0.0 , cnstCoxi_dVg =0.0 , cnstCoxi_dVd =0.0 , cnstCoxi_dVb =0.0 ;
double fac1 =0.0 ;
double fac1_dVbs =0.0, fac1_dVds =0.0, fac1_dVgs =0.0 ;
double fac1p2 =0.0 ;
double fs01 =0.0 ;
double fs01_dPs0 =0.0 ;
double fs01_dVbs =0.0, fs01_dVds =0.0, fs01_dVgs =0.0 ;
double fs02 =0.0 ;
double fs02_dPs0 =0.0 ;
double fs02_dVbs =0.0, fs02_dVds =0.0, fs02_dVgs =0.0 ;
double fsl1 =0.0 ;
double fsl1_dPsl =0.0 ;
double fsl1_dVbs =0.0, fsl1_dVds =0.0, fsl1_dVgs =0.0; /* Vdseff */
double fsl2 =0.0 ;
double fsl2_dPsl =0.0 ;
double fsl2_dVbs =0.0, fsl2_dVds =0.0, fsl2_dVgs =0.0; /* Vdseff */
double cfs1 =0.0 ;
double fb =0.0, fb_dChi =0.0 ;
double fi =0.0, fi_dChi =0.0 ;
double exp_Chi =0.0, exp_Rho =0.0, exp_bVbs =0.0, exp_bVbsVds =0.0 ;
double Fs0=0.0, Fsl =0.0 ;
double Fs0_dPs0 =0.0, Fsl_dPsl =0.0 ;
double dPs0 =0.0, dPsl =0.0 ;
double Qn0 = 0.0e0 ;
double Qn0_dVbs =0.0, Qn0_dVds =0.0, Qn0_dVgs =0.0 ;
double Qb0 =0.0 ;
double Qb0_dVb =0.0, Qb0_dVd =0.0, Qb0_dVg =0.0 ;
double Qbnm =0.0 ;
double Qbnm_dVbs =0.0, Qbnm_dVds =0.0, Qbnm_dVgs =0.0 ;
double DtPds =0.0 ;
double DtPds_dVbs =0.0, DtPds_dVds =0.0, DtPds_dVgs =0.0 ;
double Qinm =0.0 ;
double Qinm_dVbs =0.0, Qinm_dVds =0.0, Qinm_dVgs =0.0 ;
double Qidn =0.0 ;
double Qidn_dVbs =0.0, Qidn_dVds =0.0, Qidn_dVgs =0.0 ;
double Qdnm =0.0 ;
double Qdnm_dVbs =0.0, Qdnm_dVds =0.0, Qdnm_dVgs =0.0 ;
double Qddn =0.0 ;
double Qddn_dVbs =0.0, Qddn_dVds =0.0, Qddn_dVgs =0.0 ;
double Quot =0.0 ;
double Qdrat = 0.5 ;
double Qdrat_dVbs = 0.0 , Qdrat_dVds = 0.0, Qdrat_dVgs = 0.0 ;
double Qdrat_dVbse =0.0, Qdrat_dVdse =0.0, Qdrat_dVgse =0.0 ;
double Idd =0.0 ;
double Idd_dVbs =0.0, Idd_dVds =0.0, Idd_dVgs =0.0 ;
double Fdd =0.0 ;
double Fdd_dVbs =0.0, Fdd_dVds =0.0, Fdd_dVgs =0.0 ;
double Eeff =0.0 ;
double Eeff_dVbs =0.0, Eeff_dVds =0.0, Eeff_dVgs =0.0 ;
double Rns =0.0 ;
double Mu = 0.0 ;
double Mu_dVbs =0.0, Mu_dVds =0.0, Mu_dVgs =0.0 ;
double Muun =0.0, Muun_dVbs =0.0, Muun_dVds =0.0, Muun_dVgs =0.0 ;
double Ey = 0e0 ;
double Ey_dVbs =0.0, Ey_dVds =0.0, Ey_dVgs =0.0 ;
double Em =0.0 ;
double Em_dVbs =0.0, Em_dVds =0.0, Em_dVgs =0.0 ;
double Vmax =0.0 ;
double Eta =0.0 ;
double Eta_dVbs =0.0, Eta_dVds =0.0, Eta_dVgs =0.0 ;
double Eta1 =0.0, Eta1p12 =0.0, Eta1p32 =0.0, Eta1p52 =0.0 ;
double Zeta12 =0.0, Zeta32 =0.0, Zeta52 =0.0 ;
double F00 =0.0 ;
double F00_dVbs =0.0, F00_dVds =0.0, F00_dVgs =0.0 ;
double F10 =0.0 ;
double F10_dVbs =0.0, F10_dVds =0.0, F10_dVgs =0.0 ;
double F30 =0.0 ;
double F30_dVbs =0.0, F30_dVds =0.0, F30_dVgs =0.0 ;
double F11 =0.0 ;
double F11_dVbs =0.0, F11_dVds =0.0, F11_dVgs =0.0 ;
double Ps0_min =0.0 ;
double Ps0_min_dVbs =0.0, Ps0_min_dVds =0.0, Ps0_min_dVgs =0.0 ;
double Acn =0.0, Acd =0.0, Ac1 =0.0, Ac2 =0.0, Ac3 =0.0, Ac4 =0.0, Ac31 =0.0, Ac41 =0.0 ;
double Acn_dVbs =0.0, Acn_dVds =0.0, Acn_dVgs =0.0 ;
double Acd_dVbs =0.0, Acd_dVds =0.0, Acd_dVgs =0.0 ;
double Ac1_dVbs =0.0, Ac1_dVds =0.0, Ac1_dVgs =0.0 ;
double Ac2_dVbs =0.0, Ac2_dVds =0.0, Ac2_dVgs =0.0 ;
double Ac3_dVbs =0.0, Ac3_dVds =0.0, Ac3_dVgs =0.0 ;
double Ac4_dVbs =0.0, Ac4_dVds =0.0, Ac4_dVgs =0.0 ;
double Ac31_dVbs =0.0, Ac31_dVds =0.0, Ac31_dVgs =0.0 ;
/* PART-2 (Isub) */
double Isub =0.0 ;
double Isub_dVbs =0.0, Isub_dVds =0.0, Isub_dVgs =0.0 ;
double Isub_dVbse =0.0, Isub_dVdse =0.0, Isub_dVgse =0.0 ;
double Psislsat=0.0, Psisubsat =0.0 ;
double Psislsat_dVd=0.0, Psislsat_dVg=0.0, Psislsat_dVb =0.0 ;
double Psisubsat_dVd=0.0, Psisubsat_dVg=0.0, Psisubsat_dVb =0.0 ;
/* PART-3 (overlap) */
double cov_slp =0.0, cov_mag =0.0, covvg =0.0, covvg_dVgs =0.0 ;
double Lov =0.0 ;
double Qgos = 0.0, Qgos_dVbs = 0.0, Qgos_dVds = 0.0, Qgos_dVgs = 0.0 ;
double Qgos_dVbse =0.0, Qgos_dVdse =0.0, Qgos_dVgse =0.0 ;
double Qgod = 0.0, Qgod_dVbs = 0.0, Qgod_dVds = 0.0, Qgod_dVgs = 0.0 ;
double Qgod_dVbse =0.0, Qgod_dVdse =0.0, Qgod_dVgse =0.0 ;
int flg_overgiven =0 ;
double Qgbo =0.0, Qgbo_dVbs =0.0, Qgbo_dVds =0.0, Qgbo_dVgs =0.0 ;
double Qgbo_dVbse =0.0, Qgbo_dVdse =0.0, Qgbo_dVgse =0.0 ;
double Cggo = 0.0 , Cgdo = 0.0 , Cgso = 0.0 , Cgbo = 0.0 , Cgbo_loc=0.0 ;
/* fringing capacitance */
double Cf =0.0 ;
double Qfd =0.0, Qfs =0.0 ;
/* Cqy */
double Ec =0.0, Ec_dVbs =0.0, Ec_dVds =0.0, Ec_dVgs =0.0 ;
double Pslk =0.0, Pslk_dVbs =0.0, Pslk_dVds =0.0, Pslk_dVgs =0.0 ;
double Qy =0.0 ;
double Cqyd=0.0, Cqyg=0.0, Cqys=0.0, Cqyb =0.0 ;
double Qy_dVbs =0.0, Qy_dVds =0.0, Qy_dVgs=0.0 ;
double Qy_dVbse =0.0, Qy_dVdse=0.0, Qy_dVgse=0.0 ;
double Qys=0.0, Qys_dVbse =0.0, Qys_dVdse=0.0, Qys_dVgse=0.0 ;
/* PART-4 (junction diode) */
double Ibs =0.0, Ibd =0.0, Gbs =0.0, Gbd =0.0, Gbse =0.0, Gbde =0.0 ;
/* junction capacitance */
double Qbs =0.0, Qbd =0.0, Capbs =0.0, Capbd =0.0, Capbse =0.0, Capbde =0.0 ;
double czbd =0.0, czbdsw =0.0, czbdswg =0.0, czbs =0.0, czbssw =0.0, czbsswg =0.0 ;
double arg =0.0, sarg =0.0 ;
/* PART-5 (NQS) */
double tau=0.0, Qi_prev =0.0;
double tau_dVgs=0.0, tau_dVds=0.0, tau_dVbs =0.0 ;
double tau_dVgse=0.0, tau_dVdse=0.0, tau_dVbse =0.0 ;
double Qi_nqs =0.0 ;
double Qi_dVbs_nqs=0.0, Qi_dVds_nqs=0.0, Qi_dVgs_nqs =0.0 ;
double Qi_dVbse_nqs=0.0, Qi_dVdse_nqs=0.0, Qi_dVgse_nqs =0.0 ;
double taub=0.0, Qb_prev =0.0;
double taub_dVgs=0.0, taub_dVds=0.0, taub_dVbs =0.0 ;
double taub_dVgse=0.0, taub_dVdse=0.0, taub_dVbse =0.0 ;
double Qb_nqs =0.0 ;
double Qb_dVbs_nqs=0.0, Qb_dVds_nqs=0.0, Qb_dVgs_nqs =0.0 ;
double Qb_dVbse_nqs=0.0, Qb_dVdse_nqs=0.0, Qb_dVgse_nqs =0.0 ;
/* PART-6 (noise) */
/* 1/f */
double NFalp =0.0, NFtrp =0.0, Cit =0.0, Nflic =0.0 ;
double Qi_noi =0.0 , Qiu_noi =0.0 ;
/* thermal */
double Eyd=0.0, Mu_Ave=0.0, Nthrml=0.0, Mud_hoso =0.0 ;
/* induced gate noise ( Part 0/3 ) */
double kusai00 =0.0, kusaidd =0.0, kusaiL =0.0, kusai00L =0.0 ;
int flg_ign = 0 ;
double sqrtkusaiL =0.0, kusai_ig =0.0, gds0_ign =0.0, gds0_h2 =0.0, GAMMA =0.0, crl_f =0.0 ;
const double c_sqrt_15 = 3.872983346207417e0 ; /* sqrt(15) */
const double Cox_small = 1.0e-6 ;
const double c_16o135 = 1.185185185185185e-1 ; /* 16/135 */
double Nign0 =0.0, MuModA =0.0, MuModB =0.0, correct_w1 =0.0 ;
/* Bias iteration accounting Rs/Rd */
int lp_bs =0 ;
double Ids_last =0.0 ;
double vtol_iprv = 2.0e-1 ;
double vtol_pprv = 1.01e-1 ;
double Vbsc_dif =0.0, Vdsc_dif =0.0, Vgsc_dif =0.0, sum_vdif =0.0 ;
double Vbsc_dif2 =0.0, Vdsc_dif2 =0.0, Vgsc_dif2 =0.0, sum_vdif2 =0.0 ;
double Rs =0.0, Rd =0.0 ;
double Fbs =0.0, Fds =0.0, Fgs =0.0 ;
double DJ =0.0, DJI =0.0 ;
double JI11 =0.0, JI12 =0.0, JI13 =0.0, JI21 =0.0, JI22 =0.0, JI23 =0.0, JI31 =0.0, JI32 =0.0, JI33 =0.0 ;
double dVbs =0.0, dVds =0.0, dVgs =0.0 ;
double dV_sum =0.0 ;
/* temporary vars. */
double T0, T1, T2, T3, T4, T5, T6, T7, T8, T9 = 0.0, T10 = 0.0, T11 = 0.0, T12 ;
double TX =0.0, TX_dVbs =0.0, TX_dVds =0.0, TX_dVgs =0.0 ;
double TY =0.0, TY_dVbs =0.0, TY_dVds =0.0, TY_dVgs =0.0 ;
double T1_dVb =0.0, T1_dVd =0.0, T1_dVg =0.0 ;
double T2_dVb =0.0, T2_dVd =0.0, T2_dVg =0.0 ;
double T3_dVb =0.0, T3_dVd =0.0, T3_dVg =0.0 ;
double T4_dVb =0.0, T4_dVd =0.0, T4_dVg =0.0 ;
double T5_dVb =0.0, T5_dVd =0.0, T5_dVg =0.0 ;
double T6_dVb =0.0, T6_dVd =0.0, T6_dVg =0.0 ;
double T7_dVb =0.0, T7_dVd =0.0, T7_dVg =0.0 ;
double T8_dVb =0.0, T8_dVd =0.0, T8_dVg =0.0 ;
double T9_dVb =0.0, T9_dVd =0.0, T9_dVg =0.0 ;
double T10_dVb =0.0, T10_dVd =0.0, T10_dVg =0.0 ;
double T15, T16, T17 ;
int flg_zone = 0 ;
/* Vdseff */
double Vdseff =0.0, Vdsorg =0.0 ;
double Vdseff_dVbs =0.0, Vdseff_dVds =0.0, Vdseff_dVgs =0.0 ;
/* G/S and G/D Overlap Charges: Qovs/Qovd */
double Qovd = 0.0, Qovd_dVbse = 0.0, Qovd_dVdse = 0.0, Qovd_dVgse = 0.0 ;
double Qovd_dVbs = 0.0, Qovd_dVds = 0.0, Qovd_dVgs = 0.0 ;
double Qovs = 0.0, Qovs_dVbse = 0.0, Qovs_dVdse = 0.0, Qovs_dVgse = 0.0 ;
double Qovs_dVbs = 0.0, Qovs_dVds = 0.0, Qovs_dVgs = 0.0 ;
int lcover = 0, flg_ovloops = 0, flg_ovloopd = 0 ;
int flg_overs = 0, flg_overd = 0 ;
double VgpLD =0.0 ;
double QbdLD = 0.0 , QbdLD_dVbs = 0.0 , QbdLD_dVds = 0.0 , QbdLD_dVgs = 0.0 ;
double QidLD = 0.0 , QidLD_dVbs = 0.0 , QidLD_dVds = 0.0 , QidLD_dVgs = 0.0 ;
double QbsLD = 0.0 , QbsLD_dVbs = 0.0 , QbsLD_dVds = 0.0 , QbsLD_dVgs = 0.0 ;
double QisLD = 0.0 , QisLD_dVbs = 0.0 , QisLD_dVds = 0.0 , QisLD_dVgs = 0.0 ;
double QbdLD_dVbse = 0.0 , QbdLD_dVdse = 0.0 , QbdLD_dVgse = 0.0 ;
double QidLD_dVbse = 0.0 , QidLD_dVdse = 0.0 , QidLD_dVgse = 0.0 ;
double QbsLD_dVbse = 0.0 , QbsLD_dVdse = 0.0 , QbsLD_dVgse = 0.0 ;
double QisLD_dVbse = 0.0 , QisLD_dVdse = 0.0 , QisLD_dVgse = 0.0 ;
double QbuLD = 0.0 , QbuLD_dVbs = 0.0 , QbuLD_dVds = 0.0 , QbuLD_dVgs = 0.0 ;
double QsuLD = 0.0 , QsuLD_dVbs = 0.0 , QsuLD_dVds = 0.0 , QsuLD_dVgs = 0.0 ;
double QiuLD = 0.0 , QiuLD_dVbs = 0.0 , QiuLD_dVds = 0.0 , QiuLD_dVgs = 0.0 ;
double Ps0LD = 0.0 , Ps0LD_dVds = 0.0 ;
double QbuLD_dVxb = 0.0 , QbuLD_dVgb = 0.0 ;
double QsuLD_dVxb = 0.0 , QsuLD_dVgb = 0.0 ;
int flg_ovzone = 0 ;
/* Vgsz for SCE and PGD */
double Vbsz2 =0.0, Vbsz2_dVbs =0.0, Vbsz2_dVds =0.0, Vbsz2_dVgs =0.0 ;
/* Multiplication factor of a MOSFET instance */
double M = 1.0 ;
/* Mode flag ( = 0 | 1 ) */
double ModeNML =0.0, ModeRVS =0.0 ;
/* For Gate Leak Current Partitioning */
double GLPART1 ;
double GLPART1_dVgs=0.0, GLPART1_dVds=0.0, GLPART1_dVbs =0.0;
double GLPART1_dVgse=0.0, GLPART1_dVdse=0.0, GLPART1_dVbse =0.0;
/* IBPC */
double IdsIBPC = 0.0 ;
double IdsIBPC_dVbs = 0.0 , IdsIBPC_dVds = 0.0 , IdsIBPC_dVgs = 0.0 ;
double IdsIBPC_dVbse = 0.0 , IdsIBPC_dVdse = 0.0 , IdsIBPC_dVgse = 0.0 ;
/* Overlap Charge: Qover */
double Vbsgmt =0.0, Vdsgmt =0.0, Vgsgmt =0.0, Vdbgmt =0.0, Vgbgmt =0.0, Vsbgmt =0.0, Vxbgmt =0.0 ;
double Vxbgmtcl = 0.0, Vxbgmtcl_dVxbgmt = 0.0 ;
double Pb2over =0.0 ;
/* Qover Iterative and Analytical Model */
const double large_arg = 80 ;
int lp_ld =0 ;
double T1_dVxb=0.0, T1_dVgb=0.0, T5_dVxb=0.0, T5_dVgb =0.0 ;
double Vgb_fb_LD=0.0, VgpLD_dVgb =0.0 ;
double VgpLD_shift=0.0, VgpLD_shift_dVxb=0.0, VgpLD_shift_dVgb =0.0 ;
double TX_dVxb=0.0, TX_dVgb=0.0, TY_dVxb=0.0, TY_dVgb =0.0 ;
double Ac1_dVxb=0.0, Ac1_dVgb=0.0, Ac2_dVxb=0.0, Ac2_dVgb =0.0 ;
double Ac3_dVxb=0.0, Ac3_dVgb=0.0, Ac31_dVxb=0.0, Ac31_dVgb =0.0;
double Acd_dVxb=0.0, Acd_dVgb=0.0, Acn_dVxb=0.0, Acn_dVgb =0.0;
double Ta = 9.3868e-3, Tb = -0.1047839 ;
double Tc=0.0, Tp =0.0 ;
double Td=0.0, Td_dVxb=0.0, Td_dVgb =0.0 ;
double Tq=0.0, Tq_dVxb=0.0, Tq_dVgb =0.0 ;
double Tu=0.0, Tu_dVxb=0.0, Tu_dVgb =0.0 ;
double Tv=0.0, Tv_dVxb=0.0, Tv_dVgb =0.0 ;
double exp_bVbs_dVxb=0.0, exp_bPs0 =0.0 ;
double cnst1over =0.0;
double gamma=0.0, gamma_dVxb =0.0;
double Chi_dVxb=0.0, Chi_dVgb =0.0 ;
double Chi_A=0.0, Chi_A_dVxb=0.0, Chi_A_dVgb =0.0 ;
double Chi_B=0.0, Chi_B_dVxb=0.0, Chi_B_dVgb =0.0 ;
double Chi_1=0.0, Chi_1_dVxb=0.0, Chi_1_dVgb =0.0 ;
double psi_B=0.0, arg_B =0.0 ;
double psi=0.0, psi_dVgb=0.0, psi_dVxb =0.0 ;
double Ps0_iniA_dVxb=0.0, Ps0_iniA_dVgb =0.0 ;
double Ps0_iniB_dVxb=0.0, Ps0_iniB_dVgb =0.0 ;
double Psa_dVxb=0.0, Psa_dVgb=0.0, Ps0LD_dVxb=0.0, Ps0LD_dVgb =0.0 ;
double fs02_dVxb=0.0, fs02_dVgb =0.0 ;
/* SCE LOOP */
double A =0.0, A_dVgs=0.0, A_dVds=0.0, A_dVbs =0.0 ;
int NNN =0 ;
double PS0_SCE=0 , PS0_SCE_dVgs = 0 , PS0_SCE_dVds = 0 , PS0_SCE_dVbs = 0 ;
double PS0Z_SCE=0 , PS0Z_SCE_dVgs = 0 , PS0Z_SCE_dVds = 0 , PS0Z_SCE_dVbs = 0 ;
/* double arg0 = 0.01 , arg1 = 0.04 ; */
double arg0 = 0.01 ;
double arg2 = here->HSM2_2qnsub_esi * 1.0e-4 ;
int MAX_LOOP_SCE =0 ;
int codqb = 0 ;
int corecip = model->HSM2_corecip ;
int START_OF_SCE_LOOP = 1 , end_of_part_1 = 0 ;
/* modify Qy in accumulation region */
double Aclm_eff=0.0, Aclm_eff_dVds=0.0, Aclm_eff_dVgs=0.0, Aclm_eff_dVbs =0.0 ;
double Idd1 =0.0, Idd1_dVbs =0.0, Idd1_dVgs =0.0, Idd1_dVds =0.0 ;
double tcjbs=0.0, tcjbssw=0.0, tcjbsswg=0.0,
tcjbd=0.0, tcjbdsw=0.0, tcjbdswg=0.0 ;
double TTEMP =0.0 ;
double PS0_SCE_tol = 4.0e-7 ;
double PS0_SCE_deriv_tol = 1.0e-8 ;
double Ps0_ini_dVds =0.0, Ps0_ini_dVgs =0.0, Ps0_ini_dVbs =0.0 ;
double Ps0_iniA_dVds =0.0, Ps0_iniA_dVgs =0.0, Ps0_iniA_dVbs =0.0 ;
double Ps0_iniB_dVds =0.0, Ps0_iniB_dVgs =0.0, Ps0_iniB_dVbs =0.0 ;
double A_dPS0Z = 0.0, dqb_dPS0Z = 0.0, dVth_dPS0Z = 0.0, dVth0_dPS0Z = 0.0,
dVthLP_dPS0Z = 0.0, dVthSC_dPS0Z = 0.0, Qbmm_dPS0Z = 0.0,
Vgp_dPS0Z = 0.0, Vgpz_dPS0Z = 0.0, Vthp_dPS0Z = 0.0,
Vth0_dPS0Z = 0.0 ;
double T1_dPS0Z=0.0, T3_dPS0Z=0.0, T4_dPS0Z=0.0, T5_dPS0Z=0.0,
T6_dPS0Z=0.0, T7_dPS0Z=0.0, T8_dPS0Z=0.0, T9_dPS0Z=0.0,
T10_dPS0Z=0.0, TX_dPS0Z =0.0 ;
double Ac1_dPS0Z=0.0, Ac2_dPS0Z=0.0, Ac3_dPS0Z=0.0, Ac31_dPS0Z=0.0,
Acd_dPS0Z=0.0, Acn_dPS0Z=0.0, Chi_dPS0Z=0.0, Psa_dPS0Z =0.0 ;
double Fs0_dPS0Z=0.0, Fsl_dPS0Z=0.0, Ps0_dPS0Z=0.0, Psl_dPS0Z=0.0,
Pds_dPS0Z=0.0, Pzadd_dPS0Z=0.0, Ps0z_dPS0Z =0.0 ;
double G=0.0, delta_PS0Z_SCE=0.0, delta_PS0Z_SCE_dVds=0.0,
delta_PS0Z_SCE_dVgs=0.0, delta_PS0Z_SCE_dVbs =0.0 ;
double Vgs_min =0.0 ;
/*================ Start of executable code.=================*/
if (here->HSM2_mode == HiSIM_NORMAL_MODE) {
ModeNML = 1.0 ;
ModeRVS = 0.0 ;
} else {
ModeNML = 0.0 ;
ModeRVS = 1.0 ;
}
T1 = vbs + vds + vgs + vbd_jct + vbs_jct ;
if ( ! finite (T1) ) {
fprintf (stderr ,
"*** warning(HiSIM): Unacceptable Bias(es).\n" ) ;
fprintf (stderr , "----- bias information (HiSIM)\n" ) ;
fprintf (stderr , "name: %s\n" , here->HSM2name ) ;
fprintf (stderr , "states: %d\n" , here->HSM2states ) ;
fprintf (stderr , "vds= %12.5e vgs=%12.5e vbs=%12.5e\n"
, vds , vgs , vbs ) ;
fprintf (stderr , "vbs_jct= %12.5e vbd_jct= %12.5e\n"
, vbs_jct , vbd_jct ) ;
fprintf (stderr , "vd= %12.5e vg= %12.5e vb= %12.5e vs= %12.5e\n"
, *( ckt->CKTrhsOld + here->HSM2dNodePrime )
, *( ckt->CKTrhsOld + here->HSM2gNodePrime )
, *( ckt->CKTrhsOld + here->HSM2bNodePrime )
, *( ckt->CKTrhsOld + here->HSM2sNodePrime ) ) ;
if ( here->HSM2_called >= 1 ) {
fprintf (stderr , "vdsc_prv= %12.5e vgsc_prv=%12.5e vbsc_prv=%12.5e\n"
, here->HSM2_vdsc_prv , here->HSM2_vgsc_prv
, here->HSM2_vbsc_prv ) ;
}
fprintf (stderr , "----- bias information (end)\n" ) ;
return ( HiSIM_ERROR ) ;
}
flg_info = model->HSM2_info ;
flg_nqs = model->HSM2_conqs ;
/*-----------------------------------------------------------*
* Start of the routine. (label)
*-----------------*/
/*start_of_routine:*/
TTEMP = ckt->CKTtemp ;
if ( here->HSM2_dtemp_Given ) { TTEMP = TTEMP + here->HSM2_dtemp ; }
beta = here->HSM2_beta ;
/* Inverse of the thermal voltage */
beta_inv = here->HSM2_beta_inv ;
beta2 = here->HSM2_beta2 ;
/* Bandgap */
Egp12 = here->HSM2_egp12 ;
Egp32 = here->HSM2_egp32 ;
/* Metallurgical channel geometry */
Leff = here->HSM2_leff ;
Weff = here->HSM2_weff ;
/* Flat band voltage */
Vfb = pParam->HSM2_vfbc ;
/* Surface impurity profile */
q_Nsub = here->HSM2_qnsub ;
/* Velocity Temperature Dependence */
Vmax = here->HSM2_vmax ;
/* 2 phi_B */
Pb2 = here->HSM2_pb2 ;
Pb20 = here->HSM2_pb20 ;
Pb2c = here->HSM2_pb2c ;
/* Coefficient of the F function for bulk charge */
cnst0 = here->HSM2_cnst0 ;
/* cnst1: n_{p0} / p_{p0} */
cnst1 = here->HSM2_cnst1 ;
/* c_eox: Permitivity in ox */
c_eox = here->HSM2_cecox ;
/* Tox and Cox without QME */
Tox0 = model->HSM2_tox ;
Cox0 = c_eox / Tox0 ;
Cox0_inv = 1.0 / Cox0 ;
/* for calculation of Ps0_min */
Vgs_min = model->HSM2_type * model->HSM2_Vgsmin ;
/*-----------------------------------------------------------*
* Exchange bias conditions according to MOS type.
* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0
* are assumed.)
*-----------------*/
Vbse = vbs ;
Vdse = vds ;
Vgse = vgs ;
/*---------------------------------------------------*
* Clamp too large biases.
* -note: Quantities are extrapolated in PART-5.
*-----------------*/
if ( Pb2 - model->HSM2_vzadd0 < Vbs_max ) {
Vbs_max = Pb2 - model->HSM2_vzadd0 ;
}
if ( Pb20 - model->HSM2_vzadd0 < Vbs_max ) {
Vbs_max = Pb20 - model->HSM2_vzadd0 ;
}
if ( Pb2c - model->HSM2_vzadd0 < Vbs_max ) {
Vbs_max = Pb2c - model->HSM2_vzadd0 ;
}
if ( Vbs_bnd > Vbs_max * 0.5 ) {
Vbs_bnd = 0.5 * Vbs_max ;
}
if ( Vbse > Vbs_bnd ) {
flg_vbsc = 1 ;
T1 = Vbse - Vbs_bnd ;
T2 = Vbs_max - Vbs_bnd ;
Fn_SUPoly4m( TY , T1 , T2 , Vbsc_dVbse , T0 ) ;
Vbsc = Vbs_bnd + TY ;
T3 = 1 / T2 ;
/* x/xmax */
T4 = T1 * T3 ;
T4_dVb = T3 ;
T5 = T4 * T4;
T5_dVb = 2 * T4_dVb * T4 ;
T15 = 2 * T4_dVb * T4_dVb ; /* T15 = T5_dVb_dVb */
T6 = T4 * T5 ;
T6_dVb = T4_dVb * T5 + T4 * T5_dVb ;
T16 = T4_dVb * T5_dVb + T4_dVb * T5_dVb + T4 * T15 ; /* T16 = T6_dVb_dVb */
/* T7 = Z T7_dVb = dZ_dVb T17 = dZ_dVb_dVb */
T7 = 1 + T4 + T5 + T6 + T5 * T5 ;
T7_dVb = T4_dVb + T5_dVb + T6_dVb + 2 * T5_dVb * T5 ;
T17 = T15 + T16 + 2 * T15 * T5 + 2 * T5_dVb * T5_dVb ;
T8 = T7 * T7 ;
T8_dVb = 2 * T7_dVb * T7 ;
T9 = 1 / T8 ;
T9_dVb = - T8_dVb * T9 * T9 ;
Vbsc_dVbse = T2 * T7_dVb * T9 ;
Vbsc_dVbse_dVbs = T2 * ( T17 * T9 + T7_dVb * T9_dVb ) ;
} else if ( Vbse < Vbs_min ) {
flg_vbsc = -1 ;
Vbsc = Vbs_min ;
Vbsc_dVbse_dVbs = 0.0 ;
} else {
flg_vbsc = 0 ;
Vbsc = Vbse ;
Vbsc_dVbse = 1.0 ;
Vbsc_dVbse_dVbs = 0.0 ;
}
Vdsc = Vdse ;
Vgsc = Vgse ;
if (here->HSM2_rs > 0.0 || here->HSM2_rd > 0.0) {
if ( model->HSM2_corsrd == 1 ) flg_rsrd = 1 ;
if ( model->HSM2_corsrd == 2 ) flg_rsrd = 2 ;
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-1: Basic device characteristics.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
* Prepare for potential initial guesses using previous values
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
flg_pprv = 0 ;
if ( here->HSM2_called >= 1 ) {
Vbsc_dif = Vbsc - here->HSM2_vbsc_prv ;
Vdsc_dif = Vdsc - here->HSM2_vdsc_prv ;
Vgsc_dif = Vgsc - here->HSM2_vgsc_prv ;
sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif )
+ fabs( Vgsc_dif ) ;
if ( model->HSM2_copprv >= 1 && sum_vdif <= vtol_pprv &&
here->HSM2_mode * here->HSM2_mode_prv > 0 ) { flg_pprv = 1 ;}
if ( here->HSM2_called >= 2 && flg_pprv == 1 ) {
Vbsc_dif2 = here->HSM2_vbsc_prv - here->HSM2_vbsc_prv2 ;
Vdsc_dif2 = here->HSM2_vdsc_prv - here->HSM2_vdsc_prv2 ;
Vgsc_dif2 = here->HSM2_vgsc_prv - here->HSM2_vgsc_prv2 ;
sum_vdif2 = fabs( Vbsc_dif2 ) + fabs( Vdsc_dif2 )
+ fabs( Vgsc_dif2 ) ;
if ( epsm10 < sum_vdif2 && sum_vdif2 <= vtol_pprv &&
here->HSM2_mode_prv * here->HSM2_mode_prv2 > 0 ) { flg_pprv = 2 ; }
}
} else {
Vbsc_dif = 0.0 ;
Vdsc_dif = 0.0 ;
Vgsc_dif = 0.0 ;
sum_vdif = 0.0 ;
Vbsc_dif2 = 0.0 ;
Vdsc_dif2 = 0.0 ;
Vgsc_dif2 = 0.0 ;
sum_vdif2 = 0.0 ;
flg_iprv = 0 ;
flg_pprv = 0 ;
}
dVbs = Vbsc_dif ;
dVds = Vdsc_dif ;
dVgs = Vgsc_dif ;
if ( flg_pprv >= 1 ) {
Ps0 = here->HSM2_ps0_prv ;
Ps0_dVbs = here->HSM2_ps0_dvbs_prv ;
Ps0_dVds = here->HSM2_ps0_dvds_prv ;
Ps0_dVgs = here->HSM2_ps0_dvgs_prv ;
Pds = here->HSM2_pds_prv ;
Pds_dVbs = here->HSM2_pds_dvbs_prv ;
Pds_dVds = here->HSM2_pds_dvds_prv ;
Pds_dVgs = here->HSM2_pds_dvgs_prv ;
}
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
* Bias loop: iteration to solve the system of equations of
* the small circuit taking into account Rs and Rd.
* - Vxs are internal (or effective) biases.
* - Equations:
* Vbs = Vbsc - Rs * Ids
* Vds = Vdsc - ( Rs + Rd ) * Ids
* Vgs = Vgsc - Rs * Ids
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
if ( flg_rsrd == 1 ) {
if (here->HSM2_mode == HiSIM_NORMAL_MODE) {
Rs = here->HSM2_rs ;
Rd = here->HSM2_rd ;
} else {
Rs = here->HSM2_rd ;
Rd = here->HSM2_rs ;
}
if ( here->HSM2_called >= 1 ) {
if ( model->HSM2_coiprv >= 1 &&
0.0 < sum_vdif && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;}
}
/*-----------------------------------------------------------*
* Initial guesses using the previous values.
*-----------------*/
if ( flg_iprv == 1 ) {
here->HSM2_ids_dvbs_prv = Fn_Max( 0.0 , here->HSM2_ids_dvbs_prv ) ;
here->HSM2_ids_dvds_prv = Fn_Max( 0.0 , here->HSM2_ids_dvds_prv ) ;
here->HSM2_ids_dvgs_prv = Fn_Max( 0.0 , here->HSM2_ids_dvgs_prv ) ;
dVbs = Vbsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * here->HSM2_ids_dvbs_prv ) ) ;
dVds = Vdsc_dif * ( 1.0 - 1.0 / ( 1.0 + ( Rs + Rd ) * here->HSM2_ids_dvds_prv ) ) ;
dVgs = Vgsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * here->HSM2_ids_dvgs_prv ) ) ;
Ids = here->HSM2_ids_prv
+ here->HSM2_ids_dvbs_prv * dVbs
+ here->HSM2_ids_dvds_prv * dVds
+ here->HSM2_ids_dvgs_prv * dVgs ;
T1 = ( Ids - here->HSM2_ids_prv ) ;
T2 = fabs( T1 ) ;
if ( Ids_maxvar * here->HSM2_ids_prv < T2 ) {
Ids = here->HSM2_ids_prv * ( 1.0 + Fn_Sgn( T1 ) * Ids_maxvar ) ;
}
if ( Ids < 0 ) Ids = 0.0 ;
} else {
Ids = 0.0 ;
if ( flg_pprv >= 1 ) {
dVbs = Vbsc_dif ;
dVds = Vdsc_dif ;
dVgs = Vgsc_dif ;
}
} /* end of flg_iprv if-blocks */
Vbs = Vbsc - Ids * Rs ;
Vds = Vdsc - Ids * ( Rs + Rd ) ;
if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; }
Vgs = Vgsc - Ids * Rs ;
} else {
lp_bs_max = 1 ;
Ids = 0.0 ;
Vbs = Vbsc ;
Vds = Vdsc ;
Vgs = Vgsc ;
} /* end of flg_rsrd if-blocks */
if( model->HSM2_codep == 1 ) {
/*---------------------------------------------------*
* CODEP=1 : Depletion mode MOSFET
*-----------------*/
/*-----------------------------------------------------------*
* Vxsz: Modified bias introduced to realize symmetry at Vds=0.
*-----------------*/
T1 = Vbsc_dVbse * Vds / 2 ;
Fn_SymAdd( Vzadd , T1 , model->HSM2_vzadd0 , T2 ) ;
Vzadd_dVbs = T2 * Vbsc_dVbse_dVbs * Vds / 2 ;
T2 *= Vbsc_dVbse / 2 ;
Vzadd_dVds = T2 ;
if ( Vzadd < ps_conv ) {
Vzadd = ps_conv ;
Vzadd_dVds = 0.0 ;
Vzadd_dVbs = 0.0 ;
}
Vbsz = Vbs + Vzadd ;
Vbsz_dVbs = 1.0 ;
Vbsz_dVds = Vzadd_dVds ;
Vdsz = Vds + 2.0 * Vzadd ;
Vdsz_dVbs = 0.0 ;
Vdsz_dVds = 1.0 + 2.0 * Vzadd_dVds ;
Vgsz = Vgs + Vzadd ;
Vgsz_dVgs = 1.0 ;
Vgsz_dVbs = 0.0 ;
Vgsz_dVds = Vzadd_dVds ;
/*---------------------------------------------------*
* Factor of modification for symmetry.
*-----------------*/
T1 = here->HSM2_qnsub_esi * Cox0_inv * Cox0_inv ;
T2 = Vgs - Vfb ;
T3 = 1 + 2.0 / T1 * ( T2 - beta_inv - Vbs ) ;
Fn_SZ( T4 , T3 , 1e-3 , T5 ) ;
TX = sqrt( T4 ) ;
Pslsat = T2 + T1 * ( 1.0 - TX ) ;
VdsatS = Pslsat - Pb2 ;
Fn_SL( VdsatS , VdsatS , 0.1 , 5e-2 , T6 ) ;
VdsatS_dVbs = ( TX ? (T6 * T5 / TX ) : 0.0 ) ;
VdsatS_dVds = 0.0 ;
VdsatS_dVgs = ( TX ? (T6 * ( 1.0 - T5 / TX )) : 0.0 ) ;
T1 = Vds / VdsatS ;
Fn_SUPoly4( TX , T1 , 1.0 , T0 ) ;
FMDVDS = TX * TX ;
T2 = 2 * TX * T0 ;
T3 = T2 / ( VdsatS * VdsatS ) ;
FMDVDS_dVbs = T3 * ( - Vds * VdsatS_dVbs ) ;
FMDVDS_dVds = T3 * ( 1.0 * VdsatS - Vds * VdsatS_dVds ) ;
FMDVDS_dVgs = T3 * ( - Vds * VdsatS_dVgs ) ;
/*-----------------------------------------------------------*
* Quantum effect
*-----------------*/
if ( model->HSM2_flg_qme == 0 ) {
flg_qme = 0 ;
} else {
flg_qme = 1 ;
}
T1 = here->HSM2_2qnsub_esi ;
T2 = sqrt( T1 * Pb20 ) ;
Vthq = Pb20 + Vfb + T2 * Cox0_inv ;
Vthq_dVb = 0.0 ;
Vthq_dVd = 0.0 ;
if ( flg_qme == 0 ) {
Tox = Tox0 ;
Tox_dVb = 0.0 ;
Tox_dVd = 0.0 ;
Tox_dVg = 0.0 ;
Cox = Cox0 ;
Cox_dVb = 0.0 ;
Cox_dVd = 0.0 ;
Cox_dVg = 0.0 ;
Cox_inv = Cox0_inv ;
Cox_inv_dVb = 0.0 ;
Cox_inv_dVd = 0.0 ;
Cox_inv_dVg = 0.0 ;
T0 = cnst0 * cnst0 * Cox_inv ;
cnstCoxi = T0 * Cox_inv ;
cnstCoxi_dVb = 0.0 ;
cnstCoxi_dVd = 0.0 ;
cnstCoxi_dVg = 0.0 ;
} else {
T5 = Vgs - Vbs - Vthq + model->HSM2_qme2 ;
T5_dVb = -1.0 - Vthq_dVb ;
T5_dVd = - Vthq_dVd ;
T5_dVg = 1.0 ;
Fn_SZ( T2 , T5 , qme_dlt, T3) ;
T2 = T2 + small ;
T2_dVb = T3 * T5_dVb ;
T2_dVd = T3 * T5_dVd ;
T2_dVg = T3 * T5_dVg ;
T3 = 1.0 / T2 ;
T7 = -1.0 / ( T2 * T2 ) ;
T3_dVb = T7 * T2_dVb ;
T3_dVd = T7 * T2_dVd ;
T3_dVg = T7 * T2_dVg ;
T4 = 2.0 * fabs(Vthq) ;
T6 = Vfb - Vthq + model->HSM2_qme2 ;
if(T6 > T4) { T4 = T6; }
Fn_SU( T2 , T3 , 1.0 / T4 , qme_dlt, T6 ) ;
T2_dVb = T6 * T3_dVb ;
T2_dVd = T6 * T3_dVd ;
T2_dVg = T6 * T3_dVg ;
dTox = model->HSM2_qme1 * T2 + model->HSM2_qme3 ;
T7 = model->HSM2_qme1 ;
dTox_dVb = T7 * T2_dVb ;
dTox_dVd = T7 * T2_dVd ;
dTox_dVg = T7 * T2_dVg ;
if ( dTox * 1.0e12 < Tox0 ) {
dTox = 0.0 ;
dTox_dVb = 0.0 ;
dTox_dVd = 0.0 ;
dTox_dVg = 0.0 ;
flg_qme = 0 ;
}
Tox = Tox0 + dTox ;
Tox_dVb = dTox_dVb ;
Tox_dVd = dTox_dVd ;
Tox_dVg = dTox_dVg ;
Cox = c_eox / Tox ;
T1 = - c_eox / ( Tox * Tox ) ;
Cox_dVb = T1 * Tox_dVb ;
Cox_dVd = T1 * Tox_dVd ;
Cox_dVg = T1 * Tox_dVg ;
Cox_inv = Tox / c_eox ;
T1 = 1.0 / c_eox ;
Cox_inv_dVb = T1 * Tox_dVb ;
Cox_inv_dVd = T1 * Tox_dVd ;
Cox_inv_dVg = T1 * Tox_dVg ;
T0 = cnst0 * cnst0 * Cox_inv ;
cnstCoxi = T0 * Cox_inv ;
T1 = 2.0 * T0 ;
cnstCoxi_dVb = T1 * Cox_inv_dVb ;
cnstCoxi_dVd = T1 * Cox_inv_dVd ;
cnstCoxi_dVg = T1 * Cox_inv_dVg ;
}
fac1 = cnst0 * Cox_inv ;
fac1_dVds = cnst0 * Cox_inv_dVd ;
fac1_dVgs = cnst0 * Cox_inv_dVg ;
fac1_dVbs = cnst0 * Cox_inv_dVb ;
fac1p2 = fac1 * fac1 ;
/* Ps0_min: approx. solution of Poisson equation at Vgs_min */
/* ( easy to improve, if necessary ) */
Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ;
Ps0_min_dVds = -2.0 * beta_inv * fac1_dVds / fac1 ;
Ps0_min_dVgs = -2.0 * beta_inv * fac1_dVgs / fac1 ;
Ps0_min_dVbs = -2.0 * beta_inv * fac1_dVbs / fac1 ;
/*---------------------------------------------------*
* Vbsz2 : Vbs for dVth
*-----------------*/
Vbsz2 = Vbsz ;
Vbsz2_dVbs = Vbsz_dVbs ;
Vbsz2_dVds = Vbsz_dVds ;
Vbsz2_dVgs = 0.0 ;
/*---------------------------------------------------*
* Vthp : Vth with pocket.
*-----------------*/
T1 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt (T1 * (Pb20 - Vbsz2)) ;
T2 = 0.5 * T1 / Qb0 ;
Qb0_dVb = T2 * (- Vbsz2_dVbs) ;
Qb0_dVd = T2 * (- Vbsz2_dVds) ;
Qb0_dVg = T2 * (- Vbsz2_dVgs) ;
Vthp = Pb20 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr;
Vthp_dVb = Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ;
Vthp_dVd = Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ;
Vthp_dVg = Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ;
Pb20b = Pb20 ;
Pb20b_dVb = 0.0 ;
Pb20b_dVd = 0.0 ;
Pb20b_dVg = 0.0 ;
T0 = 0.95 ;
T1 = T0 * Pb20b - Vbsz2 - 1.0e-3 ;
T1_dVb = T0 * Pb20b_dVb - Vbsz2_dVbs ;
T1_dVd = T0 * Pb20b_dVd - Vbsz2_dVds ;
T1_dVg = T0 * Pb20b_dVg - Vbsz2_dVgs ;
T2 = sqrt (T1 * T1 + 4.0 * T0 * Pb20b * 1.0e-3) ;
T3 = T0 * Pb20b - 0.5 * (T1 + T2) ;
T4 = 2.0 * T0 * 1.0e-3 ;
T5 = T1 / T2 ;
T6 = T4 / T2 ;
T3_dVb = T0 * Pb20b_dVb
- 0.5 * (T1_dVb + (T1_dVb * T5 + T6 * Pb20b_dVb ) ) ;
T3_dVd = T0 * Pb20b_dVd
- 0.5 * (T1_dVd + (T1_dVd * T5 + T6 * Pb20b_dVd ) ) ;
T3_dVg = T0 * Pb20b_dVg
- 0.5 * (T1_dVg + (T1_dVg * T5 + T6 * Pb20b_dVg ) ) ;
Pbsum = Pb20b - T3 ;
Pbsum_dVb = Pb20b_dVb - T3_dVb ;
Pbsum_dVd = Pb20b_dVd - T3_dVd ;
Pbsum_dVg = Pb20b_dVg - T3_dVg ;
if( model->HSM2_codep ) {
Pbsum = Pbsum + model->HSM2_depeta * Vdsz ;
Pbsum_dVb = Pbsum_dVb + model->HSM2_depeta * Vdsz_dVbs ;
Pbsum_dVd = Pbsum_dVd + model->HSM2_depeta * Vdsz_dVds ;
}
sqrt_Pbsum = sqrt( Pbsum ) ;
/*-------------------------------------------*
* dVthLP : Short-channel effect induced by pocket.
* - Vth0 : Vth without pocket.
*-----------------*/
if ( model->HSM2_lp != 0.0 ) {
T1 = here->HSM2_2qnsub_esi ;
T2 = model->HSM2_bs2 - Vbsz2 ;
T3 = T2 + small ;
T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ;
T5 = 0.5 * (T3 + T4) ;
T6 = 0.5 * (1.0 + T3 / T4) ;
T5_dVb = - Vbsz2_dVbs * T6 ;
T5_dVd = - Vbsz2_dVds * T6 ;
T5_dVg = - Vbsz2_dVgs * T6 ;
T7 = 1.0 / T5 ;
bs12 = model->HSM2_bs1 * T7 ;
T8 = - bs12 * T7 ;
bs12_dVb = T8 * T5_dVb ;
bs12_dVd = T8 * T5_dVd ;
bs12_dVg = T8 * T5_dVg ;
Fn_SU( T10 , Vbsz2 + bs12, 0.93 * Pb20, vth_dlt, T0) ;
Qbmm = sqrt (T1 * (Pb20 - T10 )) ;
T9 = T0 / Qbmm ;
Qbmm_dVb = 0.5 * T1 * - (Vbsz2_dVbs + bs12_dVb) * T9 ;
Qbmm_dVd = 0.5 * T1 * - (Vbsz2_dVds + bs12_dVd) * T9 ;
Qbmm_dVg = 0.5 * T1 * - (Vbsz2_dVgs + bs12_dVg) * T9 ;
dqb = (Qb0 - Qbmm) * Cox_inv ;
dqb_dVb = Vthp_dVb - Qbmm_dVb * Cox_inv - Qbmm * Cox_inv_dVb ;
dqb_dVd = Vthp_dVd - Qbmm_dVd * Cox_inv - Qbmm * Cox_inv_dVd ;
dqb_dVg = Vthp_dVg - Qbmm_dVg * Cox_inv - Qbmm * Cox_inv_dVg ;
T1 = 2.0 * C_QE * here->HSM2_nsubc * C_ESI ;
T2 = sqrt( T1 * ( Pb2c - Vbsz2 ) ) ;
Vth0 = Pb2c + Vfb + T2 * Cox_inv ;
T3 = 0.5 * T1 / T2 * Cox_inv ;
Vth0_dVb = T3 * ( - Vbsz2_dVbs ) + T2 * Cox_inv_dVb ;
Vth0_dVd = T3 * ( - Vbsz2_dVds ) + T2 * Cox_inv_dVd ;
Vth0_dVg = T3 * ( - Vbsz2_dVgs ) + T2 * Cox_inv_dVg ;
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdplp ;
T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = 0.5 * T5 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ;
T1 = Vthp - Vth0 ;
T1_dVb = Vthp_dVb - Vth0_dVb ;
T2 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * Pbsum / model->HSM2_lp ;
T2_dVb = pParam->HSM2_scp3 * Pbsum_dVb / model->HSM2_lp ;
T3 = T2 + pParam->HSM2_scp2 * Vdsz ;
T3_dVb = T2_dVb + pParam->HSM2_scp2 * Vdsz_dVbs ;
Vdx = model->HSM2_scp21 + Vdsz ;
Vdx_dVbs = Vdsz_dVbs ;
Vdx2 = Vdx * Vdx ;
Vdx2_dVbs = 2 * Vdx_dVbs * Vdx ;
dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc / Vdx2 ;
dVthLP_dVb = T1_dVb * dVth0 * T3 + T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb
+ dqb_dVb + here->HSM2_msc / Vdx2 /Vdx2 *Vdx2_dVbs;
T4 = T1 * dVth0 * pParam->HSM2_scp3 / model->HSM2_lp ;
dVthLP_dVd = (Vthp_dVd - Vth0_dVd) * dVth0 * T3 + T1 * dVth0_dVd * T3
+ T4 * Pbsum_dVd
+ T1 * dVth0 * pParam->HSM2_scp2 * Vdsz_dVds
+ dqb_dVd
+ 2.0e0 * here->HSM2_msc * Vdx * Vdsz_dVds / ( Vdx2 * Vdx2 ) ;
dVthLP_dVg = (Vthp_dVg - Vth0_dVg) * dVth0 * T3 + T1 * dVth0_dVg * T3
+ T4 * Pbsum_dVg + dqb_dVg ;
} else {
dVthLP = 0.0e0 ;
dVthLP_dVb = 0.0e0 ;
dVthLP_dVd = 0.0e0 ;
dVthLP_dVg = 0.0e0 ;
}
/*---------------------------------------------------*
* dVthSC : Short-channel effect induced by Vds.
*-----------------*/
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdpl ;
T3 = here->HSM2_lgate - model->HSM2_parl2 ;
T4 = 1.0e0 / ( T3 * T3 ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = T5 / 2.0 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ;
T1 = pParam->HSM2_sc3 / here->HSM2_lgate ;
T4 = pParam->HSM2_sc1 + T1 * Pbsum ;
T4_dVb = T1 * Pbsum_dVb ;
T4_dVd = T1 * Pbsum_dVd ;
T4_dVg = T1 * Pbsum_dVg ;
T5 = T4 + pParam->HSM2_sc2 * Vdsz * ( 1.0 + model->HSM2_sc4 * Pbsum );
T5_dVb = T4_dVb + pParam->HSM2_sc2 * Vdsz * model->HSM2_sc4 * Pbsum_dVb
+ pParam->HSM2_sc2 * Vdsz_dVbs * model->HSM2_sc4 * Pbsum;
T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds * ( 1.0 + model->HSM2_sc4 * Pbsum )
+ pParam->HSM2_sc2 * Vdsz * model->HSM2_sc4 * Pbsum_dVd;
T5_dVg = T4_dVg + pParam->HSM2_sc2 * Vdsz * model->HSM2_sc4 * Pbsum_dVg;
dVthSC = dVth0 * T5 ;
dVthSC_dVb = dVth0_dVb * T5 + dVth0 * T5_dVb ;
dVthSC_dVd = dVth0_dVd * T5 + dVth0 * T5_dVd ;
dVthSC_dVg = dVth0_dVg * T5 + dVth0 * T5_dVg ;
/*---------------------------------------------------*
* dVthW : narrow-channel effect.
*-----------------*/
T1 = 1.0 / Cox ;
T2 = T1 * T1 ;
T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ;
T4 = T3 * T3 ;
T5 = T1 - T3 ;
T6 = Qb0 * ( T2 - T4 ) ;
dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ;
dVthW_dVb = Qb0_dVb * T5 - Cox_dVb * T6 ;
dVthW_dVd = Qb0_dVd * T5 - Cox_dVd * T6 ;
dVthW_dVg = - Cox_dVg * T6 ;
/*---------------------------------------------------*
* dVth : Total variation.
* - Positive dVth means the decrease in Vth.
*-----------------*/
dVth = dVthSC + dVthLP + dVthW + here->HSM2_dVthsm ;
dVth_dVb = dVthSC_dVb + dVthLP_dVb + dVthW_dVb ;
dVth_dVd = dVthSC_dVd + dVthLP_dVd + dVthW_dVd ;
dVth_dVg = dVthSC_dVg + dVthLP_dVg + dVthW_dVg ;
/*---------------------------------------------------*
* Vth : Threshold voltagei for OP.
*-----------------*/
T2 = sqrt( here->HSM2_2qnsub_esi * (Pb2-Vbsz) ) ;
Vth = Pb2 + Vfb + T2 * Cox0_inv - dVth ;
/*-----------------------------------------------------------*
* Constants in the equation of Ps0 .
*-----------------*/
fac1 = cnst0 * Cox_inv ;
fac1_dVbs = cnst0 * Cox_inv_dVb ;
fac1_dVds = cnst0 * Cox_inv_dVd ;
fac1_dVgs = cnst0 * Cox_inv_dVg ;
fac1p2 = fac1 * fac1 ;
/*---------------------------------------------------*
* Poly-Depletion Effect
*-----------------*/
dPpg = 0.0 ;
dPpg_dVb = 0.0 ;
dPpg_dVd = 0.0 ;
dPpg_dVg = 0.0 ;
if ( here->HSM2_flg_pgd == 1 ) {
T7 = Vgsz ;
T7_dVb = Vgsz_dVbs ;
T7_dVd = Vgsz_dVds ;
T7_dVg = Vgsz_dVgs ;
T0 = here->HSM2_cnstpgd ;
T3 = T7 - model->HSM2_pgd2 ;
T3_dVb = T7_dVb ;
T3_dVd = T7_dVd ;
T3_dVg = T7_dVg ;
Fn_ExpLim( dPpg , T3 , T6 ) ;
dPpg_dVb = T6 * T3_dVb ;
dPpg_dVd = T6 * T3_dVd ;
dPpg_dVg = T6 * T3_dVg ;
Fn_SZ( dPpg , dPpg - 1.0 , pol_dlt , T6 ) ;
dPpg_dVb *= T6 ;
dPpg_dVd *= T6 ;
dPpg_dVg *= T6 ;
dPpg *= T0 ;
dPpg_dVb *= T0 ;
dPpg_dVd *= T0 ;
dPpg_dVg *= T0 ;
Fn_SU( dPpg , dPpg , pol_b , pol_dlt , T9 ) ;
dPpg_dVb *= T9 ;
dPpg_dVd *= T9 ;
dPpg_dVg *= T9 ;
}
/*---------------------------------------------------*
* Vgp : Effective gate bias with SCE & RSCE & flatband.
*-----------------*/
Vgp = Vgs - Vfb + dVth - dPpg ;
Vgp_dVbs = dVth_dVb - dPpg_dVb ;
Vgp_dVds = dVth_dVd - dPpg_dVd ;
Vgp_dVgs = 1.0e0 + dVth_dVg - dPpg_dVg ;
/*---------------------------------------------------*
* Vgs_fb : Actual flatband voltage taking account Vbs.
* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs .
*------------------*/
Vgs_fb = Vfb - dVth + dPpg + Vbs ;
#include "hsm2eval_dep.h"
} else {
/*---------------------------------------------------*
* Normal mode MOSFET
*------------------*/
/*-----------------------------------------------------------*
* start of the loop.
*-----------------*/
for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) {
Ids_last = Ids ;
/* Initialization of counters is needed for restart. */
lp_s0 = 0 ;
lp_sl = 0 ;
/*-----------------------------------------------------------*
* Vxsz: Modified bias introduced to realize symmetry at Vds=0.
*-----------------*/
T1 = Vbsc_dVbse * Vds / 2 ;
Fn_SymAdd( Vzadd , T1 , model->HSM2_vzadd0 , T2 ) ;
T2 *= Vbsc_dVbse / 2 ;
Vzadd_dVds = T2 ;
if ( Vzadd < ps_conv ) {
Vzadd = ps_conv ;
Vzadd_dVds = 0.0 ;
}
Vbsz = Vbs + Vzadd ;
Vbsz_dVbs = 1.0 ;
Vbsz_dVds = Vzadd_dVds ;
Vdsz = Vds + 2.0 * Vzadd ;
Vdsz_dVds = 1.0 + 2.0 * Vzadd_dVds ;
Vgsz = Vgs + Vzadd ;
Vgsz_dVgs = 1.0 ;
Vgsz_dVds = Vzadd_dVds ;
/*---------------------------------------------------*
* Factor of modification for symmetry.
*-----------------*/
T1 = here->HSM2_qnsub_esi * Cox0_inv * Cox0_inv ;
T2 = Vgs - Vfb ;
T3 = 1 + 2.0 / T1 * ( T2 - beta_inv - Vbs ) ;
Fn_SZ( T4 , T3 , 1e-3 , T5 ) ;
TX = sqrt( T4 ) ;
Pslsat = T2 + T1 * ( 1.0 - TX ) ;
VdsatS = Pslsat - Pb2 ;
Fn_SL( VdsatS , VdsatS , 0.1 , 5e-2 , T6 ) ;
VdsatS_dVbs = ( TX ? (T6 * T5 / TX ) : 0.0 ) ;
VdsatS_dVds = 0.0 ;
VdsatS_dVgs = ( TX ? (T6 * ( 1.0 - T5 / TX )) : 0.0 ) ;
T1 = Vds / VdsatS ;
Fn_SUPoly4( TX , T1 , 1.0 , T0 ) ;
FMDVDS = TX * TX ;
T2 = 2 * TX * T0 ;
T3 = T2 / ( VdsatS * VdsatS ) ;
FMDVDS_dVbs = T3 * ( - Vds * VdsatS_dVbs ) ;
FMDVDS_dVds = T3 * ( 1.0 * VdsatS - Vds * VdsatS_dVds ) ;
FMDVDS_dVgs = T3 * ( - Vds * VdsatS_dVgs ) ;
/*-----------------------------------------------------------*
* Quantum effect
*-----------------*/
if ( model->HSM2_flg_qme == 0 ) {
flg_qme = 0 ;
} else {
flg_qme = 1 ;
}
T1 = here->HSM2_2qnsub_esi ;
T2 = sqrt( T1 * Pb20 ) ;
Vthq = Pb20 + Vfb + T2 * Cox0_inv ;
Vthq_dVb = 0.0 ;
Vthq_dVd = 0.0 ;
if ( flg_qme == 0 ) {
Tox = Tox0 ;
Tox_dVb = 0.0 ;
Tox_dVd = 0.0 ;
Tox_dVg = 0.0 ;
Cox = Cox0 ;
Cox_dVb = 0.0 ;
Cox_dVd = 0.0 ;
Cox_dVg = 0.0 ;
Cox_inv = Cox0_inv ;
Cox_inv_dVb = 0.0 ;
Cox_inv_dVd = 0.0 ;
Cox_inv_dVg = 0.0 ;
T0 = cnst0 * cnst0 * Cox_inv ;
cnstCoxi = T0 * Cox_inv ;
cnstCoxi_dVb = 0.0 ;
cnstCoxi_dVd = 0.0 ;
cnstCoxi_dVg = 0.0 ;
} else {
T5 = Vgs - Vbs - Vthq + model->HSM2_qme2 ;
T5_dVb = -1.0 - Vthq_dVb ;
T5_dVd = - Vthq_dVd ;
T5_dVg = 1.0 ;
Fn_SZ( T2 , T5 , qme_dlt, T3) ;
T2 = T2 + small ;
T2_dVb = T3 * T5_dVb ;
T2_dVd = T3 * T5_dVd ;
T2_dVg = T3 * T5_dVg ;
T3 = 1.0 / T2 ;
T7 = -1.0 / ( T2 * T2 ) ;
T3_dVb = T7 * T2_dVb ;
T3_dVd = T7 * T2_dVd ;
T3_dVg = T7 * T2_dVg ;
T4 = 2.0 * fabs(Vthq) ;
T6 = Vfb - Vthq + model->HSM2_qme2 ;
if(T6 > T4) { T4 = T6; }
Fn_SU( T2 , T3 , 1.0 / T4 , qme_dlt, T6 ) ;
T2_dVb = T6 * T3_dVb ;
T2_dVd = T6 * T3_dVd ;
T2_dVg = T6 * T3_dVg ;
dTox = model->HSM2_qme1 * T2 + model->HSM2_qme3 ;
T7 = model->HSM2_qme1 ;
dTox_dVb = T7 * T2_dVb ;
dTox_dVd = T7 * T2_dVd ;
dTox_dVg = T7 * T2_dVg ;
if ( dTox * 1.0e12 < Tox0 ) {
dTox = 0.0 ;
dTox_dVb = 0.0 ;
dTox_dVd = 0.0 ;
dTox_dVg = 0.0 ;
flg_qme = 0 ;
}
Tox = Tox0 + dTox ;
Tox_dVb = dTox_dVb ;
Tox_dVd = dTox_dVd ;
Tox_dVg = dTox_dVg ;
Cox = c_eox / Tox ;
T1 = - c_eox / ( Tox * Tox ) ;
Cox_dVb = T1 * Tox_dVb ;
Cox_dVd = T1 * Tox_dVd ;
Cox_dVg = T1 * Tox_dVg ;
Cox_inv = Tox / c_eox ;
T1 = 1.0 / c_eox ;
Cox_inv_dVb = T1 * Tox_dVb ;
Cox_inv_dVd = T1 * Tox_dVd ;
Cox_inv_dVg = T1 * Tox_dVg ;
T0 = cnst0 * cnst0 * Cox_inv ;
cnstCoxi = T0 * Cox_inv ;
T1 = 2.0 * T0 ;
cnstCoxi_dVb = T1 * Cox_inv_dVb ;
cnstCoxi_dVd = T1 * Cox_inv_dVd ;
cnstCoxi_dVg = T1 * Cox_inv_dVg ;
}
fac1 = cnst0 * Cox_inv ;
fac1_dVds = cnst0 * Cox_inv_dVd ;
fac1_dVgs = cnst0 * Cox_inv_dVg ;
fac1_dVbs = cnst0 * Cox_inv_dVb ;
fac1p2 = fac1 * fac1 ;
/* Ps0_min: approx. solution of Poisson equation at Vgs_min */
/* ( easy to improve, if necessary ) */
Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ;
Ps0_min_dVds = -2.0 * beta_inv * fac1_dVds / fac1 ;
Ps0_min_dVgs = -2.0 * beta_inv * fac1_dVgs / fac1 ;
Ps0_min_dVbs = -2.0 * beta_inv * fac1_dVbs / fac1 ;
/*---------------------------------------------------*
* Vbsz2 : Vbs for dVth
*-----------------*/
Vbsz2 = Vbsz ;
Vbsz2_dVbs = Vbsz_dVbs ;
Vbsz2_dVds = Vbsz_dVds ;
Vbsz2_dVgs = 0.0 ;
if ( corecip ) {
/* ************************** */
/* Initial value for PS0Z_SCE */
/* ************************** */
T1 = dP_max + dP_max ;
if ( flg_pprv >= 1 ) {
/* -------------------------- *
* Extrapolate previous value *
* -------------------------- */
T1 = here->HSM2_PS0Z_SCE_dvbs_prv * dVbs
+ here->HSM2_PS0Z_SCE_dvds_prv * dVds
+ here->HSM2_PS0Z_SCE_dvgs_prv * dVgs ;
if ( fabs(T1) <= dP_max ) {
Ps0_ini = here->HSM2_PS0Z_SCE_prv + T1 ; /* take extrapolated value */
Ps0_ini_dVds = here->HSM2_PS0Z_SCE_dvds_prv ;
Ps0_ini_dVgs = here->HSM2_PS0Z_SCE_dvgs_prv ;
Ps0_ini_dVbs = here->HSM2_PS0Z_SCE_dvbs_prv ;
}
} /* end of (flg_pprv >=1) if-block */
if ( fabs(T1) > dP_max) {
/* ------------------------------------- *
* Analytical initial value for PS0Z_SCE *
* ------------------------------------- */
T1 = here->HSM2_2qnsub_esi ;
T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ;
Vthq = Pb20 + Vfb + T2 * Cox0_inv ;
Vth = Vthq ;
TX = 4.0e0 * ( beta * ( Vgs - Vbs ) - 1.0e0 ) / ( fac1p2 * beta2 ) ;
TX_dVds = - 2.0 * TX / fac1 * fac1_dVds ;
TX_dVgs = - 2.0 * TX / fac1 * fac1_dVgs + 4.0 * beta / ( fac1p2 * beta2 ) ;
TX_dVbs = - 2.0 * TX / fac1 * fac1_dVbs - 4.0 * beta / ( fac1p2 * beta2 ) ;
TX += 1.0 ;
if ( TX > epsm10 ) {
T3 = sqrt( TX ) ;
T3_dVd = 0.5 * TX_dVds / T3 ;
T3_dVg = 0.5 * TX_dVgs / T3 ;
T3_dVb = 0.5 * TX_dVbs / T3 ;
} else {
T3 = sqrt( epsm10 ) ;
T3_dVd = T3_dVg = T3_dVb = 0.0 ;
}
Ps0_iniA = Vgs + fac1p2 * beta * 0.5 * ( 1.0e0 - T3 ) ;
Ps0_iniA_dVds = fac1 * beta * ( 1.0 - T3 ) * fac1_dVds - fac1p2 * beta * 0.5 * T3_dVd ;
Ps0_iniA_dVgs = 1.0 + fac1 * beta * ( 1.0 - T3 ) * fac1_dVgs - fac1p2 * beta * 0.5 * T3_dVg ;
Ps0_iniA_dVbs = fac1 * beta * ( 1.0 - T3 ) * fac1_dVbs - fac1p2 * beta * 0.5 * T3_dVb ;
Chi = beta * ( Ps0_iniA - Vbs ) ;
if ( Chi < znbd3 ) {
/*-----------------------------------*
* zone-D1/D2
* - Ps0_ini is the analytical solution of Qs=Qb0 with
* Qb0 being approximated to 3-degree polynomial.
*-----------------*/
TY = beta * ( Vgs - Vbs ) ;
TY_dVds = 0.0 ;
TY_dVgs = beta ;
TY_dVbs = - beta ;
T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ;
T1_dVd = - T1 / fac1 * fac1_dVds ;
T1_dVg = - T1 / fac1 * fac1_dVgs ;
T1_dVb = - T1 / fac1 * fac1_dVbs ;
T2 = 81.0 + 3.0 * T1 ;
T2_dVd = 3.0 * T1_dVd ;
T2_dVg = 3.0 * T1_dVg ;
T2_dVb = 3.0 * T1_dVb ;
T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ;
T3_dVd = ( - 81.0 + 27.0 * TY ) * T1_dVd + 27.0 * T1 * TY_dVds ;
T3_dVg = ( - 81.0 + 27.0 * TY ) * T1_dVg + 27.0 * T1 * TY_dVgs ;
T3_dVb = ( - 81.0 + 27.0 * TY ) * T1_dVb + 27.0 * T1 * TY_dVbs ;
T4 = T3 ;
T4_dVd = T3_dVd ;
T4_dVg = T3_dVg ;
T4_dVb = T3_dVb ;
T6 = sqrt( 4 * T2 * T2 * T2 + T4 * T4 ) ;
T6_dVd = ( 6.0 * T2 * T2 * T2_dVd + T4 * T4_dVd ) / T6 ;
T6_dVg = ( 6.0 * T2 * T2 * T2_dVg + T4 * T4_dVg ) / T6 ;
T6_dVb = ( 6.0 * T2 * T2 * T2_dVb + T4 * T4_dVb ) / T6 ;
T5 = Fn_Pow( T3 + T6 , C_1o3 ) ;
T5_dVd = ( T3_dVd + T6_dVd ) / ( 3.0 * T5 * T5 ) ;
T5_dVg = ( T3_dVg + T6_dVg ) / ( 3.0 * T5 * T5 ) ;
T5_dVb = ( T3_dVb + T6_dVb ) / ( 3.0 * T5 * T5 ) ;
TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 )
+ 1 / ( 3.0 * C_2p_1o3 ) * T5 ;
TX_dVds = - C_2p_1o3 / (3.0 * T5) * T2_dVd + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVd ;
TX_dVgs = - C_2p_1o3 / (3.0 * T5) * T2_dVg + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVg ;
TX_dVbs = - C_2p_1o3 / (3.0 * T5) * T2_dVb + ( C_2p_1o3 * T2 / (3.0 * T5 * T5) + 1.0 / (3.0 * C_2p_1o3) ) * T5_dVb ;
Ps0_iniA = TX * beta_inv + Vbs ;
Ps0_iniA_dVds = TX_dVds * beta_inv ;
Ps0_iniA_dVgs = TX_dVgs * beta_inv ;
Ps0_iniA_dVbs = TX_dVbs * beta_inv + 1.0 ;
Ps0_ini = Ps0_iniA ;
Ps0_ini_dVds = Ps0_iniA_dVds ;
Ps0_ini_dVgs = Ps0_iniA_dVgs ;
Ps0_ini_dVbs = Ps0_iniA_dVbs ;
} else if ( Vgs <= Vth ) {
/*-----------------------------------*
* Weak inversion zone.
*-----------------*/
Ps0_ini = Ps0_iniA ;
Ps0_ini_dVds = Ps0_iniA_dVds ;
Ps0_ini_dVgs = Ps0_iniA_dVgs ;
Ps0_ini_dVbs = Ps0_iniA_dVbs ;
} else {
/*-----------------------------------*
* Strong inversion zone.
* - Ps0_iniB : upper bound.
*-----------------*/
T1 = 1.0 / cnst1 / cnstCoxi ;
T1_dVd = - T1 / cnstCoxi * cnstCoxi_dVd ;
T1_dVg = - T1 / cnstCoxi * cnstCoxi_dVg ;
T1_dVb = - T1 / cnstCoxi * cnstCoxi_dVb ;
T0 = Vgs - Vfb ;
T2 = T1 * T0 * T0 ;
T2_dVd = T1_dVd * T0 * T0 ;
T2_dVg = T1_dVg * T0 * T0 + 2.0 * T1 * T0 ;
T2_dVb = T1_dVb * T0 * T0 ;
T3 = beta + 2.0 / T0 ;
T3_dVg = -2.0 / (T0 * T0) ;
Ps0_iniB = log( T2 + small ) / T3 ;
Ps0_iniB_dVds = T2_dVd / (T2 * T3) ;
Ps0_iniB_dVgs = T2_dVg / (T2 * T3) - T3_dVg * Ps0_iniB / T3 ;
Ps0_iniB_dVbs = T2_dVb / (T2 * T3) ;
Fn_SU2( Ps0_ini , Ps0_iniA, Ps0_iniB, c_ps0ini_2, T1,T2) ;
Ps0_ini_dVds = Ps0_iniA_dVds * T1 + Ps0_iniB_dVds * T2 ;
Ps0_ini_dVgs = Ps0_iniA_dVgs * T1 + Ps0_iniB_dVgs * T2 ;
Ps0_ini_dVbs = Ps0_iniA_dVbs * T1 + Ps0_iniB_dVbs * T2 ;
}
} /* end of initial value calulation */
/**************************/
/* initial value for SCE LOOP */
PS0_SCE = Ps0_ini ;
PS0_SCE_dVds = Ps0_ini_dVds ;
PS0_SCE_dVgs = Ps0_ini_dVgs ;
PS0_SCE_dVbs = Ps0_ini_dVbs ;
PS0Z_SCE = Ps0_ini ;
PS0Z_SCE_dVds = Ps0_ini_dVds ;
PS0Z_SCE_dVgs = Ps0_ini_dVgs ;
PS0Z_SCE_dVbs = Ps0_ini_dVbs ;
} /* end of corecip=1 case (initial value calculation) */
MAX_LOOP_SCE = 5 ;
NNN = 0 ;
/* ************************************************************************* */
// START_OF_SCE_LOOP : /* outer loop of multi level Newton framework */
START_OF_SCE_LOOP = 1 ; end_of_part_1 = 0 ;
while( START_OF_SCE_LOOP ) { /* Begin: 1st SCE LOOP */
while( START_OF_SCE_LOOP ) { /* Begin: 2nd SCE LOOP */
while( START_OF_SCE_LOOP ) { /* Begin: 3rd SCE LOOP */
START_OF_SCE_LOOP = 0 ;
/* ************************************************************************* */
/* for multi level Newton method we need the derivatives */
/* with respect to PS0Z_SCE */
/* naming convention: ..._dPS0Z means d.../dPS0Z_SCE */
if ( flg_qme == 1 ) {
/*---------------------------------------------------*
* Vthp : Vth with pocket.
*-----------------*/
if( corecip ){
T1 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt ( T1 ) ;
Qb0_dVb = 0.0 ;
Qb0_dVd = 0.0 ;
Qb0_dVg = 0.0 ;
Vthp = PS0Z_SCE + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr ;
Vthp_dVb = PS0Z_SCE_dVbs + Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ;
Vthp_dVd = PS0Z_SCE_dVds + Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ;
Vthp_dVg = PS0Z_SCE_dVgs + Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ;
Vthp_dPS0Z = 1.0 ;
}else{ /* original */
T1 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt (T1 * (Pb20 - Vbsz2)) ;
T2 = 0.5 * T1 / Qb0 ;
Qb0_dVb = T2 * (- Vbsz2_dVbs) ;
Qb0_dVd = T2 * (- Vbsz2_dVds) ;
Qb0_dVg = T2 * (- Vbsz2_dVgs) ;
Vthp = Pb20 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr;
Vthp_dVb = Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ;
Vthp_dVd = Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ;
Vthp_dVg = Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ;
}
Pb20b = Pb20 ;
Pb20b_dVb = 0.0 ;
Pb20b_dVd = 0.0 ;
Pb20b_dVg = 0.0 ;
T0 = 0.95 ;
T1 = T0 * Pb20b - Vbsz2 - 1.0e-3 ;
T1_dVb = T0 * Pb20b_dVb - Vbsz2_dVbs ;
T1_dVd = T0 * Pb20b_dVd - Vbsz2_dVds ;
T1_dVg = T0 * Pb20b_dVg - Vbsz2_dVgs ;
T2 = sqrt (T1 * T1 + 4.0 * T0 * Pb20b * 1.0e-3) ;
T3 = T0 * Pb20b - 0.5 * (T1 + T2) ;
T4 = 2.0 * T0 * 1.0e-3 ;
T5 = T1 / T2 ;
T6 = T4 / T2 ;
T3_dVb = T0 * Pb20b_dVb
- 0.5 * (T1_dVb + (T1_dVb * T5 + T6 * Pb20b_dVb ) ) ;
T3_dVd = T0 * Pb20b_dVd
- 0.5 * (T1_dVd + (T1_dVd * T5 + T6 * Pb20b_dVd ) ) ;
T3_dVg = T0 * Pb20b_dVg
- 0.5 * (T1_dVg + (T1_dVg * T5 + T6 * Pb20b_dVg ) ) ;
Pbsum = Pb20b - T3 ;
Pbsum_dVb = Pb20b_dVb - T3_dVb ;
Pbsum_dVd = Pb20b_dVd - T3_dVd ;
Pbsum_dVg = Pb20b_dVg - T3_dVg ;
sqrt_Pbsum = sqrt( Pbsum ) ;
/*-------------------------------------------*
* dVthLP : Short-channel effect induced by pocket.
* - Vth0 : Vth without pocket.
*-----------------*/
if ( model->HSM2_lp != 0.0 ) {
if( corecip ){
T1 = here->HSM2_2qnsub_esi ;
T2 = model->HSM2_bs2 - Vbsz2 ;
T3 = T2 + small ;
T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ;
T5 = 0.5 * (T3 + T4) ;
T6 = 0.5 * (1.0 + T3 / T4) ;
T5_dVb = - Vbsz2_dVbs * T6 ;
T5_dVd = - Vbsz2_dVds * T6 ;
T5_dVg = - Vbsz2_dVgs * T6 ;
T7 = 1.0 / T5 ;
bs12 = model->HSM2_bs1 * T7 ;
T8 = - bs12 * T7 ;
bs12_dVb = T8 * T5_dVb ;
bs12_dVd = T8 * T5_dVd ;
bs12_dVg = T8 * T5_dVg ;
T1 = 0.93 * ( PS0Z_SCE + Ps0_min - Vbsz2 );
T1_dVb = 0.93 * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs );
T1_dVd = 0.93 * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds );
T1_dVg = 0.93 * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs );
T1_dPS0Z = 0.93 ;
T2 = bs12 ;
T2_dVb = bs12_dVb ;
T2_dVd = bs12_dVd ;
T2_dVg = bs12_dVg ;
Fn_SU2( T10 , T2 , T1 , vth_dlt, T0, T3 ) ;
T10_dVb = T2_dVb * T0 + T1_dVb * T3 ;
T10_dVd = T2_dVd * T0 + T1_dVd * T3 ;
T10_dVg = T2_dVg * T0 + T1_dVg * T3 ;
T10_dPS0Z = T1_dPS0Z * T3 ;
T4 = here->HSM2_2qnsub_esi * ( PS0Z_SCE + Ps0_min - Vbsz2 - T10 ) ;
T4_dVb = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs - T10_dVb ) ;
T4_dVd = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds - T10_dVd ) ;
T4_dVg = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs - T10_dVg ) ;
T4_dPS0Z = here->HSM2_2qnsub_esi * ( 1.0 - T10_dPS0Z ) ;
if (T4 > arg2){
Qbmm = sqrt ( T4 ) ;
Qbmm_dVb = 0.5 / Qbmm * T4_dVb ;
Qbmm_dVd = 0.5 / Qbmm * T4_dVd ;
Qbmm_dVg = 0.5 / Qbmm * T4_dVg ;
Qbmm_dPS0Z = 0.5 / Qbmm * T4_dPS0Z ;
} else {
Qbmm = sqrt(arg2) + 0.5 / sqrt(arg2) * ( T4 - arg2) ;
Qbmm_dVb = 0.5 / sqrt(arg2) * T4_dVb ;
Qbmm_dVd = 0.5 / sqrt(arg2) * T4_dVd ;
Qbmm_dVg = 0.5 / sqrt(arg2) * T4_dVg ;
Qbmm_dPS0Z = 0.5 / sqrt(arg2) * T4_dPS0Z ;
}
dqb = ( Qb0 - Qbmm ) * Cox_inv ;
dqb_dVb = ( Qb0_dVb - Qbmm_dVb ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVb ;
dqb_dVd = ( Qb0_dVd - Qbmm_dVd ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVd ;
dqb_dVg = ( Qb0_dVg - Qbmm_dVg ) * Cox_inv + ( Qb0 - Qbmm ) * Cox_inv_dVg ;
dqb_dPS0Z = - Qbmm_dPS0Z * Cox_inv ;
if( codqb == 0 ){
dqb = 0.0 ;
dqb_dVb = 0.0 ;
dqb_dVd = 0.0 ;
dqb_dVg = 0.0 ;
dqb_dPS0Z = 0.0 ;
}
T1 = 2.0 * C_QE * here->HSM2_nsubc * C_ESI ;
T2 = sqrt( T1 ) ;
T2_dVb = 0.0 ;
T2_dVd = 0.0 ;
T2_dVg = 0.0 ;
Vth0 = PS0Z_SCE + Vfb + T2 * Cox_inv ;
Vth0_dVb = PS0Z_SCE_dVbs + T2_dVb * Cox_inv + T2 * Cox_inv_dVb ;
Vth0_dVd = PS0Z_SCE_dVds + T2_dVd * Cox_inv + T2 * Cox_inv_dVd ;
Vth0_dVg = PS0Z_SCE_dVgs + T2_dVg * Cox_inv + T2 * Cox_inv_dVg ;
Vth0_dPS0Z = 1.0 ;
T1 = C_ESI * Cox_inv ;
T1_dVb = C_ESI * Cox_inv_dVb ;
T1_dVd = C_ESI * Cox_inv_dVd ;
T1_dVg = C_ESI * Cox_inv_dVg ;
T2 = here->HSM2_wdplp ;
T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ;
T3 = 2.0 * ( model->HSM2_vbi - Pb20 ) * T2 * T4 ;
T5 = T1 * T3 ;
T5_dVb = T1_dVb * T3 ;
T5_dVd = T1_dVd * T3 ;
T5_dVg = T1_dVg * T3 ;
T6 = PS0Z_SCE - Vbsz ;
T6_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs ;
T6_dVd = PS0Z_SCE_dVds - Vbsz_dVds ;
T6_dVg = PS0Z_SCE_dVgs ;
T6_dPS0Z = 1.0 ;
Fn_SZ( T6, T6, C_sce_dlt, T0 );
T6_dVb *= T0 ;
T6_dVd *= T0 ;
T6_dVg *= T0 ;
T6_dPS0Z *= T0 ;
dVth0 = T5 * sqrt( T6 ) ;
dVth0_dVb = T5 * 0.5 / sqrt( T6 ) * T6_dVb + T5_dVb * sqrt( T6 );
dVth0_dVd = T5 * 0.5 / sqrt( T6 ) * T6_dVd + T5_dVd * sqrt( T6 ) ;
dVth0_dVg = T5 * 0.5 / sqrt( T6 ) * T6_dVg + T5_dVg * sqrt( T6 ) ;
dVth0_dPS0Z = T5 * 0.5 / sqrt( T6 ) * T6_dPS0Z ;
T1 = Vthp - Vth0 ;
T1_dVb = Vthp_dVb - Vth0_dVb ;
T1_dVd = Vthp_dVd - Vth0_dVd ;
T1_dVg = Vthp_dVg - Vth0_dVg ;
T1_dPS0Z = Vthp_dPS0Z - Vth0_dPS0Z ;
T9 = PS0Z_SCE - Vbsz2 ;
T9_dVb = PS0Z_SCE_dVbs - Vbsz2_dVbs ;
T9_dVd = PS0Z_SCE_dVds - Vbsz2_dVds ;
T9_dVg = PS0Z_SCE_dVgs - Vbsz2_dVgs ;
T9_dPS0Z = 1.0 ;
T3 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * T9 / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz ;
T3_dVb = pParam->HSM2_scp3 * T9_dVb / model->HSM2_lp ;
T3_dVd = pParam->HSM2_scp3 * T9_dVd / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz_dVds ;
T3_dVg = pParam->HSM2_scp3 * T9_dVg / model->HSM2_lp ;
T3_dPS0Z = pParam->HSM2_scp3 * T9_dPS0Z / model->HSM2_lp ;
Vdx = model->HSM2_scp21 + Vdsz ;
Vdx2 = Vdx * Vdx + small ;
T4 = Vdx * Vdx + small ;
T4_dVb = 0.0 ;
T4_dVd = 2.0 * Vdx * Vdsz_dVds ;
T4_dVg = 0.0 ;
T5 = 1.0 / T4 ;
T5_dVb = - T4_dVb / T4 / T4 ;
T5_dVd = - T4_dVd / T4 / T4 ;
T5_dVg = - T4_dVg / T4 / T4 ;
dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc * T5 ;
dVthLP_dVb = T1_dVb * dVth0 * T3 + T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb + dqb_dVb - here->HSM2_msc * T5_dVb ;
dVthLP_dVd = T1_dVd * dVth0 * T3 + T1 * dVth0_dVd * T3 + T1 * dVth0 * T3_dVd + dqb_dVd - here->HSM2_msc * T5_dVd ;
dVthLP_dVg = T1_dVg * dVth0 * T3 + T1 * dVth0_dVg * T3 + T1 * dVth0 * T3_dVg + dqb_dVg - here->HSM2_msc * T5_dVg ;
dVthLP_dPS0Z = T1_dPS0Z * dVth0 * T3 + T1 * dVth0_dPS0Z * T3 + T1 * dVth0 * T3_dPS0Z + dqb_dPS0Z ;
}else{ /* original */
T1 = here->HSM2_2qnsub_esi ;
T2 = model->HSM2_bs2 - Vbsz2 ;
T3 = T2 + small ;
T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ;
T5 = 0.5 * (T3 + T4) ;
T6 = 0.5 * (1.0 + T3 / T4) ;
T5_dVb = - Vbsz2_dVbs * T6 ;
T5_dVd = - Vbsz2_dVds * T6 ;
T5_dVg = - Vbsz2_dVgs * T6 ;
T7 = 1.0 / T5 ;
bs12 = model->HSM2_bs1 * T7 ;
T8 = - bs12 * T7 ;
bs12_dVb = T8 * T5_dVb ;
bs12_dVd = T8 * T5_dVd ;
bs12_dVg = T8 * T5_dVg ;
Fn_SU( T10 , Vbsz2 + bs12, 0.93 * Pb20, vth_dlt, T0) ;
Qbmm = sqrt (T1 * (Pb20 - T10 )) ;
T9 = T0 / Qbmm ;
Qbmm_dVb = 0.5 * T1 * - (Vbsz2_dVbs + bs12_dVb) * T9 ;
Qbmm_dVd = 0.5 * T1 * - (Vbsz2_dVds + bs12_dVd) * T9 ;
Qbmm_dVg = 0.5 * T1 * - (Vbsz2_dVgs + bs12_dVg) * T9 ;
dqb = (Qb0 - Qbmm) * Cox_inv ;
dqb_dVb = Vthp_dVb - Qbmm_dVb * Cox_inv - Qbmm * Cox_inv_dVb ;
dqb_dVd = Vthp_dVd - Qbmm_dVd * Cox_inv - Qbmm * Cox_inv_dVd ;
dqb_dVg = Vthp_dVg - Qbmm_dVg * Cox_inv - Qbmm * Cox_inv_dVg ;
T1 = 2.0 * C_QE * here->HSM2_nsubc * C_ESI ;
T2 = sqrt( T1 * ( Pb2c - Vbsz2 ) ) ;
Vth0 = Pb2c + Vfb + T2 * Cox_inv ;
T3 = 0.5 * T1 / T2 * Cox_inv ;
Vth0_dVb = T3 * ( - Vbsz2_dVbs ) + T2 * Cox_inv_dVb ;
Vth0_dVd = T3 * ( - Vbsz2_dVds ) + T2 * Cox_inv_dVd ;
Vth0_dVg = T3 * ( - Vbsz2_dVgs ) + T2 * Cox_inv_dVg ;
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdplp ;
T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = 0.5 * T5 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ;
T1 = Vthp - Vth0 ;
T2 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * Pbsum / model->HSM2_lp ;
T3 = T2 + pParam->HSM2_scp2 * Vdsz ;
Vdx = model->HSM2_scp21 + Vdsz ;
Vdx2 = Vdx * Vdx + small ;
dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc / Vdx2 ;
T4 = T1 * dVth0 * pParam->HSM2_scp3 / model->HSM2_lp ;
dVthLP_dVb = (Vthp_dVb - Vth0_dVb) * dVth0 * T3 + T1 * dVth0_dVb * T3
+ T4 * Pbsum_dVb + dqb_dVb ;
dVthLP_dVd = (Vthp_dVd - Vth0_dVd) * dVth0 * T3 + T1 * dVth0_dVd * T3
+ T4 * Pbsum_dVd
+ T1 * dVth0 * pParam->HSM2_scp2 * Vdsz_dVds
+ dqb_dVd
+ 2.0e0 * here->HSM2_msc * Vdx * Vdsz_dVds / ( Vdx2 * Vdx2 ) ;
dVthLP_dVg = (Vthp_dVg - Vth0_dVg) * dVth0 * T3 + T1 * dVth0_dVg * T3
+ T4 * Pbsum_dVg + dqb_dVg ;
}
} else {
dVthLP = 0.0e0 ;
dVthLP_dVb = 0.0e0 ;
dVthLP_dVd = 0.0e0 ;
dVthLP_dVg = 0.0e0 ;
}
/*---------------------------------------------------*
* dVthSC : Short-channel effect induced by Vds.
*-----------------*/
if( corecip ){
T3 = here->HSM2_lgate - model->HSM2_parl2 ;
T4 = 1.0e0 / ( T3 * T3 ) ;
T5 = pParam->HSM2_sc3 / here->HSM2_lgate ;
T6 = pParam->HSM2_sc1 + T5 * ( PS0Z_SCE - Vbsz ) ;
T6_dVb = T5 * ( PS0Z_SCE_dVbs - Vbsz_dVbs );
T6_dVd = T5 * ( PS0Z_SCE_dVds - Vbsz_dVds );
T6_dVg = T5 * PS0Z_SCE_dVgs ;
T6_dPS0Z = T5 ;
/* QME:1 CORECIP:1 */
if( pParam->HSM2_sc4 != 0 ){
T8 = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE - Vbsz ) ;
T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * ( PS0Z_SCE - Vbsz ) + Vdsz * ( PS0Z_SCE_dVds - Vbsz_dVds ) ) ;
T8_dVb = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE_dVbs - Vbsz_dVbs ) ;
T8_dVg = pParam->HSM2_sc4 * Vdsz * PS0Z_SCE_dVgs ;
T8_dPS0Z = pParam->HSM2_sc4 * Vdsz ;
T1 = T6 + pParam->HSM2_sc2 * Vdsz + T8 ;
T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ;
T1_dVb = T6_dVb + T8_dVb ;
T1_dVg = T6_dVg + T8_dVg ;
T1_dPS0Z = T6_dPS0Z + T8_dPS0Z ;
}else{
T1 = T6 + pParam->HSM2_sc2 * Vdsz ;
T1_dVb = T6_dVb ;
T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds ;
T1_dVg = T6_dVg ;
T1_dPS0Z = T6_dPS0Z ;
}
T0 = C_ESI * here->HSM2_wdpl * 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T4 ;
T2 = T0 * Cox_inv ;
T2_dVb = T0 * Cox_inv_dVb ;
T2_dVd = T0 * Cox_inv_dVd ;
T2_dVg = T0 * Cox_inv_dVg ;
A = T2 * T1 ;
A_dVbs = T2 * T1_dVb + T1 * T2_dVb ;
A_dVds = T2 * T1_dVd + T1 * T2_dVd ;
A_dVgs = T2 * T1_dVg + T1 * T2_dVg ;
A_dPS0Z = T2 * T1_dPS0Z ;
T9 = PS0Z_SCE - Vbsz + Ps0_min ;
T9_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs + Ps0_min_dVbs ;
T9_dVd = PS0Z_SCE_dVds - Vbsz_dVds + Ps0_min_dVds ;
T9_dVg = PS0Z_SCE_dVgs + Ps0_min_dVgs ;
T9_dPS0Z = 1.0 ;
if ( T9 > arg0 ) {
T8 = sqrt( T9 ) ;
T8_dVb = 0.5 * T9_dVb / T8 ;
T8_dVd = 0.5 * T9_dVd / T8 ;
T8_dVg = 0.5 * T9_dVg / T8 ;
T8_dPS0Z = 0.5 * T9_dPS0Z / T8 ;
} else {
T8 = sqrt(arg0) + 0.5 / sqrt(arg0) * ( T9 - arg0) ;
T8_dVb = 0.5 / sqrt(arg0) * T9_dVb ;
T8_dVd = 0.5 / sqrt(arg0) * T9_dVd ;
T8_dVg = 0.5 / sqrt(arg0) * T9_dVg ;
T8_dPS0Z = 0.5 / sqrt(arg0) * T9_dPS0Z ;
}
dVthSC = A * T8 ;
dVthSC_dVb = A * T8_dVb + A_dVbs * T8;
dVthSC_dVd = A * T8_dVd + A_dVds * T8;
dVthSC_dVg = A * T8_dVg + A_dVgs * T8;
dVthSC_dPS0Z = A * T8_dPS0Z + A_dPS0Z * T8;
}else{ /* original */
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdpl ;
T3 = here->HSM2_lgate - model->HSM2_parl2 ;
T4 = 1.0e0 / ( T3 * T3 ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = T5 / 2.0 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ;
T1 = pParam->HSM2_sc3 / here->HSM2_lgate ;
T4 = pParam->HSM2_sc1 + T1 * Pbsum ;
T4_dVb = T1 * Pbsum_dVb ;
T4_dVd = T1 * Pbsum_dVd ;
T4_dVg = T1 * Pbsum_dVg ;
/* QME:1 CORECIP:0 */
if( pParam->HSM2_sc4 != 0 ){
T8 = pParam->HSM2_sc4 * Vdsz * Pbsum ;
T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * Pbsum + Vdsz * Pbsum_dVd ) ;
T8_dVb = pParam->HSM2_sc4 * Vdsz * Pbsum_dVb ;
T8_dVg = pParam->HSM2_sc4 * Vdsz * Pbsum_dVg ;
T5 = T4 + pParam->HSM2_sc2 * Vdsz + T8 ;
T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ;
T5_dVb = T4_dVb + T8_dVb ;
T5_dVg = T4_dVg + T8_dVg ;
}else{
T5 = T4 + pParam->HSM2_sc2 * Vdsz ;
T5_dVb = T4_dVb ;
T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds ;
T5_dVg = T4_dVg ;
}
dVthSC = dVth0 * T5 ;
dVthSC_dVb = dVth0_dVb * T5 + dVth0 * T5_dVb ;
dVthSC_dVd = dVth0_dVd * T5 + dVth0 * T5_dVd ;
dVthSC_dVg = dVth0_dVg * T5 + dVth0 * T5_dVg ;
}
/*---------------------------------------------------*
* dVthW : narrow-channel effect.
*-----------------*/
T1 = 1.0 / Cox ;
T2 = T1 * T1 ;
T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ;
T4 = T3 * T3 ;
T5 = T1 - T3 ;
T6 = Qb0 * ( T2 - T4 ) ;
if( corecip ){
dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ;
dVthW_dVb = Qb0_dVb * T5 - Cox_dVb * T6 ;
dVthW_dVd = Qb0_dVd * T5 - Cox_dVd * T6 ;
dVthW_dVg = Qb0_dVg * T5 - Cox_dVg * T6 ;
}else{ /* original */
dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ;
dVthW_dVb = Qb0_dVb * T5 - Cox_dVb * T6 ;
dVthW_dVd = Qb0_dVd * T5 - Cox_dVd * T6 ;
dVthW_dVg = - Cox_dVg * T6 ;
}
/* end of case flg_qme = 1 */
} else {
/* now case flg_qme = 0 */
/*---------------------------------------------------*
* Vthp : Vth with pocket.
*-----------------*/
if( corecip ){
T1 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt ( T1 ) ;
Qb0_dVb = 0.0 ;
Qb0_dVd = 0.0 ;
Qb0_dVg = 0.0 ;
Vthp = PS0Z_SCE + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr;
Vthp_dVb = PS0Z_SCE_dVbs + Qb0_dVb * Cox_inv ;
Vthp_dVd = PS0Z_SCE_dVds + Qb0_dVd * Cox_inv ;
Vthp_dVg = PS0Z_SCE_dVgs + Qb0_dVg * Cox_inv ;
Vthp_dPS0Z = 1.0 ;
}else{ /* original */
T1 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt (T1 * (Pb20 - Vbsz2)) ;
T2 = 0.5 * T1 / Qb0 ;
Qb0_dVb = T2 * (- Vbsz2_dVbs) ;
Qb0_dVd = T2 * (- Vbsz2_dVds) ;
Qb0_dVg = T2 * (- Vbsz2_dVgs) ;
Vthp = Pb20 + Vfb + Qb0 * Cox_inv + here->HSM2_ptovr;
Vthp_dVb = Qb0_dVb * Cox_inv ;
Vthp_dVd = Qb0_dVd * Cox_inv ;
Vthp_dVg = Qb0_dVg * Cox_inv ;
}
Pb20b = Pb20 ;
Pb20b_dVb = 0.0 ;
Pb20b_dVd = 0.0 ;
Pb20b_dVg = 0.0 ;
T0 = 0.95 ;
T1 = T0 * Pb20b - Vbsz2 - 1.0e-3 ;
T1_dVb = T0 * Pb20b_dVb - Vbsz2_dVbs ;
T1_dVd = T0 * Pb20b_dVd - Vbsz2_dVds ;
T1_dVg = T0 * Pb20b_dVg - Vbsz2_dVgs ;
T2 = sqrt (T1 * T1 + 4.0 * T0 * Pb20b * 1.0e-3) ;
T3 = T0 * Pb20b - 0.5 * (T1 + T2) ;
T4 = 2.0 * T0 * 1.0e-3 ;
T5 = T1 / T2 ;
T6 = T4 / T2 ;
T3_dVb = T0 * Pb20b_dVb
- 0.5 * (T1_dVb + (T1_dVb * T5 + T6 * Pb20b_dVb ) ) ;
T3_dVd = T0 * Pb20b_dVd
- 0.5 * (T1_dVd + (T1_dVd * T5 + T6 * Pb20b_dVd ) ) ;
T3_dVg = T0 * Pb20b_dVg
- 0.5 * (T1_dVg + (T1_dVg * T5 + T6 * Pb20b_dVg ) ) ;
Pbsum = Pb20b - T3 ;
Pbsum_dVb = Pb20b_dVb - T3_dVb ;
Pbsum_dVd = Pb20b_dVd - T3_dVd ;
Pbsum_dVg = Pb20b_dVg - T3_dVg ;
sqrt_Pbsum = sqrt( Pbsum ) ;
/*-------------------------------------------*
* dVthLP : Short-channel effect induced by pocket.
* - Vth0 : Vth without pocket.
*-----------------*/
if ( model->HSM2_lp != 0.0 ) {
if( corecip ){
T1 = here->HSM2_2qnsub_esi ;
T2 = model->HSM2_bs2 - Vbsz2 ;
T3 = T2 + small ;
T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ;
T5 = 0.5 * (T3 + T4) ;
T6 = 0.5 * (1.0 + T3 / T4) ;
T5_dVb = - Vbsz2_dVbs * T6 ;
T5_dVd = - Vbsz2_dVds * T6 ;
T5_dVg = - Vbsz2_dVgs * T6 ;
T7 = 1.0 / T5 ;
bs12 = model->HSM2_bs1 * T7 ;
T8 = - bs12 * T7 ;
bs12_dVb = T8 * T5_dVb ;
bs12_dVd = T8 * T5_dVd ;
bs12_dVg = T8 * T5_dVg ;
T1 = 0.93 * ( PS0Z_SCE + Ps0_min - Vbsz2 );
T1_dVb = 0.93 * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs );
T1_dVd = 0.93 * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds );
T1_dVg = 0.93 * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs );
T1_dPS0Z = 0.93 ;
T2 = bs12 ;
T2_dVb = bs12_dVb ;
T2_dVd = bs12_dVd ;
T2_dVg = bs12_dVg ;
Fn_SU2( T10 , T2 , T1 , vth_dlt, T0, T3 ) ;
T10_dVb = T2_dVb * T0 + T1_dVb * T3 ;
T10_dVd = T2_dVd * T0 + T1_dVd * T3 ;
T10_dVg = T2_dVg * T0 + T1_dVg * T3 ;
T10_dPS0Z = T1_dPS0Z * T3 ;
T4 = here->HSM2_2qnsub_esi * ( PS0Z_SCE + Ps0_min - Vbsz2 - T10 ) ;
T4_dVb = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVbs + Ps0_min_dVbs - Vbsz2_dVbs - T10_dVb ) ;
T4_dVd = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVds + Ps0_min_dVds - Vbsz2_dVds - T10_dVd ) ;
T4_dVg = here->HSM2_2qnsub_esi * ( PS0Z_SCE_dVgs + Ps0_min_dVgs - Vbsz2_dVgs - T10_dVg ) ;
T4_dPS0Z = here->HSM2_2qnsub_esi * ( 1.0 - T10_dPS0Z ) ;
if (T4 > arg2){
Qbmm = sqrt ( T4 ) ;
Qbmm_dVb = 0.5 / Qbmm * T4_dVb ;
Qbmm_dVd = 0.5 / Qbmm * T4_dVd ;
Qbmm_dVg = 0.5 / Qbmm * T4_dVg ;
Qbmm_dPS0Z = 0.5 / Qbmm * T4_dPS0Z ;
} else {
Qbmm = sqrt(arg2) + 0.5 / sqrt(arg2) * ( T4 - arg2) ;
Qbmm_dVb = 0.5 / sqrt(arg2) * T4_dVb ;
Qbmm_dVd = 0.5 / sqrt(arg2) * T4_dVd ;
Qbmm_dVg = 0.5 / sqrt(arg2) * T4_dVg ;
Qbmm_dPS0Z = 0.5 / sqrt(arg2) * T4_dPS0Z ;
}
dqb = ( Qb0 - Qbmm ) * Cox_inv ;
dqb_dVb = ( Qb0_dVb - Qbmm_dVb ) * Cox_inv ;
dqb_dVd = ( Qb0_dVd - Qbmm_dVd ) * Cox_inv ;
dqb_dVg = ( Qb0_dVg - Qbmm_dVg ) * Cox_inv ;
dqb_dPS0Z = ( - Qbmm_dPS0Z ) * Cox_inv ;
/* W/O QME PART */
if( codqb == 0 ){
dqb = 0 ;
dqb_dVb = 0 ;
dqb_dVd = 0 ;
dqb_dVg = 0 ;
dqb_dPS0Z = 0.0 ;
}
T1 = 2.0 * C_QE * here->HSM2_nsubc * C_ESI ;
T2 = sqrt( T1 ) ;
T2_dVb = 0.0 ;
T2_dVd = 0.0 ;
T2_dVg = 0.0 ;
Vth0 = PS0Z_SCE + Vfb + T2 * Cox_inv ;
Vth0_dVb = PS0Z_SCE_dVbs + T2_dVb * Cox_inv ;
Vth0_dVd = PS0Z_SCE_dVds + T2_dVd * Cox_inv ;
Vth0_dVg = PS0Z_SCE_dVgs + T2_dVg * Cox_inv ;
Vth0_dPS0Z = 1.0 ;
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdplp ;
T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T1 * T2 * T4 ;
T5_dVb = 0.0 ;
T5_dVd = 0.0 ;
T5_dVg = 0.0 ;
T6 = PS0Z_SCE - Vbsz ;
T6_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs ;
T6_dVd = PS0Z_SCE_dVds - Vbsz_dVds ;
T6_dVg = PS0Z_SCE_dVgs ;
T6_dPS0Z = 1.0 ;
Fn_SZ(T6, T6, C_sce_dlt, T0 );
T6 += small ;
T6_dVb *= T0 ;
T6_dVd *= T0 ;
T6_dVg *= T0 ;
T6_dPS0Z *= T0 ;
dVth0 = T5 * sqrt( T6 ) ;
dVth0_dVb = T5 * 0.5 / sqrt( T6 ) * T6_dVb + T5_dVb * sqrt( T6 );
dVth0_dVd = T5 * 0.5 / sqrt( T6 ) * T6_dVd + T5_dVd * sqrt( T6 ) ;
dVth0_dVg = T5 * 0.5 / sqrt( T6 ) * T6_dVg + T5_dVg * sqrt( T6 ) ;
dVth0_dPS0Z = T5 * 0.5 / sqrt( T6 ) * T6_dPS0Z ;
T1 = Vthp - Vth0 ;
T1_dVb = Vthp_dVb - Vth0_dVb ;
T1_dVd = Vthp_dVd - Vth0_dVd ;
T1_dVg = Vthp_dVg - Vth0_dVg ;
T1_dPS0Z = Vthp_dPS0Z - Vth0_dPS0Z ;
T9 = PS0Z_SCE - Vbsz2 ;
T9_dVb = PS0Z_SCE_dVbs - Vbsz2_dVbs ;
T9_dVd = PS0Z_SCE_dVds - Vbsz2_dVds ;
T9_dVg = PS0Z_SCE_dVgs - Vbsz2_dVgs ;
T9_dPS0Z = 1.0 ;
T3 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * T9 / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz ;
T3_dVb = pParam->HSM2_scp3 * T9_dVb / model->HSM2_lp ;
T3_dVd = pParam->HSM2_scp3 * T9_dVd / model->HSM2_lp + pParam->HSM2_scp2 * Vdsz_dVds ;
T3_dVg = pParam->HSM2_scp3 * T9_dVg / model->HSM2_lp ;
T3_dPS0Z = pParam->HSM2_scp3 * T9_dPS0Z / model->HSM2_lp ;
Vdx = model->HSM2_scp21 + Vdsz ;
Vdx2 = Vdx * Vdx + small ;
T4 = Vdx * Vdx + small ;
T4_dVb = 0.0 ;
T4_dVd = 2.0 * Vdx * Vdsz_dVds ;
T4_dVg = 0.0 ;
T5 = 1.0 / T4 ;
T5_dVb = - T4_dVb / T4 / T4 ;
T5_dVd = - T4_dVd / T4 / T4 ;
T5_dVg = - T4_dVg / T4 / T4 ;
dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc * T5 ;
dVthLP_dVb = T1_dVb * dVth0 * T3 + T1 * dVth0_dVb * T3 + T1 * dVth0 * T3_dVb + dqb_dVb - here->HSM2_msc * T5_dVb ;
dVthLP_dVd = T1_dVd * dVth0 * T3 + T1 * dVth0_dVd * T3 + T1 * dVth0 * T3_dVd + dqb_dVd - here->HSM2_msc * T5_dVd ;
dVthLP_dVg = T1_dVg * dVth0 * T3 + T1 * dVth0_dVg * T3 + T1 * dVth0 * T3_dVg + dqb_dVg - here->HSM2_msc * T5_dVg ;
dVthLP_dPS0Z = T1_dPS0Z * dVth0 * T3 + T1 * dVth0_dPS0Z * T3 + T1 * dVth0 * T3_dPS0Z + dqb_dPS0Z ;
}else{ /* Original */
T1 = here->HSM2_2qnsub_esi ;
T2 = model->HSM2_bs2 - Vbsz2 ;
T3 = T2 + small ;
T4 = sqrt (T3 * T3 + 4.0 * vth_dlt) ;
T5 = 0.5 * (T3 + T4) ;
T6 = 0.5 * (1.0 + T3 / T4) ;
T5_dVb = - Vbsz2_dVbs * T6 ;
T5_dVd = - Vbsz2_dVds * T6 ;
T5_dVg = - Vbsz2_dVgs * T6 ;
T7 = 1.0 / T5 ;
bs12 = model->HSM2_bs1 * T7 ;
T8 = - bs12 * T7 ;
bs12_dVb = T8 * T5_dVb ;
bs12_dVd = T8 * T5_dVd ;
bs12_dVg = T8 * T5_dVg ;
Fn_SU( T10 , Vbsz2 + bs12, 0.93 * Pb20, vth_dlt, T0) ;
Qbmm = sqrt (T1 * (Pb20 - T10 )) ;
T9 = T0 / Qbmm ;
Qbmm_dVb = 0.5 * T1 * - (Vbsz2_dVbs + bs12_dVb) * T9 ;
Qbmm_dVd = 0.5 * T1 * - (Vbsz2_dVds + bs12_dVd) * T9 ;
Qbmm_dVg = 0.5 * T1 * - (Vbsz2_dVgs + bs12_dVg) * T9 ;
dqb = (Qb0 - Qbmm) * Cox_inv ;
dqb_dVb = Vthp_dVb - Qbmm_dVb * Cox_inv ;
dqb_dVd = Vthp_dVd - Qbmm_dVd * Cox_inv ;
dqb_dVg = Vthp_dVg - Qbmm_dVg * Cox_inv ;
T1 = 2.0 * C_QE * here->HSM2_nsubc * C_ESI ;
T2 = sqrt( T1 * ( Pb2c - Vbsz2 ) ) ;
Vth0 = Pb2c + Vfb + T2 * Cox_inv ;
T3 = 0.5 * T1 / T2 * Cox_inv ;
Vth0_dVb = T3 * ( - Vbsz2_dVbs ) ;
Vth0_dVd = T3 * ( - Vbsz2_dVds ) ;
Vth0_dVg = T3 * ( - Vbsz2_dVgs ) ;
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdplp ;
T4 = 1.0e0 / ( model->HSM2_lp * model->HSM2_lp ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = 0.5 * T5 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T8 * Pb20b_dVg ;
T1 = Vthp - Vth0 ;
T2 = pParam->HSM2_scp1 + pParam->HSM2_scp3 * Pbsum / model->HSM2_lp ;
T3 = T2 + pParam->HSM2_scp2 * Vdsz ;
Vdx = model->HSM2_scp21 + Vdsz ;
Vdx2 = Vdx * Vdx + small ;
dVthLP = T1 * dVth0 * T3 + dqb - here->HSM2_msc / Vdx2 ;
T4 = T1 * dVth0 * pParam->HSM2_scp3 / model->HSM2_lp ;
dVthLP_dVb = (Vthp_dVb - Vth0_dVb) * dVth0 * T3 + T1 * dVth0_dVb * T3
+ T4 * Pbsum_dVb + dqb_dVb ;
dVthLP_dVd = (Vthp_dVd - Vth0_dVd) * dVth0 * T3 + T1 * dVth0_dVd * T3
+ T4 * Pbsum_dVd
+ T1 * dVth0 * pParam->HSM2_scp2 * Vdsz_dVds
+ dqb_dVd
+ 2.0e0 * here->HSM2_msc * Vdx * Vdsz_dVds / ( Vdx2 * Vdx2 ) ;
dVthLP_dVg = (Vthp_dVg - Vth0_dVg) * dVth0 * T3 + T1 * dVth0_dVg * T3
+ T4 * Pbsum_dVg + dqb_dVg ;
}
} else {
dVthLP = 0.0e0 ;
dVthLP_dVb = 0.0e0 ;
dVthLP_dVd = 0.0e0 ;
dVthLP_dVg = 0.0e0 ;
}
/*---------------------------------------------------*
* dVthSC : Short-channel effect induced by Vds.
*-----------------*/
if( corecip ){
T3 = here->HSM2_lgate - model->HSM2_parl2 ;
T4 = 1.0e0 / ( T3 * T3 ) ;
T5 = pParam->HSM2_sc3 / here->HSM2_lgate ;
T6 = pParam->HSM2_sc1 + T5 * ( PS0Z_SCE - Vbsz ) ;
T6_dVb = T5 * ( PS0Z_SCE_dVbs - Vbsz_dVbs );
T6_dVd = T5 * ( PS0Z_SCE_dVds - Vbsz_dVds );
T6_dVg = T5 * PS0Z_SCE_dVgs ;
T6_dPS0Z = T5 ;
/* QME:0 CORECIP:1 */
if( pParam->HSM2_sc4 != 0 ){
T8 = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE - Vbsz ) ;
T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * ( PS0Z_SCE - Vbsz ) + Vdsz * ( PS0Z_SCE_dVds - Vbsz_dVds ) ) ;
T8_dVb = pParam->HSM2_sc4 * Vdsz * ( PS0Z_SCE_dVbs - Vbsz_dVbs ) ;
T8_dVg = pParam->HSM2_sc4 * Vdsz * PS0Z_SCE_dVgs ;
T8_dPS0Z = pParam->HSM2_sc4 * Vdsz ;
T1 = T6 + pParam->HSM2_sc2 * Vdsz + T8 ;
T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ;
T1_dVb = T6_dVb + T8_dVb ;
T1_dVg = T6_dVg + T8_dVg ;
T1_dPS0Z = T6_dPS0Z + T8_dPS0Z ;
}else{
T1 = T6 + pParam->HSM2_sc2 * Vdsz ;
T1_dVb = T6_dVb ;
T1_dVd = T6_dVd + pParam->HSM2_sc2 * Vdsz_dVds ;
T1_dVg = T6_dVg ;
T1_dPS0Z = T6_dPS0Z ;
}
T2 = C_ESI * Cox_inv * here->HSM2_wdpl * 2.0e0 * ( model->HSM2_vbi - Pb20 ) * T4 ;
A = T2 * T1 ;
A_dVbs = T2 * T1_dVb ;
A_dVds = T2 * T1_dVd ;
A_dVgs = T2 * T1_dVg ;
A_dPS0Z = T2 * T1_dPS0Z ;
T7 = PS0Z_SCE - Vbsz + Ps0_min ;
T7_dVb = PS0Z_SCE_dVbs - Vbsz_dVbs + Ps0_min_dVbs;
T7_dVd = PS0Z_SCE_dVds - Vbsz_dVds + Ps0_min_dVds ;
T7_dVg = PS0Z_SCE_dVgs + Ps0_min_dVgs ;
T7_dPS0Z = 1.0 ;
if ( T7 > arg0 ) {
T8 = sqrt( T7 ) ;
T8_dVb = 0.5 * T7_dVb / T8 ;
T8_dVd = 0.5 * T7_dVd / T8 ;
T8_dVg = 0.5 * T7_dVg / T8 ;
T8_dPS0Z = 0.5 * T7_dPS0Z / T8 ;
} else {
T8 = sqrt(arg0) + 0.5 / sqrt(arg0) * ( T7 - arg0) ;
T8_dVb = 0.5 / sqrt(arg0) * T7_dVb ;
T8_dVd = 0.5 / sqrt(arg0) * T7_dVd ;
T8_dVg = 0.5 / sqrt(arg0) * T7_dVg ;
T8_dPS0Z = 0.5 / sqrt(arg0) * T7_dPS0Z ;
}
dVthSC = A * T8 ;
dVthSC_dVb = A * T8_dVb + A_dVbs * T8;
dVthSC_dVd = A * T8_dVd + A_dVds * T8;
dVthSC_dVg = A * T8_dVg + A_dVgs * T8;
dVthSC_dPS0Z = A * T8_dPS0Z + A_dPS0Z * T8;
}else{ /* original */
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdpl ;
T3 = here->HSM2_lgate - model->HSM2_parl2 ;
T4 = 1.0e0 / ( T3 * T3 ) ;
T5 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = T5 / 2.0 / sqrt_Pbsum ;
T7 = 2.0e0 * ( model->HSM2_vbi - Pb20b ) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0e0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T8 * Pb20b_dVg ;
T1 = pParam->HSM2_sc3 / here->HSM2_lgate ;
T4 = pParam->HSM2_sc1 + T1 * Pbsum ;
T4_dVb = T1 * Pbsum_dVb ;
T4_dVd = T1 * Pbsum_dVd ;
T4_dVg = T1 * Pbsum_dVg ;
/* QME:0 CORECIP:0 */
if( pParam->HSM2_sc4 != 0 ){
T8 = pParam->HSM2_sc4 * Vdsz * Pbsum ;
T8_dVd = pParam->HSM2_sc4 * ( Vdsz_dVds * Pbsum + Vdsz * Pbsum_dVd ) ;
T8_dVb = pParam->HSM2_sc4 * Vdsz * Pbsum_dVb ;
T8_dVg = pParam->HSM2_sc4 * Vdsz * Pbsum_dVg ;
T5 = T4 + pParam->HSM2_sc2 * Vdsz + T8 ;
T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds + T8_dVd ;
T5_dVb = T4_dVb + T8_dVb ;
T5_dVg = T4_dVg + T8_dVg ;
}else{
T5 = T4 + pParam->HSM2_sc2 * Vdsz ;
T5_dVb = T4_dVb ;
T5_dVd = T4_dVd + pParam->HSM2_sc2 * Vdsz_dVds ;
T5_dVg = T4_dVg ;
}
dVthSC = dVth0 * T5 ;
dVthSC_dVb = dVth0_dVb * T5 + dVth0 * T5_dVb ;
dVthSC_dVd = dVth0_dVd * T5 + dVth0 * T5_dVd ;
dVthSC_dVg = dVth0_dVg * T5 + dVth0 * T5_dVg ;
}
/*---------------------------------------------------*
* dVthW : narrow-channel effect.
*-----------------*/
T1 = 1.0 / Cox ;
T3 = 1.0 / ( Cox + pParam->HSM2_wfc / Weff ) ;
T5 = T1 - T3 ;
if( corecip ){
dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ;
dVthW_dVb = Qb0_dVb * T5 ;
dVthW_dVd = Qb0_dVd * T5 ;
dVthW_dVg = Qb0_dVg * T5 ;
}else{ /* original */
dVthW = Qb0 * T5 + pParam->HSM2_wvth0 / here->HSM2_wg ;
dVthW_dVb = Qb0_dVb * T5 ;
dVthW_dVd = Qb0_dVd * T5 ;
dVthW_dVg = 0.0 ;
}
} /* end of flg_qme if-blocks */
/*---------------------------------------------------*
* dVth : Total variation.
* - Positive dVth means the decrease in Vth.
*-----------------*/
dVth = dVthSC + dVthLP + dVthW + here->HSM2_dVthsm ;
dVth_dVb = dVthSC_dVb + dVthLP_dVb + dVthW_dVb ;
dVth_dVd = dVthSC_dVd + dVthLP_dVd + dVthW_dVd ;
dVth_dVg = dVthSC_dVg + dVthLP_dVg + dVthW_dVg ;
dVth_dPS0Z = dVthSC_dPS0Z + dVthLP_dPS0Z ;
/*---------------------------------------------------*
* Vth : Threshold voltagei for OP.
*-----------------*/
T2 = sqrt( here->HSM2_2qnsub_esi * Pb2 ) ;
Vth = Pb2 + Vfb + T2 * Cox0_inv - dVth ;
/*-----------------------------------------------------------*
* Constants in the equation of Ps0 .
*-----------------*/
fac1 = cnst0 * Cox_inv ;
fac1_dVbs = cnst0 * Cox_inv_dVb ;
fac1_dVds = cnst0 * Cox_inv_dVd ;
fac1_dVgs = cnst0 * Cox_inv_dVg ;
fac1p2 = fac1 * fac1 ;
/*---------------------------------------------------*
* Poly-Depletion Effect
*-----------------*/
if ( here->HSM2_flg_pgd == 0 ) {
dPpg = 0.0 ;
dPpg_dVb = 0.0 ;
dPpg_dVd = 0.0 ;
dPpg_dVg = 0.0 ;
} else {
T7 = Vgsz ;
T7_dVb = 0.0 ;
T7_dVd = Vgsz_dVds ;
T7_dVg = Vgsz_dVgs ;
T0 = here->HSM2_cnstpgd ;
T3 = T7 - model->HSM2_pgd2 ;
T3_dVb = T7_dVb ;
T3_dVd = T7_dVd ;
T3_dVg = T7_dVg ;
Fn_ExpLim( dPpg , T3 , T6 ) ;
dPpg_dVb = T6 * T3_dVb ;
dPpg_dVd = T6 * T3_dVd ;
dPpg_dVg = T6 * T3_dVg ;
Fn_SZ( dPpg , dPpg - 1.0 , 0.1 , T6 ) ;
dPpg_dVb *= T6 ;
dPpg_dVd *= T6 ;
dPpg_dVg *= T6 ;
dPpg *= T0 ;
dPpg_dVb *= T0 ;
dPpg_dVd *= T0 ;
dPpg_dVg *= T0 ;
Fn_SU( dPpg , dPpg , pol_b , pol_dlt , T9 ) ;
dPpg_dVb *= T9 ;
dPpg_dVd *= T9 ;
dPpg_dVg *= T9 ;
}
/*---------------------------------------------------*
* Vgp : Effective gate bias with SCE & RSCE & flatband.
*-----------------*/
Vgp = Vgs - Vfb + dVth - dPpg ;
Vgp_dVbs = dVth_dVb - dPpg_dVb ;
Vgp_dVds = dVth_dVd - dPpg_dVd ;
Vgp_dVgs = 1.0e0 + dVth_dVg - dPpg_dVg ;
Vgp_dPS0Z = dVth_dPS0Z ;
Vgpz = Vgsz - Vfb + dVth - dPpg ; /* (tmp) */
Vgpz_dVbs = dVth_dVb ;
Vgpz_dVds = Vgsz_dVds + dVth_dVd - dPpg_dVd ;
Vgpz_dVgs = Vgsz_dVgs + dVth_dVg - dPpg_dVg ;
Vgpz_dPS0Z = dVth_dPS0Z ;
/*---------------------------------------------------*
* Vgs_fb : Actual flatband voltage taking account Vbs.
* - note: if Vgs == Vgs_fb then Vgp == Ps0 == Vbs .
*------------------*/
Vgs_fb = Vfb - dVth + dPpg + Vbs ;
/*-----------------------------------------------------------*
* Accumulation zone. (zone-A)
* - evaluate basic characteristics and exit from this part.
*-----------------*/
if ( Vgs < Vgs_fb ) {
flg_zone = -1 ;
/*---------------------------------------------------*
* Evaluation of Ps0.
* - Psa : Analytical solution of
* Cox( Vgp - Psa ) = cnst0 * Qacc
* where Qacc is the 3-degree series of (fdep)^{1/2}.
* The unknown is transformed to Chi=beta(Ps0-Vbs).
* - Ps0_min : |Ps0_min| when Vbs=0.
*-----------------*/
/* Ps0_min = here->HSM2_eg - Pb2 ; */
/* -> replaced by approx. solving Poisson equation at Vgs=Vgs_min */
/* Ps0_min = 2.0 * beta_inv * log(-Vgs_min/fac1) ; already done above */
TX = beta * ( Vgp - Vbs ) ;
TX_dVbs = beta * ( Vgp_dVbs - 1.0 ) ;
TX_dVds = beta * Vgp_dVds ;
TX_dVgs = beta * Vgp_dVgs ;
TX_dPS0Z = beta * Vgp_dPS0Z ;
T1 = 1.0 / ( beta * cnst0 ) ;
TY = T1 * Cox ;
TY_dVbs = T1 * Cox_dVb ;
TY_dVds = T1 * Cox_dVd ;
TY_dVgs = T1 * Cox_dVg ;
Ac41 = 2.0 + 3.0 * C_SQRT_2 * TY ;
Ac4 = 8.0 * Ac41 * Ac41 * Ac41 ;
T1 = 72.0 * Ac41 * Ac41 * C_SQRT_2 ;
Ac4_dVbs = T1 * TY_dVbs ;
Ac4_dVds = T1 * TY_dVds ;
Ac4_dVgs = T1 * TY_dVgs ;
T4 = ( TX - 2.0 ) ;
T5 = 9.0 * TY * T4 ;
T5_dVb = 9.0 * ( TY_dVbs * T4 + TY * TX_dVbs ) ;
T5_dVd = 9.0 * ( TY_dVds * T4 + TY * TX_dVds ) ;
T5_dVg = 9.0 * ( TY_dVgs * T4 + TY * TX_dVgs ) ;
T5_dPS0Z = 9.0 * ( TY * TX_dPS0Z ) ;
Ac31 = 7.0 * C_SQRT_2 - T5 ;
Ac31_dVbs = -T5_dVb ;
Ac31_dVds = -T5_dVd ;
Ac31_dVgs = -T5_dVg ;
Ac31_dPS0Z = -T5_dPS0Z ;
Ac3 = Ac31 * Ac31 ;
T1 = 2.0 * Ac31 ;
Ac3_dVbs = T1 * Ac31_dVbs ;
Ac3_dVds = T1 * Ac31_dVds ;
Ac3_dVgs = T1 * Ac31_dVgs ;
Ac3_dPS0Z = T1 * Ac31_dPS0Z ;
Ac2 = sqrt( Ac4 + Ac3 ) ;
T1 = 0.5 / Ac2 ;
Ac2_dVbs = T1 * ( Ac4_dVbs + Ac3_dVbs ) ;
Ac2_dVds = T1 * ( Ac4_dVds + Ac3_dVds ) ;
Ac2_dVgs = T1 * ( Ac4_dVgs + Ac3_dVgs ) ;
Ac2_dPS0Z = T1 * ( Ac3_dPS0Z ) ;
Ac1 = -7.0 * C_SQRT_2 + Ac2 + T5 ;
Ac1_dVbs = Ac2_dVbs + T5_dVb ;
Ac1_dVds = Ac2_dVds + T5_dVd ;
Ac1_dVgs = Ac2_dVgs + T5_dVg ;
Ac1_dPS0Z = Ac2_dPS0Z + T5_dPS0Z ;
Acd = Fn_Pow( Ac1 , C_1o3 ) ;
T1 = C_1o3 / ( Acd * Acd ) ;
Acd_dVbs = Ac1_dVbs * T1 ;
Acd_dVds = Ac1_dVds * T1 ;
Acd_dVgs = Ac1_dVgs * T1 ;
Acd_dPS0Z = Ac1_dPS0Z * T1 ;
Acn = -4.0 * C_SQRT_2 - 12.0 * TY + 2.0 * Acd + C_SQRT_2 * Acd * Acd ;
T1 = 2.0 + 2.0 * C_SQRT_2 * Acd ;
Acn_dVbs = - 12.0 * TY_dVbs + T1 * Acd_dVbs ;
Acn_dVds = - 12.0 * TY_dVds + T1 * Acd_dVds ;
Acn_dVgs = - 12.0 * TY_dVgs + T1 * Acd_dVgs ;
Acn_dPS0Z = T1 * Acd_dPS0Z ;
T1 = 1.0 / Acd ;
Chi = Acn * T1 ;
Chi_dVbs = ( Acn_dVbs - Chi * Acd_dVbs ) * T1 ;
Chi_dVds = ( Acn_dVds - Chi * Acd_dVds ) * T1 ;
Chi_dVgs = ( Acn_dVgs - Chi * Acd_dVgs ) * T1 ;
Chi_dPS0Z = ( Acn_dPS0Z - Chi * Acd_dPS0Z ) * T1 ;
Psa = Chi * beta_inv + Vbs ;
Psa_dVbs = Chi_dVbs * beta_inv + 1.0 ;
Psa_dVds = Chi_dVds * beta_inv ;
Psa_dVgs = Chi_dVgs * beta_inv ;
Psa_dPS0Z = Chi_dPS0Z * beta_inv ;
T1 = Psa - Vbs ;
T2 = T1 / Ps0_min ;
T3 = sqrt( 1.0 + ( T2 * T2 ) ) ;
T9 = T2 / T3 / Ps0_min ;
T3_dVb = T9 * ( Psa_dVbs - 1.0 ) ;
T3_dVd = T9 * ( Psa_dVds ) ;
T3_dVg = T9 * ( Psa_dVgs ) ;
T3_dPS0Z = T9 * ( Psa_dPS0Z ) ;
Ps0 = T1 / T3 + Vbs ;
T9 = 1.0 / ( T3 * T3 ) ;
Ps0_dVbs = T9 * ( ( Psa_dVbs - 1.0 ) * T3 - T1 * T3_dVb ) + 1.0 ;
Ps0_dVds = T9 * ( Psa_dVds * T3 - T1 * T3_dVd ) ;
Ps0_dVgs = T9 * ( Psa_dVgs * T3 - T1 * T3_dVg ) ;
Ps0_dPS0Z = T9 * ( Psa_dPS0Z * T3 - T1 * T3_dPS0Z ) ;
/*---------------------------------------------------*
* Characteristics.
*-----------------*/
Psl = Ps0 ;
Psl_dVbs = Ps0_dVbs ;
Psl_dVds = Ps0_dVds ;
Psl_dVgs = Ps0_dVgs ;
T2 = ( Vgp - Ps0 ) ;
Qbu = Cox * T2 ;
Qbu_dVbs = Cox * ( Vgp_dVbs - Ps0_dVbs ) + Cox_dVb * T2 ;
Qbu_dVds = Cox * ( Vgp_dVds - Ps0_dVds ) + Cox_dVd * T2 ;
Qbu_dVgs = Cox * ( Vgp_dVgs - Ps0_dVgs ) + Cox_dVg * T2 ;
Qiu = 0.0e0 ;
Qiu_dVbs = 0.0e0 ;
Qiu_dVds = 0.0e0 ;
Qiu_dVgs = 0.0e0 ;
Qdrat = 0.5e0 ;
Qdrat_dVbs = 0.0e0 ;
Qdrat_dVds = 0.0e0 ;
Qdrat_dVgs = 0.0e0 ;
Lred = 0.0e0 ;
Lred_dVbs = 0.0e0 ;
Lred_dVds = 0.0e0 ;
Lred_dVgs = 0.0e0 ;
Ids = 0.0e0 ;
Ids_dVbs = 0.0e0 ;
Ids_dVds = 0.0e0 ;
Ids_dVgs = 0.0e0 ;
VgVt = 0.0 ;
flg_noqi = 1 ;
DJI = 1.0 ;
if( corecip ){
/*!! This is for Accumulation Region !!*/
T1 = Vds * 0.5 ;
Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ;
T2 /= 2 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = T2 * ( 1.0 ) ;
Pzadd_dVgs = 0.0 ;
Pzadd_dPS0Z = 0.0 ;
if ( Pzadd < epsm10 ) {
Pzadd = epsm10 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = 0.0 ;
Pzadd_dVgs = 0.0 ;
Pzadd_dPS0Z = 0.0 ;
}
Ps0z = Ps0 + Pzadd ;
Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ;
Ps0z_dVds = Ps0_dVds + Pzadd_dVds ;
Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ;
Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ;
/* calculate Newton correction: */
G = PS0Z_SCE - Ps0z ;
delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ;
delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs;
delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds;
delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs;
PS0Z_SCE += delta_PS0Z_SCE ;
PS0Z_SCE_dVbs = Ps0z_dVbs ;
PS0Z_SCE_dVds = Ps0z_dVds ;
PS0Z_SCE_dVgs = Ps0z_dVgs ;
PS0_SCE = PS0Z_SCE - Pzadd ;
PS0_SCE_dVbs = Ps0_dVbs ;
PS0_SCE_dVds = Ps0_dVds ;
PS0_SCE_dVgs = Ps0_dVgs ;
NNN += 1 ;
if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol
|| fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol
) && (NNN < MAX_LOOP_SCE) ){
// goto START_OF_SCE_LOOP;
START_OF_SCE_LOOP = 1 ;
}
}
//goto end_of_part_1 ;
if( START_OF_SCE_LOOP==0 ) end_of_part_1 = 1 ;
}
} /* End of 3rd SCE_LOOP */
if ( end_of_part_1 == 0 ) { /* skip to end_of_part_1 */
/*-----------------------------------------------------------*
* Initial guess for Ps0.
*-----------------*/
/*---------------------------------------------------*
* Ps0_iniA: solution of subthreshold equation assuming zone-D1/D2.
*-----------------*/
TX = 1.0e0 + 4.0e0
* ( beta * ( Vgp - Vbs ) - 1.0e0 ) / ( fac1p2 * beta2 ) ;
TX = Fn_Max( TX , epsm10 ) ;
Ps0_iniA = Vgp + fac1p2 * beta * 0.5 * ( 1.0e0 - sqrt( TX ) ) ;
/* use analitical value in subthreshold region. */
if ( Vgs < ( Vfb + Vth ) * 0.5 ) {
flg_pprv = 0 ;
}
if ( flg_pprv >= 1 ) {
/*---------------------------------------------------*
* Use previous value.
*-----------------*/
T1 = Ps0_dVbs * dVbs + Ps0_dVds * dVds + Ps0_dVgs * dVgs ;
Ps0_ini = Ps0 + T1 ;
if ( flg_pprv == 2 ) {
/* TX_dVxs = d^2 Ps0 / d Vxs^2 here */
if ( Vbsc_dif2 > epsm10 ) {
TX_dVbs = ( here->HSM2_ps0_dvbs_prv - here->HSM2_ps0_dvbs_prv2 )
/ Vbsc_dif2 ;
} else {
TX_dVbs = 0.0 ;
}
if ( Vdsc_dif2 > epsm10 ) {
TX_dVds = ( here->HSM2_ps0_dvds_prv - here->HSM2_ps0_dvds_prv2 )
/ Vdsc_dif2 ;
} else {
TX_dVds = 0.0 ;
}
if ( Vgsc_dif2 > epsm10 ) {
TX_dVgs = ( here->HSM2_ps0_dvgs_prv - here->HSM2_ps0_dvgs_prv2 )
/ Vgsc_dif2 ;
} else {
TX_dVgs = 0.0 ;
}
T2 = ( dVbs * dVbs ) / 2 * TX_dVbs
+ ( dVds * dVds ) / 2 * TX_dVds
+ ( dVgs * dVgs ) / 2 * TX_dVgs ;
if ( fabs( T2 ) < fabs( 0.5 * T1 ) ) {
Ps0_ini += T2 ;
} else {
flg_pprv = 1 ;
}
}
T1 = Ps0_ini - Ps0 ;
if ( T1 < - dP_max || T1 > dP_max ) {
flg_pprv = 0 ; /* flag changes to analitical */
} else {
Ps0_iniA = Fn_Max( Ps0_ini , Ps0_iniA ) ;
}
} /* end of (flg_pprv >=1) if-block */
if ( flg_pprv == 0 ) {
/*---------------------------------------------------*
* Analytical initial guess.
*-----------------*/
/*-------------------------------------------*
* Common part.
*-----------------*/
Chi = beta * ( Ps0_iniA - Vbs ) ;
if ( Chi < znbd3 ) {
/*-----------------------------------*
* zone-D1/D2
* - Ps0_ini is the analytical solution of Qs=Qb0 with
* Qb0 being approximated to 3-degree polynomial.
*-----------------*/
TY = beta * ( Vgp - Vbs ) ;
T1 = 1.0e0 / ( cn_nc3 * beta * fac1 ) ;
T2 = 81.0 + 3.0 * T1 ;
T3 = -2916.0 - 81.0 * T1 + 27.0 * T1 * TY ;
T4 = 1458.0 - 81.0 * ( 54.0 + T1 ) + 27.0 * T1 * TY ;
T4 = T4 * T4 ;
T5 = Fn_Pow( T3 + sqrt( 4 * T2 * T2 * T2 + T4 ) , C_1o3 ) ;
TX = 3.0 - ( C_2p_1o3 * T2 ) / ( 3.0 * T5 )
+ 1 / ( 3.0 * C_2p_1o3 ) * T5 ;
Ps0_iniA = TX * beta_inv + Vbs ;
Ps0_ini = Ps0_iniA ;
} else if ( Vgs <= Vth ) {
/*-----------------------------------*
* Weak inversion zone.
*-----------------*/
Ps0_ini = Ps0_iniA ;
} else {
/*-----------------------------------*
* Strong inversion zone.
* - Ps0_iniB : upper bound.
*-----------------*/
T1 = 1.0 / cnst1 / cnstCoxi ;
T2 = T1 * Vgp * Vgp ;
T3 = beta + 2.0 / Vgp ;
Ps0_iniB = log( T2 + small ) / T3 ;
Fn_SU( Ps0_ini , Ps0_iniA, Ps0_iniB, c_ps0ini_2, T1) ;
}
}
TX = Vbs + ps_conv / 2 ;
if ( Ps0_ini < TX ) Ps0_ini = TX ;
/*---------------------------------------------------*
* Assign initial guess.
*-----------------*/
if ( NNN == 0 ) {
Ps0 = Ps0_ini ;
}
Psl_lim = Ps0_iniA ;
/*---------------------------------------------------*
* Calculation of Ps0. (beginning of Newton loop)
* - Fs0 : Fs0 = 0 is the equation to be solved.
* - dPs0 : correction value.
*-----------------*/
exp_bVbs = exp( beta * Vbs ) ;
cfs1 = cnst1 * exp_bVbs ;
flg_conv = 0 ;
for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max + 1 ; lp_s0 ++ ) {
Chi = beta * ( Ps0 - Vbs ) ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D1/D2. (Ps0)
* - Qb0 is approximated to 5-degree polynomial.
*-----------------*/
fi = Chi * Chi * Chi
* ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ;
fi_dChi = Chi * Chi
* ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ;
fs01 = cfs1 * fi * fi ;
fs01_dPs0 = cfs1 * beta * 2 * fi * fi_dChi ;
fb = Chi * ( cn_nc51
+ Chi * ( cn_nc52
+ Chi * ( cn_nc53
+ Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ;
fb_dChi = cn_nc51
+ Chi * ( 2 * cn_nc52
+ Chi * ( 3 * cn_nc53
+ Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ;
fs02 = sqrt( fb * fb + fs01 ) ;
fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) / ( fs02 + fs02 ) ;
} else {
/*-------------------------------------------*
* zone-D3. (Ps0)
*-----------------*/
if ( Chi < large_arg ) { /* avoid exp_Chi to become extremely large */
exp_Chi = exp( Chi ) ;
fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ;
fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ;
} else {
exp_bPs0 = exp( beta*Ps0 ) ;
fs01 = cnst1 * ( exp_bPs0 - exp_bVbs ) ;
fs01_dPs0 = cnst1 * beta * exp_bPs0 ;
}
fs02 = sqrt( Chi - 1.0 + fs01 ) ;
fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ;
} /* end of if ( Chi ... ) else block */
Fs0 = Vgp - Ps0 - fac1 * fs02 ;
Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ;
if ( flg_conv == 1 ) break ;
dPs0 = - Fs0 / Fs0_dPs0 ;
/*-------------------------------------------*
* Update Ps0 .
* - clamped to Vbs if Ps0 < Vbs .
*-----------------*/
dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Ps0))) ;
if ( fabs( dPs0 ) > dPlim ) dPs0 = dPlim * Fn_Sgn( dPs0 ) ;
Ps0 = Ps0 + dPs0 ;
TX = Vbs + ps_conv / 2 ;
if ( Ps0 < TX ) Ps0 = TX ;
/*-------------------------------------------*
* Check convergence.
* NOTE: This condition may be too rigid.
*-----------------*/
if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) {
flg_conv = 1 ;
}
} /* end of Ps0 Newton loop */
/* Eliminate loop count to take account of the derivative loop */
lp_s0 -- ;
/*-------------------------------------------*
* Procedure for diverged case.
*-----------------*/
if ( flg_conv == 0 ) {
fprintf( stderr ,
"*** warning(HiSIM): Went Over Iteration Maximum (Ps0)\n" ) ;
fprintf( stderr ,
" Vbse = %7.3f Vdse = %7.3f Vgse = %7.3f\n" ,
Vbse , Vdse , Vgse ) ;
if ( flg_info >= 2 ) {
printf( "*** warning(HiSIM): Went Over Iteration Maximum (Ps0)\n" ) ;
}
}
/*---------------------------------------------------*
* Evaluate derivatives of Ps0.
* - note: Here, fs01_dVbs and fs02_dVbs are derivatives
* w.r.t. explicit Vbs. So, Ps0 in the fs01 and fs02
* expressions is regarded as a constant.
*-----------------*/
/* derivatives of fs0* w.r.t. explicit Vbs */
if ( Chi < znbd5 ) {
fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ;
T2 = 1.0e0 / ( fs02 + fs02 ) ;
fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) * T2 ;
} else {
fs01_dVbs = - cfs1 * beta ;
T2 = 0.5e0 / fs02 ;
fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ;
}
T1 = 1.0 / Fs0_dPs0 ;
Ps0_dVbs = - ( Vgp_dVbs - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) ) * T1 ;
Ps0_dVds = - ( Vgp_dVds - fac1_dVds * fs02 ) * T1 ;
Ps0_dVgs = - ( Vgp_dVgs - fac1_dVgs * fs02 ) * T1 ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D1/D2. (Ps0)
* Xi0 := fdep0^2 = fb * fb [D1,D2]
*-----------------*/
Xi0 = fb * fb + epsm10 ;
T1 = 2 * fb * fb_dChi * beta ;
Xi0_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ;
Xi0_dVds = T1 * Ps0_dVds ;
Xi0_dVgs = T1 * Ps0_dVgs ;
Xi0p12 = fb + epsm10 ;
T1 = fb_dChi * beta ;
Xi0p12_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ;
Xi0p12_dVds = T1 * Ps0_dVds ;
Xi0p12_dVgs = T1 * Ps0_dVgs ;
Xi0p32 = fb * fb * fb + epsm10 ;
T1 = 3 * fb * fb * fb_dChi * beta ;
Xi0p32_dVbs = T1 * ( Ps0_dVbs - 1.0 ) ;
Xi0p32_dVds = T1 * Ps0_dVds ;
Xi0p32_dVgs = T1 * Ps0_dVgs ;
} else {
/*-------------------------------------------*
* zone-D3. (Ps0)
*-----------------*/
flg_zone = 3 ;
flg_noqi = 0 ;
/*-----------------------------------*
* Xi0 := fdep0^2 = Chi - 1 = beta * ( Ps0 - Vbs ) - 1 [D3]
*-----------------*/
Xi0 = Chi - 1.0e0 ;
Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ;
Xi0_dVds = beta * Ps0_dVds ;
Xi0_dVgs = beta * Ps0_dVgs ;
Xi0p12 = sqrt( Xi0 ) ;
T1 = 0.5e0 / Xi0p12 ;
Xi0p12_dVbs = T1 * Xi0_dVbs ;
Xi0p12_dVds = T1 * Xi0_dVds ;
Xi0p12_dVgs = T1 * Xi0_dVgs ;
Xi0p32 = Xi0 * Xi0p12 ;
T1 = 1.5e0 * Xi0p12 ;
Xi0p32_dVbs = T1 * Xi0_dVbs ;
Xi0p32_dVds = T1 * Xi0_dVds ;
Xi0p32_dVgs = T1 * Xi0_dVgs ;
} /* end of if ( Chi ... ) block */
/*-----------------------------------------------------------*
* - Recalculate the derivatives of fs01 and fs02.
* note: fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ;
* fs02 = sqrt( Xi0 + fs01 ) ;
*-----------------*/
fs01_dVbs = Ps0_dVbs * fs01_dPs0 + fs01_dVbs ;
fs01_dVds = Ps0_dVds * fs01_dPs0 ;
fs01_dVgs = Ps0_dVgs * fs01_dPs0 ;
fs02_dVbs = Ps0_dVbs * fs02_dPs0 + fs02_dVbs ;
fs02_dVds = Ps0_dVds * fs02_dPs0 ;
fs02_dVgs = Ps0_dVgs * fs02_dPs0 ;
/*-----------------------------------------------------------*
* Qb0 : Qb at source side.
* Qn0 : Qi at source side.
*-----------------*/
Qb0 = cnst0 * Xi0p12 ;
Qb0_dVb = cnst0 * Xi0p12_dVbs ;
Qb0_dVd = cnst0 * Xi0p12_dVds ;
Qb0_dVg = cnst0 * Xi0p12_dVgs ;
T1 = 1.0 / ( fs02 + Xi0p12 ) ;
Qn0 = cnst0 * fs01 * T1 ;
T2 = 1.0 / ( fs01 + epsm10 ) ;
Qn0_dVbs = Qn0 * ( fs01_dVbs * T2 - ( fs02_dVbs + Xi0p12_dVbs ) * T1 ) ;
Qn0_dVds = Qn0 * ( fs01_dVds * T2 - ( fs02_dVds + Xi0p12_dVds ) * T1 ) ;
Qn0_dVgs = Qn0 * ( fs01_dVgs * T2 - ( fs02_dVgs + Xi0p12_dVgs ) * T1 ) ;
/*-----------------------------------------------------------*
* zone-D1 and D2
*-----------------*/
if ( Chi < znbd5 ) {
if ( Chi < znbd3 ) {
/*-------------------------------------------*
* zone-D1. (Ps0)
*-----------------*/
flg_zone = 1 ;
flg_noqi = 1 ; /** !! to be revisited !! **/
Qiu = Qn0 ;
Qiu_dVbs = Qn0_dVbs ;
Qiu_dVds = Qn0_dVds ;
Qiu_dVgs = Qn0_dVgs ;
Qbu = Qb0 ;
Qbu_dVbs = Qb0_dVb ;
Qbu_dVds = Qb0_dVd ;
Qbu_dVgs = Qb0_dVg ;
Qdrat = 0.5 ;
Qdrat_dVbs = 0.0 ;
Qdrat_dVds = 0.0 ;
Qdrat_dVgs = 0.0 ;
Lred = 0.0e0 ;
Lred_dVbs = 0.0e0 ;
Lred_dVds = 0.0e0 ;
Lred_dVgs = 0.0e0 ;
} else {
/*-------------------------------------------*
* zone-D2 (Ps0)
*-----------------*/
flg_zone = 2 ;
flg_noqi = 0 ;
/*-----------------------------------------------------------*
* FD2 : connecting function for zone-D2.
* - Qiu, Qbu, Qdrat and Lred should be interpolated later.
*-----------------*/
T1 = 1.0 / ( znbd5 - znbd3 ) ;
TX = T1 * ( Chi - znbd3 ) ;
TX_dVbs = beta * T1 * ( Ps0_dVbs - 1.0 ) ;
TX_dVds = beta * T1 * Ps0_dVds ;
TX_dVgs = beta * T1 * Ps0_dVgs ;
FD2 = TX * TX * TX * ( 10.0 + TX * ( -15.0 + TX * 6.0 ) ) ;
T4 = TX * TX * ( 30.0 + TX * ( -60.0 + TX * 30.0 ) ) ;
FD2_dVbs = T4 * TX_dVbs ;
FD2_dVds = T4 * TX_dVds ;
FD2_dVgs = T4 * TX_dVgs ;
} /* end of zone-D2 */
}
/*---------------------------------------------------*
* VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. )
*-----------------*/
VgVt = Qn0 * Cox_inv ;
VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVb ;
VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVd ;
VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVg ;
/*-----------------------------------------------------------*
* make Qi=Qd=Ids=0 if VgVt <= VgVt_small
*-----------------*/
if ( VgVt <= VgVt_small && model->HSM2_bypass_enable ) {
flg_zone = 4 ;
flg_noqi = 1 ;
Psl = Ps0 ;
Psl_dVbs = Ps0_dVbs ;
Psl_dVds = Ps0_dVds ;
Psl_dVgs = Ps0_dVgs ;
Pds = 0.0 ;
Pds_dVbs = 0.0 ;
Pds_dVds = 0.0 ;
Pds_dVgs = 0.0 ;
Qbu = Qb0 ;
Qbu_dVbs = Qb0_dVb ;
Qbu_dVds = Qb0_dVd ;
Qbu_dVgs = Qb0_dVg ;
Qiu = 0.0 ;
Qiu_dVbs = 0.0 ;
Qiu_dVds = 0.0 ;
Qiu_dVgs = 0.0 ;
Qdrat = 0.5 ;
Qdrat_dVbs = 0.0 ;
Qdrat_dVds = 0.0 ;
Qdrat_dVgs = 0.0 ;
Lred = 0.0 ;
Lred_dVbs = 0.0 ;
Lred_dVds = 0.0 ;
Lred_dVgs = 0.0 ;
Ids = 0.0e0 ;
Ids_dVbs = 0.0e0 ;
Ids_dVds = 0.0e0 ;
Ids_dVgs = 0.0e0 ;
DJI = 1.0 ;
if( corecip ){
Fs0_dPS0Z = Vgp_dPS0Z ;
Ps0_dPS0Z = - Fs0_dPS0Z / Fs0_dPs0 ;
T1 = Vds * 0.5 ;
Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ;
T2 /= 2 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = T2 * ( 1.0 ) ;
Pzadd_dVgs = 0.0 ;
Pzadd_dPS0Z = 0.0 ;
if ( Pzadd < epsm10 ) {
Pzadd = epsm10 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = 0.0 ;
Pzadd_dVgs = 0.0 ;
Pzadd_dPS0Z = 0.0 ;
}
Ps0z = Ps0 + Pzadd ;
Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ;
Ps0z_dVds = Ps0_dVds + Pzadd_dVds ;
Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ;
Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ;
/* calculate Newton correction: */
G = PS0Z_SCE - Ps0z ;
delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ;
delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs;
delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds;
delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs;
PS0Z_SCE += delta_PS0Z_SCE ;
PS0Z_SCE_dVbs = Ps0z_dVbs ;
PS0Z_SCE_dVds = Ps0z_dVds ;
PS0Z_SCE_dVgs = Ps0z_dVgs ;
PS0_SCE = PS0Z_SCE - Pzadd ;
PS0_SCE_dVbs = Ps0_dVbs ;
PS0_SCE_dVds = Ps0_dVds ;
PS0_SCE_dVgs = Ps0_dVgs ;
NNN += 1 ;
if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol
|| fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol
) && (NNN < MAX_LOOP_SCE) ){
//go to START_OF_SCE_LOOP;
START_OF_SCE_LOOP = 1 ;
}
}
//goto end_of_part_1 ;
if( START_OF_SCE_LOOP==0 ) end_of_part_1 = 1 ;
}
} /* skip end_of_part_1 */
} /* End of 2nd SCE_LOOP */
if( end_of_part_1 == 0 ) { /* skip to end_of_part_1 */
/*-----------------------------------------------------------*
* Start point of Psl (= Ps0 + Pds) calculation. (label)
*-----------------*/
/* start_of_Psl:*/
/* Vdseff (begin) */
Vdsorg = Vds ;
T2 = here->HSM2_qnsub_esi / ( Cox * Cox ) ;
T4 = - 2.0e0 * T2 / Cox ;
T2_dVb = T4 * Cox_dVb ;
T2_dVd = T4 * Cox_dVd ;
T2_dVg = T4 * Cox_dVg ;
T5 = Vgpz - beta_inv - Vbsz ;
T5_dVb = Vgpz_dVbs - Vbsz_dVbs ;
T5_dVd = Vgpz_dVds - Vbsz_dVds ;
T5_dVg = Vgpz_dVgs ;
T0 = 2.0 / T2 ;
T1 = 1.0e0 + T0 * T5 ;
T1_dVb = ( T5_dVb * T2 - T5 * T2_dVb ) * T0 / T2 ;
T1_dVd = ( T5_dVd * T2 - T5 * T2_dVd ) * T0 / T2 ;
T1_dVg = ( T5_dVg * T2 - T5 * T2_dVg ) * T0 / T2 ;
Fn_SZ( T1 , T1 , 0.05 , T9 ) ;
T1 += small ;
T1_dVb *= T9 ;
T1_dVd *= T9 ;
T1_dVg *= T9 ;
T3 = sqrt( T1 ) ;
T3_dVb = 0.5 / T3 * T1_dVb ;
T3_dVd = 0.5 / T3 * T1_dVd ;
T3_dVg = 0.5 / T3 * T1_dVg ;
T10 = Vgpz + T2 * ( 1.0e0 - T3 ) ;
T10_dVb = Vgpz_dVbs + T2_dVb * ( 1.0e0 - T3 ) - T2 * T3_dVb ;
T10_dVd = Vgpz_dVds + T2_dVd * ( 1.0e0 - T3 ) - T2 * T3_dVd ;
T10_dVg = Vgpz_dVgs + T2_dVg * ( 1.0e0 - T3 ) - T2 * T3_dVg ;
Fn_SZ( T10 , T10 , 0.01 , T0 ) ;
T10 += epsm10 ;
T10_dVb *= T0 ;
T10_dVd *= T0 ;
T10_dVg *= T0 ;
T1 = Vds / T10 ;
T2 = Fn_Pow( T1 , here->HSM2_ddlt - 1.0e0 ) ;
T7 = T2 * T1 ;
T0 = here->HSM2_ddlt * T2 / ( T10 * T10 ) ;
T7_dVb = T0 * ( - Vds * T10_dVb ) ;
T7_dVd = T0 * ( T10 - Vds * T10_dVd ) ;
T7_dVg = T0 * ( - Vds * T10_dVg ) ;
T3 = 1.0 + T7 ;
T4 = Fn_Pow( T3 , 1.0 / here->HSM2_ddlt - 1.0 ) ;
T6 = T4 * T3 ;
T0 = T4 / here->HSM2_ddlt ;
T6_dVb = T0 * T7_dVb ;
T6_dVd = T0 * T7_dVd ;
T6_dVg = T0 * T7_dVg ;
Vdseff = Vds / T6 ;
T0 = 1.0 / ( T6 * T6 ) ;
Vdseff_dVbs = - Vds * T6_dVb * T0 ;
Vdseff_dVds = ( T6 - Vds * T6_dVd ) * T0 ;
Vdseff_dVgs = - Vds * T6_dVg * T0 ;
Vds = Vdseff ;
/* Vdseff (end) */
exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ;
/*---------------------------------------------------*
* Skip Psl calculation when Vds is very small.
*-----------------*/
if ( Vds <= 0.0 ) {
Pds = 0.0 ;
Psl = Ps0 ;
flg_conv = 1 ;
goto start_of_loopl ;
}
/*-----------------------------------------------------------*
* Initial guess for Pds ( = Psl - Ps0 ).
*-----------------*/
if ( flg_pprv >= 1 ) {
/*---------------------------------------------------*
* Use previous value.
*-----------------*/
T1 = Pds_dVbs * dVbs + Pds_dVds * dVds + Pds_dVgs * dVgs ;
Pds_ini = Pds + T1 ;
if ( flg_pprv == 2 ) {
/* TX_dVxs = d^2 Pds / d Vxs^2 here */
if ( Vbsc_dif2 > epsm10 ) {
TX_dVbs = ( here->HSM2_pds_dvbs_prv - here->HSM2_pds_dvbs_prv2 )
/ Vbsc_dif2 ;
} else {
TX_dVbs = 0.0 ;
}
if ( Vdsc_dif2 > epsm10 ) {
TX_dVds = ( here->HSM2_pds_dvds_prv - here->HSM2_pds_dvds_prv2 )
/ Vdsc_dif2 ;
} else {
TX_dVds = 0.0 ;
}
if ( Vgsc_dif2 > epsm10 ) {
TX_dVgs = ( here->HSM2_pds_dvgs_prv - here->HSM2_pds_dvgs_prv2 )
/ Vgsc_dif2 ;
} else {
TX_dVgs = 0.0 ;
}
T2 = ( dVbs * dVbs ) / 2 * TX_dVbs
+ ( dVds * dVds ) / 2 * TX_dVds
+ ( dVgs * dVgs ) / 2 * TX_dVgs ;
if ( fabs( T2 ) < fabs( 0.5 * T1 ) ) {
Pds_ini += T2 ;
} else {
flg_pprv = 1 ;
}
}
T1 = Pds_ini - Pds ;
if ( T1 < - dP_max || T1 > dP_max ) flg_pprv = 0 ; /* flag changes */
} /* end of (flg_pprv>=1) if-block */
if ( flg_pprv == 0 ) {
/*---------------------------------------------------*
* Analytical initial guess.
*-----------------*/
Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ) ;
Fn_SU( Pds_ini , Vds, (1.0e0 + c_pslini_1) * Pds_max, c_pslini_2, T1 ) ;
Pds_ini = Fn_Min( Pds_ini , Pds_max ) ;
}
if ( Pds_ini < 0.0 ) Pds_ini = 0.0 ;
else if ( Pds_ini > Vds ) Pds_ini = Vds ;
/*---------------------------------------------------*
* Assign initial guess.
*-----------------*/
if ( NNN == 0 ) {
Pds = Pds_ini ;
Psl = Ps0 + Pds ;
} else {
/* take solution from previous PS0_SCE_loop as initial value */
Pds = Psl - Ps0 ;
}
TX = Vbs + ps_conv / 2 ;
if ( Psl < TX ) Psl = TX ;
/*---------------------------------------------------*
* Calculation of Psl by solving Poisson eqn.
* (beginning of Newton loop)
* - Fsl : Fsl = 0 is the equation to be solved.
* - dPsl : correction value.
*-----------------*/
flg_conv = 0 ;
/*---------------------------------------------------*
* start of Psl calculation. (label)
*-----------------*/
start_of_loopl:
for ( lp_sl = 1 ; lp_sl <= lp_sl_max + 1 ; lp_sl ++ ) {
Chi = beta * ( Psl - Vbs ) ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D2. (Psl)
* - Qb0 is approximated to 5-degree polynomial.
*-----------------*/
fi = Chi * Chi * Chi
* ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ;
fi_dChi = Chi * Chi
* ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ;
cfs1 = cnst1 * exp_bVbsVds ;
fsl1 = cfs1 * fi * fi ;
fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ;
fb = Chi * ( cn_nc51
+ Chi * ( cn_nc52
+ Chi * ( cn_nc53
+ Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ;
fb_dChi = cn_nc51
+ Chi * ( 2 * cn_nc52
+ Chi * ( 3 * cn_nc53
+ Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ;
fsl2 = sqrt( fb * fb + fsl1 ) ;
fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) / ( fsl2 + fsl2 ) ;
} else {
/*-------------------------------------------*
* zone-D3. (Psl)
*-----------------*/
Rho = beta * ( Psl - Vds ) ;
exp_Rho = exp( Rho ) ;
fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ;
fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ;
Xil = Chi - 1.0e0 ;
fsl2 = sqrt( Xil + fsl1 ) ;
fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ;
}
Fsl = Vgp - Psl - fac1 * fsl2 ;
Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ;
if ( flg_conv == 1 ) break ;
dPsl = - Fsl / Fsl_dPsl ;
/*-------------------------------------------*
* Update Psl .
* - clamped to Vbs if Psl < Vbs .
*-----------------*/
dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Psl))) ;
if ( fabs( dPsl ) > dPlim ) dPsl = dPlim * Fn_Sgn( dPsl ) ;
Psl = Psl + dPsl ;
TX = Vbs + ps_conv / 2 ;
if ( Psl < TX ) Psl = TX ;
/*-------------------------------------------*
* Check convergence.
* NOTE: This condition may be too rigid.
*-----------------*/
if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) {
flg_conv = 1 ;
}
} /* end of Psl Newton loop */
/* Eliminate loop count to take account of the derivative loop */
lp_sl -- ;
/*-------------------------------------------*
* Procedure for diverged case.
*-----------------*/
if ( flg_conv == 0 ) {
fprintf( stderr ,
"*** warning(HiSIM): Went Over Iteration Maximum (Psl)\n" ) ;
fprintf( stderr ,
" Vbse = %7.3f Vdse = %7.3f Vgse = %7.3f\n" ,
Vbse , Vdse , Vgse ) ;
if ( flg_info >= 2 ) {
printf("*** warning(HiSIM): Went Over Iteration Maximum (Psl)\n" ) ;
}
}
/*---------------------------------------------------*
* Evaluate derivatives of Psl.
* - note: Here, fsl1_dVbs and fsl2_dVbs are derivatives
* w.r.t. explicit Vbs. So, Psl in the fsl1 and fsl2
* expressions is regarded as a constant.
*-----------------*/
if ( Chi < znbd5 ) {
T1 = cfs1 * beta * fi ;
fsl1_dVbs = T1 * ( ( 1.0 - Vdseff_dVbs ) * fi - 2.0 * fi_dChi ) ;
fsl1_dVds = - T1 * fi * Vdseff_dVds ;
fsl1_dVgs = - T1 * fi * Vdseff_dVgs ;
T2 = 0.5 / fsl2 ;
fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ;
fsl2_dVds = fsl1_dVds * T2 ;
fsl2_dVgs = fsl1_dVgs * T2 ;
} else {
T1 = cnst1 * beta ;
fsl1_dVbs = - T1 * ( exp_Rho * Vdseff_dVbs
+ ( 1.0 - Vdseff_dVbs ) * exp_bVbsVds );
fsl1_dVds = - T1 * Vdseff_dVds * ( exp_Rho - exp_bVbsVds );
fsl1_dVgs = T1 * Vdseff_dVgs * ( - exp_Rho + exp_bVbsVds );
T2 = 0.5e0 / fsl2 ;
fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ;
fsl2_dVds = ( fsl1_dVds ) * T2 ;
fsl2_dVgs = ( fsl1_dVgs ) * T2 ;
}
T1 = 1.0 / Fsl_dPsl ;
Psl_dVbs = - ( Vgp_dVbs - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) ) * T1 ;
Psl_dVds = - ( Vgp_dVds - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) ) * T1 ;
Psl_dVgs = - ( Vgp_dVgs - ( fac1 * fsl2_dVgs + fac1_dVgs * fsl2 ) ) * T1 ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D1/D2. (Psl)
*-----------------*/
Xil = fb * fb + epsm10 ;
T1 = 2 * fb * fb_dChi * beta ;
Xil_dVbs = T1 * ( Psl_dVbs - 1.0 ) ;
Xil_dVds = T1 * Psl_dVds ;
Xil_dVgs = T1 * Psl_dVgs ;
Xilp12 = fb + epsm10 ;
T1 = fb_dChi * beta ;
Xilp12_dVbs = T1 * ( Psl_dVbs - 1.0 ) ;
Xilp12_dVds = T1 * Psl_dVds ;
Xilp12_dVgs = T1 * Psl_dVgs ;
Xilp32 = fb * fb * fb + epsm10 ;
T1 = 3 * fb * fb * fb_dChi * beta ;
Xilp32_dVbs = T1 * ( Psl_dVbs - 1.0 ) ;
Xilp32_dVds = T1 * Psl_dVds ;
Xilp32_dVgs = T1 * Psl_dVgs ;
} else {
/*-------------------------------------------*
* zone-D3. (Psl)
*-----------------*/
Xil = Chi - 1.0e0 ;
Xil_dVbs = beta * ( Psl_dVbs - 1.0e0 ) ;
Xil_dVds = beta * Psl_dVds ;
Xil_dVgs = beta * Psl_dVgs ;
Xilp12 = sqrt( Xil ) ;
T1 = 0.5e0 / Xilp12 ;
Xilp12_dVbs = T1 * Xil_dVbs ;
Xilp12_dVds = T1 * Xil_dVds ;
Xilp12_dVgs = T1 * Xil_dVgs ;
Xilp32 = Xil * Xilp12 ;
T1 = 1.5e0 * Xilp12 ;
Xilp32_dVbs = T1 * Xil_dVbs ;
Xilp32_dVds = T1 * Xil_dVds ;
Xilp32_dVgs = T1 * Xil_dVgs ;
}
/*---------------------------------------------------*
* Assign Pds.
*-----------------*/
Pds = Psl - Ps0 ;
if ( Pds < 0.0 ) {
Pds = 0.0 ;
Psl = Ps0 ;
}
Pds_dVbs = Psl_dVbs - Ps0_dVbs ;
Pds_dVds = Psl_dVds - Ps0_dVds ;
Pds_dVgs = Psl_dVgs - Ps0_dVgs ;
if ( Pds < ps_conv ) {
Pds_dVbs = 0.0 ;
Pds_dVgs = 0.0 ;
Psl_dVbs = Ps0_dVbs ;
Psl_dVgs = Ps0_dVgs ;
}
/* Vdseff */
Vds = Vdsorg;
if( corecip ){
/* For multi level Newton method to calculate PS0Z_SCE */
/* remember that for the inner Newton: */
/* Fs0(PS0Z_SCE,Ps0) = Vgp(PSOZ_SCE) - Ps0 - fac1 * fs02(Ps0) */
/* -> dPs0/dPS0Z_SCE = - (dFs0/dPS0Z_SCE) / (dFs0/dPs0) */
/* and */
/* Fsl(PS0Z_SCE,Psl) = Vgp(PS0Z_SCE) - Psl - fac1 * fsl1(Psl) */
/* -> dPsl/dPS0Z_SCE = - (dFsl/dPS0Z_SCE) / (dFsl/dPsl) */
/* Outer Newton: */
/* PS0Z_SCE = Ps0 + Pzadd(Ps0,Psl) */
/* -> G(PS0Z_SCE) := PS0Z_SCE - Ps0(PS0Z_SCE) - Pzadd(Ps0(PS0Z_SCE),Psl(Ps0Z_SCE)) = 0 */
/* -> Newton correction delta_PS0Z_SCE from: */
/* (1.0 - dPs0/dPS0Z_SCE - dPzadd/dPS0Z_SCE) * delta_PS0Z_SCE = - G */
Fs0_dPS0Z = Vgp_dPS0Z ;
Ps0_dPS0Z = - Fs0_dPS0Z / Fs0_dPs0 ;
Fsl_dPS0Z = Vgp_dPS0Z ;
Psl_dPS0Z = - Fsl_dPS0Z / Fsl_dPsl ;
if ( Pds < ps_conv ) {
Pds_dPS0Z = 0.0 ;
} else {
Pds_dPS0Z = Psl_dPS0Z - Ps0_dPS0Z ;
}
T1 = ( Vds - Pds ) / 2 ;
Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ;
T2 /= 2 ;
Pzadd_dVbs = T2 * ( - Pds_dVbs ) ;
Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ;
Pzadd_dVgs = T2 * ( - Pds_dVgs ) ;
Pzadd_dPS0Z = T2 * ( - Pds_dPS0Z) ;
if ( Pzadd < epsm10 ) {
Pzadd = epsm10 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = 0.0 ;
Pzadd_dVgs = 0.0 ;
Pzadd_dPS0Z = 0.0 ;
}
Ps0z = Ps0 + Pzadd ;
Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ;
Ps0z_dVds = Ps0_dVds + Pzadd_dVds ;
Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ;
Ps0z_dPS0Z = Ps0_dPS0Z + Pzadd_dPS0Z ;
/* calculate Newton correction: */
G = PS0Z_SCE - Ps0z ;
delta_PS0Z_SCE = - G / (1.0 - Ps0z_dPS0Z) ;
delta_PS0Z_SCE_dVbs = Ps0z_dVbs - PS0Z_SCE_dVbs;
delta_PS0Z_SCE_dVds = Ps0z_dVds - PS0Z_SCE_dVds;
delta_PS0Z_SCE_dVgs = Ps0z_dVgs - PS0Z_SCE_dVgs;
PS0Z_SCE += delta_PS0Z_SCE ;
PS0Z_SCE_dVbs = Ps0z_dVbs ;
PS0Z_SCE_dVds = Ps0z_dVds ;
PS0Z_SCE_dVgs = Ps0z_dVgs ;
PS0_SCE = PS0Z_SCE - Pzadd ;
PS0_SCE_dVbs = Ps0_dVbs ;
PS0_SCE_dVds = Ps0_dVds ;
PS0_SCE_dVgs = Ps0_dVgs ;
NNN += 1 ;
if( ( fabs(delta_PS0Z_SCE) > PS0_SCE_tol
|| fabs(delta_PS0Z_SCE_dVbs) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVds) > PS0_SCE_deriv_tol
|| fabs(delta_PS0Z_SCE_dVgs) > PS0_SCE_deriv_tol
) && (NNN < MAX_LOOP_SCE) ){
// goto START_OF_SCE_LOOP;
START_OF_SCE_LOOP = 1 ;
}
}
} /* skip end_of_part_1 */
} /* End of 1st SCE_LOOP */
if ( end_of_part_1 == 0 ) { /* skip to end_of_part_1 */
/*-----------------------------------------------------------*
* Evaluate Idd.
* - Eta : substantial variable of QB'/Pds and Idd/Pds.
* - note: Eta = 4 * GAMMA_{hisim_0}
*-----------------*/
T1 = beta / Xi0 ;
Eta = T1 * Pds ;
T2 = Eta * beta_inv ;
Eta_dVbs = T1 * ( Pds_dVbs - Xi0_dVbs * T2 ) ;
Eta_dVds = T1 * ( Pds_dVds - Xi0_dVds * T2 ) ;
Eta_dVgs = T1 * ( Pds_dVgs - Xi0_dVgs * T2 ) ;
/* ( Eta + 1 )^n */
Eta1 = Eta + 1.0e0 ;
Eta1p12 = sqrt( Eta1 ) ;
Eta1p32 = Eta1p12 * Eta1 ;
Eta1p52 = Eta1p32 * Eta1 ;
/* 1 / ( ( Eta + 1 )^n + 1 ) */
Zeta12 = 1.0e0 / ( Eta1p12 + 1.0e0 ) ;
Zeta32 = 1.0e0 / ( Eta1p32 + 1.0e0 ) ;
Zeta52 = 1.0e0 / ( Eta1p52 + 1.0e0 ) ;
/*---------------------------------------------------*
* F00 := PS00/Pds (n=1/2)
*-----------------*/
F00 = Zeta12 / Xi0p12 ;
T3 = - 1 / Xi0 ;
T4 = - 0.5e0 / Eta1p12 * F00 ;
T5 = Zeta12 * T3 ;
T6 = Zeta12 * T4 ;
F00_dVbs = ( Xi0p12_dVbs * T5 + Eta_dVbs * T6 ) ;
F00_dVds = ( Xi0p12_dVds * T5 + Eta_dVds * T6 ) ;
F00_dVgs = ( Xi0p12_dVgs * T5 + Eta_dVgs * T6 ) ;
/*---------------------------------------------------*
* F10 := PS10/Pds (n=3/2)
*-----------------*/
T1 = 3.0e0 + Eta * ( 3.0e0 + Eta ) ;
F10 = C_2o3 * Xi0p12 * Zeta32 * T1 ;
T2 = 3.0e0 + Eta * 2.0e0 ;
T3 = C_2o3 * T1 ;
T4 = - 1.5e0 * Eta1p12 * F10 + C_2o3 * Xi0p12 * T2 ;
T5 = Zeta32 * T3 ;
T6 = Zeta32 * T4 ;
F10_dVbs = ( Xi0p12_dVbs * T5 + Eta_dVbs * T6 ) ;
F10_dVds = ( Xi0p12_dVds * T5 + Eta_dVds * T6 ) ;
F10_dVgs = ( Xi0p12_dVgs * T5 + Eta_dVgs * T6 ) ;
/*---------------------------------------------------*
* F30 := PS30/Pds (n=5/2)
*-----------------*/
T1 = 5e0 + Eta * ( 10e0 + Eta * ( 10e0 + Eta * ( 5e0 + Eta ) ) ) ;
F30 = 4e0 / ( 15e0 * beta ) * Xi0p32 * Zeta52 * T1 ;
T2 = 10e0 + Eta * ( 20e0 + Eta * ( 15e0 + Eta * 4e0 ) ) ;
T3 = 4e0 / ( 15e0 * beta ) * T1 ;
T4 = - ( 5e0 / 2e0 ) * Eta1p32 * F30 + 4e0 / ( 15e0 * beta ) * Xi0p32 * T2 ;
T5 = Zeta52 * T3 ;
T6 = Zeta52 * T4 ;
F30_dVbs = ( Xi0p32_dVbs * T5 + Eta_dVbs * T6 ) ;
F30_dVds = ( Xi0p32_dVds * T5 + Eta_dVds * T6 ) ;
F30_dVgs = ( Xi0p32_dVgs * T5 + Eta_dVgs * T6 ) ;
/*---------------------------------------------------*
* F11 := PS11/Pds.
*-----------------*/
F11 = Ps0 * F10 + C_2o3 * beta_inv * Xilp32 - F30 ;
T1 = C_2o3 * beta_inv ;
F11_dVbs = Ps0_dVbs * F10 + Ps0 * F10_dVbs
+ T1 * Xilp32_dVbs - F30_dVbs ;
F11_dVds = Ps0_dVds * F10 + Ps0 * F10_dVds
+ T1 * Xilp32_dVds - F30_dVds ;
F11_dVgs = Ps0_dVgs * F10 + Ps0 * F10_dVgs
+ T1 * Xilp32_dVgs - F30_dVgs ;
/*---------------------------------------------------*
* Fdd := Idd/Pds.
*-----------------*/
T1 = Vgp + beta_inv - 0.5e0 * ( 2.0e0 * Ps0 + Pds ) ;
T2 = - F10 + F00 ;
T3 = beta * Cox ;
T4 = beta * cnst0 ;
Fdd = T3 * T1 + T4 * T2 ;
Fdd_dVbs = T3 * ( Vgp_dVbs - Ps0_dVbs - 0.5e0 * Pds_dVbs )
+ beta * Cox_dVb * T1 + T4 * ( - F10_dVbs + F00_dVbs ) ;
Fdd_dVds = T3 * ( Vgp_dVds - Ps0_dVds - 0.5e0 * Pds_dVds )
+ beta * Cox_dVd * T1 + T4 * ( - F10_dVds + F00_dVds ) ;
Fdd_dVgs = T3 * ( Vgp_dVgs - Ps0_dVgs - 0.5e0 * Pds_dVgs )
+ beta * Cox_dVg * T1 + T4 * ( - F10_dVgs + F00_dVgs ) ;
/*---------------------------------------------------*
* Idd:
*-----------------*/
Idd = Pds * Fdd ;
Idd_dVbs = Pds_dVbs * Fdd + Pds * Fdd_dVbs ;
Idd_dVds = Pds_dVds * Fdd + Pds * Fdd_dVds ;
Idd_dVgs = Pds_dVgs * Fdd + Pds * Fdd_dVgs ;
/*-----------------------------------------------------------*
* Skip CLM and integrated charges if zone==D1
*-----------------*/
if( flg_zone == 1 ) {
goto start_of_mobility ;
}
/*-----------------------------------------------------------*
* Channel Length Modulation. Lred: \Delta L
*-----------------*/
if( pParam->HSM2_clm2 < epsm10 && pParam->HSM2_clm3 < epsm10 ) {
Lred = 0.0e0 ;
Lred_dVbs = 0.0e0 ;
Lred_dVds = 0.0e0 ;
Lred_dVgs = 0.0e0 ;
Psdl = Psl ;
Psdl_dVbs = Psl_dVbs ;
Psdl_dVds = Psl_dVds ;
Psdl_dVgs = Psl_dVgs ;
if ( Psdl > Ps0 + Vds - epsm10 ) {
Psdl = Ps0 + Vds - epsm10 ;
Psdl_dVbs = Ps0_dVbs ;
Psdl_dVds = Ps0_dVds + 1.0 ;
Psdl_dVgs = Ps0_dVgs ;
}
} else {
T1 = here->HSM2_wdpl ;
T8 = sqrt (Psl - Vbs) ;
Wd = T1 * T8 ;
T9 = 0.5 * T1 / T8 ;
Wd_dVbs = T9 * (Psl_dVbs - 1.0) ;
Wd_dVds = T9 * Psl_dVds ;
Wd_dVgs = T9 * Psl_dVgs ;
T0 = 1.0 / Wd ;
T1 = Qn0 * T0 ;
T2 = pParam->HSM2_clm3 * T1 ;
T3 = pParam->HSM2_clm3 * T0 ;
T2_dVb = T3 * (Qn0_dVbs - T1 * Wd_dVbs) ;
T2_dVd = T3 * (Qn0_dVds - T1 * Wd_dVds) ;
T2_dVg = T3 * (Qn0_dVgs - T1 * Wd_dVgs) ;
T5 = pParam->HSM2_clm2 * q_Nsub + T2 ;
T1 = 1.0 / T5 ;
T4 = C_ESI * T1 ;
T4_dVb = - T4 * T2_dVb * T1 ;
T4_dVd = - T4 * T2_dVd * T1 ;
T4_dVg = - T4 * T2_dVg * T1 ;
T1 = (1.0e0 - pParam->HSM2_clm1) ;
Psdl = pParam->HSM2_clm1 * (Vds + Ps0) + T1 * Psl ;
Psdl_dVbs = pParam->HSM2_clm1 * Ps0_dVbs + T1 * Psl_dVbs ;
Psdl_dVds = pParam->HSM2_clm1 * (1.0 + Ps0_dVds) + T1 * Psl_dVds ;
Psdl_dVgs = pParam->HSM2_clm1 * Ps0_dVgs + T1 * Psl_dVgs ;
if ( Psdl > Ps0 + Vds - epsm10 ) {
Psdl = Ps0 + Vds - epsm10 ;
Psdl_dVbs = Ps0_dVbs ;
Psdl_dVds = Ps0_dVds + 1.0 ;
Psdl_dVgs = Ps0_dVgs ;
}
T6 = Psdl - Psl ;
T6_dVb = Psdl_dVbs - Psl_dVbs ;
T6_dVd = Psdl_dVds - Psl_dVds ;
T6_dVg = Psdl_dVgs - Psl_dVgs ;
T3 = beta * Qn0 ;
T1 = 1.0 / T3 ;
T5 = Idd * T1 ;
T2 = T5 * beta ;
T5_dVb = (Idd_dVbs - T2 * Qn0_dVbs) * T1 ;
T5_dVd = (Idd_dVds - T2 * Qn0_dVds) * T1 ;
T5_dVg = (Idd_dVgs - T2 * Qn0_dVgs) * T1 ;
T10 = q_Nsub / C_ESI ;
T1 = C_E0_p2 ; // E0^2
T2 = 1.0 / Leff ;
T11 = (2.0 * T5 + 2.0 * T10 * T6 * T4 + T1 * T4) * T2 ;
T3 = T2 * T4 ;
T7 = T11 * T4 ;
T7_dVb = (2.0 * T5_dVb + 2.0 * T10 * (T6_dVb * T4 + T6 * T4_dVb) + T1 * T4_dVb) * T3 + T11 * T4_dVb ;
T7_dVd = (2.0 * T5_dVd + 2.0 * T10 * (T6_dVd * T4 + T6 * T4_dVd) + T1 * T4_dVd) * T3 + T11 * T4_dVd ;
T7_dVg = (2.0 * T5_dVg + 2.0 * T10 * (T6_dVg * T4 + T6 * T4_dVg) + T1 * T4_dVg) * T3 + T11 * T4_dVg ;
T11 = 4.0 * (2.0 * T10 * T6 + T1) ;
T1 = 8.0 * T10 * T4 * T4 ;
T2 = 2.0 * T11 * T4 ;
T8 = T11 * T4 * T4 ;
T8_dVb = ( T1 * T6_dVb + T2 * T4_dVb) ;
T8_dVd = ( T1 * T6_dVd + T2 * T4_dVd) ;
T8_dVg = ( T1 * T6_dVg + T2 * T4_dVg) ;
T9 = sqrt (T7 * T7 + T8);
T1 = 1.0 / T9 ;
T2 = T7 * T1 ;
T3 = 0.5 * T1 ;
T9_dVb = (T2 * T7_dVb + T3 * T8_dVb) ;
T9_dVd = (T2 * T7_dVd + T3 * T8_dVd) ;
T9_dVg = (T2 * T7_dVg + T3 * T8_dVg) ;
Lred = 0.5 * (- T7 + T9) ;
Lred_dVbs = 0.5 * (- T7_dVb + T9_dVb) ;
Lred_dVds = 0.5 * (- T7_dVd + T9_dVd) ;
Lred_dVgs = 0.5 * (- T7_dVg + T9_dVg) ;
/*---------------------------------------------------*
* Modify Lred for symmetry.
*-----------------*/
T1 = Lred ;
Lred = FMDVDS * T1 ;
Lred_dVbs = FMDVDS_dVbs * T1 + FMDVDS * Lred_dVbs ;
Lred_dVds = FMDVDS_dVds * T1 + FMDVDS * Lred_dVds ;
Lred_dVgs = FMDVDS_dVgs * T1 + FMDVDS * Lred_dVgs ;
}
/* CLM5 & CLM6 */
Lred *= here->HSM2_clmmod ;
Lred_dVbs *= here->HSM2_clmmod ;
Lred_dVds *= here->HSM2_clmmod ;
Lred_dVgs *= here->HSM2_clmmod ;
/*---------------------------------------------------*
* Qbu : -Qb in unit area.
*-----------------*/
T1 = Vgp + beta_inv ;
T2 = T1 * F10 - F11 ;
Qbnm = cnst0 * ( cnst0 * ( 1.5e0 - ( Xi0 + 1.0e0 ) - 0.5e0 * beta * Pds )
+ Cox * T2 ) ;
Qbnm_dVbs = cnst0 * ( cnst0 * ( - Xi0_dVbs - 0.5e0 * beta * Pds_dVbs )
+ Cox * ( Vgp_dVbs * F10 + T1 * F10_dVbs - F11_dVbs )
+ Cox_dVb * T2 ) ;
Qbnm_dVds = cnst0 * ( cnst0 * ( - Xi0_dVds - 0.5e0 * beta * Pds_dVds )
+ Cox * ( Vgp_dVds * F10 + T1 * F10_dVds - F11_dVds )
+ Cox_dVd * T2 ) ;
Qbnm_dVgs = cnst0 * ( cnst0 * ( - Xi0_dVgs - 0.5e0 * beta * Pds_dVgs )
+ Cox * ( Vgp_dVgs * F10 + T1 * F10_dVgs - F11_dVgs )
+ Cox_dVg * T2 ) ;
T1 = beta ;
Qbu = T1 * Qbnm / Fdd ;
T2 = T1 / ( Fdd * Fdd ) ;
Qbu_dVbs = T2 * ( Fdd * Qbnm_dVbs - Qbnm * Fdd_dVbs ) ;
Qbu_dVds = T2 * ( Fdd * Qbnm_dVds - Qbnm * Fdd_dVds ) ;
Qbu_dVgs = T2 * ( Fdd * Qbnm_dVgs - Qbnm * Fdd_dVgs ) ;
/*---------------------------------------------------*
* preparation for Qi and Qd.
* - DtPds: Delta * Pds ;
* - Achi: (1+Delta) * Pds ;
*-----------------*/
T1 = 2.0e0 * fac1 ;
DtPds = T1 * ( F10 - Xi0p12 ) ;
T2 = 2.0 * ( F10 - Xi0p12 ) ;
DtPds_dVbs = T1 * ( F10_dVbs - Xi0p12_dVbs )
+ T2 * fac1_dVbs ;
DtPds_dVds = T1 * ( F10_dVds - Xi0p12_dVds )
+ T2 * fac1_dVds ;
DtPds_dVgs = T1 * ( F10_dVgs - Xi0p12_dVgs )
+ T2 * fac1_dVgs ;
Achi = Pds + DtPds ;
Achi_dVbs = Pds_dVbs + DtPds_dVbs ;
Achi_dVds = Pds_dVds + DtPds_dVds ;
Achi_dVgs = Pds_dVgs + DtPds_dVgs ;
/*-----------------------------------------------------------*
* Alpha : parameter to evaluate charges.
* - Achi: (1+Delta) * Pds ;
* - clamped to 0 if Alpha < 0.
*-----------------*/
T1 = 1.0 / VgVt ;
T2 = Achi * T1 ;
T3 = 1.0e0 - T2 ;
TX = 1.0 - T3 ;
Fn_CP( TY , TX , 1.0 , 4 , T4 ) ;
Alpha = 1.0 - TY ;
T5 = T1 * T4 ;
Alpha_dVbs = - ( Achi_dVbs - T2 * VgVt_dVbs ) * T5 ;
Alpha_dVds = - ( Achi_dVds - T2 * VgVt_dVds ) * T5 ;
Alpha_dVgs = - ( Achi_dVgs - T2 * VgVt_dVgs ) * T5 ;
/*-----------------------------------------------------------*
* Qiu : -Qi in unit area.
*-----------------*/
Qinm = 1.0e0 + Alpha * ( 1.0e0 + Alpha ) ;
T1 = 1.0e0 + Alpha + Alpha ;
Qinm_dVbs = Alpha_dVbs * T1 ;
Qinm_dVds = Alpha_dVds * T1 ;
Qinm_dVgs = Alpha_dVgs * T1 ;
Qidn = Fn_Max( 1.0e0 + Alpha , epsm10 ) ;
Qidn_dVbs = Alpha_dVbs ;
Qidn_dVds = Alpha_dVds ;
Qidn_dVgs = Alpha_dVgs ;
T1 = C_2o3 * VgVt * Qinm / Qidn ;
Qiu = T1 * Cox ;
T2 = 1.0 / VgVt ;
T3 = 1.0 / Qinm ;
T4 = 1.0 / Qidn ;
Qiu_dVbs = Qiu * ( VgVt_dVbs * T2 + Qinm_dVbs * T3 - Qidn_dVbs * T4 )
+ T1 * Cox_dVb ;
Qiu_dVds = Qiu * ( VgVt_dVds * T2 + Qinm_dVds * T3 - Qidn_dVds * T4)
+ T1 * Cox_dVd ;
Qiu_dVgs = Qiu * ( VgVt_dVgs * T2 + Qinm_dVgs * T3 - Qidn_dVgs * T4)
+ T1 * Cox_dVg ;
/*-----------------------------------------------------------*
* Qdrat : Qd/Qi
*-----------------*/
Qdnm = 0.5e0 + Alpha ;
Qdnm_dVbs = Alpha_dVbs ;
Qdnm_dVds = Alpha_dVds ;
Qdnm_dVgs = Alpha_dVgs ;
Qddn = Qidn * Qinm ;
Qddn_dVbs = Qidn_dVbs * Qinm + Qidn * Qinm_dVbs ;
Qddn_dVds = Qidn_dVds * Qinm + Qidn * Qinm_dVds ;
Qddn_dVgs = Qidn_dVgs * Qinm + Qidn * Qinm_dVgs ;
Quot = 0.4e0 * Qdnm / Qddn ;
Qdrat = 0.6e0 - Quot ;
if ( Qdrat <= 0.5e0 ) {
T1 = 1.0 / Qddn ;
T2 = 1.0 / Qdnm ;
Qdrat_dVbs = Quot * ( Qddn_dVbs * T1 - Qdnm_dVbs * T2 ) ;
Qdrat_dVds = Quot * ( Qddn_dVds * T1 - Qdnm_dVds * T2 ) ;
Qdrat_dVgs = Quot * ( Qddn_dVgs * T1 - Qdnm_dVgs * T2 ) ;
} else {
Qdrat = 0.5e0 ;
Qdrat_dVbs = 0.0e0 ;
Qdrat_dVds = 0.0e0 ;
Qdrat_dVgs = 0.0e0 ;
}
/*-----------------------------------------------------------*
* Interpolate charges and CLM for zone-D2.
*-----------------*/
if ( flg_zone == 2 ) {
T1 = Qbu ;
Qbu = FD2 * Qbu + ( 1.0 - FD2 ) * Qb0 ;
Qbu_dVbs = FD2 * Qbu_dVbs + FD2_dVbs * T1
+ ( 1.0 - FD2 ) * Qb0_dVb - FD2_dVbs * Qb0 ;
Qbu_dVds = FD2 * Qbu_dVds + FD2_dVds * T1
+ ( 1.0 - FD2 ) * Qb0_dVd - FD2_dVds * Qb0 ;
Qbu_dVgs = FD2 * Qbu_dVgs + FD2_dVgs * T1
+ ( 1.0 - FD2 ) * Qb0_dVg - FD2_dVgs * Qb0 ;
if ( Qbu < 0.0 ) {
Qbu = 0.0 ;
Qbu_dVbs = 0.0 ;
Qbu_dVds = 0.0 ;
Qbu_dVgs = 0.0 ;
}
T1 = Qiu ;
Qiu = FD2 * Qiu + ( 1.0 - FD2 ) * Qn0 ;
Qiu_dVbs = FD2 * Qiu_dVbs + FD2_dVbs * T1
+ ( 1.0 - FD2 ) * Qn0_dVbs - FD2_dVbs * Qn0 ;
Qiu_dVds = FD2 * Qiu_dVds + FD2_dVds * T1
+ ( 1.0 - FD2 ) * Qn0_dVds - FD2_dVds * Qn0 ;
Qiu_dVgs = FD2 * Qiu_dVgs + FD2_dVgs * T1
+ ( 1.0 - FD2 ) * Qn0_dVgs - FD2_dVgs * Qn0 ;
if ( Qiu < 0.0 ) {
Qiu = 0.0 ;
Qiu_dVbs = 0.0 ;
Qiu_dVds = 0.0 ;
Qiu_dVgs = 0.0 ;
}
T1 = Qdrat ;
Qdrat = FD2 * Qdrat + ( 1.0 - FD2 ) * 0.5e0 ;
Qdrat_dVbs = FD2 * Qdrat_dVbs + FD2_dVbs * T1 - FD2_dVbs * 0.5e0 ;
Qdrat_dVds = FD2 * Qdrat_dVds + FD2_dVds * T1 - FD2_dVds * 0.5e0 ;
Qdrat_dVgs = FD2 * Qdrat_dVgs + FD2_dVgs * T1 - FD2_dVgs * 0.5e0 ;
/* note: Lred=0 in zone-D1 */
T1 = Lred ;
Lred = FD2 * Lred ;
Lred_dVbs = FD2 * Lred_dVbs + FD2_dVbs * T1 ;
Lred_dVds = FD2 * Lred_dVds + FD2_dVds * T1 ;
Lred_dVgs = FD2 * Lred_dVgs + FD2_dVgs * T1 ;
} /* end of flg_zone==2 if-block */
start_of_mobility:
Lch = Leff - Lred ;
if ( Lch < 1.0e-9 ) {
Lch = 1.0e-9 ; Lch_dVbs = Lch_dVds = Lch_dVgs = 0.0 ;
} else { Lch_dVbs = - Lred_dVbs ; Lch_dVds = - Lred_dVds ; Lch_dVgs = - Lred_dVgs ; }
/*-----------------------------------------------------------*
* Muun : universal mobility. (CGS unit)
*-----------------*/
T1 = here->HSM2_ndep_o_esi / C_m2cm ; /* fix in version 2.8 */
T2 = here->HSM2_ninv_o_esi / C_m2cm ; /* fix in version 2.8 */
T0 = here->HSM2_ninvd ;
T3 = sqrt(Pds*Pds + model->HSM2_vzadd0) ;
Pdsz = T3 - sqrt(model->HSM2_vzadd0) ;
Pdsz_dVbs = Pds_dVbs * Pds / T3 ;
Pdsz_dVds = Pds_dVds * Pds / T3 ;
Pdsz_dVgs = Pds_dVgs * Pds / T3 ;
T4 = 1.0 + Pdsz * T0 ;
T4_dVb = Pdsz_dVbs * T0 ;
T4_dVd = Pdsz_dVds * T0 ;
T4_dVg = Pdsz_dVgs * T0 ;
T5 = T1 * Qbu + T2 * Qiu ;
T5_dVb = T1 * Qbu_dVbs + T2 * Qiu_dVbs ;
T5_dVd = T1 * Qbu_dVds + T2 * Qiu_dVds ;
T5_dVg = T1 * Qbu_dVgs + T2 * Qiu_dVgs ;
T3 = T5 / T4 ;
T3_dVb = ( - T4_dVb * T5 + T4 * T5_dVb ) / T4 / T4 ;
T3_dVd = ( - T4_dVd * T5 + T4 * T5_dVd ) / T4 / T4 ;
T3_dVg = ( - T4_dVg * T5 + T4 * T5_dVg ) / T4 / T4 ;
Eeff = T3 ;
Eeff_dVbs = T3_dVb ;
Eeff_dVds = T3_dVd ;
Eeff_dVgs = T3_dVg ;
T5 = Fn_Pow( Eeff , model->HSM2_mueph0 - 1.0e0 ) ;
T8 = T5 * Eeff ;
T7 = Fn_Pow( Eeff , here->HSM2_muesr - 1.0e0 ) ;
T6 = T7 * Eeff ;
T9 = C_QE * C_m2cm_p2 ;
Rns = Qiu / T9 ;
T1 = 1.0e0 / ( here->HSM2_muecb0 + here->HSM2_muecb1 * Rns / 1.0e11 )
+ here->HSM2_mphn0 * T8 + T6 / pParam->HSM2_muesr1 ;
Muun = 1.0e0 / T1 ;
T1 = 1.0e0 / ( T1 * T1 ) ;
T2 = here->HSM2_muecb0 + here->HSM2_muecb1 * Rns / 1.0e11 ;
T2 = 1.0e0 / ( T2 * T2 ) ;
T3 = here->HSM2_mphn1 * T5 ;
T4 = here->HSM2_muesr * T7 / pParam->HSM2_muesr1 ;
T5 = - 1.0e-11 * here->HSM2_muecb1 / C_QE * T2 / C_m2cm_p2 ;
Muun_dVbs = - ( T5 * Qiu_dVbs
+ Eeff_dVbs * T3 + Eeff_dVbs * T4 ) * T1 ;
Muun_dVds = - ( T5 * Qiu_dVds
+ Eeff_dVds * T3 + Eeff_dVds * T4 ) * T1 ;
Muun_dVgs = - ( T5 * Qiu_dVgs
+ Eeff_dVgs * T3 + Eeff_dVgs * T4 ) * T1 ;
/* Change to MKS unit */
Muun /= C_m2cm_p2 ;
Muun_dVbs /= C_m2cm_p2 ;
Muun_dVds /= C_m2cm_p2 ;
Muun_dVgs /= C_m2cm_p2 ;
/*-----------------------------------------------------------*
* Mu : mobility
*-----------------*/
T2 = beta * (Qn0 + small) * Lch ;
T1 = 1.0e0 / T2 ;
T3 = T1 * T1 ;
T4 = - beta * T3 ;
T5 = T4 * Lch ;
T6 = T4 * (Qn0 + small) ;
T1_dVb = ( T5 * Qn0_dVbs + T6 * Lch_dVbs) ;
T1_dVd = ( T5 * Qn0_dVds + T6 * Lch_dVds) ;
T1_dVg = ( T5 * Qn0_dVgs + T6 * Lch_dVgs) ;
TY = Idd * T1 ;
TY_dVbs = Idd_dVbs * T1 + Idd * T1_dVb ;
TY_dVds = Idd_dVds * T1 + Idd * T1_dVd ;
TY_dVgs = Idd_dVgs * T1 + Idd * T1_dVg ;
T2 = 0.2 * Vmax / Muun ;
T3 = - T2 / Muun ;
T2_dVb = T3 * Muun_dVbs ;
T2_dVd = T3 * Muun_dVds ;
T2_dVg = T3 * Muun_dVgs ;
Ey = sqrt( TY * TY + T2 * T2 ) ;
T4 = 1.0 / Ey ;
Ey_dVbs = T4 * ( TY * TY_dVbs + T2 * T2_dVb ) ;
Ey_dVds = T4 * ( TY * TY_dVds + T2 * T2_dVd ) ;
Ey_dVgs = T4 * ( TY * TY_dVgs + T2 * T2_dVg ) ;
Em = Muun * Ey ;
Em_dVbs = Muun_dVbs * Ey + Muun * Ey_dVbs ;
Em_dVds = Muun_dVds * Ey + Muun * Ey_dVds ;
Em_dVgs = Muun_dVgs * Ey + Muun * Ey_dVgs ;
T1 = Em / Vmax ;
/* note: model->HSM2_bb = 2 (electron) ;1 (hole) */
if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) {
T3 = 1.0e0 ;
} else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) {
T3 = T1 ;
} else {
T3 = Fn_Pow( T1 , model->HSM2_bb - 1.0e0 ) ;
}
T2 = T1 * T3 ;
T4 = 1.0e0 + T2 ;
if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) {
T5 = 1.0 / T4 ;
T6 = T5 / T4 ;
} else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) {
T5 = 1.0 / sqrt( T4 ) ;
T6 = T5 / T4 ;
} else {
T6 = Fn_Pow( T4 , ( - 1.0e0 / model->HSM2_bb - 1.0e0 ) ) ;
T5 = T4 * T6 ;
}
T7 = Muun / Vmax * T6 * T3 ;
Mu = Muun * T5 ;
Mu_dVbs = Muun_dVbs * T5 - T7 * Em_dVbs ;
Mu_dVds = Muun_dVds * T5 - T7 * Em_dVds ;
Mu_dVgs = Muun_dVgs * T5 - T7 * Em_dVgs ;
/* end_of_mobility : */
/*-----------------------------------------------------------*
* Ids: channel current.
*-----------------*/
betaWL = here->HSM2_weff_nf * beta_inv / Lch ;
T1 = - betaWL / Lch ;
betaWL_dVbs = T1 * Lch_dVbs ;
betaWL_dVds = T1 * Lch_dVds ;
betaWL_dVgs = T1 * Lch_dVgs ;
Ids0 = betaWL * Idd * Mu ;
T1 = betaWL * Idd ;
T2 = Idd * Mu ;
T3 = Mu * betaWL ;
Ids0_dVbs = T3 * Idd_dVbs + T1 * Mu_dVbs + T2 * betaWL_dVbs ;
Ids0_dVds = T3 * Idd_dVds + T1 * Mu_dVds + T2 * betaWL_dVds ;
Ids0_dVgs = T3 * Idd_dVgs + T1 * Mu_dVgs + T2 * betaWL_dVgs ;
/*-----------------------------------------------------------*
* Adding parasitic components to the channel current.
*-----------------*/
if( model->HSM2_ptl != 0 ){
T1 = 0.5 * ( Vds - Pds ) ;
Fn_SymAdd( T6 , T1 , 0.01 , T2 ) ;
T2 *= 0.5 ;
T6_dVb = T2 * ( - Pds_dVbs ) ;
T6_dVd = T2 * ( 1.0 - Pds_dVds ) ;
T6_dVg = T2 * ( - Pds_dVgs ) ;
T1 = 1.1 - ( Ps0 + T6 );
T1_dVb = - ( Ps0_dVbs + T6_dVb );
T1_dVd = - ( Ps0_dVds + T6_dVd );
T1_dVg = - ( Ps0_dVgs + T6_dVg );
Fn_SZ( T2 , T1 , 0.05 , T0 ) ;
T2 += small ;
T2_dVb = T1_dVb * T0 ;
T2_dVd = T1_dVd * T0 ;
T2_dVg = T1_dVg * T0 ;
T0 = beta * here->HSM2_ptl0 ;
T3 = Cox * T0 ;
T3_dVb = Cox_dVb * T0 ;
T3_dVd = Cox_dVd * T0 ;
T3_dVg = Cox_dVg * T0 ;
T0 = pow( T2 , model->HSM2_ptp ) ;
T9 = T3 * T0 ;
T9_dVb = T3 * model->HSM2_ptp * T0 / T2 * T2_dVb + T3_dVb * T0 ;
T9_dVd = T3 * model->HSM2_ptp * T0 / T2 * T2_dVd + T3_dVd * T0 ;
T9_dVg = T3 * model->HSM2_ptp * T0 / T2 * T2_dVg + T3_dVg * T0 ;
T4 = 1.0 + Vdsz * model->HSM2_pt2 ;
T4_dVb = 0.0 ;
T4_dVd = Vdsz_dVds * model->HSM2_pt2 ;
T4_dVg = 0.0 ;
T0 = here->HSM2_pt40 ;
T5 = Ps0 + T6 - Vbsz ;
T5_dVb = Ps0_dVbs + T6_dVb - Vbsz_dVbs ;
T5_dVd = Ps0_dVds + T6_dVd - Vbsz_dVds ;
T5_dVg = Ps0_dVgs + T6_dVg ;
T4 += Vdsz * T0 * T5 ;
T4_dVb += Vdsz * T0 * T5_dVb ;
T4_dVd += Vdsz * T0 * T5_dVd + Vdsz_dVds * T0 * T5 ;
T4_dVg += Vdsz * T0 * T5_dVg ;
T6 = T9 * T4 ;
T9_dVb = T9_dVb * T4 + T9 * T4_dVb ;
T9_dVd = T9_dVd * T4 + T9 * T4_dVd ;
T9_dVg = T9_dVg * T4 + T9 * T4_dVg ;
T9 = T6 ;
}else{
T9 = 0.0 ;
T9_dVb = 0.0 ;
T9_dVd = 0.0 ;
T9_dVg = 0.0 ;
}
if( model->HSM2_gdl != 0 ){
T1 = beta * here->HSM2_gdl0 ;
T2 = Cox * T1 ;
T2_dVb = Cox_dVb * T1 ;
T2_dVd = Cox_dVd * T1 ;
T2_dVg = Cox_dVg * T1 ;
T8 = T2 * Vdsz ;
T8_dVb = T2_dVb * Vdsz ;
T8_dVd = T2_dVd * Vdsz + T2 * Vdsz_dVds ;
T8_dVg = T2_dVg * Vdsz ;
}else{
T8 = 0.0 ;
T8_dVb = 0.0 ;
T8_dVd = 0.0 ;
T8_dVg = 0.0 ;
}
if ( ( T9 + T8 ) > 0.0 ) {
Idd1 = Pds * ( T9 + T8 ) ;
Idd1_dVbs = Pds_dVbs * ( T9 + T8 ) + Pds * ( T9_dVb + T8_dVb ) ;
Idd1_dVds = Pds_dVds * ( T9 + T8 ) + Pds * ( T9_dVd + T8_dVd ) ;
Idd1_dVgs = Pds_dVgs * ( T9 + T8 ) + Pds * ( T9_dVg + T8_dVg ) ;
Ids0 += betaWL * Idd1 * Mu ;
T1 = betaWL * Idd1 ;
T2 = Idd1 * Mu ;
T3 = Mu * betaWL ;
Ids0_dVbs += T3 * Idd1_dVbs + T1 * Mu_dVbs + T2 * betaWL_dVbs ;
Ids0_dVds += T3 * Idd1_dVds + T1 * Mu_dVds + T2 * betaWL_dVds ;
Ids0_dVgs += T3 * Idd1_dVgs + T1 * Mu_dVgs + T2 * betaWL_dVgs ;
}
/* (note: rpock procedure was removed. (2006.04.20) */
if ( flg_rsrd == 2 ) {
Rd = here->HSM2_rd ;
T0 = Rd * Ids0 ;
T1 = Vds + small ;
T2 = 1.0 / T1 ;
T3 = 1.0 + T0 * T2 ;
T3_dVb = Rd * Ids0_dVbs * T2 ;
T3_dVd = ( Rd * Ids0_dVds * T1 - T0 ) * T2 * T2 ;
T3_dVg = Rd * Ids0_dVgs * T2 ;
T4 = 1.0 / T3 ;
Ids = Ids0 * T4 ;
T5 = T4 * T4 ;
Ids_dVbs = ( Ids0_dVbs * T3 - Ids0 * T3_dVb ) * T5 ;
Ids_dVds = ( Ids0_dVds * T3 - Ids0 * T3_dVd ) * T5 ;
Ids_dVgs = ( Ids0_dVgs * T3 - Ids0 * T3_dVg ) * T5 ;
} else {
Ids = Ids0 ;
Ids_dVbs = Ids0_dVbs ;
Ids_dVds = Ids0_dVds ;
Ids_dVgs = Ids0_dVgs ;
}
if ( Pds < ps_conv ) {
Ids_dVbs = 0.0 ;
Ids_dVgs = 0.0 ;
}
Ids += Gdsmin * Vds ;
Ids_dVds += Gdsmin ;
/*-----------------------------------------------------------*
* STI
*-----------------*/
if ( model->HSM2_coisti != 0 ) {
/*---------------------------------------------------*
* dVthSCSTI : Short-channel effect induced by Vds (STI).
*-----------------*/
T1 = C_ESI * Cox_inv ;
T2 = here->HSM2_wdpl ;
T3 = here->HSM2_lgatesm - model->HSM2_parl2 ;
T4 = 1.0 / (T3 * T3) ;
T5 = 2.0 * (model->HSM2_vbi - Pb20b) * T1 * T2 * T4 ;
dVth0 = T5 * sqrt_Pbsum ;
T6 = T5 * 0.5 / sqrt_Pbsum ;
T7 = 2.0 * (model->HSM2_vbi - Pb20b) * C_ESI * T2 * T4 * sqrt_Pbsum ;
T8 = - 2.0 * T1 * T2 * T4 * sqrt_Pbsum ;
dVth0_dVb = T6 * Pbsum_dVb + T7 * Cox_inv_dVb + T8 * Pb20b_dVb ;
dVth0_dVd = T6 * Pbsum_dVd + T7 * Cox_inv_dVd + T8 * Pb20b_dVd ;
dVth0_dVg = T6 * Pbsum_dVg + T7 * Cox_inv_dVg + T8 * Pb20b_dVg ;
T4 = pParam->HSM2_scsti1 ;
T6 = pParam->HSM2_scsti2 ;
T1 = T4 + T6 * Vdsz ;
dVthSCSTI = dVth0 * T1 ;
dVthSCSTI_dVb = dVth0_dVb * T1 ;
dVthSCSTI_dVd = dVth0_dVd * T1 + dVth0 * T6 * Vdsz_dVds ;
dVthSCSTI_dVg = dVth0_dVg * T1 ;
T1 = pParam->HSM2_vthsti - model->HSM2_vdsti * Vds ;
T1_dVd = - model->HSM2_vdsti ;
Vgssti = Vgsz - Vfb + T1 + dVthSCSTI ;
Vgssti_dVbs = dVthSCSTI_dVb ;
Vgssti_dVds = Vgsz_dVds + T1_dVd + dVthSCSTI_dVd ;
Vgssti_dVgs = Vgsz_dVgs + dVthSCSTI_dVg ;
costi0 = here->HSM2_costi0 ;
costi1 = here->HSM2_costi1 ;
costi3 = here->HSM2_costi0_p2 * Cox_inv * Cox_inv ;
T1 = 2.0 * here->HSM2_costi0_p2 * Cox_inv ;
costi3_dVb = T1 * Cox_inv_dVb ;
costi3_dVd = T1 * Cox_inv_dVd ;
costi3_dVg = T1 * Cox_inv_dVg ;
T2 = 1.0 / costi3 ;
costi3_dVb_c3 = costi3_dVb * T2 ;
costi3_dVd_c3 = costi3_dVd * T2 ;
costi3_dVg_c3 = costi3_dVg * T2 ;
costi4 = costi3 * beta * 0.5 ;
costi5 = costi4 * beta * 2.0 ;
T11 = beta * 0.25 ;
T10 = beta_inv - costi3 * T11 + Vfb - pParam->HSM2_vthsti - dVthSCSTI + small ;
T10_dVb = - T11 * costi3_dVb - dVthSCSTI_dVb ;
T10_dVd = - T11 * costi3_dVd - dVthSCSTI_dVd ;
T10_dVg = - T11 * costi3_dVg - dVthSCSTI_dVg ;
T1 = Vgsz - T10 - psisti_dlt ;
T1_dVb = - T10_dVb ;
T1_dVd = Vgsz_dVds - T10_dVd ;
T1_dVg = Vgsz_dVgs - T10_dVg ;
T0 = Fn_Sgn(T10) ;
T2 = sqrt (T1 * T1 + T0 * 4.0 * T10 * psisti_dlt) ;
T3 = T10 + 0.5 * (T1 + T2) - Vfb + pParam->HSM2_vthsti + dVthSCSTI - Vbsz ;
T3_dVb = T10_dVb + 0.5 * (T1_dVb + (T1 * T1_dVb + T0 * 2.0 * T10_dVb * psisti_dlt) / T2)
+ dVthSCSTI_dVb - Vbsz_dVbs ;
T3_dVd = T10_dVd + 0.5 * (T1_dVd + (T1 * T1_dVd + T0 * 2.0 * T10_dVd * psisti_dlt) / T2)
+ dVthSCSTI_dVd - Vbsz_dVds ;
T3_dVg = T10_dVg + 0.5 * (T1_dVg + (T1 * T1_dVg + T0 * 2.0 * T10_dVg * psisti_dlt) / T2)
+ dVthSCSTI_dVg ;
T4 = beta * T3 - 1.0 ;
T5 = 4.0 / costi5 ;
T1 = 1.0 + T4 * T5 ;
T6 = beta * T5 ;
T7 = T4 * T5 ;
T1_dVb = (T6 * T3_dVb - T7 * costi3_dVb_c3) ;
T1_dVd = (T6 * T3_dVd - T7 * costi3_dVd_c3) ;
T1_dVg = (T6 * T3_dVg - T7 * costi3_dVg_c3) ;
Fn_SZ( T1 , T1, 1.0e-2, T2) ;
T1 += small ;
T1_dVb *= T2 ;
T1_dVd *= T2 ;
T1_dVg *= T2 ;
costi6 = sqrt (T1) ;
T0 = costi4 * (1.0 - costi6) ;
Psasti = Vgssti + T0 ;
T2 = 0.5 * costi4 / costi6 ;
Psasti_dVbs = Vgssti_dVbs + costi3_dVb_c3 * T0 - T2 * T1_dVb ;
Psasti_dVds = Vgssti_dVds + costi3_dVd_c3 * T0 - T2 * T1_dVd ;
Psasti_dVgs = Vgssti_dVgs + costi3_dVg_c3 * T0 - T2 * T1_dVg ;
T0 = 1.0 / (beta + 2.0 / (Vgssti + small)) ;
Psbsti = log (1.0 / costi1 / costi3 * (Vgssti * Vgssti)) * T0 ;
T2 = 2.0 * T0 / (Vgssti + small) ;
T3 = Psbsti / (Vgssti + small) ;
Psbsti_dVbs = T2 * (Vgssti_dVbs - 0.5 * costi3_dVb_c3 * Vgssti
+ T3 * Vgssti_dVbs ) ;
Psbsti_dVds = T2 * (Vgssti_dVds - 0.5 * costi3_dVd_c3 * Vgssti
+ T3 * Vgssti_dVds ) ;
Psbsti_dVgs = T2 * (Vgssti_dVgs - 0.5 * costi3_dVg_c3 * Vgssti
+ T3 * Vgssti_dVgs ) ;
Psab = Psbsti - Psasti - sti2_dlt ;
Psab_dVbs = Psbsti_dVbs - Psasti_dVbs ;
Psab_dVds = Psbsti_dVds - Psasti_dVds ;
Psab_dVgs = Psbsti_dVgs - Psasti_dVgs ;
T0 = sqrt (Psab * Psab + 4.0 * sti2_dlt * Psbsti) ;
Psti = Psbsti - 0.5 * (Psab + T0) ;
T1 = 1.0 / T0 ;
Psti_dVbs = Psbsti_dVbs
- 0.5 * ( Psab_dVbs
+ ( Psab * Psab_dVbs + 2.0 * sti2_dlt * Psbsti_dVbs ) * T1 ) ;
Psti_dVds = Psbsti_dVds
- 0.5 * ( Psab_dVds
+ ( Psab * Psab_dVds + 2.0 * sti2_dlt * Psbsti_dVds ) * T1 ) ;
Psti_dVgs = Psbsti_dVgs
- 0.5 * ( Psab_dVgs
+ ( Psab * Psab_dVgs + 2.0 * sti2_dlt * Psbsti_dVgs ) * T1 ) ;
T0 = costi1 * exp (beta * Psti) ;
T1 = beta * (Psti - Vbsz) - 1.0 + T0 ;
T1_dVb = beta * ((Psti_dVbs - Vbsz_dVbs) + T0 * Psti_dVbs) ;
T1_dVd = beta * ((Psti_dVds - Vbsz_dVds) + T0 * Psti_dVds) ;
T1_dVg = beta * (Psti_dVgs + T0 * Psti_dVgs) ;
Fn_SZ ( T1 , T1, 1.0e-2, T0) ;
T1 += epsm10 ;
T1_dVb *= T0 ;
T1_dVd *= T0 ;
T1_dVg *= T0 ;
sq1sti = sqrt (T1);
T2 = 0.5 / sq1sti ;
sq1sti_dVbs = T2 * T1_dVb ;
sq1sti_dVds = T2 * T1_dVd ;
sq1sti_dVgs = T2 * T1_dVg ;
T1 = beta * (Psti - Vbsz) - 1.0;
T1_dVb = beta * (Psti_dVbs - Vbsz_dVbs) ;
T1_dVd = beta * (Psti_dVds - Vbsz_dVds) ;
T1_dVg = beta * Psti_dVgs ;
Fn_SZ( T1 , T1, 1.0e-2, T0) ;
T1 += epsm10 ;
T1_dVb *= T0 ;
T1_dVd *= T0 ;
T1_dVg *= T0 ;
sq2sti = sqrt (T1);
T2 = 0.5 / sq2sti ;
sq2sti_dVbs = T2 * T1_dVb ;
sq2sti_dVds = T2 * T1_dVd ;
sq2sti_dVgs = T2 * T1_dVg ;
Qn0sti = costi0 * (sq1sti - sq2sti) ;
Qn0sti_dVbs = costi0 * (sq1sti_dVbs - sq2sti_dVbs) ;
Qn0sti_dVds = costi0 * (sq1sti_dVds - sq2sti_dVds) ;
Qn0sti_dVgs = costi0 * (sq1sti_dVgs - sq2sti_dVgs) ;
/* T1: Vdsatsti */
T1 = Psasti - Psti ;
T1_dVb = Psasti_dVbs - Psti_dVbs ;
T1_dVd = Psasti_dVds - Psti_dVds ;
T1_dVg = Psasti_dVgs - Psti_dVgs ;
Fn_SZ( T1 , T1 , 1.0e-1 , T2 ) ;
T1 += epsm10 ;
T1_dVb *= T2 ;
T1_dVd *= T2 ;
T1_dVg *= T2 ;
TX = Vds / T1 ;
T2 = 1.0 / ( T1 * T1 ) ;
TX_dVbs = T2 * ( - Vds * T1_dVb ) ;
TX_dVds = T2 * ( T1 - Vds * T1_dVd ) ;
TX_dVgs = T2 * ( - Vds * T1_dVg ) ;
Fn_CP( TY , TX , 1.0 , 4 , T2 ) ;
TY_dVbs = T2 * TX_dVbs ;
TY_dVds = T2 * TX_dVds ;
TY_dVgs = T2 * TX_dVgs ;
costi7 = 2.0 * here->HSM2_wsti * here->HSM2_nf * beta_inv ;
T1 = Lch ;
Idssti = costi7 * Mu * Qn0sti * TY / T1;
T3 = 1.0 / T1 ;
T4 = Mu * Qn0sti * TY / T1 / T1 ;
T5 = Mu * Qn0sti ;
Idssti_dVbs = costi7 * (((Mu_dVbs * Qn0sti + Mu * Qn0sti_dVbs) * TY
+ T5 * TY_dVbs ) * T3
- Lch_dVbs * T4 ) ;
Idssti_dVds = costi7 * (((Mu_dVds * Qn0sti + Mu * Qn0sti_dVds) * TY
+ T5 * TY_dVds ) * T3
- Lch_dVds * T4 ) ;
Idssti_dVgs = costi7 * (((Mu_dVgs * Qn0sti + Mu * Qn0sti_dVgs) * TY
+ T5 * TY_dVgs ) * T3
- Lch_dVgs * T4 ) ;
Ids = Ids + Idssti ;
Ids_dVbs = Ids_dVbs + Idssti_dVbs ;
Ids_dVds = Ids_dVds + Idssti_dVds ;
Ids_dVgs = Ids_dVgs + Idssti_dVgs ;
}
/*-----------------------------------------------------------*
* Break point for the case of Rs=Rd=0.
*-----------------*/
if ( flg_rsrd == 0 ) {
DJI = 1.0 ;
break ;
}
/*-----------------------------------------------------------*
* calculate corrections of biases.
* - Fbs = 0, etc. are the small ciucuit equations.
* - DJ, Jacobian of the small circuit matrix, is g.t. 1
* provided Rs, Rd and conductances are positive.
*-----------------*/
Fbs = Vbs - Vbsc + Ids * Rs ;
Fds = Vds - Vdsc + Ids * ( Rs + Rd ) ;
Fgs = Vgs - Vgsc + Ids * Rs ;
DJ = 1.0 + Rs * Ids_dVbs + ( Rs + Rd ) * Ids_dVds + Rs * Ids_dVgs ;
DJI = 1.0 / DJ ;
JI11 = 1 + ( Rs + Rd ) * Ids_dVds + Rs * Ids_dVgs ;
JI12 = - Rs * Ids_dVds ;
JI13 = - Rs * Ids_dVgs ;
JI21 = - ( Rs + Rd ) * Ids_dVbs ;
JI22 = 1 + Rs * Ids_dVbs + Rs * Ids_dVgs ;
JI23 = - ( Rs + Rd ) * Ids_dVgs ;
JI31 = - Rs * Ids_dVbs ;
JI32 = - Rs * Ids_dVds ;
JI33 = 1 + Rs * Ids_dVbs + ( Rs + Rd ) * Ids_dVds ;
dVbs = - DJI * ( JI11 * Fbs + JI12 * Fds + JI13 * Fgs ) ;
dVds = - DJI * ( JI21 * Fbs + JI22 * Fds + JI23 * Fgs ) ;
dVgs = - DJI * ( JI31 * Fbs + JI32 * Fds + JI33 * Fgs ) ;
dV_sum = fabs( dVbs ) + fabs( dVds ) + fabs( dVgs ) ;
/*-----------------------------------------------------------*
* Break point for converged case.
* - Exit from the bias loop.
* - NOTE: Update of internal biases is avoided.
*-----------------*/
if ( Ids_last * Ids_tol >= fabs( Ids_last - Ids ) || mini_current >= fabs( Ids_last - Ids )
|| dV_sum < ps_conv ) break ;
/*-----------------------------------------------------------*
* Update the internal biases.
*-----------------*/
Vbs = Vbs + dVbs ;
Vds = Vds + dVds ;
Vgs = Vgs + dVgs ;
if ( Vds < 0.0 ) {
Vds = 0.0 ;
dVds = 0.0 ;
}
/*-----------------------------------------------------------*
* Bottom of bias loop. (label)
*-----------------*/
/* bottom_of_bias_loop :*/
/*-----------------------------------------------------------*
* Make initial guess flag of potential ON.
* - This effects for the 2nd and later iterations of bias loop.
*-----------------*/
flg_pprv = 1 ;
} /* skip to end_of_part_1 */
} /*++ End of the bias loop +++++++++++++++++++++++++++++*/
if ( end_of_part_1 == 0 ) {
if ( lp_bs > lp_bs_max ) { lp_bs -- ; }
/*----------------------------------------------------------*
* induced gate noise. ( Part 1/3 )
*----------------------*/
if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 ) {
kusai00 = VgVt * VgVt ;
kusaidd = 2.0e0 * beta_inv * Cox_inv * Idd ;
kusaiL = kusai00 - kusaidd ;
Fn_SZ( kusai00 , kusai00 , 1.0e-3 , T0 ) ;
Fn_SZ( kusaiL , kusaiL , 1.0e-3 , T0 ) ;
kusai00L = kusai00 - kusaiL ;
if ( Qn0 < epsm10 || kusai00L < epsm10 ) flg_ign = 0 ;
else flg_ign = 1 ;
}
/*-----------------------------------------------------------*
* End of PART-1. (label)
*-----------------*/
} /* skip end_of_part_1 */
/* end_of_part_1: */
end_of_part_1 = 0;
// Qiu for noise calcs
Qiu_noi = Qiu ;
} // end of Normal mode MOSFET
/*----------------------------------------------------------*
* Evaluate integrated chages in unit [C].
*----------------------*/
T1 = - here->HSM2_weff_nf * Leff ;
Qb = T1 * Qbu ;
Qb_dVbs = T1 * Qbu_dVbs ;
Qb_dVds = T1 * Qbu_dVds ;
Qb_dVgs = T1 * Qbu_dVgs ;
Qi = T1 * Qiu ;
Qi_dVbs = T1 * Qiu_dVbs ;
Qi_dVds = T1 * Qiu_dVds ;
Qi_dVgs = T1 * Qiu_dVgs ;
Qi_noi = T1 * Qiu_noi ; // for noise calc.
Qd = Qi * Qdrat ;
Qd_dVbs = Qi_dVbs * Qdrat + Qi * Qdrat_dVbs ;
Qd_dVds = Qi_dVds * Qdrat + Qi * Qdrat_dVds ;
Qd_dVgs = Qi_dVgs * Qdrat + Qi * Qdrat_dVgs ;
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-2: Substrate / gate / leak currents
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*-----------------------------------------------------------*
* Modified potential for symmetry.
*-----------------*/
T1 = ( Vds - Pds ) / 2 ;
Fn_SymAdd( Pzadd , T1 , model->HSM2_pzadd0 , T2 ) ;
T2 /= 2 ;
Pzadd_dVbs = T2 * ( - Pds_dVbs ) ;
Pzadd_dVds = T2 * ( 1.0 - Pds_dVds ) ;
Pzadd_dVgs = T2 * ( - Pds_dVgs ) ;
if ( Pzadd < epsm10 ) {
Pzadd = epsm10 ;
Pzadd_dVbs = 0.0 ;
Pzadd_dVds = 0.0 ;
Pzadd_dVgs = 0.0 ;
}
Ps0z = Ps0 + Pzadd ;
Ps0z_dVbs = Ps0_dVbs + Pzadd_dVbs ;
Ps0z_dVds = Ps0_dVds + Pzadd_dVds ;
Ps0z_dVgs = Ps0_dVgs + Pzadd_dVgs ;
/*-----------------------------------------------------------*
* Isub : substrate current induced by impact ionization.
*-----------------*/
if ( flg_noqi == 1 || model->HSM2_coisub == 0 ) {
/* Accumulation zone or nonconductive case, in which Ids==0. */
Isub = 0.0e0 ;
Isub_dVbs = Isub_dVds = Isub_dVgs = 0.0e0 ;
} else {
/*-------------------------------------------*
* Conductive case.
*-----------------*/
if ( pParam->HSM2_sub1 > 0.0e0 && pParam->HSM2_vmax > 0.0e0 ) {
T0 = here->HSM2_vg2const ;
T1 = T0 * Vgp ;
T1_dVd = T0 * Vgp_dVds ;
T1_dVg = T0 * Vgp_dVgs ;
T1_dVb = T0 * Vgp_dVbs ;
T7 = Cox0 * Cox0 ;
T8 = here->HSM2_qnsub_esi ;
T3 = T8 / T7 ;
T9 = 2.0 / T8 ;
T4 = T9 * T7 ; /* bugfix in version 2.80 */
T2 = here->HSM2_xvbs ;
T5 = T1 - beta_inv - T2 * Vbsz ;
T5_dVd = T1_dVd - T2 * Vbsz_dVds;
T5_dVg = T1_dVg ;
T5_dVb = T1_dVb - T2 * Vbsz_dVbs;
T6 = 1.0 + T4 * T5 ; /* bugfix in version 2.80 */
T6_dVd = T4 * T5_dVd ;
T6_dVg = T4 * T5_dVg ;
T6_dVb = T4 * T5_dVb ;
Fn_SZ( T6 , T6, 1.0e-3, T9) ;
T6 += small ;
T6_dVd *= T9 ;
T6_dVg *= T9 ;
T6_dVb *= T9 ;
T6 = sqrt( T6 ) ;
T9 = 0.5 / T6 ;
T6_dVd = T9 * T6_dVd ;
T6_dVg = T9 * T6_dVg ;
T6_dVb = T9 * T6_dVb ;
Psislsat = T1 + T3 * ( 1.0 - T6 ) ;
Psislsat_dVd = T1_dVd - T3 * T6_dVd ;
Psislsat_dVg = T1_dVg - T3 * T6_dVg ;
Psislsat_dVb = T1_dVb - T3 * T6_dVb ;
T2 = here->HSM2_lgate / (here->HSM2_xgate + here->HSM2_lgate) ;
Psisubsat = pParam->HSM2_svds * Vdsz + Ps0z - T2 * Psislsat ;
Psisubsat_dVd = pParam->HSM2_svds * Vdsz_dVds + Ps0z_dVds - T2 * Psislsat_dVd ;
Psisubsat_dVg = Ps0z_dVgs - T2 * Psislsat_dVg ;
Psisubsat_dVb = Ps0z_dVbs - T2 * Psislsat_dVb ;
Fn_SZ( Psisubsat , Psisubsat, 1.0e-3, T9 ) ;
Psisubsat += small ;
Psisubsat_dVd *= T9 ;
Psisubsat_dVg *= T9 ;
Psisubsat_dVb *= T9 ;
T5 = here->HSM2_xsub1 ;
T6 = here->HSM2_xsub2 ;
T2 = exp( - T6 / Psisubsat ) ;
T3 = T2 * T6 / ( Psisubsat * Psisubsat ) ;
T2_dVd = T3 * Psisubsat_dVd ;
T2_dVg = T3 * Psisubsat_dVg ;
T2_dVb = T3 * Psisubsat_dVb ;
Isub = T5 * Psisubsat * Ids * T2 ;
Isub_dVds = T5 * ( Psisubsat_dVd * Ids * T2
+ Psisubsat * Ids_dVds * T2
+ Psisubsat * Ids * T2_dVd ) ;
Isub_dVgs = T5 * ( Psisubsat_dVg * Ids * T2
+ Psisubsat * Ids_dVgs * T2
+ Psisubsat * Ids * T2_dVg ) ;
Isub_dVbs = T5 * ( Psisubsat_dVb * Ids * T2
+ Psisubsat * Ids_dVbs * T2
+ Psisubsat * Ids * T2_dVb ) ;
} else {
Isub = 0.0e0 ;
Isub_dVbs = Isub_dVds = Isub_dVgs = 0.0e0 ;
} /* end of if ( pParam->HSM2_sub1 ... ) else block. */
}
/*---------------------------------------------------*
* Impact-Ionization Induced Bulk Potential Change (IBPC)
*-----------------*/
if ( flg_noqi == 0 && Isub > 0e0 && pParam->HSM2_ibpc1 != 0e0 ) {
/* delta Vbs */
T0 = 1e0 + pParam->HSM2_ibpc2 * dVth ;
dVbsIBPC = pParam->HSM2_ibpc1 * T0 * Isub ;
dVbsIBPC_dVbs = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVb * Isub + T0 * Isub_dVbs ) ;
dVbsIBPC_dVds = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVd * Isub + T0 * Isub_dVds ) ;
dVbsIBPC_dVgs = pParam->HSM2_ibpc1 * ( pParam->HSM2_ibpc2 * dVth_dVg * Isub + T0 * Isub_dVgs ) ;
/* dG3 & dG4 */
T10 = 1e0 / Xi0 ;
T1 = beta * dVbsIBPC * T10 ;
T10 *= T10 ;
T1_dVb = beta * ( dVbsIBPC_dVbs * Xi0 - dVbsIBPC * Xi0_dVbs ) * T10 ;
T1_dVd = beta * ( dVbsIBPC_dVds * Xi0 - dVbsIBPC * Xi0_dVds ) * T10 ;
T1_dVg = beta * ( dVbsIBPC_dVgs * Xi0 - dVbsIBPC * Xi0_dVgs ) * T10 ;
T10 = 1e0 / Xil ;
T2 = beta * dVbsIBPC * T10 ;
T10 *= T10 ;
T2_dVb = beta * ( dVbsIBPC_dVbs * Xil - dVbsIBPC * Xil_dVbs ) * T10 ;
T2_dVd = beta * ( dVbsIBPC_dVds * Xil - dVbsIBPC * Xil_dVds ) * T10 ;
T2_dVg = beta * ( dVbsIBPC_dVgs * Xil - dVbsIBPC * Xil_dVgs ) * T10 ;
dG3 = cnst0 * ( Xilp32 * T2 - Xi0p32 * T1 ) ;
dG3_dVbs = cnst0 * ( Xilp32_dVbs * T2 + Xilp32 * T2_dVb - Xi0p32_dVbs * T1 - Xi0p32 * T1_dVb ) ;
dG3_dVds = cnst0 * ( Xilp32_dVds * T2 + Xilp32 * T2_dVd - Xi0p32_dVds * T1 - Xi0p32 * T1_dVd ) ;
dG3_dVgs = cnst0 * ( Xilp32_dVgs * T2 + Xilp32 * T2_dVg - Xi0p32_dVgs * T1 - Xi0p32 * T1_dVg ) ;
dG4 = cnst0 * 0.5 * ( - Xilp12 * T2 + Xi0p12 * T1 ) ;
dG4_dVbs = cnst0 * 0.5 * ( - Xilp12_dVbs * T2 - Xilp12 * T2_dVb + Xi0p12_dVbs * T1 + Xi0p12 * T1_dVb ) ;
dG4_dVds = cnst0 * 0.5 * ( - Xilp12_dVds * T2 - Xilp12 * T2_dVd + Xi0p12_dVds * T1 + Xi0p12 * T1_dVd ) ;
dG4_dVgs = cnst0 * 0.5 * ( - Xilp12_dVgs * T2 - Xilp12 * T2_dVg + Xi0p12_dVgs * T1 + Xi0p12 * T1_dVg ) ;
/* Add IBPC current into Ids */
dIdd = dG3 + dG4 ;
dIdd_dVbs = dG3_dVbs + dG4_dVbs ;
dIdd_dVds = dG3_dVds + dG4_dVds ;
dIdd_dVgs = dG3_dVgs + dG4_dVgs ;
IdsIBPC = betaWL * dIdd * Mu ;
IdsIBPC_dVbs = betaWL * ( Mu * dIdd_dVbs + dIdd * Mu_dVbs ) + betaWL_dVbs * Mu * dIdd ;
IdsIBPC_dVds = betaWL * ( Mu * dIdd_dVds + dIdd * Mu_dVds ) + betaWL_dVds * Mu * dIdd ;
IdsIBPC_dVgs = betaWL * ( Mu * dIdd_dVgs + dIdd * Mu_dVgs ) + betaWL_dVgs * Mu * dIdd ;
} /* End if (IBPC) */
/*-----------------------------------------------------------*
* Igate : Gate current induced by tunneling.
*-----------------*/
if ( model->HSM2_coiigs == 0 ) {
Igate = 0.0 ;
Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ;
Igs = 0.0 ;
Igs_dVbs = Igs_dVds = Igs_dVgs = 0.0 ;
Igd = 0.0 ;
Igd_dVbs = Igd_dVds = Igd_dVgs = 0.0 ;
Igb = 0.0 ;
Igb_dVbs = Igb_dVds = Igb_dVgs = 0.0 ;
GLPART1 = 0.0 ;
GLPART1_dVgs = GLPART1_dVds = GLPART1_dVbs = 0.0 ;
} else {
/* Igate */
if ( flg_noqi == 0 ) {
Psdlz = Ps0z + Vdsz - epsm10 ;
Psdlz_dVbs = Ps0z_dVbs ;
Psdlz_dVds = Ps0z_dVds + Vdsz_dVds ;
Psdlz_dVgs = Ps0z_dVgs ;
T1 = Vgsz - Vfb + modelMKS->HSM2_gleak4 * (dVth - dPpg) * Leff - Psdlz * pParam->HSM2_gleak3 ;
T1_dVg = Vgsz_dVgs + modelMKS->HSM2_gleak4 * (dVth_dVg - dPpg_dVg) * Leff - Psdlz_dVgs * pParam->HSM2_gleak3 ;
T1_dVd = Vgsz_dVds + modelMKS->HSM2_gleak4 * (dVth_dVd - dPpg_dVd) * Leff - Psdlz_dVds * pParam->HSM2_gleak3 ;
T1_dVb = modelMKS->HSM2_gleak4 * ( dVth_dVb - dPpg_dVb ) * Leff - Psdlz_dVbs * pParam->HSM2_gleak3 ;
T3 = 1.0 / Tox0 ;
T2 = T1 * T3 ;
T2_dVg = (T1_dVg ) * T3 ;
T2_dVd = (T1_dVd ) * T3 ;
T2_dVb = (T1_dVb ) * T3 ;
T3 = 1.0 / modelMKS->HSM2_gleak5 ;
if ( VgVt <= VgVt_small ) {
Ey = 0.0 ;
Ey_dVgs = 0.0 ;
Ey_dVds = 0.0 ;
Ey_dVbs = 0.0 ;
}
T7 = 1.0 + Ey * T3 ;
T7_dVg = Ey_dVgs * T3 ;
T7_dVd = Ey_dVds * T3 ;
T7_dVb = Ey_dVbs * T3 ;
Etun = T2 * T7 ;
Etun_dVgs = T2_dVg * T7 + T7_dVg * T2 ;
Etun_dVds = T2_dVd * T7 + T7_dVd * T2 ;
Etun_dVbs = T2_dVb * T7 + T7_dVb * T2 ;
Fn_SZ( Etun , Etun , igate_dlt , T5 ) ;
Etun_dVgs *= T5 ;
Etun_dVds *= T5 ;
Etun_dVbs *= T5 ;
Fn_SZ( T3 , Vgsz , 1.0e-3 , T4 ) ;
T3 -= model->HSM2_vzadd0 ;
TX = T3 / cclmmdf ;
T2 = 1.0 + TX * TX ;
T1 = 1.0 - 1.0 / T2 ;
T1_dVg = 2.0 * TX * T4 / ( T2 * T2 * cclmmdf ) ;
T1_dVd = T1_dVg * Vgsz_dVds ;
Etun_dVgs = T1 * Etun_dVgs + Etun * T1_dVg ;
Etun_dVds = T1 * Etun_dVds + Etun * T1_dVd ;
Etun_dVbs *= T1 ;
Etun *= T1 ;
T0 = Leff * here->HSM2_weff_nf ;
T7 = modelMKS->HSM2_gleak7 / (modelMKS->HSM2_gleak7 + T0) ;
T6 = pParam->HSM2_gleak6 ;
T9 = T6 / (T6 + Vdsz) ;
T9_dVd = - T9 / (T6 + Vdsz) * Vdsz_dVds ;
T1 = - pParam->HSM2_gleak2 * Egp32 / (Etun + small) ;
if ( T1 < - EXP_THR ) {
Igate = 0.0 ;
Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ;
} else {
T2 = exp ( T1 ) ;
T3 = pParam->HSM2_gleak1 / Egp12 * C_QE * T0 ;
T4 = T2 * T3 * sqrt ((Qiu + Cox0 * VgVt_small ) / cnst0) ;
T5 = T4 * Etun ;
T6 = 0.5 * Etun / (Qiu + Cox0 * VgVt_small ) ;
T10 = T5 * Etun ;
T10_dVb = T5 * (2.0 * Etun_dVbs - T1 * Etun_dVbs + T6 * Qiu_dVbs) ;
T10_dVd = T5 * (2.0 * Etun_dVds - T1 * Etun_dVds + T6 * Qiu_dVds) ;
T10_dVg = T5 * (2.0 * Etun_dVgs - T1 * Etun_dVgs + T6 * Qiu_dVgs) ;
Igate = T7 * T9 * T10 ;
Igate_dVbs = T7 * T9 * T10_dVb ;
Igate_dVds = T7 * (T9_dVd * T10 + T9 * T10_dVd) ;
Igate_dVgs = T7 * T9 * T10_dVg ;
}
} else {
Igate = 0.0 ;
Igate_dVbs = Igate_dVds = Igate_dVgs = 0.0 ;
}
/* Igs */
T0 = - pParam->HSM2_glksd2 * Vgs + modelMKS->HSM2_glksd3 ;
T2 = exp (Tox0 * T0);
T2_dVg = (- Tox0 * pParam->HSM2_glksd2) * T2;
T0 = Vgs / Tox0 / Tox0 ;
T3 = Vgs * T0 ;
T3_dVg = 2.0 * T0 * (1.0 ) ;
T4 = pParam->HSM2_glksd1 / 1.0e6 * here->HSM2_weff_nf ;
Igs = T4 * T2 * T3 ;
Igs_dVgs = T4 * (T2_dVg * T3 + T2 * T3_dVg) ;
Igs_dVds = 0.0 ;
Igs_dVbs = 0.0 ;
if ( Vgs >= 0.0e0 ){
Igs *= -1.0 ;
Igs_dVgs *= -1.0 ;
Igs_dVds *= -1.0 ;
Igs_dVbs *= -1.0 ;
}
/* Igd */
T1 = Vgs - Vds ;
T0 = - pParam->HSM2_glksd2 * T1 + modelMKS->HSM2_glksd3 ;
T2 = exp (Tox0 * T0);
T2_dVg = (- Tox0 * pParam->HSM2_glksd2) * T2;
T2_dVd = (+ Tox0 * pParam->HSM2_glksd2) * T2;
T2_dVb = 0.0 ;
T0 = T1 / Tox0 / Tox0 ;
T3 = T1 * T0 ;
T3_dVg = 2.0 * T0 ;
T3_dVd = - 2.0 * T0 ;
T3_dVb = 0.0 ;
T4 = pParam->HSM2_glksd1 / 1.0e6 * here->HSM2_weff_nf ;
Igd = T4 * T2 * T3 ;
Igd_dVgs = T4 * (T2_dVg * T3 + T2 * T3_dVg) ;
Igd_dVds = T4 * (T2_dVd * T3 + T2 * T3_dVd) ;
Igd_dVbs = 0.0 ;
if( T1 >= 0.0e0 ){
Igd *= -1.0 ;
Igd_dVgs *= -1.0 ;
Igd_dVds *= -1.0 ;
Igd_dVbs *= -1.0 ;
}
/* Igb */
Etun = (- Vgs + Vbs + Vfb + model->HSM2_glkb3 ) / Tox0 ;
Etun_dVgs = - 1.0 / Tox0 ;
Etun_dVds = 0.0 ;
Etun_dVbs = 1.0 / Tox0 ;
Fn_SZ( Etun , Etun, igate_dlt, T5) ;
Etun += small ;
Etun_dVgs *= T5 ;
Etun_dVbs *= T5 ;
T1 = - pParam->HSM2_glkb2 / Etun ;
if ( T1 < - EXP_THR ) {
Igb = 0.0 ;
Igb_dVgs = Igb_dVds = Igb_dVbs = 0.0 ;
} else {
T2 = exp ( T1 );
T3 = pParam->HSM2_glkb2 / ( Etun * Etun ) * T2 ;
T2_dVg = T3 * Etun_dVgs ;
T2_dVb = T3 * Etun_dVbs ;
T3 = pParam->HSM2_glkb1 * here->HSM2_weff_nf * Leff ;
Igb = T3 * Etun * Etun * T2 ;
Igb_dVgs = T3 * (2.0 * Etun * Etun_dVgs * T2 + Etun * Etun * T2_dVg);
Igb_dVds = 0.0 ;
Igb_dVbs = T3 * (2.0 * Etun * Etun_dVbs * T2 + Etun * Etun * T2_dVb);
}
GLPART1 = 0.5 ;
GLPART1_dVgs = 0.0 ;
GLPART1_dVds = 0.0 ;
GLPART1_dVbs = 0.0 ;
} /* if ( model->HSM2_coiigs == 0 ) */
/*-----------------------------------------------------------*
* Igidl : GIDL
*-----------------*/
if( model->HSM2_cogidl == 0 ){
Igidl = 0.0e0 ;
Igidl_dVbs = 0.0e0 ;
Igidl_dVds = 0.0e0 ;
Igidl_dVgs = 0.0e0 ;
} else {
T3 = here->HSM2_2qnsub_esi ;
Qb0 = sqrt (T3 * (Pb20 - Vbsz2)) ;
T4 = 0.5 * T3 / Qb0 ;
Qb0_dVb = T4 * (- Vbsz2_dVbs) ;
Qb0_dVd = T4 * (- Vbsz2_dVds) ;
Qb0_dVg = T4 * (- Vbsz2_dVgs) ;
Qb0Cox = model->HSM2_gidl6 * Qb0 * Cox_inv ;
Qb0Cox_dVb = model->HSM2_gidl6 * ( Qb0_dVb * Cox_inv + Qb0 * Cox_inv_dVb ) ;
Qb0Cox_dVd = model->HSM2_gidl6 * ( Qb0_dVd * Cox_inv + Qb0 * Cox_inv_dVd ) ;
Qb0Cox_dVg = model->HSM2_gidl6 * ( Qb0_dVg * Cox_inv + Qb0 * Cox_inv_dVg ) ;
T1 = model->HSM2_gidl3 * (Vds + model->HSM2_gidl4) - Vgs + (dVthSC + dVthLP) * model->HSM2_gidl5 - Qb0Cox ;
T2 = 1.0 / Tox0 ;
E1 = T1 * T2 ;
E1_dVb = ( model->HSM2_gidl5 * (dVthSC_dVb + dVthLP_dVb) - Qb0Cox_dVb ) * T2 ;
E1_dVd = ( model->HSM2_gidl3 + model->HSM2_gidl5 * (dVthSC_dVd + dVthLP_dVd) - Qb0Cox_dVd ) * T2 ;
E1_dVg = ( -1.0 + model->HSM2_gidl5 * (dVthSC_dVg + dVthLP_dVg) - Qb0Cox_dVg ) * T2 ;
Fn_SZ( Egidl , E1, eef_dlt, T5) ;
Egidl_dVb = T5 * E1_dVb ;
Egidl_dVd = T5 * E1_dVd ;
Egidl_dVg = T5 * E1_dVg ;
Egidl += small ;
T6 = pow(Egidl,model->HSM2_gidl7) ;
T1 = model->HSM2_gidl7 * pow(Egidl,model->HSM2_gidl7 -1.0) ;
T6_dVb = Egidl_dVb * T1 ;
T6_dVd = Egidl_dVd * T1 ;
T6_dVg = Egidl_dVg * T1 ;
T0 = - pParam->HSM2_gidl2 * Egp32 / T6 ;
if ( T0 < - EXP_THR ) {
Igidl = 0.0 ;
Igidl_dVbs = Igidl_dVds = Igidl_dVgs = 0.0 ;
} else {
T1 = exp ( T0 ) ;
T2 = pParam->HSM2_gidl1 / Egp12 * C_QE * here->HSM2_weff_nf ;
Igidl = T2 * Egidl * Egidl * T1 ;
T3 = T2 * T1 * Egidl * (2.0 + pParam->HSM2_gidl2 * Egp32 * Egidl / T6 / T6 ) ;
Igidl_dVbs = T3 * Egidl_dVb ;
Igidl_dVds = T3 * Egidl_dVd ;
Igidl_dVgs = T3 * Egidl_dVg ;
}
Vdb = Vds - Vbs ;
if ( Vdb > 0.0 ) {
T2 = Vdb * Vdb ;
T4 = T2 * Vdb ;
T0 = T4 + C_gidl_delta ;
T5 = T4 / T0 ;
T7 = ( 3.0 * T2 * T0 - T4 * 3.0 * T2 ) / ( T0 * T0 ) ; /* == T5_dVdb */
Igidl_dVbs = Igidl_dVbs * T5 + Igidl * T7 * ( - 1.0 ) ; /* Vdb_dVbs = -1 */
Igidl_dVds = Igidl_dVds * T5 + Igidl * T7 * ( + 1.0 ) ; /* Vdb_dVds = +1 */
Igidl_dVgs = Igidl_dVgs * T5 ; /* Vdb_dVgs = 0 */
Igidl *= T5 ;
} else {
Igidl = 0.0 ;
Igidl_dVbs = Igidl_dVds = Igidl_dVgs = 0.0 ;
}
}
/*-----------------------------------------------------------*
* Igisl : GISL
*-----------------*/
if( model->HSM2_cogidl == 0){
Igisl = 0.0e0 ;
Igisl_dVbs = 0.0e0 ;
Igisl_dVds = 0.0e0 ;
Igisl_dVgs = 0.0e0 ;
} else {
T1 = model->HSM2_gidl3 * ( - Vds + model->HSM2_gidl4 )
- ( Vgs - Vds ) + ( dVthSC + dVthLP ) * model->HSM2_gidl5 - Qb0Cox ;
T2 = 1.0 / Tox0 ;
E1 = T1 * T2 ;
E1_dVb = ( model->HSM2_gidl5 * (dVthSC_dVb + dVthLP_dVb) - Qb0Cox_dVb ) * T2 ;
E1_dVd = ( -1.0 * model->HSM2_gidl3 + 1.0 + model->HSM2_gidl5 * (dVthSC_dVd + dVthLP_dVd) - Qb0Cox_dVd ) * T2 ;
E1_dVg = ( -1.0 + model->HSM2_gidl5 * (dVthSC_dVg + dVthLP_dVg) - Qb0Cox_dVg ) * T2 ;
Fn_SZ( Egisl , E1, eef_dlt, T5) ;
Egisl_dVb = T5 * E1_dVb ;
Egisl_dVd = T5 * E1_dVd ;
Egisl_dVg = T5 * E1_dVg ;
Egisl += small ;
T6 = pow(Egisl,model->HSM2_gidl7) ;
T1 = model->HSM2_gidl7 * pow(Egisl,model->HSM2_gidl7 -1.0) ;
T6_dVb = Egisl_dVb * T1 ;
T6_dVd = Egisl_dVd * T1 ;
T6_dVg = Egisl_dVg * T1 ;
T0 = - pParam->HSM2_gidl2 * Egp32 / T6 ;
if ( T0 < - EXP_THR ) {
Igisl = 0.0 ;
Igisl_dVbs = Igisl_dVds = Igisl_dVgs = 0.0 ;
} else {
T1 = exp ( T0 ) ;
T2 = pParam->HSM2_gidl1 / Egp12 * C_QE * here->HSM2_weff_nf ;
Igisl = T2 * Egisl * Egisl * T1 ;
T3 = T2 * T1 * Egisl * (2.0 + pParam->HSM2_gidl2 * Egp32 * Egisl / T6 / T6) ;
Igisl_dVbs = T3 * Egisl_dVb ;
Igisl_dVds = T3 * Egisl_dVd ;
Igisl_dVgs = T3 * Egisl_dVg ;
}
Vsb = - Vbs ;
if ( Vsb > 0.0 ) {
T2 = Vsb * Vsb ;
T4 = T2 * Vsb ;
T0 = T4 + C_gidl_delta ;
T5 = T4 / T0 ;
T7 = ( 3.0 * T2 * T0 - T4 * 3.0 * T2 ) / ( T0 * T0 ) ; /* == T5_dVsb */
Igisl_dVbs = Igisl_dVbs * T5 + Igisl * T7 * ( - 1.0 ) ; /* Vsb_dVbs = -1 */
Igisl_dVds = Igisl_dVds * T5 ; /* Vsb_dVds = 0 */
Igisl_dVgs = Igisl_dVgs * T5 ; /* Vsb_dVgs = 0 */
Igisl *= T5 ;
} else {
Igisl = 0.0 ;
Igisl_dVbs = Igisl_dVds = Igisl_dVgs = 0.0 ;
}
}
/*-----------------------------------------------------------*
* End of PART-2. (label)
*-----------------*/
/* end_of_part_2: */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-3: Overlap charge
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
Aclm = pParam->HSM2_clm1 ;
if ( flg_noqi != 0 ) {
/*-------------------------------------------*
* Calculation of Psdl for cases of flg_noqi==1.
*-----------------*/
Psdl = Aclm * (Vds + Ps0) + (1.0e0 - Aclm) * Psl ;
Psdl_dVbs = Aclm * Ps0_dVbs + (1.0e0 - Aclm) * Psl_dVbs ;
Psdl_dVds = Aclm * (1.0e0 + Ps0_dVds) + (1.0e0 - Aclm) * Psl_dVds ;
Psdl_dVgs = Aclm * Ps0_dVgs + (1.0e0 - Aclm) * Psl_dVgs ;
if ( Psdl > Ps0 + Vds - epsm10 ) {
Psdl = Ps0 + Vds - epsm10 ;
Psdl_dVbs = Ps0_dVbs ;
Psdl_dVds = Ps0_dVds + 1.0 ;
Psdl_dVgs = Ps0_dVgs ;
}
if (model->HSM2_xqy !=0) {
Ec = 0.0e0 ;
Ec_dVbs =0.0e0 ;
Ec_dVds =0.0e0 ;
Ec_dVgs =0.0e0 ;
}
} else {
/* Ec is removed from Lred calc. part */
if (model->HSM2_xqy !=0) {
if ( Idd < C_IDD_MIN ) {
Ec = 0.0e0 ;
Ec_dVbs =0.0e0 ;
Ec_dVds =0.0e0 ;
Ec_dVgs =0.0e0 ;
} else {
T1 = beta_inv / Leff ;
T2 = 1.0 / (Qn0 + 1e-20) ;
T3 = T2 * T2 ;
Ec = Idd * T1 * T2 ;
Ec_dVbs = T1 * (Idd_dVbs * T2 - Idd * Qn0_dVbs * T3 ) ;
Ec_dVds = T1 * (Idd_dVds * T2 - Idd * Qn0_dVds * T3 ) ;
Ec_dVgs = T1 * (Idd_dVgs * T2 - Idd * Qn0_dVgs * T3 ) ;
}
}
}
/*-------------------------------------------*
* Overlap charges: Qgod, Qgos, and Qover
*-----------------*/
if ( model->HSM2_coovlp >= 1 && pParam->HSM2_lover > 0.0 ){
cov_slp = modelMKS->HSM2_ovslp ;
cov_mag = model->HSM2_ovmag ;
covvg = Vgs ;
covvg_dVgs = 1.0 ;
T1 = Cox0 * here->HSM2_weff_nf ;
Lov = pParam->HSM2_lover ;
if ( pParam->HSM2_nover == 0.0 ){
T4 = cov_slp * T1 * ( cov_mag + covvg ) ;
T4_dVg = cov_slp * T1 * covvg_dVgs ;
T4_dVd = 0.0 ;
T5 = Lov * T1 ;
TX = Ps0 ;
TX_dVbs = Ps0_dVbs ;
TX_dVds = Ps0_dVds ;
TX_dVgs = Ps0_dVgs ;
T9 = 1.2e0 - TX ;
Qgos = Vgs * T5 - T9 * T4 ;
Qgos_dVbs = T4 * TX_dVbs ;
Qgos_dVds = T4 * TX_dVds - T9 * T4_dVd ;
Qgos_dVgs = T5 + T4 * TX_dVgs - T9 * T4_dVg ;
T4 = cov_slp * T1 * ( cov_mag + covvg - Vds ) ;
T4_dVg = cov_slp * T1 * covvg_dVgs ;
T4_dVd = - cov_slp * T1 ;
TX = Psl - Vds ;
TX_dVbs = Psl_dVbs ;
TX_dVds = Psl_dVds - 1.0 ;
TX_dVgs = Psl_dVgs ;
T9 = 1.2e0 - TX ;
Qgod = (Vgs - Vds) * T5 - T4 * T9 ;
Qgod_dVbs = T4 * TX_dVbs ;
Qgod_dVds = - T5 + T4 * TX_dVds - T9 * T4_dVd ;
Qgod_dVgs = T5 + T4 * TX_dVgs - T9 * T4_dVg ;
} else {
for ( lcover = -1 ; lcover <= +1 ; lcover += 2 ) {
flg_ovloops = ( 1 - lcover ) / 2 ; /* 1 in Source overlap calc. */
flg_ovloopd = ( 1 + lcover ) / 2 ; /* 1 in Drain overlap calc. */
/*-------------------------------------------*
* Qover (G/D overlap charge) | note: _dVxs means _dVxse
*------------------------*/
Vbsgmt = ModeNML * Vbse + ModeRVS * ( Vbse - Vdse ) ;
Vdsgmt = ModeNML * Vdse + ModeRVS * ( - Vdse ) ;
Vgsgmt = ModeNML * Vgse + ModeRVS * ( Vgse - Vdse ) ;
Vdbgmt = Vdsgmt - Vbsgmt ;
Vgbgmt = Vgsgmt - Vbsgmt ;
Vsbgmt = - Vbsgmt ;
flg_overs = flg_ovloops * (int)ModeNML + flg_ovloopd * (int)ModeRVS ; /* geometrical source */
flg_overd = flg_ovloops * (int)ModeRVS + flg_ovloopd * (int)ModeNML ; /* geometrical drain */
Vxbgmt = flg_overs * Vsbgmt + flg_overd * Vdbgmt + epsm10 ;
/*---------------------------------------------------*
* Clamp -Vxbgmt.
*-----------------*/
T0 = - Vxbgmt;
if ( T0 > Vbs_bnd ) {
T1 = T0 - Vbs_bnd;
T2 = Vbs_max - Vbs_bnd;
Fn_SUPoly4( TY, T1, T2, T11 );
T10 = Vbs_bnd + TY ;
} else {
T10 = T0 ;
T11 = 1.0 ;
}
Vxbgmtcl = - T10 - small2 ;
Vxbgmtcl_dVxbgmt = T11;
fac1 = here->HSM2_cnst0over * Cox0_inv ;
fac1_dVbs = 0.0; fac1_dVds = 0.0; fac1_dVgs = 0.0;
fac1p2 = fac1 * fac1 ;
VgpLD = - Vgbgmt + pParam->HSM2_vfbover;
VgpLD_dVgb = - 1.0e0 ;
T0 = pParam->HSM2_nover / here->HSM2_nin ;
Pb2over = 2.0 / beta * log( T0 ) ;
Vgb_fb_LD = - Vxbgmtcl ;
/*-----------------------------------*
* QsuLD: total charge = Accumulation | Depletion+inversion
*-----------------*/
if ( VgpLD < Vgb_fb_LD ){
/*---------------------------*
* Accumulation
*-----------------*/
flg_ovzone = -1 ;
T1 = 1.0 / ( beta * here->HSM2_cnst0over ) ;
TY = T1 * Cox0 ;
Ac41 = 2.0 + 3.0 * C_SQRT_2 * TY ;
Ac4 = 8.0 * Ac41 * Ac41 * Ac41 ;
Ps0_min = here->HSM2_eg - Pb2over ;
TX = beta * ( VgpLD + Vxbgmtcl ) ;
TX_dVxb = beta * Vxbgmtcl_dVxbgmt ;
TX_dVgb = beta * VgpLD_dVgb ;
Ac31 = 7.0 * C_SQRT_2 - 9.0 * TY * ( TX - 2.0 ) ;
Ac31_dVxb = - 9.0 * TY * TX_dVxb ;
Ac31_dVgb = - 9.0 * TY * TX_dVgb ;
Ac3 = Ac31 * Ac31 ;
T1 = 2.0 * Ac31 ;
Ac3_dVxb = T1 * Ac31_dVxb ;
Ac3_dVgb = T1 * Ac31_dVgb ;
Ac2 = sqrt( Ac4 + Ac3 ) ;
T1 = 0.5 / Ac2 ;
Ac2_dVxb = T1 * Ac3_dVxb ;
Ac2_dVgb = T1 * Ac3_dVgb ;
Ac1 = -7.0 * C_SQRT_2 + Ac2 + 9.0 * TY * ( TX - 2.0 ) ;
Ac1_dVxb = Ac2_dVxb + 9.0 * TY * TX_dVxb ;
Ac1_dVgb = Ac2_dVgb + 9.0 * TY * TX_dVgb ;
Acd = pow( Ac1 , C_1o3 ) ;
T1 = C_1o3 / ( Acd * Acd ) ;
Acd_dVxb = Ac1_dVxb * T1 ;
Acd_dVgb = Ac1_dVgb * T1 ;
Acn = -4.0 * C_SQRT_2 - 12.0 * TY + 2.0 * Acd + C_SQRT_2 * Acd * Acd ;
T1 = 2.0 + 2.0 * C_SQRT_2 * Acd ;
Acn_dVxb = T1 * Acd_dVxb ;
Acn_dVgb = T1 * Acd_dVgb ;
Chi = Acn / Acd ;
T1 = 1.0 / ( Acd * Acd ) ;
Chi_dVxb = ( Acn_dVxb * Acd - Acn * Acd_dVxb ) * T1 ;
Chi_dVgb = ( Acn_dVgb * Acd - Acn * Acd_dVgb ) * T1 ;
Psa = Chi * beta_inv - Vxbgmtcl ;
Psa_dVxb = Chi_dVxb * beta_inv - Vxbgmtcl_dVxbgmt ;
Psa_dVgb = Chi_dVgb * beta_inv ;
T1 = Psa + Vxbgmtcl ;
T2 = T1 / Ps0_min ;
T3 = sqrt( 1.0 + ( T2 * T2 ) ) ;
T9 = T2 / T3 / Ps0_min ;
T3_dVd = T9 * ( Psa_dVxb + Vxbgmtcl_dVxbgmt ) ;
T3_dVg = T9 * Psa_dVgb ;
Ps0LD = T1 / T3 - Vxbgmtcl ;
T9 = 1.0 / ( T3 * T3 ) ;
Ps0LD_dVxb = T9 * ( ( Psa_dVxb + Vxbgmtcl_dVxbgmt ) * T3 - T1 * T3_dVd ) - Vxbgmtcl_dVxbgmt ;
Ps0LD_dVgb = T9 * ( Psa_dVgb * T3 - T1 * T3_dVg );
T2 = ( VgpLD - Ps0LD ) ;
QsuLD = Cox0 * T2 ;
QsuLD_dVxb = - Cox0 * Ps0LD_dVxb ;
QsuLD_dVgb = Cox0 * ( VgpLD_dVgb - Ps0LD_dVgb ) ;
QbuLD = QsuLD ;
QbuLD_dVxb = QsuLD_dVxb ;
QbuLD_dVgb = QsuLD_dVgb ;
} else {
/*---------------------------*
* Depletion and inversion
*-----------------*/
/* initial value for a few fixpoint iterations
to get Ps0_iniA from simplified Poisson equation: */
flg_ovzone = 2 ;
Chi = znbd3 ;
Chi_dVxb = 0.0 ; Chi_dVgb = 0.0 ;
Ps0_iniA= Chi/beta - Vxbgmtcl ;
Ps0_iniA_dVxb = Chi_dVxb/beta - Vxbgmtcl_dVxbgmt ;
Ps0_iniA_dVgb = Chi_dVgb/beta ;
/* 1 .. 2 relaxation steps should be sufficient */
for ( lp_ld = 1; lp_ld <= 2; lp_ld ++ ) {
TY = exp(-Chi);
TY_dVxb = -Chi_dVxb * TY;
TY_dVgb = -Chi_dVgb * TY;
TX = 1.0e0 + 4.0e0
* ( beta * ( VgpLD + Vxbgmtcl ) - 1.0e0 + TY ) / ( fac1p2 * beta2 ) ;
TX_dVxb = 4.0e0 * ( beta * ( Vxbgmtcl_dVxbgmt ) + TY_dVxb ) / ( fac1p2 * beta2 );
TX_dVgb = 4.0e0 * ( beta * ( VgpLD_dVgb ) + TY_dVgb ) / ( fac1p2 * beta2 );
T1 = ( beta * ( VgpLD + Vxbgmtcl ) - 1.0e0 + TY );
T3 = fac1p2 * beta2 ;
if ( TX < epsm10) {
TX = epsm10; TX_dVxb = 0.0; TX_dVgb = 0.0;
}
Ps0_iniA = VgpLD + fac1p2 * beta / 2.0e0 * ( 1.0e0 - sqrt( TX ) ) ;
Ps0_iniA_dVxb = - fac1p2 * beta / 2.0e0 * TX_dVxb * 0.5 / sqrt( TX );
Ps0_iniA_dVgb = VgpLD_dVgb - fac1p2 * beta / 2.0e0 * TX_dVgb * 0.5 / sqrt( TX );
T1 = fac1p2 * beta ;
T2 = 1.0 - sqrt( TX );
Chi = beta * ( Ps0_iniA + Vxbgmtcl ) ;
Chi_dVxb = beta * ( Ps0_iniA_dVxb + Vxbgmtcl_dVxbgmt ) ;
Chi_dVgb = beta * ( Ps0_iniA_dVgb ) ;
} /* End of iteration */
if ( Chi < znbd3 ) {
flg_ovzone = 1 ;
/*-----------------------------------*
* zone-D1
* - Ps0_iniA is the analytical solution of QovLD=Qb0 with
* Qb0 being approximated by 3-degree polynomial.
*
* new: Inclusion of exp(-Chi) term at right border
*-----------------*/
Ta = 1.0/(9.0*sqrt(2.0)) - (5.0+7.0*exp(-3.0)) / (54.0*sqrt(2.0+exp(-3.0)));
Tb = (1.0+exp(-3.0)) / (2.0*sqrt(2.0+exp(-3.0))) - sqrt(2.0) / 3.0;
Tc = 1.0/sqrt(2.0) + 1.0/(beta*fac1);
Td = - (VgpLD + Vxbgmtcl) / fac1;
Td_dVxb = - Vxbgmtcl_dVxbgmt / fac1;
Td_dVgb = - VgpLD_dVgb / fac1;
Tq = Tb*Tb*Tb / (27.0*Ta*Ta*Ta) - Tb*Tc/(6.0*Ta*Ta) + Td/(2.0*Ta);
Tq_dVxb = Td_dVxb/(2.0*Ta);
Tq_dVgb = Td_dVgb / (2.0*Ta);
Tp = (3.0*Ta*Tc-Tb*Tb)/(9.0*Ta*Ta);
T5 = sqrt(Tq*Tq + Tp*Tp*Tp);
T5_dVxb = 2.0*Tq*Tq_dVxb / (2.0*T5);
T5_dVgb = 2.0*Tq*Tq_dVgb / (2.0*T5);
Tu = pow(-Tq + T5,C_1o3);
Tu_dVxb = Tu / (3.0 * (-Tq + T5)) * (-Tq_dVxb + T5_dVxb);
Tu_dVgb = Tu / (3.0 * (-Tq + T5)) * (-Tq_dVgb + T5_dVgb);
Tv = -pow(Tq + T5,C_1o3);
Tv_dVxb = Tv / (3.0 * (-Tq - T5)) * (-Tq_dVxb - T5_dVxb);
Tv_dVgb = Tv / (3.0 * (-Tq - T5)) * (-Tq_dVgb - T5_dVgb);
TX = Tu + Tv - Tb/(3.0*Ta);
TX_dVxb = Tu_dVxb + Tv_dVxb;
TX_dVgb = Tu_dVgb + Tv_dVgb;
Ps0_iniA = TX * beta_inv - Vxbgmtcl ;
Ps0_iniA_dVxb = TX_dVxb * beta_inv - Vxbgmtcl_dVxbgmt;
Ps0_iniA_dVgb = TX_dVgb * beta_inv;
Chi = beta * ( Ps0_iniA + Vxbgmtcl ) ;
Chi_dVxb = beta * ( Ps0_iniA_dVxb + Vxbgmtcl_dVxbgmt ) ;
Chi_dVgb = beta * ( Ps0_iniA_dVgb ) ;
}
if ( model->HSM2_coqovsm > 0 ) {
/*-----------------------------------*
* - Ps0_iniB : upper bound.
*-----------------*/
flg_ovzone += 2;
VgpLD_shift = VgpLD + Vxbgmtcl + 0.1;
VgpLD_shift_dVgb = VgpLD_dVgb;
VgpLD_shift_dVxb = Vxbgmtcl_dVxbgmt;
exp_bVbs = exp( beta * - Vxbgmtcl ) + small ;
exp_bVbs_dVxb = - exp_bVbs * beta * Vxbgmtcl_dVxbgmt;
T0 = here->HSM2_nin / pParam->HSM2_nover;
cnst1over = T0 * T0;
gamma = cnst1over * exp_bVbs ;
gamma_dVxb = cnst1over * exp_bVbs_dVxb;
T0 = beta2 * fac1p2;
psi = beta*VgpLD_shift;
psi_dVgb = beta*VgpLD_shift_dVgb;
psi_dVxb = beta*VgpLD_shift_dVxb;
Chi_1 = log(gamma*T0 + psi*psi) - log(cnst1over*T0) + beta*Vxbgmtcl;
Chi_1_dVgb = 2.0*psi*psi_dVgb/ (gamma*T0 + psi*psi);
Chi_1_dVxb = (gamma_dVxb*T0+2.0*psi*psi_dVxb)/(gamma*T0+psi*psi)
+ beta*Vxbgmtcl_dVxbgmt;
Fn_SU2( Chi_1, Chi_1, psi, 1.0, T1, T2 );
Chi_1_dVgb = Chi_1_dVgb*T1 + psi_dVgb*T2;
Chi_1_dVxb = Chi_1_dVxb*T1 + psi_dVxb*T2;
/* 1 fixpoint step for getting more accurate Chi_B */
psi -= Chi_1 ;
psi_dVgb -= Chi_1_dVgb ;
psi_dVxb -= Chi_1_dVxb ;
psi += beta*0.1 ;
psi_B = psi;
arg_B = psi*psi/(gamma*T0);
Chi_B = log(gamma*T0 + psi*psi) - log(cnst1over*T0) + beta*Vxbgmtcl;
Chi_B_dVgb = 2.0*psi*psi_dVgb/ (gamma*T0 + psi*psi);
Chi_B_dVxb = (gamma_dVxb*T0+2.0*psi*psi_dVxb)/(gamma*T0+psi*psi)
+ beta*Vxbgmtcl_dVxbgmt;
Ps0_iniB = Chi_B/beta - Vxbgmtcl ;
Ps0_iniB_dVgb = Chi_B_dVgb/beta;
Ps0_iniB_dVxb = Chi_B_dVxb/beta- Vxbgmtcl_dVxbgmt;
/* construction of Ps0LD by taking Ps0_iniB as an upper limit of Ps0_iniA
*
* Limiting is done for Chi rather than for Ps0LD, to avoid shifting
* for Fn_SU2 */
Chi_A = Chi;
Chi_A_dVxb = Chi_dVxb;
Chi_A_dVgb = Chi_dVgb;
Fn_SU2( Chi, Chi_A, Chi_B, c_ps0ini_2*75.00, T1, T2 ); /* org: 50 */
Chi_dVgb = Chi_A_dVgb * T1 + Chi_B_dVgb * T2;
Chi_dVxb = Chi_A_dVxb * T1 + Chi_B_dVxb * T2;
}
/* updating Ps0LD */
Ps0LD= Chi/beta - Vxbgmtcl ;
Ps0LD_dVgb = Chi_dVgb/beta;
Ps0LD_dVxb = Chi_dVxb/beta- Vxbgmtcl_dVxbgmt;
T1 = Chi - 1.0 + exp(-Chi);
T1_dVxb = (1.0 - exp(-Chi)) * Chi_dVxb ;
T1_dVgb = (1.0 - exp(-Chi)) * Chi_dVgb ;
if (T1 < epsm10) {
T1 = epsm10 ;
T1_dVxb = 0.0 ;
T1_dVgb = 0.0 ;
}
T2 = sqrt(T1);
QbuLD = here->HSM2_cnst0over * T2 ;
T3 = here->HSM2_cnst0over * 0.5 / T2 ;
QbuLD_dVxb = T3 * T1_dVxb ;
QbuLD_dVgb = T3 * T1_dVgb ;
/*-----------------------------------------------------------*
* QsuLD : Qovs or Qovd in unit area.
* note: QsuLD = Qdep+Qinv.
*-----------------*/
QsuLD = Cox0 * ( VgpLD - Ps0LD ) ;
QsuLD_dVxb = Cox0 * ( - Ps0LD_dVxb ) ;
QsuLD_dVgb = Cox0 * ( VgpLD_dVgb - Ps0LD_dVgb ) ;
if ( model->HSM2_coqovsm == 1 ) { /* take initial values from analytical model */
/*---------------------------------------------------*
* Calculation of Ps0LD. (beginning of Newton loop)
* - Fs0 : Fs0 = 0 is the equation to be solved.
* - dPs0 : correction value.
*-----------------*/
/* initial value too close to flat band should not be used */
exp_bVbs = exp( beta * - Vxbgmtcl ) ;
T0 = here->HSM2_nin / pParam->HSM2_nover;
cnst1over = T0 * T0;
cfs1 = cnst1over * exp_bVbs ;
flg_conv = 0 ;
for ( lp_s0 = 1 ; lp_s0 <= 2*lp_s0_max + 1 ; lp_s0 ++ ) {
Chi = beta * ( Ps0LD + Vxbgmtcl ) ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D1/D2. (Ps0LD)
*-----------------*/
fi = Chi * Chi * Chi
* ( cn_im53 + Chi * ( cn_im54 + Chi * cn_im55 ) ) ;
fi_dChi = Chi * Chi
* ( 3 * cn_im53 + Chi * ( 4 * cn_im54 + Chi * 5 * cn_im55 ) ) ;
fs01 = cfs1 * fi * fi ;
fs01_dPs0 = cfs1 * beta * 2 * fi * fi_dChi ;
fb = Chi * ( cn_nc51
+ Chi * ( cn_nc52
+ Chi * ( cn_nc53
+ Chi * ( cn_nc54 + Chi * cn_nc55 ) ) ) ) ;
fb_dChi = cn_nc51
+ Chi * ( 2 * cn_nc52
+ Chi * ( 3 * cn_nc53
+ Chi * ( 4 * cn_nc54 + Chi * 5 * cn_nc55 ) ) ) ;
fs02 = sqrt( fb * fb + fs01 + small ) ;
fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) / ( fs02 + fs02 ) ;
} else {
/*-------------------------------------------*
* zone-D3. (Ps0LD)
*-----------------*/
if ( Chi < large_arg ) { /* avoid exp_Chi to become extremely large */
exp_Chi = exp( Chi ) ;
fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ;
fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ;
} else {
exp_bPs0 = exp( beta*Ps0LD ) ;
fs01 = cnst1over * ( exp_bPs0 - exp_bVbs ) ;
fs01_dPs0 = cnst1over * beta * exp_bPs0 ;
}
fs02 = sqrt( Chi - 1.0 + fs01 ) ;
fs02_dPs0 = ( beta + fs01_dPs0 ) / fs02 * 0.5 ;
} /* end of if ( Chi ... ) block */
/*-----------------------------------------------------------*
* Fs0
*-----------------*/
Fs0 = VgpLD - Ps0LD - fac1 * fs02 ;
Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ;
if ( flg_conv == 1 ) break ;
dPs0 = - Fs0 / Fs0_dPs0 ;
/*-------------------------------------------*
* Update Ps0LD .
*-----------------*/
dPlim = 0.5*dP_max*(1.0 + Fn_Max(1.e0,fabs(Ps0LD))) ;
if ( fabs( dPs0 ) > dPlim ) dPs0 = dPlim * Fn_Sgn( dPs0 ) ;
Ps0LD = Ps0LD + dPs0 ;
TX = -Vxbgmtcl + ps_conv / 2 ;
if ( Ps0LD < TX ) Ps0LD = TX ;
/*-------------------------------------------*
* Check convergence.
*-----------------*/
if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) {
flg_conv = 1 ;
}
} /* end of Ps0LD Newton loop */
/*-------------------------------------------*
* Procedure for diverged case.
*-----------------*/
if ( flg_conv == 0 ) {
fprintf( stderr ,
"*** warning(HiSIM_HV): Went Over Iteration Maximum (Ps0LD)\n" ) ;
fprintf( stderr , " -Vxbgmtcl = %e Vgbgmt = %e\n" , -Vxbgmtcl , Vgbgmt ) ;
}
/*---------------------------------------------------*
* Evaluate derivatives of Ps0LD.
*-----------------*/
if ( Chi < znbd5 ) {
fs01_dVbs = cfs1 * beta * fi * ( - fi + 2 * fi_dChi ) ; /* fs01_dVxbgmtcl */
T2 = 1.0e0 / ( fs02 + fs02 ) ;
fs02_dVbs = ( + beta * fb_dChi * 2 * fb + fs01_dVbs ) * T2 ; /* fs02_dVxbgmtcl */
} else {
if ( Chi < large_arg ) {
fs01_dVbs = + cfs1 * beta ; /* fs01_dVxbgmtcl */
} else {
fs01_dVbs = + cfs1 * beta ;
}
T2 = 0.5e0 / fs02 ;
fs02_dVbs = ( + beta + fs01_dVbs ) * T2 ; /* fs02_dVxbgmtcl */
}
T1 = 1.0 / Fs0_dPs0 ;
Ps0LD_dVxb = - ( - fac1 * fs02_dVbs ) * T1 ;
Ps0LD_dVds = 0.0 ;
Ps0LD_dVgb = - ( VgpLD_dVgb - fac1_dVgs * fs02 ) * T1 ;
if ( Chi < znbd5 ) {
/*-------------------------------------------*
* zone-D1/D2. (Ps0LD)
*-----------------*/
if ( Chi < znbd3 ) { flg_ovzone = 1; }
else { flg_ovzone = 2; }
Xi0 = fb * fb + epsm10 ;
T1 = 2 * fb * fb_dChi * beta ;
Xi0_dVbs = T1 * ( Ps0LD_dVxb + 1.0 ) ; /* Xi0_dVxbgmtcl */
Xi0_dVds = T1 * Ps0LD_dVds ;
Xi0_dVgs = T1 * Ps0LD_dVgb ;
Xi0p12 = fb + epsm10 ;
T1 = fb_dChi * beta ;
Xi0p12_dVbs = T1 * ( Ps0LD_dVxb + 1.0 ) ; /* Xi0p12_dVxbgmtcl */
Xi0p12_dVds = T1 * Ps0LD_dVds ;
Xi0p12_dVgs = T1 * Ps0LD_dVgb ;
Xi0p32 = fb * fb * fb + epsm10 ;
T1 = 3 * fb * fb * fb_dChi * beta ;
Xi0p32_dVbs = T1 * ( Ps0LD_dVxb + 1.0 ) ; /* Xi0p32_dVxbgmtcl */
Xi0p32_dVds = T1 * Ps0LD_dVds ;
Xi0p32_dVgs = T1 * Ps0LD_dVgb ;
} else {
/*-------------------------------------------*
* zone-D3. (Ps0LD)
*-----------------*/
flg_ovzone = 3 ;
Xi0 = Chi - 1.0e0 ;
Xi0_dVbs = beta * ( Ps0LD_dVxb + 1.0e0 ) ; /* Xi0_dVxbgmtcl */
Xi0_dVds = beta * Ps0LD_dVds ;
Xi0_dVgs = beta * Ps0LD_dVgb ;
Xi0p12 = sqrt( Xi0 ) ;
T1 = 0.5e0 / Xi0p12 ;
Xi0p12_dVbs = T1 * Xi0_dVbs ;
Xi0p12_dVds = T1 * Xi0_dVds ;
Xi0p12_dVgs = T1 * Xi0_dVgs ;
Xi0p32 = Xi0 * Xi0p12 ;
T1 = 1.5e0 * Xi0p12 ;
Xi0p32_dVbs = T1 * Xi0_dVbs ;
Xi0p32_dVds = T1 * Xi0_dVds ;
Xi0p32_dVgs = T1 * Xi0_dVgs ;
if ( Chi < large_arg ) {
} else {
}
} /* end of if ( Chi ... ) block */
/*-----------------------------------------------------------*
* - Recalculate the derivatives of fs01 and fs02.
*-----------------*/
fs01_dVbs = Ps0LD_dVxb * fs01_dPs0 + fs01_dVbs ;
fs01_dVds = Ps0LD_dVds * fs01_dPs0 ;
fs01_dVgs = Ps0LD_dVgb * fs01_dPs0 ;
fs02_dVbs = Ps0LD_dVxb * fs02_dPs0 + fs02_dVbs ;
fs02_dVxb = Ps0LD_dVds * fs02_dPs0 ;
fs02_dVgb = Ps0LD_dVgb * fs02_dPs0 ;
/*-----------------------------------------------------------*
* QbuLD and QiuLD
*-----------------*/
QbuLD = here->HSM2_cnst0over * Xi0p12 ;
QbuLD_dVxb = here->HSM2_cnst0over * Xi0p12_dVbs ;
QbuLD_dVgb = here->HSM2_cnst0over * Xi0p12_dVgs ;
T1 = 1.0 / ( fs02 + Xi0p12 ) ;
QiuLD = here->HSM2_cnst0over * fs01 * T1 ;
T2 = 1.0 / ( fs01 + epsm10 ) ;
QiuLD_dVbs = QiuLD * ( fs01_dVbs * T2 - ( fs02_dVbs + Xi0p12_dVbs ) * T1 ) ;
QiuLD_dVgs = QiuLD * ( fs01_dVgs * T2 - ( fs02_dVgb + Xi0p12_dVgs ) * T1 ) ;
/*-----------------------------------------------------------*
* Extrapolation: X_dVxbgmt = X_dVxbgmtcl * Vxbgmtcl_dVxbgmt
*-----------------*/
QbuLD_dVxb *= Vxbgmtcl_dVxbgmt ;
QiuLD_dVbs *= Vxbgmtcl_dVxbgmt ;
/*-----------------------------------------------------------*
* Total overlap charge
*-----------------*/
QsuLD = QbuLD + QiuLD;
QsuLD_dVxb = QbuLD_dVxb + QiuLD_dVbs;
QsuLD_dVgb = QbuLD_dVgb + QiuLD_dVgs;
} /* end of COQOVSM branches */
} /* end of Vgbgmt region blocks */
/* convert to source ref. */
QsuLD_dVbs = - (QsuLD_dVxb + QsuLD_dVgb) ;
QsuLD_dVds = QsuLD_dVxb * flg_overd ;
QsuLD_dVgs = QsuLD_dVgb ;
QbuLD_dVbs = - (QbuLD_dVxb + QbuLD_dVgb) ;
QbuLD_dVds = QbuLD_dVxb * flg_overd ;
QbuLD_dVgs = QbuLD_dVgb ;
/* inversion charge = total - depletion */
QiuLD = QsuLD - QbuLD ;
QiuLD_dVbs = QsuLD_dVbs - QbuLD_dVbs ;
QiuLD_dVds = QsuLD_dVds - QbuLD_dVds ;
QiuLD_dVgs = QsuLD_dVgs - QbuLD_dVgs ;
/* assign final outputs of Qover model */
/* note: Qovs and Qovd are exchanged in reverse mode */
T4 = here->HSM2_weff_nf * Lov ;
if(flg_ovloops) {
Qovs = T4 * QsuLD ;
Qovs_dVbs = T4 * QsuLD_dVbs ;
Qovs_dVds = T4 * QsuLD_dVds ;
Qovs_dVgs = T4 * QsuLD_dVgs ;
QisLD = T4 * QiuLD ;
QisLD_dVbs = T4 * QiuLD_dVbs ;
QisLD_dVds = T4 * QiuLD_dVds ;
QisLD_dVgs = T4 * QiuLD_dVgs ;
QbsLD = T4 * QbuLD ;
QbsLD_dVbs = T4 * QbuLD_dVbs ;
QbsLD_dVds = T4 * QbuLD_dVds ;
QbsLD_dVgs = T4 * QbuLD_dVgs ;
}
if(flg_ovloopd) {
Qovd = T4 * QsuLD ;
Qovd_dVbs = T4 * QsuLD_dVbs ;
Qovd_dVds = T4 * QsuLD_dVds ;
Qovd_dVgs = T4 * QsuLD_dVgs ;
QidLD = T4 * QiuLD ;
QidLD_dVbs = T4 * QiuLD_dVbs ;
QidLD_dVds = T4 * QiuLD_dVds ;
QidLD_dVgs = T4 * QiuLD_dVgs ;
QbdLD = T4 * QbuLD ;
QbdLD_dVbs = T4 * QbuLD_dVbs ;
QbdLD_dVds = T4 * QbuLD_dVds ;
QbdLD_dVgs = T4 * QbuLD_dVgs ;
}
} /* end of lcover loop */
/* convert to the derivatives w.r.t. mode-dependent biases */
Qovs_dVds = ModeNML * Qovs_dVds
- ModeRVS * ( Qovs_dVds + Qovs_dVgs + Qovs_dVbs ) ;
QisLD_dVds = ModeNML * QisLD_dVds
- ModeRVS * ( QisLD_dVds + QisLD_dVgs + QisLD_dVbs ) ;
QbsLD_dVds = ModeNML * QbsLD_dVds
- ModeRVS * ( QbsLD_dVds + QbsLD_dVgs + QbsLD_dVbs ) ;
Qovd_dVds = ModeNML * Qovd_dVds
- ModeRVS * ( Qovd_dVds + Qovd_dVgs + Qovd_dVbs );
QidLD_dVds = ModeNML * QidLD_dVds
- ModeRVS * ( QidLD_dVds + QidLD_dVgs + QidLD_dVbs ) ;
QbdLD_dVds = ModeNML * QbdLD_dVds
- ModeRVS * ( QbdLD_dVds + QbdLD_dVgs + QbdLD_dVbs ) ;
} /* end of if ( pParam->HSM2_nover == 0.0 ) */
/*-----------------------------------*
* Additional constant capacitance model
*-----------------*/
flg_overgiven = ( (int)ModeRVS * model->HSM2_cgso_Given
+ (int)ModeNML * model->HSM2_cgdo_Given ) ;
if ( flg_overgiven ) {
Cgdo = ModeRVS * pParam->HSM2_cgso + ModeNML * pParam->HSM2_cgdo ;
Cgdo *= - here->HSM2_weff_nf ;
Qgod += - Cgdo * (Vgs - Vds) ;
Qgod_dVds += Cgdo ;
Qgod_dVgs += -Cgdo ;
}
flg_overgiven = ( (int)ModeNML * model->HSM2_cgso_Given
+ (int)ModeRVS * model->HSM2_cgdo_Given ) ;
if(flg_overgiven) {
Cgso = ModeNML * pParam->HSM2_cgso + ModeRVS * pParam->HSM2_cgdo ;
Cgso *= - here->HSM2_weff_nf ;
Qgos += - Cgso * Vgs ;
Qgos_dVgs += -Cgso ;
}
} else { /* else case of if ( model->HSM2_coovlp >= 1 ) */
if ( (here->HSM2_mode == HiSIM_NORMAL_MODE && !model->HSM2_cgdo_Given) ||
(here->HSM2_mode != HiSIM_NORMAL_MODE && !model->HSM2_cgso_Given) ) {
Cgdo = - Cox0 * pParam->HSM2_lover * here->HSM2_weff_nf ;
} else {
Cgdo = ModeRVS * pParam->HSM2_cgso + ModeNML * pParam->HSM2_cgdo ;
Cgdo *= - here->HSM2_weff_nf ;
}
Qgod = - Cgdo * (Vgs - Vds) ;
Qgod_dVbs = 0.0 ;
Qgod_dVds = Cgdo ;
Qgod_dVgs = - Cgdo ;
if ( (here->HSM2_mode == HiSIM_NORMAL_MODE && !model->HSM2_cgso_Given) ||
(here->HSM2_mode != HiSIM_NORMAL_MODE && !model->HSM2_cgdo_Given) ) {
Cgso = - Cox0 * pParam->HSM2_lover * here->HSM2_weff_nf ;
} else {
Cgso = ModeNML * pParam->HSM2_cgso + ModeRVS * pParam->HSM2_cgdo ;
Cgso *= - here->HSM2_weff_nf ;
}
Qgos = - Cgso * Vgs ;
Qgos_dVbs = 0.0 ;
Qgos_dVds = 0.0 ;
Qgos_dVgs = - Cgso ;
} /* end of if ( model->HSM2_coovlp >= 1 ) */
/*-------------------------------------------*
* Gate/Bulk overlap charge: Qgbo
*-----------------*/
Cgbo_loc = - model->HSM2_cgbo * here->HSM2_lgate ;
Qgbo = - Cgbo_loc * (Vgs -Vbs) ;
Qgbo_dVgs = - Cgbo_loc ;
Qgbo_dVbs = Cgbo_loc ;
Qgbo_dVds = 0.0 ;
/*---------------------------------------------------*
* Lateral-field-induced capacitance.
*-----------------*/
if ( model->HSM2_coqy == 0 || model->HSM2_xqy == 0 ){
Qy = 0.0e0 ;
Qy_dVds = 0.0e0 ;
Qy_dVgs = 0.0e0 ;
Qy_dVbs = 0.0e0 ;
} else {
Pslk = Ec * Leff + Ps0 ;
Pslk_dVbs = Ec_dVbs * Leff + Ps0_dVbs;
Pslk_dVds = Ec_dVds * Leff + Ps0_dVds;
Pslk_dVgs = Ec_dVgs * Leff + Ps0_dVgs;
Fn_SU2( T10, (Pslk + C_PSLK_SHIFT), (Psdl + C_PSLK_SHIFT), C_PSLK_DELTA, T1, T2 );
Pslk_dVbs = Pslk_dVbs * T1 + Psdl_dVbs * T2;
Pslk_dVds = Pslk_dVds * T1 + Psdl_dVds * T2;
Pslk_dVgs = Pslk_dVgs * T1 + Psdl_dVgs * T2;
Pslk = T10 - C_PSLK_SHIFT;
/* suppress Qy in accumulation region */
/*
Aclm_eff = 1.0 - Pds / (eps_qy + Pds) * (1.0 - Aclm) ;
Aclm_eff_dVds = eps_qy * Pds_dVds / ((eps_qy + Pds)*(eps_qy + Pds)) ;
Aclm_eff_dVgs = eps_qy * Pds_dVgs / ((eps_qy + Pds)*(eps_qy + Pds)) ;
Aclm_eff_dVbs = eps_qy * Pds_dVbs / ((eps_qy + Pds)*(eps_qy + Pds)) ;
*/
Aclm_eff = Aclm ; Aclm_eff_dVds = Aclm_eff_dVgs = Aclm_eff_dVbs = 0.0 ;
T1 = Aclm_eff * ( Vds + Ps0 ) + ( 1.0e0 - Aclm_eff ) * Pslk ;
T1_dVb = Aclm_eff * ( Ps0_dVbs ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVbs
+ Aclm_eff_dVbs * ( Vds + Ps0 - Pslk ) ;
T1_dVd = Aclm_eff * ( 1.0 + Ps0_dVds ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVds
+ Aclm_eff_dVds * ( Vds + Ps0 - Pslk ) ;
T1_dVg = Aclm_eff * ( Ps0_dVgs ) + ( 1.0e0 - Aclm_eff ) * Pslk_dVgs
+ Aclm_eff_dVgs * ( Vds + Ps0 - Pslk ) ;
T10 = here->HSM2_wdpl ;
T3 = T10 * 1.3 ;
T2 = C_ESI * here->HSM2_weff_nf * T3 ;
T7 = 1.0e-9 ; /* 1nm */
T0 = Fn_Max( model->HSM2_xqy , T7 ) ;
T4 = T2 / T0 ;
Qy = - ( Ps0 + Vds - T1 ) * T4 ;
Qy_dVds = - ( Ps0_dVds + 1.0e0 - T1_dVd ) * T4 ;
Qy_dVgs = - ( Ps0_dVgs - T1_dVg ) * T4 ;
Qy_dVbs = - ( Ps0_dVbs - T1_dVb ) * T4 ;
}
if ( model->HSM2_xqy1 != 0.0 ){
Qy += here->HSM2_cqyb0 * Vbs ;
Qy_dVbs += here->HSM2_cqyb0 ;
}
Qy = Qy * FMDVDS ;
Qy_dVbs = Qy_dVbs * FMDVDS + Qy * FMDVDS_dVbs ;
Qy_dVds = Qy_dVds * FMDVDS + Qy * FMDVDS_dVds ;
Qy_dVgs = Qy_dVgs * FMDVDS + Qy * FMDVDS_dVgs ;
/*---------------------------------------------------*
* Fringing capacitance.
*-----------------*/
Cf = here->HSM2_cfrng ;
Qfd = Cf * ( Vgs - Vds ) ;
Qfs = Cf * Vgs ;
/*-----------------------------------------------------------*
* End of PART-3. (label)
*-----------------*/
/* end_of_part_3:*/
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-4: Substrate-source/drain junction diode.
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*-----------------------------------------------------------*
* Cbsj, Cbdj: node-base S/D biases.
*-----------------*/
T10 = model->HSM2_cvb * here->HSM2_jd_nvtm_inv ;
T11 = model->HSM2_cvbk * here->HSM2_jd_nvtm_inv ;
T9 = model->HSM2_cisb * here->HSM2_exptemp ;
T0 = here->HSM2_isbd2 * T9 ;
T2 = exp (- vbd_jct * T10 );
T2_dVb = - T2 * T10 ;
T3 = exp (- vbd_jct * T11 );
T3_dVb = - T3 * T11 ;
/* ibd */
if ( vbd_jct < here->HSM2_vbdt ) {
TX = vbd_jct * here->HSM2_jd_nvtm_inv ;
if ( TX < - EXP_THR ) {
T1 = 0.0 ;
T1_dVb = 0.0 ;
} else {
T1 = exp ( TX ) ;
T1_dVb = T1 * here->HSM2_jd_nvtm_inv ;
}
Ibd = here->HSM2_isbd * (T1 - 1.0)
+ T0 * (T2 - 1.0)
+ pParam->HSM2_cisbk * (T3 - 1.0);
Gbd = here->HSM2_isbd * T1_dVb
+ T0 * T2_dVb
+ pParam->HSM2_cisbk * T3_dVb ;
} else {
T1 = here->HSM2_jd_expcd ;
T4 = here->HSM2_isbd * here->HSM2_jd_nvtm_inv * T1 ;
Ibd = here->HSM2_isbd * (T1 - 1.0)
+ T4 * (vbd_jct - here->HSM2_vbdt)
+ T0 * (T2 - 1.0)
+ pParam->HSM2_cisbk * (T3 - 1.0) ;
Gbd = T4
+ T0 * T2_dVb
+ pParam->HSM2_cisbk * T3_dVb ;
}
T12 = model->HSM2_divx * here->HSM2_isbd2 ;
Ibd += T12 * vbd_jct ;
Gbd += T12 ;
/* ibs */
T0 = here->HSM2_isbs2 * T9 ;
TX = - vbs_jct * T10 ;
if ( TX < - EXP_THR ) {
T2 = 0.0 ;
T2_dVb = 0.0 ;
} else {
T2 = exp ( TX );
T2_dVb = - T2 * T10 ;
}
TX = - vbs_jct * T11 ;
if ( TX < - EXP_THR ) {
T3 = 0.0 ;
T3_dVb = 0.0 ;
} else {
T3 = exp ( TX );
T3_dVb = - T3 * T11 ;
}
if ( vbs_jct < here->HSM2_vbst ) {
TX = vbs_jct * here->HSM2_jd_nvtm_inv ;
if ( TX < - EXP_THR ) {
T1 = 0.0 ;
T1_dVb = 0.0 ;
} else {
T1 = exp ( TX ) ;
T1_dVb = T1 * here->HSM2_jd_nvtm_inv ;
}
Ibs = here->HSM2_isbs * (T1 - 1.0)
+ T0 * (T2 - 1.0)
+ pParam->HSM2_cisbk * (T3 - 1.0);
Gbs = here->HSM2_isbs * T1_dVb
+ T0 * T2_dVb
+ pParam->HSM2_cisbk * T3_dVb ;
} else {
T1 = here->HSM2_jd_expcs ;
T4 = here->HSM2_isbs * here->HSM2_jd_nvtm_inv * T1 ;
Ibs = here->HSM2_isbs * (T1 - 1.0)
+ T4 * (vbs_jct - here->HSM2_vbst)
+ T0 * (T2 - 1.0)
+ pParam->HSM2_cisbk * (T3 - 1.0) ;
Gbs = T4
+ T0 * T2_dVb
+ pParam->HSM2_cisbk * T3_dVb ;
}
T12 = model->HSM2_divx * here->HSM2_isbs2 ;
Ibs += T12 * vbs_jct ;
Gbs += T12 ;
/*---------------------------------------------------*
* Add Gjmin.
*-----------------*/
Ibd += Gjmin * vbd_jct ;
Ibs += Gjmin * vbs_jct ;
Gbd += Gjmin ;
Gbs += Gjmin ;
/*-----------------------------------------------------------*
* Charges and Capacitances.
*-----------------*/
/* charge storage elements
* bulk-drain and bulk-source depletion capacitances
* czbd : zero bias drain junction capacitance
* czbs : zero bias source junction capacitance
* czbdsw:zero bias drain junction sidewall capacitance
* czbssw:zero bias source junction sidewall capacitance
*/
/* add new parameters
tcjbs : temperature dependence of czbs
tcjbd : temperature dependence of czbd
tcjbssw : temperature dependence of czbssw
tcjbdsw : temperature dependence of czbdsw
tcjbsswg : temperature dependence of czbsswg
tcjbdswg : temperature dependence of czbdswg
*/
tcjbd=model->HSM2_tcjbd;
tcjbs=model->HSM2_tcjbs;
tcjbdsw=model->HSM2_tcjbdsw;
tcjbssw=model->HSM2_tcjbssw;
tcjbdswg=model->HSM2_tcjbdswg;
tcjbsswg=model->HSM2_tcjbsswg;
czbs = model->HSM2_cj * here->HSM2_as ;
czbs = czbs * ( 1.0 + tcjbs * ( TTEMP - model->HSM2_ktnom )) ;
czbd = model->HSM2_cj * here->HSM2_ad ;
czbd = czbd * ( 1.0 + tcjbd * ( TTEMP - model->HSM2_ktnom )) ;
/* Source Bulk Junction */
if (here->HSM2_ps > here->HSM2_weff_nf) {
czbssw = model->HSM2_cjsw * ( here->HSM2_ps - here->HSM2_weff_nf ) ;
czbssw = czbssw * ( 1.0 + tcjbssw * ( TTEMP - model->HSM2_ktnom )) ;
czbsswg = model->HSM2_cjswg * here->HSM2_weff_nf ;
czbsswg = czbsswg * ( 1.0 + tcjbsswg * ( TTEMP - model->HSM2_ktnom )) ;
if (vbs_jct == 0.0) {
Qbs = 0.0 ;
Capbs = czbs + czbssw + czbsswg ;
} else if (vbs_jct < 0.0) {
if (czbs > 0.0) {
arg = 1.0 - vbs_jct / model->HSM2_pb ;
if (model->HSM2_mj == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mj ) ;
Qbs = model->HSM2_pb * czbs * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ;
Capbs = czbs * sarg ;
} else {
Qbs = 0.0 ;
Capbs = 0.0 ;
}
if (czbssw > 0.0) {
arg = 1.0 - vbs_jct / model->HSM2_pbsw ;
if (model->HSM2_mjsw == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjsw ) ;
Qbs += model->HSM2_pbsw * czbssw * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjsw) ;
Capbs += czbssw * sarg ;
}
if (czbsswg > 0.0) {
arg = 1.0 - vbs_jct / model->HSM2_pbswg ;
if (model->HSM2_mjswg == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ;
Qbs += model->HSM2_pbswg * czbsswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ;
Capbs += czbsswg * sarg ;
}
} else {
T1 = czbs + czbssw + czbsswg ;
T2 = czbs * model->HSM2_mj / model->HSM2_pb
+ czbssw * model->HSM2_mjsw / model->HSM2_pbsw
+ czbsswg * model->HSM2_mjswg / model->HSM2_pbswg ;
Qbs = vbs_jct * (T1 + vbs_jct * 0.5 * T2) ;
Capbs = T1 + vbs_jct * T2 ;
}
} else {
czbsswg = model->HSM2_cjswg * here->HSM2_ps ;
czbsswg = czbsswg * ( 1.0 + tcjbsswg * ( TTEMP - model->HSM2_ktnom )) ;
if (vbs_jct == 0.0) {
Qbs = 0.0 ;
Capbs = czbs + czbsswg ;
} else if (vbs_jct < 0.0) {
if (czbs > 0.0) {
arg = 1.0 - vbs_jct / model->HSM2_pb ;
if (model->HSM2_mj == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mj ) ;
Qbs = model->HSM2_pb * czbs * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ;
Capbs = czbs * sarg ;
} else {
Qbs = 0.0 ;
Capbs = 0.0 ;
}
if (czbsswg > 0.0) {
arg = 1.0 - vbs_jct / model->HSM2_pbswg ;
if (model->HSM2_mjswg == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ;
Qbs += model->HSM2_pbswg * czbsswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ;
Capbs += czbsswg * sarg ;
}
} else {
T1 = czbs + czbsswg ;
T2 = czbs * model->HSM2_mj / model->HSM2_pb
+ czbsswg * model->HSM2_mjswg / model->HSM2_pbswg ;
Qbs = vbs_jct * (T1 + vbs_jct * 0.5 * T2) ;
Capbs = T1 + vbs_jct * T2 ;
}
}
/* Drain Bulk Junction */
if (here->HSM2_pd > here->HSM2_weff_nf) {
czbdsw = model->HSM2_cjsw * ( here->HSM2_pd - here->HSM2_weff_nf ) ;
czbdsw = czbdsw * ( 1.0 + tcjbdsw * ( TTEMP - model->HSM2_ktnom )) ;
czbdswg = model->HSM2_cjswg * here->HSM2_weff_nf ;
czbdswg = czbdswg * ( 1.0 + tcjbdswg * ( TTEMP - model->HSM2_ktnom )) ;
if (vbd_jct == 0.0) {
Qbd = 0.0 ;
Capbd = czbd + czbdsw + czbdswg ;
} else if (vbd_jct < 0.0) {
if (czbd > 0.0) {
arg = 1.0 - vbd_jct / model->HSM2_pb ;
if (model->HSM2_mj == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mj ) ;
Qbd = model->HSM2_pb * czbd * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ;
Capbd = czbd * sarg ;
} else {
Qbd = 0.0 ;
Capbd = 0.0 ;
}
if (czbdsw > 0.0) {
arg = 1.0 - vbd_jct / model->HSM2_pbsw ;
if (model->HSM2_mjsw == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjsw ) ;
Qbd += model->HSM2_pbsw * czbdsw * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjsw) ;
Capbd += czbdsw * sarg ;
}
if (czbdswg > 0.0) {
arg = 1.0 - vbd_jct / model->HSM2_pbswg ;
if (model->HSM2_mjswg == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ;
Qbd += model->HSM2_pbswg * czbdswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ;
Capbd += czbdswg * sarg ;
}
} else {
T1 = czbd + czbdsw + czbdswg ;
T2 = czbd * model->HSM2_mj / model->HSM2_pb
+ czbdsw * model->HSM2_mjsw / model->HSM2_pbsw
+ czbdswg * model->HSM2_mjswg / model->HSM2_pbswg ;
Qbd = vbd_jct * (T1 + vbd_jct * 0.5 * T2) ;
Capbd = T1 + vbd_jct * T2 ;
}
} else {
czbdswg = model->HSM2_cjswg * here->HSM2_pd ;
czbdswg = czbdswg * ( 1.0 + tcjbdswg * ( TTEMP - model->HSM2_ktnom )) ;
if (vbd_jct == 0.0) {
Qbd = 0.0 ;
Capbd = czbd + czbdswg ;
} else if (vbd_jct < 0.0) {
if (czbd > 0.0) {
arg = 1.0 - vbd_jct / model->HSM2_pb ;
if (model->HSM2_mj == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mj ) ;
Qbd = model->HSM2_pb * czbd * (1.0 - arg * sarg) / (1.0 - model->HSM2_mj) ;
Capbd = czbd * sarg ;
} else {
Qbd = 0.0 ;
Capbd = 0.0 ;
}
if (czbdswg > 0.0) {
arg = 1.0 - vbd_jct / model->HSM2_pbswg ;
if (model->HSM2_mjswg == 0.5)
sarg = 1.0 / sqrt(arg) ;
else
sarg = Fn_Pow( arg , -model->HSM2_mjswg ) ;
Qbd += model->HSM2_pbswg * czbdswg * (1.0 - arg * sarg) / (1.0 - model->HSM2_mjswg) ;
Capbd += czbdswg * sarg ;
}
} else {
T1 = czbd + czbdswg ;
T2 = czbd * model->HSM2_mj / model->HSM2_pb
+ czbdswg * model->HSM2_mjswg / model->HSM2_pbswg ;
Qbd = vbd_jct * (T1 + vbd_jct * 0.5 * T2) ;
Capbd = T1 + vbd_jct * T2 ;
}
}
/*-----------------------------------------------------------*
* End of PART-4. (label)
*-----------------*/
/* end_of_part_4:*/
/*-----------------------------------------------------------*
* PART-5: NQS. (label)
*-----------------*/
if (flg_nqs) {
if(ckt->CKTmode & MODETRAN){
if( ckt->CKTmode & MODEINITTRAN ){
Qi_nqs = Qi ;
Qi_dVgs_nqs = Qi_dVgs ;
Qi_dVds_nqs = Qi_dVds ;
Qi_dVbs_nqs = Qi_dVbs ;
Qb_nqs = Qb ;
Qb_dVgs_nqs = Qb_dVgs ;
Qb_dVds_nqs = Qb_dVds ;
Qb_dVbs_nqs = Qb_dVbs ;
} else {
/* tau for inversion charge */
if (flg_noqi == 0) {
T12 = model->HSM2_dly1;
T10 = model->HSM2_dly2;
T3 = Lch ;
T1 = T10 * T12 * T3 * T3 ;
T2 = Mu * VgVt * T12 + T10 * T3 * T3 + small ;
tau = T1 / T2 ;
T1_dVg = T10 * T12 * 2.0 * T3 * Lch_dVgs ;
T1_dVd = T10 * T12 * 2.0 * T3 * Lch_dVds ;
T1_dVb = T10 * T12 * 2.0 * T3 * Lch_dVbs ;
T2_dVg = T12 * Mu_dVgs * VgVt
+ T12 * Mu * VgVt_dVgs + T10 * 2.0 * T3 * Lch_dVgs ;
T2_dVd = T12 * Mu_dVds * VgVt
+ T12 * Mu * VgVt_dVds + T10 * 2.0 * T3 * Lch_dVds ;
T2_dVb = T12 * Mu_dVbs * VgVt
+ T12 * Mu * VgVt_dVbs + T10 * 2.0 * T3 * Lch_dVbs ;
T4 = 1.0 / ( T2 * T2 ) ;
tau_dVgs = ( T2 * T1_dVg - T1 * T2_dVg ) * T4 ;
tau_dVds = ( T2 * T1_dVd - T1 * T2_dVd ) * T4 ;
tau_dVbs = ( T2 * T1_dVb - T1 * T2_dVb ) * T4 ;
} else {
tau = model->HSM2_dly1 + small ;
tau_dVgs = tau_dVds = tau_dVbs = 0.0 ;
}
T1 = ckt->CKTdelta ;
/* Calculation of Qi */
Qi_prev = *(ckt->CKTstate1 + here->HSM2qi_nqs) ;
T2 = T1 + tau ;
T0 = Qi - Qi_prev ;
Qi_nqs = Qi_prev + T1 / T2 * T0;
T3 = T1 / T2 ;
T4 = T0 / T2 ;
Qi_dVgs_nqs = T3 * (Qi_dVgs - T4 * tau_dVgs);
Qi_dVds_nqs = T3 * (Qi_dVds - T4 * tau_dVds);
Qi_dVbs_nqs = T3 * (Qi_dVbs - T4 * tau_dVbs);
/* tau for bulk charge */
T2 = modelMKS->HSM2_dly3 ;
taub = T2 * Cox ;
taub_dVgs = T2 * Cox_dVg ;
taub_dVds = T2 * Cox_dVd ;
taub_dVbs = T2 * Cox_dVb ;
/* Calculation of Qb */
Qb_prev = *(ckt->CKTstate1 + here->HSM2qb_nqs) ;
T2 = T1 + taub ;
T0 = Qb - Qb_prev ;
Qb_nqs = Qb_prev + T1 / T2 * T0 ;
T3 = T1 / T2 ;
T4 = T0 / T2 ;
Qb_dVgs_nqs = T3 * (Qb_dVgs - T4 * taub_dVgs) ;
Qb_dVds_nqs = T3 * (Qb_dVds - T4 * taub_dVds) ;
Qb_dVbs_nqs = T3 * (Qb_dVbs - T4 * taub_dVbs) ;
}
} else { /* !(CKT_mode & MODETRAN) */
Qi_nqs = Qi ;
Qi_dVgs_nqs = Qi_dVgs ;
Qi_dVds_nqs = Qi_dVds ;
Qi_dVbs_nqs = Qi_dVbs ;
Qb_nqs = Qb ;
Qb_dVgs_nqs = Qb_dVgs ;
Qb_dVds_nqs = Qb_dVds ;
Qb_dVbs_nqs = Qb_dVbs ;
}
}
if ( flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG)) ) { /* ACNQS */
if (flg_noqi == 0) {
T10 = model->HSM2_dly1 ;
T11 = model->HSM2_dly2 ;
T12 = Lch ;
T1 = T10 * T11 * T12 * T12 ;
T2 = Mu * VgVt * T10 + T11 * T12 * T12 + small ;
tau = T1 / T2 ;
T1_dVg = T10 * T11 * 2.0 * T12 * Lch_dVgs ;
T1_dVd = T10 * T11 * 2.0 * T12 * Lch_dVds ;
T1_dVb = T10 * T11 * 2.0 * T12 * Lch_dVbs ;
T2_dVg = T10 * Mu_dVgs * VgVt + T10 * Mu * VgVt_dVgs
+ T11 * 2.0 * T12 * Lch_dVgs ;
T2_dVd = T10 * Mu_dVds * VgVt + T10 * Mu * VgVt_dVds
+ T11 * 2.0 * T12 * Lch_dVds ;
T2_dVb = T10 * Mu_dVbs * VgVt + T10 * Mu * VgVt_dVbs
+ T11 * 2.0 * T12 * Lch_dVbs ;
T3 = 1.0 / T2 ;
tau_dVgs = (T1_dVg - tau * T2_dVg) * T3 ;
tau_dVds = (T1_dVd - tau * T2_dVd) * T3 ;
tau_dVbs = (T1_dVb - tau * T2_dVb) * T3 ;
} else {
tau = model->HSM2_dly1 + small ;
tau_dVgs = tau_dVds = tau_dVbs = 0.0 ;
}
T1 = modelMKS->HSM2_dly3 ;
taub = T1 * Cox ;
taub_dVgs = T1 * Cox_dVg ;
taub_dVds = T1 * Cox_dVd ;
taub_dVbs = T1 * Cox_dVb ;
}
/*-----------------------------------------------------------*
* End of PART-5. (label)
*-----------------*/
/* end_of_part_5: */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-6: Noise Calculation.
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*-----------------------------------------------------------*
* 1/f noise.
*-----------------*/
if ( model->HSM2_coflick != 0 && !flg_noqi ) {
NFalp = pParam->HSM2_nfalp ;
NFtrp = pParam->HSM2_nftrp ;
Cit = modelMKS->HSM2_cit ;
T1 = Qn0 / C_QE ;
T2 = ( Cox + Qn0 / ( Ps0 - Vbs ) + Cit ) * beta_inv / C_QE ;
T3 = -2.0E0 * Qi_noi / C_QE / Lch / here->HSM2_weff_nf - T1 ;
if ( T3 != T1 ) {
T4 = 1.0E0 / ( T1 + T2 ) / ( T3 + T2 ) + 2.0E0 * NFalp * Ey * Mu / ( T3 - T1 )
* log( ( T3 + T2 ) / ( T1 + T2 ) ) + NFalp * Ey * Mu * NFalp * Ey * Mu ;
} else {
T4 = 1.0 / ( T1 + T2 ) / ( T3 + T2 ) + 2.0 * NFalp * Ey * Mu / ( T1 + T2 )
+ NFalp * Ey * Mu * NFalp * Ey * Mu;
}
Nflic = Ids * Ids * NFtrp / ( Lch * beta * here->HSM2_weff_nf ) * T4 ;
} else {
Nflic = 0.0 ;
}
/*-----------------------------------------------------------*
* thermal noise.
*-----------------*/
if ( model->HSM2_cothrml != 0 && !flg_noqi ) {
Eyd = ( Psdl - Ps0 ) / Lch ;
T12 = Muun * Eyd / C_vmax ;
/* note: model->HSM2_bb = 2 (electron) ;1 (hole) */
if ( 1.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 1.0e0 + epsm10 ) {
T7 = 1.0e0 ;
} else if ( 2.0e0 - epsm10 <= model->HSM2_bb && model->HSM2_bb <= 2.0e0 + epsm10 ) {
T7 = T12 ;
} else {
T7 = Fn_Pow( Eyd, model->HSM2_bb - 1.0e0 ) ;
}
T8 = T12 * T7 ;
T9 = 1.0e0 + T8 ;
T10 = Fn_Pow( T9, ( - 1.0e0 / model->HSM2_bb - 1.0e0 ) ) ;
T11 = T9 * T10 ;
Mud_hoso = Muun * T11 ;
Mu_Ave = ( Mu + Mud_hoso ) / 2.0 ;
/* Sid_h = GAMMA * 4.0 * C_KB * model->HSM2_temp * gds0_h2; */
T0 = Alpha * Alpha ;
Nthrml = here->HSM2_weff_nf * Cox * VgVt * Mu
* ( ( 1e0 + 3e0 * Alpha + 6e0 * T0 ) * Mud_hoso * Mud_hoso
+ ( 3e0 + 4e0 * Alpha + 3e0 * T0 ) * Mud_hoso * Mu
+ ( 6e0 + 3e0 * Alpha + T0 ) * Mu * Mu )
/ ( 15e0 * Lch * ( 1e0 + Alpha ) * Mu_Ave * Mu_Ave ) ;
} else {
Nthrml = 0e0 ;
}
/*----------------------------------------------------------*
* induced gate noise. ( Part 2/3 )
*----------------------*/
if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 && flg_ign == 1 && !flg_noqi ) {
sqrtkusaiL = sqrt( kusaiL ) ;
T2 = VgVt + sqrtkusaiL ;
T3 = kusai00 * kusai00 ;
T4 = kusaiL * kusaiL ;
T5 = 42.0e0 * kusai00 * kusaiL ;
T5 += 4.0e0 * ( T3 + T4 ) ;
T5 += 20.0e0 * sqrtkusaiL * VgVt * ( kusai00 + kusaiL ) ;
T10 = T2 * T2 ;
T10 *= T10 ;
kusai_ig = T5 / ( T10 * T2 ) ; /* Induced Gate Noise parameter */
gds0_ign = here->HSM2_weff_nf / Lch * Mu * Cox ;
gds0_h2 = gds0_ign * VgVt ;
GAMMA = Nthrml / gds0_h2 ;
T7 = kusai00 + 4.0e0 * VgVt * sqrtkusaiL + kusaiL ;
/* cross-correlation coefficient (= Sigid/sqrt(Sig*Sid) ) */
crl_f = c_sqrt_15 * kusai00L * T7
/ ( 6.0e0 * T2 * sqrt( GAMMA * T2 * VgVt * T5 ) ) ;
}
/*-----------------------------------------------------------*
* End of PART-6. (label)
*-----------------*/
/* end_of_part_6: */
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PART-7: Evaluation of outputs.
*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/*-----------------------------------------------------------*
* Implicit quantities related to Alpha.
*-----------------*/
/* note: T1 = 1 + Delta */
if ( flg_noqi == 0 && VgVt > VgVt_small ) {
Delta = fac1 * beta / ( 2 * Xi0p12 ) ;
Pslsat = VgVt / ( 1.0 + Delta ) + Ps0 ;
} else {
Pslsat = 0.0 ;
}
Vdsat = Pslsat - Pb2 ;
if ( Vdsat < 0.0 ) {
Vdsat = 0.0 ;
}
/*-----------------------------------------------------------*
* Evaluate the derivatives w.r.t. external biases.
* - All derivatives that influence outputs must be modified here.
*-----------------*/
/*---------------------------------------------------*
* Case ignoring Rs/Rd.
*-----------------*/
if ( flg_rsrd != 1 || Ids < 0.0 ) {
Ids_dVbse = Ids_dVbs ; Ids_dVdse = Ids_dVds ; Ids_dVgse = Ids_dVgs ;
Qb_dVbse = Qb_dVbs ; Qb_dVdse = Qb_dVds ; Qb_dVgse = Qb_dVgs ;
Qi_dVbse = Qi_dVbs ; Qi_dVdse = Qi_dVds ; Qi_dVgse = Qi_dVgs ;
Qd_dVbse = Qd_dVbs ; Qd_dVdse = Qd_dVds ; Qd_dVgse = Qd_dVgs ;
Isub_dVbse = Isub_dVbs ; Isub_dVdse = Isub_dVds ; Isub_dVgse = Isub_dVgs ;
IdsIBPC_dVbse = IdsIBPC_dVbs ; IdsIBPC_dVdse = IdsIBPC_dVds ; IdsIBPC_dVgse = IdsIBPC_dVgs ;
Igate_dVbse = Igate_dVbs ; Igate_dVdse = Igate_dVds ; Igate_dVgse = Igate_dVgs ;
Igd_dVbse = Igd_dVbs ; Igd_dVdse = Igd_dVds ; Igd_dVgse = Igd_dVgs ;
Igs_dVbse = Igs_dVbs ; Igs_dVdse = Igs_dVds ; Igs_dVgse = Igs_dVgs ;
Igb_dVbse = Igb_dVbs ; Igb_dVdse = Igb_dVds ; Igb_dVgse = Igb_dVgs ;
Igidl_dVbse = Igidl_dVbs ; Igidl_dVdse = Igidl_dVds ; Igidl_dVgse = Igidl_dVgs ;
Igisl_dVbse = Igisl_dVbs ; Igisl_dVdse = Igisl_dVds ; Igisl_dVgse = Igisl_dVgs ;
Qgos_dVbse = Qgos_dVbs ; Qgos_dVdse = Qgos_dVds ; Qgos_dVgse = Qgos_dVgs ;
Qgod_dVbse = Qgod_dVbs ; Qgod_dVdse = Qgod_dVds ; Qgod_dVgse = Qgod_dVgs ;
Qgbo_dVbse = Qgbo_dVbs ; Qgbo_dVdse = Qgbo_dVds ; Qgbo_dVgse = Qgbo_dVgs ;
Qovd_dVbse = Qovd_dVbs ; Qovd_dVdse = Qovd_dVds ; Qovd_dVgse = Qovd_dVgs ;
QidLD_dVbse = QidLD_dVbs ; QidLD_dVdse = QidLD_dVds ; QidLD_dVgse = QidLD_dVgs ;
QbdLD_dVbse = QbdLD_dVbs ; QbdLD_dVdse = QbdLD_dVds ; QbdLD_dVgse = QbdLD_dVgs ;
Qovs_dVbse = Qovs_dVbs ; Qovs_dVdse = Qovs_dVds ; Qovs_dVgse = Qovs_dVgs ;
QisLD_dVbse = QisLD_dVbs ; QisLD_dVdse = QisLD_dVds ; QisLD_dVgse = QisLD_dVgs ;
QbsLD_dVbse = QbsLD_dVbs ; QbsLD_dVdse = QbsLD_dVds ; QbsLD_dVgse = QbsLD_dVgs ;
Qy_dVbse = Qy_dVbs ; Qy_dVdse = Qy_dVds ; Qy_dVgse = Qy_dVgs ;
Qdrat_dVbse = Qdrat_dVbs; Qdrat_dVdse = Qdrat_dVds; Qdrat_dVgse = Qdrat_dVgs;
GLPART1_dVbse = GLPART1_dVbs ;GLPART1_dVdse = GLPART1_dVds ;GLPART1_dVgse = GLPART1_dVgs ;
if (flg_nqs) { /* NQS */
Qi_dVgse_nqs = Qi_dVgs_nqs; Qi_dVdse_nqs = Qi_dVds_nqs; Qi_dVbse_nqs = Qi_dVbs_nqs;
Qb_dVgse_nqs = Qb_dVgs_nqs; Qb_dVdse_nqs = Qb_dVds_nqs; Qb_dVbse_nqs = Qb_dVbs_nqs;
}
if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */
tau_dVgse = tau_dVgs ; tau_dVdse = tau_dVds ; tau_dVbse = tau_dVbs ;
taub_dVgse = taub_dVgs ; taub_dVdse = taub_dVds ; taub_dVbse = taub_dVbs ;
}
} else {
/*---------------------------------------------------*
* Case Rs>0 or Rd>0
*-----------------*/
/*-------------------------------------------*
* Conductances w.r.t. confined biases.
*-----------------*/
Ids_dVbse = Ids_dVbs * DJI ;
Ids_dVdse = Ids_dVds * DJI ;
Ids_dVgse = Ids_dVgs * DJI ;
/*-------------------------------------------*
* Derivatives of internal biases w.r.t. external biases.
*-----------------*/
Vbs_dVbse = ( 1.0 - Rs * Ids_dVbse ) ;
Vbs_dVdse = - Rs * Ids_dVdse ;
Vbs_dVgse = - Rs * Ids_dVgse ;
Vds_dVbse = - ( Rs + Rd ) * Ids_dVbse ;
Vds_dVdse = ( 1.0 - ( Rs + Rd ) * Ids_dVdse ) ;
Vds_dVgse = - ( Rs + Rd ) * Ids_dVgse ;
Vgs_dVbse = - Rs * Ids_dVbse ;
Vgs_dVdse = - Rs * Ids_dVdse ;
Vgs_dVgse = ( 1.0 - Rs * Ids_dVgse ) ;
/*-------------------------------------------*
* Derivatives of charges.
*-----------------*/
Qb_dVbse = Qb_dVbs * Vbs_dVbse + Qb_dVds * Vds_dVbse + Qb_dVgs * Vgs_dVbse ;
Qb_dVdse = Qb_dVbs * Vbs_dVdse + Qb_dVds * Vds_dVdse + Qb_dVgs * Vgs_dVdse ;
Qb_dVgse = Qb_dVbs * Vbs_dVgse + Qb_dVds * Vds_dVgse + Qb_dVgs * Vgs_dVgse ;
Qi_dVbse = Qi_dVbs * Vbs_dVbse + Qi_dVds * Vds_dVbse + Qi_dVgs * Vgs_dVbse ;
Qi_dVdse = Qi_dVbs * Vbs_dVdse + Qi_dVds * Vds_dVdse + Qi_dVgs * Vgs_dVdse ;
Qi_dVgse = Qi_dVbs * Vbs_dVgse + Qi_dVds * Vds_dVgse + Qi_dVgs * Vgs_dVgse ;
Qd_dVbse = Qd_dVbs * Vbs_dVbse + Qd_dVds * Vds_dVbse + Qd_dVgs * Vgs_dVbse ;
Qd_dVdse = Qd_dVbs * Vbs_dVdse + Qd_dVds * Vds_dVdse + Qd_dVgs * Vgs_dVdse ;
Qd_dVgse = Qd_dVbs * Vbs_dVgse + Qd_dVds * Vds_dVgse + Qd_dVgs * Vgs_dVgse ;
/*-------------------------------------------*
* Substrate/gate/leak conductances.
*-----------------*/
Isub_dVbse = Isub_dVbs * Vbs_dVbse + Isub_dVds * Vds_dVbse + Isub_dVgs * Vgs_dVbse ;
Isub_dVdse = Isub_dVbs * Vbs_dVdse + Isub_dVds * Vds_dVdse + Isub_dVgs * Vgs_dVdse ;
Isub_dVgse = Isub_dVbs * Vbs_dVgse + Isub_dVds * Vds_dVgse + Isub_dVgs * Vgs_dVgse ;
IdsIBPC_dVbse = IdsIBPC_dVbs * Vbs_dVbse + IdsIBPC_dVds * Vds_dVbse + IdsIBPC_dVgs * Vgs_dVbse ;
IdsIBPC_dVdse = IdsIBPC_dVbs * Vbs_dVdse + IdsIBPC_dVds * Vds_dVdse + IdsIBPC_dVgs * Vgs_dVdse ;
IdsIBPC_dVgse = IdsIBPC_dVbs * Vbs_dVgse + IdsIBPC_dVds * Vds_dVgse + IdsIBPC_dVgs * Vgs_dVgse ;
Igate_dVbse = Igate_dVbs * Vbs_dVbse + Igate_dVds * Vds_dVbse + Igate_dVgs * Vgs_dVbse ;
Igate_dVdse = Igate_dVbs * Vbs_dVdse + Igate_dVds * Vds_dVdse + Igate_dVgs * Vgs_dVdse ;
Igate_dVgse = Igate_dVbs * Vbs_dVgse + Igate_dVds * Vds_dVgse + Igate_dVgs * Vgs_dVgse ;
Igb_dVbse = Igb_dVbs * Vbs_dVbse + Igb_dVds * Vds_dVbse + Igb_dVgs * Vgs_dVbse ;
Igb_dVdse = Igb_dVbs * Vbs_dVdse + Igb_dVds * Vds_dVdse + Igb_dVgs * Vgs_dVdse ;
Igb_dVgse = Igb_dVbs * Vbs_dVgse + Igb_dVds * Vds_dVgse + Igb_dVgs * Vgs_dVgse ;
Igd_dVbse = Igd_dVbs * Vbs_dVbse + Igd_dVds * Vds_dVbse + Igd_dVgs * Vgs_dVbse ;
Igd_dVdse = Igd_dVbs * Vbs_dVdse + Igd_dVds * Vds_dVdse + Igd_dVgs * Vgs_dVdse ;
Igd_dVgse = Igd_dVbs * Vbs_dVgse + Igd_dVds * Vds_dVgse + Igd_dVgs * Vgs_dVgse ;
Igs_dVbse = Igs_dVbs * Vbs_dVbse + Igs_dVds * Vds_dVbse + Igs_dVgs * Vgs_dVbse ;
Igs_dVdse = Igs_dVbs * Vbs_dVdse + Igs_dVds * Vds_dVdse + Igs_dVgs * Vgs_dVdse ;
Igs_dVgse = Igs_dVbs * Vbs_dVgse + Igs_dVds * Vds_dVgse + Igs_dVgs * Vgs_dVgse ;
Igidl_dVbse = Igidl_dVbs * Vbs_dVbse + Igidl_dVds * Vds_dVbse + Igidl_dVgs * Vgs_dVbse ;
Igidl_dVdse = Igidl_dVbs * Vbs_dVdse + Igidl_dVds * Vds_dVdse + Igidl_dVgs * Vgs_dVdse ;
Igidl_dVgse = Igidl_dVbs * Vbs_dVgse + Igidl_dVds * Vds_dVgse + Igidl_dVgs * Vgs_dVgse ;
Igisl_dVbse = Igisl_dVbs * Vbs_dVbse + Igisl_dVds * Vds_dVbse + Igisl_dVgs * Vgs_dVbse ;
Igisl_dVdse = Igisl_dVbs * Vbs_dVdse + Igisl_dVds * Vds_dVdse + Igisl_dVgs * Vgs_dVdse ;
Igisl_dVgse = Igisl_dVbs * Vbs_dVgse + Igisl_dVds * Vds_dVgse + Igisl_dVgs * Vgs_dVgse ;
GLPART1_dVbse = GLPART1_dVbs * Vbs_dVbse + GLPART1_dVds * Vds_dVbse + GLPART1_dVgs * Vgs_dVbse ;
GLPART1_dVdse = GLPART1_dVbs * Vbs_dVdse + GLPART1_dVds * Vds_dVdse + GLPART1_dVgs * Vgs_dVdse ;
GLPART1_dVgse = GLPART1_dVbs * Vbs_dVgse + GLPART1_dVds * Vds_dVgse + GLPART1_dVgs * Vgs_dVgse ;
/*---------------------------------------------------*
* Derivatives of overlap charges.
*-----------------*/
Qgos_dVbse = Qgos_dVbs * Vbs_dVbse + Qgos_dVds * Vds_dVbse + Qgos_dVgs * Vgs_dVbse ;
Qgos_dVdse = Qgos_dVbs * Vbs_dVdse + Qgos_dVds * Vds_dVdse + Qgos_dVgs * Vgs_dVdse ;
Qgos_dVgse = Qgos_dVbs * Vbs_dVgse + Qgos_dVds * Vds_dVgse + Qgos_dVgs * Vgs_dVgse ;
Qgod_dVbse = Qgod_dVbs * Vbs_dVbse + Qgod_dVds * Vds_dVbse + Qgod_dVgs * Vgs_dVbse ;
Qgod_dVdse = Qgod_dVbs * Vbs_dVdse + Qgod_dVds * Vds_dVdse + Qgod_dVgs * Vgs_dVdse ;
Qgod_dVgse = Qgod_dVbs * Vbs_dVgse + Qgod_dVds * Vds_dVgse + Qgod_dVgs * Vgs_dVgse ;
Qgbo_dVbse = Qgbo_dVbs * Vbs_dVbse + Qgbo_dVds * Vds_dVbse + Qgbo_dVgs * Vgs_dVbse ;
Qgbo_dVdse = Qgbo_dVbs * Vbs_dVdse + Qgbo_dVds * Vds_dVdse + Qgbo_dVgs * Vgs_dVdse ;
Qgbo_dVgse = Qgbo_dVbs * Vbs_dVgse + Qgbo_dVds * Vds_dVgse + Qgbo_dVgs * Vgs_dVgse ;
Qovd_dVbse = Qovd_dVbs * Vbs_dVbse + Qovd_dVds * Vds_dVbse + Qovd_dVgs * Vgs_dVbse ;
Qovd_dVdse = Qovd_dVbs * Vbs_dVdse + Qovd_dVds * Vds_dVdse + Qovd_dVgs * Vgs_dVdse ;
Qovd_dVgse = Qovd_dVbs * Vbs_dVgse + Qovd_dVds * Vds_dVgse + Qovd_dVgs * Vgs_dVgse ;
QidLD_dVbse = QidLD_dVbs * Vbs_dVbse + QidLD_dVds * Vds_dVbse + QidLD_dVgs * Vgs_dVbse ;
QidLD_dVdse = QidLD_dVbs * Vbs_dVdse + QidLD_dVds * Vds_dVdse + QidLD_dVgs * Vgs_dVdse ;
QidLD_dVgse = QidLD_dVbs * Vbs_dVgse + QidLD_dVds * Vds_dVgse + QidLD_dVgs * Vgs_dVgse ;
QbdLD_dVbse = QbdLD_dVbs * Vbs_dVbse + QbdLD_dVds * Vds_dVbse + QbdLD_dVgs * Vgs_dVbse ;
QbdLD_dVdse = QbdLD_dVbs * Vbs_dVdse + QbdLD_dVds * Vds_dVdse + QbdLD_dVgs * Vgs_dVdse ;
QbdLD_dVgse = QbdLD_dVbs * Vbs_dVgse + QbdLD_dVds * Vds_dVgse + QbdLD_dVgs * Vgs_dVgse ;
Qovs_dVbse = Qovs_dVbs * Vbs_dVbse + Qovs_dVds * Vds_dVbse + Qovs_dVgs * Vgs_dVbse ;
Qovs_dVdse = Qovs_dVbs * Vbs_dVdse + Qovs_dVds * Vds_dVdse + Qovs_dVgs * Vgs_dVdse ;
Qovs_dVgse = Qovs_dVbs * Vbs_dVgse + Qovs_dVds * Vds_dVgse + Qovs_dVgs * Vgs_dVgse ;
QisLD_dVbse = QisLD_dVbs * Vbs_dVbse + QisLD_dVds * Vds_dVbse + QisLD_dVgs * Vgs_dVbse ;
QisLD_dVdse = QisLD_dVbs * Vbs_dVdse + QisLD_dVds * Vds_dVdse + QisLD_dVgs * Vgs_dVdse ;
QisLD_dVgse = QisLD_dVbs * Vbs_dVgse + QisLD_dVds * Vds_dVgse + QisLD_dVgs * Vgs_dVgse ;
QbsLD_dVbse = QbsLD_dVbs * Vbs_dVbse + QbsLD_dVds * Vds_dVbse + QbsLD_dVgs * Vgs_dVbse ;
QbsLD_dVdse = QbsLD_dVbs * Vbs_dVdse + QbsLD_dVds * Vds_dVdse + QbsLD_dVgs * Vgs_dVdse ;
QbsLD_dVgse = QbsLD_dVbs * Vbs_dVgse + QbsLD_dVds * Vds_dVgse + QbsLD_dVgs * Vgs_dVgse ;
Qy_dVbse = Qy_dVbs * Vbs_dVbse + Qy_dVds * Vds_dVbse + Qy_dVgs * Vgs_dVbse ;
Qy_dVdse = Qy_dVbs * Vbs_dVdse + Qy_dVds * Vds_dVdse + Qy_dVgs * Vgs_dVdse ;
Qy_dVgse = Qy_dVbs * Vbs_dVgse + Qy_dVds * Vds_dVgse + Qy_dVgs * Vgs_dVgse ;
Qdrat_dVbse = Qdrat_dVbs * Vbs_dVbse + Qdrat_dVds * Vds_dVbse + Qdrat_dVgs * Vgs_dVbse ;
Qdrat_dVdse = Qdrat_dVbs * Vbs_dVdse + Qdrat_dVds * Vds_dVdse + Qdrat_dVgs * Vgs_dVdse ;
Qdrat_dVgse = Qdrat_dVbs * Vbs_dVgse + Qdrat_dVds * Vds_dVgse + Qdrat_dVgs * Vgs_dVgse ;
if (flg_nqs) { /* NQS */
Qi_dVgse_nqs = Qi_dVgs_nqs * Vgs_dVgse + Qi_dVds_nqs * Vds_dVgse + Qi_dVbs_nqs * Vbs_dVgse;
Qi_dVdse_nqs = Qi_dVgs_nqs * Vgs_dVdse + Qi_dVds_nqs * Vds_dVdse + Qi_dVbs_nqs * Vbs_dVdse;
Qi_dVbse_nqs = Qi_dVgs_nqs * Vgs_dVbse + Qi_dVds_nqs * Vds_dVbse + Qi_dVbs_nqs * Vbs_dVbse;
Qb_dVgse_nqs = Qb_dVgs_nqs * Vgs_dVgse + Qb_dVds_nqs * Vds_dVgse + Qb_dVbs_nqs * Vbs_dVgse;
Qb_dVdse_nqs = Qb_dVgs_nqs * Vgs_dVdse + Qb_dVds_nqs * Vds_dVdse + Qb_dVbs_nqs * Vbs_dVdse;
Qb_dVbse_nqs = Qb_dVgs_nqs * Vgs_dVbse + Qb_dVds_nqs * Vds_dVbse + Qb_dVbs_nqs * Vbs_dVbse;
}
if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */
tau_dVgse = tau_dVgs * Vgs_dVgse + tau_dVds * Vds_dVgse + tau_dVbs * Vbs_dVgse;
tau_dVdse = tau_dVgs * Vgs_dVdse + tau_dVds * Vds_dVdse + tau_dVbs * Vbs_dVdse;
tau_dVbse = tau_dVgs * Vgs_dVbse + tau_dVds * Vds_dVbse + tau_dVbs * Vbs_dVbse;
taub_dVgse = taub_dVgs * Vgs_dVgse + taub_dVds * Vds_dVgse + taub_dVbs * Vbs_dVgse;
taub_dVdse = taub_dVgs * Vgs_dVdse + taub_dVds * Vds_dVdse + taub_dVbs * Vbs_dVdse;
taub_dVbse = taub_dVgs * Vgs_dVbse + taub_dVds * Vds_dVbse + taub_dVbs * Vbs_dVbse;
}
} /* end of if ( flg_rsrd == 0 ) blocks */
/*-------------------------------------------*
* Add IdsIBPC to Ids.
*-----------------*/
Ids += IdsIBPC ;
Ids_dVbse += IdsIBPC_dVbse ;
Ids_dVdse += IdsIBPC_dVdse ;
Ids_dVgse += IdsIBPC_dVgse ;
/*---------------------------------------------------*
* Derivatives of junction diode currents and charges.
* - NOTE: These quantities are regarded as functions of
* external biases.
* - NOTE: node-base S/D
*-----------------*/
Gbse = Gbs ;
Gbde = Gbd ;
Capbse = Capbs ;
Capbde = Capbd ;
/*---------------------------------------------------*
* Extrapolate quantities if external biases are out of bounds.
*-----------------*/
if ( flg_vbsc == 1 ) {
Ids_dVbse *= Vbsc_dVbse ;
Qb_dVbse *= Vbsc_dVbse ;
Qi_dVbse *= Vbsc_dVbse ;
Qd_dVbse *= Vbsc_dVbse ;
Isub_dVbse *= Vbsc_dVbse ;
Igate_dVbse *= Vbsc_dVbse ;
Igs_dVbse *= Vbsc_dVbse ;
Igd_dVbse *= Vbsc_dVbse ;
Igb_dVbse *= Vbsc_dVbse ;
Igidl_dVbse *= Vbsc_dVbse ;
Igisl_dVbse *= Vbsc_dVbse ;
Qgos_dVbse *= Vbsc_dVbse ;
Qgod_dVbse *= Vbsc_dVbse ;
Qgbo_dVbse *= Vbsc_dVbse ;
Qy_dVbse *= Vbsc_dVbse ;
if (flg_nqs) {
Qi_dVbse_nqs *= Vbsc_dVbse ;
Qb_dVbse_nqs *= Vbsc_dVbse ;
}
if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */
tau_dVbse *= Vbsc_dVbse ;
taub_dVbse *= Vbsc_dVbse ;
}
} else if ( flg_vbsc == -1 ) {
T1 = Vbse - Vbsc ;
TX = Ids + T1 * Ids_dVbse ;
if ( TX * Ids >= 0.0 ) {
Ids = TX ;
} else {
Ids_dVbse = 0.0 ;
Ids_dVdse = 0.0 ;
Ids_dVgse = 0.0 ;
Ids = 0.0 ;
}
TX = Qb + T1 * Qb_dVbse ;
/*note: The sign of Qb can be changed.*/
Qb = TX ;
TX = Qd + T1 * Qd_dVbse ;
if ( TX * Qd >= 0.0 ) {
Qd = TX ;
} else {
Qd_dVbse = 0.0 ;
Qd_dVdse = 0.0 ;
Qd_dVgse = 0.0 ;
Qd = 0.0 ;
}
TX = Qi + T1 * Qi_dVbse ;
if ( TX * Qi >= 0.0 ) {
Qi = TX ;
} else {
Qi_dVbse = 0.0 ;
Qi_dVdse = 0.0 ;
Qi_dVgse = 0.0 ;
Qi = 0.0 ;
}
TX = Isub + T1 * Isub_dVbse ;
if ( TX * Isub >= 0.0 ) {
Isub = TX ;
} else {
Isub_dVbse = 0.0 ;
Isub_dVdse = 0.0 ;
Isub_dVgse = 0.0 ;
Isub = 0.0 ;
}
TX = Igate + T1 * Igate_dVbse ;
if ( TX * Igate >= 0.0 ) {
Igate = TX ;
} else {
Igate_dVbse = 0.0 ;
Igate_dVdse = 0.0 ;
Igate_dVgse = 0.0 ;
Igate = 0.0 ;
}
TX = Igs + T1 * Igs_dVbse ;
if ( TX * Igs >= 0.0 ) {
Igs = TX ;
} else {
Igs_dVbse = 0.0 ;
Igs_dVdse = 0.0 ;
Igs_dVgse = 0.0 ;
Igs = 0.0 ;
}
TX = Igd + T1 * Igd_dVbse ;
if ( TX * Igd >= 0.0 ) {
Igd = TX ;
} else {
Igd_dVbse = 0.0 ;
Igd_dVdse = 0.0 ;
Igd_dVgse = 0.0 ;
Igd = 0.0 ;
}
TX = Igb + T1 * Igb_dVbse ;
if ( TX * Igb >= 0.0 ) {
Igb = TX ;
} else {
Igb_dVbse = 0.0 ;
Igb_dVdse = 0.0 ;
Igb_dVgse = 0.0 ;
Igb = 0.0 ;
}
TX = Igidl + T1 * Igidl_dVbse ;
if ( TX * Igidl >= 0.0 ) {
Igidl = TX ;
} else {
Igidl_dVbse = 0.0 ;
Igidl_dVdse = 0.0 ;
Igidl_dVgse = 0.0 ;
Igidl = 0.0 ;
}
TX = Igisl + T1 * Igisl_dVbse ;
if ( TX * Igisl >= 0.0 ) {
Igisl = TX ;
} else {
Igisl_dVbse = 0.0 ;
Igisl_dVdse = 0.0 ;
Igisl_dVgse = 0.0 ;
Igisl = 0.0 ;
}
TX = GLPART1 + T1 * GLPART1_dVbse ;
if ( TX * GLPART1 >= 0.0 ) {
GLPART1 = TX ;
} else{
GLPART1_dVbse = 0.0 ;
GLPART1_dVdse = 0.0 ;
GLPART1_dVgse = 0.0 ;
GLPART1 = 0.0 ;
}
TX = Qgod + T1 * Qgod_dVbse ;
if ( TX * Qgod >= 0.0 ) {
Qgod = TX ;
} else {
Qgod_dVbse = 0.0 ;
Qgod_dVdse = 0.0 ;
Qgod_dVgse = 0.0 ;
Qgod = 0.0 ;
}
TX = Qgos + T1 * Qgos_dVbse ;
if ( TX * Qgos >= 0.0 ) {
Qgos = TX ;
} else {
Qgos_dVbse = 0.0 ;
Qgos_dVdse = 0.0 ;
Qgos_dVgse = 0.0 ;
Qgos = 0.0 ;
}
TX = Qgbo + T1 * Qgbo_dVbse ;
if ( TX * Qgbo >= 0.0 ) {
Qgbo = TX ;
} else {
Qgbo_dVbse = 0.0 ;
Qgbo_dVdse = 0.0 ;
Qgbo_dVgse = 0.0 ;
Qgbo = 0.0 ;
}
TX = Qy + T1 * Qy_dVbse ;
if ( TX * Qy >= 0.0 ) {
Qy = TX ;
} else {
Qy_dVbse = 0.0 ;
Qy_dVdse = 0.0 ;
Qy_dVgse = 0.0 ;
Qy = 0.0 ;
}
TX = Qdrat + T1 * Qdrat_dVbse ;
if ( TX * Qdrat >= 0.0 ) {
Qdrat = TX ;
} else{
Qdrat_dVbse = 0.0 ;
Qdrat_dVdse = 0.0 ;
Qdrat_dVgse = 0.0 ;
Qdrat = 0.0 ;
}
TX = Qovd + T1 * Qovd_dVbse ;
if ( TX * Qovd >= 0.0 ) {
Qovd = TX ;
} else{
Qovd_dVbse = 0.0 ;
Qovd_dVdse = 0.0 ;
Qovd_dVgse = 0.0 ;
Qovd = 0.0 ;
}
TX = QidLD + T1 * QidLD_dVbse ;
if ( TX * QidLD >= 0.0 ) {
QidLD = TX ;
} else{
QidLD_dVbse = 0.0 ;
QidLD_dVdse = 0.0 ;
QidLD_dVgse = 0.0 ;
QidLD = 0.0 ;
}
TX = QbdLD + T1 * QbdLD_dVbse ;
if ( TX * QbdLD >= 0.0 ) {
QbdLD = TX ;
} else{
QbdLD_dVbse = 0.0 ;
QbdLD_dVdse = 0.0 ;
QbdLD_dVgse = 0.0 ;
QbdLD = 0.0 ;
}
TX = Qovs + T1 * Qovs_dVbse ;
if ( TX * Qovs >= 0.0 ) {
Qovs = TX ;
} else{
T7 = Qovs / ( Qovs - TX ) ;
Qovs_dVbse *= T7 ;
Qovs_dVdse *= T7 ;
Qovs_dVgse *= T7 ;
Qovs = 0.0 ;
}
TX = QisLD + T1 * QisLD_dVbse ;
if ( TX * QisLD >= 0.0 ) {
QisLD = TX ;
} else{
QisLD_dVbse = 0.0 ;
QisLD_dVdse = 0.0 ;
QisLD_dVgse = 0.0 ;
QisLD = 0.0 ;
}
TX = QbsLD + T1 * QbsLD_dVbse ;
if ( TX * QbsLD >= 0.0 ) {
QbsLD = TX ;
} else{
QbsLD_dVbse = 0.0 ;
QbsLD_dVdse = 0.0 ;
QbsLD_dVgse = 0.0 ;
QbsLD = 0.0 ;
}
if (flg_nqs) { /* for NQS charge */
TX = Qi_nqs + T1 * Qi_dVbse_nqs ;
if ( TX * Qi_nqs >= 0.0 ) {
Qi_nqs = TX ;
} else {
Qi_dVbse_nqs = 0.0 ;
Qi_dVdse_nqs = 0.0 ;
Qi_dVgse_nqs = 0.0 ;
Qi_nqs = 0.0 ;
}
TX = Qb_nqs + T1 * Qb_dVbse_nqs ;
Qb_nqs = TX ;
}
if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) { /* ACNQS */
TX = tau + T1 * tau_dVbse ;
if ( TX * tau >= 0.0 ) {
tau = TX ;
} else {
tau_dVbse = 0.0 ;
tau_dVdse = 0.0 ;
tau_dVgse = 0.0 ;
tau = 0.0 ;
}
TX = taub + T1 * taub_dVbse ;
if ( TX * taub >= 0.0 ) {
taub = TX ;
} else {
taub_dVbse = 0.0 ;
taub_dVdse = 0.0 ;
taub_dVgse = 0.0 ;
taub = 0.0 ;
}
}
}
/*-----------------------------------------------------------*
* Warn negative conductance.
* - T1 ( = d Ids / d Vds ) is the derivative w.r.t. circuit bias.
*-----------------*/
if ( here->HSM2_mode == HiSIM_NORMAL_MODE ) {
T1 = Ids_dVdse ;
} else {
T1 = Ids_dVbse + Ids_dVdse + Ids_dVgse ; /* Ids_dVss * -1 */
}
if ( flg_info >= 1 &&
(Ids_dVbse < 0.0 || T1 < 0.0 || Ids_dVgse < 0.0) ) {
printf( "*** warning(HiSIM): Negative Conductance\n" ) ;
printf( " type = %d mode = %d\n" , model->HSM2_type , here->HSM2_mode ) ;
printf( " Vbse = %12.5e Vdse = %12.5e Vgse = %12.5e\n" ,
Vbse , Vdse , Vgse ) ;
printf( " Ids_dVbse = %12.5e\n" , Ids_dVbse ) ;
printf( " Ids_dVdse = %12.5e\n" , T1 ) ;
printf( " Ids_dVgse = %12.5e\n" , Ids_dVgse ) ;
}
/*-----------------------------------------------------------*
* Redefine overlap charges/capacitances.
*-----------------*/
/*---------------------------------------------------*
* Overlap capacitance.
*-----------------*/
Cggo = Qgos_dVgse + Qgod_dVgse + Qgbo_dVgse ;
Cgdo = Qgos_dVdse + Qgod_dVdse ;
Cgso = - (Qgos_dVbse + Qgod_dVbse + Qgos_dVdse + Qgod_dVdse
+ Qgos_dVgse + Qgod_dVgse) ;
Cgbo = Qgos_dVbse + Qgod_dVbse + Qgbo_dVbse ;
/*---------------------------------------------------*
* Add fringing charge/capacitance to overlap.
*-----------------*/
Qgod += Qfd ;
Qgos += Qfs ;
Cggo += 2.0 * Cf ;
Cgdo += - Cf ;
Cgso += - Cf ;
/*-----------------------------------------------------------*
* Assign outputs.
*-----------------*/
/*---------------------------------------------------*
* Multiplication factor of a MOSFET instance.
*-----------------*/
M = here->HSM2_m ;
/*---------------------------------------------------*
* Channel current and conductances.
*-----------------*/
here->HSM2_ids = M * Ids ;
here->HSM2_gmbs = M * Ids_dVbse ;
here->HSM2_gds = M * Ids_dVdse ;
here->HSM2_gm = M * Ids_dVgse ;
/*---------------------------------------------------*
* Overlap capacitances.
*-----------------*/
/* Q_dVsx */
T2 = - ( Qovd_dVbse + Qovd_dVdse + Qovd_dVgse ) ;
T6 = - ( Qovs_dVbse + Qovs_dVdse + Qovs_dVgse ) ;
T5 = - ( QbdLD_dVbse + QbdLD_dVdse + QbdLD_dVgse ) ;
T7 = - ( QbsLD_dVbse + QbsLD_dVdse + QbsLD_dVgse ) ;
here->HSM2_cgdo = M * ( Cgdo - Qovd_dVdse - Qovs_dVdse ) ;
here->HSM2_cgso = M * ( Cgso - T2 - T6 ) ;
here->HSM2_cgbo = M * ( Cgbo - Qovd_dVbse - Qovs_dVbse ) ;
here->HSM2_cdgo = M * ( - Qgod_dVgse - Cf + QbdLD_dVgse ) ;
here->HSM2_cddo = M * ( - Qgod_dVdse + Cf + QbdLD_dVdse ) ;
here->HSM2_cdso = M * ( Qgod_dVbse + Qgod_dVdse + Qgod_dVgse + T5 ) ;
here->HSM2_csgo = M * ( - Qgos_dVgse - Cf + QbsLD_dVgse ) ;
here->HSM2_csdo = M * ( - Qgos_dVdse + QbsLD_dVdse ) ;
here->HSM2_csso = M * ( Qgos_dVbse + Qgos_dVdse + Qgos_dVgse + Cf + T7 ) ;
/*---------------------------------------------------*
* Lateral-field-induced capacitance.
*-----------------*/
T0 = model->HSM2_qyrat ;
T1 = 1.0 - T0 ;
Qys = Qy * T1 ;
Qys_dVdse = Qy_dVdse * T1 ;
Qys_dVgse = Qy_dVgse * T1 ;
Qys_dVbse = Qy_dVbse * T1 ;
Qy = Qy * T0 ;
Qy_dVdse = Qy_dVdse * T0 ;
Qy_dVgse = Qy_dVgse * T0 ;
Qy_dVbse = Qy_dVbse * T0 ;
Cqyd = Qy_dVdse ;
Cqyg = Qy_dVgse ;
Cqyb = Qy_dVbse ;
Cqys = - ( Cqyb + Cqyd + Cqyg ) ;
here->HSM2_cqyd = M * Cqyd ;
here->HSM2_cqyg = M * Cqyg ;
here->HSM2_cqyb = M * Cqyb ;
/* -------------------------------------*
* Intrinsic charges / capacitances.
*-----------------*/
if ( flg_nqs && ((ckt->CKTmode & MODETRAN) ||
(ckt->CKTmode & MODEINITFIX)) ) { /* NQS (tran. analysis) */
*(ckt->CKTstate0 + here->HSM2qi_nqs) = Qi_nqs ;
*(ckt->CKTstate0 + here->HSM2qb_nqs) = Qb_nqs ;
here->HSM2_qg = M * - (Qb_nqs + Qi_nqs) ;
here->HSM2_qd = M * Qi_nqs * Qdrat ;
here->HSM2_qs = M * Qi_nqs * (1.0 - Qdrat) ;
here->HSM2_cbgb = M * Qb_dVgse_nqs ;
here->HSM2_cbdb = M * Qb_dVdse_nqs ;
here->HSM2_cbsb = M * - (Qb_dVbse_nqs + Qb_dVdse_nqs + Qb_dVgse_nqs) ;
here->HSM2_cggb = M * ( - Qb_dVgse_nqs - Qi_dVgse_nqs ) ;
here->HSM2_cgdb = M * ( - Qb_dVdse_nqs - Qi_dVdse_nqs ) ;
here->HSM2_cgsb = M * ( Qb_dVbse_nqs + Qb_dVdse_nqs + Qb_dVgse_nqs
+ Qi_dVbse_nqs + Qi_dVdse_nqs + Qi_dVgse_nqs ) ;
qd_dVgse = Qi_dVgse_nqs * Qdrat + Qdrat_dVgse * Qi_nqs ;
qd_dVdse = Qi_dVdse_nqs * Qdrat + Qdrat_dVdse * Qi_nqs ;
qd_dVbse = Qi_dVbse_nqs * Qdrat + Qdrat_dVbse * Qi_nqs ;
qd_dVsse = - ( qd_dVgse + qd_dVdse + qd_dVbse ) ;
here->HSM2_cdgb = M * qd_dVgse ;
here->HSM2_cddb = M * qd_dVdse ;
here->HSM2_cdsb = M * qd_dVsse ;
} else { /* QS or NQS (ac dc analysis) */
here->HSM2_qg = M * - (Qb + Qi) ;
here->HSM2_qd = M * Qd ;
here->HSM2_qs = M * ( Qi - Qd ) ;
here->HSM2_cbgb = M * Qb_dVgse ;
here->HSM2_cbdb = M * Qb_dVdse ;
here->HSM2_cbsb = M * - (Qb_dVbse + Qb_dVdse + Qb_dVgse) ;
here->HSM2_cggb = M * ( - Qb_dVgse - Qi_dVgse ) ;
here->HSM2_cgdb = M * ( - Qb_dVdse - Qi_dVdse ) ;
here->HSM2_cgsb = M * ( Qb_dVbse + Qb_dVdse + Qb_dVgse
+ Qi_dVbse + Qi_dVdse + Qi_dVgse ) ;
here->HSM2_cdgb = M * Qd_dVgse ;
here->HSM2_cddb = M * Qd_dVdse ;
here->HSM2_cdsb = M * - (Qd_dVgse + Qd_dVdse + Qd_dVbse) ;
}
/*---------------------------------------------------*
* Add lateral-field-induced charges/capacitances to intrinsic ones.
* - NOTE: This function depends on coqy, a control option.
*-----------------*/
if ( model->HSM2_coqy == 1 ) {
here->HSM2_qg += M * ( Qy + Qys ) ;
here->HSM2_qd += M * ( - Qy ) ;
here->HSM2_qs += M * ( - Qys ) ;
T8 = - ( Qys_dVbse + Qys_dVdse + Qys_dVgse ) ;
here->HSM2_cggb += M * ( Cqyg + Qys_dVgse ) ;
here->HSM2_cgdb += M * ( Cqyd + Qys_dVdse ) ;
here->HSM2_cgsb += M * ( Cqys + T8 ) ;
here->HSM2_cdgb += M * ( - Cqyg ) ;
here->HSM2_cddb += M * ( - Cqyd ) ;
here->HSM2_cdsb += M * ( - Cqys ) ;
}
/*---------------------------------------------------*
* Add S/D overlap charges/capacitances to intrinsic ones.
* - NOTE: This function depends on coadov, a control option.
*-----------------*/
if ( model->HSM2_coadov == 1 ) {
/* Q_dVsb */
T0 = - ( Qgbo_dVbse + Qgbo_dVdse + Qgbo_dVgse ) ;
T1 = - ( Qovd_dVbse + Qovd_dVdse + Qovd_dVgse ) ;
T3 = - ( Qovs_dVbse + Qovs_dVdse + Qovs_dVgse ) ;
T4 = - ( QidLD_dVbse + QidLD_dVdse + QidLD_dVgse + QisLD_dVbse + QisLD_dVdse + QisLD_dVgse ) ;
T5 = - ( QbdLD_dVbse + QbdLD_dVdse + QbdLD_dVgse ) ;
T7 = - ( Qgod_dVbse + Qgod_dVdse + Qgod_dVgse ) ;
here->HSM2_qg += M * ( Qgod + Qgos + Qgbo - Qovd - Qovs ) ;
here->HSM2_qd += M * ( - Qgod + QbdLD ) ;
here->HSM2_qs += M * ( - Qgos + QbsLD ) ;
here->HSM2_cbgb += M * ( - Qgbo_dVgse + QidLD_dVgse + QisLD_dVgse ) ;
here->HSM2_cbdb += M * ( - Qgbo_dVdse + QidLD_dVdse + QisLD_dVdse ) ;
here->HSM2_cbsb += M * ( - T0 + T4 ) ;
here->HSM2_cggb += M * ( Cggo - Qovd_dVgse - Qovs_dVgse ) ;
here->HSM2_cgdb += M * ( Cgdo - Qovd_dVdse - Qovs_dVdse ) ;
here->HSM2_cgsb += M * ( Cgso - T1 - T3 ) ;
here->HSM2_cdgb += M * ( - Qgod_dVgse - Cf + QbdLD_dVgse ) ;
here->HSM2_cddb += M * ( - Qgod_dVdse + Cf + QbdLD_dVdse ) ;
here->HSM2_cdsb += M * ( - T7 + T5 ) ;
}
/*---------------------------------------------------*
* tau (channel/bulk charge) for ACNQS.
*-----------------*/
if (flg_nqs && (ckt->CKTmode & (MODEDCOP | MODEINITSMSIG))) {
here->HSM2_tau = tau ;
here->HSM2_tau_dVgs = tau_dVgse ;
here->HSM2_tau_dVds = tau_dVdse ;
here->HSM2_tau_dVbs = tau_dVbse ;
here->HSM2_taub = taub ;
here->HSM2_taub_dVgs = taub_dVgse ;
here->HSM2_taub_dVds = taub_dVdse ;
here->HSM2_taub_dVbs = taub_dVbse ;
here->HSM2_Xd = Qdrat;
here->HSM2_Xd_dVgs = Qdrat_dVgse ;
here->HSM2_Xd_dVds = Qdrat_dVdse ;
here->HSM2_Xd_dVbs = Qdrat_dVbse ;
here->HSM2_Qb = M * Qb ;
here->HSM2_Qb_dVgs = M * Qb_dVgse ;
here->HSM2_Qb_dVds = M * Qb_dVdse ;
here->HSM2_Qb_dVbs = M * Qb_dVbse ;
here->HSM2_Qi = M * Qi ;
here->HSM2_Qi_dVgs = M * Qi_dVgse ;
here->HSM2_Qi_dVds = M * Qi_dVdse ;
here->HSM2_Qi_dVbs = M * Qi_dVbse ;
}
/*---------------------------------------------------*
* Substrate/gate/leak currents.
*-----------------*/
here->HSM2_isub = M * Isub ;
here->HSM2_gbbs = M * Isub_dVbse ;
here->HSM2_gbds = M * Isub_dVdse ;
here->HSM2_gbgs = M * Isub_dVgse ;
here->HSM2_igb = M * -Igb ;
here->HSM2_gigbb = M * -Igb_dVbse ;
here->HSM2_gigbg = M * -Igb_dVgse ;
if (here->HSM2_mode == HiSIM_NORMAL_MODE) {
here->HSM2_gigbd = M * -Igb_dVdse ;
here->HSM2_gigbs = M * ( Igb_dVbse + Igb_dVdse + Igb_dVgse ) ;
} else {
here->HSM2_gigbd = M * ( Igb_dVbse + Igb_dVdse + Igb_dVgse ) ;
here->HSM2_gigbs = M * -Igb_dVdse ;
}
if (here->HSM2_mode == HiSIM_NORMAL_MODE) {
here->HSM2_igd = M * ( GLPART1 * Igate - Igd ) ;
here->HSM2_gigdb = M * ( GLPART1 * Igate_dVbse + GLPART1_dVbse * Igate - Igd_dVbse ) ;
here->HSM2_gigdd = M * ( GLPART1 * Igate_dVdse + GLPART1_dVdse * Igate - Igd_dVdse ) ;
here->HSM2_gigdg = M * ( GLPART1 * Igate_dVgse + GLPART1_dVgse * Igate - Igd_dVgse ) ;
} else {
T1 = 1.0 - GLPART1 ;
T1_dVb = - GLPART1_dVbse ;
T1_dVd = - GLPART1_dVdse ;
T1_dVg = - GLPART1_dVgse ;
here->HSM2_igd = M * ( T1 * Igate - Igs ) ;
here->HSM2_gigdb = M * ( T1 * Igate_dVbse + T1_dVb * Igate - Igs_dVbse ) ;
here->HSM2_gigdd = M * ( T1 * - ( Igate_dVgse + Igate_dVbse + Igate_dVdse )
+ ( - T1_dVb - T1_dVg - T1_dVd ) * Igate + ( Igs_dVgse + Igs_dVbse + Igs_dVdse ) ) ;
here->HSM2_gigdg = M * ( T1 * Igate_dVgse + T1_dVg * Igate - Igs_dVgse ) ;
}
here->HSM2_gigds = -(here->HSM2_gigdb + here->HSM2_gigdd + here->HSM2_gigdg) ;
if (here->HSM2_mode == HiSIM_NORMAL_MODE) {
T1 = 1.0 - GLPART1 ;
T1_dVb = - GLPART1_dVbse ;
T1_dVd = - GLPART1_dVdse ;
T1_dVg = - GLPART1_dVgse ;
here->HSM2_igs = M * ( T1 * Igate - Igs ) ;
here->HSM2_gigsb = M * ( T1 * Igate_dVbse + T1_dVb * Igate - Igs_dVbse ) ;
here->HSM2_gigsd = M * ( T1 * Igate_dVdse + T1_dVd * Igate - Igs_dVdse ) ;
here->HSM2_gigsg = M * ( T1 * Igate_dVgse + T1_dVg * Igate - Igs_dVgse ) ;
} else {
here->HSM2_igs = M * ( GLPART1 * Igate - Igd ) ;
here->HSM2_gigsb = M * ( GLPART1 * Igate_dVbse + GLPART1_dVbse * Igate - Igd_dVbse ) ;
here->HSM2_gigsd = M * ( GLPART1 * -(Igate_dVgse + Igate_dVbse + Igate_dVdse)
- Igate * ( GLPART1_dVbse + GLPART1_dVdse + GLPART1_dVgse ) + (Igs_dVgse + Igs_dVbse + Igs_dVdse) ) ;
here->HSM2_gigsg = M * ( GLPART1 * Igate_dVgse + GLPART1_dVgse * Igate - Igd_dVgse ) ;
}
here->HSM2_gigss = -(here->HSM2_gigsb + here->HSM2_gigsd + here->HSM2_gigsg) ;
here->HSM2_igidl = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl : M * Igisl ;
here->HSM2_gigidlbs = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVbse : M * Igisl_dVbse ;
here->HSM2_gigidlds = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVdse : M * ( - Igisl_dVbse - Igisl_dVdse - Igisl_dVgse ) ;
here->HSM2_gigidlgs = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igidl_dVgse : M * Igisl_dVgse ;
here->HSM2_igisl = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl : M * Igidl ;
here->HSM2_gigislbd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVbse : M * Igidl_dVbse ;
here->HSM2_gigislsd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVdse : M * ( - Igidl_dVbse - Igidl_dVdse - Igidl_dVgse ) ;
here->HSM2_gigislgd = (here->HSM2_mode == HiSIM_NORMAL_MODE) ? M * Igisl_dVgse : M * Igidl_dVgse ;
/*---------------------------------------------------*
* Von, Vdsat.
*-----------------*/
here->HSM2_von = Vth ;
here->HSM2_vdsat = Vdsat ;
/*---------------------------------------------------*
* Junction diode.
*-----------------*/
here->HSM2_ibs = M * Ibs ;
here->HSM2_ibd = M * Ibd ;
here->HSM2_gbs = M * Gbse ;
here->HSM2_gbd = M * Gbde ;
*(ckt->CKTstate0 + here->HSM2qbs) = M * Qbs ;
*(ckt->CKTstate0 + here->HSM2qbd) = M * Qbd ;
here->HSM2_capbs = M * Capbse ;
here->HSM2_capbd = M * Capbde ;
/*-----------------------------------------------------------*
* Warn floating-point exceptions.
* - Function finite() in libm is called.
* - Go to start with info==5.
*-----------------*/
T1 = here->HSM2_ids + here->HSM2_gmbs + here->HSM2_gds + here->HSM2_gm ;
T1 = T1 + here->HSM2_qd + here->HSM2_cdsb ;
if ( ! finite (T1) ) {
flg_err = 1 ;
fprintf (stderr ,
"*** warning(HiSIM): FP-exception (PART-1)\n" ) ;
if ( flg_info >= 1 ) {
printf ( "*** warning(HiSIM): FP-exception\n") ;
printf ( "here->HSM2_ids = %12.5e\n" , here->HSM2_ids ) ;
printf ( "here->HSM2_gmbs = %12.5e\n" , here->HSM2_gmbs) ;
printf ( "here->HSM2_gds = %12.5e\n" , here->HSM2_gds ) ;
printf ( "here->HSM2_gm = %12.5e\n" , here->HSM2_gm ) ;
printf ( "here->HSM2_qd = %12.5e\n" , here->HSM2_qd ) ;
printf ( "here->HSM2_cdsb = %12.5e\n" , here->HSM2_cdsb) ;
}
}
T1 = here->HSM2_isub + here->HSM2_gbbs + here->HSM2_gbds + here->HSM2_gbgs ;
if ( ! finite (T1) ) {
flg_err = 1 ;
fprintf (stderr ,
"*** warning(HiSIM): FP-exception (PART-2)\n") ;
if ( flg_info >= 1 ) {
printf ("*** warning(HiSIM): FP-exception\n") ;
}
}
T1 = here->HSM2_cgbo + Cgdo + Cgso + Cggo ;
if ( ! finite (T1) ) {
flg_err = 1 ;
fprintf(stderr ,
"*** warning(HiSIM): FP-exception (PART-3)\n") ;
if ( flg_info >= 1 ) {
printf ("*** warning(HiSIM): FP-exception\n") ;
}
}
T1 = here->HSM2_ibs + here->HSM2_ibd + here->HSM2_gbs + here->HSM2_gbd ;
T1 = T1 + *(ckt->CKTstate0 + here->HSM2qbs) + *(ckt->CKTstate0 + here->HSM2qbd)
+ here->HSM2_capbs + here->HSM2_capbd ;
if ( ! finite (T1) ) {
flg_err = 1 ;
fprintf(stderr ,
"*** warning(HiSIM): FP-exception (PART-4)\n") ;
if ( flg_info >= 1 ) {
printf ("*** warning(HiSIM): FP-exception\n") ;
}
}
/*-----------------------------------------------------------*
* Exit for error case.
*-----------------*/
if ( flg_err != 0 ) {
fprintf (stderr , "----- bias information (HiSIM)\n" ) ;
fprintf (stderr , "name: %s\n" , here->HSM2name ) ;
fprintf (stderr , "stetes: %d\n" , here->HSM2states ) ;
fprintf (stderr , "vds= %12.5e vgs=%12.5e vbs=%12.5e\n"
, vds , vgs , vbs ) ;
fprintf (stderr , "vbs_jct= %12.5e vbd_jct= %12.5e\n"
, vbs_jct , vbd_jct ) ;
fprintf (stderr , "vd= %12.5e vg= %12.5e vb= %12.5e vs= %12.5e\n"
, *( ckt->CKTrhsOld + here->HSM2dNodePrime )
, *( ckt->CKTrhsOld + here->HSM2gNodePrime )
, *( ckt->CKTrhsOld + here->HSM2bNodePrime )
, *( ckt->CKTrhsOld + here->HSM2sNodePrime ) ) ;
if ( here->HSM2_called >= 1 ) {
fprintf (stderr , "vdsc_prv= %12.5e vgsc_prv=%12.5e vbsc_prv=%12.5e\n"
, here->HSM2_vdsc_prv , here->HSM2_vgsc_prv
, here->HSM2_vbsc_prv ) ;
}
fprintf (stderr , "----- bias information (end)\n" ) ;
}
if ( flg_err != 0 ) return ( HiSIM_ERROR ) ;
/*-----------------------------------------------------------*
* Noise.
*-----------------*/
here->HSM2_noiflick = M * Nflic ;
here->HSM2_noithrml = M * Nthrml ;
/*----------------------------------------------------------*
* induced gate noise. ( Part 3/3 )
*----------------------*/
if ( model->HSM2_coign != 0 && model->HSM2_cothrml != 0 && flg_ign == 1 && !flg_noqi ) {
T0 = Cox_small * Cox * here->HSM2_weff_nf * Leff ;
T1 = here->HSM2_cgsb / M ;
if( - T1 > T0 ){
Nign0 = c_16o135 * C_QE * beta_inv * T1 * T1 / gds0_ign ;
if ( kusai00L > epsm10 && Vds > epsm10 ) {
MuModA = Muun / Mu ;
MuModB = ( Muun / Mud_hoso - MuModA ) / Vds ;
correct_w1 = MuModA + C_2o3 * MuModB
* ( kusai00 + VgVt * sqrtkusaiL + kusaiL )
/ ( VgVt + sqrtkusaiL ) ;
} else {
correct_w1 = Muun / Mud_hoso ;
}
here->HSM2_noiigate = M * Nign0 * kusai_ig * correct_w1 ;
here->HSM2_noicross = crl_f ;
if ( here->HSM2_noiigate < 0.0 ) here->HSM2_noiigate = 0.0e0 ;
}else{
here->HSM2_noiigate = 0.0e0 ;
here->HSM2_noicross = 0.0e0 ;
}
here->HSM2_Qdrat = Qdrat ; /* needed for calculating induced gate noise */
}else{
here->HSM2_noiigate = 0.0e0 ;
here->HSM2_noicross = 0.0e0 ;
}
/*-----------------------------------------------------------*
* Restore values for next calculation.
*-----------------*/
/* Confined biases */
if ( here->HSM2_called >= 1 ) {
here->HSM2_vbsc_prv2 = here->HSM2_vbsc_prv ;
here->HSM2_vdsc_prv2 = here->HSM2_vdsc_prv ;
here->HSM2_vgsc_prv2 = here->HSM2_vgsc_prv ;
here->HSM2_mode_prv2 = here->HSM2_mode_prv ;
}
here->HSM2_vbsc_prv = Vbsc ;
here->HSM2_vdsc_prv = Vdsc ;
here->HSM2_vgsc_prv = Vgsc ;
here->HSM2_mode_prv = here->HSM2_mode ;
/* Surface potentials and derivatives w.r.t. internal biases */
if ( here->HSM2_called >= 1 ) {
here->HSM2_ps0_prv2 = here->HSM2_ps0_prv ;
here->HSM2_ps0_dvbs_prv2 = here->HSM2_ps0_dvbs_prv ;
here->HSM2_ps0_dvds_prv2 = here->HSM2_ps0_dvds_prv ;
here->HSM2_ps0_dvgs_prv2 = here->HSM2_ps0_dvgs_prv ;
here->HSM2_pds_prv2 = here->HSM2_pds_prv ;
here->HSM2_pds_dvbs_prv2 = here->HSM2_pds_dvbs_prv ;
here->HSM2_pds_dvds_prv2 = here->HSM2_pds_dvds_prv ;
here->HSM2_pds_dvgs_prv2 = here->HSM2_pds_dvgs_prv ;
}
here->HSM2_ps0_prv = Ps0 ;
here->HSM2_ps0_dvbs_prv = Ps0_dVbs ;
here->HSM2_ps0_dvds_prv = Ps0_dVds ;
here->HSM2_ps0_dvgs_prv = Ps0_dVgs ;
here->HSM2_pds_prv = Pds ;
here->HSM2_pds_dvbs_prv = Pds_dVbs ;
here->HSM2_pds_dvds_prv = Pds_dVds ;
here->HSM2_pds_dvgs_prv = Pds_dVgs ;
/* Derivatives of channel current w.r.t. internal biases */
here->HSM2_ids_prv = Ids ;
here->HSM2_ids_dvbs_prv = Ids_dVbs ;
here->HSM2_ids_dvds_prv = Ids_dVds ;
here->HSM2_ids_dvgs_prv = Ids_dVgs ;
/* For CORECIP = 1 */
if ( corecip ) {
here->HSM2_PS0Z_SCE_prv = PS0Z_SCE ;
here->HSM2_PS0Z_SCE_dvds_prv = PS0Z_SCE_dVds ;
here->HSM2_PS0Z_SCE_dvgs_prv = PS0Z_SCE_dVgs ;
here->HSM2_PS0Z_SCE_dvbs_prv = PS0Z_SCE_dVbs ;
/* here->HSM2_nnn = NNN ; */
}
/*-----------------------------------------------------------*
* End of PART-7. (label)
*-----------------*/
/* end_of_part_7: */
/*-----------------------------------------------------------*
* Bottom of hsm2eval.
*-----------------*/
return ( HiSIM_OK ) ;
} /* end of hsm2eval */