Jspice3
moseq.c File Reference
#include "spice.h"
#include <stdio.h>
#include <math.h>
#include "mosdefs.h"
#include "const.h"
#include "sperror.h"
#include "util.h"
Include dependency graph for moseq.c:

Go to the source code of this file.

Macros

#define EPSSIL   (11.7 * 8.854214871e-12)
 
#define P66   .66666666666667
 
#define P33   .33333333333333
 
#define P1X3   1.3333333333333
 
#define CM2PM2   1e4
 
#define M2PCM2   1e-4
 

Functions

static void mos2_vsat ()
 
double MOSeq1 (MOSmodel *model, MOSinstance *here, struct mosstuff *ms)
 
double MOSeq2 (MOSmodel *model, MOSinstance *here, struct mosstuff *ms)
 
static void mos2_vsat (double *vsat, double *baum)
 
double MOSeq3 (MOSmodel *model, MOSinstance *here, struct mosstuff *ms)
 
double MOSeq6 (MOSmodel *model, MOSinstance *here, struct mosstuff *ms)
 
double cryoMOSeq (MOSmodel *model, MOSinstance *here, struct mosstuff *ms)
 

Macro Definition Documentation

#define CM2PM2   1e4

Definition at line 26 of file moseq.c.

#define EPSSIL   (11.7 * 8.854214871e-12)

Definition at line 18 of file moseq.c.

#define M2PCM2   1e-4

Definition at line 29 of file moseq.c.

#define P1X3   1.3333333333333

Definition at line 23 of file moseq.c.

#define P33   .33333333333333

Definition at line 22 of file moseq.c.

#define P66   .66666666666667

Definition at line 21 of file moseq.c.

Function Documentation

double cryoMOSeq ( MOSmodel model,
MOSinstance here,
struct mosstuff ms 
)

Definition at line 1225 of file moseq.c.

1230 {
1231 
1232  /*
1233  * this block of code evaluates the drain current and its
1234  * derivatives using the cryo-MOS model and the
1235  * charges associated with the gate, channel and bulk.
1236  *
1237  */
1238 
1239  double sarg;
1240  double vgst;
1241  double vgst2;
1242  double cdrain;
1243  double vbx;
1244  double vgx;
1245  double vds;
1246  double L;
1247  double delta;
1248  double lambda;
1249  double litl;
1250  double factor;
1251  double t1,t2,t3,t4,t5;
1252  double u0;
1253  double eta;
1254  double d1u0dvgst;
1255  double ueff;
1256  double dueffdvds;
1257  double dueffdvdsat;
1258  double dueffdvgst;
1259  double dueffdvdsatdvgst;
1260  double vdsat;
1261  double dvdsatdvgst;
1262  double idsat;
1263  double didsatdvdsat;
1264  double didsatdvgst;
1265  double va;
1266  double dvadvds;
1267  double dvadvgst;
1268  double vasat;
1269  double dvasatdvgst;
1270  double vgst1=1.5;
1271 
1272  L = here->MOSeffectiveLength;
1273  factor = here->MOSw/L*model->MOSoxideCapFactor;
1274  litl = sqrt(11.7/3.9*model->MOSoxideThickness*model->MOSjunctionDepth);
1275 
1276  vbx = ((here->MOSmode == 1) ? ms->ms_vbs : ms->ms_vbd);
1277  vgx = ((here->MOSmode == 1) ? ms->ms_vgs : ms->ms_vgd);
1278 
1279  if (vbx <= 0) {
1280  sarg = sqrt(model->MOSphi-vbx)-sqrt(model->MOSphi);
1281  delta = model->MOSgamma/(2.0*sqrt(model->MOSphi-vbx));
1282  } else if (vbx < model->MOSphi) {
1283  sarg = -vbx/(2.0*sqrt(model->MOSphi));
1284  delta = model->MOSgamma/(2.0*sqrt(model->MOSphi));
1285  } else {
1286  sarg = -sqrt(model->MOSphi)/2.0;
1287  delta = 0;
1288  }
1289 
1290  if (model->MOStype > 0)
1291  ms->ms_von = model->MOSvt0 + model->MOSgamma*sarg;
1292  else
1293  ms->ms_von = -model->MOSvt0 + model->MOSgamma*sarg;
1294  vgst = vgx - ms->ms_von;
1295  vgst2 = vgst*vgst;
1296 
1297  u0 = 1.0/(model->MOSk1/vgst + model->MOSk2
1298  + model->MOSk3*vgst2 + model->MOSk4*vgst);
1299  d1u0dvgst = -model->MOSk1/vgst2 + 2.0*model->MOSk3*vgst + model->MOSk4;
1300  eta = u0/model->MOSmaxDriftVel/L;
1301 
1302  t1 = u0*model->MOSa1/vgst/(L+model->MOSa2/(1+delta));
1303  t2 = u0*model->MOSa1*L/vgst/(L+model->MOSa2*0.5/(1+delta))
1304  /(L+model->MOSa2*0.5/(1+delta));
1305  t3 = vgst/(1+delta);
1306  t4 = sqrt((1.0+(-t1+t2)*t3)*(1.0+(-t1+t2)*t3)+2.0*(eta+eta+t1+t1-t2)*t3);
1307  ms->ms_vdsat = vdsat = (-(1.0+(-t1+t2)*t3)+t4)/(eta+eta+t1+t1-t2);
1308  t5 = (eta+eta)/u0/(1+delta);
1309  dvdsatdvgst = (-d1u0dvgst*u0+((1.0+(-t1+t2)*t3)*d1u0dvgst+t5
1310  + (eta+eta+t1+t1-t2)*t3*d1u0dvgst)/t4)/(eta+eta+t1+t1-t2)
1311  - vdsat*(-(t1+t1-t2)/vgst)/(eta+eta+t1+t1-t2);
1312 
1313  if (vgst <= 0) {
1314  cdrain = 0;
1315  here->MOSgm = 0;
1316  here->MOSgds = 0;
1317  here->MOSgmbs = 0;
1318  }
1319  else {
1320  if (here->MOSmode > 0)
1321  vds = ms->ms_vds;
1322  else
1323  vds = -ms->ms_vds;
1324 
1325  if (vdsat <= vds) {
1326  /* saturation region */
1327  t2 = 1.0/(vgst*L+model->MOSa2*vdsat);
1328  ueff = u0/(1+eta*vdsat+u0*model->MOSa1*vdsat*t2);
1329  dueffdvdsat = -ueff*ueff*(eta/u0+model->MOSa1*vgst*L*t2*t2);
1330  dueffdvgst = -ueff*ueff*(d1u0dvgst+eta/u0*dvdsatdvgst+
1331  model->MOSa1*L*(vgst*dvdsatdvgst-vdsat)*t2*t2);
1332  dueffdvdsatdvgst = -2.0*ueff*dueffdvgst*(eta/u0+
1333  model->MOSa1*vgst*L*t2*t2)-ueff*ueff*(model->MOSa1*L*t2*t2-
1334  model->MOSa1*vgst*L*2.0*t2*t2*t2*
1335  (L+model->MOSa2*dvdsatdvgst));
1336  idsat = factor*ueff*(vgst-0.5*(1.0+delta)*vdsat)*vdsat;
1337  didsatdvdsat = idsat*dueffdvdsat/ueff+
1338  factor*ueff*(vgst-(1.0+delta)*vdsat);
1339  didsatdvgst = idsat*(dueffdvgst/ueff+dvdsatdvgst/vdsat)+
1340  factor*ueff*(1.0-0.5*(1.0+delta)*dvdsatdvgst)*vdsat;
1341  vasat = idsat/didsatdvdsat;
1342  dvasatdvgst = didsatdvgst/didsatdvdsat-
1343  idsat/didsatdvdsat/didsatdvdsat*(factor*dueffdvdsat*
1344  (vdsat+vgst*dvdsatdvgst-(1.0+delta)*vdsat*dvdsatdvgst)+
1345  idsat/ueff*dueffdvdsatdvgst +
1346  factor*ueff*(1.0-(1.0+delta)*dvdsatdvgst));
1347 
1348  t1 = 1/(1.0-ueff*vdsat/L/model->MOSmaxDriftVel);
1349  lambda = 0.5*L/model->MOSem/litl*t1;
1350  va = vasat + (L*t1-lambda*(vds - vdsat))*
1351  (vds - vdsat)/model->MOSpclm/litl;
1352  dvadvds = (L*t1-2.0*lambda*(vds-vdsat))/model->MOSpclm/litl;
1353  dvadvgst = dvasatdvgst+L*t1*t1*(-(dueffdvgst*vdsat+
1354  ueff*dvdsatdvgst)/L/model->MOSmaxDriftVel)*
1355  (1.0-0.5*(vds-vdsat)/model->MOSem/litl)*
1356  (vds-vdsat)/model->MOSpclm/litl-dvadvds*dvdsatdvgst;
1357 
1358  here->MOSgm = didsatdvgst*(1.0+(vds-vdsat)/va)+
1359  idsat*(-dvdsatdvgst/va-(vds-vdsat)/va/va*dvadvgst);
1360  here->MOSgds = idsat*(1.0/va-(vds-vdsat)/va/va*dvadvds);
1361  here->MOSgmbs = delta*here->MOSgm;
1362  cdrain = idsat*(1.0+(vds-vdsat)/va);
1363  }
1364  else {
1365  /* linear region */
1366 
1367  ueff = u0/(1+eta*vds+
1368  u0*model->MOSa1*vds/(vgst*L+model->MOSa2*vds));
1369  cdrain = factor*ueff*(vgst-0.5*(1+delta)*vds)*vds;
1370  dueffdvgst = -ueff*ueff*(d1u0dvgst-model->MOSa1*L*vds/
1371  (vgst*L+model->MOSa2*vds)/(vgst*L+model->MOSa2*vds));
1372  dueffdvds = -ueff*ueff*(eta/u0+model->MOSa1*vgst/L/(vgst+
1373  model->MOSa2*vds/L)/(vgst+model->MOSa2*vds/L));
1374  here->MOSgm = factor*vds*(ueff+
1375  (vgst-0.5*(1+delta)*vds)*dueffdvgst);
1376  here->MOSgds = factor*ueff*(vgst-
1377  (1.0+delta)*vds)+cdrain*dueffdvds/ueff;
1378  here->MOSgmbs = delta*here->MOSgm;
1379  }
1380 
1381  }
1382  return (cdrain);
1383 
1384 }
double MOSgamma
Definition: mosdefs.h:286
double ms_von
Definition: mosdefs.h:607
double MOSgm
Definition: mosdefs.h:74
double MOSem
Definition: mosdefs.h:352
double ms_vbd
Definition: mosdefs.h:612
double MOSgmbs
Definition: mosdefs.h:73
double MOSoxideThickness
Definition: mosdefs.h:302
double MOSvt0
Definition: mosdefs.h:284
double MOSa2
Definition: mosdefs.h:346
double MOSk3
Definition: mosdefs.h:349
double MOSgds
Definition: mosdefs.h:75
int MOStype
Definition: mosdefs.h:279
double MOSa1
Definition: mosdefs.h:345
double ms_vbs
Definition: mosdefs.h:611
double MOSoxideCapFactor
Definition: mosdefs.h:282
double MOSmaxDriftVel
Definition: mosdefs.h:323
#define L
Definition: parse.c:442
double MOSjunctionDepth
Definition: mosdefs.h:324
double MOSw
Definition: mosdefs.h:35
double MOSk4
Definition: mosdefs.h:350
double MOSk1
Definition: mosdefs.h:347
double MOSphi
Definition: mosdefs.h:287
double MOSpclm
Definition: mosdefs.h:351
double MOSk2
Definition: mosdefs.h:348
double ms_vds
Definition: mosdefs.h:610
int MOSmode
Definition: mosdefs.h:32
double ms_vgd
Definition: mosdefs.h:614
double MOSeffectiveLength
Definition: mosdefs.h:91
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
static void mos2_vsat ( )
static
static void mos2_vsat ( double *  vsat,
double *  baum 
)
static

Definition at line 621 of file moseq.c.

624 {
625 
626  double a00, a01, a02, a03, a04, a05, b00, b01;
627  double poly4, az[4], bz[4];
628  double a1, a3, b1, b3, c1, d1, p0, p2, p, s2, s, y3;
629  double tmp, tmp1, ptmp;
630  int i, jknt;
631 
632  /*
633  * evaluate saturation voltage and its derivatives
634  * according to baum's theory of scattering velocity
635  * saturation
636  */
637  a1 = baum[0];
638  b1 = baum[1];
639  c1 = baum[2];
640  d1 = baum[3];
641 
642  tmp = a1*c1 - 4.0*d1;
643  tmp1 = -P33*b1*b1 + tmp;
644  s = -2.0*b1*b1*b1/27.0 + P33*b1*tmp;
645  tmp = -d1*(a1*a1 - 4.0*b1) - c1*c1;
646  s += tmp;
647 
648  tmp = P33*tmp1;
649  tmp *= tmp*tmp;
650  s2 = s*s;
651  p = .25*s2 + tmp;
652  p0 = FABS(p);
653  p2 = sqrt(p0);
654 
655  if (p < 0) {
656  tmp = sqrt(.25*s2 + p0);
657  tmp = exp(P33*log(tmp));
658  y3 = 2.0*tmp*cos(P33*atan(-2.0*p2/s)) + P33*b1;
659  }
660  else {
661  tmp = (-.5*s + p2);
662  tmp = exp(P33*log(FABS(tmp)));
663  tmp1 = (-.5*s - p2);
664  tmp1 = exp(P33*log(FABS(tmp1)));
665  y3 += tmp + tmp1 + P33*b1;
666  }
667 
668  jknt = 0;
669  a3 = sqrt(.25*a1*a1 - b1 + y3);
670  b3 = sqrt(.25*y3*y3 - d1);
671  b00 = .5*y3 + b3;
672  b01 = .5*y3 - b3;
673  a00 = .5*a1 + a3;
674  a01 = .5*a1 - a3;
675  a02 = .25*a00*a00;
676  a03 = .25*a01*a01;
677  a04 = -.5*a00;
678  a05 = -.5*a01;
679  az[0] = a02 - b00;
680  az[1] = a03 - b00;
681  az[2] = a02 - b01;
682  az[3] = a03 - b01;
683  bz[0] = a04;
684  bz[1] = a05;
685  bz[2] = a04;
686  bz[3] = a05;
687 
688  for (i = 0; i < 4; i++) {
689  tmp = az[i];
690  if (tmp >= 0) {
691  tmp = sqrt(tmp);
692  ptmp = bz[i] + tmp;
693  if (ptmp > 0) {
694  poly4 = d1 + ptmp*(c1 + ptmp*(b1 + ptmp*(a1 + ptmp)));
695  if (FABS(poly4) <= 1.0e-6) {
696  if (!jknt || ptmp <= tmp1)
697  tmp1 = ptmp;
698  jknt++;
699  }
700  }
701  ptmp = bz[i] - tmp;
702  if (ptmp > 0) {
703  poly4 = d1 + ptmp*(c1 + ptmp*(b1 + ptmp*(a1 + ptmp)));
704  if (FABS(poly4) <= 1.0e-6) {
705  if (!jknt || ptmp <= tmp1)
706  tmp1 = ptmp;
707  jknt++;
708  }
709  }
710  }
711  }
712  if (jknt > 0)
713  *vsat = tmp1*tmp1 - baum[4];
714 }
Definition: cddefs.h:119
FILE * p
Definition: proc2mod.c:48
double cos()
#define FABS(a)
Definition: util.h:41
#define P33
Definition: moseq.c:22
double MOSeq1 ( MOSmodel model,
MOSinstance here,
struct mosstuff ms 
)

Definition at line 40 of file moseq.c.

45 {
46 
47  /*
48  * this block of code evaluates the drain current and its
49  * derivatives using the shichman-hodges model and the
50  * charges associated with the gate, channel and bulk for
51  * mosfets
52  *
53  */
54  double arg;
55  double betap;
56  double sarg;
57  double vgst;
58  double cdrain;
59  double vbx;
60  double vgx;
61  double vds;
62 
63  vbx = ((here->MOSmode == 1) ? ms->ms_vbs : ms->ms_vbd);
64  vgx = ((here->MOSmode == 1) ? ms->ms_vgs : ms->ms_vgd);
65 
66  if (vbx <= 0) {
67  sarg = sqrt(here->MOStPhi - vbx);
68  }
69  else {
70  sarg = sqrt(here->MOStPhi);
71  sarg = sarg - vbx/(sarg+sarg);
72  sarg = MAX(0,sarg);
73  }
74  if (model->MOStype > 0)
75  ms->ms_von = here->MOStVbi + model->MOSgamma*sarg;
76  else
77  ms->ms_von = -here->MOStVbi + model->MOSgamma*sarg;
78 
79  vgst = vgx - ms->ms_von;
80  ms->ms_vdsat = MAX(vgst,0);
81 
82  if (vgst <= 0) {
83  /* cutoff region */
84  cdrain = 0;
85  here->MOSgm = 0;
86  here->MOSgds = 0;
87  here->MOSgmbs = 0;
88  }
89  else {
90  if (here->MOSmode > 0)
91  vds = ms->ms_vds;
92  else
93  vds = -ms->ms_vds;
94 
95  if (sarg <= 0)
96  arg = 0;
97  else
98  arg = model->MOSgamma/(sarg+sarg);
99  betap = here->MOSbeta * (1 + model->MOSlambda*vds);
100 
101  if (vgst <= vds) {
102  /* saturation region */
103 
104  here->MOSgm = betap*vgst;
105  vgst *= vgst*.5;
106  cdrain = betap*vgst;
107  here->MOSgds = model->MOSlambda*here->MOSbeta*vgst;
108  here->MOSgmbs = here->MOSgm*arg;
109  }
110  else {
111  /* linear region */
112 
113  here->MOSgm = betap*vds;
114  cdrain = here->MOSgm*(vgst - .5*vds);
115  here->MOSgds = betap*(vgst - vds) +
116  model->MOSlambda*here->MOSbeta*vds*(vgst - .5*vds);
117  here->MOSgmbs = here->MOSgm*arg;
118  }
119  }
120  return (cdrain);
121 }
double MOSbeta
Definition: mosdefs.h:95
double MOSgamma
Definition: mosdefs.h:286
double ms_von
Definition: mosdefs.h:607
double MOSgm
Definition: mosdefs.h:74
double ms_vbd
Definition: mosdefs.h:612
double MOSgmbs
Definition: mosdefs.h:73
#define MAX(a, b)
Definition: spdefs.h:135
double MOSgds
Definition: mosdefs.h:75
int MOStype
Definition: mosdefs.h:279
double ms_vbs
Definition: mosdefs.h:611
double ms_vds
Definition: mosdefs.h:610
double MOStPhi
Definition: mosdefs.h:49
int MOSmode
Definition: mosdefs.h:32
double MOStVbi
Definition: mosdefs.h:59
double ms_vgd
Definition: mosdefs.h:614
double MOSlambda
Definition: mosdefs.h:313
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
double MOSeq2 ( MOSmodel model,
MOSinstance here,
struct mosstuff ms 
)

Definition at line 125 of file moseq.c.

130 {
131 
132  /*
133  * this routine evaluates the drain current, its derivatives and
134  * the charges associated with the gate, channel and bulk
135  * for mosfets (level 2 model)
136  *
137  */
138 
139  double cdrain;
140  double arg;
141  double sarg;
142  double beta1;
143  double dsrgdb;
144  double d2sdb2;
145  double sphi; /* square root of phi */
146  double sphi3; /* square root of phi cubed */
147  double barg;
148  double d2bdb2;
149  double factor;
150  double dbrgdb;
151  double eta;
152  double vbin;
153  double dgddb2;
154  double dgddvb;
155  double dgdvds;
156  double gamasd;
157  double gammad;
158  double vth;
159  double xn;
160  double argg;
161  double vgst;
162  double sarg3;
163  double sbiarg;
164  double dgdvbs;
165  double body;
166  double gdbdv;
167  double dodvbs;
168  double dodvds;
169  double dxndvd;
170  double dxndvb;
171  double dudvgs;
172  double dudvds;
173  double dudvbs;
174  double vgsx;
175  double ufact;
176  double ueff;
177  double dsdvgs;
178  double dsdvbs;
179  double bsarg;
180  double dbsrdb;
181  double bodys;
182  double gdbdvs;
183  double dldvgs;
184  double dldvds;
185  double dldvbs;
186  double dfact;
187  double clfact;
188  double xwb;
189  double vdson;
190  double cdson;
191  double didvds;
192  double gdson;
193  double gmw;
194  double gbson;
195  double xlamda;
196  double lvbs;
197  double lvds;
198  double lvgs;
199  double phiMinVbs;
200  double oneoverl;
201  double oneovere;
202  double tmp, tmp1; /* temporary variable, not used for more than */
203  /* about 10 lines at a time */
204  int i;
205  int j;
206 
207  /* 'local' variables - these switch d & s around appropriately
208  * so that we don't have to worry about vds < 0
209  */
210  if (here->MOSmode > 0) {
211  lvbs = ms->ms_vbs;
212  lvds = ms->ms_vds;
213  lvgs = ms->ms_vgs;
214  }
215  else {
216  lvbs = ms->ms_vbd;
217  lvds = -ms->ms_vds;
218  lvgs = ms->ms_vgd;
219  }
220  xlamda = model->MOSlambda;
221  phiMinVbs = here->MOStPhi - lvbs;
222  oneoverl = 1.0/here->MOSeffectiveLength;
223 
224  /*
225  * compute some useful quantities
226  */
227 
228  if (lvbs <= 0.0) {
229  sarg = sqrt(phiMinVbs);
230  dsrgdb = -0.5/sarg;
231  d2sdb2 = 0.5*dsrgdb/phiMinVbs;
232  }
233  else {
234  sphi = sqrt(here->MOStPhi);
235  sphi3 = here->MOStPhi*sphi;
236  sarg = sphi/(1.0 + 0.5*lvbs/here->MOStPhi);
237  tmp = sarg/sphi3;
238  dsrgdb = -0.5*sarg*tmp;
239  d2sdb2 = -dsrgdb*tmp;
240  }
241  if ((lvds - lvbs) >= 0) {
242  barg = sqrt(phiMinVbs + lvds);
243  dbrgdb = -0.5/barg;
244  d2bdb2 = 0.5*dbrgdb/(phiMinVbs + lvds);
245  }
246  else {
247  barg = sphi/(1.0 + 0.5*(lvbs - lvds)/here->MOStPhi);
248  tmp = barg/sphi3;
249  dbrgdb = -0.5*barg*tmp;
250  d2bdb2 = -dbrgdb*tmp;
251  }
252 
253  /*
254  * calculate threshold voltage (von)
255  * narrow-channel effect
256  */
257  factor = 0.125*model->MOSnarrowFactor*2.0*M_PI*EPSSIL/
258  here->MOSoxideCap*here->MOSeffectiveLength;
259  eta = 1.0 + factor;
260  oneovere = 1.0/eta;
261  vbin = here->MOStVbi*model->MOStype + factor*phiMinVbs;
262 
263  gamasd = model->MOSgamma;
264  gammad = model->MOSgamma;
265  dgddvb = 0.0;
266  dgdvds = 0.0;
267  dgddb2 = 0.0;
268 
269  if ((model->MOSgamma > 0.0) ||
270  (model->MOSsubstrateDoping > 0.0)) {
271 
272  /*
273  * short-channel effect with vds != 0.0
274  */
275  dgddvb = -model->MOSgamma;
276 
277  if (model->MOSjunctionDepth > 0) {
278  double tbxwd, tbxws, targxs, targxd, targs, targd;
279 
280  tbxwd = model->MOSxd*dbrgdb;
281  tbxws = model->MOSxd*dsrgdb;
282 
283  tmp = 2.0/model->MOSjunctionDepth;
284  targxs = 1.0 + tmp*model->MOSxd*sarg;
285  targxd = 1.0 + tmp*model->MOSxd*barg;
286  targs = sqrt(targxs);
287  targd = sqrt(targxd);
288  tmp = .5*model->MOSjunctionDepth*oneoverl;
289  gamasd *= (1.0 - tmp*(targs + targd - 2.0));
290 
291  targs = oneoverl/targs;
292  targd = oneoverl/targd;
293  dgddvb *= .5*(tbxws*targs + tbxwd*targd);
294  dgdvds = model->MOSgamma*0.5*tbxwd*targd;
295 
296  tmp = -model->MOSxd*(d2sdb2 + dsrgdb*dsrgdb*
297  model->MOSxd/(model->MOSjunctionDepth*targxs))*targs;
298  tmp1 = -model->MOSxd*(d2bdb2 + dbrgdb*dbrgdb*
299  model->MOSxd/(model->MOSjunctionDepth*targxd))*targd;
300  dgddb2 = -0.5*model->MOSgamma*(tmp + tmp1);
301  }
302  }
303 
304  ms->ms_von = vbin + gamasd*sarg;
305  vth = ms->ms_von;
306  ms->ms_vdsat = 0.0;
307 
308  if (model->MOSfastSurfaceStateDensity != 0.0 &&
309  here->MOSoxideCap != 0.0) {
311  tmp1 = -(gamasd*dsrgdb + dgddvb*sarg) + factor;
312  xn = 1.0 +
313  tmp/here->MOSoxideCap*here->MOSw*here->MOSeffectiveLength + tmp1;
314  tmp = ms->ms_vt*xn;
315  ms->ms_von += tmp;
316  argg = 1.0/tmp;
317  vgst = lvgs - ms->ms_von;
318  }
319  else {
320  vgst = lvgs - ms->ms_von;
321  if (lvgs <= ms->ms_von) {
322  /*
323  * cutoff region
324  */
325  here->MOSgds = 0.0;
326  goto bad;
327  }
328  }
329 
330  /*
331  * compute some more useful quantities
332  */
333  sarg3 = sarg*sarg*sarg;
334  sbiarg = sqrt(here->MOStBulkPot);
335  gammad = gamasd;
336  dgdvbs = dgddvb;
337  body = barg*barg*barg - sarg3;
338  gdbdv = 2.0*gammad*(barg*barg*dbrgdb - sarg*sarg*dsrgdb);
339  dodvbs = -factor + dgdvbs*sarg + gammad*dsrgdb;
340 
341  if (model->MOSfastSurfaceStateDensity != 0.0 &&
342  here->MOSoxideCap != 0.0) {
343 
344  dxndvb = 2.0*dgdvbs*dsrgdb + gammad*d2sdb2 + dgddb2*sarg;
345  dodvbs = dodvbs + ms->ms_vt*dxndvb;
346  dxndvd = dgdvds*dsrgdb;
347  dodvds = dgdvds*sarg + ms->ms_vt*dxndvd;
348  }
349 
350  /*
351  * evaluate effective mobility and its derivatives
352  */
353  if (here->MOSoxideCap <= 0.0) {
354  ufact = 1.0;
355  ueff = model->MOSsurfaceMobility * M2PCM2;
356  dudvgs = 0.0;
357  dudvds = 0.0;
358  dudvbs = 0.0;
359  }
360  else {
361  tmp = model->MOScritField * 100 /* cm/m */ * EPSSIL/
362  model->MOSoxideCapFactor;
363  if (vgst <= tmp) {
364  ufact = 1.0;
365  ueff = model->MOSsurfaceMobility * M2PCM2;
366  dudvgs = 0.0;
367  dudvds = 0.0;
368  dudvbs = 0.0;
369  }
370  else {
371  ufact = exp(model->MOScritFieldExp*log(tmp/vgst));
372  ueff = model->MOSsurfaceMobility * M2PCM2 *ufact;
373  dudvgs = -ufact*model->MOScritFieldExp/vgst;
374  dudvds = 0.0;
375  dudvbs = model->MOScritFieldExp*ufact*dodvbs/vgst;
376  }
377  }
378 
379  /*
380  * evaluate saturation voltage and its derivatives according to
381  * grove-frohman equation
382  */
383  vgsx = lvgs;
384  gammad = gamasd*oneovere;
385  dgdvbs = dgddvb;
386  if (model->MOSfastSurfaceStateDensity != 0 && here->MOSoxideCap != 0) {
387  vgsx = MAX(lvgs,ms->ms_von);
388  }
389  if (gammad > 0) {
390  tmp = gammad*gammad;
391  tmp1 = (vgsx - vbin)*oneovere + phiMinVbs;
392  if (tmp1 <= 0.0) {
393  ms->ms_vdsat = 0.0;
394  dsdvgs = 0.0;
395  dsdvbs = 0.0;
396  }
397  else {
398  arg = sqrt(1.0 + 4.0*tmp1/tmp);
399  ms->ms_vdsat = (vgsx - vbin)*oneovere + .5*tmp*(1.0 - arg);
400  ms->ms_vdsat = MAX(ms->ms_vdsat,0.0);
401  dsdvgs = (1.0 - 1.0/arg)*oneovere;
402  dsdvbs = (gammad*(1.0 - arg) + 2.0*tmp1/(gammad*arg))*oneovere
403  * dgdvbs + 1.0/arg + factor*dsdvgs;
404  }
405  }
406  else {
407  ms->ms_vdsat = (vgsx - vbin)*oneovere;
408  ms->ms_vdsat = MAX(ms->ms_vdsat,0.0);
409  dsdvgs = 1.0;
410  dsdvbs = 0.0;
411  }
412  if (model->MOSmaxDriftVel > 0) {
413  double param[5];
414 
415  tmp = model->MOSmaxDriftVel*here->MOSeffectiveLength/ueff;
416  tmp1 = (vgsx - vbin)*oneovere + phiMinVbs;
417  param[0] = P1X3*gammad;
418  param[1] = -2.0*(tmp1 + tmp);
419  param[2] = -2.0*gammad*tmp;
420  param[3] = 2.0*tmp1*(phiMinVbs + tmp) - phiMinVbs*phiMinVbs -
421  P1X3*gammad*sarg3;
422  param[4] = phiMinVbs;
423 
424  mos2_vsat(&ms->ms_vdsat,param);
425  }
426 
427  /*
428  * evaluate effective channel length and its derivatives
429  */
430  dldvgs = 0.0;
431  dldvds = 0.0;
432  dldvbs = 0.0;
433 
434  if (lvds != 0.0) {
435 
436  gammad = gamasd;
437  if ((lvbs - ms->ms_vdsat) <= 0) {
438  bsarg = sqrt(ms->ms_vdsat + phiMinVbs);
439  dbsrdb = -0.5/bsarg;
440  }
441  else {
442  bsarg = sphi/(1.0 + 0.5*(lvbs - ms->ms_vdsat)/here->MOStPhi);
443  dbsrdb = -0.5*bsarg*bsarg/sphi3;
444  }
445  bodys = bsarg*bsarg*bsarg - sarg3;
446  gdbdvs = 2.0*gammad*(bsarg*bsarg*dbsrdb - sarg*sarg*dsrgdb);
447 
448  if (model->MOSmaxDriftVel <= 0) {
449  if (model->MOSsubstrateDoping != 0.0 && xlamda <= 0.0) {
450  tmp = .25*(lvds - ms->ms_vdsat);
451  tmp1 = sqrt(1.0 + tmp*tmp);
452  tmp = sqrt(tmp + tmp1);
453  xlamda = model->MOSxd*tmp*oneoverl/lvds;
454  tmp = lvds*xlamda/(8.0*tmp1);
455  dldvgs = tmp*dsdvgs;
456  dldvds = -xlamda + tmp;
457  dldvbs = tmp*dsdvbs;
458  }
459  }
460  else {
461  double txdv, txlv, tqdsat;
462 
463  txdv = model->MOSxd/sqrt(model->MOSchannelCharge);
464  txlv = model->MOSmaxDriftVel*txdv/(2.0*ueff);
465  tqdsat = -1.0 + gammad*dbsrdb;
466  tmp = model->MOSmaxDriftVel*here->MOSeffectiveLength;
467  tmp1 = (vgsx - vbin)*oneovere - ms->ms_vdsat - gammad*bsarg;
468  tmp1 = 1.0/(tmp*tqdsat - ueff*tmp1);
469  dsdvgs = -(tmp - ueff*ms->ms_vdsat)*oneovere*tmp1;
470  dsdvbs = -(-tmp*(1.0 + tqdsat - factor*oneovere) +
471  ueff*(gdbdvs - P66*dgdvbs*bodys)*oneovere)*tmp1;
472 
473  if (model->MOSsubstrateDoping != 0.0 && xlamda <= 0.0) {
474  tmp = lvds - ms->ms_vdsat;
475  tmp = MAX(tmp,0.0);
476  tmp1 = sqrt(txlv*txlv + tmp);
477  tmp = txdv*oneoverl/(2.0*tmp1);
478  xlamda = txdv*(tmp1 - txlv)*oneoverl/lvds;
479  dldvgs = tmp*dsdvgs;
480  dldvds = -xlamda + tmp;
481  dldvbs = tmp*dsdvbs;
482  }
483  }
484  }
485 
486  /*
487  * limit channel shortening at punch-through
488  */
489  xwb = model->MOSxd*sbiarg;
490  clfact = 1.0 - xlamda*lvds;
491  dldvds = -xlamda - dldvds;
492  tmp1 = here->MOSeffectiveLength*clfact;
493  tmp = xlamda*lvds*here->MOSeffectiveLength;
494  if (model->MOSsubstrateDoping == 0.0) xwb = 0.25e-6;
495  if (tmp1 < xwb) {
496  tmp1 = xwb/(1.0 + (tmp - here->MOSeffectiveLength - xwb)/xwb);
497  clfact = tmp1*oneoverl;
498 
499  dfact = tmp1/xwb;
500  dfact *= dfact;
501  dldvgs *= dfact;
502  dldvds *= dfact;
503  dldvbs *= dfact;
504  }
505 
506  /*
507  * evaluate effective beta (effective kp)
508  */
509  clfact = 1.0/clfact;
510  beta1 = here->MOSbeta*ufact*clfact;
511  ufact = 1.0/ufact;
512 
513  /*
514  * test for mode of operation and branch appropriately
515  */
516  gammad = gamasd;
517  dgdvbs = dgddvb;
518  if (lvds <= 1.0e-10) {
519  if (lvgs <= ms->ms_von) {
520  if ((model->MOSfastSurfaceStateDensity == 0.0) ||
521  (here->MOSoxideCap == 0.0)) {
522  here->MOSgds = 0.0;
523  goto bad;
524  }
525 
526  here->MOSgds = beta1*(ms->ms_von - vbin - gammad*sarg)*exp(argg*
527  (lvgs-ms->ms_von));
528  goto bad;
529  }
530 
531  here->MOSgds = beta1*(lvgs-vbin-gammad*sarg);
532  goto bad;
533  }
534 
535  if (lvgs > ms->ms_von) {
536 
537  if (lvds <= ms->ms_vdsat) {
538  /*
539  * linear region
540  */
541 
542  cdrain = beta1*((lvgs - vbin - .5*eta*lvds)*lvds -
543  P66*gammad*body);
544 
545  tmp = cdrain*(dudvgs*ufact - dldvgs*clfact);
546  here->MOSgm = tmp + beta1*lvds;
547 
548  tmp = cdrain*(dudvds*ufact - dldvds*clfact);
549  here->MOSgds = tmp + beta1*(lvgs - vbin - eta*lvds -
550  gammad*barg - P66*dgdvds*body);
551 
552  tmp = cdrain*(dudvbs*ufact - dldvbs*clfact);
553  here->MOSgmbs = tmp - beta1*(gdbdv + P66*dgdvbs*body -
554  factor*lvds);
555  }
556  else {
557  /*
558  * saturation region
559  */
560  cdrain = beta1*((lvgs - vbin - eta*
561  .5*ms->ms_vdsat)*ms->ms_vdsat - P66*gammad*bodys);
562 
563  tmp = cdrain*(dudvgs*ufact - dldvgs*clfact);
564  here->MOSgm = tmp + beta1*ms->ms_vdsat + beta1*(lvgs -
565  vbin - eta*ms->ms_vdsat - gammad*bsarg)*dsdvgs;
566  here->MOSgds = -cdrain*dldvds*clfact - P66*beta1*dgdvds*bodys;
567  tmp = cdrain*(dudvbs*ufact - dldvbs*clfact);
568  here->MOSgmbs = tmp - beta1*(gdbdvs + P66*dgdvbs*bodys -
569  factor*ms->ms_vdsat) + beta1*
570  (lvgs - vbin - eta*ms->ms_vdsat - gammad*bsarg)*dsdvbs;
571  }
572  return (cdrain);
573  }
574 
575  /*
576  * subthreshold region
577  */
578  if (ms->ms_vdsat <= 0) {
579  here->MOSgds = 0.0;
580  if (lvgs > vth) return (cdrain);
581  goto bad;
582  }
583  vdson = MIN(ms->ms_vdsat,lvds);
584  if (lvds > ms->ms_vdsat) {
585  barg = bsarg;
586  dbrgdb = dbsrdb;
587  body = bodys;
588  gdbdv = gdbdvs;
589  }
590  cdson = beta1*((ms->ms_von - vbin - .5*eta*vdson)*vdson -
591  P66*gammad*body);
592  didvds = beta1*(ms->ms_von - vbin - eta*vdson - gammad*barg);
593  gdson = -cdson*dldvds*clfact - P66*beta1*dgdvds*body;
594  if (lvds < ms->ms_vdsat)
595  gdson += didvds;
596  gbson = -cdson*dldvbs*clfact + beta1*
597  (dodvbs*vdson + factor*vdson - P66*dgdvbs*body - gdbdv);
598  if (lvds > ms->ms_vdsat)
599  gbson += didvds*dsdvbs;
600  tmp = exp(argg*(lvgs - ms->ms_von));
601  cdrain = cdson*tmp;
602  gmw = cdrain*argg;
603  here->MOSgm = gmw;
604  if (lvds > ms->ms_vdsat) here->MOSgm = gmw + didvds*dsdvgs*tmp;
605  tmp1 = gmw*(lvgs - ms->ms_von)/xn;
606  here->MOSgds = gdson*tmp - here->MOSgm*dodvds - tmp1*dxndvd;
607  here->MOSgmbs = gbson*tmp - here->MOSgm*dodvbs - tmp1*dxndvb;
608  return (cdrain);
609 
610  /*
611  * finish special cases
612  */
613 bad:
614  here->MOSgm = 0.0;
615  here->MOSgmbs = 0.0;
616  return (0.0);
617 }
double MOSbeta
Definition: mosdefs.h:95
double MOSgamma
Definition: mosdefs.h:286
double MOStBulkPot
Definition: mosdefs.h:57
double ms_von
Definition: mosdefs.h:607
double MOSgm
Definition: mosdefs.h:74
double ms_vbd
Definition: mosdefs.h:612
double MOSgmbs
Definition: mosdefs.h:73
double ms_vt
Definition: mosdefs.h:606
double MOSchannelCharge
Definition: mosdefs.h:317
double MOSxd
Definition: mosdefs.h:325
#define MAX(a, b)
Definition: spdefs.h:135
#define MIN(a, b)
Definition: spdefs.h:136
#define P1X3
Definition: moseq.c:23
#define M_PI
Definition: spice.h:132
#define CHARGE
Definition: const.h:10
double MOSgds
Definition: mosdefs.h:75
static void mos2_vsat()
static double e
Definition: vectors.c:17
int MOStype
Definition: mosdefs.h:279
double ms_vbs
Definition: mosdefs.h:611
double MOSoxideCapFactor
Definition: mosdefs.h:282
double MOSmaxDriftVel
Definition: mosdefs.h:323
#define EPSSIL
Definition: moseq.c:18
double MOSnarrowFactor
Definition: mosdefs.h:322
double MOSjunctionDepth
Definition: mosdefs.h:324
double MOSw
Definition: mosdefs.h:35
#define P66
Definition: moseq.c:21
double ms_vds
Definition: mosdefs.h:610
double MOSsubstrateDoping
Definition: mosdefs.h:308
double MOScritField
Definition: mosdefs.h:318
double MOSoxideCap
Definition: mosdefs.h:96
double MOStPhi
Definition: mosdefs.h:49
double MOSfastSurfaceStateDensity
Definition: mosdefs.h:321
int MOSmode
Definition: mosdefs.h:32
double MOStVbi
Definition: mosdefs.h:59
double ms_vgd
Definition: mosdefs.h:614
double MOScritFieldExp
Definition: mosdefs.h:316
double MOSlambda
Definition: mosdefs.h:313
double MOSeffectiveLength
Definition: mosdefs.h:91
#define M2PCM2
Definition: moseq.c:29
#define CM2PM2
Definition: moseq.c:26
double MOSsurfaceMobility
Definition: mosdefs.h:305
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
double MOSeq3 ( MOSmodel model,
MOSinstance here,
struct mosstuff ms 
)

Definition at line 718 of file moseq.c.

723 {
724 
725  /*
726  * this routine evaluates the drain current, its derivatives and
727  * the charges associated with the gate, channel and bulk
728  * for mosfets based on semi-empirical equations (level 3 model)
729  */
730 
731  double beta = here->MOSbeta;
732  double cdrain;
733  double coeff0 = 0.0631353e0;
734  double coeff1 = 0.8013292e0;
735  double coeff2 = -0.01110777e0;
736  double oneoverxl; /* 1/effective length */
737  double eta; /* eta from model after length factor */
738  double phibs; /* phi - vbs */
739  double sqphbs; /* square root of phibs */
740  double dsqdvb;
741  double sqphis; /* square root of phi */
742  double sqphs3; /* square root of phi cubed */
743  double wps;
744  double oneoverxj; /* 1/junction depth */
745  double xjonxl; /* junction depth/effective length */
746  double djonxj;
747  double wponxj;
748  double arga;
749  double argb;
750  double argc;
751  double dwpdvb;
752  double dadvb;
753  double dbdvb;
754  double gammas;
755  double fbodys;
756  double fbody;
757  double onfbdy;
758  double qbonco;
759  double wconxj;
760  double dfsdvb;
761  double dfbdvb;
762  double dqbdvb;
763  double vth;
764  double dvtdvb;
765  double csonco;
766  double cdonco;
767  double dxndvb;
768  double dvodvb;
769  double dvodvd;
770  double vgsx;
771  double dvtdvd;
772  double onfg;
773  double fgate;
774  double us;
775  double dfgdvg;
776  double dfgdvd;
777  double dfgdvb;
778  double dvsdvg;
779  double dvsdvb;
780  double dvsdvd;
781  double xn;
782  double vdsc;
783  double onvdsc;
784  double dvsdga;
785  double vdsx;
786  double dcodvb;
787  double cdnorm;
788  double cdo;
789  double cd1;
790  double fdrain;
791  double fd2;
792  double dfddvg;
793  double dfddvb;
794  double dfddvd;
795  double gdsat;
796  double cdsat;
797  double gdoncd;
798  double gdonfd;
799  double gdonfg;
800  double dgdvg;
801  double dgdvd;
802  double dgdvb;
803  double emax;
804  double emongd;
805  double demdvg;
806  double demdvd;
807  double demdvb;
808  double delxl;
809  double dldvd;
810  double dldem;
811  double ddldvg;
812  double ddldvd;
813  double ddldvb;
814  double dlonxl;
815  double xlfact;
816  double diddl;
817  double gds0;
818  double emoncd;
819  double ondvt;
820  double onxn;
821  double wfact;
822  double gms;
823  double gmw;
824  double fshort;
825  double lvbs;
826  double lvds;
827  double lvgs;
828 
829  /* 'local' variables - these switch d & s around appropriately
830  * so that we don't have to worry about vds < 0
831  */
832  if (here->MOSmode > 0) {
833  lvbs = ms->ms_vbs;
834  lvds = ms->ms_vds;
835  lvgs = ms->ms_vgs;
836  }
837  else {
838  lvbs = ms->ms_vbd;
839  lvds = -ms->ms_vds;
840  lvgs = ms->ms_vgd;
841  }
842  /*
843  * bypasses the computation of charges
844  */
845 
846  /*
847  * reference cdrain equations to source and
848  * charge equations to bulk
849  */
850  ms->ms_vdsat = 0.0;
851  oneoverxl = 1.0/here->MOSeffectiveLength;
852 
853  eta = model->MOSeta * 8.15e-22/(model->MOSoxideCapFactor*
854  here->MOSeffectiveLength*
856  /*
857  *.....square root term
858  */
859  if (lvbs <= 0.0 ) {
860  phibs = here->MOStPhi - lvbs;
861  sqphbs = sqrt(phibs);
862  dsqdvb = -0.5/sqphbs;
863  }
864  else {
865  sqphis = sqrt(here->MOStPhi);
866  sqphs3 = here->MOStPhi*sqphis;
867  sqphbs = sqphis/(1.0 + lvbs/(here->MOStPhi + here->MOStPhi));
868  phibs = sqphbs*sqphbs;
869  dsqdvb = -phibs/(sqphs3+sqphs3);
870  }
871  /*
872  *.....short channel effect factor
873  */
874  if ( (model->MOSjunctionDepth != 0.0) &&
875  (model->MOSxd != 0.0) ) {
876  wps = model->MOSxd*sqphbs;
877  oneoverxj = 1.0/model->MOSjunctionDepth;
878  xjonxl = model->MOSjunctionDepth*oneoverxl;
879  djonxj = model->MOSlatDiff*oneoverxj;
880  wponxj = wps*oneoverxj;
881  wconxj = coeff0 + coeff1*wponxj + coeff2*wponxj*wponxj;
882  arga = wconxj + djonxj;
883  argc = wponxj/(1.0 + wponxj);
884  argb = sqrt(1.0 - argc*argc);
885  fshort = 1.0 - xjonxl*(arga*argb - djonxj);
886  dwpdvb = model->MOSxd*dsqdvb;
887  dadvb = (coeff1 + coeff2*(wponxj+wponxj))*dwpdvb*oneoverxj;
888  dbdvb = -argc*argc*(1.0 - argc)*dwpdvb/(argb*wps);
889  dfsdvb = -xjonxl*(dadvb*argb + arga*dbdvb);
890  }
891  else {
892  fshort = 1.0;
893  dfsdvb = 0.0;
894  }
895  /*
896  *.....body effect
897  */
898  gammas = model->MOSgamma*fshort;
899  fbodys = 0.5*gammas/(sqphbs+sqphbs);
900  fbody = fbodys+model->MOSnarrowFactor/here->MOSw;
901  onfbdy = 1.0/(1.0 + fbody);
902  dfbdvb = -fbodys*dsqdvb/sqphbs + fbodys*dfsdvb/fshort;
903  qbonco = gammas*sqphbs + model->MOSnarrowFactor*phibs/here->MOSw;
904  dqbdvb = gammas*dsqdvb + model->MOSgamma*dfsdvb*sqphbs -
905  model->MOSnarrowFactor/here->MOSw;
906  /*
907  *.....threshold voltage
908  */
909  vth = qbonco + here->MOStVbi*model->MOStype - eta*lvds;
910  dvtdvd = -eta;
911  dvtdvb = dqbdvb;
912  /*
913  *.....joint weak inversion and strong inversion
914  */
915  ms->ms_von = vth;
916  if (model->MOSfastSurfaceStateDensity != 0.0) {
917  csonco = CHARGE*model->MOSfastSurfaceStateDensity * CM2PM2 *
918  here->MOSeffectiveLength*here->MOSw/here->MOSoxideCap;
919  cdonco = qbonco/(phibs + phibs);
920  xn = 1.0 + csonco + cdonco;
921  ms->ms_von = vth + ms->ms_vt*xn;
922  dxndvb = dqbdvb/(phibs + phibs) - qbonco*dsqdvb/(phibs*sqphbs);
923  dvodvd = dvtdvd;
924  dvodvb = dvtdvb + ms->ms_vt*dxndvb;
925  }
926  else {
927  /*
928  *.....cutoff region
929  */
930  if (lvgs <= ms->ms_von ) {
931  cdrain = 0.0;
932  here->MOSgm = 0.0;
933  here->MOSgds = 0.0;
934  here->MOSgmbs = 0.0;
935  goto done;
936  }
937  }
938  /*
939  *.....device is on
940  */
941  vgsx = MAX(lvgs,ms->ms_von);
942  /*
943  *.....mobility modulation by gate voltage
944  */
945  onfg = 1.0 + model->MOStheta*(vgsx - vth);
946  fgate = 1.0/onfg;
947  us = here->MOStSurfMob * M2PCM2 * fgate;
948  dfgdvg = -model->MOStheta*fgate*fgate;
949  dfgdvd = -dfgdvg*dvtdvd;
950  dfgdvb = -dfgdvg*dvtdvb;
951  /*
952  *.....saturation voltage
953  */
954  ms->ms_vdsat = (vgsx - vth)*onfbdy;
955  if ( model->MOSmaxDriftVel <= 0.0 ) {
956  dvsdvg = onfbdy;
957  dvsdvd = -dvsdvg*dvtdvd;
958  dvsdvb = -dvsdvg*dvtdvb-ms->ms_vdsat*dfbdvb*onfbdy;
959  }
960  else {
961  vdsc = here->MOSeffectiveLength*model->MOSmaxDriftVel/us;
962  onvdsc = 1.0/vdsc;
963  arga = (vgsx - vth)*onfbdy;
964  argb = sqrt(arga*arga + vdsc*vdsc);
965  ms->ms_vdsat = arga+vdsc - argb;
966  dvsdga = (1.0 - arga/argb)*onfbdy;
967  dvsdvg = dvsdga - (1.0 - vdsc/argb)*vdsc*dfgdvg*onfg;
968  dvsdvd = -dvsdvg*dvtdvd;
969  dvsdvb = -dvsdvg*dvtdvb - arga*dvsdga*dfbdvb;
970  }
971  /*
972  *.....current factors in linear region
973  */
974  vdsx = MIN(lvds,ms->ms_vdsat);
975  if (vdsx == 0.0) {
976  beta *= fgate;
977  cdrain = 0.0;
978  here->MOSgm = 0.0;
979  here->MOSgds = beta*(vgsx-vth);
980  here->MOSgmbs = 0.0;
981  if ( (model->MOSfastSurfaceStateDensity != 0.0) &&
982  (lvgs < ms->ms_von) ) {
983  here->MOSgds *= exp( (lvgs - ms->ms_von)/(ms->ms_vt*xn) );
984  }
985  goto done;
986  }
987 
988  cdo = vgsx - vth - 0.5*(1.0 + fbody)*vdsx;
989  dcodvb = -dvtdvb - 0.5*dfbdvb*vdsx;
990  /*
991  *.....normalized drain current
992  */
993  cdnorm = cdo*vdsx;
994  here->MOSgm = vdsx;
995  here->MOSgds = vgsx - vth - (1.0 + fbody + dvtdvd)*vdsx;
996  here->MOSgmbs = dcodvb*vdsx;
997  /*
998  *.....drain current without velocity saturation effect
999  */
1000  cd1 = beta*cdnorm;
1001  beta *= fgate;
1002  cdrain = beta*cdnorm;
1003  here->MOSgm = beta*here->MOSgm+dfgdvg*cd1;
1004  here->MOSgds = beta*here->MOSgds+dfgdvd*cd1;
1005  here->MOSgmbs = beta*here->MOSgmbs;
1006  /*
1007  *.....velocity saturation factor
1008  */
1009  if ( model->MOSmaxDriftVel != 0.0 ) {
1010  fdrain = 1.0/(1.0+vdsx*onvdsc);
1011  fd2 = fdrain*fdrain;
1012  arga = fd2*vdsx*onvdsc*onfg;
1013  dfddvg = -dfgdvg*arga;
1014  dfddvd = -dfgdvd*arga - fd2*onvdsc;
1015  dfddvb = -dfgdvb*arga;
1016  /*
1017  *.....drain current
1018  */
1019  here->MOSgm = fdrain*here->MOSgm + dfddvg*cdrain;
1020  here->MOSgds = fdrain*here->MOSgds + dfddvd*cdrain;
1021  here->MOSgmbs = fdrain*here->MOSgmbs + dfddvb*cdrain;
1022  cdrain = fdrain*cdrain;
1023  beta *= fdrain;
1024  }
1025  /*
1026  *.....channel length modulation
1027  */
1028  if (lvds <= ms->ms_vdsat) goto invers;
1029 
1030  if (model->MOSmaxDriftVel == 0.0) {
1031  delxl =
1032  sqrt(model->MOSkappa*(lvds - ms->ms_vdsat)*model->MOSalpha);
1033  dldvd = 0.5*delxl/(lvds - ms->ms_vdsat);
1034  ddldvg = 0.0;
1035  ddldvd = -dldvd;
1036  ddldvb = 0.0;
1037  }
1038  else {
1039 
1040  if (model->MOSalpha == 0.0) goto invers;
1041 
1042  cdsat = cdrain;
1043  gdsat = cdsat*(1.0 - fdrain)*onvdsc;
1044  gdsat = MAX(1.0e-12,gdsat);
1045  gdoncd = gdsat/cdsat;
1046  gdonfd = gdsat/(1.0 - fdrain);
1047  gdonfg = gdsat*onfg;
1048  dgdvg = gdoncd*here->MOSgm - gdonfd*dfddvg+gdonfg*dfgdvg;
1049  dgdvd = gdoncd*here->MOSgds - gdonfd*dfddvd+gdonfg*dfgdvd;
1050  dgdvb = gdoncd*here->MOSgmbs - gdonfd*dfddvb+gdonfg*dfgdvb;
1051 
1052  emax = model->MOSkappa * cdsat*oneoverxl/gdsat;
1053 
1054  emoncd = emax/cdsat;
1055  emongd = emax/gdsat;
1056  demdvg = emoncd*here->MOSgm - emongd*dgdvg;
1057  demdvd = emoncd*here->MOSgds - emongd*dgdvd;
1058  demdvb = emoncd*here->MOSgmbs - emongd*dgdvb;
1059 
1060  arga = 0.5*emax*model->MOSalpha;
1061  argc = model->MOSkappa*model->MOSalpha;
1062  argb = sqrt(arga*arga + argc*(lvds - ms->ms_vdsat));
1063  delxl = argb - arga;
1064  dldvd = argc/(argb+argb);
1065  dldem = 0.5*(arga/argb - 1.0)*model->MOSalpha;
1066  ddldvg = dldem*demdvg;
1067  ddldvd = dldem*demdvd-dldvd;
1068  ddldvb = dldem*demdvb;
1069  }
1070  /*
1071  *.....punch through approximation
1072  */
1073  if (delxl > (0.5*here->MOSeffectiveLength)) {
1074  delxl = here->MOSeffectiveLength -
1076  (4.0*delxl));
1077  arga = 4.0*(here->MOSeffectiveLength - delxl)*
1078  (here->MOSeffectiveLength - delxl)/
1079  (here->MOSeffectiveLength*here->MOSeffectiveLength);
1080  ddldvg = ddldvg*arga;
1081  ddldvd = ddldvd*arga;
1082  ddldvb = ddldvb*arga;
1083  dldvd = dldvd*arga;
1084  }
1085  /*
1086  *.....saturation region
1087  */
1088  dlonxl = delxl*oneoverxl;
1089  xlfact = 1.0/(1.0 - dlonxl);
1090  cdrain = cdrain*xlfact;
1091  diddl = cdrain/(here->MOSeffectiveLength - delxl);
1092  here->MOSgm= here->MOSgm*xlfact + diddl*ddldvg;
1093  gds0 = here->MOSgds*xlfact + diddl*ddldvd;
1094  here->MOSgmbs = here->MOSgmbs*xlfact + diddl*ddldvb;
1095  here->MOSgm = here->MOSgm + gds0*dvsdvg;
1096  here->MOSgmbs = here->MOSgmbs + gds0*dvsdvb;
1097  here->MOSgds = gds0*dvsdvd + diddl*dldvd;
1098 
1099 invers:
1100  /*
1101  *.....finish strong inversion case
1102  */
1103  if (lvgs < ms->ms_von) {
1104  /*
1105  *.....weak inversion
1106  */
1107  onxn = 1.0/xn;
1108  ondvt = onxn/ms->ms_vt;
1109  wfact = exp((lvgs - ms->ms_von)*ondvt);
1110  cdrain = cdrain*wfact;
1111  gms = here->MOSgm*wfact;
1112  gmw = cdrain*ondvt;
1113  here->MOSgm = gmw;
1114  if (lvds > ms->ms_vdsat) {
1115  here->MOSgm = here->MOSgm+gds0*dvsdvg*wfact;
1116  }
1117  here->MOSgds = here->MOSgds*wfact+(gms-gmw)*dvodvd;
1118  here->MOSgmbs = here->MOSgmbs*wfact + (gms-gmw)*dvodvb - gmw*
1119  (lvgs - ms->ms_von)*onxn*dxndvb;
1120  }
1121 
1122 done:
1123  return (cdrain);
1124 }
double MOSbeta
Definition: mosdefs.h:95
double MOSgamma
Definition: mosdefs.h:286
double ms_von
Definition: mosdefs.h:607
double MOSlatDiff
Definition: mosdefs.h:303
double MOSgm
Definition: mosdefs.h:74
double ms_vbd
Definition: mosdefs.h:612
double MOSgmbs
Definition: mosdefs.h:73
double ms_vt
Definition: mosdefs.h:606
double MOSxd
Definition: mosdefs.h:325
#define MAX(a, b)
Definition: spdefs.h:135
double MOSeta
Definition: mosdefs.h:328
#define MIN(a, b)
Definition: spdefs.h:136
#define CHARGE
Definition: const.h:10
double MOSgds
Definition: mosdefs.h:75
double MOStSurfMob
Definition: mosdefs.h:48
static double e
Definition: vectors.c:17
int MOStype
Definition: mosdefs.h:279
double MOSkappa
Definition: mosdefs.h:330
double ms_vbs
Definition: mosdefs.h:611
double MOSoxideCapFactor
Definition: mosdefs.h:282
double MOSmaxDriftVel
Definition: mosdefs.h:323
double MOSnarrowFactor
Definition: mosdefs.h:322
double MOSjunctionDepth
Definition: mosdefs.h:324
double MOSw
Definition: mosdefs.h:35
double ms_vds
Definition: mosdefs.h:610
double MOSoxideCap
Definition: mosdefs.h:96
double MOSalpha
Definition: mosdefs.h:332
double MOStPhi
Definition: mosdefs.h:49
double MOSfastSurfaceStateDensity
Definition: mosdefs.h:321
int MOSmode
Definition: mosdefs.h:32
double MOStVbi
Definition: mosdefs.h:59
double ms_vgd
Definition: mosdefs.h:614
double MOSeffectiveLength
Definition: mosdefs.h:91
double MOStheta
Definition: mosdefs.h:329
#define M2PCM2
Definition: moseq.c:29
#define CM2PM2
Definition: moseq.c:26
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
double MOSeq6 ( MOSmodel model,
MOSinstance here,
struct mosstuff ms 
)

Definition at line 1128 of file moseq.c.

1133 {
1134  /*
1135  * this block of code evaluates the drain current and its
1136  * derivatives using the n-th power MOS model and the
1137  * charges associated with the gate, channel and bulk for
1138  * mosfets
1139  *
1140  */
1141  double arg;
1142  double sarg;
1143  double vgon;
1144  double cdrain;
1145  double lvds, lvbs, lvgs;
1146  double idsat, lambda, vonbm;
1147  double vdst, vdst1, vdst2, ivdst1, vdstg;
1148 
1149  lvbs = (here->MOSmode == 1 ? ms->ms_vbs : ms->ms_vbd);
1150  lvds = ms->ms_vds * here->MOSmode;
1151  lvgs = (here->MOSmode == 1 ? ms->ms_vgs : ms->ms_vgd);
1152 
1153  if (lvbs <= 0 ) {
1154  sarg = sqrt(here->MOStPhi - lvbs);
1155  }
1156  else {
1157  sarg = sqrt(here->MOStPhi);
1158  sarg = sarg - lvbs/(sarg+sarg);
1159  sarg = MAX(0,sarg);
1160  }
1161  ms->ms_von = (here->MOStVbi*model->MOStype)+model->MOSgamma*sarg
1162  - model->MOSgamma1 * lvbs;
1163  - model->MOSsigma * lvds;
1164  vgon = lvgs - ms->ms_von;
1165 
1166  if (vgon <= 0) {
1167  /*
1168  * cutoff region
1169  */
1170  ms->ms_vdsat = 0;
1171  here->MOSgm = 0;
1172  here->MOSgds = 0;
1173  here->MOSgmbs = 0;
1174  cdrain = 0;
1175 
1176  }
1177  else {
1178  if (sarg <= 0) {
1179  arg = 0;
1180  }
1181  else {
1182  if (lvbs <= 0 ) {
1183  vonbm = model->MOSgamma1
1184  + model->MOSgamma/(sarg + sarg);
1185  }
1186  else {
1187  vonbm = model->MOSgamma1
1188  + .5*model->MOSgamma/sqrt(here->MOStPhi);
1189  }
1190  }
1191  sarg = log(vgon);
1192  ms->ms_vdsat = model->MOSkv * exp(sarg * model->MOSnv);
1193  idsat = here->MOSbeta * exp(sarg * model->MOSnc);
1194  lambda = model->MOSlamda0 - model->MOSlamda1*lvbs;
1195  /*
1196  * saturation region
1197  */
1198  cdrain = idsat*(1 + lambda*lvds);
1199  here->MOSgm = cdrain*model->MOSnc/vgon;
1200  here->MOSgds = here->MOSgm*model->MOSsigma + idsat*lambda;
1201  here->MOSgmbs = here->MOSgm*vonbm - idsat*model->MOSlamda1*lvds;
1202 
1203  if (ms->ms_vdsat > lvds) {
1204  /*
1205  * linear region
1206  */
1207  vdst = lvds/ms->ms_vdsat;
1208  vdst2 = (2 - vdst)*vdst;
1209  vdstg = -vdst*model->MOSnv/vgon;
1210  ivdst1 = cdrain*(2 - vdst - vdst);
1211  cdrain = cdrain*vdst2;
1212  here->MOSgm = here->MOSgm*vdst2 + ivdst1*vdstg;
1213  here->MOSgds = here->MOSgds*vdst2 +
1214  ivdst1*(1/ms->ms_vdsat + vdstg*model->MOSsigma);
1215  here->MOSgmbs = here->MOSgmbs*vdst2 +
1216  ivdst1*vdstg*vonbm;
1217  }
1218  }
1219  return (cdrain);
1220 }
double MOSbeta
Definition: mosdefs.h:95
double MOSgamma
Definition: mosdefs.h:286
double ms_von
Definition: mosdefs.h:607
double MOSgm
Definition: mosdefs.h:74
double ms_vbd
Definition: mosdefs.h:612
double MOSgmbs
Definition: mosdefs.h:73
#define MAX(a, b)
Definition: spdefs.h:135
if(TDesc==NULL)
Definition: cd.c:1326
double MOSgamma1
Definition: mosdefs.h:339
double MOSlamda0
Definition: mosdefs.h:341
double MOSgds
Definition: mosdefs.h:75
double MOSsigma
Definition: mosdefs.h:340
int MOStype
Definition: mosdefs.h:279
double ms_vbs
Definition: mosdefs.h:611
double MOSnc
Definition: mosdefs.h:338
double ms_vds
Definition: mosdefs.h:610
double MOStPhi
Definition: mosdefs.h:49
int MOSmode
Definition: mosdefs.h:32
double MOStVbi
Definition: mosdefs.h:59
double ms_vgd
Definition: mosdefs.h:614
double MOSkv
Definition: mosdefs.h:335
double MOSlamda1
Definition: mosdefs.h:342
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
double MOSnv
Definition: mosdefs.h:336