1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1985 Thomas L. Quarles
4
5 This function is obsolete (was used by an old sensitivity analysis)
6 **********/
7
8 /* actually load the current sensitivity
9 * information into the array previously provided
10 */
11
12 #include "ngspice/ngspice.h"
13 #include "ngspice/smpdefs.h"
14 #include "ngspice/cktdefs.h"
15 #include "mos2defs.h"
16 #include "ngspice/sperror.h"
17 #include "ngspice/suffix.h"
18
19 int
MOS2sLoad(GENmodel * inModel,CKTcircuit * ckt)20 MOS2sLoad(GENmodel *inModel, CKTcircuit *ckt)
21 {
22 MOS2model *model = (MOS2model *)inModel;
23 MOS2instance *here;
24 double SaveState[44];
25 int save_mode;
26 int i;
27 int iparmno;
28 int error;
29 int flag;
30 double A0;
31 double DELA;
32 double Apert;
33 double DELAinv;
34 double gspr0;
35 double gspr;
36 double gdpr0;
37 double gdpr;
38 double cdpr0;
39 double cspr0;
40 double cd0;
41 double cbd0;
42 double cbs0;
43 double cd;
44 double cbd;
45 double cbs;
46 double DcdprDp;
47 double DcsprDp;
48 double DcbDp;
49 double DcdDp;
50 double DcbsDp;
51 double DcbdDp;
52 double DcdprmDp;
53 double DcsprmDp;
54 double qgs0;
55 double qgd0;
56 double qgb0;
57 double qbd0;
58 double qbd;
59 double qbs0;
60 double qbs;
61 double DqgsDp;
62 double DqgdDp;
63 double DqgbDp;
64 double DqbdDp;
65 double DqbsDp;
66 double Osxpgs;
67 double Osxpgd;
68 double Osxpgb;
69 double Osxpbd;
70 double Osxpbs;
71 double tag0;
72 double tag1;
73 double arg;
74 double sarg;
75 double sargsw;
76 int offset;
77 double EffectiveLength;
78 SENstruct *info;
79
80 #ifdef SENSDEBUG
81 printf("MOS2senload \n");
82 printf("CKTtime = %.5e\n",ckt->CKTtime);
83 printf("CKTorder = %d\n",ckt->CKTorder);
84 #endif /* SENSDEBUG */
85
86 info = ckt->CKTsenInfo;
87 info->SENstatus = PERTURBATION;
88
89 tag0 = ckt->CKTag[0];
90 tag1 = ckt->CKTag[1];
91 if(ckt->CKTorder == 1){
92 tag1 = 0;
93 }
94
95 /* loop through all the models */
96 for( ; model != NULL; model = MOS2nextModel(model)) {
97
98 /* loop through all the instances of the model */
99 for (here = MOS2instances(model); here != NULL ;
100 here=MOS2nextInstance(here)) {
101
102 #ifdef SENSDEBUG
103 printf("senload instance name %s\n",here->MOS2name);
104 printf("gate = %d ,drain = %d, drainprm = %d\n",
105 here->MOS2gNode,here->MOS2dNode,here->MOS2dNodePrime);
106 printf("source = %d , sourceprm = %d ,body = %d, senparmno = %d\n",
107 here->MOS2sNode ,here->MOS2sNodePrime,
108 here->MOS2bNode,here->MOS2senParmNo);
109 #endif /* SENSDEBUG */
110
111
112 /* save the unperturbed values in the state vector */
113 for(i=0; i <= 16; i++){
114 *(SaveState + i) = *(ckt->CKTstate0 + here->MOS2states + i);
115 }
116
117 *(SaveState + 17) = here->MOS2sourceConductance;
118 *(SaveState + 18) = here->MOS2drainConductance;
119 *(SaveState + 19) = here->MOS2cd;
120 *(SaveState + 20) = here->MOS2cbs;
121 *(SaveState + 21) = here->MOS2cbd;
122 *(SaveState + 22) = here->MOS2gmbs;
123 *(SaveState + 23) = here->MOS2gm;
124 *(SaveState + 24) = here->MOS2gds;
125 *(SaveState + 25) = here->MOS2gbd;
126 *(SaveState + 26) = here->MOS2gbs;
127 *(SaveState + 27) = here->MOS2capbd;
128 *(SaveState + 28) = here->MOS2capbs;
129 *(SaveState + 29) = here->MOS2Cbd;
130 *(SaveState + 30) = here->MOS2Cbdsw;
131 *(SaveState + 31) = here->MOS2Cbs;
132 *(SaveState + 32) = here->MOS2Cbssw;
133 *(SaveState + 33) = here->MOS2f2d;
134 *(SaveState + 34) = here->MOS2f3d;
135 *(SaveState + 35) = here->MOS2f4d;
136 *(SaveState + 36) = here->MOS2f2s;
137 *(SaveState + 37) = here->MOS2f3s;
138 *(SaveState + 38) = here->MOS2f4s;
139 *(SaveState + 39) = here->MOS2cgs;
140 *(SaveState + 40) = here->MOS2cgd;
141 *(SaveState + 41) = here->MOS2cgb;
142 *(SaveState + 42) = here->MOS2vdsat;
143 *(SaveState + 43) = here->MOS2von;
144 save_mode = here->MOS2mode;
145
146
147 if(here->MOS2senParmNo == 0) goto next1;
148
149 #ifdef SENSDEBUG
150 printf("without perturbation \n");
151 printf("gbd =%.5e\n",here->MOS2gbd);
152 printf("satCur =%.5e\n",here->MOS2tSatCur);
153 printf("satCurDens =%.5e\n",here->MOS2tSatCurDens);
154 printf("vbd =%.5e\n",*(ckt->CKTstate0 + here->MOS2vbd));
155 #endif /* SENSDEBUG */
156
157 cdpr0= here->MOS2cd;
158 cspr0= -(here->MOS2cd + here->MOS2cbd + here->MOS2cbs);
159 if((info->SENmode == TRANSEN) &&
160 (ckt->CKTmode & MODEINITTRAN)){
161 qgs0 = *(ckt->CKTstate1 + here->MOS2qgs);
162 qgd0 = *(ckt->CKTstate1 + here->MOS2qgd);
163 qgb0 = *(ckt->CKTstate1 + here->MOS2qgb);
164 }
165 else{
166 qgs0 = *(ckt->CKTstate0 + here->MOS2qgs);
167 qgd0 = *(ckt->CKTstate0 + here->MOS2qgd);
168 qgb0 = *(ckt->CKTstate0 + here->MOS2qgb);
169 }
170
171 here->MOS2senPertFlag = ON;
172 error = MOS2load((GENmodel*)model,ckt);
173 if(error) return(error);
174
175 cd0 = here->MOS2cd ;
176 cbd0 = here->MOS2cbd ;
177 cbs0 = here->MOS2cbs ;
178 gspr0= here->MOS2sourceConductance ;
179 gdpr0= here->MOS2drainConductance ;
180
181 qbs0 = *(ckt->CKTstate0 + here->MOS2qbs);
182 qbd0 = *(ckt->CKTstate0 + here->MOS2qbd);
183
184 for( flag = 0 ; flag <= 1 ; flag++){
185 if(here->MOS2sens_l == 0)
186 if(flag == 0) goto next2;
187 if(here->MOS2sens_w == 0)
188 if(flag == 1) goto next2;
189 if(flag == 0){
190 A0 = here->MOS2l;
191 DELA = info->SENpertfac * A0;
192 DELAinv = 1.0/DELA;
193 Apert = A0 + DELA;
194 here->MOS2l = Apert;
195 }
196 else{
197 A0 = here->MOS2w;
198 DELA = info->SENpertfac * A0;
199 DELAinv = 1.0/DELA;
200 Apert = A0 + DELA;
201 here->MOS2w = Apert;
202 here->MOS2drainArea *= (1 + info->SENpertfac);
203 here->MOS2sourceArea *= (1 + info->SENpertfac);
204 here->MOS2Cbd *= (1 + info->SENpertfac);
205 here->MOS2Cbs *= (1 + info->SENpertfac);
206 if(here->MOS2drainPerimiter){
207 here->MOS2Cbdsw += here->MOS2Cbdsw *
208 DELA/here->MOS2drainPerimiter;
209 }
210 if(here->MOS2sourcePerimiter){
211 here->MOS2Cbssw += here->MOS2Cbssw *
212 DELA/here->MOS2sourcePerimiter;
213 }
214 if(*(ckt->CKTstate0 + here->MOS2vbd) >=
215 here->MOS2tDepCap){
216 arg = 1-model->MOS2fwdCapDepCoeff;
217 sarg = exp( (-model->MOS2bulkJctBotGradingCoeff) *
218 log(arg) );
219 sargsw = exp( (-model->MOS2bulkJctSideGradingCoeff) *
220 log(arg) );
221 here->MOS2f2d = here->MOS2Cbd*
222 (1-model->MOS2fwdCapDepCoeff*
223 (1+model->MOS2bulkJctBotGradingCoeff))* sarg/arg
224 + here->MOS2Cbdsw*(1-model->MOS2fwdCapDepCoeff*
225 (1+model->MOS2bulkJctSideGradingCoeff))*
226 sargsw/arg;
227 here->MOS2f3d = here->MOS2Cbd *
228 model->MOS2bulkJctBotGradingCoeff * sarg/arg/
229 here->MOS2tBulkPot + here->MOS2Cbdsw *
230 model->MOS2bulkJctSideGradingCoeff *
231 sargsw/arg / here->MOS2tBulkPot;
232 here->MOS2f4d = here->MOS2Cbd*
233 here->MOS2tBulkPot*(1-arg*sarg)/
234 (1-model->MOS2bulkJctBotGradingCoeff)
235 + here->MOS2Cbdsw*here->MOS2tBulkPot*
236 (1-arg*sargsw)/
237 (1-model->MOS2bulkJctSideGradingCoeff)
238 -here->MOS2f3d/2*
239 (here->MOS2tDepCap*here->MOS2tDepCap)
240 -here->MOS2tDepCap * here->MOS2f2d;
241 }
242 if(*(ckt->CKTstate0 + here->MOS2vbs) >=
243 here->MOS2tDepCap){
244 arg = 1-model->MOS2fwdCapDepCoeff;
245 sarg = exp( (-model->MOS2bulkJctBotGradingCoeff) *
246 log(arg) );
247 sargsw = exp( (-model->MOS2bulkJctSideGradingCoeff) *
248 log(arg) );
249 here->MOS2f2s = here->MOS2Cbs*
250 (1-model->MOS2fwdCapDepCoeff*
251 (1+model->MOS2bulkJctBotGradingCoeff))* sarg/arg
252 + here->MOS2Cbssw*(1-model->MOS2fwdCapDepCoeff*
253 (1+model->MOS2bulkJctSideGradingCoeff))*
254 sargsw/arg;
255 here->MOS2f3s = here->MOS2Cbs *
256 model->MOS2bulkJctBotGradingCoeff * sarg/arg/
257 here->MOS2tBulkPot + here->MOS2Cbssw *
258 model->MOS2bulkJctSideGradingCoeff *sargsw/arg /
259 here->MOS2tBulkPot;
260 here->MOS2f4s = here->MOS2Cbs*here->MOS2tBulkPot*
261 (1-arg*sarg)/
262 (1-model->MOS2bulkJctBotGradingCoeff)
263 + here->MOS2Cbssw*here->MOS2tBulkPot*
264 (1-arg*sargsw)/
265 (1-model->MOS2bulkJctSideGradingCoeff)
266 -here->MOS2f3s/2*
267 (here->MOS2tDepCap*here->MOS2tDepCap)
268 -here->MOS2tDepCap * here->MOS2f2s;
269 }
270 here->MOS2drainConductance *= Apert/A0;
271 here->MOS2sourceConductance *= Apert/A0;
272 }
273
274
275 #ifdef SENSDEBUG
276 if(flag == 0)
277 printf("perturbation of l\n");
278 if(flag == 1)
279 printf("perturbation of w\n");
280 #endif /* SENSDEBUG */
281
282 error = MOS2load((GENmodel*)model,ckt);
283 if(error) return(error);
284
285 if(flag == 0){
286 here->MOS2l = A0;
287 }
288 else{
289 here->MOS2w = A0;
290 here->MOS2drainArea /= (1 + info->SENpertfac);
291 here->MOS2sourceArea /= (1 + info->SENpertfac);
292 here->MOS2drainConductance *= A0/Apert;
293 here->MOS2sourceConductance *= A0/Apert;
294 }
295 cd = here->MOS2cd ;
296 cbd = here->MOS2cbd ;
297 cbs = here->MOS2cbs ;
298
299 gspr= here->MOS2sourceConductance ;
300 gdpr= here->MOS2drainConductance ;
301
302 DcdDp = (cd - cd0) * DELAinv;
303 DcbsDp = (cbs - cbs0) * DELAinv;
304 DcbdDp = (cbd - cbd0) * DELAinv;
305 DcbDp = ( DcbsDp + DcbdDp );
306
307 DcdprDp = 0;
308 DcsprDp = 0;
309 if(here->MOS2dNode != here->MOS2dNodePrime)
310 if(gdpr0) DcdprDp = cdpr0 * (gdpr - gdpr0)/gdpr0 * DELAinv;
311 if(here->MOS2sNode != here->MOS2sNodePrime)
312 if(gspr0) DcsprDp = cspr0 * (gspr - gspr0)/gspr0 * DELAinv;
313
314 DcdprmDp = ( - DcdprDp + DcdDp);
315 DcsprmDp = ( - DcbsDp - DcdDp - DcbdDp - DcsprDp);
316
317 if(flag == 0){
318 EffectiveLength = here->MOS2l
319 - 2*model->MOS2latDiff;
320 if(EffectiveLength == 0){
321 DqgsDp = 0;
322 DqgdDp = 0;
323 DqgbDp = 0;
324 }
325 else{
326 DqgsDp = model->MOS2type * qgs0 / EffectiveLength;
327 DqgdDp = model->MOS2type * qgd0 / EffectiveLength;
328 DqgbDp = model->MOS2type * qgb0 / EffectiveLength;
329 }
330 }
331 else{
332 DqgsDp = model->MOS2type * qgs0 / here->MOS2w;
333 DqgdDp = model->MOS2type * qgd0 / here->MOS2w;
334 DqgbDp = model->MOS2type * qgb0 / here->MOS2w;
335 }
336
337
338 qbd = *(ckt->CKTstate0 + here->MOS2qbd);
339 qbs = *(ckt->CKTstate0 + here->MOS2qbs);
340
341 DqbsDp = model->MOS2type * (qbs - qbs0)*DELAinv;
342 DqbdDp = model->MOS2type * (qbd - qbd0)*DELAinv;
343
344 if(flag == 0){
345 *(here->MOS2dphigs_dl) = DqgsDp;
346 *(here->MOS2dphigd_dl) = DqgdDp;
347 *(here->MOS2dphibs_dl) = DqbsDp;
348 *(here->MOS2dphibd_dl) = DqbdDp;
349 *(here->MOS2dphigb_dl) = DqgbDp;
350 }
351 else{
352 *(here->MOS2dphigs_dw) = DqgsDp;
353 *(here->MOS2dphigd_dw) = DqgdDp;
354 *(here->MOS2dphibs_dw) = DqbsDp;
355 *(here->MOS2dphibd_dw) = DqbdDp;
356 *(here->MOS2dphigb_dw) = DqgbDp;
357 }
358
359
360 #ifdef SENSDEBUG
361 printf("CKTag[0]=%.7e,CKTag[1]=%.7e,flag= %d\n",
362 ckt->CKTag[0],ckt->CKTag[1],flag);
363 printf("cd0 = %.7e ,cd = %.7e,\n",cd0,cd);
364 printf("cbs0 = %.7e ,cbs = %.7e,\n",cbs0,cbs);
365 printf("cbd0 = %.7e ,cbd = %.7e,\n",cbd0,cbd);
366 printf("DcdprmDp = %.7e,\n",DcdprmDp);
367 printf("DcsprmDp = %.7e,\n",DcsprmDp);
368 printf("DcdprDp = %.7e,\n",DcdprDp);
369 printf("DcsprDp = %.7e,\n",DcsprDp);
370 printf("qgs0 = %.7e \n",qgs0);
371 printf("qgd0 = %.7e \n",qgd0);
372 printf("qgb0 = %.7e \n",qgb0);
373 printf("qbs0 = %.7e ,qbs = %.7e,\n",qbs0,qbs);
374 printf("qbd0 = %.7e ,qbd = %.7e,\n",qbd0,qbd);
375 printf("DqgsDp = %.7e \n",DqgsDp);
376 printf("DqgdDp = %.7e \n",DqgdDp);
377 printf("DqgbDp = %.7e \n",DqgbDp);
378 printf("DqbsDp = %.7e \n",DqbsDp);
379 printf("DqbdDp = %.7e \n",DqbdDp);
380 printf("EffectiveLength = %.7e \n",EffectiveLength);
381 printf("tdepCap = %.7e \n",here->MOS2tDepCap);
382 printf("\n");
383 #endif /* SENSDEBUG*/
384 if((info->SENmode == TRANSEN) &&
385 (ckt->CKTmode & MODEINITTRAN))
386 goto next2;
387
388 /*
389 * load RHS matrix
390 */
391
392 if(flag == 0){
393 *(info->SEN_RHS[here->MOS2bNode] + here->MOS2senParmNo) -=
394 model->MOS2type * DcbDp;
395 *(info->SEN_RHS[here->MOS2dNode] + here->MOS2senParmNo) -=
396 model->MOS2type * DcdprDp;
397 *(info->SEN_RHS[here->MOS2dNodePrime] + here->MOS2senParmNo)
398 -= model->MOS2type * DcdprmDp;
399 *(info->SEN_RHS[here->MOS2sNode] + here->MOS2senParmNo) -=
400 model->MOS2type * DcsprDp;
401 *(info->SEN_RHS[here->MOS2sNodePrime] + here->MOS2senParmNo)
402 -= model->MOS2type * DcsprmDp;
403 }
404 else{
405 offset = here->MOS2sens_l;
406
407 *(info->SEN_RHS[here->MOS2bNode] + here->MOS2senParmNo +
408 offset) -= model->MOS2type * DcbDp;
409 *(info->SEN_RHS[here->MOS2dNode] + here->MOS2senParmNo +
410 offset) -= model->MOS2type * DcdprDp;
411 *(info->SEN_RHS[here->MOS2dNodePrime] + here->MOS2senParmNo
412 + offset) -= model->MOS2type * DcdprmDp;
413 *(info->SEN_RHS[here->MOS2sNode] + here->MOS2senParmNo +
414 offset) -= model->MOS2type * DcsprDp;
415 *(info->SEN_RHS[here->MOS2sNodePrime] + here->MOS2senParmNo
416 + offset) -= model->MOS2type * DcsprmDp;
417 }
418 #ifdef SENSDEBUG
419 printf("after loading\n");
420 if(flag == 0){
421 printf("DcbDp=%.7e\n",
422 *(info->SEN_RHS[here->MOS2bNode] +
423 here->MOS2senParmNo));
424 printf("DcdprDp=%.7e\n",
425 *(info->SEN_RHS[here->MOS2dNode] +
426 here->MOS2senParmNo));
427 printf("DcsprDp=%.7e\n",
428 *(info->SEN_RHS[here->MOS2sNode] +
429 here->MOS2senParmNo));
430 printf("DcdprmDp=%.7e\n",
431 *(info->SEN_RHS[here->MOS2dNodePrime] +
432 here->MOS2senParmNo));
433 printf("DcsprmDp=%.7e\n",
434 *(info->SEN_RHS[here->MOS2sNodePrime] +
435 here->MOS2senParmNo));
436 printf("\n");
437 }
438 else{
439 printf("DcbDp=%.7e\n",
440 *(info->SEN_RHS[here->MOS2bNode] +
441 here->MOS2senParmNo + here->MOS2sens_l));
442 printf("DcdprDp=%.7e\n",
443 *(info->SEN_RHS[here->MOS2dNode] +
444 here->MOS2senParmNo + here->MOS2sens_l));
445 printf("DcsprDp=%.7e\n",
446 *(info->SEN_RHS[here->MOS2sNode] +
447 here->MOS2senParmNo + here->MOS2sens_l));
448 printf("DcdprmDp=%.7e\n",
449 *(info->SEN_RHS[here->MOS2dNodePrime] +
450 here->MOS2senParmNo + here->MOS2sens_l));
451 printf("DcsprmDp=%.7e\n",
452 *(info->SEN_RHS[here->MOS2sNodePrime] +
453 here->MOS2senParmNo + here->MOS2sens_l));
454 }
455 #endif /* SENSDEBUG*/
456 next2:
457 ;
458 }
459 next1:
460 if((info->SENmode == DCSEN) ||
461 (ckt->CKTmode&MODETRANOP) ) goto restore;
462 if((info->SENmode == TRANSEN) &&
463 (ckt->CKTmode & MODEINITTRAN)) goto restore;
464 for(iparmno = 1;iparmno<=info->SENparms;iparmno++){
465 #ifdef SENSDEBUG
466 printf("after conductive currents\n");
467 printf("iparmno = %d\n",iparmno);
468 printf("DcbDp=%.7e\n",
469 *(info->SEN_RHS[here->MOS2bNode] + iparmno));
470 printf("DcdprDp=%.7e\n",
471 *(info->SEN_RHS[here->MOS2dNode] + iparmno));
472 printf("DcdprmDp=%.7e\n",
473 *(info->SEN_RHS[here->MOS2dNodePrime] + iparmno));
474 printf("DcsprDp=%.7e\n",
475 *(info->SEN_RHS[here->MOS2sNode] + iparmno));
476 printf("DcsprmDp=%.7e\n",
477 *(info->SEN_RHS[here->MOS2sNodePrime] + iparmno));
478 printf("\n");
479 #endif /* SENSDEBUG */
480 Osxpgs = tag0 * *(ckt->CKTstate1 + here->MOS2sensxpgs +
481 10*(iparmno - 1))
482 + tag1 * *(ckt->CKTstate1 + here->MOS2sensxpgs +
483 10*(iparmno - 1) + 1);
484
485 Osxpgd = tag0 * *(ckt->CKTstate1 + here->MOS2sensxpgd +
486 10*(iparmno - 1))
487 + tag1 * *(ckt->CKTstate1 + here->MOS2sensxpgd +
488 10*(iparmno - 1) + 1);
489
490 Osxpbs = tag0 * *(ckt->CKTstate1 + here->MOS2sensxpbs +
491 10*(iparmno - 1))
492 + tag1 * *(ckt->CKTstate1 + here->MOS2sensxpbs +
493 10*(iparmno - 1) + 1);
494
495 Osxpbd =tag0 * *(ckt->CKTstate1 + here->MOS2sensxpbd +
496 10*(iparmno - 1))
497 + tag1 * *(ckt->CKTstate1 + here->MOS2sensxpbd +
498 10*(iparmno - 1) + 1);
499 Osxpgb = tag0 * *(ckt->CKTstate1 + here->MOS2sensxpgb +
500 10*(iparmno - 1))
501 + tag1 * *(ckt->CKTstate1 + here->MOS2sensxpgb +
502 10*(iparmno - 1) + 1);
503
504 #ifdef SENSDEBUG
505 printf("iparmno=%d\n",iparmno);
506 printf("sxpgs=%.7e,sdgs=%.7e\n",
507 *(ckt->CKTstate1 + here->MOS2sensxpgs +
508 10*(iparmno - 1)), *(ckt->CKTstate1 +
509 here->MOS2sensxpgs + 10*(iparmno - 1) + 1));
510 printf("sxpgd=%.7e,sdgd=%.7e\n",
511 *(ckt->CKTstate1 + here->MOS2sensxpgd +
512 10*(iparmno - 1)), *(ckt->CKTstate1 +
513 here->MOS2sensxpgd + 10*(iparmno - 1) + 1));
514 printf("sxpbs=%.7e,sdbs=%.7e\n",
515 *(ckt->CKTstate1 + here->MOS2sensxpbs +
516 10*(iparmno - 1)), *(ckt->CKTstate1 +
517 here->MOS2sensxpbs + 10*(iparmno - 1) + 1));
518 printf("sxpbd=%.7e,sdbd=%.7e\n",
519 *(ckt->CKTstate1 + here->MOS2sensxpbd +
520 10*(iparmno - 1)), *(ckt->CKTstate1 +
521 here->MOS2sensxpbd + 10*(iparmno - 1) + 1));
522 printf("sxpgb=%.7e,sdgb=%.7e\n",
523 *(ckt->CKTstate1 + here->MOS2sensxpgb +
524 10*(iparmno - 1)), *(ckt->CKTstate1 +
525 here->MOS2sensxpgb + 10*(iparmno - 1) + 1));
526 printf("before loading DqDp\n");
527 printf("Osxpgs=%.7e,Osxpgd=%.7e\n",Osxpgs,Osxpgd);
528 printf("Osxpbs=%.7e,Osxpbd=%.7e,Osxpgb=%.7e\n",
529 Osxpbs,Osxpbd,Osxpgb);
530 printf("\n");
531 #endif /* SENSDEBUG */
532 if(here->MOS2sens_l && (iparmno == here->MOS2senParmNo)){
533 Osxpgs -= tag0 * *(here->MOS2dphigs_dl);
534 Osxpgd -= tag0 * *(here->MOS2dphigd_dl);
535 Osxpbs -= tag0 * *(here->MOS2dphibs_dl);
536 Osxpbd -= tag0 * *(here->MOS2dphibd_dl);
537 Osxpgb -= tag0 * *(here->MOS2dphigb_dl);
538 }
539 if(here->MOS2sens_w &&
540 (iparmno == (here->MOS2senParmNo +
541 (int) here->MOS2sens_l))){
542 Osxpgs -= tag0 * *(here->MOS2dphigs_dw);
543 Osxpgd -= tag0 * *(here->MOS2dphigd_dw);
544 Osxpbs -= tag0 * *(here->MOS2dphibs_dw);
545 Osxpbd -= tag0 * *(here->MOS2dphibd_dw);
546 Osxpgb -= tag0 * *(here->MOS2dphigb_dw);
547 }
548 #ifdef SENSDEBUG
549 printf("after loading DqDp\n");
550 printf("DqgsDp=%.7e",DqgsDp);
551 printf("Osxpgs=%.7e,Osxpgd=%.7e\n",Osxpgs,Osxpgd);
552 printf("Osxpbs=%.7e,Osxpbd=%.7e,Osxpgb=%.7e\n",
553 Osxpbs,Osxpbd,Osxpgb);
554 #endif /* SENSDEBUG */
555
556 *(info->SEN_RHS[here->MOS2bNode] + iparmno) +=
557 Osxpbs + Osxpbd -Osxpgb;
558 *(info->SEN_RHS[here->MOS2gNode] + iparmno) +=
559 Osxpgs + Osxpgd + Osxpgb;
560
561 *(info->SEN_RHS[here->MOS2dNodePrime] + iparmno) -=
562 Osxpgd + Osxpbd ;
563
564 *(info->SEN_RHS[here->MOS2sNodePrime] + iparmno) -=
565 Osxpgs + Osxpbs;
566 #ifdef SENSDEBUG
567 printf("after capacitive currents\n");
568 printf("DcbDp=%.7e\n",
569 *(info->SEN_RHS[here->MOS2bNode] + iparmno));
570 printf("DcdprDp=%.7e\n",
571 *(info->SEN_RHS[here->MOS2dNode] + iparmno));
572 printf("DcdprmDp=%.7e\n",
573 *(info->SEN_RHS[here->MOS2dNodePrime] + iparmno));
574 printf("DcsprDp=%.7e\n",
575 *(info->SEN_RHS[here->MOS2sNode] + iparmno));
576 printf("DcsprmDp=%.7e\n",
577 *(info->SEN_RHS[here->MOS2sNodePrime] + iparmno));
578 #endif /* SENSDEBUG */
579
580 }
581 restore: /* put the unperturbed values back into the state vector */
582 for(i=0; i <= 16; i++)
583 *(ckt->CKTstate0 + here->MOS2states + i) = *(SaveState + i);
584 here->MOS2sourceConductance = *(SaveState + 17) ;
585 here->MOS2drainConductance = *(SaveState + 18) ;
586 here->MOS2cd = *(SaveState + 19) ;
587 here->MOS2cbs = *(SaveState + 20) ;
588 here->MOS2cbd = *(SaveState + 21) ;
589 here->MOS2gmbs = *(SaveState + 22) ;
590 here->MOS2gm = *(SaveState + 23) ;
591 here->MOS2gds = *(SaveState + 24) ;
592 here->MOS2gbd = *(SaveState + 25) ;
593 here->MOS2gbs = *(SaveState + 26) ;
594 here->MOS2capbd = *(SaveState + 27) ;
595 here->MOS2capbs = *(SaveState + 28) ;
596 here->MOS2Cbd = *(SaveState + 29) ;
597 here->MOS2Cbdsw = *(SaveState + 30) ;
598 here->MOS2Cbs = *(SaveState + 31) ;
599 here->MOS2Cbssw = *(SaveState + 32) ;
600 here->MOS2f2d = *(SaveState + 33) ;
601 here->MOS2f3d = *(SaveState + 34) ;
602 here->MOS2f4d = *(SaveState + 35) ;
603 here->MOS2f2s = *(SaveState + 36) ;
604 here->MOS2f3s = *(SaveState + 37) ;
605 here->MOS2f4s = *(SaveState + 38) ;
606 here->MOS2cgs = *(SaveState + 39) ;
607 here->MOS2cgd = *(SaveState + 40) ;
608 here->MOS2cgb = *(SaveState + 41) ;
609 here->MOS2vdsat = *(SaveState + 42) ;
610 here->MOS2von = *(SaveState + 43) ;
611 here->MOS2mode = save_mode ;
612
613 here->MOS2senPertFlag = OFF;
614
615 }
616 }
617 info->SENstatus = NORMAL;
618 #ifdef SENSDEBUG
619 printf("MOS2senload end\n");
620 #endif /* SENSDEBUG */
621 return(OK);
622 }
623
624