b3ld.c

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

C
1,722
字号
		      + (T2 - 1.0) / n * dn_dVd;              dT2_dVb = -dT2_dVg * (dVth_dVb - 2.0 * Vtm * ExpArg * dn_dVb)		      + (T2 - 1.0) / n * dn_dVb;              Vgsteff = T1 / T2;	      T3 = T2 * T2;              dVgsteff_dVg = (T2 * dT1_dVg - T1 * dT2_dVg) / T3 * dVgs_eff_dVg;              dVgsteff_dVd = (T2 * dT1_dVd - T1 * dT2_dVd) / T3;              dVgsteff_dVb = (T2 * dT1_dVb - T1 * dT2_dVb) / T3;	  }	  /* Added revision dependent code */          if (model->BSIM3intVersion > BSIM3V323) {	    here->BSIM3Vgsteff = Vgsteff;	  }/* Calculate Effective Channel Geometry */          T9 = sqrtPhis - pParam->BSIM3sqrtPhi;          Weff = pParam->BSIM3weff - 2.0 * (pParam->BSIM3dwg * Vgsteff                + pParam->BSIM3dwb * T9);           dWeff_dVg = -2.0 * pParam->BSIM3dwg;          dWeff_dVb = -2.0 * pParam->BSIM3dwb * dsqrtPhis_dVb;          if (Weff < 2.0e-8) /* to avoid the discontinuity problem due to Weff*/	  {   T0 = 1.0 / (6.0e-8 - 2.0 * Weff);	      Weff = 2.0e-8 * (4.0e-8 - Weff) * T0;	      T0 *= T0 * 4.0e-16;              dWeff_dVg *= T0;	      dWeff_dVb *= T0;          }          T0 = pParam->BSIM3prwg * Vgsteff + pParam->BSIM3prwb * T9;	  if (T0 >= -0.9)	  {   Rds = pParam->BSIM3rds0 * (1.0 + T0);	      dRds_dVg = pParam->BSIM3rds0 * pParam->BSIM3prwg;              dRds_dVb = pParam->BSIM3rds0 * pParam->BSIM3prwb * dsqrtPhis_dVb;	  }	  else           /* to avoid the discontinuity problem due to prwg and prwb*/	  {   T1 = 1.0 / (17.0 + 20.0 * T0);	      Rds = pParam->BSIM3rds0 * (0.8 + T0) * T1;	      T1 *= T1;	      dRds_dVg = pParam->BSIM3rds0 * pParam->BSIM3prwg * T1;              dRds_dVb = pParam->BSIM3rds0 * pParam->BSIM3prwb * dsqrtPhis_dVb		       * T1;	  }	  /* Added revision dependent code */          if (model->BSIM3intVersion > BSIM3V323) {	    here->BSIM3rds = Rds;	/* Noise Bugfix */          }	  /* Calculate Abulk */          T1 = 0.5 * pParam->BSIM3k1ox / sqrtPhis;          dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb;          T9 = sqrt(pParam->BSIM3xj * Xdep);          tmp1 = Leff + 2.0 * T9;          T5 = Leff / tmp1;           tmp2 = pParam->BSIM3a0 * T5;          tmp3 = pParam->BSIM3weff + pParam->BSIM3b1;           tmp4 = pParam->BSIM3b0 / tmp3;          T2 = tmp2 + tmp4;          dT2_dVb = -T9 / tmp1 / Xdep * dXdep_dVb;          T6 = T5 * T5;          T7 = T5 * T6;          Abulk0 = 1.0 + T1 * T2;           dAbulk0_dVb = T1 * tmp2 * dT2_dVb + T2 * dT1_dVb;          T8 = pParam->BSIM3ags * pParam->BSIM3a0 * T7;          dAbulk_dVg = -T1 * T8;          Abulk = Abulk0 + dAbulk_dVg * Vgsteff;           dAbulk_dVb = dAbulk0_dVb - T8 * Vgsteff * (dT1_dVb		     + 3.0 * T1 * dT2_dVb);          if (Abulk0 < 0.1) /* added to avoid the problems caused by Abulk0 */	  {   T9 = 1.0 / (3.0 - 20.0 * Abulk0);	      Abulk0 = (0.2 - Abulk0) * T9;	      dAbulk0_dVb *= T9 * T9;	  }          if (Abulk < 0.1)          /* added to avoid the problems caused by Abulk */	  {   T9 = 1.0 / (3.0 - 20.0 * Abulk);	      Abulk = (0.2 - Abulk) * T9;	      /* Added revision dependent code */              if (model->BSIM3intVersion > BSIM3V32) {	        T10 = T9 * T9;	        dAbulk_dVb *= T10;	        dAbulk_dVg *= T10;	      } else {	      	dAbulk_dVb *= T9 * T9;	      }	  }	  /* Added revision dependent code */          if (model->BSIM3intVersion > BSIM3V323) {	    here->BSIM3Abulk = Abulk;          }          T2 = pParam->BSIM3keta * Vbseff;	  if (T2 >= -0.9)	  {   T0 = 1.0 / (1.0 + T2);              dT0_dVb = -pParam->BSIM3keta * T0 * T0;	  }	  else          /* added to avoid the problems caused by Keta */	  {   T1 = 1.0 / (0.8 + T2);	      T0 = (17.0 + 20.0 * T2) * T1;              dT0_dVb = -pParam->BSIM3keta * T1 * T1;	  }	  dAbulk_dVg *= T0;	  dAbulk_dVb = dAbulk_dVb * T0 + Abulk * dT0_dVb;	  dAbulk0_dVb = dAbulk0_dVb * T0 + Abulk0 * dT0_dVb;	  Abulk *= T0;	  Abulk0 *= T0;/* Mobility calculation */          if (model->BSIM3mobMod == 1)	  {   T0 = Vgsteff + Vth + Vth;              T2 = pParam->BSIM3ua + pParam->BSIM3uc * Vbseff;              T3 = T0 / model->BSIM3tox;              T5 = T3 * (T2 + pParam->BSIM3ub * T3);              dDenomi_dVg = (T2 + 2.0 * pParam->BSIM3ub * T3) / model->BSIM3tox;              dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;              dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3uc * T3;          }	  else if (model->BSIM3mobMod == 2)	  {   T5 = Vgsteff / model->BSIM3tox * (pParam->BSIM3ua		 + pParam->BSIM3uc * Vbseff + pParam->BSIM3ub * Vgsteff                 / model->BSIM3tox);              dDenomi_dVg = (pParam->BSIM3ua + pParam->BSIM3uc * Vbseff		          + 2.0 * pParam->BSIM3ub * Vgsteff / model->BSIM3tox)		          / model->BSIM3tox;              dDenomi_dVd = 0.0;              dDenomi_dVb = Vgsteff * pParam->BSIM3uc / model->BSIM3tox;           }	  else	  {   T0 = Vgsteff + Vth + Vth;              T2 = 1.0 + pParam->BSIM3uc * Vbseff;              T3 = T0 / model->BSIM3tox;              T4 = T3 * (pParam->BSIM3ua + pParam->BSIM3ub * T3);	      T5 = T4 * T2;              dDenomi_dVg = (pParam->BSIM3ua + 2.0 * pParam->BSIM3ub * T3) * T2		          / model->BSIM3tox;              dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;              dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3uc * T4;          }	  if (T5 >= -0.8)	  {   Denomi = 1.0 + T5;	  }	  else /* Added to avoid the discontinuity problem caused by ua and ub*/ 	  {   T9 = 1.0 / (7.0 + 10.0 * T5);	      Denomi = (0.6 + T5) * T9;	      T9 *= T9;              dDenomi_dVg *= T9;              dDenomi_dVd *= T9;              dDenomi_dVb *= T9;	  }          here->BSIM3ueff = ueff = pParam->BSIM3u0temp / Denomi;	  T9 = -ueff / Denomi;          dueff_dVg = T9 * dDenomi_dVg;          dueff_dVd = T9 * dDenomi_dVd;          dueff_dVb = T9 * dDenomi_dVb;/* Saturation Drain Voltage  Vdsat */          WVCox = Weff * pParam->BSIM3vsattemp * model->BSIM3cox;          WVCoxRds = WVCox * Rds;           Esat = 2.0 * pParam->BSIM3vsattemp / ueff;          EsatL = Esat * Leff;          T0 = -EsatL /ueff;          dEsatL_dVg = T0 * dueff_dVg;          dEsatL_dVd = T0 * dueff_dVd;          dEsatL_dVb = T0 * dueff_dVb;  	  /* Sqrt() */          a1 = pParam->BSIM3a1;	  if (a1 == 0.0)	  {   Lambda = pParam->BSIM3a2;	      dLambda_dVg = 0.0;	  }	  else if (a1 > 0.0)/* Added to avoid the discontinuity problem   caused by a1 and a2 (Lambda) */	  {   T0 = 1.0 - pParam->BSIM3a2;	      T1 = T0 - pParam->BSIM3a1 * Vgsteff - 0.0001;	      T2 = sqrt(T1 * T1 + 0.0004 * T0);	      Lambda = pParam->BSIM3a2 + T0 - 0.5 * (T1 + T2);	      dLambda_dVg = 0.5 * pParam->BSIM3a1 * (1.0 + T1 / T2);	  }	  else	  {   T1 = pParam->BSIM3a2 + pParam->BSIM3a1 * Vgsteff - 0.0001;	      T2 = sqrt(T1 * T1 + 0.0004 * pParam->BSIM3a2);	      Lambda = 0.5 * (T1 + T2);	      dLambda_dVg = 0.5 * pParam->BSIM3a1 * (1.0 + T1 / T2);	  }          Vgst2Vtm = Vgsteff + 2.0 * Vtm;	  /* Added revision dependent code */          if (model->BSIM3intVersion > BSIM3V323) {            here->BSIM3AbovVgst2Vtm = Abulk / Vgst2Vtm;          }          if (Rds > 0)          {   tmp2 = dRds_dVg / Rds + dWeff_dVg / Weff;              tmp3 = dRds_dVb / Rds + dWeff_dVb / Weff;          }          else          {   tmp2 = dWeff_dVg / Weff;              tmp3 = dWeff_dVb / Weff;	  }          if ((Rds == 0.0) && (Lambda == 1.0))          {   T0 = 1.0 / (Abulk * EsatL + Vgst2Vtm);              tmp1 = 0.0;	      T1 = T0 * T0;	      T2 = Vgst2Vtm * T0;              T3 = EsatL * Vgst2Vtm;              Vdsat = T3 * T0;                                         dT0_dVg = -(Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 1.0) * T1;              dT0_dVd = -(Abulk * dEsatL_dVd) * T1;               dT0_dVb = -(Abulk * dEsatL_dVb + dAbulk_dVb * EsatL) * T1;                 dVdsat_dVg = T3 * dT0_dVg + T2 * dEsatL_dVg + EsatL * T0;              dVdsat_dVd = T3 * dT0_dVd + T2 * dEsatL_dVd;              dVdsat_dVb = T3 * dT0_dVb + T2 * dEsatL_dVb;             }          else          {   tmp1 = dLambda_dVg / (Lambda * Lambda);              T9 = Abulk * WVCoxRds;	      T8 = Abulk * T9;	      T7 = Vgst2Vtm * T9;              T6 = Vgst2Vtm * WVCoxRds;              T0 = 2.0 * Abulk * (T9 - 1.0 + 1.0 / Lambda);               dT0_dVg = 2.0 * (T8 * tmp2 - Abulk * tmp1		      + (2.0 * T9 + 1.0 / Lambda - 1.0) * dAbulk_dVg);                           dT0_dVb = 2.0 * (T8 * (2.0 / Abulk * dAbulk_dVb + tmp3)		      + (1.0 / Lambda - 1.0) * dAbulk_dVb);	      dT0_dVd = 0.0;               T1 = Vgst2Vtm * (2.0 / Lambda - 1.0) + Abulk * EsatL + 3.0 * T7;                           dT1_dVg = (2.0 / Lambda - 1.0) - 2.0 * Vgst2Vtm * tmp1		      + Abulk * dEsatL_dVg + EsatL * dAbulk_dVg + 3.0 * (T9		      + T7 * tmp2 + T6 * dAbulk_dVg);              dT1_dVb = Abulk * dEsatL_dVb + EsatL * dAbulk_dVb	              + 3.0 * (T6 * dAbulk_dVb + T7 * tmp3);              dT1_dVd = Abulk * dEsatL_dVd;              T2 = Vgst2Vtm * (EsatL + 2.0 * T6);              dT2_dVg = EsatL + Vgst2Vtm * dEsatL_dVg		      + T6 * (4.0 + 2.0 * Vgst2Vtm * tmp2);              dT2_dVb = Vgst2Vtm * (dEsatL_dVb + 2.0 * T6 * tmp3);              dT2_dVd = Vgst2Vtm * dEsatL_dVd;              T3 = sqrt(T1 * T1 - 2.0 * T0 * T2);              Vdsat = (T1 - T3) / T0;              dT3_dVg = (T1 * dT1_dVg - 2.0 * (T0 * dT2_dVg + T2 * dT0_dVg))	              / T3;              dT3_dVd = (T1 * dT1_dVd - 2.0 * (T0 * dT2_dVd + T2 * dT0_dVd))		      / T3;              dT3_dVb = (T1 * dT1_dVb - 2.0 * (T0 * dT2_dVb + T2 * dT0_dVb))		      / T3;              dVdsat_dVg = (dT1_dVg - (T1 * dT1_dVg - dT0_dVg * T2			 - T0 * dT2_dVg) / T3 - Vdsat * dT0_dVg) / T0;              dVdsat_dVb = (dT1_dVb - (T1 * dT1_dVb - dT0_dVb * T2			 - T0 * dT2_dVb) / T3 - Vdsat * dT0_dVb) / T0;              dVdsat_dVd = (dT1_dVd - (T1 * dT1_dVd - T0 * dT2_dVd) / T3) / T0;          }          here->BSIM3vdsat = Vdsat;/* Effective Vds (Vdseff) Calculation */          T1 = Vdsat - Vds - pParam->BSIM3delta;          dT1_dVg = dVdsat_dVg;          dT1_dVd = dVdsat_dVd - 1.0;          dT1_dVb = dVdsat_dVb;          T2 = sqrt(T1 * T1 + 4.0 * pParam->BSIM3delta * Vdsat);	  T0 = T1 / T2;	  T3 = 2.0 * pParam->BSIM3delta / T2;          dT2_dVg = T0 * dT1_dVg + T3 * dVdsat_dVg;          dT2_dVd = T0 * dT1_dVd + T3 * dVdsat_dVd;          dT2_dVb = T0 * dT1_dVb + T3 * dVdsat_dVb;          Vdseff = Vdsat - 0.5 * (T1 + T2);          dVdseff_dVg = dVdsat_dVg - 0.5 * (dT1_dVg + dT2_dVg);           dVdseff_dVd = dVdsat_dVd - 0.5 * (dT1_dVd + dT2_dVd);           dVdseff_dVb = dVdsat_dVb - 0.5 * (dT1_dVb + dT2_dVb); 	  /* Added revision dependent code */	  switch (model->BSIM3intVersion) {	    case BSIM3V324:	    case BSIM3V323:	    case BSIM3V322:	      /* Added to eliminate non-zero Vdseff at Vds=0.0 */	      if (Vds == 0.0)		{		  Vdseff = 0.0;		  dVdseff_dVg = 0.0;		  dVdseff_dVb = 0.0;		}	      break;	    case BSIM3V32:	    default:	      /* Do nothing */	      break;	  }/* Calculate VAsat */          tmp4 = 1.0 - 0.5 * Abulk * Vdsat / Vgst2Vtm;          T9 = WVCoxRds * Vgsteff;	  T8 = T9 / Vgst2Vtm;          T0 = EsatL + Vdsat + 2.0 * T9 * tmp4;                   T7 = 2.0 * WVCoxRds * tmp4;          dT0_dVg = dEsatL_dVg + dVdsat_dVg + T7 * (1.0 + tmp2 * Vgsteff)		  - T8 * (Abulk * dVdsat_dVg - Abulk * Vdsat / Vgst2Vtm		  + Vdsat * dAbulk_dVg);   		            dT0_dVb = dEsatL_dVb + dVdsat_dVb + T7 * tmp3 * Vgsteff		  - T8 * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);          dT0_dVd = dEsatL_dVd + dVdsat_dVd - T8 * Abulk * dVdsat_dVd;          T9 = WVCoxRds * Abulk;           T1 = 2.0 / Lambda - 1.0 + T9;           dT1_dVg = -2.0 * tmp1 +  WVCoxRds * (Abulk * tmp2 + dAbulk_dVg);          dT1_dVb = dAbulk_dVb * WVCoxRds + T9 * tmp3;          Vasat = T0 / T1;          dVasat_dVg = (dT0_dVg - Vasat * dT1_dVg) / T1;          dVasat_dVb = (dT0_dVb - Vasat * dT1_dVb) / T1;          dVasat_dVd = dT0_dVd / T1;          if (Vdseff > Vds)             Vdseff = Vds;          diffVds = Vds - Vdseff;	  /* Added revision dependent code */          if (model->BSIM3intVersion > BSIM3V323) {	    here->BSIM3Vdseff = Vdseff;	  }/* Calculate VACLM */

⌨️ 快捷键说明

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