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 Hong June Park, Thomas L. Quarles
5 1993 Stephen R. Whiteley
6 ****************************************************************************/
7
8 #include "spice.h"
9 #include <stdio.h>
10 #include <math.h>
11 #include "bsim2def.h"
12 #include "const.h"
13 #include "sperror.h"
14 #include "util.h"
15 #include "niext.h"
16
17
18 int
B2load(inModel,ckt)19 B2load(inModel,ckt)
20
21 GENmodel *inModel;
22 register CKTcircuit *ckt;
23
24 /* actually load the current value into the
25 * sparse matrix previously provided
26 */
27 {
28 register B2model *model = (B2model*)inModel;
29 register B2instance *here;
30 double DrainSatCurrent;
31 double EffectiveLength;
32 double GateBulkOverlapCap;
33 double GateDrainOverlapCap;
34 double GateSourceOverlapCap;
35 double SourceSatCurrent;
36 double DrainArea;
37 double SourceArea;
38 double DrainPerimeter;
39 double SourcePerimeter;
40 double arg;
41 double capbd;
42 double capbs;
43 double cbd;
44 double cbhat;
45 double cbs;
46 double cd;
47 double cdrain;
48 double cdhat;
49 double cdreq;
50 double ceq;
51 double ceqbd;
52 double ceqbs;
53 double ceqqb;
54 double ceqqd;
55 double ceqqg;
56 double czbd;
57 double czbdsw;
58 double czbs;
59 double czbssw;
60 double delvbd;
61 double delvbs;
62 double delvds;
63 double delvgd;
64 double delvgs;
65 double evbd;
66 double evbs;
67 double gbd;
68 double gbs;
69 double gcbdb;
70 double gcbgb;
71 double gcbsb;
72 double gcddb;
73 double gcdgb;
74 double gcdsb;
75 double gcgdb;
76 double gcggb;
77 double gcgsb;
78 double gcsdb;
79 double gcsgb;
80 double gcssb;
81 double gds;
82 double geq;
83 double gm;
84 double gmbs;
85 double sarg;
86 double sargsw;
87 double tol;
88 double vbd;
89 double vbs;
90 double vcrit;
91 double vds;
92 double vdsat;
93 double vgb;
94 double vgd;
95 double vgdo;
96 double vgs;
97 double von;
98 double xfact;
99 double xnrm;
100 double xrev;
101 int Check;
102 double cgdb;
103 double cgsb;
104 double cbdb;
105 double cdgb;
106 double cddb;
107 double cdsb;
108 double cggb;
109 double cbgb;
110 double cbsb;
111 double csgb;
112 double cssb;
113 double csdb;
114 double PhiB;
115 double PhiBSW;
116 double MJ;
117 double MJSW;
118 double argsw;
119 double qgate;
120 double qbulk;
121 double qdrn;
122 double qsrc;
123 double cqgate;
124 double cqbulk;
125 double cqdrn;
126 double vt0;
127 double args[7];
128 int ByPass;
129 #ifndef NOBYPASS
130 double tempv;
131 #endif /*NOBYPASS*/
132 int error;
133
134 /* loop through all the B2 device models */
135 for( ; model != NULL; model = model->B2nextModel ) {
136
137 /* loop through all the instances of the model */
138 for (here = model->B2instances; here != NULL ;
139 here=here->B2nextInstance) {
140 EffectiveLength=here->B2l - model->B2deltaL * 1.e-6;/* m */
141 DrainArea = here->B2drainArea;
142 SourceArea = here->B2sourceArea;
143 DrainPerimeter = here->B2drainPerimeter;
144 SourcePerimeter = here->B2sourcePerimeter;
145 if( (DrainSatCurrent=DrainArea*model->B2jctSatCurDensity)
146 < 1e-15){
147 DrainSatCurrent = 1.0e-15;
148 }
149 if( (SourceSatCurrent=SourceArea*model->B2jctSatCurDensity)
150 <1.0e-15){
151 SourceSatCurrent = 1.0e-15;
152 }
153 GateSourceOverlapCap = model->B2gateSourceOverlapCap *here->B2w;
154 GateDrainOverlapCap = model->B2gateDrainOverlapCap * here->B2w;
155 GateBulkOverlapCap = model->B2gateBulkOverlapCap *EffectiveLength;
156 von = model->B2type * here->B2von;
157 vdsat = model->B2type * here->B2vdsat;
158 vt0 = model->B2type * here->pParam->B2vt0;
159
160 Check=1;
161 ByPass = 0;
162 if((ckt->CKTmode & MODEINITSMSIG)) {
163 vbs= *(ckt->CKTstate0 + here->B2vbs);
164 vgs= *(ckt->CKTstate0 + here->B2vgs);
165 vds= *(ckt->CKTstate0 + here->B2vds);
166 } else if ((ckt->CKTmode & MODEINITTRAN)) {
167 vbs= *(ckt->CKTstate1 + here->B2vbs);
168 vgs= *(ckt->CKTstate1 + here->B2vgs);
169 vds= *(ckt->CKTstate1 + here->B2vds);
170 } else if((ckt->CKTmode & MODEINITJCT) && !here->B2off) {
171 vds= model->B2type * here->B2icVDS;
172 vgs= model->B2type * here->B2icVGS;
173 vbs= model->B2type * here->B2icVBS;
174 if((vds==0) && (vgs==0) && (vbs==0) &&
175 ((ckt->CKTmode &
176 (MODETRAN|MODEAC|MODEDCOP|MODEDCTRANCURVE)) ||
177 (!(ckt->CKTmode & MODEUIC)))) {
178 vbs = -1;
179 vgs = vt0;
180 vds = 0;
181 }
182 } else if((ckt->CKTmode & (MODEINITJCT | MODEINITFIX) ) &&
183 (here->B2off)) {
184 vbs=vgs=vds=0;
185 } else {
186 #ifndef PREDICTOR
187 if((ckt->CKTmode & MODEINITPRED)) {
188 xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1];
189 *(ckt->CKTstate0 + here->B2vbs) =
190 *(ckt->CKTstate1 + here->B2vbs);
191 vbs = (1+xfact)* (*(ckt->CKTstate1 + here->B2vbs))
192 -(xfact * (*(ckt->CKTstate2 + here->B2vbs)));
193 *(ckt->CKTstate0 + here->B2vgs) =
194 *(ckt->CKTstate1 + here->B2vgs);
195 vgs = (1+xfact)* (*(ckt->CKTstate1 + here->B2vgs))
196 -(xfact * (*(ckt->CKTstate2 + here->B2vgs)));
197 *(ckt->CKTstate0 + here->B2vds) =
198 *(ckt->CKTstate1 + here->B2vds);
199 vds = (1+xfact)* (*(ckt->CKTstate1 + here->B2vds))
200 -(xfact * (*(ckt->CKTstate2 + here->B2vds)));
201 *(ckt->CKTstate0 + here->B2vbd) =
202 *(ckt->CKTstate0 + here->B2vbs)-
203 *(ckt->CKTstate0 + here->B2vds);
204 *(ckt->CKTstate0 + here->B2cd) =
205 *(ckt->CKTstate1 + here->B2cd);
206 *(ckt->CKTstate0 + here->B2cbs) =
207 *(ckt->CKTstate1 + here->B2cbs);
208 *(ckt->CKTstate0 + here->B2cbd) =
209 *(ckt->CKTstate1 + here->B2cbd);
210 *(ckt->CKTstate0 + here->B2gm) =
211 *(ckt->CKTstate1 + here->B2gm);
212 *(ckt->CKTstate0 + here->B2gds) =
213 *(ckt->CKTstate1 + here->B2gds);
214 *(ckt->CKTstate0 + here->B2gmbs) =
215 *(ckt->CKTstate1 + here->B2gmbs);
216 *(ckt->CKTstate0 + here->B2gbd) =
217 *(ckt->CKTstate1 + here->B2gbd);
218 *(ckt->CKTstate0 + here->B2gbs) =
219 *(ckt->CKTstate1 + here->B2gbs);
220 *(ckt->CKTstate0 + here->B2cggb) =
221 *(ckt->CKTstate1 + here->B2cggb);
222 *(ckt->CKTstate0 + here->B2cbgb) =
223 *(ckt->CKTstate1 + here->B2cbgb);
224 *(ckt->CKTstate0 + here->B2cbsb) =
225 *(ckt->CKTstate1 + here->B2cbsb);
226 *(ckt->CKTstate0 + here->B2cgdb) =
227 *(ckt->CKTstate1 + here->B2cgdb);
228 *(ckt->CKTstate0 + here->B2cgsb) =
229 *(ckt->CKTstate1 + here->B2cgsb);
230 *(ckt->CKTstate0 + here->B2cbdb) =
231 *(ckt->CKTstate1 + here->B2cbdb);
232 *(ckt->CKTstate0 + here->B2cdgb) =
233 *(ckt->CKTstate1 + here->B2cdgb);
234 *(ckt->CKTstate0 + here->B2cddb) =
235 *(ckt->CKTstate1 + here->B2cddb);
236 *(ckt->CKTstate0 + here->B2cdsb) =
237 *(ckt->CKTstate1 + here->B2cdsb);
238 } else {
239 #endif /* PREDICTOR */
240 vbs = model->B2type * (
241 *(ckt->CKTrhsOld+here->B2bNode) -
242 *(ckt->CKTrhsOld+here->B2sNodePrime));
243 vgs = model->B2type * (
244 *(ckt->CKTrhsOld+here->B2gNode) -
245 *(ckt->CKTrhsOld+here->B2sNodePrime));
246 vds = model->B2type * (
247 *(ckt->CKTrhsOld+here->B2dNodePrime) -
248 *(ckt->CKTrhsOld+here->B2sNodePrime));
249 #ifndef PREDICTOR
250 }
251 #endif /* PREDICTOR */
252 vbd=vbs-vds;
253 vgd=vgs-vds;
254 vgdo = *(ckt->CKTstate0 + here->B2vgs) -
255 *(ckt->CKTstate0 + here->B2vds);
256 delvbs = vbs - *(ckt->CKTstate0 + here->B2vbs);
257 delvbd = vbd - *(ckt->CKTstate0 + here->B2vbd);
258 delvgs = vgs - *(ckt->CKTstate0 + here->B2vgs);
259 delvds = vds - *(ckt->CKTstate0 + here->B2vds);
260 delvgd = vgd-vgdo;
261
262 if (here->B2mode >= 0) {
263 cdhat=
264 *(ckt->CKTstate0 + here->B2cd) -
265 *(ckt->CKTstate0 + here->B2gbd) * delvbd +
266 *(ckt->CKTstate0 + here->B2gmbs) * delvbs +
267 *(ckt->CKTstate0 + here->B2gm) * delvgs +
268 *(ckt->CKTstate0 + here->B2gds) * delvds ;
269 } else {
270 cdhat=
271 *(ckt->CKTstate0 + here->B2cd) -
272 ( *(ckt->CKTstate0 + here->B2gbd) -
273 *(ckt->CKTstate0 + here->B2gmbs)) * delvbd -
274 *(ckt->CKTstate0 + here->B2gm) * delvgd +
275 *(ckt->CKTstate0 + here->B2gds) * delvds;
276 }
277 cbhat=
278 *(ckt->CKTstate0 + here->B2cbs) +
279 *(ckt->CKTstate0 + here->B2cbd) +
280 *(ckt->CKTstate0 + here->B2gbd) * delvbd +
281 *(ckt->CKTstate0 + here->B2gbs) * delvbs ;
282
283 #ifndef NOBYPASS
284 /* now lets see if we can bypass (ugh) */
285
286 /* following should be one big if connected by && all over
287 * the place, but some C compilers can't handle that, so
288 * we split it up here to let them digest it in stages
289 */
290 tempv = MAX(FABS(cbhat),FABS(*(ckt->CKTstate0 + here->B2cbs)
291 + *(ckt->CKTstate0 + here->B2cbd)))+ckt->CKTabstol;
292 if((!(ckt->CKTmode & MODEINITPRED)) && (ckt->CKTbypass) )
293 if( (FABS(delvbs) < (ckt->CKTreltol * MAX(FABS(vbs),
294 FABS(*(ckt->CKTstate0+here->B2vbs)))+
295 ckt->CKTvoltTol)) )
296 if ( (FABS(delvbd) < (ckt->CKTreltol * MAX(FABS(vbd),
297 FABS(*(ckt->CKTstate0+here->B2vbd)))+
298 ckt->CKTvoltTol)) )
299 if( (FABS(delvgs) < (ckt->CKTreltol * MAX(FABS(vgs),
300 FABS(*(ckt->CKTstate0+here->B2vgs)))+
301 ckt->CKTvoltTol)))
302 if ( (FABS(delvds) < (ckt->CKTreltol * MAX(FABS(vds),
303 FABS(*(ckt->CKTstate0+here->B2vds)))+
304 ckt->CKTvoltTol)) )
305 if( (FABS(cdhat- *(ckt->CKTstate0 + here->B2cd)) <
306 ckt->CKTreltol * MAX(FABS(cdhat),FABS(*(ckt->CKTstate0 +
307 here->B2cd))) + ckt->CKTabstol) )
308 if ( (FABS(cbhat-(*(ckt->CKTstate0 + here->B2cbs) +
309 *(ckt->CKTstate0 + here->B2cbd))) < ckt->CKTreltol *
310 tempv)) {
311 /* bypass code */
312 vbs = *(ckt->CKTstate0 + here->B2vbs);
313 vbd = *(ckt->CKTstate0 + here->B2vbd);
314 vgs = *(ckt->CKTstate0 + here->B2vgs);
315 vds = *(ckt->CKTstate0 + here->B2vds);
316 vgd = vgs - vds;
317 vgb = vgs - vbs;
318 cd = *(ckt->CKTstate0 + here->B2cd);
319 cbs = *(ckt->CKTstate0 + here->B2cbs);
320 cbd = *(ckt->CKTstate0 + here->B2cbd);
321 cdrain = here->B2mode * (cd + cbd);
322 gm = *(ckt->CKTstate0 + here->B2gm);
323 gds = *(ckt->CKTstate0 + here->B2gds);
324 gmbs = *(ckt->CKTstate0 + here->B2gmbs);
325 gbd = *(ckt->CKTstate0 + here->B2gbd);
326 gbs = *(ckt->CKTstate0 + here->B2gbs);
327 if((ckt->CKTmode & (MODETRAN | MODEAC)) ||
328 ((ckt->CKTmode & MODETRANOP) &&
329 (ckt->CKTmode & MODEUIC))) {
330 cggb = *(ckt->CKTstate0 + here->B2cggb);
331 cgdb = *(ckt->CKTstate0 + here->B2cgdb);
332 cgsb = *(ckt->CKTstate0 + here->B2cgsb);
333 cbgb = *(ckt->CKTstate0 + here->B2cbgb);
334 cbdb = *(ckt->CKTstate0 + here->B2cbdb);
335 cbsb = *(ckt->CKTstate0 + here->B2cbsb);
336 cdgb = *(ckt->CKTstate0 + here->B2cdgb);
337 cddb = *(ckt->CKTstate0 + here->B2cddb);
338 cdsb = *(ckt->CKTstate0 + here->B2cdsb);
339 capbs = *(ckt->CKTstate0 + here->B2capbs);
340 capbd = *(ckt->CKTstate0 + here->B2capbd);
341 ByPass = 1;
342 goto line755;
343 } else {
344 goto line850;
345 }
346 }
347 #endif /*NOBYPASS*/
348
349 von = model->B2type * here->B2von;
350 if(*(ckt->CKTstate0 + here->B2vds) >=0) {
351 vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->B2vgs)
352 ,von);
353 vds = vgs - vgd;
354 vds = DEVlimvds(vds,*(ckt->CKTstate0 + here->B2vds));
355 vgd = vgs - vds;
356 } else {
357 vgd = DEVfetlim(vgd,vgdo,von);
358 vds = vgs - vgd;
359 vds = -DEVlimvds(-vds,-(*(ckt->CKTstate0 +
360 here->B2vds)));
361 vgs = vgd + vds;
362 }
363 if(vds >= 0) {
364 vcrit = CONSTvt0 *log(CONSTvt0/(CONSTroot2*SourceSatCurrent));
365 vbs = DEVpnjlim(vbs,*(ckt->CKTstate0 + here->B2vbs),
366 CONSTvt0,vcrit,&Check); /* B2 test */
367 vbd = vbs-vds;
368 } else {
369 vcrit = CONSTvt0 * log(CONSTvt0/(CONSTroot2*DrainSatCurrent));
370 vbd = DEVpnjlim(vbd,*(ckt->CKTstate0 + here->B2vbd),
371 CONSTvt0,vcrit,&Check); /* B2 test*/
372 vbs = vbd + vds;
373 }
374 }
375
376 /* determine DC current and derivatives */
377 vbd = vbs - vds;
378 vgd = vgs - vds;
379 vgb = vgs - vbs;
380
381
382 if(vbs <= 0.0 ) {
383 gbs = SourceSatCurrent / CONSTvt0 + ckt->CKTgmin;
384 cbs = gbs * vbs ;
385 } else {
386 evbs = exp(vbs/CONSTvt0);
387 gbs = SourceSatCurrent*evbs/CONSTvt0 + ckt->CKTgmin;
388 cbs = SourceSatCurrent * (evbs-1) + ckt->CKTgmin * vbs ;
389 }
390 if(vbd <= 0.0) {
391 gbd = DrainSatCurrent / CONSTvt0 + ckt->CKTgmin;
392 cbd = gbd * vbd ;
393 } else {
394 evbd = exp(vbd/CONSTvt0);
395 gbd = DrainSatCurrent*evbd/CONSTvt0 +ckt->CKTgmin;
396 cbd = DrainSatCurrent *(evbd-1)+ckt->CKTgmin*vbd;
397 }
398 /* line 400 */
399 if(vds >= 0) {
400 /* normal mode */
401 here->B2mode = 1;
402 } else {
403 /* inverse mode */
404 here->B2mode = -1;
405 }
406 /* call B2evaluate to calculate drain current and its
407 * derivatives and charge and capacitances related to gate
408 * drain, and bulk
409 */
410 if( vds >= 0 ) {
411 B2evaluate(vds,vbs,vgs,here,model,&gm,&gds,&gmbs,&qgate,
412 &qbulk,&qdrn,&cggb,&cgdb,&cgsb,&cbgb,&cbdb,&cbsb,&cdgb,
413 &cddb,&cdsb,&cdrain,&von,&vdsat,ckt);
414 } else {
415 B2evaluate(-vds,vbd,vgd,here,model,&gm,&gds,&gmbs,&qgate,
416 &qbulk,&qsrc,&cggb,&cgsb,&cgdb,&cbgb,&cbsb,&cbdb,&csgb,
417 &cssb,&csdb,&cdrain,&von,&vdsat,ckt);
418 }
419
420 here->B2von = model->B2type * von;
421 here->B2vdsat = model->B2type * vdsat;
422
423
424
425 /*
426 * COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
427 */
428 cd=here->B2mode * cdrain - cbd;
429 if ((ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG)) ||
430 ((ckt->CKTmode & MODETRANOP ) &&
431 (ckt->CKTmode & MODEUIC))) {
432 /*
433 * charge storage elements
434 *
435 * bulk-drain and bulk-source depletion capacitances
436 * czbd : zero bias drain junction capacitance
437 * czbs : zero bias source junction capacitance
438 * czbdsw:zero bias drain junction sidewall capacitance
439 * czbssw:zero bias source junction sidewall capacitance
440 */
441
442 czbd = model->B2unitAreaJctCap * DrainArea;
443 czbs = model->B2unitAreaJctCap * SourceArea;
444 czbdsw= model->B2unitLengthSidewallJctCap * DrainPerimeter;
445 czbssw= model->B2unitLengthSidewallJctCap * SourcePerimeter;
446 PhiB = model->B2bulkJctPotential;
447 PhiBSW = model->B2sidewallJctPotential;
448 MJ = model->B2bulkJctBotGradingCoeff;
449 MJSW = model->B2bulkJctSideGradingCoeff;
450
451 /* Source Bulk Junction */
452 if( vbs < 0 ) {
453 arg = 1 - vbs / PhiB;
454 argsw = 1 - vbs / PhiBSW;
455 sarg = exp(-MJ*log(arg));
456 sargsw = exp(-MJSW*log(argsw));
457 *(ckt->CKTstate0 + here->B2qbs) =
458 PhiB * czbs * (1-arg*sarg)/(1-MJ) + PhiBSW *
459 czbssw * (1-argsw*sargsw)/(1-MJSW);
460 capbs = czbs * sarg + czbssw * sargsw ;
461 } else {
462 *(ckt->CKTstate0+here->B2qbs) =
463 vbs*(czbs+czbssw)+ vbs*vbs*(czbs*MJ*0.5/PhiB
464 + czbssw * MJSW * 0.5/PhiBSW);
465 capbs = czbs + czbssw + vbs *(czbs*MJ/PhiB+
466 czbssw * MJSW / PhiBSW );
467 }
468
469 /* Drain Bulk Junction */
470 if( vbd < 0 ) {
471 arg = 1 - vbd / PhiB;
472 argsw = 1 - vbd / PhiBSW;
473 sarg = exp(-MJ*log(arg));
474 sargsw = exp(-MJSW*log(argsw));
475 *(ckt->CKTstate0 + here->B2qbd) =
476 PhiB * czbd * (1-arg*sarg)/(1-MJ) + PhiBSW *
477 czbdsw * (1-argsw*sargsw)/(1-MJSW);
478 capbd = czbd * sarg + czbdsw * sargsw ;
479 } else {
480 *(ckt->CKTstate0+here->B2qbd) =
481 vbd*(czbd+czbdsw)+ vbd*vbd*(czbd*MJ*0.5/PhiB
482 + czbdsw * MJSW * 0.5/PhiBSW);
483 capbd = czbd + czbdsw + vbd *(czbd*MJ/PhiB+
484 czbdsw * MJSW / PhiBSW );
485 }
486
487 }
488
489
490
491
492 /*
493 * check convergence
494 */
495 /* troubleElts new in 3f2 */
496 if ( (here->B2off == 0) || (!(ckt->CKTmode & MODEINITFIX)) ){
497 if (Check == 1) {
498 ckt->CKTnoncon++;
499 ckt->CKTtroubleElt = (GENinstance *) here;
500 #ifndef NEWCONV
501 } else {
502 tol=ckt->CKTreltol*MAX(FABS(cdhat),FABS(cd))+ckt->CKTabstol;
503 if (FABS(cdhat-cd) >= tol) {
504 ckt->CKTnoncon++;
505 ckt->CKTtroubleElt = (GENinstance *) here;
506 } else {
507 tol=ckt->CKTreltol*MAX(FABS(cbhat),FABS(cbs+cbd))+
508 ckt->CKTabstol;
509 if (FABS(cbhat-(cbs+cbd)) > tol) {
510 ckt->CKTnoncon++;
511 ckt->CKTtroubleElt = (GENinstance *) here;
512 }
513 }
514 #endif /* NEWCONV */
515 }
516 }
517 *(ckt->CKTstate0 + here->B2vbs) = vbs;
518 *(ckt->CKTstate0 + here->B2vbd) = vbd;
519 *(ckt->CKTstate0 + here->B2vgs) = vgs;
520 *(ckt->CKTstate0 + here->B2vds) = vds;
521 *(ckt->CKTstate0 + here->B2cd) = cd;
522 *(ckt->CKTstate0 + here->B2cbs) = cbs;
523 *(ckt->CKTstate0 + here->B2cbd) = cbd;
524 *(ckt->CKTstate0 + here->B2gm) = gm;
525 *(ckt->CKTstate0 + here->B2gds) = gds;
526 *(ckt->CKTstate0 + here->B2gmbs) = gmbs;
527 *(ckt->CKTstate0 + here->B2gbd) = gbd;
528 *(ckt->CKTstate0 + here->B2gbs) = gbs;
529
530 *(ckt->CKTstate0 + here->B2cggb) = cggb;
531 *(ckt->CKTstate0 + here->B2cgdb) = cgdb;
532 *(ckt->CKTstate0 + here->B2cgsb) = cgsb;
533
534 *(ckt->CKTstate0 + here->B2cbgb) = cbgb;
535 *(ckt->CKTstate0 + here->B2cbdb) = cbdb;
536 *(ckt->CKTstate0 + here->B2cbsb) = cbsb;
537
538 *(ckt->CKTstate0 + here->B2cdgb) = cdgb;
539 *(ckt->CKTstate0 + here->B2cddb) = cddb;
540 *(ckt->CKTstate0 + here->B2cdsb) = cdsb;
541
542 *(ckt->CKTstate0 + here->B2capbs) = capbs;
543 *(ckt->CKTstate0 + here->B2capbd) = capbd;
544
545 /* bulk and channel charge plus overlaps */
546
547 if((!(ckt->CKTmode & (MODETRAN | MODEAC))) &&
548 ((!(ckt->CKTmode & MODETRANOP)) ||
549 (!(ckt->CKTmode & MODEUIC))) && (!(ckt->CKTmode
550 & MODEINITSMSIG))) goto line850;
551
552 line755:
553 if( here->B2mode > 0 ) {
554
555 args[0] = GateDrainOverlapCap;
556 args[1] = GateSourceOverlapCap;
557 args[2] = GateBulkOverlapCap;
558 args[3] = capbd;
559 args[4] = capbs;
560 args[5] = cggb;
561 args[6] = cgdb;
562 args[7] = cgsb;
563
564 B2mosCap(ckt,vgd,vgs,vgb,
565 args,
566 /*
567 GateDrainOverlapCap,
568 GateSourceOverlapCap,GateBulkOverlapCap,
569 capbd,capbs,cggb,cgdb,cgsb,
570 */
571 cbgb,cbdb,cbsb,cdgb,cddb,cdsb
572 ,&gcggb,&gcgdb,&gcgsb,&gcbgb,&gcbdb,&gcbsb,&gcdgb
573 ,&gcddb,&gcdsb,&gcsgb,&gcsdb,&gcssb,&qgate,&qbulk
574 ,&qdrn,&qsrc);
575 } else {
576
577 args[0] = GateSourceOverlapCap;
578 args[1] = GateDrainOverlapCap;
579 args[2] = GateBulkOverlapCap;
580 args[3] = capbs;
581 args[4] = capbd;
582 args[5] = cggb;
583 args[6] = cgsb;
584 args[7] = cgdb;
585
586 B2mosCap(ckt,vgs,vgd,vgb,args,
587 /*
588 GateSourceOverlapCap,
589 GateDrainOverlapCap,GateBulkOverlapCap,
590 capbs,capbd,cggb,cgsb,cgdb,
591 */
592 cbgb,cbsb,cbdb,csgb,cssb,csdb
593 ,&gcggb,&gcgsb,&gcgdb,&gcbgb,&gcbsb,&gcbdb,&gcsgb
594 ,&gcssb,&gcsdb,&gcdgb,&gcdsb,&gcddb,&qgate,&qbulk
595 ,&qsrc,&qdrn);
596 }
597
598 if(ByPass) goto line860;
599 *(ckt->CKTstate0 + here->B2qg) = qgate;
600 *(ckt->CKTstate0 + here->B2qd) = qdrn -
601 *(ckt->CKTstate0 + here->B2qbd);
602 *(ckt->CKTstate0 + here->B2qb) = qbulk +
603 *(ckt->CKTstate0 + here->B2qbd) +
604 *(ckt->CKTstate0 + here->B2qbs);
605
606 /* store small signal parameters */
607 if((!(ckt->CKTmode & (MODEAC | MODETRAN))) &&
608 (ckt->CKTmode & MODETRANOP ) && (ckt->CKTmode &
609 MODEUIC )) goto line850;
610 if(ckt->CKTmode & MODEINITSMSIG ) {
611 *(ckt->CKTstate0+here->B2cggb) = cggb;
612 *(ckt->CKTstate0+here->B2cgdb) = cgdb;
613 *(ckt->CKTstate0+here->B2cgsb) = cgsb;
614 *(ckt->CKTstate0+here->B2cbgb) = cbgb;
615 *(ckt->CKTstate0+here->B2cbdb) = cbdb;
616 *(ckt->CKTstate0+here->B2cbsb) = cbsb;
617 *(ckt->CKTstate0+here->B2cdgb) = cdgb;
618 *(ckt->CKTstate0+here->B2cddb) = cddb;
619 *(ckt->CKTstate0+here->B2cdsb) = cdsb;
620 *(ckt->CKTstate0+here->B2capbd) = capbd;
621 *(ckt->CKTstate0+here->B2capbs) = capbs;
622
623 goto line1000;
624 }
625
626 if(ckt->CKTmode & MODEINITTRAN ) {
627 *(ckt->CKTstate1+here->B2qb) =
628 *(ckt->CKTstate0+here->B2qb) ;
629 *(ckt->CKTstate1+here->B2qg) =
630 *(ckt->CKTstate0+here->B2qg) ;
631 *(ckt->CKTstate1+here->B2qd) =
632 *(ckt->CKTstate0+here->B2qd) ;
633 }
634
635
636 NI_INTEG(ckt,geq,ceq,0.0,here->B2qb);
637 NI_INTEG(ckt,geq,ceq,0.0,here->B2qg);
638 NI_INTEG(ckt,geq,ceq,0.0,here->B2qd);
639
640 goto line860;
641
642 line850:
643 /* initialize to zero charge conductance and current */
644 ceqqg = ceqqb = ceqqd = 0.0;
645 gcdgb = gcddb = gcdsb = 0.0;
646 gcsgb = gcsdb = gcssb = 0.0;
647 gcggb = gcgdb = gcgsb = 0.0;
648 gcbgb = gcbdb = gcbsb = 0.0;
649 goto line900;
650
651 line860:
652 /* evaluate equivalent charge current */
653 cqgate = *(ckt->CKTstate0 + here->B2iqg);
654 cqbulk = *(ckt->CKTstate0 + here->B2iqb);
655 cqdrn = *(ckt->CKTstate0 + here->B2iqd);
656 ceqqg = cqgate - gcggb * vgb + gcgdb * vbd + gcgsb * vbs;
657 ceqqb = cqbulk - gcbgb * vgb + gcbdb * vbd + gcbsb * vbs;
658 ceqqd = cqdrn - gcdgb * vgb + gcddb * vbd + gcdsb * vbs;
659
660 if(ckt->CKTmode & MODEINITTRAN ) {
661 *(ckt->CKTstate1 + here->B2iqb) =
662 *(ckt->CKTstate0 + here->B2iqb);
663 *(ckt->CKTstate1 + here->B2iqg) =
664 *(ckt->CKTstate0 + here->B2iqg);
665 *(ckt->CKTstate1 + here->B2iqd) =
666 *(ckt->CKTstate0 + here->B2iqd);
667 }
668
669 /*
670 * load current vector
671 */
672 line900:
673
674 ceqbs = model->B2type * (cbs-(gbs-ckt->CKTgmin)*vbs);
675 ceqbd = model->B2type * (cbd-(gbd-ckt->CKTgmin)*vbd);
676
677 ceqqg = model->B2type * ceqqg;
678 ceqqb = model->B2type * ceqqb;
679 ceqqd = model->B2type * ceqqd;
680 if (here->B2mode >= 0) {
681 xnrm=1;
682 xrev=0;
683 cdreq=model->B2type*(cdrain-gds*vds-gm*vgs-gmbs*vbs);
684 } else {
685 xnrm=0;
686 xrev=1;
687 cdreq = -(model->B2type)*(cdrain+gds*vds-gm*vgd-gmbs*vbd);
688 }
689
690 *(ckt->CKTrhs + here->B2gNode) -= ceqqg;
691 *(ckt->CKTrhs + here->B2bNode) -=(ceqbs+ceqbd+ceqqb);
692 *(ckt->CKTrhs + here->B2dNodePrime) +=
693 (ceqbd-cdreq-ceqqd);
694 *(ckt->CKTrhs + here->B2sNodePrime) +=
695 (cdreq+ceqbs+ceqqg+ceqqb+ceqqd);
696
697 /*
698 * load y matrix
699 */
700
701 *(here->B2DdPtr) += (here->B2drainConductance);
702 *(here->B2GgPtr) += (gcggb);
703 *(here->B2SsPtr) += (here->B2sourceConductance);
704 *(here->B2BbPtr) += (gbd+gbs-gcbgb-gcbdb-gcbsb);
705 *(here->B2DPdpPtr) +=
706 (here->B2drainConductance+gds+gbd+xrev*(gm+gmbs)+gcddb);
707 *(here->B2SPspPtr) +=
708 (here->B2sourceConductance+gds+gbs+xnrm*(gm+gmbs)+gcssb);
709 *(here->B2DdpPtr) += (-here->B2drainConductance);
710 *(here->B2GbPtr) += (-gcggb-gcgdb-gcgsb);
711 *(here->B2GdpPtr) += (gcgdb);
712 *(here->B2GspPtr) += (gcgsb);
713 *(here->B2SspPtr) += (-here->B2sourceConductance);
714 *(here->B2BgPtr) += (gcbgb);
715 *(here->B2BdpPtr) += (-gbd+gcbdb);
716 *(here->B2BspPtr) += (-gbs+gcbsb);
717 *(here->B2DPdPtr) += (-here->B2drainConductance);
718 *(here->B2DPgPtr) += ((xnrm-xrev)*gm+gcdgb);
719 *(here->B2DPbPtr) += (-gbd+(xnrm-xrev)*gmbs-gcdgb-gcddb-gcdsb);
720 *(here->B2DPspPtr) += (-gds-xnrm*(gm+gmbs)+gcdsb);
721 *(here->B2SPgPtr) += (-(xnrm-xrev)*gm+gcsgb);
722 *(here->B2SPsPtr) += (-here->B2sourceConductance);
723 *(here->B2SPbPtr) += (-gbs-(xnrm-xrev)*gmbs-gcsgb-gcsdb-gcssb);
724 *(here->B2SPdpPtr) += (-gds-xrev*(gm+gmbs)+gcsdb);
725
726
727 line1000: ;
728
729 } /* End of Mosfet Instance */
730
731 } /* End of Model Instance */
732 return(OK);
733 }
734
735