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
MOSload(inModel,ckt)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
mos_limiting(ckt,here,ms)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
mos_limvds(vnew,vold)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
mos_pnjlim(vnew,vold,vt,vcrit)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
mos_fetlim(vnew,vold,vto)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
mos_bypass(ckt,model,here,ms)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) +
674                         here->MOSgateSourceOverlapCap;
675 
676         ms->ms_capgd = *(ckt->CKTstate0 + here->MOScapgd) +
677                     *(ckt->CKTstate1 + here->MOScapgd) +
678                         here->MOSgateDrainOverlapCap;
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
mos_iv(ckt,model,here,ms)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
mos_cap(ckt,model,here,ms)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) +
991                 here->MOSgateSourceOverlapCap;
992         ms->ms_capgd = *(ckt->CKTstate0 + here->MOScapgd) +
993                 *(ckt->CKTstate0 + here->MOScapgd) +
994                 here->MOSgateDrainOverlapCap;
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) +
1018                 here->MOSgateSourceOverlapCap;
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
mos_integ(ckt,here,ms)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
mos_load(ckt,model,here,ms)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
mos_load_dc(ckt,model,here,ms)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 }
1327