📄 hsm1eval1_0.c
字号:
T3 = beta + 2.0 / Vgp ; Ps0_iniB = log( T2 ) / T3 ; T1 = Ps0_iniB - Ps0_iniA - c_ps0ini_2 ; T2 = sqrt( T1 * T1 + 4.0e0 * c_ps0ini_2 * Ps0_iniB ) ; Ps0_ini = Ps0_iniB - ( T1 + T2 ) / 2 ; } } if ( Ps0_ini < Vbs ) { Ps0_ini = Vbs ; } /*---------------------------------------------------** Assign initial guess.*-----------------*/ 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 ; for ( lp_s0 = 1 ; lp_s0 <= lp_s0_max ; lp_s0 ++ ) { Chi = beta * ( Ps0 - Vbs ) ; exp_Chi = exp( Chi ) ; fs01 = cfs1 * ( exp_Chi - 1.0e0 ) ; fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; if ( fs01 < epsm10 * cfs1 ) { fs01 = 0.0 ; fs01_dPs0 = 0.0 ; }/*-------------------------------------------** zone-D1/D2. (Ps0)* - Qb0 is approximated to 5-dgree polynomial.*-----------------*/ if ( Chi < znbd5 ) { 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 ) ; if ( fs02 >= epsm10 ) { fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) / ( fs02 + fs02 ) ; } else { fs02 = sqrt( fb * fb + fs01 ) ; fs02_dPs0 = beta * fb_dChi ; } Fs0 = Vgp - Ps0 - fac1 * fs02 ; Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; dPs0 = - Fs0 / Fs0_dPs0 ; /*-------------------------------------------** zone-D3. (Ps0)*-----------------*/ } else { Xi0 = Chi - 1.0e0 ; Xi0p12 = sqrt( Xi0 ) ; fs02 = sqrt( Xi0 + fs01 ) ; fs02_dPs0 = ( beta + fs01_dPs0 ) / ( fs02 + fs02 ) ; Fs0 = Vgp - Ps0 - fac1 * fs02 ; Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; dPs0 = - Fs0 / Fs0_dPs0 ; } /* end of if ( Chi ... ) else block */ /*-------------------------------------------** Update Ps0 . * - cramped to Vbs if Ps0 < Vbs . *-----------------*/ if ( fabs( dPs0 ) > dP_max ) { dPs0 = fabs( dP_max ) * Fn_Sgn( dPs0 ) ; } Ps0 = Ps0 + dPs0 ; if ( Ps0 < Vbs ) { Ps0 = Vbs ; } /*-------------------------------------------** Check convergence. * NOTE: This condition may be too rigid. *-----------------*/ if ( fabs( dPs0 ) <= ps_conv && fabs( Fs0 ) <= gs_conv ) { break ; } } /* end of Ps0 Newton loop */ /*-------------------------------------------** Procedure for diverged case.*-----------------*/ if ( lp_s0 > lp_s0_max ) { 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.*-----------------*/ Chi = beta * ( Ps0 - Vbs ) ; exp_Chi = exp( Chi ) ; cfs1 = cnst1 * exp_bVbs ; if ( fs01 < epsm10 * cfs1 ) { fs01 = 0.0 ; fs01_dPs0 = 0.0 ; fs01_dVbs = 0.0 ; } /*-------------------------------------------** zone-D1/D2. (Ps0)*-----------------*/ if ( Chi < znbd5 ) { 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 ; fs01_dVbs = cfs1 * beta * fi * ( fi - 2 * 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 ) ; T2 = 1.0e0 / ( fs02 + fs02 ) ; if ( fs02 >= epsm10 ) { fs02_dPs0 = ( beta * fb_dChi * 2 * fb + fs01_dPs0 ) * T2 ; fs02_dVbs = ( - beta * fb_dChi * 2 * fb + fs01_dVbs ) * T2 ; } else { fs02_dPs0 = beta * fb_dChi ; fs02_dVbs = - beta * fb_dChi ; } /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; Ps0_dVbs = - ( Vgp_dVbs - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) ) / Fs0_dPs0 ; Ps0_dVds = - ( Vgp_dVds - fac1_dVds * fs02 ) / Fs0_dPs0 ; Ps0_dVgs = - ( Vgp_dVgs - fac1_dVgs * fs02 ) / Fs0_dPs0 ; T1 = cnst0 ; Qb0 = T1 * fb ; Qb0_dVbs = ( Ps0_dVbs - 1.0e0 ) * T1 * beta * fb_dChi ; Qb0_dVds = Ps0_dVds * T1 * beta * fb_dChi ; Qb0_dVgs = Ps0_dVgs * T1 * beta * fb_dChi ; 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 ; T1 = 1.0 / ( fs02 + fb * fb ) ; T2 = T1 * T1 ; Qn0 = cnst0 * fs01 * T1 ; T3 = 2.0 * fb_dChi * fb * beta ; Qn0_dVbs = cnst0 * ( fs01_dVbs * T1 - fs01 * ( fs02_dVbs + T3 * ( Ps0_dVbs - 1.0 ) ) * T2 ) ; Qn0_dVds = cnst0 * ( fs01_dVds * T1 - fs01 * ( fs02_dVds + T3 * Ps0_dVds ) * T2 ) ; Qn0_dVgs = cnst0 * ( fs01_dVgs * T1 - fs01 * ( fs02_dVgs + T3 * Ps0_dVgs ) * T2 ) ;/*-------------------------------------------** zone-D1. (Ps0)* - Evaluate basic characteristics and exit from this part.*-----------------*/ if ( Chi < znbd3 ) { 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 ; T1 = - Weff * Leff ; Qb = T1 * Qb0 ; Qb_dVbs = T1 * Qb0_dVbs ; Qb_dVds = T1 * Qb0_dVds ; Qb_dVgs = T1 * Qb0_dVgs ; if ( Qn0 < Cox * VgVt_small ) { Qn0 = 0.0 ; Qn0_dVbs = 0.0 ; Qn0_dVds = 0.0 ; Qn0_dVgs = 0.0 ; } Qi = T1 * Qn0 ; Qi_dVbs = T1 * Qn0_dVbs ; Qi_dVds = T1 * Qn0_dVds ; Qi_dVgs = T1 * Qn0_dVgs ; Qd = 0.0e0 ; Qd_dVbs = 0.0e0 ; Qd_dVds = 0.0e0 ; Qd_dVgs = 0.0e0 ; Ids = 0.0e0 ; Ids_dVbs = 0.0e0 ; Ids_dVds = 0.0e0 ; Ids_dVgs = 0.0e0 ; VgVt = 0.0 ; flg_noqi = 1 ; goto end_of_part_1 ; } /*-------------------------------------------** zone-D2*-----------------*/ Xi0 = Chi - 1.0e0 ; Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; Xi0_dVds = beta * Ps0_dVds ; Xi0_dVgs = beta * Ps0_dVgs ; Xi0p12 = sqrt( Xi0 ) ; Xi0p32 = Xi0 * Xi0p12 ; Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; Qn00 = Qn0 ; Qn00_dVbs = Qn0_dVbs ; Qn00_dVds = Qn0_dVds ; Qn00_dVgs = Qn0_dVgs ; fs01 = cfs1 * ( exp_Chi - 1.0 ) ; fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; fs01_dVbs = - cfs1 * beta ; fs02 = sqrt( Xi0 + fs01 ) ; T2 = 0.5e0 / fs02 ; fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; flg_noqi = 0 ; /*-------------------------------------------** zone-D3. (Ps0)*-----------------*/ } else { fs01 = cfs1 * ( exp_Chi - 1.0 ) ; fs01_dPs0 = cfs1 * beta * ( exp_Chi ) ; fs01_dVbs = - cfs1 * beta ; Xi0 = Chi - 1.0e0 ; Xi0p12 = sqrt( Xi0 ) ; Xi0p32 = Xi0 * Xi0p12 ; fs02 = sqrt( Xi0 + fs01 ) ; T2 = 0.5e0 / fs02 ; fs02_dPs0 = ( beta + fs01_dPs0 ) * T2 ; fs02_dVbs = ( - beta + fs01_dVbs ) * T2 ; /* memo: Fs0 = Vgp - Ps0 - fac1 * fs02 */ T2 = 0.5e0 / Xi0p12 ; Fs0_dPs0 = - 1.0e0 - fac1 * fs02_dPs0 ; Ps0_dVbs = - ( Vgp_dVbs - ( fac1 * fs02_dVbs + fac1_dVbs * fs02 ) ) / Fs0_dPs0 ; Ps0_dVds = - ( Vgp_dVds - fac1_dVds * fs02 ) / Fs0_dPs0 ; Ps0_dVgs = - ( Vgp_dVgs - fac1_dVgs * fs02 ) / Fs0_dPs0 ; Xi0_dVbs = beta * ( Ps0_dVbs - 1.0e0 ) ; Xi0_dVds = beta * Ps0_dVds ; Xi0_dVgs = beta * Ps0_dVgs ; Xi0p12_dVbs = 0.5e0 * Xi0_dVbs / Xi0p12 ; Xi0p12_dVds = 0.5e0 * Xi0_dVds / Xi0p12 ; Xi0p12_dVgs = 0.5e0 * Xi0_dVgs / Xi0p12 ; Xi0p32_dVbs = 1.5e0 * Xi0_dVbs * Xi0p12 ; Xi0p32_dVds = 1.5e0 * Xi0_dVds * Xi0p12 ; Xi0p32_dVgs = 1.5e0 * Xi0_dVgs * Xi0p12 ; flg_noqi = 0 ; } /* end of if ( Chi ... ) block */ /*-----------------------------------------------------------** NOTE: The following sections of this part are only for * the conductive case. *-----------------*//*-----------------------------------------------------------** Xi0 : beta * ( Ps0 - Vbs ) - 1 = Chi - 1 .*-----------------*//*-----------------------------------------------------------** Qn0 : Qi at source side.* - Qn0 := cnst0 * ( ( Xi0 + fs01 )^(1/2) - ( Xi0 )^(1/2) ) * - Derivatives of fs01 are redefined here.*-----------------*//* note:------------------------* fs01 = cnst1 * exp( Vbs ) * ( exp( Chi ) - Chi - 1.0e0 ) ;* fs02 = sqrt( Xi0 + fs01 ) ;*-------------------------------*/ Qn0 = cnst0 * fs01 / ( fs02 + Xi0p12 ) ; 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 ; Qn0_dVbs = Qn0 * ( fs01_dVbs / fs01 - ( fs02_dVbs + Xi0p12_dVbs ) / ( fs02 + Xi0p12 ) ) ; Qn0_dVds = Qn0 * ( fs01_dVds / fs01 - ( fs02_dVds + Xi0p12_dVds ) / ( fs02 + Xi0p12 ) ) ; Qn0_dVgs = Qn0 * ( fs01_dVgs / fs01 - ( fs02_dVgs + Xi0p12_dVgs ) / ( fs02 + Xi0p12 ) ) ;/*-----------------------------------------------------------** Qb0 : Qb at source side.*-----------------*/ if ( Chi > znbd5 ) { Qb0 = cnst0 * Xi0p12 ; Qb0_dVbs = cnst0 * Xi0p12_dVbs ; Qb0_dVds = cnst0 * Xi0p12_dVds ; Qb0_dVgs = cnst0 * Xi0p12_dVgs ; }/*-----------------------------------------------------------** FD2 : connecting function for zone-D2.*-----------------*/ if ( Chi < znbd5 ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -