hsm1eval102.c
来自「ngspice又一个电子CAD仿真软件代码.功能更全」· C语言 代码 · 共 2,335 行 · 第 1/5 页
C
2,335 行
/*-----------------------------------------------------------** Change units into CGS.* - This section may be moved to an interface routine.*-----------------*//* device instances */ sIN.xl *= C_m2cm ; sIN.xw *= C_m2cm ; sIN.as *= C_m2cm_p2 ; sIN.ad *= C_m2cm_p2 ; sIN.ps *= C_m2cm ; sIN.pd *= C_m2cm ;/* model parameters */ sIN.tox *= C_m2cm ; sIN.xld *= C_m2cm ; sIN.xwd *= C_m2cm ; sIN.xj *= C_m2cm ; sIN.lp *= C_m2cm ; sIN.xpolyd *= C_m2cm ; sIN.tpoly *= C_m2cm ; sIN.rs *= C_m2cm ; sIN.rd *= C_m2cm ; sIN.sc3 *= C_m2cm ; sIN.scp3 *= C_m2cm ; sIN.parl2 *= C_m2cm ; sIN.wfc *= C_m2cm ; sIN.rpock1 *= C_m2cm_p1o2 ; sIN.qme1 *= C_m2cm ; sIN.qme3 *= C_m2cm ; sIN.gidl1 /= C_m2cm_p1o2 ; sIN.cgso /= C_m2cm ; sIN.cgdo /= C_m2cm ; sIN.cgbo /= C_m2cm ; sIN.js0 /= C_m2cm_p2 ; sIN.js0sw /= C_m2cm ; sIN.cj /= C_m2cm_p2 ; sIN.cjsw /= C_m2cm ; sIN.cjswg /= C_m2cm ;/*-----------------------------------------------------------** Start of the routine. (label) not being used so commenting out*-----------------*//*start_of_routine:*//*-----------------------------------------------------------** Temperature dependent constants. *-----------------*/ /* Inverse of the thermal voltage */ beta = C_QE / ( C_KB * sIN.temp ) ; beta2 = beta * beta ; /* Band gap */ Eg = C_Eg0 - sIN.temp * ( sIN.bgtmp1 + sIN.temp * sIN.bgtmp2 ) ; Eg300 = C_Eg0 - C_T300 * ( sIN.bgtmp1 + C_T300 * sIN.bgtmp2 ) ;/* Intrinsic carrier concentration */ Nin = C_Nin0 * pow( sIN.temp / C_T300 , 1.5e0 ) * exp( - Eg / 2.0e0 * beta + Eg300 / 2.0e0 * C_b300 ) ;/*-----------------------------------------------------------** Fixed part. *-----------------*//* Lgate in [cm] / [m] */ Lgate = sIN.xl + 2.0e0 * sIN.xpolyd ; Wgate = sIN.xw + 2.0e0 * sIN.xpolyd ; /* Phonon Scattering */ T1 = log( Wgate ) ; T2 = sIN.w0 - T1 - sti_dlt ; T3 = T2 * T2 ; T4 = sqrt( T3 + 4.0 * sti_dlt * sIN.w0 ) ; T5 = sIN.w0 - ( T2 - T4 ) / 2 ; mueph = sIN.mueph1 + sIN.mueph2 * T5 ; /* Metallurgical channel geometry */ Weff = Wgate - 2.0e0 * sIN.xwd ; Leff = Lgate - 2.0e0 * sIN.xld ; Leff_inv = 1.0e0 / Leff ; /* Flat band voltage */ Vfb = sIN.vfbc ; /* Surface impurity profile */ if( Leff > sIN.lp ){ Nsub = ( sIN.nsubc * ( Leff - sIN.lp ) + sIN.nsubp * sIN.lp ) / Leff ; } else { Nsub = sIN.nsubp + ( sIN.nsubp - sIN.nsubc ) * ( sIN.lp - Leff ) / sIN.lp ; } q_Nsub = C_QE * Nsub ; /* 2 phi_B */ /* @temp, with pocket */ Pb2 = 2.0e0 / beta * log( Nsub / Nin ) ; /* @300K, with pocket */ Pb20 = 2.0e0 / C_b300 * log( Nsub / C_Nin0 ) ; /* @300K, w/o pocket */ Pb2c = 2.0e0 / C_b300 * log( sIN.nsubc / C_Nin0 ) ;/* Debye length */ Ldby = sqrt( C_ESI / beta / q_Nsub ) ; /* Coefficient of the F function for bulk charge */ cnst0 = q_Nsub * Ldby * C_SQRT_2 ; /* cnst1: n_{p0} / p_{p0} */ T1 = Nin / Nsub ; cnst1 = T1 * T1 ;/* Cox (clasical) */ Cox0 = C_EOX / sIN.tox ;/*-----------------------------------------------------------** Exchange bias conditions according to MOS type.* - Vxse are external biases for HiSIM. ( type=NMOS , Vds >= 0* are assumed.) *-----------------*/ /* Vbse = sIN.type * sIN.vbs ; Vdse = sIN.type * sIN.vds ; Vgse = sIN.type * sIN.vgs ; Vbde = Vbse - Vdse ; */ /* modified by K. M. for SPICE3f5 */ Vbse = sIN.vbs ; Vdse = sIN.vds ; Vgse = sIN.vgs ; Vbde = Vbse - Vdse ;/*---------------------------------------------------** Clamp too large biases. * -note: Quantities are extrapolated in PART-5.*-----------------*/ if ( Vbse < Vbs_min ) { flg_vbsc = -1 ; Vbsc = Vbs_min ; } else if ( Vbse > 0.0 ) { flg_vbsc = 1 ; T1 = Vbse / Vbs_max ; T2 = sqrt ( 1.0 + ( T1 * T1 ) ) ; Vbsc = Vbse / T2 ; Vbsc_dVbse = Vbs_max * Vbs_max / ( ( Vbs_max * Vbs_max + Vbse * Vbse ) * T2 ) ; } else { flg_vbsc = 0 ; Vbsc = Vbse ; } if ( Vdse > Vds_max ) { flg_vdsc = 1 ; Vdsc = Vds_max ; } else { flg_vdsc = 0 ; Vdsc = Vdse ; } if ( Vgse > Vgs_max ) { flg_vgsc = 1 ; Vgsc = Vgs_max ; } else { flg_vgsc = 0 ; Vgsc = Vgse ; } if ( Vbde < Vbd_min ) { flg_vbdc = -1 ; Vbdc = Vbd_min ; } else if ( Vbde > Vbd_max ) { Vbdc = Vbd_max ; flg_vbdc = 1 ; } else { Vbdc = Vbde ; flg_vbdc = 0 ; } if ( flg_vbsc == -1 || flg_vdsc != 0 || flg_vgsc != 0 || flg_vbdc != 0 ) { flg_vxxc = 1 ; }/*-------------------------------------------------------------------** Set flags. *-----------------*/ flg_rsrd = 0 ; flg_iprv = 0 ; flg_pprv = 0 ; if (sIN.mode == HiSIM_NORMAL_MODE) { Rs = sIN.rs / Weff ; Rd = sIN.rd / Weff ; } else { Rd = sIN.rs / Weff ; Rs = sIN.rd / Weff ; } if ( Rs + Rd >= epsm10 && sIN.corsrd >= 1 ) { flg_rsrd = 1 ; } if ( sIN.has_prv == 1 ) { Vbsc_dif = Vbsc - sIN.vbsc_prv ; Vdsc_dif = Vdsc - sIN.vdsc_prv ; Vgsc_dif = Vgsc - sIN.vgsc_prv ; sum_vdif = fabs( Vbsc_dif ) + fabs( Vdsc_dif ) + fabs( Vgsc_dif ) ; if ( sIN.coiprv >= 1 && sum_vdif <= vtol_iprv ) { flg_iprv = 1 ;} if ( sIN.copprv >= 1 && sum_vdif <= vtol_pprv ) { flg_pprv = 1 ;} } if ( flg_rsrd == 0 ) { lp_bs_max = 1 ; flg_iprv = 0 ; }/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++** Bias loop: iteration to solve the system of equations of * the small circuit taking account Rs and Rd.* - Vxs are internal (or effective) biases.* - Equations:* Vbs = Vbsc - Rs * Ids* Vds = Vdsc - ( Rs + Rd ) * Ids* Vgs = Vgsc - Rs * Ids*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//*-----------------------------------------------------------** Initial guesses for biases.*-----------------*/ if ( flg_iprv == 1 ) { sIN.ids_dvbs_prv = Fn_Max( 0.0 , sIN.ids_dvbs_prv ) ; sIN.ids_dvds_prv = Fn_Max( 0.0 , sIN.ids_dvds_prv ) ; sIN.ids_dvgs_prv = Fn_Max( 0.0 , sIN.ids_dvgs_prv ) ; dVbs = Vbsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * sIN.ids_dvbs_prv ) ) ; dVds = Vdsc_dif * ( 1.0 - 1.0 / ( 1.0 + ( Rs + Rd ) * sIN.ids_dvds_prv ) ) ; dVgs = Vgsc_dif * ( 1.0 - 1.0 / ( 1.0 + Rs * sIN.ids_dvgs_prv ) ) ; /* Ids = sIN.type * sIN.ids_prv + sIN.ids_dvbs_prv * dVbs + sIN.ids_dvds_prv * dVds + sIN.ids_dvgs_prv * dVgs ; */ Ids = sIN.ids_prv + sIN.ids_dvbs_prv * dVbs + sIN.ids_dvds_prv * dVds + sIN.ids_dvgs_prv * dVgs ; T1 = ( Ids - sIN.ids_prv ) ; T2 = fabs( T1 ) ; if ( Ids_maxvar * sIN.ids_prv < T2 ) { Ids = sIN.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 ; } } Vbs = Vbsc - Ids * Rs ; Vds = Vdsc - Ids * ( Rs + Rd ) ; if ( Vds * Vdsc <= 0.0 ) { Vds = 0.0 ; } Vgs = Vgsc - Ids * Rs ; if ( flg_pprv == 1 ) { Ps0 = sIN.ps0_prv ; Ps0_dVbs = sIN.ps0_dvbs_prv ; Ps0_dVds = sIN.ps0_dvds_prv ; Ps0_dVgs = sIN.ps0_dvgs_prv ; Pds = sIN.pds_prv ; Pds_dVbs = sIN.pds_dvbs_prv ; Pds_dVds = sIN.pds_dvds_prv ; Pds_dVgs = sIN.pds_dvgs_prv ; }/*-----------------------------------------------------------** start of the loop.*-----------------*/ for ( lp_bs = 1 ; lp_bs <= lp_bs_max ; lp_bs ++ ) { Ids_last = Ids ;/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * PART-1: Basic device characteristics. *++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /*-----------------------------------------------------------** Initialization. *-----------------*/ /* Initialization of counters is needed for restart. */ lp_s0 = 0 ; lp_sl = 0 ; /*-----------------------------------------------------------** Vxsz: Modified bias introduced to realize symmetry at Vds=0.*-----------------*/ T1 = exp( - Vbsc_dVbse * Vds / ( 2.0 * sIN.vzadd0 ) ) ; Vzadd = sIN.vzadd0 * T1 ; Vzadd_dVds = - 0.5 * Vbsc_dVbse * T1 ; if ( Vzadd < ps_conv ) { Vzadd = 0.0 ; Vzadd_dVds = 0.0 ; } Vbsz = Vbs + Vzadd ; Vbsz_dVbs = 1.0 ; Vbsz_dVds = Vzadd_dVds ; Vdsz = Vds + 2 * Vzadd ; Vdsz_dVds = 1.0 + 2 * Vzadd_dVds ; Vgsz = Vgs + Vzadd ; Vgsz_dVgs = 1.0 ; Vgsz_dVds = Vzadd_dVds ;/*-----------------------------------------------------------** Quantum effect*-----------------*/ T1 = 2.0 * q_Nsub * C_ESI ; T2 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; Vthq = Pb20 + Vfb + sIN.tox / C_EOX * T2 + sIN.qme2 ; T3 = - 0.5 * sIN.tox / C_EOX * T1 / T2 ; Vthq_dVbs = T3 * Vbsz_dVbs ; Vthq_dVds = T3 * Vbsz_dVds ; T1 = - sIN.qme2 ; T2 = Vgsz - Vthq ; T3 = sIN.qme1 * T1 * T1 + sIN.qme3 ; T4 = sIN.qme1 * T2 * T2 + sIN.qme3 ; T5 = T4 - T3 - qme_dlt ; T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; dTox = T4 - 0.5 * ( T5 + T6 ) ; /* dTox_dT4 */ T7 = 1.0 - 0.5 * ( 1.0 + ( T4 - T3 + qme_dlt ) / T6 ) ; T8 = 2.0 * sIN.qme1 * T2 * T7 ; dTox_dVbs = T8 * ( - Vthq_dVbs ) ; dTox_dVds = T8 * ( Vgsz_dVds - Vthq_dVds ) ; dTox_dVgs = T8 * ( Vgsz_dVgs ) ; if ( Vgsz - Vthq > 0 ) { T4 = sIN.qme3 ; T5 = T4 - T3 - qme_dlt ; T6 = sqrt( T5 * T5 + 4.0 * qme_dlt * T4 ) ; dTox = T4 - 0.5 * ( T5 + T6 ) ; dTox_dVbs = 0.0 ; dTox_dVds = 0.0 ; dTox_dVgs = 0.0 ; } Tox = sIN.tox + dTox ; Tox_dVbs = dTox_dVbs ; Tox_dVds = dTox_dVds ; Tox_dVgs = dTox_dVgs ; Cox = C_EOX / Tox ; T1 = - C_EOX / ( Tox * Tox ) ; Cox_dVbs = T1 * Tox_dVbs ; Cox_dVds = T1 * Tox_dVds ; Cox_dVgs = T1 * Tox_dVgs ; Cox_inv = Tox / C_EOX ; T1 = 1.0 / C_EOX ; Cox_inv_dVbs = T1 * Tox_dVbs ; Cox_inv_dVds = T1 * Tox_dVds ; Cox_inv_dVgs = T1 * Tox_dVgs ; /*-----------------------------------------------------------** Threshold voltage. *-----------------*/ Delta = 0.1 ; Vbs1 = 2.0 - 0.25 * Vbsz ; Vbs2 = - Vbsz ; Vbsd = Vbs1 - Vbs2 - Delta ; Vbsd_dVbs = 0.75 * Vbsz_dVbs ; Vbsd_dVds = 0.75 * Vbsz_dVds ; T1 = sqrt( Vbsd * Vbsd + 4.0 * Delta ) ; Psum = ( Pb20 - Vbsz ) ; if ( Psum >= epsm10 ) { Psum_dVbs = - Vbsz_dVbs ; Psum_dVds = - Vbsz_dVds ; } else { Psum = epsm10 ; Psum_dVbs = 0.0e0 ; Psum_dVds = 0.0e0 ; } sqrt_Psum = sqrt( Psum ) ;/*---------------------------------------------------** Vthp : Vth with pocket.*-----------------*/ T1 = 2.0 * q_Nsub * C_ESI ; Qb0 = sqrt( T1 * ( Pb20 - Vbsz ) ) ; Qb0_dVbs = 0.5 * T1 / Qb0 * ( - Vbsz_dVbs ) ; Qb0_dVds = 0.5 * T1 / Qb0 * ( - Vbsz_dVds ) ; Vthp = Pb20 + Vfb + Qb0 * Cox_inv ; Vthp_dVbs = Qb0_dVbs * Cox_inv + Qb0 * Cox_inv_dVbs ; Vthp_dVds = Qb0_dVds * Cox_inv + Qb0 * Cox_inv_dVds ; Vthp_dVgs = Qb0 * Cox_inv_dVgs ;/*-------------------------------------------** dVthLP : Short-channel effect induced by pocket.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?