hsm1eval102.c

来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 2,335 行 · 第 1/5 页

C
2,335
字号
    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-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 ) ) ;            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 . * - clamped 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 ) {        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 ;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?