📄 hsm1eval1_1.c
字号:
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 ) { 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 ; }/*-----------------------------------------------------------** Modify Qn0 for zone-D2.*-----------------*/ if ( Chi < znbd5 ) { Qn0_dVbs = FD2 * Qn0_dVbs + FD2_dVbs * Qn0 + ( 1.0 - FD2 ) * Qn00_dVbs - FD2_dVbs * Qn00 ; Qn0_dVds = FD2 * Qn0_dVds + FD2_dVds * Qn0 + ( 1.0 - FD2 ) * Qn00_dVds - FD2_dVds * Qn00 ; Qn0_dVgs = FD2 * Qn0_dVgs + FD2_dVgs * Qn0 + ( 1.0 - FD2 ) * Qn00_dVgs - FD2_dVgs * Qn00 ; Qn0 = FD2 * Qn0 + ( 1.0 - FD2 ) * Qn00 ; if ( Qn0 < 0.0 ) { Qn0 = 0.0 ; Qn0_dVbs = 0.0 ; Qn0_dVds = 0.0 ; Qn0_dVgs = 0.0 ; } } /*---------------------------------------------------** VgVt : Vgp - Vth_qi. ( Vth_qi is Vth for Qi evaluation. ) *-----------------*/ VgVt = Qn0 * Cox_inv ; VgVt_dVbs = Qn0_dVbs * Cox_inv + Qn0 * Cox_inv_dVbs ; VgVt_dVds = Qn0_dVds * Cox_inv + Qn0 * Cox_inv_dVds ; VgVt_dVgs = Qn0_dVgs * Cox_inv + Qn0 * Cox_inv_dVgs ;/*-----------------------------------------------------------** make Qi=Qd=Ids=0 if VgVt <= VgVt_small *-----------------*/ if ( VgVt <= VgVt_small ) { Psl = Ps0 ; Psl_dVbs = Ps0_dVbs ; Psl_dVds = Ps0_dVds ; Psl_dVgs = Ps0_dVgs ; Psdl = Psl ; Psdl_dVbs = Psl_dVbs ; Psdl_dVds = Psl_dVds ; Psdl_dVgs = Psl_dVgs ; Pds = 0.0 ; Pds_dVbs = 0.0 ; Pds_dVds = 0.0 ; Pds_dVgs = 0.0 ; T1 = - Leff * Weff ; Qb = T1 * Qb0 ; Qb_dVbs = T1 * Qb0_dVbs ; Qb_dVds = T1 * Qb0_dVds ; Qb_dVgs = T1 * Qb0_dVgs ; Qi = 0.0 ; Qi_dVbs = 0.0 ; Qi_dVds = 0.0 ; Qi_dVgs = 0.0 ; Qd = 0.0 ; Qd_dVbs = 0.0 ; Qd_dVds = 0.0 ; Qd_dVgs = 0.0 ; Ids = 0.0e0 ; Ids_dVbs = 0.0e0 ; Ids_dVds = 0.0e0 ; Ids_dVgs = 0.0e0 ; flg_noqi = 1 ; goto end_of_part_1 ; } /*-----------------------------------------------------------** Start point of Psl (= Ps0 + Pds) calculation. (label)*-----------------*/start_of_Psl: ; exp_bVbsVds = exp( beta * ( Vbs - Vds ) ) ; /*---------------------------------------------------** Skip Psl calculation when Vds is very small.*-----------------*/ if ( Vds <= epsm10 ) { Pds = 0.0 ; Psl = Ps0 ; goto end_of_loopl ; } /*-----------------------------------------------------------** Initial guess for Pds ( = Psl - Ps0 ). *-----------------*/ /*---------------------------------------------------** Use previous value.*-----------------*/ if ( flg_pprv == 1 ) { Pds_ini = Pds + Pds_dVbs * dVbs + Pds_dVds * dVds + Pds_dVgs * dVgs ; T1 = Pds_ini - Pds ; if ( T1 < - dP_max || T1 > dP_max ) { flg_pprv = 0 ; } } /*---------------------------------------------------** Analytical initial guess.*-----------------*/ if ( flg_pprv == 0 ) { Pds_max = Fn_Max( Psl_lim - Ps0 , 0.0e0 ); T1 = ( 1.0e0 + c_pslini_1 ) * Pds_max ; T2 = T1 - Vds - c_pslini_2 ; T3 = sqrt( T2 * T2 + 4.0e0 * T1 * c_pslini_2 ) ; Pds_ini = T1 - ( T2 + T3 ) / 2 ; 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.*-----------------*/ Pds = Pds_ini ; Psl = Ps0 + Pds ; /*---------------------------------------------------** Calculation of Psl by solving Poisson eqn.* (beginning of Newton loop)* - Fsl : Fsl = 0 is the equation to be solved.* - dPsl : correction value.*-----------------*/ for ( lp_sl = 1 ; lp_sl <= lp_sl_max ; lp_sl ++ ) { Chi = beta * ( Psl - Vbs ) ;/*-------------------------------------------** zone-D2. (Psl)* - 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 ) ) ; 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 ) ; if ( fsl2 >= epsm10 ) { fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; } else { fsl2 = sqrt( fb * fb + fsl1 ) ; fsl2_dPsl = beta * fb_dChi ; } Fsl = Vgp - Psl - fac1 * fsl2 ; Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; dPsl = - Fsl / Fsl_dPsl ; /*-------------------------------------------** zone-D3. (Psl)*-----------------*/ } else { Rho = beta * ( Psl - Vds ) ; exp_Rho = exp( Rho ) ; fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; if ( fsl1 < epsm10 * cnst1 ) { fsl1 = 0.0 ; fsl1_dPsl = 0.0 ; } Xil = Chi - 1.0e0 ; Xilp12 = sqrt( Xil ) ; fsl2 = sqrt( Xil + fsl1 ) ; fsl2_dPsl = ( beta + fsl1_dPsl ) / ( fsl2 + fsl2 ) ; Fsl = Vgp - Psl - fac1 * fsl2 ; Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; dPsl = - Fsl / Fsl_dPsl ; }/*-------------------------------------------** Update Psl .* - cramped to Vbs if Psl < Vbs .*-----------------*/ if ( fabs( dPsl ) > dP_max ) { dPsl = fabs( dP_max ) * Fn_Sgn( dPsl ) ; } Psl = Psl + dPsl ; if ( Psl < Vbs ) { Psl = Vbs ; }/*-------------------------------------------** Check convergence.* NOTE: This condition may be too rigid.*-----------------*/ if ( fabs( dPsl ) <= ps_conv && fabs( Fsl ) <= gs_conv ) { break ; } } /* end of Psl Newton loop *//*-------------------------------------------** Procedure for diverged case.*-----------------*/ if ( lp_sl > lp_sl_max ) { 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" ) ; } }/*---------------------------------------------------** End of Psl calculation. (label)*-----------------*/end_of_loopl: ;/*---------------------------------------------------** Assign Pds.*-----------------*/ Pds = Psl - Ps0 ; if ( Pds < ps_conv ) { Pds = 0.0 ; Psl = Ps0 ; }/*---------------------------------------------------** 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.*-----------------*/ Chi = beta * ( Psl - Vbs ) ;/*-------------------------------------------** zone-D2. (Psl)*-----------------*/ 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 ) ) ; /*note: cfs1 = cnst1 * exp_bVbsVds */ fsl1 = cfs1 * fi * fi ; fsl1_dPsl = cfs1 * beta * 2 * fi * fi_dChi ; fsl1_dVbs = cfs1 * beta * fi * ( fi - 2 * fi_dChi ) ; fsl1_dVds = - cfs1 * beta * fi * fi ; 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 ) ; T2 = 0.5 / fsl2 ; if ( fsl2 >= epsm10 ) { fsl2_dPsl = ( beta * fb_dChi * 2 * fb + fsl1_dPsl ) * T2 ; fsl2_dVbs = ( - beta * fb_dChi * 2 * fb + fsl1_dVbs ) * T2 ; fsl2_dVds = fsl1_dVds * T2 ; } else { fsl2_dPsl = beta * fb_dChi ; fsl2_dVbs = - beta * fb_dChi ; fsl2_dVds = 0.0 ; } /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; Psl_dVbs = - ( Vgp_dVbs - ( fac1 * fsl2_dVbs + fac1_dVbs * fsl2 ) ) / Fsl_dPsl ; Psl_dVds = - ( Vgp_dVds - ( fac1 * fsl2_dVds + fac1_dVds * fsl2 ) ) / Fsl_dPsl ; Psl_dVgs = - ( Vgp_dVgs - fac1_dVgs * fsl2 ) / Fsl_dPsl ; Pds_dVbs = Psl_dVbs - Ps0_dVbs ; Pds_dVds = Psl_dVds - Ps0_dVds ; Pds_dVgs = Psl_dVgs - Ps0_dVgs ; Xil = Chi - 1.0e0 ; Xilp12 = sqrt( Xil ) ; Xilp32 = Xil * Xilp12 ; /*-------------------------------------------** zone-D3. (Psl)*-----------------*/ } else { Rho = beta * ( Psl - Vds ) ; exp_Rho = exp( Rho ) ; fsl1 = cnst1 * ( exp_Rho - exp_bVbsVds ) ; fsl1_dPsl = cnst1 * beta * ( exp_Rho ) ; fsl1_dVbs = - cnst1 * beta * exp_bVbsVds ; fsl1_dVds = - beta * fsl1 ; if ( fsl1 < epsm10 * T1 ) { fsl1 = 0.0 ; fsl1_dPsl = 0.0 ; fsl1_dVds = 0.0 ; } Xil = Chi - 1.0e0 ; Xilp12 = sqrt( Xil ) ; Xilp32 = Xil * Xilp12 ; fsl2 = sqrt( Xil + fsl1 ) ; T2 = 0.5e0 / fsl2 ; fsl2_dPsl = ( beta + fsl1_dPsl ) * T2 ; fsl2_dVbs = ( - beta + fsl1_dVbs ) * T2 ; fsl2_dVds = ( fsl1_dVds ) * T2 ; /* memo: Fsl = Vgp - Psl - fac1 * fsl2 */ T2 = 0.5e0 / Xilp12 ; Fsl_dPsl = - 1.0e0 - fac1 * fsl2_dPsl ; Psl_dVbs = - ( Vgp_dVbs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -