📄 mos3load.c
字号:
cdrain = here->MOS3mode * (here->MOS3cd + here->MOS3cbd); if(ckt->CKTmode & (MODETRAN | MODETRANOP)) { capgs = ( *(ckt->CKTstate0+here->MOS3capgs)+ *(ckt->CKTstate1+here->MOS3capgs) + GateSourceOverlapCap ); capgd = ( *(ckt->CKTstate0+here->MOS3capgd)+ *(ckt->CKTstate1+here->MOS3capgd) + GateDrainOverlapCap ); capgb = ( *(ckt->CKTstate0+here->MOS3capgb)+ *(ckt->CKTstate1+here->MOS3capgb) + GateBulkOverlapCap ); } goto bypass; }#endif /*NOBYPASS*/#ifdef DETAILPROFasm(" .globl mos3ptc");asm("mos3ptc:");#endif /* DETAILPROF */ /* ok - bypass is out, do it the hard way */ von = model->MOS3type * here->MOS3von;#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->MOS3vds) >=0) { vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->MOS3vgs) ,von); vds = vgs - vgd; vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->MOS3vds)); vgd = vgs - vds; } else { vgd = DEVfetlim(vgd,vgdo,von); vds = vgs - vgd; if(!(ckt->CKTfixLimit)) { vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 + here->MOS3vds))); } vgs = vgd + vds; } if(vds >= 0) { vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->MOS3vbs), vt,here->MOS3sourceVcrit,&Check); vbd = vbs-vds; } else { vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->MOS3vbd), vt,here->MOS3drainVcrit,&Check); vbs = vbd + vds; }#endif /*NODELIMITING*/ } else {#ifdef DETAILPROFasm(" .globl mos3ptd");asm("mos3ptd:");#endif /* DETAILPROF */ /* 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->MOS3off) { vds= model->MOS3type * here->MOS3icVDS; vgs= model->MOS3type * here->MOS3icVGS; vbs= model->MOS3type * here->MOS3icVBS; if((vds==0) && (vgs==0) && (vbs==0) && ((ckt->CKTmode & (MODETRAN|MODEDCOP|MODEDCTRANCURVE)) || (!(ckt->CKTmode & MODEUIC)))) { vbs = -1; vgs = model->MOS3type * here->MOS3tVto; vds = 0; } } else { vbs=vgs=vds=0; } }#ifdef DETAILPROFasm(" .globl mos3pte");asm("mos3pte:");#endif /* DETAILPROF */ /* * 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 <= 0) { here->MOS3gbs = SourceSatCur/vt; here->MOS3cbs = here->MOS3gbs*vbs; here->MOS3gbs += ckt->CKTgmin; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); here->MOS3gbs = SourceSatCur*evbs/vt + ckt->CKTgmin; here->MOS3cbs = SourceSatCur * (evbs-1); } if(vbd <= 0) { here->MOS3gbd = DrainSatCur/vt; here->MOS3cbd = here->MOS3gbd *vbd; here->MOS3gbd += ckt->CKTgmin; } else { evbd = exp(MIN(MAX_EXP_ARG,vbd/vt)); here->MOS3gbd = DrainSatCur*evbd/vt +ckt->CKTgmin; here->MOS3cbd = DrainSatCur *(evbd-1); } /* now to determine whether the user was able to correctly * identify the source and drain of his device */ if(vds >= 0) { /* normal mode */ here->MOS3mode = 1; } else { /* inverse mode */ here->MOS3mode = -1; }#ifdef DETAILPROFasm(" .globl mos3ptf");asm("mos3ptf:");#endif /* DETAILPROF */ { /* * 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; double dvodvb; double dvodvd; double vgsx; double dvtdvd; double onfg; double fgate; double us; double dfgdvg; double dfgdvd; double dfgdvb; double dvsdvg; double dvsdvb; double dvsdvd; double xn; double vdsc; double onvdsc; double dvsdga; double vdsx; double dcodvb; double cdnorm; double cdo; double cd1; double fdrain; double fd2; double dfddvg; double dfddvb; double dfddvd; 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; 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->MOS3eta * 8.15e-22/(model->MOS3oxideCapFactor* EffectiveLength*EffectiveLength*EffectiveLength); /* *.....square root term */ if ( (here->MOS3mode==1?vbs:vbd) <= 0.0 ) { phibs = here->MOS3tPhi-(here->MOS3mode==1?vbs:vbd); sqphbs = sqrt(phibs); dsqdvb = -0.5/sqphbs; } else { sqphis = sqrt(here->MOS3tPhi); sqphs3 = here->MOS3tPhi*sqphis; sqphbs = sqphis/(1.0+(here->MOS3mode==1?vbs:vbd)/ (here->MOS3tPhi+here->MOS3tPhi)); phibs = sqphbs*sqphbs; dsqdvb = -phibs/(sqphs3+sqphs3); } /* *.....short channel effect factor */ if ( (model->MOS3junctionDepth != 0.0) && (model->MOS3coeffDepLayWidth != 0.0) ) { wps = model->MOS3coeffDepLayWidth*sqphbs; oneoverxj = 1.0/model->MOS3junctionDepth; xjonxl = model->MOS3junctionDepth*oneoverxl; djonxj = model->MOS3latDiff*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->MOS3coeffDepLayWidth*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->MOS3gamma*fshort; fbodys = 0.5*gammas/(sqphbs+sqphbs); fbody = fbodys+model->MOS3narrowFactor/here->MOS3w; onfbdy = 1.0/(1.0+fbody); dfbdvb = -fbodys*dsqdvb/sqphbs+fbodys*dfsdvb/fshort; qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/here->MOS3w; dqbdvb = gammas*dsqdvb+model->MOS3gamma*dfsdvb*sqphbs- model->MOS3narrowFactor/here->MOS3w; /* *.....static feedback effect */ vbix = here->MOS3tVbi*model->MOS3type-eta*(here->MOS3mode*vds); /* *.....threshold voltage */ vth = vbix+qbonco; dvtdvd = -eta; dvtdvb = dqbdvb; /* *.....joint weak inversion and strong inversion */ von = vth; if ( model->MOS3fastSurfaceStateDensity != 0.0 ) { csonco = CHARGE*model->MOS3fastSurfaceStateDensity *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -