📄 mos9load.c
字号:
GateSourceOverlapCap ); capgd = ( *(ckt->CKTstate0+here->MOS9capgd)+ *(ckt->CKTstate1+here->MOS9capgd) + GateDrainOverlapCap ); capgb = ( *(ckt->CKTstate0+here->MOS9capgb)+ *(ckt->CKTstate1+here->MOS9capgb) + GateBulkOverlapCap ); } goto bypass; }#endif /*NOBYPASS*/ /* ok - bypass is out, do it the hard way */ von = model->MOS9type * here->MOS9von;#ifndef NODELIMITING /* * limiting * we want to keep device voltages from changing * so fast that the exponentials churn out overflows * and similar rudeness */ if(*(ckt->CKTstate0 + here->MOS9vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS9vgs) ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS9vds)); vgd = vgs - vds; } else { vgd = DEVfetlim(vgd,vgdo,von); vds = vgs - vgd; if(!(ckt->CKTfixLimit)) { vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + here->MOS9vds))); } vgs = vgd + vds; } if(vds >= 0) { vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS9vbs), vt,here->MOS9sourceVcrit,&Check); vbd = vbs-vds; } else { vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS9vbd), vt,here->MOS9drainVcrit,&Check); vbs = vbd + vds; }#endif /*NODELIMITING*/ } else { /* ok - not one of the simple cases, so we have to * look at all of the possibilities for why we were * called. We still just initialize the three voltages */ if((ckt->CKTmode & MODEINITJCT) && !here->MOS9off) { vds= model->MOS9type * here->MOS9icVDS; vgs= model->MOS9type * here->MOS9icVGS; vbs= model->MOS9type * here->MOS9icVBS; if((vds==0) && (vgs==0) && (vbs==0) && ((ckt->CKTmode & (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = -1; vgs = model->MOS9type * here->MOS9tVto; vds = 0; } } else { vbs=vgs=vds=0; } } /* * now all the preliminaries are over - we can start doing the * real work */ vbd = vbs - vds; vgd = vgs - vds; vgb = vgs - vbs; /* * bulk-source and bulk-drain diodes * here we just evaluate the ideal diode current and the * corresponding derivative (conductance). */next1: if(vbs <= -3*vt) { arg=3*vt/(vbs*CONSTe); arg = arg * arg * arg; here->MOS9cbs = -SourceSatCur*(1+arg)+ckt->CKTgmin*vbs; here->MOS9gbs = SourceSatCur*3*arg/vbs+ckt->CKTgmin; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS9gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; here->MOS9cbs = SourceSatCur*(evbs-1) + ckt->CKTgmin*vbs; } if(vbd <= -3*vt) { arg=3*vt/(vbd*CONSTe); arg = arg * arg * arg; here->MOS9cbd = -DrainSatCur*(1+arg)+ckt->CKTgmin*vbd; here->MOS9gbd = DrainSatCur*3*arg/vbd+ckt->CKTgmin; } else { evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); here->MOS9gbd = DrainSatCur*evbd/vt + ckt->CKTgmin; here->MOS9cbd = DrainSatCur*(evbd-1) + ckt->CKTgmin*vbd; } /* now to determine whether the user was able to correctly * identify the source and drain of his device */ if(vds >= 0) { /* normal mode */ here->MOS9mode = 1; } else { /* inverse mode */ here->MOS9mode = -1; } { /* * subroutine moseq3(vds,vbs,vgs,gm,gds,gmbs, * qg,qc,qb,cggb,cgdb,cgsb,cbgb,cbdb,cbsb) */ /* * this routine evaluates the drain current, its derivatives and * the charges associated with the gate, channel and bulk * for mosfets based on semi-empirical equations */ /* common /mosarg/ vto,beta,gamma,phi,phib,cox,xnsub,xnfs,xd,xj,xld, 1 xlamda,uo,uexp,vbp,utra,vmax,xneff,xl,xw,vbi,von,vdsat,qspof, 2 beta0,beta1,cdrain,xqco,xqc,fnarrw,fshort,lev common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet, 1 xmu,sfactr,mode,modedc,icalc,initf,method,iord,maxord,noncon, 2 iterno,itemno,nosolv,modac,ipiv,ivmflg,ipostp,iscrch,iofile common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok, 1 gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox, 2 pivtol,pivrel */ /* equivalence (xlamda,alpha),(vbp,theta),(uexp,eta),(utra,xkappa)*/ double coeff0 = 0.0631353e0; double coeff1 = 0.8013292e0; double coeff2 = -0.01110777e0; double oneoverxl; /* 1/effective length */ double eta; /* eta from model after length factor */ double phibs; /* phi - vbs */ double sqphbs; /* square root of phibs */ double dsqdvb; /* */ double sqphis; /* square root of phi */ double sqphs3; /* square root of phi cubed */ double wps; double oneoverxj; /* 1/junction depth */ double xjonxl; /* junction depth/effective length */ double djonxj; double wponxj; double arga; double argb; double argc; double dwpdvb; double dadvb; double dbdvb; double gammas; double fbodys; double fbody; double onfbdy; double qbonco; double vbix; double wconxj; double dfsdvb; double dfbdvb; double dqbdvb; double vth; double dvtdvb; double csonco; double cdonco; double dxndvb = 0.0; double dvodvb = 0.0; double dvodvd = 0.0; double vgsx; double dvtdvd; double onfg; double fgate; double us; double dfgdvg; double dfgdvd; double dfgdvb; double dvsdvg; double dvsdvb; double dvsdvd; double xn = 0.0; double vdsc; double onvdsc = 0.0; double dvsdga; double vdsx; double dcodvb; double cdnorm; double cdo; double cd1; double fdrain = 0.0; double fd2; double dfddvg = 0.0; double dfddvb = 0.0; double dfddvd = 0.0; double gdsat; double cdsat; double gdoncd; double gdonfd; double gdonfg; double dgdvg; double dgdvd; double dgdvb; double emax; double emongd; double demdvg; double demdvd; double demdvb; double delxl; double dldvd; double dldem; double ddldvg; double ddldvd; double ddldvb; double dlonxl; double xlfact; double diddl; double gds0 = 0.0; double emoncd; double ondvt; double onxn; double wfact; double gms; double gmw; double fshort; /* * bypasses the computation of charges */ /* * reference cdrain equations to source and * charge equations to bulk */ vdsat = 0.0; oneoverxl = 1.0/EffectiveLength; eta = model->MOS9eta * 8.15e-22/(model->MOS9oxideCapFactor* EffectiveLength*EffectiveLength*EffectiveLength); /* *.....square root term */ if ( (here->MOS9mode==1?vbs:vbd) <= 0.0 ) { phibs = here->MOS9tPhi-(here->MOS9mode==1?vbs:vbd); sqphbs = sqrt(phibs); dsqdvb = -0.5/sqphbs; } else { sqphis = sqrt(here->MOS9tPhi); sqphs3 = here->MOS9tPhi*sqphis; sqphbs = sqphis/(1.0+(here->MOS9mode==1?vbs:vbd)/ (here->MOS9tPhi+here->MOS9tPhi)); phibs = sqphbs*sqphbs; dsqdvb = -phibs/(sqphs3+sqphs3); } /* *.....short channel effect factor */ if ( (model->MOS9junctionDepth != 0.0) && (model->MOS9coeffDepLayWidth != 0.0) ) { wps = model->MOS9coeffDepLayWidth*sqphbs; oneoverxj = 1.0/model->MOS9junctionDepth; xjonxl = model->MOS9junctionDepth*oneoverxl; djonxj = model->MOS9latDiff*oneoverxj; wponxj = wps*oneoverxj; wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj; arga = wconxj+djonxj; argc = wponxj/(1.0+wponxj); argb = sqrt(1.0-argc*argc); fshort = 1.0-xjonxl*(arga*argb-djonxj); dwpdvb = model->MOS9coeffDepLayWidth*dsqdvb; dadvb = (coeff1+coeff2*(wponxj+wponxj))*dwpdvb*oneoverxj; dbdvb = -argc*argc*(1.0-argc)*dwpdvb/(argb*wps); dfsdvb = -xjonxl*(dadvb*argb+arga*dbdvb); } else { fshort = 1.0; dfsdvb = 0.0; } /* *.....body effect */ gammas = model->MOS9gamma*fshort; fbodys = 0.5*gammas/(sqphbs+sqphbs); fbody = fbodys+model->MOS9narrowFactor/EffectiveWidth; onfbdy = 1.0/(1.0+fbody); dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; qbonco =gammas*sqphbs+model->MOS9narrowFactor*phibs/EffectiveWidth; dqbdvb = gammas*dsqdvb+model->MOS9gamma*dfsdvb*sqphbs- model->MOS9narrowFactor/EffectiveWidth; /* *.....static feedback effect */ vbix = here->MOS9tVbi*model->MOS9type-eta*(here->MOS9mode*vds); /* *.....threshold voltage */ vth = vbix+qbonco; dvtdvd = -eta; dvtdvb = dqbdvb; /* *.....joint weak inversion and strong inversion */ von = vth; if ( model->MOS9fastSurfaceStateDensity != 0.0 ) { csonco = CHARGE*model->MOS9fastSurfaceStateDensity * 1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth * here->MOS9m/OxideCap; cdonco = qbonco/(phibs+phibs); xn = 1.0+csonco+cdonco; von = vth+vt*xn; dxndvb = dqbdvb/(phibs+phibs)-qbonco*dsqdvb/(phibs*sqphbs); dvodvd = dvtdvd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -