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