📄 mos9dset.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1988 Jaijeet S RoychowdhuryModified: Alan Gillespie**********/#include "ngspice.h"#include "cktdefs.h"#include "devdefs.h"#include "mos9defs.h"#include "trandefs.h"#include "distodef.h"#include "const.h"#include "sperror.h"#include "suffix.h"intMOS9dSetup(GENmodel *inModel, CKTcircuit *ckt) /* actually load the current value into the * sparse matrix previously provided */{ MOS9model *model = (MOS9model *)inModel; MOS9instance *here; double Beta; double DrainSatCur; double EffectiveLength; double EffectiveWidth; double GateBulkOverlapCap; double GateDrainOverlapCap; double GateSourceOverlapCap; double OxideCap; double SourceSatCur; double arg; double cdrain; double evbs; double sarg; double sargsw; double lvgs; double vbd; double vbs; double vds; double vdsat; double vgb; double vgd; double vgs; double von; double lcapgs2,lcapgs3; /* total gate-source capacitance */ double lcapgd2,lcapgd3; /* total gate-drain capacitance */ double lcapgb2,lcapgb3; /* total gate-bulk capacitance */ double lgbs, lgbs2, lgbs3; double lgbd, lgbd2, lgbd3; double gm2, gb2, gds2, gmb, gmds, gbds; double gm3, gb3, gds3, gm2ds, gm2b, gb2ds, gbds2, gmb2, gmds2, gmbds; double lcapbd, lcapbd2, lcapbd3; double lcapbs, lcapbs2, lcapbs3; double ebd; double vt; /* vt at instance temperature */ Dderivs d_cdrain; /* loop through all the MOS9 device models */ for( ; model != NULL; model = model->MOS9nextModel ) { /* loop through all the instances of the model */ for (here = model->MOS9instances; here != NULL ; here=here->MOS9nextInstance) { if (here->MOS9owner != ARCHme) continue; vt = CONSTKoverQ * here->MOS9temp; /* first, we compute a few useful values - these could be * pre-computed, but for historical reasons are still done * here. They may be moved at the expense of instance size */ EffectiveWidth=here->MOS9w-2*model->MOS9widthNarrow+ model->MOS9widthAdjust; EffectiveLength=here->MOS9l - 2*model->MOS9latDiff+ model->MOS9lengthAdjust; if( (here->MOS9tSatCurDens == 0) || (here->MOS9drainArea == 0) || (here->MOS9sourceArea == 0)) { DrainSatCur = here->MOS9m * here->MOS9tSatCur; SourceSatCur = here->MOS9m * here->MOS9tSatCur; } else { DrainSatCur = here->MOS9tSatCurDens * here->MOS9m * here->MOS9drainArea; SourceSatCur = here->MOS9tSatCurDens * here->MOS9m * here->MOS9sourceArea; } GateSourceOverlapCap = model->MOS9gateSourceOverlapCapFactor * here->MOS9m * EffectiveWidth; GateDrainOverlapCap = model->MOS9gateDrainOverlapCapFactor * here->MOS9m * EffectiveWidth; GateBulkOverlapCap = model->MOS9gateBulkOverlapCapFactor * here->MOS9m * EffectiveLength; Beta = here->MOS9tTransconductance * here->MOS9m * EffectiveWidth/EffectiveLength; OxideCap = model->MOS9oxideCapFactor * EffectiveLength * here->MOS9m * EffectiveWidth; /* * ok - now to do the start-up operations * * we must get values for vbs, vds, and vgs from somewhere * so we either predict them or recover them from last iteration * These are the two most common cases - either a prediction * step or the general iteration step and they * share some code, so we put them first - others later on */ /* general iteration */ vbs = model->MOS9type * ( *(ckt->CKTrhsOld+here->MOS9bNode) - *(ckt->CKTrhsOld+here->MOS9sNodePrime)); vgs = model->MOS9type * ( *(ckt->CKTrhsOld+here->MOS9gNode) - *(ckt->CKTrhsOld+here->MOS9sNodePrime)); vds = model->MOS9type * ( *(ckt->CKTrhsOld+here->MOS9dNodePrime) - *(ckt->CKTrhsOld+here->MOS9sNodePrime)); /* now some common crunching for some more useful quantities */ /* * 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 doides * here we just evaluate the ideal diode current and the * correspoinding derivative (conductance). *//*next1:*/ if(vbs <= 0) { lgbs = SourceSatCur/vt; lgbs += ckt->CKTgmin; lgbs2 = lgbs3 = 0; } else { evbs = exp(MIN(MAX_EXP_ARG,vbs/vt)); lgbs = SourceSatCur*evbs/vt + ckt->CKTgmin; lgbs2 = model->MOS9type *0.5 * (lgbs - ckt->CKTgmin)/vt; lgbs3 = model->MOS9type *lgbs2/(vt*3); } if(vbd <= 0) { lgbd = DrainSatCur/vt; lgbd += ckt->CKTgmin; lgbd2 = lgbd3 = 0; } else { ebd = exp(MIN(MAX_EXP_ARG,vbd/vt)); lgbd = DrainSatCur*ebd/vt +ckt->CKTgmin; lgbd2 = model->MOS9type *0.5 * (lgbd - ckt->CKTgmin)/vt; lgbd3 = model->MOS9type *lgbd2/(vt*3); } /* 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 sqphis; /* square root of phi */ double wps; double oneoverxj; /* 1/junction depth */ double xjonxl; /* junction depth/effective length */ double djonxj; double wponxj; double arga; double argb; double argc; double gammas; double fbodys; double fbody; double onfbdy; double qbonco; double vbix; double wconxj; double vth; double csonco; double cdonco; double vgsx; double onfg; double fgate; double us; double xn = 0.0; double vdsc; double onvdsc = 0.0; double vdsx; double cdnorm; double cdo; double fdrain = 0.0; double gdsat; double cdsat; double emax; double delxl; double dlonxl; double xlfact; double ondvt; double onxn; double wfact; double fshort; double lvds, lvbs, lvbd; Dderivs d_onxn, d_ondvt, d_wfact, d_MOS9gds; Dderivs d_emax, d_delxl, d_dlonxl, d_xlfact; Dderivs d_cdonco, d_fdrain, d_cdsat, d_gdsat; Dderivs d_vdsx, d_cdo, d_cdnorm, d_Beta, d_dummy; Dderivs d_vdsc, d_onvdsc, d_arga, d_argb; Dderivs d_onfg, d_fgate, d_us, d_vgsx; Dderivs d_von, d_xn, d_vth, d_onfbdy, d_qbonco, d_vbix; Dderivs d_argc, d_fshort, d_gammas, d_fbodys, d_fbody; Dderivs d_wps, d_wconxj, d_wponxj; Dderivs d_phibs, d_sqphbs; Dderivs d_p, d_q, d_r, d_zero, d_vdsat; /* * bypasses the computation of charges */ if (here->MOS9mode == 1) { lvgs = vgs; lvds = vds; lvbs = vbs; lvbd = vbd; } else { lvgs = vgd; lvds = -vds; lvbs = vbd; lvbd = vbs; } /* * reference cdrain equations to source and * charge equations to bulk */d_p.value = 0.0;d_p.d1_p = 1.0;d_p.d1_q = 0.0;d_p.d1_r = 0.0;d_p.d2_p2 = 0.0;d_p.d2_q2 = 0.0;d_p.d2_r2 = 0.0;d_p.d2_pq = 0.0;d_p.d2_qr = 0.0;d_p.d2_pr = 0.0;d_p.d3_p3 = 0.0;d_p.d3_q3 = 0.0;d_p.d3_r3 = 0.0;d_p.d3_p2r = 0.0;d_p.d3_p2q = 0.0;d_p.d3_q2r = 0.0;d_p.d3_pq2 = 0.0;d_p.d3_pr2 = 0.0;d_p.d3_qr2 = 0.0;d_p.d3_pqr = 0.0; EqualDeriv(&d_q,&d_p); EqualDeriv(&d_r,&d_p); EqualDeriv(&d_zero,&d_p); d_q.d1_p = d_r.d1_p = d_zero.d1_p = 0.0; d_q.d1_q = d_r.d1_r = 1.0; vdsat = 0.0; EqualDeriv(&d_vdsat,&d_zero); oneoverxl = 1.0/EffectiveLength;/*const*/ eta = model->MOS9eta * 8.15e-22/(model->MOS9oxideCapFactor* EffectiveLength*EffectiveLength*EffectiveLength);/*const*/ /* *.....square root term */ if ( lvbs <= 0.0 ) { phibs = here->MOS9tPhi-lvbs; EqualDeriv(&d_phibs,&d_q); d_phibs.value = lvbs; TimesDeriv(&d_phibs,&d_phibs,-1.0); d_phibs.value += here->MOS9tPhi; sqphbs = sqrt(phibs); SqrtDeriv(&d_sqphbs,&d_phibs); } else { sqphis = sqrt(here->MOS9tPhi);/*const*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -