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
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 */
|
|
|