hsm1eval102.c
来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 2,335 行 · 第 1/5 页
C
2,335 行
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)* not really being used so commenting out*-----------------*//*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-degree 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 .* - clamped 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 - ( 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 ; } if ( Pds < ps_conv ) { Pds_dVbs = 0.0 ; Pds_dVgs = 0.0 ; Psl_dVbs = Ps0_dVbs ; Psl_dVgs = Ps0_dVgs ; }/*-----------------------------------------------------------** Evaluate Qb and Idd. * - Eta : substantial variable of QB'/Pds and Idd/Pds. * - note: Eta = 4 * GAMMA_{hisim_0} *-----------------*/ Eta = beta * Pds / Xi0 ; Eta_dVbs = beta * ( Pds_dVbs - ( Ps0_dVbs - 1.0e0 ) * Eta ) / Xi0 ; Eta_dVds = beta * ( Pds_dVds - Ps0_dVds * Eta ) / Xi0 ; Eta_dVgs = beta * ( Pds_dVgs - Ps0_dVgs * Eta ) / Xi0 ; /* ( 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 = - 0.5e0 / Xi0p32 ; T4 = - 0.5e0 / Eta1p12 * F00 ; F00_dVbs = Zeta12 * ( Xi0_dVbs * T3 + Eta_dVbs * T4 ) ; F00_dVds = Zeta12 * ( Xi0_dVds * T3 + Eta_dVds * T4 ) ; F00_dVgs = Zeta12 * ( Xi0_dVgs * T3 + Eta_dVgs * T4 ) ;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?