b3ld.c

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

C
1,722
字号
          if ((pParam->BSIM3pclm > 0.0) && (diffVds > 1.0e-10))	  {   T0 = 1.0 / (pParam->BSIM3pclm * Abulk * pParam->BSIM3litl);              dT0_dVb = -T0 / Abulk * dAbulk_dVb;              dT0_dVg = -T0 / Abulk * dAbulk_dVg;               	      T2 = Vgsteff / EsatL;              T1 = Leff * (Abulk + T2);               dT1_dVg = Leff * ((1.0 - T2 * dEsatL_dVg) / EsatL + dAbulk_dVg);              dT1_dVb = Leff * (dAbulk_dVb - T2 * dEsatL_dVb / EsatL);              dT1_dVd = -T2 * dEsatL_dVd / Esat;	      T9 = T0 * T1;              VACLM = T9 * diffVds;              dVACLM_dVg = T0 * dT1_dVg * diffVds - T9 * dVdseff_dVg                         + T1 * diffVds * dT0_dVg;              dVACLM_dVb = (dT0_dVb * T1 + T0 * dT1_dVb) * diffVds			 - T9 * dVdseff_dVb;              dVACLM_dVd = T0 * dT1_dVd * diffVds + T9 * (1.0 - dVdseff_dVd);          }	  else	  {   VACLM = MAX_EXP;              dVACLM_dVd = dVACLM_dVg = dVACLM_dVb = 0.0;          }/* Calculate VADIBL */          if (pParam->BSIM3thetaRout > 0.0)	  {   T8 = Abulk * Vdsat;	      T0 = Vgst2Vtm * T8;              dT0_dVg = Vgst2Vtm * Abulk * dVdsat_dVg + T8		      + Vgst2Vtm * Vdsat * dAbulk_dVg;              dT0_dVb = Vgst2Vtm * (dAbulk_dVb * Vdsat + Abulk * dVdsat_dVb);              dT0_dVd = Vgst2Vtm * Abulk * dVdsat_dVd;              T1 = Vgst2Vtm + T8;              dT1_dVg = 1.0 + Abulk * dVdsat_dVg + Vdsat * dAbulk_dVg;              dT1_dVb = Abulk * dVdsat_dVb + dAbulk_dVb * Vdsat;              dT1_dVd = Abulk * dVdsat_dVd;	      T9 = T1 * T1;	      T2 = pParam->BSIM3thetaRout;              VADIBL = (Vgst2Vtm - T0 / T1) / T2;              dVADIBL_dVg = (1.0 - dT0_dVg / T1 + T0 * dT1_dVg / T9) / T2;              dVADIBL_dVb = (-dT0_dVb / T1 + T0 * dT1_dVb / T9) / T2;              dVADIBL_dVd = (-dT0_dVd / T1 + T0 * dT1_dVd / T9) / T2;	      T7 = pParam->BSIM3pdiblb * Vbseff;	      if (T7 >= -0.9)	      {   T3 = 1.0 / (1.0 + T7);                  VADIBL *= T3;                  dVADIBL_dVg *= T3;                  dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->BSIM3pdiblb)			      * T3;                  dVADIBL_dVd *= T3;	      }	      else/* Added to avoid the discontinuity problem caused by pdiblcb */	      {   T4 = 1.0 / (0.8 + T7);		  T3 = (17.0 + 20.0 * T7) * T4;                  dVADIBL_dVg *= T3;                  dVADIBL_dVb = dVADIBL_dVb * T3			      - VADIBL * pParam->BSIM3pdiblb * T4 * T4;                  dVADIBL_dVd *= T3;                  VADIBL *= T3;	      }          }	  else	  {   VADIBL = MAX_EXP;              dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0;          }/* Calculate VA */          	  T8 = pParam->BSIM3pvag / EsatL;	  T9 = T8 * Vgsteff;	  if (T9 > -0.9)	  {   T0 = 1.0 + T9;              dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL);              dT0_dVb = -T9 * dEsatL_dVb / EsatL;              dT0_dVd = -T9 * dEsatL_dVd / EsatL;	  }	  else /* Added to avoid the discontinuity problems caused by pvag */	  {   T1 = 1.0 / (17.0 + 20.0 * T9);	      T0 = (0.8 + T9) * T1;	      T1 *= T1;              dT0_dVg = T8 * (1.0 - Vgsteff * dEsatL_dVg / EsatL) * T1;              T9 *= T1 / EsatL;              dT0_dVb = -T9 * dEsatL_dVb;              dT0_dVd = -T9 * dEsatL_dVd;	  }                  tmp1 = VACLM * VACLM;          tmp2 = VADIBL * VADIBL;          tmp3 = VACLM + VADIBL;          T1 = VACLM * VADIBL / tmp3;          tmp3 *= tmp3;          dT1_dVg = (tmp1 * dVADIBL_dVg + tmp2 * dVACLM_dVg) / tmp3;          dT1_dVd = (tmp1 * dVADIBL_dVd + tmp2 * dVACLM_dVd) / tmp3;          dT1_dVb = (tmp1 * dVADIBL_dVb + tmp2 * dVACLM_dVb) / tmp3;          Va = Vasat + T0 * T1;          dVa_dVg = dVasat_dVg + T1 * dT0_dVg + T0 * dT1_dVg;          dVa_dVd = dVasat_dVd + T1 * dT0_dVd + T0 * dT1_dVd;          dVa_dVb = dVasat_dVb + T1 * dT0_dVb + T0 * dT1_dVb;/* Calculate VASCBE */	  if (pParam->BSIM3pscbe2 > 0.0)	  {   if (diffVds > pParam->BSIM3pscbe1 * pParam->BSIM3litl		  / EXP_THRESHOLD)	      {   T0 =  pParam->BSIM3pscbe1 * pParam->BSIM3litl / diffVds;	          VASCBE = Leff * exp(T0) / pParam->BSIM3pscbe2;                  T1 = T0 * VASCBE / diffVds;                  dVASCBE_dVg = T1 * dVdseff_dVg;                  dVASCBE_dVd = -T1 * (1.0 - dVdseff_dVd);                  dVASCBE_dVb = T1 * dVdseff_dVb;              }	      else	      {   VASCBE = MAX_EXP * Leff/pParam->BSIM3pscbe2;                  dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;              }	  }	  else	  {   VASCBE = MAX_EXP;              dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;	  }/* Calculate Ids */          CoxWovL = model->BSIM3cox * Weff / Leff;          beta = ueff * CoxWovL;          dbeta_dVg = CoxWovL * dueff_dVg + beta * dWeff_dVg / Weff;          dbeta_dVd = CoxWovL * dueff_dVd;          dbeta_dVb = CoxWovL * dueff_dVb + beta * dWeff_dVb / Weff;          T0 = 1.0 - 0.5 * Abulk * Vdseff / Vgst2Vtm;          dT0_dVg = -0.5 * (Abulk * dVdseff_dVg 		  - Abulk * Vdseff / Vgst2Vtm + Vdseff * dAbulk_dVg) / Vgst2Vtm;          dT0_dVd = -0.5 * Abulk * dVdseff_dVd / Vgst2Vtm;          dT0_dVb = -0.5 * (Abulk * dVdseff_dVb + dAbulk_dVb * Vdseff)                  / Vgst2Vtm;          fgche1 = Vgsteff * T0;          dfgche1_dVg = Vgsteff * dT0_dVg + T0;           dfgche1_dVd = Vgsteff * dT0_dVd;           dfgche1_dVb = Vgsteff * dT0_dVb;           T9 = Vdseff / EsatL;          fgche2 = 1.0 + T9;          dfgche2_dVg = (dVdseff_dVg - T9 * dEsatL_dVg) / EsatL;          dfgche2_dVd = (dVdseff_dVd - T9 * dEsatL_dVd) / EsatL;          dfgche2_dVb = (dVdseff_dVb - T9 * dEsatL_dVb) / EsatL;           gche = beta * fgche1 / fgche2;          dgche_dVg = (beta * dfgche1_dVg + fgche1 * dbeta_dVg		    - gche * dfgche2_dVg) / fgche2;          dgche_dVd = (beta * dfgche1_dVd + fgche1 * dbeta_dVd		    - gche * dfgche2_dVd) / fgche2;          dgche_dVb = (beta * dfgche1_dVb + fgche1 * dbeta_dVb		    - gche * dfgche2_dVb) / fgche2;          T0 = 1.0 + gche * Rds;          T9 = Vdseff / T0;          Idl = gche * T9;          dIdl_dVg = (gche * dVdseff_dVg + T9 * dgche_dVg) / T0                   - Idl * gche / T0 * dRds_dVg ;           dIdl_dVd = (gche * dVdseff_dVd + T9 * dgche_dVd) / T0;           dIdl_dVb = (gche * dVdseff_dVb + T9 * dgche_dVb                    - Idl * dRds_dVb * gche) / T0;           T9 =  diffVds / Va;          T0 =  1.0 + T9;          Idsa = Idl * T0;          dIdsa_dVg = T0 * dIdl_dVg - Idl * (dVdseff_dVg + T9 * dVa_dVg) / Va;          dIdsa_dVd = T0 * dIdl_dVd + Idl * (1.0 - dVdseff_dVd		    - T9 * dVa_dVd) / Va;          dIdsa_dVb = T0 * dIdl_dVb - Idl * (dVdseff_dVb + T9 * dVa_dVb) / Va;          T9 = diffVds / VASCBE;          T0 = 1.0 + T9;          Ids = Idsa * T0;          Gm = T0 * dIdsa_dVg - Idsa * (dVdseff_dVg + T9 * dVASCBE_dVg) / VASCBE;          Gds = T0 * dIdsa_dVd + Idsa * (1.0 - dVdseff_dVd	      - T9 * dVASCBE_dVd) / VASCBE;          Gmb = T0 * dIdsa_dVb - Idsa * (dVdseff_dVb	      + T9 * dVASCBE_dVb) / VASCBE;          Gds += Gm * dVgsteff_dVd;	  Gmb += Gm * dVgsteff_dVb;	  Gm *= dVgsteff_dVg;	  Gmb *= dVbseff_dVb;          /* Substrate current begins */          tmp = pParam->BSIM3alpha0 + pParam->BSIM3alpha1 * Leff;          if ((tmp <= 0.0) || (pParam->BSIM3beta0 <= 0.0))	  {   Isub = Gbd = Gbb = Gbg = 0.0;          }	  else	  {   T2 = tmp / Leff;	      if (diffVds > pParam->BSIM3beta0 / EXP_THRESHOLD)	      {   T0 = -pParam->BSIM3beta0 / diffVds;		  T1 = T2 * diffVds * exp(T0);		  T3 = T1 / diffVds * (T0 - 1.0);                  dT1_dVg = T3 * dVdseff_dVg;                  dT1_dVd = T3 * (dVdseff_dVd - 1.0);                  dT1_dVb = T3 * dVdseff_dVb;              }	      else	      {   T3 = T2 * MIN_EXP;		  T1 = T3 * diffVds;                  dT1_dVg = -T3 * dVdseff_dVg;                  dT1_dVd = T3 * (1.0 - dVdseff_dVd);                  dT1_dVb = -T3 * dVdseff_dVb;              }              Isub = T1 * Idsa;              Gbg = T1 * dIdsa_dVg + Idsa * dT1_dVg;              Gbd = T1 * dIdsa_dVd + Idsa * dT1_dVd;              Gbb = T1 * dIdsa_dVb + Idsa * dT1_dVb;              Gbd += Gbg * dVgsteff_dVd;	      Gbb += Gbg * dVgsteff_dVb;	      Gbg *= dVgsteff_dVg;	      Gbb *= dVbseff_dVb; /* bug fixing */          }                   cdrain = Ids;          here->BSIM3gds = Gds;          here->BSIM3gm = Gm;          here->BSIM3gmbs = Gmb;                             here->BSIM3gbbs = Gbb;          here->BSIM3gbgs = Gbg;          here->BSIM3gbds = Gbd;          here->BSIM3csub = Isub;          /* BSIM3 thermal noise Qinv calculated from all capMod            * 0, 1, 2 & 3 stored in here->BSIM3qinv 1/1998 */          if ((model->BSIM3xpart < 0) || (!ChargeComputationNeeded))	  {   qgate  = qdrn = qsrc = qbulk = 0.0;              here->BSIM3cggb = here->BSIM3cgsb = here->BSIM3cgdb = 0.0;              here->BSIM3cdgb = here->BSIM3cdsb = here->BSIM3cddb = 0.0;              here->BSIM3cbgb = here->BSIM3cbsb = here->BSIM3cbdb = 0.0;              here->BSIM3cqdb = here->BSIM3cqsb = here->BSIM3cqgb                               = here->BSIM3cqbb = 0.0;              here->BSIM3gtau = 0.0;              goto finished;          }	  else if (model->BSIM3capMod == 0)	  {              if (Vbseff < 0.0)	      {   Vbseff = Vbs;                  dVbseff_dVb = 1.0;              }	      else	      {   Vbseff = pParam->BSIM3phi - Phis;                  dVbseff_dVb = -dPhis_dVb;              }              Vfb = pParam->BSIM3vfbcv;              Vth = Vfb + pParam->BSIM3phi + pParam->BSIM3k1ox * sqrtPhis;               Vgst = Vgs_eff - Vth;              dVth_dVb = pParam->BSIM3k1ox * dsqrtPhis_dVb;               dVgst_dVb = -dVth_dVb;              dVgst_dVg = dVgs_eff_dVg;               CoxWL = model->BSIM3cox * pParam->BSIM3weffCV                    * pParam->BSIM3leffCV;              Arg1 = Vgs_eff - Vbseff - Vfb;              if (Arg1 <= 0.0)	      {   qgate = CoxWL * Arg1;                  qbulk = -qgate;                  qdrn = 0.0;                  here->BSIM3cggb = CoxWL * dVgs_eff_dVg;                  here->BSIM3cgdb = 0.0;                  here->BSIM3cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg);                  here->BSIM3cdgb = 0.0;                  here->BSIM3cddb = 0.0;                  here->BSIM3cdsb = 0.0;                  here->BSIM3cbgb = -CoxWL * dVgs_eff_dVg;                  here->BSIM3cbdb = 0.0;                  here->BSIM3cbsb = -here->BSIM3cgsb;                  here->BSIM3qinv = 0.0;              }	      else if (Vgst <= 0.0)	      {   T1 = 0.5 * pParam->BSIM3k1ox;	          T2 = sqrt(T1 * T1 + Arg1);	          qgate = CoxWL * pParam->BSIM3k1ox * (T2 - T1);                  qbulk = -qgate;                  qdrn = 0.0;	          T0 = CoxWL * T1 / T2;	          here->BSIM3cggb = T0 * dVgs_eff_dVg;	          here->BSIM3cgdb = 0.0;                  here->BSIM3cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg);                     here->BSIM3cdgb = 0.0;                  here->BSIM3cddb = 0.0;                  here->BSIM3cdsb = 0.0;                  here->BSIM3cbgb = -here->BSIM3cggb;                  here->BSIM3cbdb = 0.0;                  here->BSIM3cbsb = -here->BSIM3cgsb;                  here->BSIM3qinv = 0.0;              }	      else	      {   One_Third_CoxWL = CoxWL / 3.0;                  Two_Third_CoxWL = 2.0 * One_Third_CoxWL;                  AbulkCV = Abulk0 * pParam->BSIM3abulkCVfactor;                  dAbulkCV_dVb = pParam->BSIM3abulkCVfactor * dAbulk0_dVb;	          Vdsat = Vgst / AbulkCV;	          dVdsat_dVg = dVgs_eff_dVg / AbulkCV;	          dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV;                   if (model->BSIM3xpart > 0.5)		  {   /* 0/100 Charge partition model */		      if (Vdsat <= Vds)		      {   /* saturation region */	                  T1 = Vdsat / 3.0;	                  qgate = CoxWL * (Vgs_eff - Vfb			        - pParam->BSIM3phi - T1);	                  T2 = -Two_Third_CoxWL * Vgst;	                  qbulk = -(qgate + T2);	                  qdrn = 0.0;	                  here->BSIM3cggb = One_Third_CoxWL * (3.0					  - dVdsat_dVg) * dVgs_eff_dVg;	                  T2 = -One_Third_CoxWL * dVdsat_dVb;	                  here->BSIM3cgsb = -(here->BSIM3cggb + T2);                          here->BSIM3cgdb = 0.0;                                 here->BSIM3cdgb = 0.0;                          here->BSIM3cddb = 0.0;                          here->BSIM3cdsb = 0.0;	                  here->BSIM3cbgb = -(here->BSIM3cggb					  - Two_Third_CoxWL * dVgs_eff_dVg);

⌨️ 快捷键说明

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