Jspice3
mosload.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Thomas L. Quarles
5  1989 Takayasu Sakurai
6  1993 Stephen R. Whiteley
7 ****************************************************************************/
8 
9 #include "spice.h"
10 #include <stdio.h>
11 #include <math.h>
12 #include "mosdefs.h"
13 #include "const.h"
14 #include "sperror.h"
15 #include "util.h"
16 #include "niext.h"
17 
18 /* some constants to avoid slow divides */
19 #define P66 .66666666666667
20 #define P33 .33333333333333
21 
22 
23 #ifdef __STDC__
24 static int mos_limiting(CKTcircuit*,MOSinstance*,struct mosstuff*);
25 static void mos_limvds(double*,double);
26 static int mos_pnjlim(double*,double,double,double);
27 static void mos_fetlim(double*,double,double);
28 static int mos_bypass(CKTcircuit*,MOSmodel*,MOSinstance*,struct mosstuff*);
29 static void mos_iv(CKTcircuit*,MOSmodel*,MOSinstance*,struct mosstuff*);
30 static void mos_cap(CKTcircuit*,MOSmodel*,MOSinstance*,struct mosstuff*);
31 static int mos_integ(CKTcircuit*,MOSinstance*,struct mosstuff*);
32 static void mos_load(CKTcircuit*,MOSmodel*,MOSinstance*,struct mosstuff*);
33 static void mos_load_dc(CKTcircuit*,MOSmodel*,MOSinstance*,struct mosstuff*);
34 #else
35 static int mos_limiting();
36 static void mos_limvds();
37 static int mos_pnjlim();
38 static void mos_fetlim();
39 static int mos_bypass();
40 static void mos_iv();
41 static void mos_cap();
42 static int mos_integ();
43 static void mos_load();
44 static void mos_load_dc();
45 #endif
46 
47 
48 int
49 MOSload(inModel,ckt)
50 
51 GENmodel *inModel;
52 CKTcircuit *ckt;
53 /*
54  * actually load the current value into the
55  * sparse matrix previously provided
56  */
57 {
58  MOSmodel *model = (MOSmodel *)inModel;
59  MOSinstance *here;
60  struct mosstuff ms;
61  int error;
62 
63  if (ckt->CKTmode & MODEINITFLOAT) {
64 
65  /* loop through all the MOS device models */
66  for ( ; model != NULL; model = model->MOSnextModel) {
67 
68  /* loop through all the instances of the model */
69  for (here = model->MOSinstances; here != NULL;
70  here = here->MOSnextInstance) {
71 
72  ms.ms_vt = CONSTKoverQ * here->MOStemp;
73 
74  if (model->MOStype > 0) {
75  ms.ms_vbs = *(ckt->CKTrhsOld + here->MOSbNode) -
76  *(ckt->CKTrhsOld + here->MOSsNodePrime);
77  ms.ms_vgs = *(ckt->CKTrhsOld + here->MOSgNode) -
78  *(ckt->CKTrhsOld + here->MOSsNodePrime);
79  ms.ms_vds = *(ckt->CKTrhsOld + here->MOSdNodePrime) -
80  *(ckt->CKTrhsOld + here->MOSsNodePrime);
81  ms.ms_von = here->MOSvon;
82  }
83  else {
84  ms.ms_vbs = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
85  *(ckt->CKTrhsOld + here->MOSbNode);
86  ms.ms_vgs = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
87  *(ckt->CKTrhsOld + here->MOSgNode);
88  ms.ms_vds = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
89  *(ckt->CKTrhsOld + here->MOSdNodePrime);
90  ms.ms_von = -here->MOSvon;
91  }
92  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
93  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
94  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
95 
96 #ifndef NOBYPASS
97  if (ckt->CKTbypass && mos_bypass(ckt,model,here,&ms)) {
98  continue;
99  }
100 #endif
101  (void)mos_limiting(ckt,here,&ms);
102  mos_iv(ckt,model,here,&ms);
103  if (ckt->CKTmode & MODETRAN) {
104  mos_cap(ckt,model,here,&ms);
105  error = mos_integ(ckt,here,&ms);
106  if (error) return(error);
107  mos_load(ckt,model,here,&ms);
108  }
109  else
110  mos_load_dc(ckt,model,here,&ms);
111  }
112  }
113  return (OK);
114  }
115 
116  if (ckt->CKTmode & MODEINITPRED) {
117  double xf1;
118  double xf2;
119 
120  xf2 = -ckt->CKTdelta/ckt->CKTdeltaOld[1];
121  xf1 = 1 - xf2;
122 
123  /* loop through all the MOS device models */
124  for ( ; model != NULL; model = model->MOSnextModel) {
125 
126  /* loop through all the instances of the model */
127  for (here = model->MOSinstances; here != NULL;
128  here = here->MOSnextInstance) {
129 
130  ms.ms_vt = CONSTKoverQ * here->MOStemp;
131 
132  /* predictor step */
133  ms.ms_vbs = xf1* *(ckt->CKTstate1 + here->MOSvbs)
134  + xf2* *(ckt->CKTstate2 + here->MOSvbs);
135 
136  ms.ms_vgs = xf1* *(ckt->CKTstate1 + here->MOSvgs)
137  + xf2* *(ckt->CKTstate2 + here->MOSvgs);
138 
139  ms.ms_vds = xf1* *(ckt->CKTstate1 + here->MOSvds)
140  + xf2* *(ckt->CKTstate2 + here->MOSvds);
141 
142  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
143  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
144  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
145  if (model->MOStype > 0)
146  ms.ms_von = here->MOSvon;
147  else
148  ms.ms_von = -here->MOSvon;
149 
150  *(ckt->CKTstate0 + here->MOSvbs) =
151  *(ckt->CKTstate1 + here->MOSvbs);
152  *(ckt->CKTstate0 + here->MOSvgs) =
153  *(ckt->CKTstate1 + here->MOSvgs);
154  *(ckt->CKTstate0 + here->MOSvds) =
155  *(ckt->CKTstate1 + here->MOSvds);
156  *(ckt->CKTstate0 + here->MOSvbd) =
157  *(ckt->CKTstate0 + here->MOSvbs)-
158  *(ckt->CKTstate0 + here->MOSvds);
159 
160  (void)mos_limiting(ckt,here,&ms);
161 
162  mos_iv(ckt,model,here,&ms);
163  if (ckt->CKTmode & MODETRAN) {
164  mos_cap(ckt,model,here,&ms);
165  error = mos_integ(ckt,here,&ms);
166  if (error) return(error);
167  mos_load(ckt,model,here,&ms);
168  }
169  else
170  mos_load_dc(ckt,model,here,&ms);
171 
172  }
173  }
174  return (OK);
175  }
176 
177  if (ckt->CKTmode & MODEINITFIX) {
178 
179  /* loop through all the MOS device models */
180  for ( ; model != NULL; model = model->MOSnextModel) {
181 
182  /* loop through all the instances of the model */
183  for (here = model->MOSinstances; here != NULL;
184  here = here->MOSnextInstance) {
185 
186  ms.ms_vt = CONSTKoverQ * here->MOStemp;
187 
188  if (here->MOSoff) {
189  ms.ms_vbs = 0;
190  ms.ms_vgs = 0;
191  ms.ms_vds = 0;
192  ms.ms_vbd = 0;
193  ms.ms_vgd = 0;
194  ms.ms_vgb = 0;
195  }
196  else {
197  if (model->MOStype > 0) {
198  ms.ms_vbs = *(ckt->CKTrhsOld + here->MOSbNode) -
199  *(ckt->CKTrhsOld + here->MOSsNodePrime);
200  ms.ms_vgs = *(ckt->CKTrhsOld + here->MOSgNode) -
201  *(ckt->CKTrhsOld + here->MOSsNodePrime);
202  ms.ms_vds = *(ckt->CKTrhsOld + here->MOSdNodePrime) -
203  *(ckt->CKTrhsOld + here->MOSsNodePrime);
204  }
205  else {
206  ms.ms_vbs = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
207  *(ckt->CKTrhsOld + here->MOSbNode);
208  ms.ms_vgs = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
209  *(ckt->CKTrhsOld + here->MOSgNode);
210  ms.ms_vds = *(ckt->CKTrhsOld + here->MOSsNodePrime) -
211  *(ckt->CKTrhsOld + here->MOSdNodePrime);
212  }
213  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
214  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
215  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
216  }
217 
218  if (model->MOStype > 0)
219  ms.ms_von = here->MOSvon;
220  else
221  ms.ms_von = -here->MOSvon;
222 
223 #ifndef NOBYPASS
224  if (!here->MOSoff)
225  if (ckt->CKTbypass && mos_bypass(ckt,model,here,&ms)) {
226  continue;
227  }
228 #endif
229  if (!here->MOSoff && mos_limiting(ckt,here,&ms))
230  ckt->CKTnoncon++;
231 
232  mos_iv(ckt,model,here,&ms);
233  mos_load_dc(ckt,model,here,&ms);
234  }
235  }
236  return (OK);
237  }
238 
239  if (ckt->CKTmode & MODEINITTRAN) {
240 
241  /* loop through all the MOS device models */
242  for ( ; model != NULL; model = model->MOSnextModel) {
243 
244  /* loop through all the instances of the model */
245  for (here = model->MOSinstances; here != NULL;
246  here = here->MOSnextInstance) {
247 
248  ms.ms_vt = CONSTKoverQ * here->MOStemp;
249 
250  ms.ms_vbs = *(ckt->CKTstate1 + here->MOSvbs);
251  ms.ms_vgs = *(ckt->CKTstate1 + here->MOSvgs);
252  ms.ms_vds = *(ckt->CKTstate1 + here->MOSvds);
253  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
254  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
255  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
256 
257  mos_iv(ckt,model,here,&ms);
258  mos_cap(ckt,model,here,&ms);
259  error = mos_integ(ckt,here,&ms);
260  if (error) return(error);
261  mos_load(ckt,model,here,&ms);
262  }
263  }
264  return (OK);
265  }
266 
267  if (ckt->CKTmode & MODEINITSMSIG) {
268 
269  /* loop through all the MOS device models */
270  for ( ; model != NULL; model = model->MOSnextModel) {
271 
272  /* loop through all the instances of the model */
273  for (here = model->MOSinstances; here != NULL;
274  here = here->MOSnextInstance) {
275 
276  ms.ms_vt = CONSTKoverQ * here->MOStemp;
277  ms.ms_vbs = *(ckt->CKTstate0 + here->MOSvbs);
278  ms.ms_vgs = *(ckt->CKTstate0 + here->MOSvgs);
279  ms.ms_vds = *(ckt->CKTstate0 + here->MOSvds);
280  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
281  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
282  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
283 
284  mos_iv(ckt,model,here,&ms);
285  mos_cap(ckt,model,here,&ms);
286  }
287  }
288  return (OK);
289  }
290 
291  if ((ckt->CKTmode & MODEINITJCT) &&
292  (ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC) ) {
293 
294  /* loop through all the MOS device models */
295  for ( ; model != NULL; model = model->MOSnextModel) {
296 
297  /* loop through all the instances of the model */
298  for (here = model->MOSinstances; here != NULL;
299  here = here->MOSnextInstance) {
300 
301  ms.ms_vt = CONSTKoverQ * here->MOStemp;
302  if (model->MOStype > 0) {
303  ms.ms_vds = here->MOSicVDS;
304  ms.ms_vgs = here->MOSicVGS;
305  ms.ms_vbs = here->MOSicVBS;
306  }
307  else {
308  ms.ms_vds = -here->MOSicVDS;
309  ms.ms_vgs = -here->MOSicVGS;
310  ms.ms_vbs = -here->MOSicVBS;
311  }
312  *(ckt->CKTstate0 + here->MOSvds) = ms.ms_vds;
313  *(ckt->CKTstate0 + here->MOSvgs) = ms.ms_vgs;
314  *(ckt->CKTstate0 + here->MOSvbs) = ms.ms_vbs;
315  }
316  }
317  return (OK);
318  }
319 
320  if (ckt->CKTmode & MODEINITJCT) {
321 
322  /* loop through all the MOS device models */
323  for ( ; model != NULL; model = model->MOSnextModel) {
324 
325  /* loop through all the instances of the model */
326  for (here = model->MOSinstances; here != NULL;
327  here = here->MOSnextInstance) {
328 
329  ms.ms_vt = CONSTKoverQ * here->MOStemp;
330 
331  if (here->MOSoff) {
332  ms.ms_vbs = 0;
333  ms.ms_vgs = 0;
334  ms.ms_vds = 0;
335  ms.ms_vbd = 0;
336  ms.ms_vgd = 0;
337  ms.ms_vgb = 0;
338  }
339  else {
340  if ((here->MOSicVDS == 0) &&
341  (here->MOSicVGS == 0) &&
342  (here->MOSicVBS == 0)) {
343  ms.ms_vbs = -1;
344  if (model->MOStype > 0)
345  ms.ms_vgs = here->MOStVto;
346  else
347  ms.ms_vgs = -here->MOStVto;
348  ms.ms_vds = 0;
349  }
350  else {
351  if (model->MOStype > 0) {
352  ms.ms_vds = here->MOSicVDS;
353  ms.ms_vgs = here->MOSicVGS;
354  ms.ms_vbs = here->MOSicVBS;
355  }
356  else {
357  ms.ms_vds = -here->MOSicVDS;
358  ms.ms_vgs = -here->MOSicVGS;
359  ms.ms_vbs = -here->MOSicVBS;
360  }
361  }
362  ms.ms_vbd = ms.ms_vbs - ms.ms_vds;
363  ms.ms_vgd = ms.ms_vgs - ms.ms_vds;
364  ms.ms_vgb = ms.ms_vgs - ms.ms_vbs;
365  }
366  mos_iv(ckt,model,here,&ms);
367  mos_load_dc(ckt,model,here,&ms);
368  }
369  }
370  }
371  return (OK);
372 }
373 
374 
375 static int
376 mos_limiting(ckt,here,ms)
377 
378 CKTcircuit *ckt;
379 MOSinstance *here;
380 struct mosstuff *ms;
381 {
382  int check;
383  double vgdo;
384  /*
385  * limiting
386  * We want to keep device voltages from changing
387  * so fast that the exponentials churn out overflows
388  * and similar rudeness
389  */
390 
391  if (*(ckt->CKTstate0 + here->MOSvds) >= 0) {
392  mos_fetlim(&ms->ms_vgs,*(ckt->CKTstate0 + here->MOSvgs),ms->ms_von);
393  ms->ms_vds = ms->ms_vgs - ms->ms_vgd;
394  mos_limvds(&ms->ms_vds,*(ckt->CKTstate0 + here->MOSvds));
395  ms->ms_vgd = ms->ms_vgs - ms->ms_vds;
396  }
397  else {
398  vgdo = *(ckt->CKTstate0 + here->MOSvgs) -
399  *(ckt->CKTstate0 + here->MOSvds);
400  mos_fetlim(&ms->ms_vgd,vgdo,ms->ms_von);
401  ms->ms_vds = ms->ms_vgs - ms->ms_vgd;
402  if (!ckt->CKTfixLimit) {
403  ms->ms_vds = -ms->ms_vds;
404  mos_limvds(&ms->ms_vds,-(*(ckt->CKTstate0 + here->MOSvds)));
405  ms->ms_vds = -ms->ms_vds;
406  }
407  ms->ms_vgs = ms->ms_vgd + ms->ms_vds;
408  }
409  if (ms->ms_vds >= 0) {
410  check = mos_pnjlim(&ms->ms_vbs,*(ckt->CKTstate0 + here->MOSvbs),
411  ms->ms_vt,here->MOSsourceVcrit);
412  ms->ms_vbd = ms->ms_vbs - ms->ms_vds;
413  }
414  else {
415  check = mos_pnjlim(&ms->ms_vbd,*(ckt->CKTstate0 + here->MOSvbd),
416  ms->ms_vt,here->MOSdrainVcrit);
417  ms->ms_vbs = ms->ms_vbd + ms->ms_vds;
418  }
419  ms->ms_vgb = ms->ms_vgs - ms->ms_vbs;
420  return (check);
421 }
422 
423 
424 static void
425 mos_limvds(vnew,vold)
426 
427 /*
428  * limit the per-iteration change of VDS
429  */
430 double *vnew;
431 double vold;
432 {
433  double vtmp;
434  double vn;
435 
436  vn = *vnew;
437  if (vold >= 3.5) {
438  if (vn > vold) {
439  vtmp = 3*vold + 2;
440  if (vn > vtmp)
441  *vnew = vtmp;
442  }
443  else {
444  if (vn < 2)
445  *vnew = 2;
446  }
447  }
448  else {
449  if (vn > vold) {
450  if (vn > 4)
451  *vnew = 4;
452  }
453  else {
454  if (vn < -.5)
455  *vnew = -.5;
456  }
457  }
458 }
459 
460 
461 static int
462 mos_pnjlim(vnew,vold,vt,vcrit)
463 
464 /*
465  * limit the per-iteration change of PN junction voltages
466  */
467 double *vnew;
468 double vold;
469 double vt;
470 double vcrit;
471 {
472  double arg;
473  double vn;
474 
475  vn = *vnew;
476  if ((vn > vcrit) && (FABS(vn - vold) > (vt + vt))) {
477  if (vold > 0) {
478  arg = 1 + (vn - vold)/vt;
479  if (arg > 0) {
480  *vnew = vold + vt*log(arg);
481  }
482  else {
483  *vnew = vcrit;
484  }
485  }
486  else {
487  *vnew = vt*log(vn/vt);
488  }
489  return (1);
490  }
491  return (0);
492 }
493 
494 
495 static void
496 mos_fetlim(vnew,vold,vto)
497 
498 /*
499  * limit the per-iteration change of FET voltages
500  */
501 double *vnew;
502 double vold;
503 double vto;
504 {
505  double vtsthi;
506  double vtstlo;
507  double vtox;
508  double delv;
509  double vtemp;
510  double vn;
511 
512  vn = *vnew;
513  vtsthi = FABS(2*(vold - vto)) + 2;
514  vtstlo = .5*vtsthi + 2;
515  vtox = vto + 3.5;
516  delv = vn - vold;
517 
518  if (vold >= vto) {
519  if (vold >= vtox) {
520  if (delv <= 0) {
521  /* going off */
522  if (vn >= vtox) {
523  if (-delv > vtstlo) {
524  *vnew = vold - vtstlo;
525  }
526  }
527  else {
528  vtemp = vto + 2;
529  if (vn < vtemp)
530  *vnew = vtemp;
531  }
532  }
533  else {
534  /* staying on */
535  if (delv >= vtsthi) {
536  *vnew = vold + vtsthi;
537  }
538  }
539  }
540  else {
541  /* middle region */
542  if (delv <= 0) {
543  /* decreasing */
544  vtemp = vto - .5;
545  if (vn < vtemp)
546  *vnew = vtemp;
547  }
548  else {
549  /* increasing */
550  vtemp = vto + 4;
551  if (vn > vtemp)
552  *vnew = vtemp;
553  }
554  }
555  }
556  else {
557  /* off */
558  if (delv <= 0) {
559  if (-delv > vtsthi) {
560  *vnew = vold - vtsthi;
561  }
562  }
563  else {
564  vtemp = vto + .5;
565  if (vn <= vtemp) {
566  if (delv > vtstlo) {
567  *vnew = vold + vtstlo;
568  }
569  }
570  else {
571  *vnew = vtemp;
572  }
573  }
574  }
575 }
576 
577 
578 #ifndef NOBYPASS
579 
580 static int
581 mos_bypass(ckt,model,here,ms)
582 
583 CKTcircuit* ckt;
584 MOSmodel *model;
585 MOSinstance *here;
586 struct mosstuff *ms;
587 {
588  double delvbs;
589  double delvbd;
590  double delvgs;
591  double delvds;
592  double delvgd;
593  double cdhat;
594  double cbhat;
595  double A1, A2, A3;
596  int error;
597 
598  delvbs = ms->ms_vbs - *(ckt->CKTstate0 + here->MOSvbs);
599  delvgs = ms->ms_vgs - *(ckt->CKTstate0 + here->MOSvgs);
600  delvds = ms->ms_vds - *(ckt->CKTstate0 + here->MOSvds);
601  delvbd = ms->ms_vbd - *(ckt->CKTstate0 + here->MOSvbd);
602  delvgd = ms->ms_vgd - (*(ckt->CKTstate0 + here->MOSvgs) -
603  *(ckt->CKTstate0 + here->MOSvds));
604 
605  cbhat = here->MOScbs + here->MOScbd +
606  here->MOSgbd*delvbd + here->MOSgbs*delvbs;
607 
608  /* now lets see if we can bypass (ugh) */
609 
610  A1 = FABS(cbhat);
611  A2 = here->MOScbs + here->MOScbd;
612  A2 = FABS(A2);
613  A3 = MAX(A1,A2) + ckt->CKTabstol;
614  A1 = cbhat - (here->MOScbs + here->MOScbd);
615  if (FABS(A1) >= ckt->CKTreltol*A3)
616  return (0);
617 
618  A1 = FABS(ms->ms_vbs);
619  A2 = FABS(*(ckt->CKTstate0 + here->MOSvbs));
620  if (FABS(delvbs) >= (ckt->CKTreltol*MAX(A1,A2) + ckt->CKTvoltTol))
621  return (0);
622 
623  A1 = FABS(ms->ms_vbd);
624  A2 = FABS(*(ckt->CKTstate0 + here->MOSvbd));
625  if (FABS(delvbd) >= (ckt->CKTreltol*MAX(A1,A2) + ckt->CKTvoltTol))
626  return (0);
627 
628  A1 = FABS(ms->ms_vgs);
629  A2 = FABS(*(ckt->CKTstate0 + here->MOSvgs));
630  if (FABS(delvgs) >= (ckt->CKTreltol*MAX(A1,A2) + ckt->CKTvoltTol))
631  return (0);
632 
633  A1 = FABS(ms->ms_vds);
634  A2 = FABS(*(ckt->CKTstate0 + here->MOSvds));
635  if (FABS(delvds) >= (ckt->CKTreltol*MAX(A1,A2) + ckt->CKTvoltTol))
636  return (0);
637 
638  if (here->MOSmode >= 0) {
639  cdhat = here->MOScd -
640  here->MOSgbd*delvbd + here->MOSgmbs*delvbs +
641  here->MOSgm*delvgs + here->MOSgds*delvds;
642  }
643  else {
644  cdhat = here->MOScd +
645  (here->MOSgmbs - here->MOSgbd)*delvbd -
646  here->MOSgm*delvgd + here->MOSgds*delvds;
647  }
648 
649  A1 = cdhat - here->MOScd;
650  A2 = FABS(cdhat);
651  A3 = FABS(here->MOScd);
652  if ((FABS(A1) >= ckt->CKTreltol*MAX(A2,A3) + ckt->CKTabstol))
653  return (0);
654 
655  /* bypass code */
656  /* nothing interesting has changed since last
657  * iteration on this device, so we just
658  * copy all the values computed last iteration
659  * out and keep going
660  */
661  ms->ms_vbs = *(ckt->CKTstate0 + here->MOSvbs);
662  ms->ms_vgs = *(ckt->CKTstate0 + here->MOSvgs);
663  ms->ms_vds = *(ckt->CKTstate0 + here->MOSvds);
664  ms->ms_vbd = *(ckt->CKTstate0 + here->MOSvbd);
665  ms->ms_vgd = ms->ms_vgs - ms->ms_vds;
666  ms->ms_vgb = ms->ms_vgs - ms->ms_vbs;
667 
668  ms->ms_cdrain = here->MOSmode * (here->MOScd + here->MOScbd);
669 
670  if (ckt->CKTmode & MODETRAN) {
671 
672  ms->ms_capgs = *(ckt->CKTstate0 + here->MOScapgs) +
673  *(ckt->CKTstate1 + here->MOScapgs) +
675 
676  ms->ms_capgd = *(ckt->CKTstate0 + here->MOScapgd) +
677  *(ckt->CKTstate1 + here->MOScapgd) +
679 
680  ms->ms_capgb = *(ckt->CKTstate0 + here->MOScapgb) +
681  *(ckt->CKTstate1 + here->MOScapgb) +
682  here->MOSgateBulkOverlapCap;
683 
684  /*
685  * calculate equivalent conductances and currents for
686  * Meyer's capacitors
687  */
688  NI_INTEG(ckt,ms->ms_gcgs,ms->ms_ceqgs,ms->ms_capgs,here->MOSqgs);
689 
690  NI_INTEG(ckt,ms->ms_gcgd,ms->ms_ceqgd,ms->ms_capgd,here->MOSqgd);
691 
692  NI_INTEG(ckt,ms->ms_gcgb,ms->ms_ceqgb,ms->ms_capgb,here->MOSqgb);
693 
694  ms->ms_ceqgs +=
695  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgs)
696  - ms->ms_gcgs*ms->ms_vgs;
697  ms->ms_ceqgd +=
698  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgd)
699  - ms->ms_gcgd*ms->ms_vgd;
700  ms->ms_ceqgb +=
701  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgb)
702  - ms->ms_gcgb*ms->ms_vgb;
703 
704  mos_load(ckt,model,here,ms);
705  }
706  else
707  mos_load_dc(ckt,model,here,ms);
708 
709  return (1);
710 }
711 #endif /*NOBYPASS*/
712 
713 
714 static void
715 mos_iv(ckt,model,here,ms)
716 
717 CKTcircuit* ckt;
718 MOSmodel *model;
719 MOSinstance *here;
720 struct mosstuff *ms;
721 {
722  double evb;
723 
724  /* initialize Meyer parameters */
725  ms->ms_gcgs = 0;
726  ms->ms_ceqgs = 0;
727  ms->ms_gcgd = 0;
728  ms->ms_ceqgd = 0;
729  ms->ms_gcgb = 0;
730  ms->ms_ceqgb = 0;
731 
732  /* bulk-source and bulk-drain doides
733  * here we just evaluate the ideal diode current and the
734  * correspoinding derivative (conductance).
735  */
736 
737  if (ms->ms_vbs <= 0) {
738  here->MOSgbs = here->MOStSourceSatCur/ms->ms_vt;
739  here->MOScbs = here->MOSgbs*ms->ms_vbs;
740  here->MOSgbs += ckt->CKTgmin;
741  }
742  else {
743  evb = exp(ms->ms_vbs/ms->ms_vt);
744  here->MOSgbs =
745  here->MOStSourceSatCur*evb/ms->ms_vt + ckt->CKTgmin;
746  here->MOScbs = here->MOStSourceSatCur * (evb-1);
747  }
748  if (ms->ms_vbd <= 0) {
749  here->MOSgbd = here->MOStDrainSatCur/ms->ms_vt;
750  here->MOScbd = here->MOSgbd *ms->ms_vbd;
751  here->MOSgbd += ckt->CKTgmin;
752  }
753  else {
754  evb = exp(ms->ms_vbd/ms->ms_vt);
755  here->MOSgbd =
756  here->MOStDrainSatCur*evb/ms->ms_vt + ckt->CKTgmin;
757  here->MOScbd = here->MOStDrainSatCur *(evb-1);
758  }
759 
760 
761  /* level 8, CryoMOS by Luong Huynh 1/19/95
762  * cryo-MOSFETs have zero diode currents and diode conductances
763  * at normal operating voltage
764  */
765  if (model->MOSlevel == 8) {
766  here->MOScbs = 0;
767  here->MOSgbs = 0;
768  here->MOScbd = 0;
769  here->MOSgbd = 0;
770  }
771  /*****/
772 
773 
774  /* now to determine whether the user was able to correctly
775  * identify the source and drain of his device
776  */
777  if (ms->ms_vds >= 0) {
778  /* normal mode */
779  here->MOSmode = 1;
780  }
781  else {
782  /* inverse mode */
783  here->MOSmode = -1;
784  }
785 
786  if (model->MOSlevel == 1)
787  ms->ms_cdrain = MOSeq1(model,here,ms);
788  else if (model->MOSlevel == 2)
789  ms->ms_cdrain = MOSeq2(model,here,ms);
790  else if (model->MOSlevel == 3)
791  ms->ms_cdrain = MOSeq3(model,here,ms);
792 
793  /* level 8, CryoMOS by Luong Huynh 1/19/95 */
794  else if (model->MOSlevel == 8)
795  ms->ms_cdrain = cryoMOSeq(model,here,ms);
796  /**/
797 
798  else
799  ms->ms_cdrain = MOSeq6(model,here,ms);
800 
801  /* now deal with n vs p polarity */
802 
803  if (model->MOStype > 0) {
804  here->MOSvon = ms->ms_von;
805  here->MOSvdsat = ms->ms_vdsat;
806  }
807  else {
808  here->MOSvon = -ms->ms_von;
809  here->MOSvdsat = -ms->ms_vdsat;
810  }
811  if (here->MOSmode > 0)
812  here->MOScd = ms->ms_cdrain - here->MOScbd;
813  else
814  here->MOScd = -ms->ms_cdrain - here->MOScbd;
815 }
816 
817 
818 static void
819 mos_cap(ckt,model,here,ms)
820 
821 CKTcircuit* ckt;
822 MOSmodel *model;
823 MOSinstance *here;
824 struct mosstuff *ms;
825 {
826  double arg;
827  double sarg;
828  double sargsw;
829  double vgx;
830  double vgy;
831  double vxy;
832  double vgxt;
833  double vddif1;
834  double vddif2;
835  double *px;
836  double *py;
837 
838 
839  /*
840  * now we do the hard part of the bulk-drain and bulk-source
841  * diode - we evaluate the non-linear capacitance and
842  * charge
843  *
844  * the basic equations are not hard, but the implementation
845  * is somewhat long in an attempt to avoid log/exponential
846  * evaluations
847  *
848  * charge storage elements
849  *
850  * bulk-drain and bulk-source depletion capacitances
851  */
852 
853  if (here->MOSCbs != 0 || here->MOSCbssw != 0) {
854  if (ms->ms_vbs < here->MOStDepCap) {
855  arg = 1 - ms->ms_vbs/here->MOStBulkPot;
856 
857  SARGS(arg,model->MOSbulkJctBotGradingCoeff,
858  model->MOSbulkJctSideGradingCoeff,sarg,sargsw);
859 
860  *(ckt->CKTstate0 + here->MOSqbs) = here->MOStBulkPot *
861  ( here->MOSCbs *
862  (1 - arg*sarg)/(1 - model->MOSbulkJctBotGradingCoeff)
863  + here->MOSCbssw *
864  (1 - arg*sargsw)/(1 - model->MOSbulkJctSideGradingCoeff) );
865 
866  here->MOScapbs = here->MOSCbs*sarg + here->MOSCbssw*sargsw;
867  }
868  else {
869  *(ckt->CKTstate0 + here->MOSqbs) = here->MOSf4s +
870  ms->ms_vbs*(here->MOSf2s + .5*ms->ms_vbs*here->MOSf3s);
871  here->MOScapbs = here->MOSf2s + here->MOSf3s*ms->ms_vbs;
872  }
873  }
874  else {
875  *(ckt->CKTstate0 + here->MOSqbs) = 0;
876  here->MOScapbs = 0;
877  }
878 
879  if (here->MOSCbd != 0 || here->MOSCbdsw != 0) {
880  if (ms->ms_vbd < here->MOStDepCap) {
881  arg = 1 - ms->ms_vbd/here->MOStBulkPot;
882 
883  SARGS(arg,model->MOSbulkJctBotGradingCoeff,
884  model->MOSbulkJctSideGradingCoeff,sarg,sargsw);
885 
886  *(ckt->CKTstate0 + here->MOSqbd) = here->MOStBulkPot *
887  ( here->MOSCbd *
888  (1 - arg*sarg)/(1 - model->MOSbulkJctBotGradingCoeff)
889  + here->MOSCbdsw *
890  (1 - arg*sargsw)/(1 - model->MOSbulkJctSideGradingCoeff) );
891 
892  here->MOScapbd = here->MOSCbd*sarg + here->MOSCbdsw*sargsw;
893  }
894  else {
895  *(ckt->CKTstate0 + here->MOSqbd) = here->MOSf4d +
896  ms->ms_vbd*(here->MOSf2d + .5*ms->ms_vbd*here->MOSf3d);
897  here->MOScapbd = here->MOSf2d + ms->ms_vbd*here->MOSf3d;
898  }
899  }
900  else {
901  *(ckt->CKTstate0 + here->MOSqbd) = 0;
902  here->MOScapbd = 0;
903  }
904 
905  /*
906  * calculate meyer's capacitors
907  *
908  * new cmeyer - this just evaluates at the current time,
909  * expects you to remember values from previous time
910  * returns 1/2 of non-constant portion of capacitance
911  * you must add in the other half from previous time
912  * and the constant part
913  */
914 
915  if (here->MOSmode > 0) {
916  vgx = ms->ms_vgs;
917  vgy = ms->ms_vgd;
918  px = (ckt->CKTstate0 + here->MOScapgs);
919  py = (ckt->CKTstate0 + here->MOScapgd);
920  }
921  else {
922  vgx = ms->ms_vgd;
923  vgy = ms->ms_vgs;
924  px = (ckt->CKTstate0 + here->MOScapgd);
925  py = (ckt->CKTstate0 + here->MOScapgs);
926  }
927 /*
928  DEVqmeyer (vgx,vgy,ms->ms_von,ms->ms_vdsat,px,py,
929  (ckt->CKTstate0 + here->MOScapgb),
930  here->MOStPhi,here->MOSoxideCap);
931 */
932 
933  vgxt = vgx - ms->ms_von;
934  if (vgxt <= -here->MOStPhi) {
935  *(ckt->CKTstate0 + here->MOScapgb) = .5*here->MOSoxideCap;
936  *px = 0;
937  *py = 0;
938  }
939  else if (vgxt <= -.5*here->MOStPhi) {
940  *(ckt->CKTstate0 + here->MOScapgb) =
941  -.5*vgxt*here->MOSoxideCap/here->MOStPhi;
942  *px = 0;
943  *py = 0;
944  }
945  else if (vgxt <= 0) {
946  *(ckt->CKTstate0 + here->MOScapgb) =
947  -.5*vgxt*here->MOSoxideCap/here->MOStPhi;
948  *px = P66*vgxt*here->MOSoxideCap/here->MOStPhi +
949  P33*here->MOSoxideCap;
950  *py = 0;
951  }
952  else {
953  vxy = vgx - vgy;
954  if (ms->ms_vdsat <= vxy) {
955  *px = P33*here->MOSoxideCap;
956  *py = 0;
957  }
958  else {
959  vddif1 = ms->ms_vdsat - vxy;
960  vddif2 = vddif1 + ms->ms_vdsat;
961  vddif2 = 1.0/(vddif2*vddif2);
962  *py = here->MOSoxideCap*
963  P33*(1.0 - ms->ms_vdsat*ms->ms_vdsat*vddif2);
964  *px = here->MOSoxideCap*
965  P33*(1.0 - vddif1*vddif1*vddif2);
966  }
967  *(ckt->CKTstate0 + here->MOScapgb) = 0;
968  }
969 
970  /* level 8, CryoMOS by Luong Huynh 1/19/95
971  * bulk caps are zero due to freeze out
972  */
973  if (model->MOSlevel == 8) {
974  *(ckt->CKTstate0 + here->MOScapgb) = 0;
975  here->MOScapbs = 0;
976  here->MOScapbd = 0;
977  }
978  /*****/
979 
980  if (ckt->CKTmode & (MODEINITTRAN|MODEINITSMSIG)) {
981 
982  *(ckt->CKTstate1 + here->MOScapgs) =
983  *(ckt->CKTstate0 + here->MOScapgs);
984  *(ckt->CKTstate1 + here->MOScapgd) =
985  *(ckt->CKTstate0 + here->MOScapgd);
986  *(ckt->CKTstate1 + here->MOScapgb) =
987  *(ckt->CKTstate0 + here->MOScapgb);
988 
989  ms->ms_capgs = *(ckt->CKTstate0 + here->MOScapgs) +
990  *(ckt->CKTstate0 + here->MOScapgs) +
992  ms->ms_capgd = *(ckt->CKTstate0 + here->MOScapgd) +
993  *(ckt->CKTstate0 + here->MOScapgd) +
995  ms->ms_capgb = *(ckt->CKTstate0 + here->MOScapgb) +
996  *(ckt->CKTstate0 + here->MOScapgb) +
997  here->MOSgateBulkOverlapCap;
998 
999  *(ckt->CKTstate0 + here->MOSqgs) = ms->ms_capgs*ms->ms_vgs;
1000  *(ckt->CKTstate0 + here->MOSqgd) = ms->ms_capgd*ms->ms_vgd;
1001  *(ckt->CKTstate0 + here->MOSqgb) = ms->ms_capgb*ms->ms_vgb;
1002 
1003  *(ckt->CKTstate1 + here->MOSqbd) =
1004  *(ckt->CKTstate0 + here->MOSqbd);
1005  *(ckt->CKTstate1 + here->MOSqbs) =
1006  *(ckt->CKTstate0 + here->MOSqbs);
1007  *(ckt->CKTstate1 + here->MOSqgs) =
1008  *(ckt->CKTstate0 + here->MOSqgs);
1009  *(ckt->CKTstate1 + here->MOSqgd) =
1010  *(ckt->CKTstate0 + here->MOSqgd);
1011  *(ckt->CKTstate1 + here->MOSqgb) =
1012  *(ckt->CKTstate0 + here->MOSqgb);
1013  }
1014  else {
1015 
1016  ms->ms_capgs = *(ckt->CKTstate0 + here->MOScapgs) +
1017  *(ckt->CKTstate1 + here->MOScapgs) +
1019  ms->ms_capgd = *(ckt->CKTstate0 + here->MOScapgd) +
1020  *(ckt->CKTstate1 + here->MOScapgd) +
1021  here->MOSgateDrainOverlapCap;
1022  ms->ms_capgb = *(ckt->CKTstate0 + here->MOScapgb) +
1023  *(ckt->CKTstate1 + here->MOScapgb) +
1024  here->MOSgateBulkOverlapCap;
1025 
1026  vgx = *(ckt->CKTstate1 + here->MOSvgs);
1027  vgy = vgx - *(ckt->CKTstate1 + here->MOSvds);
1028  vxy = vgx - *(ckt->CKTstate1 + here->MOSvbs);
1029 
1030  *(ckt->CKTstate0 + here->MOSqgs) =
1031  (ms->ms_vgs - vgx)*ms->ms_capgs +
1032  *(ckt->CKTstate1 + here->MOSqgs);
1033  *(ckt->CKTstate0 + here->MOSqgd) =
1034  (ms->ms_vgd - vgy)*ms->ms_capgd +
1035  *(ckt->CKTstate1 + here->MOSqgd);
1036  *(ckt->CKTstate0 + here->MOSqgb) =
1037  (ms->ms_vgb - vxy)*ms->ms_capgb +
1038  *(ckt->CKTstate1 + here->MOSqgb);
1039  }
1040 }
1041 
1042 
1043 static int
1044 mos_integ(ckt,here,ms)
1045 
1046 CKTcircuit *ckt;
1047 MOSinstance *here;
1048 struct mosstuff *ms;
1049 {
1050  double geq;
1051  double ceq;
1052  int error;
1053 
1054  /*
1055  * calculate equivalent conductances and currents for
1056  * depletion capacitors
1057  */
1058  NI_INTEG(ckt,geq,ceq,here->MOScapbd,here->MOSqbd);
1059 
1060  here->MOSgbd += geq;
1061  here->MOScbd += *(ckt->CKTstate0 + here->MOScqbd);
1062  here->MOScd -= *(ckt->CKTstate0 + here->MOScqbd);
1063 
1064  NI_INTEG(ckt,geq,ceq,here->MOScapbs,here->MOSqbs);
1065 
1066  here->MOSgbs += geq;
1067  here->MOScbs += *(ckt->CKTstate0 + here->MOScqbs);
1068 
1069  if (ms->ms_capgs == 0)
1070  *(ckt->CKTstate0 + here->MOScqgs) = 0;
1071  if (ms->ms_capgd == 0)
1072  *(ckt->CKTstate0 + here->MOScqgd) = 0;
1073  if (ms->ms_capgb == 0)
1074  *(ckt->CKTstate0 + here->MOScqgb) = 0;
1075 
1076  /*
1077  * calculate equivalent conductances and currents for
1078  * Meyer's capacitors
1079  */
1080  NI_INTEG(ckt,ms->ms_gcgs,ms->ms_ceqgs,ms->ms_capgs,here->MOSqgs);
1081 
1082  NI_INTEG(ckt,ms->ms_gcgd,ms->ms_ceqgd,ms->ms_capgd,here->MOSqgd);
1083 
1084  NI_INTEG(ckt,ms->ms_gcgb,ms->ms_ceqgb,ms->ms_capgb,here->MOSqgb);
1085 
1086  ms->ms_ceqgs +=
1087  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgs)
1088  - ms->ms_gcgs*ms->ms_vgs;
1089  ms->ms_ceqgd +=
1090  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgd)
1091  - ms->ms_gcgd*ms->ms_vgd;
1092  ms->ms_ceqgb +=
1093  ckt->CKTag[0]* *(ckt->CKTstate0 + here->MOSqgb)
1094  - ms->ms_gcgb*ms->ms_vgb;
1095 
1096  return (OK);
1097 }
1098 
1099 
1100 static void
1101 mos_load(ckt,model,here,ms)
1102 
1103 CKTcircuit* ckt;
1104 MOSmodel *model;
1105 MOSinstance *here;
1106 struct mosstuff *ms;
1107 {
1108  double ceqbs;
1109  double ceqbd;
1110  double cdreq;
1111  double dcon;
1112  double scon;
1113 
1114  /* save things away for next time */
1115  *(ckt->CKTstate0 + here->MOSvbs) = ms->ms_vbs;
1116  *(ckt->CKTstate0 + here->MOSvbd) = ms->ms_vbd;
1117  *(ckt->CKTstate0 + here->MOSvgs) = ms->ms_vgs;
1118  *(ckt->CKTstate0 + here->MOSvds) = ms->ms_vds;
1119 
1120  /*
1121  * load current vector
1122  */
1123 
1124  ceqbs = here->MOScbs - (here->MOSgbs - ckt->CKTgmin)*ms->ms_vbs;
1125  ceqbd = here->MOScbd - (here->MOSgbd - ckt->CKTgmin)*ms->ms_vbd;
1126 
1127  if (here->MOSmode > 0) {
1128  cdreq = ms->ms_cdrain - here->MOSgds*ms->ms_vds -
1129  here->MOSgm*ms->ms_vgs - here->MOSgmbs*ms->ms_vbs;
1130  }
1131  else {
1132  cdreq = -(ms->ms_cdrain + here->MOSgds*ms->ms_vds -
1133  here->MOSgm*ms->ms_vgd - here->MOSgmbs*ms->ms_vbd);
1134  }
1135 
1136  if (model->MOStype > 0) {
1137 
1138  *(ckt->CKTrhs + here->MOSgNode) -=
1139  ms->ms_ceqgs + ms->ms_ceqgb + ms->ms_ceqgd;
1140  *(ckt->CKTrhs + here->MOSbNode) -= ceqbs + ceqbd - ms->ms_ceqgb;
1141  *(ckt->CKTrhs + here->MOSdNodePrime) += ceqbd - cdreq + ms->ms_ceqgd;
1142  *(ckt->CKTrhs + here->MOSsNodePrime) += cdreq + ceqbs + ms->ms_ceqgs;
1143  }
1144  else {
1145 
1146  *(ckt->CKTrhs + here->MOSgNode) +=
1147  ms->ms_ceqgs + ms->ms_ceqgb + ms->ms_ceqgd;
1148  *(ckt->CKTrhs + here->MOSbNode) += ceqbs + ceqbd - ms->ms_ceqgb;
1149  *(ckt->CKTrhs + here->MOSdNodePrime) -= ceqbd - cdreq + ms->ms_ceqgd;
1150  *(ckt->CKTrhs + here->MOSsNodePrime) -= cdreq + ceqbs + ms->ms_ceqgs;
1151  }
1152 
1153  dcon = here->MOSdrainConductance;
1154  scon = here->MOSsourceConductance;
1155 
1156 
1157  /* level 8, CryoMOS by Luong Huynh 1/19/95
1158  * rd and rs parameters in cryo-MOS model are drain
1159  * and source resistances multiplied by the channel width
1160  * rsh should not be used
1161  */
1162  if (model->MOSlevel == 8) {
1163  dcon *= here->MOSw;
1164  scon *= here->MOSw;
1165  }
1166  /*****/
1167 
1168 
1169  /*
1170  * load y matrix
1171  */
1172  *(here->MOSDdPtr) += dcon;
1173  *(here->MOSGgPtr) += ms->ms_gcgd + ms->ms_gcgs + ms->ms_gcgb;
1174  *(here->MOSSsPtr) += scon;
1175  *(here->MOSBbPtr) += here->MOSgbd + here->MOSgbs + ms->ms_gcgb;
1176  *(here->MOSDdpPtr) -= dcon;
1177  *(here->MOSGbPtr) -= ms->ms_gcgb;
1178  *(here->MOSGdpPtr) -= ms->ms_gcgd;
1179  *(here->MOSGspPtr) -= ms->ms_gcgs;
1180  *(here->MOSSspPtr) -= scon;
1181  *(here->MOSBgPtr) -= ms->ms_gcgb;
1182  *(here->MOSBdpPtr) -= here->MOSgbd;
1183  *(here->MOSBspPtr) -= here->MOSgbs;
1184  *(here->MOSDPdPtr) -= dcon;
1185  *(here->MOSSPsPtr) -= scon;
1186 
1187  if (here->MOSmode > 0) {
1188  *(here->MOSDPdpPtr)+= dcon + here->MOSgds +
1189  here->MOSgbd + ms->ms_gcgd;
1190 
1191  *(here->MOSSPspPtr)+= scon + here->MOSgds +
1192  here->MOSgbs + here->MOSgm + here->MOSgmbs + ms->ms_gcgs;
1193 
1194  *(here->MOSDPgPtr) += here->MOSgm - ms->ms_gcgd;
1195  *(here->MOSDPbPtr) += -here->MOSgbd+ here->MOSgmbs;
1196  *(here->MOSDPspPtr)-= here->MOSgds + here->MOSgm + here->MOSgmbs;
1197  *(here->MOSSPgPtr) -= here->MOSgm + ms->ms_gcgs;
1198  *(here->MOSSPbPtr) -= here->MOSgbs + here->MOSgmbs;
1199  *(here->MOSSPdpPtr)-= here->MOSgds;
1200  }
1201  else {
1202  *(here->MOSDPdpPtr)+= dcon + here->MOSgds +
1203  here->MOSgbd + here->MOSgm + here->MOSgmbs + ms->ms_gcgd;
1204 
1205  *(here->MOSSPspPtr)+= scon + here->MOSgds +
1206  here->MOSgbs + ms->ms_gcgs;
1207 
1208  *(here->MOSDPgPtr) -= here->MOSgm + ms->ms_gcgd;
1209  *(here->MOSDPbPtr) -= here->MOSgbd + here->MOSgmbs;
1210  *(here->MOSDPspPtr)-= here->MOSgds;
1211  *(here->MOSSPgPtr) -= -here->MOSgm + ms->ms_gcgs;
1212  *(here->MOSSPbPtr) -= here->MOSgbs - here->MOSgmbs;
1213  *(here->MOSSPdpPtr)-= here->MOSgds + here->MOSgm + here->MOSgmbs;
1214  }
1215 }
1216 
1217 
1218 static void
1219 mos_load_dc(ckt,model,here,ms)
1220 
1221 CKTcircuit* ckt;
1222 MOSmodel *model;
1223 MOSinstance *here;
1224 struct mosstuff *ms;
1225 {
1226  /*
1227  * Same as above, but avoids processing 0's from Meyer parameters
1228  */
1229 
1230  double ceqbs;
1231  double ceqbd;
1232  double cdreq;
1233  double dcon;
1234  double scon;
1235 
1236  /* save things away for next time */
1237  *(ckt->CKTstate0 + here->MOSvbs) = ms->ms_vbs;
1238  *(ckt->CKTstate0 + here->MOSvbd) = ms->ms_vbd;
1239  *(ckt->CKTstate0 + here->MOSvgs) = ms->ms_vgs;
1240  *(ckt->CKTstate0 + here->MOSvds) = ms->ms_vds;
1241 
1242  /*
1243  * load current vector
1244  */
1245 
1246  ceqbs = here->MOScbs - (here->MOSgbs - ckt->CKTgmin)*ms->ms_vbs;
1247  ceqbd = here->MOScbd - (here->MOSgbd - ckt->CKTgmin)*ms->ms_vbd;
1248 
1249  if (here->MOSmode > 0) {
1250  cdreq = ms->ms_cdrain - here->MOSgds*ms->ms_vds -
1251  here->MOSgm*ms->ms_vgs - here->MOSgmbs*ms->ms_vbs;
1252  }
1253  else {
1254  cdreq = -(ms->ms_cdrain + here->MOSgds*ms->ms_vds -
1255  here->MOSgm*ms->ms_vgd - here->MOSgmbs*ms->ms_vbd);
1256  }
1257 
1258  if (model->MOStype > 0) {
1259  *(ckt->CKTrhs + here->MOSbNode) -= ceqbs + ceqbd;
1260  *(ckt->CKTrhs + here->MOSdNodePrime) += ceqbd - cdreq;
1261  *(ckt->CKTrhs + here->MOSsNodePrime) += cdreq + ceqbs;
1262  }
1263  else {
1264  *(ckt->CKTrhs + here->MOSbNode) += ceqbs + ceqbd;
1265  *(ckt->CKTrhs + here->MOSdNodePrime) -= ceqbd - cdreq;
1266  *(ckt->CKTrhs + here->MOSsNodePrime) -= cdreq + ceqbs;
1267  }
1268 
1269  dcon = here->MOSdrainConductance;
1270  scon = here->MOSsourceConductance;
1271 
1272 
1273 
1274  /* level 8, CryoMOS by Luong Huynh 1/19/95
1275  * rd and rs parameters in COLD MOSFET model are drain
1276  * and source resistances multiplied by the channel width
1277  * rsh should not be used
1278  */
1279  if (model->MOSlevel == 8) {
1280  dcon *= here->MOSw;
1281  scon *= here->MOSw;
1282  }
1283  /**/
1284 
1285 
1286 
1287  /*
1288  * load y matrix
1289  */
1290  *(here->MOSDdPtr) += dcon;
1291  *(here->MOSSsPtr) += scon;
1292  *(here->MOSBbPtr) += here->MOSgbd + here->MOSgbs;
1293  *(here->MOSDdpPtr) -= dcon;
1294  *(here->MOSSspPtr) -= scon;
1295  *(here->MOSBdpPtr) -= here->MOSgbd;
1296  *(here->MOSBspPtr) -= here->MOSgbs;
1297  *(here->MOSDPdPtr) -= dcon;
1298  *(here->MOSSPsPtr) -= scon;
1299 
1300  if (here->MOSmode > 0) {
1301  *(here->MOSDPdpPtr)+= dcon + here->MOSgds + here->MOSgbd;
1302 
1303  *(here->MOSSPspPtr)+= scon + here->MOSgds +
1304  here->MOSgbs + here->MOSgm + here->MOSgmbs;
1305 
1306  *(here->MOSDPgPtr) += here->MOSgm;
1307  *(here->MOSDPbPtr) += -here->MOSgbd+ here->MOSgmbs;
1308  *(here->MOSDPspPtr)-= here->MOSgds + here->MOSgm + here->MOSgmbs;
1309  *(here->MOSSPgPtr) -= here->MOSgm;
1310  *(here->MOSSPbPtr) -= here->MOSgbs + here->MOSgmbs;
1311  *(here->MOSSPdpPtr)-= here->MOSgds;
1312  }
1313  else {
1314  *(here->MOSDPdpPtr)+= dcon + here->MOSgds +
1315  here->MOSgbd + here->MOSgm + here->MOSgmbs;
1316 
1317  *(here->MOSSPspPtr)+= scon + here->MOSgds + here->MOSgbs;
1318 
1319  *(here->MOSDPgPtr) -= here->MOSgm;
1320  *(here->MOSDPbPtr) -= here->MOSgbd + here->MOSgmbs;
1321  *(here->MOSDPspPtr)-= here->MOSgds;
1322  *(here->MOSSPgPtr) -= -here->MOSgm;
1323  *(here->MOSSPbPtr) -= here->MOSgbs - here->MOSgmbs;
1324  *(here->MOSSPdpPtr)-= here->MOSgds + here->MOSgm + here->MOSgmbs;
1325  }
1326 }
struct sMOSmodel * MOSnextModel
Definition: mosdefs.h:274
double MOStBulkPot
Definition: mosdefs.h:57
double ms_von
Definition: mosdefs.h:607
double MOSf4d
Definition: mosdefs.h:86
double MOSgateBulkOverlapCap
Definition: mosdefs.h:94
MOSinstance * MOSinstances
Definition: mosdefs.h:276
double * MOSDPdpPtr
Definition: mosdefs.h:106
double MOStemp
Definition: mosdefs.h:44
static void mos_limvds()
double MOSgm
Definition: mosdefs.h:74
double ms_vbd
Definition: mosdefs.h:612
double * MOSSPbPtr
Definition: mosdefs.h:139
double MOSgmbs
Definition: mosdefs.h:73
double ms_vt
Definition: mosdefs.h:606
#define MODEINITPRED
Definition: cktdefs.h:161
#define MODETRAN
Definition: cktdefs.h:145
double ms_capgs
Definition: mosdefs.h:622
double * MOSBspPtr
Definition: mosdefs.h:122
double MOScd
Definition: mosdefs.h:70
#define MAX(a, b)
Definition: spdefs.h:135
double * MOSSsPtr
Definition: mosdefs.h:102
double CKTdelta
Definition: cktdefs.h:78
double MOStVto
Definition: mosdefs.h:50
double MOStDepCap
Definition: mosdefs.h:58
double ms_ceqgb
Definition: mosdefs.h:617
double * MOSSspPtr
Definition: mosdefs.h:118
#define MODEINITFLOAT
Definition: cktdefs.h:156
double * MOSGspPtr
Definition: mosdefs.h:116
double * MOSSPgPtr
Definition: mosdefs.h:133
#define MODEINITTRAN
Definition: cktdefs.h:160
static int mos_integ()
double MOSgds
Definition: mosdefs.h:75
double MOSbulkJctBotGradingCoeff
Definition: mosdefs.h:298
static void mos_load_dc()
double MOScbd
Definition: mosdefs.h:72
double MOScapbd
Definition: mosdefs.h:78
int MOStype
Definition: mosdefs.h:279
double MOSCbs
Definition: mosdefs.h:82
double * MOSDPbPtr
Definition: mosdefs.h:137
double CONSTKoverQ
Definition: main.c:915
double ms_vbs
Definition: mosdefs.h:611
unsigned MOSoff
Definition: mosdefs.h:215
double * MOSSPspPtr
Definition: mosdefs.h:108
double ms_gcgs
Definition: mosdefs.h:619
int MOSdNodePrime
Definition: mosdefs.h:29
double * MOSSPsPtr
Definition: mosdefs.h:135
double MOSeq3()
double MOSCbdsw
Definition: mosdefs.h:81
double MOSeq6()
double MOSf3d
Definition: mosdefs.h:85
double MOSbulkJctSideGradingCoeff
Definition: mosdefs.h:300
double MOSgateSourceOverlapCap
Definition: mosdefs.h:92
#define SARGS(arg, bot, side, sarg, sargsw)
Definition: mosdefs.h:651
double ms_ceqgd
Definition: mosdefs.h:616
double * MOSDdPtr
Definition: mosdefs.h:98
double MOSw
Definition: mosdefs.h:35
double MOStDrainSatCur
Definition: mosdefs.h:60
#define OK
Definition: iferrmsg.h:17
double * CKTrhsOld
Definition: cktdefs.h:98
double * MOSGbPtr
Definition: mosdefs.h:112
double MOSvon
Definition: mosdefs.h:66
double MOSdrainVcrit
Definition: mosdefs.h:69
double ms_vds
Definition: mosdefs.h:610
int MOSgNode
Definition: mosdefs.h:26
double MOSgbs
Definition: mosdefs.h:77
#define NULL
Definition: spdefs.h:121
double MOSicVBS
Definition: mosdefs.h:63
double MOSgbd
Definition: mosdefs.h:76
double * MOSSPdpPtr
Definition: mosdefs.h:141
double ms_gcgb
Definition: mosdefs.h:621
double MOSCbd
Definition: mosdefs.h:80
double MOSsourceVcrit
Definition: mosdefs.h:68
double MOSeq2()
double MOSCbssw
Definition: mosdefs.h:83
int MOSlevel
Definition: mosdefs.h:280
#define MODEINITSMSIG
Definition: cktdefs.h:159
#define NI_INTEG(ckt, geq, ceq, cap, qcap)
Definition: devdefs.h:141
#define MODETRANOP
Definition: cktdefs.h:151
double * MOSBdpPtr
Definition: mosdefs.h:120
double * MOSGgPtr
Definition: mosdefs.h:100
#define P33
Definition: mosload.c:20
int MOSsNodePrime
Definition: mosdefs.h:30
static int mos_bypass()
double MOSoxideCap
Definition: mosdefs.h:96
static void mos_load()
double * MOSGdpPtr
Definition: mosdefs.h:114
double ms_vgb
Definition: mosdefs.h:613
double MOStSourceSatCur
Definition: mosdefs.h:61
double MOStPhi
Definition: mosdefs.h:49
double MOSicVGS
Definition: mosdefs.h:65
double * MOSDPgPtr
Definition: mosdefs.h:130
static char model[32]
Definition: subckt.c:76
#define MODEINITFIX
Definition: cktdefs.h:158
double MOSf4s
Definition: mosdefs.h:89
int MOSmode
Definition: mosdefs.h:32
double * MOSBgPtr
Definition: mosdefs.h:128
int CKTbypass
Definition: cktdefs.h:169
double MOSf2d
Definition: mosdefs.h:84
#define FABS(a)
Definition: util.h:41
return(True)
double ms_vgd
Definition: mosdefs.h:614
double MOSgateDrainOverlapCap
Definition: mosdefs.h:93
double ms_cdrain
Definition: mosdefs.h:618
double * MOSDPspPtr
Definition: mosdefs.h:124
double MOSsourceConductance
Definition: mosdefs.h:42
double MOSf2s
Definition: mosdefs.h:87
int MOSbNode
Definition: mosdefs.h:28
double ms_ceqgs
Definition: mosdefs.h:615
double CKTdeltaOld[7]
Definition: cktdefs.h:79
#define P66
Definition: mosload.c:19
double ms_capgd
Definition: mosdefs.h:623
double MOScbs
Definition: mosdefs.h:71
static void mos_iv()
double MOScapbs
Definition: mosdefs.h:79
int CKTnoncon
Definition: cktdefs.h:203
static int mos_pnjlim()
double ms_vgs
Definition: mosdefs.h:609
double ms_vdsat
Definition: mosdefs.h:608
long CKTmode
Definition: cktdefs.h:139
struct sMOSinstance * MOSnextInstance
Definition: mosdefs.h:20
static int mos_limiting()
double ms_gcgd
Definition: mosdefs.h:620
double MOSf3s
Definition: mosdefs.h:88
#define MODEINITJCT
Definition: cktdefs.h:157
#define MODEUIC
Definition: cktdefs.h:166
double ms_capgb
Definition: mosdefs.h:624
int MOSload(GENmodel *inModel, CKTcircuit *ckt)
Definition: mosload.c:49
double MOSvdsat
Definition: mosdefs.h:67
double * MOSDPdPtr
Definition: mosdefs.h:126
double * MOSBbPtr
Definition: mosdefs.h:104
double * MOSDdpPtr
Definition: mosdefs.h:110
double MOSdrainConductance
Definition: mosdefs.h:43
double MOSicVDS
Definition: mosdefs.h:64
static void mos_fetlim()
double cryoMOSeq()
double MOSeq1()
static void mos_cap()