You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2906 lines
112 KiB
2906 lines
112 KiB
/**********
|
|
Copyright 1990 Regents of the University of California. All rights reserved.
|
|
Author: 1991 JianHui Huang and Min-Chie Jeng.
|
|
Modified by Mansun Chan (1995).
|
|
Modified by Weidong Liu (1997-1998).
|
|
File: b3ld.c 1/3/92
|
|
**********/
|
|
|
|
#include "ngspice.h"
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
#include "cktdefs.h"
|
|
#include "bsim3v2def.h"
|
|
#include "trandefs.h"
|
|
#include "const.h"
|
|
#include "sperror.h"
|
|
#include "devdefs.h"
|
|
#include "suffix.h"
|
|
|
|
#define MAX_EXP 5.834617425e14
|
|
#define MIN_EXP 1.713908431e-15
|
|
#define EXP_THRESHOLD 34.0
|
|
#define EPSOX 3.453133e-11
|
|
#define EPSSI 1.03594e-10
|
|
#define Charge_q 1.60219e-19
|
|
#define DELTA_1 0.02
|
|
#define DELTA_2 0.02
|
|
#define DELTA_3 0.02
|
|
#define DELTA_4 0.02
|
|
|
|
|
|
int
|
|
BSIM3V2load(inModel,ckt)
|
|
GENmodel *inModel;
|
|
CKTcircuit *ckt;
|
|
{
|
|
BSIM3V2model *model = (BSIM3V2model*)inModel;
|
|
BSIM3V2instance *here;
|
|
double SourceSatCurrent, DrainSatCurrent;
|
|
double ag0, qgd, qgs, qgb, von, cbhat, VgstNVt, ExpVgst;
|
|
double cdrain, cdhat, cdreq, ceqbd, ceqbs, ceqqb, ceqqd, ceqqg, ceq, geq;
|
|
double czbd, czbdsw, czbdswg, czbs, czbssw, czbsswg, evbd, evbs, arg, sarg;
|
|
double delvbd, delvbs, delvds, delvgd, delvgs;
|
|
double Vfbeff, dVfbeff_dVg, dVfbeff_dVd, dVfbeff_dVb, V3, V4;
|
|
double gcbdb, gcbgb, gcbsb, gcddb, gcdgb, gcdsb, gcgdb, gcggb, gcgsb, gcsdb;
|
|
double gcsgb, gcssb, tol, MJ, MJSW, MJSWG;
|
|
double vbd, vbs, vds, vgb, vgd, vgs, vgdo, xfact;
|
|
double qgate, qbulk, qdrn, qsrc, qinoi, cqgate, cqbulk, cqdrn;
|
|
double Vds, Vgs, Vbs, Gmbs, FwdSum, RevSum;
|
|
double Vgs_eff, Vfb, dVfb_dVb, dVfb_dVd, dVbs_dVb;
|
|
double Phis, dPhis_dVb, sqrtPhis, dsqrtPhis_dVb, Vth, dVth_dVb, dVth_dVd;
|
|
double Vgst, dVgst_dVg, dVgst_dVb, dVgs_eff_dVg, Nvtm;
|
|
double Vgdt, Vgsaddvth, Vgsaddvth2, Vgsaddvth1o3, Vtm;
|
|
double n, dn_dVb, dn_dVd, voffcv, noff, dnoff_dVd, dnoff_dVb;
|
|
double ExpArg, ExpArg1, V0, CoxWLcen, QovCox, LINK;
|
|
double DeltaPhi, dDeltaPhi_dVg, dDeltaPhi_dVd, dDeltaPhi_dVb;
|
|
double Cox, Tox, Tcen, dTcen_dVg, dTcen_dVd, dTcen_dVb;
|
|
double Ccen, Coxeff, dCoxeff_dVg, dCoxeff_dVd, dCoxeff_dVb;
|
|
double Denomi, dDenomi_dVg, dDenomi_dVd, dDenomi_dVb;
|
|
double ueff, dueff_dVg, dueff_dVd, dueff_dVb;
|
|
double Esat, dEsat_dVg, dEsat_dVd, dEsat_dVb, Vdsat, Vdsat0;
|
|
double EsatL, dEsatL_dVg, dEsatL_dVd, dEsatL_dVb;
|
|
double Ilimit, Iexp, dIexp_dVg, dIexp_dVd, dIexp_dVb;
|
|
double dVdsat_dVg, dVdsat_dVb, dVdsat_dVd, Vasat, dAlphaz_dVg, dAlphaz_dVb;
|
|
double dVasat_dVg, dVasat_dVb, dVasat_dVd, Va, Va2, dVa_dVd, dVa_dVg, dVa_dVb;
|
|
double Vbseff, dVbseff_dVb, VbseffCV, dVbseffCV_dVb;
|
|
double Arg1, Arg2, One_Third_CoxWL, Two_Third_CoxWL, Alphaz, CoxWL;
|
|
double dqbulk_dVb, dVgdt_dVg, dVgdt_dVd, dVgdt_dVb;
|
|
double T0, dT0_dVg, dT0_dVd, dT0_dVb;
|
|
double T1, dT1_dVg, dT1_dVd, dT1_dVb;
|
|
double T2, dT2_dVg, dT2_dVd, dT2_dVb;
|
|
double T3, dT3_dVg, dT3_dVd, dT3_dVb;
|
|
double T4, dT4_dVg, dT4_dVd, dT4_dVb;
|
|
double T5, dT5_dVg, dT5_dVd, dT5_dVb;
|
|
double T6, dT6_dVg, dT6_dVd, dT6_dVb;
|
|
double T7, dT7_dVg, dT7_dVd, dT7_dVb;
|
|
double T8, dT8_dVg, dT8_dVd, dT8_dVb;
|
|
double T9, dT9_dVg, dT9_dVd, dT9_dVb;
|
|
double T10, dT10_dVg, dT10_dVb, dT10_dVd;
|
|
double T11, T12;
|
|
double tmp, Abulk, dAbulk_dVb, Abulk0, dAbulk0_dVb;
|
|
double T100, T101;
|
|
double VACLM, dVACLM_dVg, dVACLM_dVd, dVACLM_dVb;
|
|
double VADIBL, dVADIBL_dVg, dVADIBL_dVd, dVADIBL_dVb;
|
|
double VAHCE, dVAHCE_dVg, dVAHCE_dVd, dVAHCE_dVb;
|
|
double Xdep, dXdep_dVb, lt1, dlt1_dVb, ltw, dltw_dVb, Delt_vth, dDelt_vth_dVb;
|
|
double Theta0, dTheta0_dVb, Theta1, dTheta1_dVb;
|
|
double Thetarout, dThetarout_dVb, TempRatio, tmp1, tmp2, tmp3, tmp4;
|
|
double DIBL_Sft, dDIBL_Sft_dVd, DIBL_fact, Lambda, dLambda_dVg;
|
|
double Rout_Vgs_factor, dRout_Vgs_factor_dVg, dRout_Vgs_factor_dVb;
|
|
double dRout_Vgs_factor_dVd, Idtot, Ibtot;
|
|
double tempv, a1, ScalingFactor;
|
|
|
|
double Vgsteff, dVgsteff_dVg, dVgsteff_dVd, dVgsteff_dVb;
|
|
double Vdseff, dVdseff_dVg, dVdseff_dVd, dVdseff_dVb;
|
|
double VdseffCV, dVdseffCV_dVg, dVdseffCV_dVd, dVdseffCV_dVb;
|
|
double diffVds, diffVdsCV, dAbulk_dVg;
|
|
double beta, dbeta_dVg, dbeta_dVd, dbeta_dVb;
|
|
double gche, dgche_dVg, dgche_dVd, dgche_dVb;
|
|
double fgche1, dfgche1_dVg, dfgche1_dVd, dfgche1_dVb;
|
|
double fgche2, dfgche2_dVg, dfgche2_dVd, dfgche2_dVb;
|
|
double Idl, dIdl_dVg, dIdl_dVd, dIdl_dVb;
|
|
double Idsa, dIdsa_dVg, dIdsa_dVd, dIdsa_dVb;
|
|
double Ids, Gm, Gds, Gmb;
|
|
double Isub, Isubd, Isubs, Gbd, Gbg, Gbb;
|
|
double VASCBE, dVASCBE_dVg, dVASCBE_dVd, dVASCBE_dVb;
|
|
double CoxWovL;
|
|
double Rds, dRds_dVg, dRds_dVb, WVCox, WVCoxRds;
|
|
double Vgst2Vtm, VdsatCV, dVdsatCV_dVd, dVdsatCV_dVg, dVdsatCV_dVb;
|
|
double Leff, Weff, dWeff_dVg, dWeff_dVb;
|
|
double AbulkCV, dAbulkCV_dVb;
|
|
double qgdo, qgso, cgdo, cgso;
|
|
|
|
double qcheq, qdef, gqdef, cqdef, cqcheq, gtau_diff, gtau_drift, csreq;
|
|
double gcqdb,gcqsb,gcqgb,gcqbb,vss;
|
|
double dxpart, sxpart, ggtg, ggtd, ggts, ggtb;
|
|
double ddxpart_dVd, ddxpart_dVg, ddxpart_dVb, ddxpart_dVs;
|
|
double dsxpart_dVd, dsxpart_dVg, dsxpart_dVb, dsxpart_dVs;
|
|
|
|
double gbspsp, gbbdp, gbbsp, gbspg, gbspb, gbspdp;
|
|
double gbdpdp, gbdpg, gbdpb, gbdpsp;
|
|
double Cgg, Cgd, Cgs, Cgb, Cdg, Cdd, Cds, Cdb, Qg, Qd;
|
|
double Csg, Csd, Css, Csb, Cbg, Cbd, Cbs, Cbb, Qs, Qb;
|
|
double Cgg1, Cgb1, Cgd1, Cbg1, Cbb1, Cbd1, Csg1, Csd1, Csb1, Qac0, Qsub0;
|
|
double dQac0_dVg, dQac0_dVd, dQac0_dVb, dQsub0_dVg, dQsub0_dVd, dQsub0_dVb;
|
|
|
|
struct BSIM3V2SizeDependParam *pParam;
|
|
int ByPass, Check, ChargeComputationNeeded, error;
|
|
|
|
ScalingFactor = 1.0e-9;
|
|
ChargeComputationNeeded =
|
|
((ckt->CKTmode & (MODEAC | MODETRAN | MODEINITSMSIG)) ||
|
|
((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)))
|
|
? 1 : 0;
|
|
for (; model != NULL; model = model->BSIM3V2nextModel)
|
|
{ for (here = model->BSIM3V2instances; here != NULL;
|
|
here = here->BSIM3V2nextInstance)
|
|
{
|
|
if (here->BSIM3V2owner != ARCHme) continue;
|
|
Check = 1;
|
|
ByPass = 0;
|
|
pParam = here->pParam;
|
|
if ((ckt->CKTmode & MODEINITSMSIG))
|
|
{ vbs = *(ckt->CKTstate0 + here->BSIM3V2vbs);
|
|
vgs = *(ckt->CKTstate0 + here->BSIM3V2vgs);
|
|
vds = *(ckt->CKTstate0 + here->BSIM3V2vds);
|
|
qdef = *(ckt->CKTstate0 + here->BSIM3V2qdef);
|
|
}
|
|
else if ((ckt->CKTmode & MODEINITTRAN))
|
|
{ vbs = *(ckt->CKTstate1 + here->BSIM3V2vbs);
|
|
vgs = *(ckt->CKTstate1 + here->BSIM3V2vgs);
|
|
vds = *(ckt->CKTstate1 + here->BSIM3V2vds);
|
|
qdef = *(ckt->CKTstate1 + here->BSIM3V2qdef);
|
|
}
|
|
else if ((ckt->CKTmode & MODEINITJCT) && !here->BSIM3V2off)
|
|
{ vds = model->BSIM3V2type * here->BSIM3V2icVDS;
|
|
vgs = model->BSIM3V2type * here->BSIM3V2icVGS;
|
|
vbs = model->BSIM3V2type * here->BSIM3V2icVBS;
|
|
qdef = 0.0;
|
|
|
|
if ((vds == 0.0) && (vgs == 0.0) && (vbs == 0.0) &&
|
|
((ckt->CKTmode & (MODETRAN | MODEAC|MODEDCOP |
|
|
MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC))))
|
|
{ vbs = 0.0;
|
|
vgs = model->BSIM3V2type * pParam->BSIM3V2vth0 + 0.1;
|
|
vds = 0.1;
|
|
}
|
|
}
|
|
else if ((ckt->CKTmode & (MODEINITJCT | MODEINITFIX)) &&
|
|
(here->BSIM3V2off))
|
|
{ qdef = vbs = vgs = vds = 0.0;
|
|
}
|
|
else
|
|
{
|
|
#ifndef PREDICTOR
|
|
if ((ckt->CKTmode & MODEINITPRED))
|
|
{ xfact = ckt->CKTdelta / ckt->CKTdeltaOld[1];
|
|
*(ckt->CKTstate0 + here->BSIM3V2vbs) =
|
|
*(ckt->CKTstate1 + here->BSIM3V2vbs);
|
|
vbs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3V2vbs))
|
|
- (xfact * (*(ckt->CKTstate2 + here->BSIM3V2vbs)));
|
|
*(ckt->CKTstate0 + here->BSIM3V2vgs) =
|
|
*(ckt->CKTstate1 + here->BSIM3V2vgs);
|
|
vgs = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3V2vgs))
|
|
- (xfact * (*(ckt->CKTstate2 + here->BSIM3V2vgs)));
|
|
*(ckt->CKTstate0 + here->BSIM3V2vds) =
|
|
*(ckt->CKTstate1 + here->BSIM3V2vds);
|
|
vds = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3V2vds))
|
|
- (xfact * (*(ckt->CKTstate2 + here->BSIM3V2vds)));
|
|
*(ckt->CKTstate0 + here->BSIM3V2vbd) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2vbs)
|
|
- *(ckt->CKTstate0 + here->BSIM3V2vds);
|
|
*(ckt->CKTstate0 + here->BSIM3V2qdef) =
|
|
*(ckt->CKTstate1 + here->BSIM3V2qdef);
|
|
qdef = (1.0 + xfact)* (*(ckt->CKTstate1 + here->BSIM3V2qdef))
|
|
-(xfact * (*(ckt->CKTstate2 + here->BSIM3V2qdef)));
|
|
}
|
|
else
|
|
{
|
|
#endif /* PREDICTOR */
|
|
vbs = model->BSIM3V2type
|
|
* (*(ckt->CKTrhsOld + here->BSIM3V2bNode)
|
|
- *(ckt->CKTrhsOld + here->BSIM3V2sNodePrime));
|
|
vgs = model->BSIM3V2type
|
|
* (*(ckt->CKTrhsOld + here->BSIM3V2gNode)
|
|
- *(ckt->CKTrhsOld + here->BSIM3V2sNodePrime));
|
|
vds = model->BSIM3V2type
|
|
* (*(ckt->CKTrhsOld + here->BSIM3V2dNodePrime)
|
|
- *(ckt->CKTrhsOld + here->BSIM3V2sNodePrime));
|
|
qdef = model->BSIM3V2type
|
|
* (*(ckt->CKTrhsOld + here->BSIM3V2qNode));
|
|
#ifndef PREDICTOR
|
|
}
|
|
#endif /* PREDICTOR */
|
|
|
|
vbd = vbs - vds;
|
|
vgd = vgs - vds;
|
|
vgdo = *(ckt->CKTstate0 + here->BSIM3V2vgs)
|
|
- *(ckt->CKTstate0 + here->BSIM3V2vds);
|
|
delvbs = vbs - *(ckt->CKTstate0 + here->BSIM3V2vbs);
|
|
delvbd = vbd - *(ckt->CKTstate0 + here->BSIM3V2vbd);
|
|
delvgs = vgs - *(ckt->CKTstate0 + here->BSIM3V2vgs);
|
|
delvds = vds - *(ckt->CKTstate0 + here->BSIM3V2vds);
|
|
delvgd = vgd - vgdo;
|
|
|
|
if (here->BSIM3V2mode >= 0)
|
|
{ Idtot = here->BSIM3V2cd + here->BSIM3V2csub - here->BSIM3V2cbd;
|
|
cdhat = Idtot - here->BSIM3V2gbd * delvbd
|
|
+ (here->BSIM3V2gmbs + here->BSIM3V2gbbs) * delvbs
|
|
+ (here->BSIM3V2gm + here->BSIM3V2gbgs) * delvgs
|
|
+ (here->BSIM3V2gds + here->BSIM3V2gbds) * delvds;
|
|
Ibtot = here->BSIM3V2cbs + here->BSIM3V2cbd - here->BSIM3V2csub;
|
|
cbhat = Ibtot + here->BSIM3V2gbd * delvbd
|
|
+ (here->BSIM3V2gbs - here->BSIM3V2gbbs) * delvbs
|
|
- here->BSIM3V2gbgs * delvgs
|
|
- here->BSIM3V2gbds * delvds;
|
|
}
|
|
else
|
|
{ Idtot = here->BSIM3V2cd - here->BSIM3V2cbd;
|
|
cdhat = Idtot - (here->BSIM3V2gbd - here->BSIM3V2gmbs) * delvbd
|
|
+ here->BSIM3V2gm * delvgd
|
|
- here->BSIM3V2gds * delvds;
|
|
Ibtot = here->BSIM3V2cbs + here->BSIM3V2cbd - here->BSIM3V2csub;
|
|
cbhat = Ibtot + here->BSIM3V2gbs * delvbs
|
|
+ (here->BSIM3V2gbd - here->BSIM3V2gbbs) * delvbd
|
|
- here->BSIM3V2gbgs * delvgd
|
|
+ here->BSIM3V2gbds * delvds;
|
|
}
|
|
|
|
/* following should be one big if connected by && all over
|
|
* the place, but some C compilers can't handle that, so
|
|
* we split it up here to let them digest it in stages
|
|
*/
|
|
|
|
if ((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass))
|
|
if ((fabs(delvbs) < (ckt->CKTreltol * MAX(fabs(vbs),
|
|
fabs(*(ckt->CKTstate0+here->BSIM3V2vbs))) + ckt->CKTvoltTol)))
|
|
if ((fabs(delvbd) < (ckt->CKTreltol * MAX(fabs(vbd),
|
|
fabs(*(ckt->CKTstate0+here->BSIM3V2vbd))) + ckt->CKTvoltTol)))
|
|
if ((fabs(delvgs) < (ckt->CKTreltol * MAX(fabs(vgs),
|
|
fabs(*(ckt->CKTstate0+here->BSIM3V2vgs))) + ckt->CKTvoltTol)))
|
|
if ((fabs(delvds) < (ckt->CKTreltol * MAX(fabs(vds),
|
|
fabs(*(ckt->CKTstate0+here->BSIM3V2vds))) + ckt->CKTvoltTol)))
|
|
if ((fabs(cdhat - Idtot) < ckt->CKTreltol
|
|
* MAX(fabs(cdhat),fabs(Idtot)) + ckt->CKTabstol))
|
|
{ tempv = MAX(fabs(cbhat),fabs(Ibtot)) + ckt->CKTabstol;
|
|
if ((fabs(cbhat - Ibtot)) < ckt->CKTreltol * tempv)
|
|
{ /* bypass code */
|
|
vbs = *(ckt->CKTstate0 + here->BSIM3V2vbs);
|
|
vbd = *(ckt->CKTstate0 + here->BSIM3V2vbd);
|
|
vgs = *(ckt->CKTstate0 + here->BSIM3V2vgs);
|
|
vds = *(ckt->CKTstate0 + here->BSIM3V2vds);
|
|
qdef = *(ckt->CKTstate0 + here->BSIM3V2qdef);
|
|
|
|
vgd = vgs - vds;
|
|
vgb = vgs - vbs;
|
|
|
|
cdrain = here->BSIM3V2cd;
|
|
if ((ckt->CKTmode & (MODETRAN | MODEAC)) ||
|
|
((ckt->CKTmode & MODETRANOP) &&
|
|
(ckt->CKTmode & MODEUIC)))
|
|
{ ByPass = 1;
|
|
qgate = here->BSIM3V2qgate;
|
|
qbulk = here->BSIM3V2qbulk;
|
|
qdrn = here->BSIM3V2qdrn;
|
|
goto line755;
|
|
}
|
|
else
|
|
{ goto line850;
|
|
}
|
|
}
|
|
}
|
|
|
|
von = here->BSIM3V2von;
|
|
if (*(ckt->CKTstate0 + here->BSIM3V2vds) >= 0.0)
|
|
{ vgs = DEVfetlim(vgs, *(ckt->CKTstate0+here->BSIM3V2vgs), von);
|
|
vds = vgs - vgd;
|
|
vds = DEVlimvds(vds, *(ckt->CKTstate0 + here->BSIM3V2vds));
|
|
vgd = vgs - vds;
|
|
|
|
}
|
|
else
|
|
{ vgd = DEVfetlim(vgd, vgdo, von);
|
|
vds = vgs - vgd;
|
|
vds = -DEVlimvds(-vds, -(*(ckt->CKTstate0+here->BSIM3V2vds)));
|
|
vgs = vgd + vds;
|
|
}
|
|
|
|
if (vds >= 0.0)
|
|
{ vbs = DEVpnjlim(vbs, *(ckt->CKTstate0 + here->BSIM3V2vbs),
|
|
CONSTvt0, model->BSIM3V2vcrit, &Check);
|
|
vbd = vbs - vds;
|
|
|
|
}
|
|
else
|
|
{ vbd = DEVpnjlim(vbd, *(ckt->CKTstate0 + here->BSIM3V2vbd),
|
|
CONSTvt0, model->BSIM3V2vcrit, &Check);
|
|
vbs = vbd + vds;
|
|
}
|
|
}
|
|
|
|
/* determine DC current and derivatives */
|
|
vbd = vbs - vds;
|
|
vgd = vgs - vds;
|
|
vgb = vgs - vbs;
|
|
|
|
/* Source/drain junction diode DC model begins */
|
|
Nvtm = model->BSIM3V2vtm * model->BSIM3V2jctEmissionCoeff;
|
|
if ((here->BSIM3V2sourceArea <= 0.0) && (here->BSIM3V2sourcePerimeter <= 0.0))
|
|
{ SourceSatCurrent = 1.0e-14;
|
|
}
|
|
else
|
|
{ SourceSatCurrent = here->BSIM3V2sourceArea
|
|
* model->BSIM3V2jctTempSatCurDensity
|
|
+ here->BSIM3V2sourcePerimeter
|
|
* model->BSIM3V2jctSidewallTempSatCurDensity;
|
|
}
|
|
if (SourceSatCurrent <= 0.0)
|
|
{ here->BSIM3V2gbs = ckt->CKTgmin;
|
|
here->BSIM3V2cbs = here->BSIM3V2gbs * vbs;
|
|
}
|
|
else
|
|
{ if (model->BSIM3V2ijth == 0.0)
|
|
{ evbs = exp(vbs / Nvtm);
|
|
here->BSIM3V2gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin;
|
|
here->BSIM3V2cbs = SourceSatCurrent * (evbs - 1.0)
|
|
+ ckt->CKTgmin * vbs;
|
|
}
|
|
else
|
|
{ if (vbs < here->BSIM3V2vjsm)
|
|
{ evbs = exp(vbs / Nvtm);
|
|
here->BSIM3V2gbs = SourceSatCurrent * evbs / Nvtm + ckt->CKTgmin;
|
|
here->BSIM3V2cbs = SourceSatCurrent * (evbs - 1.0)
|
|
+ ckt->CKTgmin * vbs;
|
|
}
|
|
else
|
|
{ T0 = (SourceSatCurrent + model->BSIM3V2ijth) / Nvtm;
|
|
here->BSIM3V2gbs = T0 + ckt->CKTgmin;
|
|
here->BSIM3V2cbs = model->BSIM3V2ijth + ckt->CKTgmin * vbs
|
|
+ T0 * (vbs - here->BSIM3V2vjsm);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((here->BSIM3V2drainArea <= 0.0) && (here->BSIM3V2drainPerimeter <= 0.0))
|
|
{ DrainSatCurrent = 1.0e-14;
|
|
}
|
|
else
|
|
{ DrainSatCurrent = here->BSIM3V2drainArea
|
|
* model->BSIM3V2jctTempSatCurDensity
|
|
+ here->BSIM3V2drainPerimeter
|
|
* model->BSIM3V2jctSidewallTempSatCurDensity;
|
|
}
|
|
if (DrainSatCurrent <= 0.0)
|
|
{ here->BSIM3V2gbd = ckt->CKTgmin;
|
|
here->BSIM3V2cbd = here->BSIM3V2gbd * vbd;
|
|
}
|
|
else
|
|
{ if (model->BSIM3V2ijth == 0.0)
|
|
{ evbd = exp(vbd / Nvtm);
|
|
here->BSIM3V2gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin;
|
|
here->BSIM3V2cbd = DrainSatCurrent * (evbd - 1.0)
|
|
+ ckt->CKTgmin * vbd;
|
|
}
|
|
else
|
|
{ if (vbd < here->BSIM3V2vjdm)
|
|
{ evbd = exp(vbd / Nvtm);
|
|
here->BSIM3V2gbd = DrainSatCurrent * evbd / Nvtm + ckt->CKTgmin;
|
|
here->BSIM3V2cbd = DrainSatCurrent * (evbd - 1.0)
|
|
+ ckt->CKTgmin * vbd;
|
|
}
|
|
else
|
|
{ T0 = (DrainSatCurrent + model->BSIM3V2ijth) / Nvtm;
|
|
here->BSIM3V2gbd = T0 + ckt->CKTgmin;
|
|
here->BSIM3V2cbd = model->BSIM3V2ijth + ckt->CKTgmin * vbd
|
|
+ T0 * (vbd - here->BSIM3V2vjdm);
|
|
}
|
|
}
|
|
}
|
|
/* End of diode DC model */
|
|
|
|
if (vds >= 0.0)
|
|
{ /* normal mode */
|
|
here->BSIM3V2mode = 1;
|
|
Vds = vds;
|
|
Vgs = vgs;
|
|
Vbs = vbs;
|
|
}
|
|
else
|
|
{ /* inverse mode */
|
|
here->BSIM3V2mode = -1;
|
|
Vds = -vds;
|
|
Vgs = vgd;
|
|
Vbs = vbd;
|
|
}
|
|
|
|
T0 = Vbs - pParam->BSIM3V2vbsc - 0.001;
|
|
T1 = sqrt(T0 * T0 - 0.004 * pParam->BSIM3V2vbsc);
|
|
Vbseff = pParam->BSIM3V2vbsc + 0.5 * (T0 + T1);
|
|
dVbseff_dVb = 0.5 * (1.0 + T0 / T1);
|
|
if (Vbseff < Vbs)
|
|
{ Vbseff = Vbs;
|
|
} /* Added to avoid the possible numerical problems due to computer accuracy. See comments for diffVds */
|
|
|
|
if (Vbseff > 0.0)
|
|
{ T0 = pParam->BSIM3V2phi / (pParam->BSIM3V2phi + Vbseff);
|
|
Phis = pParam->BSIM3V2phi * T0;
|
|
dPhis_dVb = -T0 * T0;
|
|
sqrtPhis = pParam->BSIM3V2phis3 / (pParam->BSIM3V2phi + 0.5 * Vbseff);
|
|
dsqrtPhis_dVb = -0.5 * sqrtPhis * sqrtPhis / pParam->BSIM3V2phis3;
|
|
}
|
|
else
|
|
{ Phis = pParam->BSIM3V2phi - Vbseff;
|
|
dPhis_dVb = -1.0;
|
|
sqrtPhis = sqrt(Phis);
|
|
dsqrtPhis_dVb = -0.5 / sqrtPhis;
|
|
}
|
|
Xdep = pParam->BSIM3V2Xdep0 * sqrtPhis / pParam->BSIM3V2sqrtPhi;
|
|
dXdep_dVb = (pParam->BSIM3V2Xdep0 / pParam->BSIM3V2sqrtPhi)
|
|
* dsqrtPhis_dVb;
|
|
|
|
Leff = pParam->BSIM3V2leff;
|
|
Vtm = model->BSIM3V2vtm;
|
|
/* Vth Calculation */
|
|
T3 = sqrt(Xdep);
|
|
V0 = pParam->BSIM3V2vbi - pParam->BSIM3V2phi;
|
|
|
|
T0 = pParam->BSIM3V2dvt2 * Vbseff;
|
|
if (T0 >= - 0.5)
|
|
{ T1 = 1.0 + T0;
|
|
T2 = pParam->BSIM3V2dvt2;
|
|
}
|
|
else /* Added to avoid any discontinuity problems caused by dvt2 */
|
|
{ T4 = 1.0 / (3.0 + 8.0 * T0);
|
|
T1 = (1.0 + 3.0 * T0) * T4;
|
|
T2 = pParam->BSIM3V2dvt2 * T4 * T4;
|
|
}
|
|
lt1 = model->BSIM3V2factor1 * T3 * T1;
|
|
dlt1_dVb = model->BSIM3V2factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
|
|
|
|
T0 = pParam->BSIM3V2dvt2w * Vbseff;
|
|
if (T0 >= - 0.5)
|
|
{ T1 = 1.0 + T0;
|
|
T2 = pParam->BSIM3V2dvt2w;
|
|
}
|
|
else /* Added to avoid any discontinuity problems caused by dvt2w */
|
|
{ T4 = 1.0 / (3.0 + 8.0 * T0);
|
|
T1 = (1.0 + 3.0 * T0) * T4;
|
|
T2 = pParam->BSIM3V2dvt2w * T4 * T4;
|
|
}
|
|
ltw = model->BSIM3V2factor1 * T3 * T1;
|
|
dltw_dVb = model->BSIM3V2factor1 * (0.5 / T3 * T1 * dXdep_dVb + T3 * T2);
|
|
|
|
T0 = -0.5 * pParam->BSIM3V2dvt1 * Leff / lt1;
|
|
if (T0 > -EXP_THRESHOLD)
|
|
{ T1 = exp(T0);
|
|
Theta0 = T1 * (1.0 + 2.0 * T1);
|
|
dT1_dVb = -T0 / lt1 * T1 * dlt1_dVb;
|
|
dTheta0_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
|
|
}
|
|
else
|
|
{ T1 = MIN_EXP;
|
|
Theta0 = T1 * (1.0 + 2.0 * T1);
|
|
dTheta0_dVb = 0.0;
|
|
}
|
|
|
|
here->BSIM3V2thetavth = pParam->BSIM3V2dvt0 * Theta0;
|
|
Delt_vth = here->BSIM3V2thetavth * V0;
|
|
dDelt_vth_dVb = pParam->BSIM3V2dvt0 * dTheta0_dVb * V0;
|
|
|
|
T0 = -0.5 * pParam->BSIM3V2dvt1w * pParam->BSIM3V2weff * Leff / ltw;
|
|
if (T0 > -EXP_THRESHOLD)
|
|
{ T1 = exp(T0);
|
|
T2 = T1 * (1.0 + 2.0 * T1);
|
|
dT1_dVb = -T0 / ltw * T1 * dltw_dVb;
|
|
dT2_dVb = (1.0 + 4.0 * T1) * dT1_dVb;
|
|
}
|
|
else
|
|
{ T1 = MIN_EXP;
|
|
T2 = T1 * (1.0 + 2.0 * T1);
|
|
dT2_dVb = 0.0;
|
|
}
|
|
|
|
T0 = pParam->BSIM3V2dvt0w * T2;
|
|
T2 = T0 * V0;
|
|
dT2_dVb = pParam->BSIM3V2dvt0w * dT2_dVb * V0;
|
|
|
|
TempRatio = ckt->CKTtemp / model->BSIM3V2tnom - 1.0;
|
|
T0 = sqrt(1.0 + pParam->BSIM3V2nlx / Leff);
|
|
T1 = pParam->BSIM3V2k1ox * (T0 - 1.0) * pParam->BSIM3V2sqrtPhi
|
|
+ (pParam->BSIM3V2kt1 + pParam->BSIM3V2kt1l / Leff
|
|
+ pParam->BSIM3V2kt2 * Vbseff) * TempRatio;
|
|
tmp2 = model->BSIM3V2tox * pParam->BSIM3V2phi
|
|
/ (pParam->BSIM3V2weff + pParam->BSIM3V2w0);
|
|
|
|
T3 = pParam->BSIM3V2eta0 + pParam->BSIM3V2etab * Vbseff;
|
|
if (T3 < 1.0e-4) /* avoid discontinuity problems caused by etab */
|
|
{ T9 = 1.0 / (3.0 - 2.0e4 * T3);
|
|
T3 = (2.0e-4 - T3) * T9;
|
|
T4 = T9 * T9;
|
|
}
|
|
else
|
|
{ T4 = 1.0;
|
|
}
|
|
dDIBL_Sft_dVd = T3 * pParam->BSIM3V2theta0vb0;
|
|
DIBL_Sft = dDIBL_Sft_dVd * Vds;
|
|
|
|
Vth = model->BSIM3V2type * pParam->BSIM3V2vth0 - pParam->BSIM3V2k1
|
|
* pParam->BSIM3V2sqrtPhi + pParam->BSIM3V2k1ox * sqrtPhis
|
|
- pParam->BSIM3V2k2ox * Vbseff - Delt_vth - T2 + (pParam->BSIM3V2k3
|
|
+ pParam->BSIM3V2k3b * Vbseff) * tmp2 + T1 - DIBL_Sft;
|
|
|
|
here->BSIM3V2von = Vth;
|
|
|
|
dVth_dVb = pParam->BSIM3V2k1ox * dsqrtPhis_dVb - pParam->BSIM3V2k2ox
|
|
- dDelt_vth_dVb - dT2_dVb + pParam->BSIM3V2k3b * tmp2
|
|
- pParam->BSIM3V2etab * Vds * pParam->BSIM3V2theta0vb0 * T4
|
|
+ pParam->BSIM3V2kt2 * TempRatio;
|
|
dVth_dVd = -dDIBL_Sft_dVd;
|
|
|
|
/* Calculate n */
|
|
tmp2 = pParam->BSIM3V2nfactor * EPSSI / Xdep;
|
|
tmp3 = pParam->BSIM3V2cdsc + pParam->BSIM3V2cdscb * Vbseff
|
|
+ pParam->BSIM3V2cdscd * Vds;
|
|
tmp4 = (tmp2 + tmp3 * Theta0 + pParam->BSIM3V2cit) / model->BSIM3V2cox;
|
|
if (tmp4 >= -0.5)
|
|
{ n = 1.0 + tmp4;
|
|
dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
|
|
+ pParam->BSIM3V2cdscb * Theta0) / model->BSIM3V2cox;
|
|
dn_dVd = pParam->BSIM3V2cdscd * Theta0 / model->BSIM3V2cox;
|
|
}
|
|
else
|
|
/* avoid discontinuity problems caused by tmp4 */
|
|
{ T0 = 1.0 / (3.0 + 8.0 * tmp4);
|
|
n = (1.0 + 3.0 * tmp4) * T0;
|
|
T0 *= T0;
|
|
dn_dVb = (-tmp2 / Xdep * dXdep_dVb + tmp3 * dTheta0_dVb
|
|
+ pParam->BSIM3V2cdscb * Theta0) / model->BSIM3V2cox * T0;
|
|
dn_dVd = pParam->BSIM3V2cdscd * Theta0 / model->BSIM3V2cox * T0;
|
|
}
|
|
|
|
/* Poly Gate Si Depletion Effect */
|
|
T0 = pParam->BSIM3V2vfb + pParam->BSIM3V2phi;
|
|
if ((pParam->BSIM3V2ngate > 1.e18) && (pParam->BSIM3V2ngate < 1.e25)
|
|
&& (Vgs > T0))
|
|
/* added to avoid the problem caused by ngate */
|
|
{ T1 = 1.0e6 * Charge_q * EPSSI * pParam->BSIM3V2ngate
|
|
/ (model->BSIM3V2cox * model->BSIM3V2cox);
|
|
T4 = sqrt(1.0 + 2.0 * (Vgs - T0) / T1);
|
|
T2 = T1 * (T4 - 1.0);
|
|
T3 = 0.5 * T2 * T2 / T1; /* T3 = Vpoly */
|
|
T7 = 1.12 - T3 - 0.05;
|
|
T6 = sqrt(T7 * T7 + 0.224);
|
|
T5 = 1.12 - 0.5 * (T7 + T6);
|
|
Vgs_eff = Vgs - T5;
|
|
dVgs_eff_dVg = 1.0 - (0.5 - 0.5 / T4) * (1.0 + T7 / T6);
|
|
}
|
|
else
|
|
{ Vgs_eff = Vgs;
|
|
dVgs_eff_dVg = 1.0;
|
|
}
|
|
Vgst = Vgs_eff - Vth;
|
|
|
|
/* Effective Vgst (Vgsteff) Calculation */
|
|
|
|
T10 = 2.0 * n * Vtm;
|
|
VgstNVt = Vgst / T10;
|
|
ExpArg = (2.0 * pParam->BSIM3V2voff - Vgst) / T10;
|
|
|
|
/* MCJ: Very small Vgst */
|
|
if (VgstNVt > EXP_THRESHOLD)
|
|
{ Vgsteff = Vgst;
|
|
dVgsteff_dVg = dVgs_eff_dVg;
|
|
dVgsteff_dVd = -dVth_dVd;
|
|
dVgsteff_dVb = -dVth_dVb;
|
|
}
|
|
else if (ExpArg > EXP_THRESHOLD)
|
|
{ T0 = (Vgst - pParam->BSIM3V2voff) / (n * Vtm);
|
|
ExpVgst = exp(T0);
|
|
Vgsteff = Vtm * pParam->BSIM3V2cdep0 / model->BSIM3V2cox * ExpVgst;
|
|
dVgsteff_dVg = Vgsteff / (n * Vtm);
|
|
dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + T0 * Vtm * dn_dVd);
|
|
dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + T0 * Vtm * dn_dVb);
|
|
dVgsteff_dVg *= dVgs_eff_dVg;
|
|
}
|
|
else
|
|
{ ExpVgst = exp(VgstNVt);
|
|
T1 = T10 * log(1.0 + ExpVgst);
|
|
dT1_dVg = ExpVgst / (1.0 + ExpVgst);
|
|
dT1_dVb = -dT1_dVg * (dVth_dVb + Vgst / n * dn_dVb)
|
|
+ T1 / n * dn_dVb;
|
|
dT1_dVd = -dT1_dVg * (dVth_dVd + Vgst / n * dn_dVd)
|
|
+ T1 / n * dn_dVd;
|
|
|
|
dT2_dVg = -model->BSIM3V2cox / (Vtm * pParam->BSIM3V2cdep0)
|
|
* exp(ExpArg);
|
|
T2 = 1.0 - T10 * dT2_dVg;
|
|
dT2_dVd = -dT2_dVg * (dVth_dVd - 2.0 * Vtm * ExpArg * dn_dVd)
|
|
+ (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;
|
|
}
|
|
|
|
/* Calculate Effective Channel Geometry */
|
|
T9 = sqrtPhis - pParam->BSIM3V2sqrtPhi;
|
|
Weff = pParam->BSIM3V2weff - 2.0 * (pParam->BSIM3V2dwg * Vgsteff
|
|
+ pParam->BSIM3V2dwb * T9);
|
|
dWeff_dVg = -2.0 * pParam->BSIM3V2dwg;
|
|
dWeff_dVb = -2.0 * pParam->BSIM3V2dwb * 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->BSIM3V2prwg * Vgsteff + pParam->BSIM3V2prwb * T9;
|
|
if (T0 >= -0.9)
|
|
{ Rds = pParam->BSIM3V2rds0 * (1.0 + T0);
|
|
dRds_dVg = pParam->BSIM3V2rds0 * pParam->BSIM3V2prwg;
|
|
dRds_dVb = pParam->BSIM3V2rds0 * pParam->BSIM3V2prwb * dsqrtPhis_dVb;
|
|
}
|
|
else
|
|
/* to avoid the discontinuity problem due to prwg and prwb*/
|
|
{ T1 = 1.0 / (17.0 + 20.0 * T0);
|
|
Rds = pParam->BSIM3V2rds0 * (0.8 + T0) * T1;
|
|
T1 *= T1;
|
|
dRds_dVg = pParam->BSIM3V2rds0 * pParam->BSIM3V2prwg * T1;
|
|
dRds_dVb = pParam->BSIM3V2rds0 * pParam->BSIM3V2prwb * dsqrtPhis_dVb
|
|
* T1;
|
|
}
|
|
|
|
/* Calculate Abulk */
|
|
T1 = 0.5 * pParam->BSIM3V2k1ox / sqrtPhis;
|
|
dT1_dVb = -T1 / sqrtPhis * dsqrtPhis_dVb;
|
|
|
|
T9 = sqrt(pParam->BSIM3V2xj * Xdep);
|
|
tmp1 = Leff + 2.0 * T9;
|
|
T5 = Leff / tmp1;
|
|
tmp2 = pParam->BSIM3V2a0 * T5;
|
|
tmp3 = pParam->BSIM3V2weff + pParam->BSIM3V2b1;
|
|
tmp4 = pParam->BSIM3V2b0 / 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->BSIM3V2ags * pParam->BSIM3V2a0 * 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;
|
|
dAbulk_dVb *= T9 * T9;
|
|
}
|
|
|
|
T2 = pParam->BSIM3V2keta * Vbseff;
|
|
if (T2 >= -0.9)
|
|
{ T0 = 1.0 / (1.0 + T2);
|
|
dT0_dVb = -pParam->BSIM3V2keta * 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->BSIM3V2keta * 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->BSIM3V2mobMod == 1)
|
|
{ T0 = Vgsteff + Vth + Vth;
|
|
T2 = pParam->BSIM3V2ua + pParam->BSIM3V2uc * Vbseff;
|
|
T3 = T0 / model->BSIM3V2tox;
|
|
T5 = T3 * (T2 + pParam->BSIM3V2ub * T3);
|
|
dDenomi_dVg = (T2 + 2.0 * pParam->BSIM3V2ub * T3) / model->BSIM3V2tox;
|
|
dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
|
|
dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3V2uc * T3;
|
|
}
|
|
else if (model->BSIM3V2mobMod == 2)
|
|
{ T5 = Vgsteff / model->BSIM3V2tox * (pParam->BSIM3V2ua
|
|
+ pParam->BSIM3V2uc * Vbseff + pParam->BSIM3V2ub * Vgsteff
|
|
/ model->BSIM3V2tox);
|
|
dDenomi_dVg = (pParam->BSIM3V2ua + pParam->BSIM3V2uc * Vbseff
|
|
+ 2.0 * pParam->BSIM3V2ub * Vgsteff / model->BSIM3V2tox)
|
|
/ model->BSIM3V2tox;
|
|
dDenomi_dVd = 0.0;
|
|
dDenomi_dVb = Vgsteff * pParam->BSIM3V2uc / model->BSIM3V2tox;
|
|
}
|
|
else
|
|
{ T0 = Vgsteff + Vth + Vth;
|
|
T2 = 1.0 + pParam->BSIM3V2uc * Vbseff;
|
|
T3 = T0 / model->BSIM3V2tox;
|
|
T4 = T3 * (pParam->BSIM3V2ua + pParam->BSIM3V2ub * T3);
|
|
T5 = T4 * T2;
|
|
dDenomi_dVg = (pParam->BSIM3V2ua + 2.0 * pParam->BSIM3V2ub * T3) * T2
|
|
/ model->BSIM3V2tox;
|
|
dDenomi_dVd = dDenomi_dVg * 2.0 * dVth_dVd;
|
|
dDenomi_dVb = dDenomi_dVg * 2.0 * dVth_dVb + pParam->BSIM3V2uc * 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->BSIM3V2ueff = ueff = pParam->BSIM3V2u0temp / 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->BSIM3V2vsattemp * model->BSIM3V2cox;
|
|
WVCoxRds = WVCox * Rds;
|
|
|
|
Esat = 2.0 * pParam->BSIM3V2vsattemp / 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->BSIM3V2a1;
|
|
if (a1 == 0.0)
|
|
{ Lambda = pParam->BSIM3V2a2;
|
|
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->BSIM3V2a2;
|
|
T1 = T0 - pParam->BSIM3V2a1 * Vgsteff - 0.0001;
|
|
T2 = sqrt(T1 * T1 + 0.0004 * T0);
|
|
Lambda = pParam->BSIM3V2a2 + T0 - 0.5 * (T1 + T2);
|
|
dLambda_dVg = 0.5 * pParam->BSIM3V2a1 * (1.0 + T1 / T2);
|
|
}
|
|
else
|
|
{ T1 = pParam->BSIM3V2a2 + pParam->BSIM3V2a1 * Vgsteff - 0.0001;
|
|
T2 = sqrt(T1 * T1 + 0.0004 * pParam->BSIM3V2a2);
|
|
Lambda = 0.5 * (T1 + T2);
|
|
dLambda_dVg = 0.5 * pParam->BSIM3V2a1 * (1.0 + T1 / T2);
|
|
}
|
|
|
|
Vgst2Vtm = Vgsteff + 2.0 * Vtm;
|
|
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->BSIM3V2vdsat = Vdsat;
|
|
|
|
/* Effective Vds (Vdseff) Calculation */
|
|
T1 = Vdsat - Vds - pParam->BSIM3V2delta;
|
|
dT1_dVg = dVdsat_dVg;
|
|
dT1_dVd = dVdsat_dVd - 1.0;
|
|
dT1_dVb = dVdsat_dVb;
|
|
|
|
T2 = sqrt(T1 * T1 + 4.0 * pParam->BSIM3V2delta * Vdsat);
|
|
T0 = T1 / T2;
|
|
T3 = 2.0 * pParam->BSIM3V2delta / 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);
|
|
|
|
/* 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; /* This code is added to fixed the problem
|
|
caused by computer precision when
|
|
Vds is very close to Vdseff. */
|
|
diffVds = Vds - Vdseff;
|
|
/* Calculate VACLM */
|
|
if ((pParam->BSIM3V2pclm > 0.0) && (diffVds > 1.0e-10))
|
|
{ T0 = 1.0 / (pParam->BSIM3V2pclm * Abulk * pParam->BSIM3V2litl);
|
|
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->BSIM3V2thetaRout > 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->BSIM3V2thetaRout;
|
|
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->BSIM3V2pdiblb * Vbseff;
|
|
if (T7 >= -0.9)
|
|
{ T3 = 1.0 / (1.0 + T7);
|
|
VADIBL *= T3;
|
|
dVADIBL_dVg *= T3;
|
|
dVADIBL_dVb = (dVADIBL_dVb - VADIBL * pParam->BSIM3V2pdiblb)
|
|
* 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->BSIM3V2pdiblb * T4 * T4;
|
|
dVADIBL_dVd *= T3;
|
|
VADIBL *= T3;
|
|
}
|
|
}
|
|
else
|
|
{ VADIBL = MAX_EXP;
|
|
dVADIBL_dVd = dVADIBL_dVg = dVADIBL_dVb = 0.0;
|
|
}
|
|
|
|
/* Calculate VA */
|
|
|
|
T8 = pParam->BSIM3V2pvag / 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->BSIM3V2pscbe2 > 0.0)
|
|
{ if (diffVds > pParam->BSIM3V2pscbe1 * pParam->BSIM3V2litl
|
|
/ EXP_THRESHOLD)
|
|
{ T0 = pParam->BSIM3V2pscbe1 * pParam->BSIM3V2litl / diffVds;
|
|
VASCBE = Leff * exp(T0) / pParam->BSIM3V2pscbe2;
|
|
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->BSIM3V2pscbe2;
|
|
dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
|
|
}
|
|
}
|
|
else
|
|
{ VASCBE = MAX_EXP;
|
|
dVASCBE_dVg = dVASCBE_dVd = dVASCBE_dVb = 0.0;
|
|
}
|
|
|
|
/* Calculate Ids */
|
|
CoxWovL = model->BSIM3V2cox * 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->BSIM3V2alpha0 + pParam->BSIM3V2alpha1 * Leff;
|
|
if ((tmp <= 0.0) || (pParam->BSIM3V2beta0 <= 0.0))
|
|
{ Isub = Gbd = Gbb = Gbg = 0.0;
|
|
}
|
|
else
|
|
{ T2 = tmp / Leff;
|
|
if (diffVds > pParam->BSIM3V2beta0 / EXP_THRESHOLD)
|
|
{ T0 = -pParam->BSIM3V2beta0 / 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->BSIM3V2gds = Gds;
|
|
here->BSIM3V2gm = Gm;
|
|
here->BSIM3V2gmbs = Gmb;
|
|
|
|
here->BSIM3V2gbbs = Gbb;
|
|
here->BSIM3V2gbgs = Gbg;
|
|
here->BSIM3V2gbds = Gbd;
|
|
|
|
here->BSIM3V2csub = Isub;
|
|
|
|
/* BSIM3V2 thermal noise Qinv calculated from all capMod
|
|
* 0, 1, 2 & 3 stored in here->BSIM3V2qinv 1/1998 */
|
|
|
|
if ((model->BSIM3V2xpart < 0) || (!ChargeComputationNeeded))
|
|
{ qgate = qdrn = qsrc = qbulk = 0.0;
|
|
here->BSIM3V2cggb = here->BSIM3V2cgsb = here->BSIM3V2cgdb = 0.0;
|
|
here->BSIM3V2cdgb = here->BSIM3V2cdsb = here->BSIM3V2cddb = 0.0;
|
|
here->BSIM3V2cbgb = here->BSIM3V2cbsb = here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2cqdb = here->BSIM3V2cqsb = here->BSIM3V2cqgb
|
|
= here->BSIM3V2cqbb = 0.0;
|
|
here->BSIM3V2gtau = 0.0;
|
|
goto finished;
|
|
}
|
|
else if (model->BSIM3V2capMod == 0)
|
|
{
|
|
if (Vbseff < 0.0)
|
|
{ Vbseff = Vbs;
|
|
dVbseff_dVb = 1.0;
|
|
}
|
|
else
|
|
{ Vbseff = pParam->BSIM3V2phi - Phis;
|
|
dVbseff_dVb = -dPhis_dVb;
|
|
}
|
|
|
|
Vfb = pParam->BSIM3V2vfbcv;
|
|
Vth = Vfb + pParam->BSIM3V2phi + pParam->BSIM3V2k1ox * sqrtPhis;
|
|
Vgst = Vgs_eff - Vth;
|
|
dVth_dVb = pParam->BSIM3V2k1ox * dsqrtPhis_dVb;
|
|
dVgst_dVb = -dVth_dVb;
|
|
dVgst_dVg = dVgs_eff_dVg;
|
|
|
|
CoxWL = model->BSIM3V2cox * pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2leffCV;
|
|
Arg1 = Vgs_eff - Vbseff - Vfb;
|
|
|
|
if (Arg1 <= 0.0)
|
|
{ qgate = CoxWL * Arg1;
|
|
qbulk = -qgate;
|
|
qdrn = 0.0;
|
|
|
|
here->BSIM3V2cggb = CoxWL * dVgs_eff_dVg;
|
|
here->BSIM3V2cgdb = 0.0;
|
|
here->BSIM3V2cgsb = CoxWL * (dVbseff_dVb - dVgs_eff_dVg);
|
|
|
|
here->BSIM3V2cdgb = 0.0;
|
|
here->BSIM3V2cddb = 0.0;
|
|
here->BSIM3V2cdsb = 0.0;
|
|
|
|
here->BSIM3V2cbgb = -CoxWL * dVgs_eff_dVg;
|
|
here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2cbsb = -here->BSIM3V2cgsb;
|
|
here->BSIM3V2qinv = 0.0;
|
|
}
|
|
else if (Vgst <= 0.0)
|
|
{ T1 = 0.5 * pParam->BSIM3V2k1ox;
|
|
T2 = sqrt(T1 * T1 + Arg1);
|
|
qgate = CoxWL * pParam->BSIM3V2k1ox * (T2 - T1);
|
|
qbulk = -qgate;
|
|
qdrn = 0.0;
|
|
|
|
T0 = CoxWL * T1 / T2;
|
|
here->BSIM3V2cggb = T0 * dVgs_eff_dVg;
|
|
here->BSIM3V2cgdb = 0.0;
|
|
here->BSIM3V2cgsb = T0 * (dVbseff_dVb - dVgs_eff_dVg);
|
|
|
|
here->BSIM3V2cdgb = 0.0;
|
|
here->BSIM3V2cddb = 0.0;
|
|
here->BSIM3V2cdsb = 0.0;
|
|
|
|
here->BSIM3V2cbgb = -here->BSIM3V2cggb;
|
|
here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2cbsb = -here->BSIM3V2cgsb;
|
|
here->BSIM3V2qinv = 0.0;
|
|
}
|
|
else
|
|
{ One_Third_CoxWL = CoxWL / 3.0;
|
|
Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
|
|
|
|
AbulkCV = Abulk0 * pParam->BSIM3V2abulkCVfactor;
|
|
dAbulkCV_dVb = pParam->BSIM3V2abulkCVfactor * dAbulk0_dVb;
|
|
Vdsat = Vgst / AbulkCV;
|
|
dVdsat_dVg = dVgs_eff_dVg / AbulkCV;
|
|
dVdsat_dVb = - (Vdsat * dAbulkCV_dVb + dVth_dVb)/ AbulkCV;
|
|
|
|
if (model->BSIM3V2xpart > 0.5)
|
|
{ /* 0/100 Charge partition model */
|
|
if (Vdsat <= Vds)
|
|
{ /* saturation region */
|
|
T1 = Vdsat / 3.0;
|
|
qgate = CoxWL * (Vgs_eff - Vfb
|
|
- pParam->BSIM3V2phi - T1);
|
|
T2 = -Two_Third_CoxWL * Vgst;
|
|
qbulk = -(qgate + T2);
|
|
qdrn = 0.0;
|
|
|
|
here->BSIM3V2cggb = One_Third_CoxWL * (3.0
|
|
- dVdsat_dVg) * dVgs_eff_dVg;
|
|
T2 = -One_Third_CoxWL * dVdsat_dVb;
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb + T2);
|
|
here->BSIM3V2cgdb = 0.0;
|
|
|
|
here->BSIM3V2cdgb = 0.0;
|
|
here->BSIM3V2cddb = 0.0;
|
|
here->BSIM3V2cdsb = 0.0;
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
- Two_Third_CoxWL * dVgs_eff_dVg);
|
|
T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cbgb + T3);
|
|
here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
else
|
|
{ /* linear region */
|
|
Alphaz = Vgst / Vdsat;
|
|
T1 = 2.0 * Vdsat - Vds;
|
|
T2 = Vds / (3.0 * T1);
|
|
T3 = T2 * Vds;
|
|
T9 = 0.25 * CoxWL;
|
|
T4 = T9 * Alphaz;
|
|
T7 = 2.0 * Vds - T1 - 3.0 * T3;
|
|
T8 = T3 - T1 - 2.0 * Vds;
|
|
qgate = CoxWL * (Vgs_eff - Vfb
|
|
- pParam->BSIM3V2phi - 0.5 * (Vds - T3));
|
|
T10 = T4 * T8;
|
|
qdrn = T4 * T7;
|
|
qbulk = -(qgate + qdrn + T10);
|
|
|
|
T5 = T3 / T1;
|
|
here->BSIM3V2cggb = CoxWL * (1.0 - T5 * dVdsat_dVg)
|
|
* dVgs_eff_dVg;
|
|
T11 = -CoxWL * T5 * dVdsat_dVb;
|
|
here->BSIM3V2cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb + T11
|
|
+ here->BSIM3V2cgdb);
|
|
T6 = 1.0 / Vdsat;
|
|
dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
|
|
dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
|
|
T7 = T9 * T7;
|
|
T8 = T9 * T8;
|
|
T9 = 2.0 * T4 * (1.0 - 3.0 * T5);
|
|
here->BSIM3V2cdgb = (T7 * dAlphaz_dVg - T9
|
|
* dVdsat_dVg) * dVgs_eff_dVg;
|
|
T12 = T7 * dAlphaz_dVb - T9 * dVdsat_dVb;
|
|
here->BSIM3V2cddb = T4 * (3.0 - 6.0 * T2 - 3.0 * T5);
|
|
here->BSIM3V2cdsb = -(here->BSIM3V2cdgb + T12
|
|
+ here->BSIM3V2cddb);
|
|
|
|
T9 = 2.0 * T4 * (1.0 + T5);
|
|
T10 = (T8 * dAlphaz_dVg - T9 * dVdsat_dVg)
|
|
* dVgs_eff_dVg;
|
|
T11 = T8 * dAlphaz_dVb - T9 * dVdsat_dVb;
|
|
T12 = T4 * (2.0 * T2 + T5 - 1.0);
|
|
T0 = -(T10 + T11 + T12);
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
+ here->BSIM3V2cdgb + T10);
|
|
here->BSIM3V2cbdb = -(here->BSIM3V2cgdb
|
|
+ here->BSIM3V2cddb + T12);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cgsb
|
|
+ here->BSIM3V2cdsb + T0);
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
}
|
|
else if (model->BSIM3V2xpart < 0.5)
|
|
{ /* 40/60 Charge partition model */
|
|
if (Vds >= Vdsat)
|
|
{ /* saturation region */
|
|
T1 = Vdsat / 3.0;
|
|
qgate = CoxWL * (Vgs_eff - Vfb
|
|
- pParam->BSIM3V2phi - T1);
|
|
T2 = -Two_Third_CoxWL * Vgst;
|
|
qbulk = -(qgate + T2);
|
|
qdrn = 0.4 * T2;
|
|
|
|
here->BSIM3V2cggb = One_Third_CoxWL * (3.0
|
|
- dVdsat_dVg) * dVgs_eff_dVg;
|
|
T2 = -One_Third_CoxWL * dVdsat_dVb;
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb + T2);
|
|
here->BSIM3V2cgdb = 0.0;
|
|
|
|
T3 = 0.4 * Two_Third_CoxWL;
|
|
here->BSIM3V2cdgb = -T3 * dVgs_eff_dVg;
|
|
here->BSIM3V2cddb = 0.0;
|
|
T4 = T3 * dVth_dVb;
|
|
here->BSIM3V2cdsb = -(T4 + here->BSIM3V2cdgb);
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
- Two_Third_CoxWL * dVgs_eff_dVg);
|
|
T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cbgb + T3);
|
|
here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
else
|
|
{ /* linear region */
|
|
Alphaz = Vgst / Vdsat;
|
|
T1 = 2.0 * Vdsat - Vds;
|
|
T2 = Vds / (3.0 * T1);
|
|
T3 = T2 * Vds;
|
|
T9 = 0.25 * CoxWL;
|
|
T4 = T9 * Alphaz;
|
|
qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM3V2phi
|
|
- 0.5 * (Vds - T3));
|
|
|
|
T5 = T3 / T1;
|
|
here->BSIM3V2cggb = CoxWL * (1.0 - T5 * dVdsat_dVg)
|
|
* dVgs_eff_dVg;
|
|
tmp = -CoxWL * T5 * dVdsat_dVb;
|
|
here->BSIM3V2cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb
|
|
+ here->BSIM3V2cgdb + tmp);
|
|
|
|
T6 = 1.0 / Vdsat;
|
|
dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
|
|
dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
|
|
|
|
T6 = 8.0 * Vdsat * Vdsat - 6.0 * Vdsat * Vds
|
|
+ 1.2 * Vds * Vds;
|
|
T8 = T2 / T1;
|
|
T7 = Vds - T1 - T8 * T6;
|
|
qdrn = T4 * T7;
|
|
T7 *= T9;
|
|
tmp = T8 / T1;
|
|
tmp1 = T4 * (2.0 - 4.0 * tmp * T6
|
|
+ T8 * (16.0 * Vdsat - 6.0 * Vds));
|
|
|
|
here->BSIM3V2cdgb = (T7 * dAlphaz_dVg - tmp1
|
|
* dVdsat_dVg) * dVgs_eff_dVg;
|
|
T10 = T7 * dAlphaz_dVb - tmp1 * dVdsat_dVb;
|
|
here->BSIM3V2cddb = T4 * (2.0 - (1.0 / (3.0 * T1
|
|
* T1) + 2.0 * tmp) * T6 + T8
|
|
* (6.0 * Vdsat - 2.4 * Vds));
|
|
here->BSIM3V2cdsb = -(here->BSIM3V2cdgb
|
|
+ T10 + here->BSIM3V2cddb);
|
|
|
|
T7 = 2.0 * (T1 + T3);
|
|
qbulk = -(qgate - T4 * T7);
|
|
T7 *= T9;
|
|
T0 = 4.0 * T4 * (1.0 - T5);
|
|
T12 = (-T7 * dAlphaz_dVg - here->BSIM3V2cdgb
|
|
- T0 * dVdsat_dVg) * dVgs_eff_dVg;
|
|
T11 = -T7 * dAlphaz_dVb - T10 - T0 * dVdsat_dVb;
|
|
T10 = -4.0 * T4 * (T2 - 0.5 + 0.5 * T5)
|
|
- here->BSIM3V2cddb;
|
|
tmp = -(T10 + T11 + T12);
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
+ here->BSIM3V2cdgb + T12);
|
|
here->BSIM3V2cbdb = -(here->BSIM3V2cgdb
|
|
+ here->BSIM3V2cddb + T11);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cgsb
|
|
+ here->BSIM3V2cdsb + tmp);
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
}
|
|
else
|
|
{ /* 50/50 partitioning */
|
|
if (Vds >= Vdsat)
|
|
{ /* saturation region */
|
|
T1 = Vdsat / 3.0;
|
|
qgate = CoxWL * (Vgs_eff - Vfb
|
|
- pParam->BSIM3V2phi - T1);
|
|
T2 = -Two_Third_CoxWL * Vgst;
|
|
qbulk = -(qgate + T2);
|
|
qdrn = 0.5 * T2;
|
|
|
|
here->BSIM3V2cggb = One_Third_CoxWL * (3.0
|
|
- dVdsat_dVg) * dVgs_eff_dVg;
|
|
T2 = -One_Third_CoxWL * dVdsat_dVb;
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb + T2);
|
|
here->BSIM3V2cgdb = 0.0;
|
|
|
|
here->BSIM3V2cdgb = -One_Third_CoxWL * dVgs_eff_dVg;
|
|
here->BSIM3V2cddb = 0.0;
|
|
T4 = One_Third_CoxWL * dVth_dVb;
|
|
here->BSIM3V2cdsb = -(T4 + here->BSIM3V2cdgb);
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
- Two_Third_CoxWL * dVgs_eff_dVg);
|
|
T3 = -(T2 + Two_Third_CoxWL * dVth_dVb);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cbgb + T3);
|
|
here->BSIM3V2cbdb = 0.0;
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
else
|
|
{ /* linear region */
|
|
Alphaz = Vgst / Vdsat;
|
|
T1 = 2.0 * Vdsat - Vds;
|
|
T2 = Vds / (3.0 * T1);
|
|
T3 = T2 * Vds;
|
|
T9 = 0.25 * CoxWL;
|
|
T4 = T9 * Alphaz;
|
|
qgate = CoxWL * (Vgs_eff - Vfb - pParam->BSIM3V2phi
|
|
- 0.5 * (Vds - T3));
|
|
|
|
T5 = T3 / T1;
|
|
here->BSIM3V2cggb = CoxWL * (1.0 - T5 * dVdsat_dVg)
|
|
* dVgs_eff_dVg;
|
|
tmp = -CoxWL * T5 * dVdsat_dVb;
|
|
here->BSIM3V2cgdb = CoxWL * (T2 - 0.5 + 0.5 * T5);
|
|
here->BSIM3V2cgsb = -(here->BSIM3V2cggb
|
|
+ here->BSIM3V2cgdb + tmp);
|
|
|
|
T6 = 1.0 / Vdsat;
|
|
dAlphaz_dVg = T6 * (1.0 - Alphaz * dVdsat_dVg);
|
|
dAlphaz_dVb = -T6 * (dVth_dVb + Alphaz * dVdsat_dVb);
|
|
|
|
T7 = T1 + T3;
|
|
qdrn = -T4 * T7;
|
|
qbulk = - (qgate + qdrn + qdrn);
|
|
T7 *= T9;
|
|
T0 = T4 * (2.0 * T5 - 2.0);
|
|
|
|
here->BSIM3V2cdgb = (T0 * dVdsat_dVg - T7
|
|
* dAlphaz_dVg) * dVgs_eff_dVg;
|
|
T12 = T0 * dVdsat_dVb - T7 * dAlphaz_dVb;
|
|
here->BSIM3V2cddb = T4 * (1.0 - 2.0 * T2 - T5);
|
|
here->BSIM3V2cdsb = -(here->BSIM3V2cdgb + T12
|
|
+ here->BSIM3V2cddb);
|
|
|
|
here->BSIM3V2cbgb = -(here->BSIM3V2cggb
|
|
+ 2.0 * here->BSIM3V2cdgb);
|
|
here->BSIM3V2cbdb = -(here->BSIM3V2cgdb
|
|
+ 2.0 * here->BSIM3V2cddb);
|
|
here->BSIM3V2cbsb = -(here->BSIM3V2cgsb
|
|
+ 2.0 * here->BSIM3V2cdsb);
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{ if (Vbseff < 0.0)
|
|
{ VbseffCV = Vbseff;
|
|
dVbseffCV_dVb = 1.0;
|
|
}
|
|
else
|
|
{ VbseffCV = pParam->BSIM3V2phi - Phis;
|
|
dVbseffCV_dVb = -dPhis_dVb;
|
|
}
|
|
|
|
CoxWL = model->BSIM3V2cox * pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2leffCV;
|
|
|
|
/* Seperate VgsteffCV with noff and voffcv */
|
|
noff = n * pParam->BSIM3V2noff;
|
|
dnoff_dVd = pParam->BSIM3V2noff * dn_dVd;
|
|
dnoff_dVb = pParam->BSIM3V2noff * dn_dVb;
|
|
T0 = Vtm * noff;
|
|
voffcv = pParam->BSIM3V2voffcv;
|
|
VgstNVt = (Vgst - voffcv) / T0;
|
|
|
|
if (VgstNVt > EXP_THRESHOLD)
|
|
{ Vgsteff = Vgst - voffcv;
|
|
dVgsteff_dVg = dVgs_eff_dVg;
|
|
dVgsteff_dVd = -dVth_dVd;
|
|
dVgsteff_dVb = -dVth_dVb;
|
|
}
|
|
else if (VgstNVt < -EXP_THRESHOLD)
|
|
{ Vgsteff = T0 * log(1.0 + MIN_EXP);
|
|
dVgsteff_dVg = 0.0;
|
|
dVgsteff_dVd = Vgsteff / noff;
|
|
dVgsteff_dVb = dVgsteff_dVd * dnoff_dVb;
|
|
dVgsteff_dVd *= dnoff_dVd;
|
|
}
|
|
else
|
|
{ ExpVgst = exp(VgstNVt);
|
|
Vgsteff = T0 * log(1.0 + ExpVgst);
|
|
dVgsteff_dVg = ExpVgst / (1.0 + ExpVgst);
|
|
dVgsteff_dVd = -dVgsteff_dVg * (dVth_dVd + (Vgst - voffcv)
|
|
/ noff * dnoff_dVd) + Vgsteff / noff * dnoff_dVd;
|
|
dVgsteff_dVb = -dVgsteff_dVg * (dVth_dVb + (Vgst - voffcv)
|
|
/ noff * dnoff_dVb) + Vgsteff / noff * dnoff_dVb;
|
|
dVgsteff_dVg *= dVgs_eff_dVg;
|
|
} /* End of VgsteffCV - Weidong 5/1998 */
|
|
|
|
if (model->BSIM3V2capMod == 1)
|
|
{ if (model->BSIM3V2version < 3.2)
|
|
{ Vfb = Vth - pParam->BSIM3V2phi - pParam->BSIM3V2k1ox * sqrtPhis;
|
|
dVfb_dVb = dVth_dVb - pParam->BSIM3V2k1ox * dsqrtPhis_dVb;
|
|
dVfb_dVd = dVth_dVd;
|
|
}
|
|
else
|
|
{ Vfb = pParam->BSIM3V2vfbzb;
|
|
dVfb_dVb = dVfb_dVd = 0.0;
|
|
}
|
|
|
|
Arg1 = Vgs_eff - VbseffCV - Vfb - Vgsteff;
|
|
|
|
if (Arg1 <= 0.0)
|
|
{ qgate = CoxWL * Arg1;
|
|
Cgg = CoxWL * (dVgs_eff_dVg - dVgsteff_dVg);
|
|
Cgd = -CoxWL * (dVfb_dVd + dVgsteff_dVd);
|
|
Cgb = -CoxWL * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb);
|
|
}
|
|
else
|
|
{ T0 = 0.5 * pParam->BSIM3V2k1ox;
|
|
T1 = sqrt(T0 * T0 + Arg1);
|
|
T2 = CoxWL * T0 / T1;
|
|
|
|
qgate = CoxWL * pParam->BSIM3V2k1ox * (T1 - T0);
|
|
|
|
Cgg = T2 * (dVgs_eff_dVg - dVgsteff_dVg);
|
|
Cgd = -T2 * (dVfb_dVd + dVgsteff_dVd);
|
|
Cgb = -T2 * (dVfb_dVb + dVbseffCV_dVb + dVgsteff_dVb);
|
|
}
|
|
qbulk = -qgate;
|
|
Cbg = -Cgg;
|
|
Cbd = -Cgd;
|
|
Cbb = -Cgb;
|
|
|
|
One_Third_CoxWL = CoxWL / 3.0;
|
|
Two_Third_CoxWL = 2.0 * One_Third_CoxWL;
|
|
AbulkCV = Abulk0 * pParam->BSIM3V2abulkCVfactor;
|
|
dAbulkCV_dVb = pParam->BSIM3V2abulkCVfactor * dAbulk0_dVb;
|
|
VdsatCV = Vgsteff / AbulkCV;
|
|
if (VdsatCV < Vds)
|
|
{ dVdsatCV_dVg = 1.0 / AbulkCV;
|
|
dVdsatCV_dVb = -VdsatCV * dAbulkCV_dVb / AbulkCV;
|
|
T0 = Vgsteff - VdsatCV / 3.0;
|
|
dT0_dVg = 1.0 - dVdsatCV_dVg / 3.0;
|
|
dT0_dVb = -dVdsatCV_dVb / 3.0;
|
|
qgate += CoxWL * T0;
|
|
Cgg1 = CoxWL * dT0_dVg;
|
|
Cgb1 = CoxWL * dT0_dVb + Cgg1 * dVgsteff_dVb;
|
|
Cgd1 = Cgg1 * dVgsteff_dVd;
|
|
Cgg1 *= dVgsteff_dVg;
|
|
Cgg += Cgg1;
|
|
Cgb += Cgb1;
|
|
Cgd += Cgd1;
|
|
|
|
T0 = VdsatCV - Vgsteff;
|
|
dT0_dVg = dVdsatCV_dVg - 1.0;
|
|
dT0_dVb = dVdsatCV_dVb;
|
|
qbulk += One_Third_CoxWL * T0;
|
|
Cbg1 = One_Third_CoxWL * dT0_dVg;
|
|
Cbb1 = One_Third_CoxWL * dT0_dVb + Cbg1 * dVgsteff_dVb;
|
|
Cbd1 = Cbg1 * dVgsteff_dVd;
|
|
Cbg1 *= dVgsteff_dVg;
|
|
Cbg += Cbg1;
|
|
Cbb += Cbb1;
|
|
Cbd += Cbd1;
|
|
|
|
if (model->BSIM3V2xpart > 0.5)
|
|
T0 = -Two_Third_CoxWL;
|
|
else if (model->BSIM3V2xpart < 0.5)
|
|
T0 = -0.4 * CoxWL;
|
|
else
|
|
T0 = -One_Third_CoxWL;
|
|
|
|
qsrc = T0 * Vgsteff;
|
|
Csg = T0 * dVgsteff_dVg;
|
|
Csb = T0 * dVgsteff_dVb;
|
|
Csd = T0 * dVgsteff_dVd;
|
|
Cgb *= dVbseff_dVb;
|
|
Cbb *= dVbseff_dVb;
|
|
Csb *= dVbseff_dVb;
|
|
}
|
|
else
|
|
{ T0 = AbulkCV * Vds;
|
|
T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1.e-20);
|
|
T2 = Vds / T1;
|
|
T3 = T0 * T2;
|
|
dT3_dVg = -12.0 * T2 * T2 * AbulkCV;
|
|
dT3_dVd = 6.0 * T0 * (4.0 * Vgsteff - T0) / T1 / T1 - 0.5;
|
|
dT3_dVb = 12.0 * T2 * T2 * dAbulkCV_dVb * Vgsteff;
|
|
|
|
qgate += CoxWL * (Vgsteff - 0.5 * Vds + T3);
|
|
Cgg1 = CoxWL * (1.0 + dT3_dVg);
|
|
Cgb1 = CoxWL * dT3_dVb + Cgg1 * dVgsteff_dVb;
|
|
Cgd1 = CoxWL * dT3_dVd + Cgg1 * dVgsteff_dVd;
|
|
Cgg1 *= dVgsteff_dVg;
|
|
Cgg += Cgg1;
|
|
Cgb += Cgb1;
|
|
Cgd += Cgd1;
|
|
|
|
qbulk += CoxWL * (1.0 - AbulkCV) * (0.5 * Vds - T3);
|
|
Cbg1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVg);
|
|
Cbb1 = -CoxWL * ((1.0 - AbulkCV) * dT3_dVb
|
|
+ (0.5 * Vds - T3) * dAbulkCV_dVb)
|
|
+ Cbg1 * dVgsteff_dVb;
|
|
Cbd1 = -CoxWL * (1.0 - AbulkCV) * dT3_dVd
|
|
+ Cbg1 * dVgsteff_dVd;
|
|
Cbg1 *= dVgsteff_dVg;
|
|
Cbg += Cbg1;
|
|
Cbb += Cbb1;
|
|
Cbd += Cbd1;
|
|
|
|
if (model->BSIM3V2xpart > 0.5)
|
|
{ /* 0/100 Charge petition model */
|
|
T1 = T1 + T1;
|
|
qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0
|
|
- T0 * T0 / T1);
|
|
Csg = -CoxWL * (0.5 + 24.0 * T0 * Vds / T1 / T1
|
|
* AbulkCV);
|
|
Csb = -CoxWL * (0.25 * Vds * dAbulkCV_dVb
|
|
- 12.0 * T0 * Vds / T1 / T1 * (4.0 * Vgsteff - T0)
|
|
* dAbulkCV_dVb) + Csg * dVgsteff_dVb;
|
|
Csd = -CoxWL * (0.25 * AbulkCV - 12.0 * AbulkCV * T0
|
|
/ T1 / T1 * (4.0 * Vgsteff - T0))
|
|
+ Csg * dVgsteff_dVd;
|
|
Csg *= dVgsteff_dVg;
|
|
}
|
|
else if (model->BSIM3V2xpart < 0.5)
|
|
{ /* 40/60 Charge petition model */
|
|
T1 = T1 / 12.0;
|
|
T2 = 0.5 * CoxWL / (T1 * T1);
|
|
T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff
|
|
* (Vgsteff - 4.0 * T0 / 3.0))
|
|
- 2.0 * T0 * T0 * T0 / 15.0;
|
|
qsrc = -T2 * T3;
|
|
T4 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
|
|
+ 0.4 * T0 * T0;
|
|
Csg = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
|
|
* Vgsteff - 8.0 * T0 / 3.0)
|
|
+ 2.0 * T0 * T0 / 3.0);
|
|
Csb = (qsrc / T1 * Vds + T2 * T4 * Vds) * dAbulkCV_dVb
|
|
+ Csg * dVgsteff_dVb;
|
|
Csd = (qsrc / T1 + T2 * T4) * AbulkCV
|
|
+ Csg * dVgsteff_dVd;
|
|
Csg *= dVgsteff_dVg;
|
|
}
|
|
else
|
|
{ /* 50/50 Charge petition model */
|
|
qsrc = -0.5 * (qgate + qbulk);
|
|
Csg = -0.5 * (Cgg1 + Cbg1);
|
|
Csb = -0.5 * (Cgb1 + Cbb1);
|
|
Csd = -0.5 * (Cgd1 + Cbd1);
|
|
}
|
|
Cgb *= dVbseff_dVb;
|
|
Cbb *= dVbseff_dVb;
|
|
Csb *= dVbseff_dVb;
|
|
}
|
|
qdrn = -(qgate + qbulk + qsrc);
|
|
here->BSIM3V2cggb = Cgg;
|
|
here->BSIM3V2cgsb = -(Cgg + Cgd + Cgb);
|
|
here->BSIM3V2cgdb = Cgd;
|
|
here->BSIM3V2cdgb = -(Cgg + Cbg + Csg);
|
|
here->BSIM3V2cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb
|
|
+ Csg + Csd + Csb);
|
|
here->BSIM3V2cddb = -(Cgd + Cbd + Csd);
|
|
here->BSIM3V2cbgb = Cbg;
|
|
here->BSIM3V2cbsb = -(Cbg + Cbd + Cbb);
|
|
here->BSIM3V2cbdb = Cbd;
|
|
here->BSIM3V2qinv = -(qgate + qbulk);
|
|
}
|
|
|
|
else if (model->BSIM3V2capMod == 2)
|
|
{ if (model->BSIM3V2version < 3.2)
|
|
{ Vfb = Vth - pParam->BSIM3V2phi - pParam->BSIM3V2k1ox * sqrtPhis;
|
|
dVfb_dVb = dVth_dVb - pParam->BSIM3V2k1ox * dsqrtPhis_dVb;
|
|
dVfb_dVd = dVth_dVd;
|
|
}
|
|
else
|
|
{ Vfb = pParam->BSIM3V2vfbzb;
|
|
dVfb_dVb = dVfb_dVd = 0.0;
|
|
}
|
|
|
|
V3 = Vfb - Vgs_eff + VbseffCV - DELTA_3;
|
|
if (Vfb <= 0.0)
|
|
{ T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * Vfb);
|
|
T2 = -DELTA_3 / T0;
|
|
}
|
|
else
|
|
{ T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * Vfb);
|
|
T2 = DELTA_3 / T0;
|
|
}
|
|
|
|
T1 = 0.5 * (1.0 + V3 / T0);
|
|
Vfbeff = Vfb - 0.5 * (V3 + T0);
|
|
dVfbeff_dVd = (1.0 - T1 - T2) * dVfb_dVd;
|
|
dVfbeff_dVg = T1 * dVgs_eff_dVg;
|
|
dVfbeff_dVb = (1.0 - T1 - T2) * dVfb_dVb
|
|
- T1 * dVbseffCV_dVb;
|
|
Qac0 = CoxWL * (Vfbeff - Vfb);
|
|
dQac0_dVg = CoxWL * dVfbeff_dVg;
|
|
dQac0_dVd = CoxWL * (dVfbeff_dVd - dVfb_dVd);
|
|
dQac0_dVb = CoxWL * (dVfbeff_dVb - dVfb_dVb);
|
|
|
|
T0 = 0.5 * pParam->BSIM3V2k1ox;
|
|
T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
|
|
if (pParam->BSIM3V2k1ox == 0.0)
|
|
{ T1 = 0.0;
|
|
T2 = 0.0;
|
|
}
|
|
else if (T3 < 0.0)
|
|
{ T1 = T0 + T3 / pParam->BSIM3V2k1ox;
|
|
T2 = CoxWL;
|
|
}
|
|
else
|
|
{ T1 = sqrt(T0 * T0 + T3);
|
|
T2 = CoxWL * T0 / T1;
|
|
}
|
|
|
|
Qsub0 = CoxWL * pParam->BSIM3V2k1ox * (T1 - T0);
|
|
|
|
dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg);
|
|
dQsub0_dVd = -T2 * (dVfbeff_dVd + dVgsteff_dVd);
|
|
dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb
|
|
+ dVgsteff_dVb);
|
|
|
|
AbulkCV = Abulk0 * pParam->BSIM3V2abulkCVfactor;
|
|
dAbulkCV_dVb = pParam->BSIM3V2abulkCVfactor * dAbulk0_dVb;
|
|
VdsatCV = Vgsteff / AbulkCV;
|
|
|
|
V4 = VdsatCV - Vds - DELTA_4;
|
|
T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV);
|
|
VdseffCV = VdsatCV - 0.5 * (V4 + T0);
|
|
T1 = 0.5 * (1.0 + V4 / T0);
|
|
T2 = DELTA_4 / T0;
|
|
T3 = (1.0 - T1 - T2) / AbulkCV;
|
|
dVdseffCV_dVg = T3;
|
|
dVdseffCV_dVd = T1;
|
|
dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
|
|
|
|
T0 = AbulkCV * VdseffCV;
|
|
T1 = 12.0 * (Vgsteff - 0.5 * T0 + 1e-20);
|
|
T2 = VdseffCV / T1;
|
|
T3 = T0 * T2;
|
|
|
|
T4 = (1.0 - 12.0 * T2 * T2 * AbulkCV);
|
|
T5 = (6.0 * T0 * (4.0 * Vgsteff - T0) / (T1 * T1) - 0.5);
|
|
T6 = 12.0 * T2 * T2 * Vgsteff;
|
|
|
|
qinoi = -CoxWL * (Vgsteff - 0.5 * T0 + AbulkCV * T3);
|
|
qgate = CoxWL * (Vgsteff - 0.5 * VdseffCV + T3);
|
|
Cgg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
|
|
Cgd1 = CoxWL * T5 * dVdseffCV_dVd + Cgg1 * dVgsteff_dVd;
|
|
Cgb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Cgg1 * dVgsteff_dVb;
|
|
Cgg1 *= dVgsteff_dVg;
|
|
|
|
T7 = 1.0 - AbulkCV;
|
|
qbulk = CoxWL * T7 * (0.5 * VdseffCV - T3);
|
|
T4 = -T7 * (T4 - 1.0);
|
|
T5 = -T7 * T5;
|
|
T6 = -(T7 * T6 + (0.5 * VdseffCV - T3));
|
|
Cbg1 = CoxWL * (T4 + T5 * dVdseffCV_dVg);
|
|
Cbd1 = CoxWL * T5 * dVdseffCV_dVd + Cbg1 * dVgsteff_dVd;
|
|
Cbb1 = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Cbg1 * dVgsteff_dVb;
|
|
Cbg1 *= dVgsteff_dVg;
|
|
|
|
if (model->BSIM3V2xpart > 0.5)
|
|
{ /* 0/100 Charge petition model */
|
|
T1 = T1 + T1;
|
|
qsrc = -CoxWL * (0.5 * Vgsteff + 0.25 * T0
|
|
- T0 * T0 / T1);
|
|
T7 = (4.0 * Vgsteff - T0) / (T1 * T1);
|
|
T4 = -(0.5 + 24.0 * T0 * T0 / (T1 * T1));
|
|
T5 = -(0.25 * AbulkCV - 12.0 * AbulkCV * T0 * T7);
|
|
T6 = -(0.25 * VdseffCV - 12.0 * T0 * VdseffCV * T7);
|
|
Csg = CoxWL * (T4 + T5 * dVdseffCV_dVg);
|
|
Csd = CoxWL * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
|
|
Csb = CoxWL * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Csg * dVgsteff_dVb;
|
|
Csg *= dVgsteff_dVg;
|
|
}
|
|
else if (model->BSIM3V2xpart < 0.5)
|
|
{ /* 40/60 Charge petition model */
|
|
T1 = T1 / 12.0;
|
|
T2 = 0.5 * CoxWL / (T1 * T1);
|
|
T3 = Vgsteff * (2.0 * T0 * T0 / 3.0 + Vgsteff
|
|
* (Vgsteff - 4.0 * T0 / 3.0))
|
|
- 2.0 * T0 * T0 * T0 / 15.0;
|
|
qsrc = -T2 * T3;
|
|
T7 = 4.0 / 3.0 * Vgsteff * (Vgsteff - T0)
|
|
+ 0.4 * T0 * T0;
|
|
T4 = -2.0 * qsrc / T1 - T2 * (Vgsteff * (3.0
|
|
* Vgsteff - 8.0 * T0 / 3.0)
|
|
+ 2.0 * T0 * T0 / 3.0);
|
|
T5 = (qsrc / T1 + T2 * T7) * AbulkCV;
|
|
T6 = (qsrc / T1 * VdseffCV + T2 * T7 * VdseffCV);
|
|
Csg = (T4 + T5 * dVdseffCV_dVg);
|
|
Csd = T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd;
|
|
Csb = (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Csg * dVgsteff_dVb;
|
|
Csg *= dVgsteff_dVg;
|
|
}
|
|
else
|
|
{ /* 50/50 Charge petition model */
|
|
qsrc = -0.5 * (qgate + qbulk);
|
|
Csg = -0.5 * (Cgg1 + Cbg1);
|
|
Csb = -0.5 * (Cgb1 + Cbb1);
|
|
Csd = -0.5 * (Cgd1 + Cbd1);
|
|
}
|
|
|
|
qgate += Qac0 + Qsub0;
|
|
qbulk -= (Qac0 + Qsub0);
|
|
qdrn = -(qgate + qbulk + qsrc);
|
|
|
|
Cgg = dQac0_dVg + dQsub0_dVg + Cgg1;
|
|
Cgd = dQac0_dVd + dQsub0_dVd + Cgd1;
|
|
Cgb = dQac0_dVb + dQsub0_dVb + Cgb1;
|
|
|
|
Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
|
|
Cbd = Cbd1 - dQac0_dVd - dQsub0_dVd;
|
|
Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
|
|
|
|
Cgb *= dVbseff_dVb;
|
|
Cbb *= dVbseff_dVb;
|
|
Csb *= dVbseff_dVb;
|
|
|
|
here->BSIM3V2cggb = Cgg;
|
|
here->BSIM3V2cgsb = -(Cgg + Cgd + Cgb);
|
|
here->BSIM3V2cgdb = Cgd;
|
|
here->BSIM3V2cdgb = -(Cgg + Cbg + Csg);
|
|
here->BSIM3V2cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb
|
|
+ Csg + Csd + Csb);
|
|
here->BSIM3V2cddb = -(Cgd + Cbd + Csd);
|
|
here->BSIM3V2cbgb = Cbg;
|
|
here->BSIM3V2cbsb = -(Cbg + Cbd + Cbb);
|
|
here->BSIM3V2cbdb = Cbd;
|
|
here->BSIM3V2qinv = qinoi;
|
|
}
|
|
|
|
/* New Charge-Thickness capMod (CTM) begins - Weidong 7/1997 */
|
|
else if (model->BSIM3V2capMod == 3)
|
|
{ V3 = pParam->BSIM3V2vfbzb - Vgs_eff + VbseffCV - DELTA_3;
|
|
if (pParam->BSIM3V2vfbzb <= 0.0)
|
|
{ T0 = sqrt(V3 * V3 - 4.0 * DELTA_3 * pParam->BSIM3V2vfbzb);
|
|
T2 = -DELTA_3 / T0;
|
|
}
|
|
else
|
|
{ T0 = sqrt(V3 * V3 + 4.0 * DELTA_3 * pParam->BSIM3V2vfbzb);
|
|
T2 = DELTA_3 / T0;
|
|
}
|
|
|
|
T1 = 0.5 * (1.0 + V3 / T0);
|
|
Vfbeff = pParam->BSIM3V2vfbzb - 0.5 * (V3 + T0);
|
|
dVfbeff_dVg = T1 * dVgs_eff_dVg;
|
|
dVfbeff_dVb = -T1 * dVbseffCV_dVb;
|
|
|
|
Cox = model->BSIM3V2cox;
|
|
Tox = 1.0e8 * model->BSIM3V2tox;
|
|
T0 = (Vgs_eff - VbseffCV - pParam->BSIM3V2vfbzb) / Tox;
|
|
dT0_dVg = dVgs_eff_dVg / Tox;
|
|
dT0_dVb = -dVbseffCV_dVb / Tox;
|
|
|
|
tmp = T0 * pParam->BSIM3V2acde;
|
|
if ((-EXP_THRESHOLD < tmp) && (tmp < EXP_THRESHOLD))
|
|
{ Tcen = pParam->BSIM3V2ldeb * exp(tmp);
|
|
dTcen_dVg = pParam->BSIM3V2acde * Tcen;
|
|
dTcen_dVb = dTcen_dVg * dT0_dVb;
|
|
dTcen_dVg *= dT0_dVg;
|
|
}
|
|
else if (tmp <= -EXP_THRESHOLD)
|
|
{ Tcen = pParam->BSIM3V2ldeb * MIN_EXP;
|
|
dTcen_dVg = dTcen_dVb = 0.0;
|
|
}
|
|
else
|
|
{ Tcen = pParam->BSIM3V2ldeb * MAX_EXP;
|
|
dTcen_dVg = dTcen_dVb = 0.0;
|
|
}
|
|
|
|
LINK = 1.0e-3 * model->BSIM3V2tox;
|
|
V3 = pParam->BSIM3V2ldeb - Tcen - LINK;
|
|
V4 = sqrt(V3 * V3 + 4.0 * LINK * pParam->BSIM3V2ldeb);
|
|
Tcen = pParam->BSIM3V2ldeb - 0.5 * (V3 + V4);
|
|
T1 = 0.5 * (1.0 + V3 / V4);
|
|
dTcen_dVg *= T1;
|
|
dTcen_dVb *= T1;
|
|
|
|
Ccen = EPSSI / Tcen;
|
|
T2 = Cox / (Cox + Ccen);
|
|
Coxeff = T2 * Ccen;
|
|
T3 = -Ccen / Tcen;
|
|
dCoxeff_dVg = T2 * T2 * T3;
|
|
dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
|
|
dCoxeff_dVg *= dTcen_dVg;
|
|
CoxWLcen = CoxWL * Coxeff / Cox;
|
|
|
|
Qac0 = CoxWLcen * (Vfbeff - pParam->BSIM3V2vfbzb);
|
|
QovCox = Qac0 / Coxeff;
|
|
dQac0_dVg = CoxWLcen * dVfbeff_dVg
|
|
+ QovCox * dCoxeff_dVg;
|
|
dQac0_dVb = CoxWLcen * dVfbeff_dVb
|
|
+ QovCox * dCoxeff_dVb;
|
|
|
|
T0 = 0.5 * pParam->BSIM3V2k1ox;
|
|
T3 = Vgs_eff - Vfbeff - VbseffCV - Vgsteff;
|
|
if (pParam->BSIM3V2k1ox == 0.0)
|
|
{ T1 = 0.0;
|
|
T2 = 0.0;
|
|
}
|
|
else if (T3 < 0.0)
|
|
{ T1 = T0 + T3 / pParam->BSIM3V2k1ox;
|
|
T2 = CoxWLcen;
|
|
}
|
|
else
|
|
{ T1 = sqrt(T0 * T0 + T3);
|
|
T2 = CoxWLcen * T0 / T1;
|
|
}
|
|
|
|
Qsub0 = CoxWLcen * pParam->BSIM3V2k1ox * (T1 - T0);
|
|
QovCox = Qsub0 / Coxeff;
|
|
dQsub0_dVg = T2 * (dVgs_eff_dVg - dVfbeff_dVg - dVgsteff_dVg)
|
|
+ QovCox * dCoxeff_dVg;
|
|
dQsub0_dVd = -T2 * dVgsteff_dVd;
|
|
dQsub0_dVb = -T2 * (dVfbeff_dVb + dVbseffCV_dVb + dVgsteff_dVb)
|
|
+ QovCox * dCoxeff_dVb;
|
|
|
|
/* Gate-bias dependent delta Phis begins */
|
|
if (pParam->BSIM3V2k1ox <= 0.0)
|
|
{ Denomi = 0.25 * pParam->BSIM3V2moin * Vtm;
|
|
T0 = 0.5 * pParam->BSIM3V2sqrtPhi;
|
|
}
|
|
else
|
|
{ Denomi = pParam->BSIM3V2moin * Vtm
|
|
* pParam->BSIM3V2k1ox * pParam->BSIM3V2k1ox;
|
|
T0 = pParam->BSIM3V2k1ox * pParam->BSIM3V2sqrtPhi;
|
|
}
|
|
T1 = 2.0 * T0 + Vgsteff;
|
|
|
|
DeltaPhi = Vtm * log(1.0 + T1 * Vgsteff / Denomi);
|
|
dDeltaPhi_dVg = 2.0 * Vtm * (T1 -T0) / (Denomi + T1 * Vgsteff);
|
|
dDeltaPhi_dVd = dDeltaPhi_dVg * dVgsteff_dVd;
|
|
dDeltaPhi_dVb = dDeltaPhi_dVg * dVgsteff_dVb;
|
|
/* End of delta Phis */
|
|
|
|
T3 = 4.0 * (Vth - pParam->BSIM3V2vfbzb - pParam->BSIM3V2phi);
|
|
Tox += Tox;
|
|
if (T3 >= 0.0)
|
|
T0 = (Vgsteff + T3) / Tox;
|
|
else
|
|
T0 = (Vgsteff + 1.0e-20) / Tox;
|
|
tmp = exp(0.7 * log(T0));
|
|
T1 = 1.0 + tmp;
|
|
T2 = 0.7 * tmp / (T0 * Tox);
|
|
Tcen = 1.9e-9 / T1;
|
|
dTcen_dVg = -1.9e-9 * T2 / T1 /T1;
|
|
dTcen_dVd = dTcen_dVg * (4.0 * dVth_dVd + dVgsteff_dVd);
|
|
dTcen_dVb = dTcen_dVg * (4.0 * dVth_dVb + dVgsteff_dVb);
|
|
dTcen_dVg *= dVgsteff_dVg;
|
|
|
|
Ccen = EPSSI / Tcen;
|
|
T0 = Cox / (Cox + Ccen);
|
|
Coxeff = T0 * Ccen;
|
|
T1 = -Ccen / Tcen;
|
|
dCoxeff_dVg = T0 * T0 * T1;
|
|
dCoxeff_dVd = dCoxeff_dVg * dTcen_dVd;
|
|
dCoxeff_dVb = dCoxeff_dVg * dTcen_dVb;
|
|
dCoxeff_dVg *= dTcen_dVg;
|
|
CoxWLcen = CoxWL * Coxeff / Cox;
|
|
|
|
AbulkCV = Abulk0 * pParam->BSIM3V2abulkCVfactor;
|
|
dAbulkCV_dVb = pParam->BSIM3V2abulkCVfactor * dAbulk0_dVb;
|
|
VdsatCV = (Vgsteff - DeltaPhi) / AbulkCV;
|
|
V4 = VdsatCV - Vds - DELTA_4;
|
|
T0 = sqrt(V4 * V4 + 4.0 * DELTA_4 * VdsatCV);
|
|
VdseffCV = VdsatCV - 0.5 * (V4 + T0);
|
|
T1 = 0.5 * (1.0 + V4 / T0);
|
|
T2 = DELTA_4 / T0;
|
|
T3 = (1.0 - T1 - T2) / AbulkCV;
|
|
T4 = T3 * ( 1.0 - dDeltaPhi_dVg);
|
|
dVdseffCV_dVg = T4;
|
|
dVdseffCV_dVd = T1;
|
|
dVdseffCV_dVb = -T3 * VdsatCV * dAbulkCV_dVb;
|
|
|
|
T0 = AbulkCV * VdseffCV;
|
|
T1 = Vgsteff - DeltaPhi;
|
|
T2 = 12.0 * (T1 - 0.5 * T0 + 1.0e-20);
|
|
T3 = T0 / T2;
|
|
T4 = 1.0 - 12.0 * T3 * T3;
|
|
T5 = AbulkCV * (6.0 * T0 * (4.0 * T1 - T0) / (T2 * T2) - 0.5);
|
|
T6 = T5 * VdseffCV / AbulkCV;
|
|
|
|
qgate = qinoi = CoxWLcen * (T1 - T0 * (0.5 - T3));
|
|
QovCox = qgate / Coxeff;
|
|
Cgg1 = CoxWLcen * (T4 * (1.0 - dDeltaPhi_dVg)
|
|
+ T5 * dVdseffCV_dVg);
|
|
Cgd1 = CoxWLcen * T5 * dVdseffCV_dVd + Cgg1
|
|
* dVgsteff_dVd + QovCox * dCoxeff_dVd;
|
|
Cgb1 = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Cgg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
|
|
Cgg1 = Cgg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
|
|
|
|
|
|
T7 = 1.0 - AbulkCV;
|
|
T8 = T2 * T2;
|
|
T9 = 12.0 * T7 * T0 * T0 / (T8 * AbulkCV);
|
|
T10 = T9 * (1.0 - dDeltaPhi_dVg);
|
|
T11 = -T7 * T5 / AbulkCV;
|
|
T12 = -(T9 * T1 / AbulkCV + VdseffCV * (0.5 - T0 / T2));
|
|
|
|
qbulk = CoxWLcen * T7 * (0.5 * VdseffCV - T0 * VdseffCV / T2);
|
|
QovCox = qbulk / Coxeff;
|
|
Cbg1 = CoxWLcen * (T10 + T11 * dVdseffCV_dVg);
|
|
Cbd1 = CoxWLcen * T11 * dVdseffCV_dVd + Cbg1
|
|
* dVgsteff_dVd + QovCox * dCoxeff_dVd;
|
|
Cbb1 = CoxWLcen * (T11 * dVdseffCV_dVb + T12 * dAbulkCV_dVb)
|
|
+ Cbg1 * dVgsteff_dVb + QovCox * dCoxeff_dVb;
|
|
Cbg1 = Cbg1 * dVgsteff_dVg + QovCox * dCoxeff_dVg;
|
|
|
|
if (model->BSIM3V2xpart > 0.5)
|
|
{ /* 0/100 partition */
|
|
qsrc = -CoxWLcen * (T1 / 2.0 + T0 / 4.0
|
|
- 0.5 * T0 * T0 / T2);
|
|
QovCox = qsrc / Coxeff;
|
|
T2 += T2;
|
|
T3 = T2 * T2;
|
|
T7 = -(0.25 - 12.0 * T0 * (4.0 * T1 - T0) / T3);
|
|
T4 = -(0.5 + 24.0 * T0 * T0 / T3) * (1.0 - dDeltaPhi_dVg);
|
|
T5 = T7 * AbulkCV;
|
|
T6 = T7 * VdseffCV;
|
|
|
|
Csg = CoxWLcen * (T4 + T5 * dVdseffCV_dVg);
|
|
Csd = CoxWLcen * T5 * dVdseffCV_dVd + Csg * dVgsteff_dVd
|
|
+ QovCox * dCoxeff_dVd;
|
|
Csb = CoxWLcen * (T5 * dVdseffCV_dVb + T6 * dAbulkCV_dVb)
|
|
+ Csg * dVgsteff_dVb + QovCox * dCoxeff_dVb;
|
|
Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
|
|
}
|
|
else if (model->BSIM3V2xpart < 0.5)
|
|
{ /* 40/60 partition */
|
|
T2 = T2 / 12.0;
|
|
T3 = 0.5 * CoxWLcen / (T2 * T2);
|
|
T4 = T1 * (2.0 * T0 * T0 / 3.0 + T1 * (T1 - 4.0
|
|
* T0 / 3.0)) - 2.0 * T0 * T0 * T0 / 15.0;
|
|
qsrc = -T3 * T4;
|
|
QovCox = qsrc / Coxeff;
|
|
T8 = 4.0 / 3.0 * T1 * (T1 - T0) + 0.4 * T0 * T0;
|
|
T5 = -2.0 * qsrc / T2 - T3 * (T1 * (3.0 * T1 - 8.0
|
|
* T0 / 3.0) + 2.0 * T0 * T0 / 3.0);
|
|
T6 = AbulkCV * (qsrc / T2 + T3 * T8);
|
|
T7 = T6 * VdseffCV / AbulkCV;
|
|
|
|
Csg = T5 * (1.0 - dDeltaPhi_dVg) + T6 * dVdseffCV_dVg;
|
|
Csd = Csg * dVgsteff_dVd + T6 * dVdseffCV_dVd
|
|
+ QovCox * dCoxeff_dVd;
|
|
Csb = Csg * dVgsteff_dVb + T6 * dVdseffCV_dVb
|
|
+ T7 * dAbulkCV_dVb + QovCox * dCoxeff_dVb;
|
|
Csg = Csg * dVgsteff_dVg + QovCox * dCoxeff_dVg;
|
|
}
|
|
else
|
|
{ /* 50/50 partition */
|
|
qsrc = -0.5 * qgate;
|
|
Csg = -0.5 * Cgg1;
|
|
Csd = -0.5 * Cgd1;
|
|
Csb = -0.5 * Cgb1;
|
|
}
|
|
|
|
qgate += Qac0 + Qsub0 - qbulk;
|
|
qbulk -= (Qac0 + Qsub0);
|
|
qdrn = -(qgate + qbulk + qsrc);
|
|
|
|
Cbg = Cbg1 - dQac0_dVg - dQsub0_dVg;
|
|
Cbd = Cbd1 - dQsub0_dVd;
|
|
Cbb = Cbb1 - dQac0_dVb - dQsub0_dVb;
|
|
|
|
Cgg = Cgg1 - Cbg;
|
|
Cgd = Cgd1 - Cbd;
|
|
Cgb = Cgb1 - Cbb;
|
|
|
|
Cgb *= dVbseff_dVb;
|
|
Cbb *= dVbseff_dVb;
|
|
Csb *= dVbseff_dVb;
|
|
|
|
here->BSIM3V2cggb = Cgg;
|
|
here->BSIM3V2cgsb = -(Cgg + Cgd + Cgb);
|
|
here->BSIM3V2cgdb = Cgd;
|
|
here->BSIM3V2cdgb = -(Cgg + Cbg + Csg);
|
|
here->BSIM3V2cdsb = (Cgg + Cgd + Cgb + Cbg + Cbd + Cbb
|
|
+ Csg + Csd + Csb);
|
|
here->BSIM3V2cddb = -(Cgd + Cbd + Csd);
|
|
here->BSIM3V2cbgb = Cbg;
|
|
here->BSIM3V2cbsb = -(Cbg + Cbd + Cbb);
|
|
here->BSIM3V2cbdb = Cbd;
|
|
here->BSIM3V2qinv = -qinoi;
|
|
} /* End of CTM */
|
|
}
|
|
|
|
finished:
|
|
/* Returning Values to Calling Routine */
|
|
/*
|
|
* COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
|
|
*/
|
|
|
|
here->BSIM3V2qgate = qgate;
|
|
here->BSIM3V2qbulk = qbulk;
|
|
here->BSIM3V2qdrn = qdrn;
|
|
here->BSIM3V2cd = cdrain;
|
|
|
|
if (ChargeComputationNeeded)
|
|
{ /* charge storage elements
|
|
* bulk-drain and bulk-source depletion capacitances
|
|
* czbd : zero bias drain junction capacitance
|
|
* czbs : zero bias source junction capacitance
|
|
* czbdsw: zero bias drain junction sidewall capacitance
|
|
along field oxide
|
|
* czbssw: zero bias source junction sidewall capacitance
|
|
along field oxide
|
|
* czbdswg: zero bias drain junction sidewall capacitance
|
|
along gate side
|
|
* czbsswg: zero bias source junction sidewall capacitance
|
|
along gate side
|
|
*/
|
|
|
|
czbd = model->BSIM3V2unitAreaJctCap * here->BSIM3V2drainArea;
|
|
czbs = model->BSIM3V2unitAreaJctCap * here->BSIM3V2sourceArea;
|
|
if (here->BSIM3V2drainPerimeter < pParam->BSIM3V2weff)
|
|
{
|
|
czbdswg = model->BSIM3V2unitLengthGateSidewallJctCap
|
|
* here->BSIM3V2drainPerimeter;
|
|
czbdsw = 0.0;
|
|
}
|
|
else
|
|
{
|
|
czbdsw = model->BSIM3V2unitLengthSidewallJctCap
|
|
* (here->BSIM3V2drainPerimeter - pParam->BSIM3V2weff);
|
|
czbdswg = model->BSIM3V2unitLengthGateSidewallJctCap
|
|
* pParam->BSIM3V2weff;
|
|
}
|
|
if (here->BSIM3V2sourcePerimeter < pParam->BSIM3V2weff)
|
|
{
|
|
czbssw = 0.0;
|
|
czbsswg = model->BSIM3V2unitLengthGateSidewallJctCap
|
|
* here->BSIM3V2sourcePerimeter;
|
|
}
|
|
else
|
|
{
|
|
czbssw = model->BSIM3V2unitLengthSidewallJctCap
|
|
* (here->BSIM3V2sourcePerimeter - pParam->BSIM3V2weff);
|
|
czbsswg = model->BSIM3V2unitLengthGateSidewallJctCap
|
|
* pParam->BSIM3V2weff;
|
|
}
|
|
|
|
MJ = model->BSIM3V2bulkJctBotGradingCoeff;
|
|
MJSW = model->BSIM3V2bulkJctSideGradingCoeff;
|
|
MJSWG = model->BSIM3V2bulkJctGateSideGradingCoeff;
|
|
|
|
/* Source Bulk Junction */
|
|
if (vbs == 0.0)
|
|
{ *(ckt->CKTstate0 + here->BSIM3V2qbs) = 0.0;
|
|
here->BSIM3V2capbs = czbs + czbssw + czbsswg;
|
|
}
|
|
else if (vbs < 0.0)
|
|
{ if (czbs > 0.0)
|
|
{ arg = 1.0 - vbs / model->BSIM3V2PhiB;
|
|
if (MJ == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJ * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbs) = model->BSIM3V2PhiB * czbs
|
|
* (1.0 - arg * sarg) / (1.0 - MJ);
|
|
here->BSIM3V2capbs = czbs * sarg;
|
|
}
|
|
else
|
|
{ *(ckt->CKTstate0 + here->BSIM3V2qbs) = 0.0;
|
|
here->BSIM3V2capbs = 0.0;
|
|
}
|
|
if (czbssw > 0.0)
|
|
{ arg = 1.0 - vbs / model->BSIM3V2PhiBSW;
|
|
if (MJSW == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJSW * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbs) += model->BSIM3V2PhiBSW * czbssw
|
|
* (1.0 - arg * sarg) / (1.0 - MJSW);
|
|
here->BSIM3V2capbs += czbssw * sarg;
|
|
}
|
|
if (czbsswg > 0.0)
|
|
{ arg = 1.0 - vbs / model->BSIM3V2PhiBSWG;
|
|
if (MJSWG == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJSWG * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbs) += model->BSIM3V2PhiBSWG * czbsswg
|
|
* (1.0 - arg * sarg) / (1.0 - MJSWG);
|
|
here->BSIM3V2capbs += czbsswg * sarg;
|
|
}
|
|
|
|
}
|
|
else
|
|
{ T0 = czbs + czbssw + czbsswg;
|
|
T1 = vbs * (czbs * MJ / model->BSIM3V2PhiB + czbssw * MJSW
|
|
/ model->BSIM3V2PhiBSW + czbsswg * MJSWG / model->BSIM3V2PhiBSWG);
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbs) = vbs * (T0 + 0.5 * T1);
|
|
here->BSIM3V2capbs = T0 + T1;
|
|
}
|
|
|
|
/* Drain Bulk Junction */
|
|
if (vbd == 0.0)
|
|
{ *(ckt->CKTstate0 + here->BSIM3V2qbd) = 0.0;
|
|
here->BSIM3V2capbd = czbd + czbdsw + czbdswg;
|
|
}
|
|
else if (vbd < 0.0)
|
|
{ if (czbd > 0.0)
|
|
{ arg = 1.0 - vbd / model->BSIM3V2PhiB;
|
|
if (MJ == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJ * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbd) = model->BSIM3V2PhiB * czbd
|
|
* (1.0 - arg * sarg) / (1.0 - MJ);
|
|
here->BSIM3V2capbd = czbd * sarg;
|
|
}
|
|
else
|
|
{ *(ckt->CKTstate0 + here->BSIM3V2qbd) = 0.0;
|
|
here->BSIM3V2capbd = 0.0;
|
|
}
|
|
if (czbdsw > 0.0)
|
|
{ arg = 1.0 - vbd / model->BSIM3V2PhiBSW;
|
|
if (MJSW == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJSW * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbd) += model->BSIM3V2PhiBSW * czbdsw
|
|
* (1.0 - arg * sarg) / (1.0 - MJSW);
|
|
here->BSIM3V2capbd += czbdsw * sarg;
|
|
}
|
|
if (czbdswg > 0.0)
|
|
{ arg = 1.0 - vbd / model->BSIM3V2PhiBSWG;
|
|
if (MJSWG == 0.5)
|
|
sarg = 1.0 / sqrt(arg);
|
|
else
|
|
sarg = exp(-MJSWG * log(arg));
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbd) += model->BSIM3V2PhiBSWG * czbdswg
|
|
* (1.0 - arg * sarg) / (1.0 - MJSWG);
|
|
here->BSIM3V2capbd += czbdswg * sarg;
|
|
}
|
|
}
|
|
else
|
|
{ T0 = czbd + czbdsw + czbdswg;
|
|
T1 = vbd * (czbd * MJ / model->BSIM3V2PhiB + czbdsw * MJSW
|
|
/ model->BSIM3V2PhiBSW + czbdswg * MJSWG / model->BSIM3V2PhiBSWG);
|
|
*(ckt->CKTstate0 + here->BSIM3V2qbd) = vbd * (T0 + 0.5 * T1);
|
|
here->BSIM3V2capbd = T0 + T1;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* check convergence
|
|
*/
|
|
if ((here->BSIM3V2off == 0) || (!(ckt->CKTmode & MODEINITFIX))) {
|
|
if (Check == 1) {
|
|
ckt->CKTnoncon++;
|
|
}
|
|
}
|
|
*(ckt->CKTstate0 + here->BSIM3V2vbs) = vbs;
|
|
*(ckt->CKTstate0 + here->BSIM3V2vbd) = vbd;
|
|
*(ckt->CKTstate0 + here->BSIM3V2vgs) = vgs;
|
|
*(ckt->CKTstate0 + here->BSIM3V2vds) = vds;
|
|
*(ckt->CKTstate0 + here->BSIM3V2qdef) = qdef;
|
|
|
|
/* bulk and channel charge plus overlaps */
|
|
|
|
if (!ChargeComputationNeeded)
|
|
goto line850;
|
|
|
|
line755:
|
|
/* NQS (Mansun 11/1993) modified by Weidong & Min-Chie 1997-1998 */
|
|
if (here->BSIM3V2nqsMod)
|
|
{ qcheq = -(qbulk + qgate);
|
|
|
|
here->BSIM3V2cqgb = -(here->BSIM3V2cggb + here->BSIM3V2cbgb);
|
|
here->BSIM3V2cqdb = -(here->BSIM3V2cgdb + here->BSIM3V2cbdb);
|
|
here->BSIM3V2cqsb = -(here->BSIM3V2cgsb + here->BSIM3V2cbsb);
|
|
here->BSIM3V2cqbb = -(here->BSIM3V2cqgb + here->BSIM3V2cqdb
|
|
+ here->BSIM3V2cqsb);
|
|
|
|
gtau_drift = fabs(pParam->BSIM3V2tconst * qcheq) * ScalingFactor;
|
|
T0 = pParam->BSIM3V2leffCV * pParam->BSIM3V2leffCV;
|
|
gtau_diff = 16.0 * pParam->BSIM3V2u0temp * model->BSIM3V2vtm / T0
|
|
* ScalingFactor;
|
|
here->BSIM3V2gtau = gtau_drift + gtau_diff;
|
|
}
|
|
|
|
if (model->BSIM3V2capMod == 0)
|
|
{ if (vgd < 0.0)
|
|
{
|
|
cgdo = pParam->BSIM3V2cgdo;
|
|
qgdo = pParam->BSIM3V2cgdo * vgd;
|
|
}
|
|
else
|
|
{ cgdo = pParam->BSIM3V2cgdo;
|
|
qgdo = pParam->BSIM3V2cgdo * vgd;
|
|
}
|
|
|
|
if (vgs < 0.0)
|
|
{
|
|
cgso = pParam->BSIM3V2cgso;
|
|
qgso = pParam->BSIM3V2cgso * vgs;
|
|
}
|
|
else
|
|
{ cgso = pParam->BSIM3V2cgso;
|
|
qgso = pParam->BSIM3V2cgso * vgs;
|
|
}
|
|
}
|
|
else if (model->BSIM3V2capMod == 1)
|
|
{ if (vgd < 0.0)
|
|
{ T1 = sqrt(1.0 - 4.0 * vgd / pParam->BSIM3V2ckappa);
|
|
cgdo = pParam->BSIM3V2cgdo + pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2cgdl / T1;
|
|
qgdo = pParam->BSIM3V2cgdo * vgd - pParam->BSIM3V2weffCV * 0.5
|
|
* pParam->BSIM3V2cgdl * pParam->BSIM3V2ckappa * (T1 - 1.0);
|
|
}
|
|
else
|
|
{ cgdo = pParam->BSIM3V2cgdo + pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2cgdl;
|
|
qgdo = (pParam->BSIM3V2weffCV * pParam->BSIM3V2cgdl
|
|
+ pParam->BSIM3V2cgdo) * vgd;
|
|
}
|
|
|
|
if (vgs < 0.0)
|
|
{ T1 = sqrt(1.0 - 4.0 * vgs / pParam->BSIM3V2ckappa);
|
|
cgso = pParam->BSIM3V2cgso + pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2cgsl / T1;
|
|
qgso = pParam->BSIM3V2cgso * vgs - pParam->BSIM3V2weffCV * 0.5
|
|
* pParam->BSIM3V2cgsl * pParam->BSIM3V2ckappa * (T1 - 1.0);
|
|
}
|
|
else
|
|
{ cgso = pParam->BSIM3V2cgso + pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2cgsl;
|
|
qgso = (pParam->BSIM3V2weffCV * pParam->BSIM3V2cgsl
|
|
+ pParam->BSIM3V2cgso) * vgs;
|
|
}
|
|
}
|
|
else
|
|
{ T0 = vgd + DELTA_1;
|
|
T1 = sqrt(T0 * T0 + 4.0 * DELTA_1);
|
|
T2 = 0.5 * (T0 - T1);
|
|
|
|
T3 = pParam->BSIM3V2weffCV * pParam->BSIM3V2cgdl;
|
|
T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM3V2ckappa);
|
|
cgdo = pParam->BSIM3V2cgdo + T3 - T3 * (1.0 - 1.0 / T4)
|
|
* (0.5 - 0.5 * T0 / T1);
|
|
qgdo = (pParam->BSIM3V2cgdo + T3) * vgd - T3 * (T2
|
|
+ 0.5 * pParam->BSIM3V2ckappa * (T4 - 1.0));
|
|
|
|
T0 = vgs + DELTA_1;
|
|
T1 = sqrt(T0 * T0 + 4.0 * DELTA_1);
|
|
T2 = 0.5 * (T0 - T1);
|
|
T3 = pParam->BSIM3V2weffCV * pParam->BSIM3V2cgsl;
|
|
T4 = sqrt(1.0 - 4.0 * T2 / pParam->BSIM3V2ckappa);
|
|
cgso = pParam->BSIM3V2cgso + T3 - T3 * (1.0 - 1.0 / T4)
|
|
* (0.5 - 0.5 * T0 / T1);
|
|
qgso = (pParam->BSIM3V2cgso + T3) * vgs - T3 * (T2
|
|
+ 0.5 * pParam->BSIM3V2ckappa * (T4 - 1.0));
|
|
}
|
|
|
|
here->BSIM3V2cgdo = cgdo;
|
|
here->BSIM3V2cgso = cgso;
|
|
|
|
ag0 = ckt->CKTag[0];
|
|
if (here->BSIM3V2mode > 0)
|
|
{ if (here->BSIM3V2nqsMod == 0)
|
|
{ gcggb = (here->BSIM3V2cggb + cgdo + cgso
|
|
+ pParam->BSIM3V2cgbo ) * ag0;
|
|
gcgdb = (here->BSIM3V2cgdb - cgdo) * ag0;
|
|
gcgsb = (here->BSIM3V2cgsb - cgso) * ag0;
|
|
|
|
gcdgb = (here->BSIM3V2cdgb - cgdo) * ag0;
|
|
gcddb = (here->BSIM3V2cddb + here->BSIM3V2capbd + cgdo) * ag0;
|
|
gcdsb = here->BSIM3V2cdsb * ag0;
|
|
|
|
gcsgb = -(here->BSIM3V2cggb + here->BSIM3V2cbgb
|
|
+ here->BSIM3V2cdgb + cgso) * ag0;
|
|
gcsdb = -(here->BSIM3V2cgdb + here->BSIM3V2cbdb
|
|
+ here->BSIM3V2cddb) * ag0;
|
|
gcssb = (here->BSIM3V2capbs + cgso - (here->BSIM3V2cgsb
|
|
+ here->BSIM3V2cbsb + here->BSIM3V2cdsb)) * ag0;
|
|
|
|
gcbgb = (here->BSIM3V2cbgb - pParam->BSIM3V2cgbo) * ag0;
|
|
gcbdb = (here->BSIM3V2cbdb - here->BSIM3V2capbd) * ag0;
|
|
gcbsb = (here->BSIM3V2cbsb - here->BSIM3V2capbs) * ag0;
|
|
|
|
qgd = qgdo;
|
|
qgs = qgso;
|
|
qgb = pParam->BSIM3V2cgbo * vgb;
|
|
qgate += qgd + qgs + qgb;
|
|
qbulk -= qgb;
|
|
qdrn -= qgd;
|
|
qsrc = -(qgate + qbulk + qdrn);
|
|
|
|
ggtg = ggtd = ggtb = ggts = 0.0;
|
|
sxpart = 0.6;
|
|
dxpart = 0.4;
|
|
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0;
|
|
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0;
|
|
}
|
|
else
|
|
{ if (qcheq > 0.0)
|
|
T0 = pParam->BSIM3V2tconst * qdef * ScalingFactor;
|
|
else
|
|
T0 = -pParam->BSIM3V2tconst * qdef * ScalingFactor;
|
|
ggtg = here->BSIM3V2gtg = T0 * here->BSIM3V2cqgb;
|
|
ggtd = here->BSIM3V2gtd = T0 * here->BSIM3V2cqdb;
|
|
ggts = here->BSIM3V2gts = T0 * here->BSIM3V2cqsb;
|
|
ggtb = here->BSIM3V2gtb = T0 * here->BSIM3V2cqbb;
|
|
gqdef = ScalingFactor * ag0;
|
|
|
|
gcqgb = here->BSIM3V2cqgb * ag0;
|
|
gcqdb = here->BSIM3V2cqdb * ag0;
|
|
gcqsb = here->BSIM3V2cqsb * ag0;
|
|
gcqbb = here->BSIM3V2cqbb * ag0;
|
|
|
|
gcggb = (cgdo + cgso + pParam->BSIM3V2cgbo ) * ag0;
|
|
gcgdb = -cgdo * ag0;
|
|
gcgsb = -cgso * ag0;
|
|
|
|
gcdgb = -cgdo * ag0;
|
|
gcddb = (here->BSIM3V2capbd + cgdo) * ag0;
|
|
gcdsb = 0.0;
|
|
|
|
gcsgb = -cgso * ag0;
|
|
gcsdb = 0.0;
|
|
gcssb = (here->BSIM3V2capbs + cgso) * ag0;
|
|
|
|
gcbgb = -pParam->BSIM3V2cgbo * ag0;
|
|
gcbdb = -here->BSIM3V2capbd * ag0;
|
|
gcbsb = -here->BSIM3V2capbs * ag0;
|
|
|
|
CoxWL = model->BSIM3V2cox * pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2leffCV;
|
|
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
|
|
{ if (model->BSIM3V2xpart < 0.5)
|
|
{ dxpart = 0.4;
|
|
}
|
|
else if (model->BSIM3V2xpart > 0.5)
|
|
{ dxpart = 0.0;
|
|
}
|
|
else
|
|
{ dxpart = 0.5;
|
|
}
|
|
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb
|
|
= ddxpart_dVs = 0.0;
|
|
}
|
|
else
|
|
{ dxpart = qdrn / qcheq;
|
|
Cdd = here->BSIM3V2cddb;
|
|
Csd = -(here->BSIM3V2cgdb + here->BSIM3V2cddb
|
|
+ here->BSIM3V2cbdb);
|
|
ddxpart_dVd = (Cdd - dxpart * (Cdd + Csd)) / qcheq;
|
|
Cdg = here->BSIM3V2cdgb;
|
|
Csg = -(here->BSIM3V2cggb + here->BSIM3V2cdgb
|
|
+ here->BSIM3V2cbgb);
|
|
ddxpart_dVg = (Cdg - dxpart * (Cdg + Csg)) / qcheq;
|
|
|
|
Cds = here->BSIM3V2cdsb;
|
|
Css = -(here->BSIM3V2cgsb + here->BSIM3V2cdsb
|
|
+ here->BSIM3V2cbsb);
|
|
ddxpart_dVs = (Cds - dxpart * (Cds + Css)) / qcheq;
|
|
|
|
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
|
|
}
|
|
sxpart = 1.0 - dxpart;
|
|
dsxpart_dVd = -ddxpart_dVd;
|
|
dsxpart_dVg = -ddxpart_dVg;
|
|
dsxpart_dVs = -ddxpart_dVs;
|
|
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
|
|
|
|
qgd = qgdo;
|
|
qgs = qgso;
|
|
qgb = pParam->BSIM3V2cgbo * vgb;
|
|
qgate = qgd + qgs + qgb;
|
|
qbulk = -qgb;
|
|
qdrn = -qgd;
|
|
qsrc = -(qgate + qbulk + qdrn);
|
|
}
|
|
}
|
|
else
|
|
{ if (here->BSIM3V2nqsMod == 0)
|
|
{ gcggb = (here->BSIM3V2cggb + cgdo + cgso
|
|
+ pParam->BSIM3V2cgbo ) * ag0;
|
|
gcgdb = (here->BSIM3V2cgsb - cgdo) * ag0;
|
|
gcgsb = (here->BSIM3V2cgdb - cgso) * ag0;
|
|
|
|
gcdgb = -(here->BSIM3V2cggb + here->BSIM3V2cbgb
|
|
+ here->BSIM3V2cdgb + cgdo) * ag0;
|
|
gcddb = (here->BSIM3V2capbd + cgdo - (here->BSIM3V2cgsb
|
|
+ here->BSIM3V2cbsb + here->BSIM3V2cdsb)) * ag0;
|
|
gcdsb = -(here->BSIM3V2cgdb + here->BSIM3V2cbdb
|
|
+ here->BSIM3V2cddb) * ag0;
|
|
|
|
gcsgb = (here->BSIM3V2cdgb - cgso) * ag0;
|
|
gcsdb = here->BSIM3V2cdsb * ag0;
|
|
gcssb = (here->BSIM3V2cddb + here->BSIM3V2capbs + cgso) * ag0;
|
|
|
|
gcbgb = (here->BSIM3V2cbgb - pParam->BSIM3V2cgbo) * ag0;
|
|
gcbdb = (here->BSIM3V2cbsb - here->BSIM3V2capbd) * ag0;
|
|
gcbsb = (here->BSIM3V2cbdb - here->BSIM3V2capbs) * ag0;
|
|
|
|
qgd = qgdo;
|
|
qgs = qgso;
|
|
qgb = pParam->BSIM3V2cgbo * vgb;
|
|
qgate += qgd + qgs + qgb;
|
|
qbulk -= qgb;
|
|
qsrc = qdrn - qgs;
|
|
qdrn = -(qgate + qbulk + qsrc);
|
|
|
|
ggtg = ggtd = ggtb = ggts = 0.0;
|
|
sxpart = 0.4;
|
|
dxpart = 0.6;
|
|
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0;
|
|
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0;
|
|
}
|
|
else
|
|
{ if (qcheq > 0.0)
|
|
T0 = pParam->BSIM3V2tconst * qdef * ScalingFactor;
|
|
else
|
|
T0 = -pParam->BSIM3V2tconst * qdef * ScalingFactor;
|
|
ggtg = here->BSIM3V2gtg = T0 * here->BSIM3V2cqgb;
|
|
ggts = here->BSIM3V2gtd = T0 * here->BSIM3V2cqdb;
|
|
ggtd = here->BSIM3V2gts = T0 * here->BSIM3V2cqsb;
|
|
ggtb = here->BSIM3V2gtb = T0 * here->BSIM3V2cqbb;
|
|
gqdef = ScalingFactor * ag0;
|
|
|
|
gcqgb = here->BSIM3V2cqgb * ag0;
|
|
gcqdb = here->BSIM3V2cqsb * ag0;
|
|
gcqsb = here->BSIM3V2cqdb * ag0;
|
|
gcqbb = here->BSIM3V2cqbb * ag0;
|
|
|
|
gcggb = (cgdo + cgso + pParam->BSIM3V2cgbo) * ag0;
|
|
gcgdb = -cgdo * ag0;
|
|
gcgsb = -cgso * ag0;
|
|
|
|
gcdgb = -cgdo * ag0;
|
|
gcddb = (here->BSIM3V2capbd + cgdo) * ag0;
|
|
gcdsb = 0.0;
|
|
|
|
gcsgb = -cgso * ag0;
|
|
gcsdb = 0.0;
|
|
gcssb = (here->BSIM3V2capbs + cgso) * ag0;
|
|
|
|
gcbgb = -pParam->BSIM3V2cgbo * ag0;
|
|
gcbdb = -here->BSIM3V2capbd * ag0;
|
|
gcbsb = -here->BSIM3V2capbs * ag0;
|
|
|
|
CoxWL = model->BSIM3V2cox * pParam->BSIM3V2weffCV
|
|
* pParam->BSIM3V2leffCV;
|
|
if (fabs(qcheq) <= 1.0e-5 * CoxWL)
|
|
{ if (model->BSIM3V2xpart < 0.5)
|
|
{ sxpart = 0.4;
|
|
}
|
|
else if (model->BSIM3V2xpart > 0.5)
|
|
{ sxpart = 0.0;
|
|
}
|
|
else
|
|
{ sxpart = 0.5;
|
|
}
|
|
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb
|
|
= dsxpart_dVs = 0.0;
|
|
}
|
|
else
|
|
{ sxpart = qdrn / qcheq;
|
|
Css = here->BSIM3V2cddb;
|
|
Cds = -(here->BSIM3V2cgdb + here->BSIM3V2cddb
|
|
+ here->BSIM3V2cbdb);
|
|
dsxpart_dVs = (Css - sxpart * (Css + Cds)) / qcheq;
|
|
Csg = here->BSIM3V2cdgb;
|
|
Cdg = -(here->BSIM3V2cggb + here->BSIM3V2cdgb
|
|
+ here->BSIM3V2cbgb);
|
|
dsxpart_dVg = (Csg - sxpart * (Csg + Cdg)) / qcheq;
|
|
|
|
Csd = here->BSIM3V2cdsb;
|
|
Cdd = -(here->BSIM3V2cgsb + here->BSIM3V2cdsb
|
|
+ here->BSIM3V2cbsb);
|
|
dsxpart_dVd = (Csd - sxpart * (Csd + Cdd)) / qcheq;
|
|
|
|
dsxpart_dVb = -(dsxpart_dVd + dsxpart_dVg + dsxpart_dVs);
|
|
}
|
|
dxpart = 1.0 - sxpart;
|
|
ddxpart_dVd = -dsxpart_dVd;
|
|
ddxpart_dVg = -dsxpart_dVg;
|
|
ddxpart_dVs = -dsxpart_dVs;
|
|
ddxpart_dVb = -(ddxpart_dVd + ddxpart_dVg + ddxpart_dVs);
|
|
|
|
qgd = qgdo;
|
|
qgs = qgso;
|
|
qgb = pParam->BSIM3V2cgbo * vgb;
|
|
qgate = qgd + qgs + qgb;
|
|
qbulk = -qgb;
|
|
qsrc = -qgs;
|
|
qdrn = -(qgate + qbulk + qsrc);
|
|
}
|
|
}
|
|
|
|
cqdef = cqcheq = 0.0;
|
|
if (ByPass) goto line860;
|
|
|
|
*(ckt->CKTstate0 + here->BSIM3V2qg) = qgate;
|
|
*(ckt->CKTstate0 + here->BSIM3V2qd) = qdrn
|
|
- *(ckt->CKTstate0 + here->BSIM3V2qbd);
|
|
*(ckt->CKTstate0 + here->BSIM3V2qb) = qbulk
|
|
+ *(ckt->CKTstate0 + here->BSIM3V2qbd)
|
|
+ *(ckt->CKTstate0 + here->BSIM3V2qbs);
|
|
|
|
if (here->BSIM3V2nqsMod)
|
|
{ *(ckt->CKTstate0 + here->BSIM3V2qcdump) = qdef * ScalingFactor;
|
|
*(ckt->CKTstate0 + here->BSIM3V2qcheq) = qcheq;
|
|
}
|
|
|
|
/* store small signal parameters */
|
|
if (ckt->CKTmode & MODEINITSMSIG)
|
|
{ goto line1000;
|
|
}
|
|
if (!ChargeComputationNeeded)
|
|
goto line850;
|
|
|
|
if (ckt->CKTmode & MODEINITTRAN)
|
|
{ *(ckt->CKTstate1 + here->BSIM3V2qb) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2qb);
|
|
*(ckt->CKTstate1 + here->BSIM3V2qg) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2qg);
|
|
*(ckt->CKTstate1 + here->BSIM3V2qd) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2qd);
|
|
if (here->BSIM3V2nqsMod)
|
|
{ *(ckt->CKTstate1 + here->BSIM3V2qcheq) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2qcheq);
|
|
*(ckt->CKTstate1 + here->BSIM3V2qcdump) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2qcdump);
|
|
}
|
|
}
|
|
|
|
error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM3V2qb);
|
|
if (error)
|
|
return(error);
|
|
error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM3V2qg);
|
|
if (error)
|
|
return(error);
|
|
error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM3V2qd);
|
|
if (error)
|
|
return(error);
|
|
if (here->BSIM3V2nqsMod)
|
|
{ error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM3V2qcdump);
|
|
if (error)
|
|
return(error);
|
|
error = NIintegrate(ckt, &geq, &ceq, 0.0, here->BSIM3V2qcheq);
|
|
if (error)
|
|
return(error);
|
|
}
|
|
|
|
goto line860;
|
|
|
|
line850:
|
|
/* initialize to zero charge conductance and current */
|
|
ceqqg = ceqqb = ceqqd = 0.0;
|
|
cqcheq = cqdef = 0.0;
|
|
|
|
gcdgb = gcddb = gcdsb = 0.0;
|
|
gcsgb = gcsdb = gcssb = 0.0;
|
|
gcggb = gcgdb = gcgsb = 0.0;
|
|
gcbgb = gcbdb = gcbsb = 0.0;
|
|
|
|
gqdef = gcqgb = gcqdb = gcqsb = gcqbb = 0.0;
|
|
ggtg = ggtd = ggtb = ggts = 0.0;
|
|
sxpart = (1.0 - (dxpart = (here->BSIM3V2mode > 0) ? 0.4 : 0.6));
|
|
ddxpart_dVd = ddxpart_dVg = ddxpart_dVb = ddxpart_dVs = 0.0;
|
|
dsxpart_dVd = dsxpart_dVg = dsxpart_dVb = dsxpart_dVs = 0.0;
|
|
|
|
if (here->BSIM3V2nqsMod)
|
|
here->BSIM3V2gtau = 16.0 * pParam->BSIM3V2u0temp * model->BSIM3V2vtm
|
|
/ pParam->BSIM3V2leffCV / pParam->BSIM3V2leffCV
|
|
* ScalingFactor;
|
|
else
|
|
here->BSIM3V2gtau = 0.0;
|
|
|
|
goto line900;
|
|
|
|
line860:
|
|
/* evaluate equivalent charge current */
|
|
|
|
cqgate = *(ckt->CKTstate0 + here->BSIM3V2cqg);
|
|
cqbulk = *(ckt->CKTstate0 + here->BSIM3V2cqb);
|
|
cqdrn = *(ckt->CKTstate0 + here->BSIM3V2cqd);
|
|
|
|
ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
|
|
ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
|
|
ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
|
|
|
|
if (here->BSIM3V2nqsMod)
|
|
{ T0 = ggtg * vgb - ggtd * vbd - ggts * vbs;
|
|
ceqqg += T0;
|
|
T1 = qdef * here->BSIM3V2gtau;
|
|
ceqqd -= dxpart * T0 + T1 * (ddxpart_dVg * vgb - ddxpart_dVd
|
|
* vbd - ddxpart_dVs * vbs);
|
|
cqdef = *(ckt->CKTstate0 + here->BSIM3V2cqcdump) - gqdef * qdef;
|
|
cqcheq = *(ckt->CKTstate0 + here->BSIM3V2cqcheq)
|
|
- (gcqgb * vgb - gcqdb * vbd - gcqsb * vbs) + T0;
|
|
}
|
|
|
|
if (ckt->CKTmode & MODEINITTRAN)
|
|
{ *(ckt->CKTstate1 + here->BSIM3V2cqb) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2cqb);
|
|
*(ckt->CKTstate1 + here->BSIM3V2cqg) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2cqg);
|
|
*(ckt->CKTstate1 + here->BSIM3V2cqd) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2cqd);
|
|
|
|
if (here->BSIM3V2nqsMod)
|
|
{ *(ckt->CKTstate1 + here->BSIM3V2cqcheq) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2cqcheq);
|
|
*(ckt->CKTstate1 + here->BSIM3V2cqcdump) =
|
|
*(ckt->CKTstate0 + here->BSIM3V2cqcdump);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* load current vector
|
|
*/
|
|
line900:
|
|
|
|
if (here->BSIM3V2mode >= 0)
|
|
{ Gm = here->BSIM3V2gm;
|
|
Gmbs = here->BSIM3V2gmbs;
|
|
FwdSum = Gm + Gmbs;
|
|
RevSum = 0.0;
|
|
cdreq = model->BSIM3V2type * (cdrain - here->BSIM3V2gds * vds
|
|
- Gm * vgs - Gmbs * vbs);
|
|
|
|
ceqbd = -model->BSIM3V2type * (here->BSIM3V2csub
|
|
- here->BSIM3V2gbds * vds - here->BSIM3V2gbgs * vgs
|
|
- here->BSIM3V2gbbs * vbs);
|
|
ceqbs = 0.0;
|
|
|
|
gbbdp = -here->BSIM3V2gbds;
|
|
gbbsp = (here->BSIM3V2gbds + here->BSIM3V2gbgs + here->BSIM3V2gbbs);
|
|
|
|
gbdpg = here->BSIM3V2gbgs;
|
|
gbdpdp = here->BSIM3V2gbds;
|
|
gbdpb = here->BSIM3V2gbbs;
|
|
gbdpsp = -(gbdpg + gbdpdp + gbdpb);
|
|
|
|
gbspg = 0.0;
|
|
gbspdp = 0.0;
|
|
gbspb = 0.0;
|
|
gbspsp = 0.0;
|
|
}
|
|
else
|
|
{ Gm = -here->BSIM3V2gm;
|
|
Gmbs = -here->BSIM3V2gmbs;
|
|
FwdSum = 0.0;
|
|
RevSum = -(Gm + Gmbs);
|
|
cdreq = -model->BSIM3V2type * (cdrain + here->BSIM3V2gds * vds
|
|
+ Gm * vgd + Gmbs * vbd);
|
|
|
|
ceqbs = -model->BSIM3V2type * (here->BSIM3V2csub
|
|
+ here->BSIM3V2gbds * vds - here->BSIM3V2gbgs * vgd
|
|
- here->BSIM3V2gbbs * vbd);
|
|
ceqbd = 0.0;
|
|
|
|
gbbsp = -here->BSIM3V2gbds;
|
|
gbbdp = (here->BSIM3V2gbds + here->BSIM3V2gbgs + here->BSIM3V2gbbs);
|
|
|
|
gbdpg = 0.0;
|
|
gbdpsp = 0.0;
|
|
gbdpb = 0.0;
|
|
gbdpdp = 0.0;
|
|
|
|
gbspg = here->BSIM3V2gbgs;
|
|
gbspsp = here->BSIM3V2gbds;
|
|
gbspb = here->BSIM3V2gbbs;
|
|
gbspdp = -(gbspg + gbspsp + gbspb);
|
|
}
|
|
|
|
if (model->BSIM3V2type > 0)
|
|
{ ceqbs += (here->BSIM3V2cbs - here->BSIM3V2gbs * vbs);
|
|
ceqbd += (here->BSIM3V2cbd - here->BSIM3V2gbd * vbd);
|
|
/*
|
|
ceqqg = ceqqg;
|
|
ceqqb = ceqqb;
|
|
ceqqd = ceqqd;
|
|
cqdef = cqdef;
|
|
cqcheq = cqcheq;
|
|
*/
|
|
}
|
|
else
|
|
{ ceqbs -= (here->BSIM3V2cbs - here->BSIM3V2gbs * vbs);
|
|
ceqbd -= (here->BSIM3V2cbd - here->BSIM3V2gbd * vbd);
|
|
ceqqg = -ceqqg;
|
|
ceqqb = -ceqqb;
|
|
ceqqd = -ceqqd;
|
|
cqdef = -cqdef;
|
|
cqcheq = -cqcheq;
|
|
}
|
|
|
|
(*(ckt->CKTrhs + here->BSIM3V2gNode) -= ceqqg);
|
|
(*(ckt->CKTrhs + here->BSIM3V2bNode) -=(ceqbs + ceqbd + ceqqb));
|
|
(*(ckt->CKTrhs + here->BSIM3V2dNodePrime) += (ceqbd - cdreq - ceqqd));
|
|
(*(ckt->CKTrhs + here->BSIM3V2sNodePrime) += (cdreq + ceqbs + ceqqg
|
|
+ ceqqb + ceqqd));
|
|
if (here->BSIM3V2nqsMod)
|
|
*(ckt->CKTrhs + here->BSIM3V2qNode) += (cqcheq - cqdef);
|
|
|
|
/*
|
|
* load y matrix
|
|
*/
|
|
|
|
T1 = qdef * here->BSIM3V2gtau;
|
|
(*(here->BSIM3V2DdPtr) += here->BSIM3V2drainConductance);
|
|
(*(here->BSIM3V2GgPtr) += gcggb - ggtg);
|
|
(*(here->BSIM3V2SsPtr) += here->BSIM3V2sourceConductance);
|
|
(*(here->BSIM3V2BbPtr) += here->BSIM3V2gbd + here->BSIM3V2gbs
|
|
- gcbgb - gcbdb - gcbsb - here->BSIM3V2gbbs);
|
|
(*(here->BSIM3V2DPdpPtr) += here->BSIM3V2drainConductance
|
|
+ here->BSIM3V2gds + here->BSIM3V2gbd
|
|
+ RevSum + gcddb + dxpart * ggtd
|
|
+ T1 * ddxpart_dVd + gbdpdp);
|
|
(*(here->BSIM3V2SPspPtr) += here->BSIM3V2sourceConductance
|
|
+ here->BSIM3V2gds + here->BSIM3V2gbs
|
|
+ FwdSum + gcssb + sxpart * ggts
|
|
+ T1 * dsxpart_dVs + gbspsp);
|
|
(*(here->BSIM3V2DdpPtr) -= here->BSIM3V2drainConductance);
|
|
(*(here->BSIM3V2GbPtr) -= gcggb + gcgdb + gcgsb + ggtb);
|
|
(*(here->BSIM3V2GdpPtr) += gcgdb - ggtd);
|
|
(*(here->BSIM3V2GspPtr) += gcgsb - ggts);
|
|
(*(here->BSIM3V2SspPtr) -= here->BSIM3V2sourceConductance);
|
|
(*(here->BSIM3V2BgPtr) += gcbgb - here->BSIM3V2gbgs);
|
|
(*(here->BSIM3V2BdpPtr) += gcbdb - here->BSIM3V2gbd + gbbdp);
|
|
(*(here->BSIM3V2BspPtr) += gcbsb - here->BSIM3V2gbs + gbbsp);
|
|
(*(here->BSIM3V2DPdPtr) -= here->BSIM3V2drainConductance);
|
|
(*(here->BSIM3V2DPgPtr) += Gm + gcdgb + dxpart * ggtg
|
|
+ T1 * ddxpart_dVg + gbdpg);
|
|
(*(here->BSIM3V2DPbPtr) -= here->BSIM3V2gbd - Gmbs + gcdgb + gcddb
|
|
+ gcdsb - dxpart * ggtb
|
|
- T1 * ddxpart_dVb - gbdpb);
|
|
(*(here->BSIM3V2DPspPtr) -= here->BSIM3V2gds + FwdSum - gcdsb
|
|
- dxpart * ggts - T1 * ddxpart_dVs - gbdpsp);
|
|
(*(here->BSIM3V2SPgPtr) += gcsgb - Gm + sxpart * ggtg
|
|
+ T1 * dsxpart_dVg + gbspg);
|
|
(*(here->BSIM3V2SPsPtr) -= here->BSIM3V2sourceConductance);
|
|
(*(here->BSIM3V2SPbPtr) -= here->BSIM3V2gbs + Gmbs + gcsgb + gcsdb
|
|
+ gcssb - sxpart * ggtb
|
|
- T1 * dsxpart_dVb - gbspb);
|
|
(*(here->BSIM3V2SPdpPtr) -= here->BSIM3V2gds + RevSum - gcsdb
|
|
- sxpart * ggtd - T1 * dsxpart_dVd - gbspdp);
|
|
|
|
if (here->BSIM3V2nqsMod)
|
|
{ *(here->BSIM3V2QqPtr) += (gqdef + here->BSIM3V2gtau);
|
|
|
|
*(here->BSIM3V2DPqPtr) += (dxpart * here->BSIM3V2gtau);
|
|
*(here->BSIM3V2SPqPtr) += (sxpart * here->BSIM3V2gtau);
|
|
*(here->BSIM3V2GqPtr) -= here->BSIM3V2gtau;
|
|
|
|
*(here->BSIM3V2QgPtr) += (ggtg - gcqgb);
|
|
*(here->BSIM3V2QdpPtr) += (ggtd - gcqdb);
|
|
*(here->BSIM3V2QspPtr) += (ggts - gcqsb);
|
|
*(here->BSIM3V2QbPtr) += (ggtb - gcqbb);
|
|
}
|
|
|
|
line1000: ;
|
|
|
|
} /* End of Mosfet Instance */
|
|
} /* End of Model Instance */
|
|
|
|
return(OK);
|
|
}
|
|
|