📄 b1eval.c
字号:
Vcut = - 40. * N0 * CONSTvt0 ;/* The following 'if' statement has been modified so that subthreshold * * current computation is always executed unless N0 >= 200. This should * * get rid of the Ids kink seen on Ids-Vgs plots at low Vds. * * Peter M. Lee * * 6/8/90 * * Old 'if' statement: * * if( (N0 >= 200) || (Vgs_Vth < Vcut ) || (Vgs_Vth > (-0.5*Vcut))) */ if (N0 >= 200) { goto ChargeComputation; } NB = here->B1subthSlopeB; ND = here->B1subthSlopeD; N = N0 + NB * vbs + ND * vds; /* subthreshold slope */ if( N < 0.5 ) N = 0.5; Warg1 = exp( - vds / CONSTvt0 ); Wds = 1 - Warg1; Wgs = exp( Vgs_Vth / ( N * CONSTvt0 )); Vtsquare = CONSTvt0 * CONSTvt0 ; Warg2 = 6.04965 * Vtsquare * here->B1betaZero; Ilimit = 4.5 * Vtsquare * here->B1betaZero; Iexp = Warg2 * Wgs * Wds; DrainCurrent = DrainCurrent + Ilimit * Iexp / ( Ilimit + Iexp ); Temp1 = Ilimit / ( Ilimit + Iexp ); Temp1 = Temp1 * Temp1; Temp3 = Ilimit / ( Ilimit + Wgs * Warg2 ); Temp3=Temp3 * Temp3 * Warg2 * Wgs;/* if ( Temp3 > Ilimit ) Temp3=Ilimit;*/ gm = gm + Temp1 * Iexp / ( N * CONSTvt0 ); /* gds term has been modified to prevent blow up at Vds=0 */ gds = gds + Temp3 * ( -Wds / N / CONSTvt0 * (dVthdVds + Vgs_Vth * ND / N ) + Warg1 / CONSTvt0 ); gmbs = gmbs - Temp1 * Iexp * (dVthdVbs + Vgs_Vth * NB / N ) / ( N * CONSTvt0 );ChargeComputation: /* Some Limiting of DC Parameters */ if(DrainCurrent < 0.0) DrainCurrent = 0.0; if(gm < 0.0) gm = 0.0; if(gds < 0.0) gds = 0.0; if(gmbs < 0.0) gmbs = 0.0; WLCox = model->B1Cox * (here->B1l - model->B1deltaL * 1.e-6) * (here->B1w - model->B1deltaW * 1.e-6) * 1.e4; /* F */ if( ! ChargeComputationNeeded ) { qg = 0; qd = 0; qb = 0; cggb = 0; cgsb = 0; cgdb = 0; cdgb = 0; cdsb = 0; cddb = 0; cbgb = 0; cbsb = 0; cbdb = 0; goto finished; } G = 1. - 1./(1.744+0.8364 * Vpb); A = 1. + 0.5*G*K1/SqrtVpb; A = MAX( A, 1.0); /* Modified */ /*Arg = 1 + Ugs * Vgs_Vth;*/ dGdVbs = -0.8364 * (1-G) * (1-G); dAdVbs = 0.25 * K1 / SqrtVpb *(2*dGdVbs + G/Vpb); Phi = MAX( 0.1, Phi); if( model->B1channelChargePartitionFlag >= 1 ) {/*0/100 partitioning for drain/source chArges at the saturation region*/ Vth0 = Vfb + Phi + K1 * SqrtVpb; Vgs_Vth = vgs - Vth0; Arg1 = A * vds; Arg2 = Vgs_Vth - 0.5 * Arg1; Arg3 = vds - Arg1; Arg5 = Arg1 * Arg1; dVthdVbs = - 0.5 * K1 / SqrtVpb; dAdVbs = 0.5 * K1 * (0.5 * G / Vpb - 0.8364 * (1 -G) * (1 - G) ) / SqrtVpb ; Ent = MAX(Arg2,1.0e-8); dEntdVds = - 0.5 * A; dEntdVbs = - dVthdVbs - 0.5 * vds * dAdVbs; Vcom = Vgs_Vth * Vgs_Vth / 6.0 - 1.25e-1 * Arg1 * Vgs_Vth + 2.5e-2 * Arg5; VdsPinchoff = MAX( Vgs_Vth / A, 0.0); Vgb = vgs - vbs ; Vgb_Vfb = Vgb - Vfb; if( Vgb_Vfb < 0){ /* Accumulation Region */ qg = WLCox * Vgb_Vfb; qb = - qg; qd = 0. ; cggb = WLCox; cgdb = 0.; cgsb = 0.; cbgb = -WLCox; cbdb = 0.; cbsb = 0.; cdgb = 0.; cddb = 0.; cdsb = 0.; goto finished; } else if ( vgs < Vth0 ){ /* Subthreshold Region */ qg = 0.5 * WLCox * K1 * K1 * (-1 + sqrt(1 + 4 * Vgb_Vfb / (K1 * K1))); qb = -qg; qd = 0.; cggb = WLCox / sqrt(1 + 4 * Vgb_Vfb / (K1 * K1)); cgdb = cgsb = 0.; cbgb = -cggb; cbdb = cbsb = cdgb = cddb = cdsb = 0.0; goto finished; } else if( vds < VdsPinchoff ){ /* triode region */ /*Vgs_Vth2 = Vgs_Vth*Vgs_Vth;*/ EntSquare = Ent * Ent; Argl1 = 1.2e1 * EntSquare; Argl2 = 1.0 - A; Argl3 = Arg1 * vds; /*Argl4 = Vcom/Ent/EntSquare;*/ if (Ent > 1.0e-8) { Argl5 = Arg1 / Ent; /*Argl6 = Vcom/EntSquare;*/ } else { Argl5 = 2.0; Argl6 = 4.0 / 1.5e1; } Argl7 = Argl5 / 1.2e1; Argl8 = 6.0 * Ent; Argl9 = 0.125 * Argl5 * Argl5; qg = WLCox * (vgs - Vfb - Phi - 0.5 * vds + vds * Argl7); qb = WLCox * ( - Vth0 + Vfb + Phi + 0.5 * Arg3 - Arg3 * Argl7); qd = - WLCox * (0.5 * Vgs_Vth - 0.75 * Arg1 + 0.125 * Arg1 * Argl5); cggb = WLCox * (1.0 - Argl3 / Argl1); cgdb = WLCox * ( - 0.5 + Arg1 / Argl8 - Argl3 * dEntdVds / Argl1); cgbb = WLCox * (vds * vds * dAdVbs * Ent - Argl3 * dEntdVbs) / Argl1; cgsb = - (cggb + cgdb + cgbb); cbgb = WLCox * Argl3 * Argl2 / Argl1; cbdb = WLCox * Argl2 * (0.5 - Arg1 / Argl8 + Argl3 * dEntdVds / Argl1); cbbb = - WLCox * (dVthdVbs + 0.5 * vds * dAdVbs + vds * vds * ((1.0 - 2.0 * A) * dAdVbs * Ent - Argl2 * A * dEntdVbs) / Argl1); cbsb = - (cbgb + cbdb + cbbb); cdgb = - WLCox * (0.5 - Argl9); cddb = WLCox * (0.75 * A - 0.25 * A * Arg1 / Ent + Argl9 * dEntdVds); cdbb = WLCox * (0.5 * dVthdVbs + vds * dAdVbs * (0.75 - 0.25 * Argl5 ) + Argl9 * dEntdVbs); cdsb = - (cdgb + cddb + cdbb); goto finished; } else if( vds >= VdsPinchoff ) { /* saturation region */ Args1 = 1.0 / (3.0 * A); qg = WLCox * (vgs - Vfb - Phi - Vgs_Vth * Args1); qb = WLCox * (Vfb + Phi - Vth0 + (1.0 - A) * Vgs_Vth * Args1); qd = 0.0; cggb = WLCox * (1.0 - Args1); cgdb = 0.0; cgbb = WLCox * Args1 * (dVthdVbs + Vgs_Vth * dAdVbs / A); cgsb = - (cggb + cgdb + cgbb); cbgb = WLCox * (Args1 - 1.0 / 3.0); cbdb = 0.0; cbbb = - WLCox * ((2.0 / 3.0 + Args1) * dVthdVbs + Vgs_Vth * Args1 * dAdVbs / A); /* Modified */ cbsb = - (cbgb + cbdb + cbbb); cdgb = 0.0; cddb = 0.0; cdsb = 0.0; goto finished; } goto finished; } else { /* ChannelChargePartionFlag < = 0 *//*40/60 partitioning for drain/source chArges at the saturation region*/ co4v15 = 4./15.; Vth0 = Vfb+Phi+K1*SqrtVpb; Vgs_Vth = vgs-Vth0; Arg1 = A*vds; Arg2 = Vgs_Vth-0.5*Arg1; Arg3 = vds-Arg1; Arg5 = Arg1*Arg1; dVthdVbs = -0.5*K1/SqrtVpb; dAdVbs = 0.5*K1*(0.5*G/Vpb-0.8364*(1-G)*(1-G))/SqrtVpb; Ent = MAX(Arg2,1.0e-8); dEntdVds = -0.5*A; dEntdVbs = -dVthdVbs-0.5*vds*dAdVbs; Vcom = Vgs_Vth*Vgs_Vth/6.0-1.25e-1*Arg1*Vgs_Vth+2.5e-2*Arg5; VdsPinchoff = MAX( Vgs_Vth/A, 0.0); Vgb = vgs - vbs ; Vgb_Vfb = Vgb - Vfb; if( Vgb_Vfb < 0) { /* Accumulation Region */ qg = WLCox * Vgb_Vfb; qb = - qg; qd = 0. ; cggb = WLCox; cgdb = 0.; cgsb = 0.; cbgb = -WLCox; cbdb = 0.; cbsb = 0.; cdgb = 0.; cddb = 0.; cdsb = 0.; goto finished; } else if ( vgs < Vth0 ) { /* Subthreshold Region */ qg = 0.5 * WLCox * K1 * K1 * (-1+sqrt(1+4*Vgb_Vfb/(K1*K1))); qb = -qg; qd = 0.; cggb = WLCox/sqrt(1+4*Vgb_Vfb/(K1*K1)); cgdb = cgsb = 0.; cbgb = -cggb; cbdb = cbsb = cdgb = cddb = cdsb = 0.0; goto finished; } else if ( vds < VdsPinchoff ) { /* triode region */ Vgs_VthSquare = Vgs_Vth*Vgs_Vth; EntSquare = Ent*Ent; Argl1 = 1.2e1*EntSquare; Argl2 = 1.0-A; Argl3 = Arg1*vds; Argl4 = Vcom/Ent/EntSquare; if (Ent > 1.0e-8) { Argl5 = Arg1/Ent; Argl6 = Vcom/EntSquare; } else { Argl5 = 2.0; Argl6 = 4.0/1.5e1; } Argl7 = Argl5/1.2e1; Argl8 = 6.0*Ent; qg = WLCox*(vgs-Vfb-Phi-0.5*vds+vds*Argl7); qb = WLCox*(-Vth0+Vfb+Phi+0.5*Arg3-Arg3*Argl7); qd = -WLCox*(0.5*(Vgs_Vth-Arg1)+Arg1*Argl6); cggb = WLCox*(1.0-Argl3/Argl1); cgdb = WLCox*(-0.5+Arg1/Argl8-Argl3*dEntdVds/Argl1); cgbb = WLCox*(vds*vds*dAdVbs*Ent-Argl3*dEntdVbs)/Argl1; cgsb = -(cggb+cgdb+cgbb); cbgb = WLCox*Argl3*Argl2/Argl1; cbdb = WLCox*Argl2*(0.5-Arg1/Argl8+Argl3*dEntdVds/Argl1); cbbb = -WLCox*(dVthdVbs+0.5*vds*dAdVbs+vds*vds*((1.0-2.0*A) *dAdVbs*Ent-Argl2*A*dEntdVbs)/Argl1); cbsb = -(cbgb+cbdb+cbbb); cdgb = -WLCox*(0.5+Arg1*(4.0*Vgs_Vth-1.5*Arg1)/Argl1- 2.0*Arg1*Argl4); cddb = WLCox*(0.5*A+2.0*Arg1*dEntdVds*Argl4-A*(2.0*Vgs_VthSquare -3.0*Arg1*Vgs_Vth+0.9*Arg5)/Argl1); cdbb = WLCox*(0.5*dVthdVbs+0.5*vds*dAdVbs+2.0*Arg1*dEntdVbs *Argl4-vds*(2.0*Vgs_VthSquare*dAdVbs-4.0*A*Vgs_Vth*dVthdVbs-3.0 *Arg1*Vgs_Vth*dAdVbs+1.5*A*Arg1*dVthdVbs+0.9*Arg5*dAdVbs) /Argl1); cdsb = -(cdgb+cddb+cdbb); goto finished; } else if( vds >= VdsPinchoff ) { /* saturation region */ Args1 = 1.0/(3.0*A); qg = WLCox*(vgs-Vfb-Phi-Vgs_Vth*Args1); qb = WLCox*(Vfb+Phi-Vth0+(1.0-A)*Vgs_Vth*Args1); qd = -co4v15*WLCox*Vgs_Vth; cggb = WLCox*(1.0-Args1); cgdb = 0.0; cgbb = WLCox*Args1*(dVthdVbs+Vgs_Vth*dAdVbs/A); cgsb = -(cggb+cgdb+cgbb); cbgb = WLCox*(Args1-1.0/3.0); cbdb = 0.0; cbbb = -WLCox*((2.0/3.0+Args1)*dVthdVbs+Vgs_Vth*Args1*dAdVbs/A); cbsb = -(cbgb+cbdb+cbbb); cdgb = -co4v15*WLCox; cddb = 0.0; cdbb = co4v15*WLCox*dVthdVbs; cdsb = -(cdgb+cddb+cdbb); goto finished; } }finished: /* returning Values to Calling Routine */ *gmPointer = MAX(gm,0.0); *gdsPointer = MAX( gds, 0.0); *gmbsPointer = MAX(gmbs,0.0); *qgPointer = qg; *qbPointer = qb; *qdPointer = qd; *cggbPointer = cggb; *cgdbPointer = cgdb; *cgsbPointer = cgsb; *cbgbPointer = cbgb; *cbdbPointer = cbdb; *cbsbPointer = cbsb; *cdgbPointer = cdgb; *cddbPointer = cddb; *cdsbPointer = cdsb; *cdrainPointer = MAX(DrainCurrent,0.0); *vonPointer = Von; *vdsatPointer = VdsSat;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -