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 ac sensitivity
9 * information into the array previously provided
10 */
11
12 #include "ngspice/ngspice.h"
13 #include "ngspice/cktdefs.h"
14 #include "ngspice/smpdefs.h"
15 #include "bjtdefs.h"
16 #include "ngspice/const.h"
17 #include "ngspice/sperror.h"
18 #include "ngspice/ifsim.h"
19 #include "ngspice/suffix.h"
20
21
22 int
BJTsAcLoad(GENmodel * inModel,CKTcircuit * ckt)23 BJTsAcLoad(GENmodel *inModel, CKTcircuit *ckt)
24 {
25
26 BJTmodel *model = (BJTmodel*)inModel;
27 BJTinstance *here;
28 double SaveState[25];
29 int error;
30 int flag;
31 double vbeOp;
32 double vbcOp;
33 double A0;
34 double DELA = 0.0;
35 double Apert;
36 double DELAinv;
37 double vte = 0.0;
38 double gcpr;
39 double gepr;
40 double gpi;
41 double gmu;
42 double go;
43 double xgm;
44 double td;
45 double arg;
46 double gm;
47 double gx;
48 double xcpi;
49 double xcmu;
50 double xcbx;
51 double xccs;
52 double xcmcb;
53 double cx,icx;
54 double cbx,icbx;
55 double ccs,iccs;
56 double cbc,icbc;
57 double cbe,icbe;
58 double cce,icce;
59 double cb,icb;
60 double cbprm,icbprm;
61 double cc,icc;
62 double ccprm,iccprm;
63 double ce,ice;
64 double ceprm,iceprm;
65 double cs,ics;
66 double vcpr,ivcpr;
67 double vepr,ivepr;
68 double vx,ivx;
69 double vbx,ivbx;
70 double vcs,ivcs;
71 double vbc,ivbc;
72 double vbe,ivbe;
73 double vce,ivce;
74 double cb0,icb0;
75 double cbprm0,icbprm0;
76 double cc0,icc0;
77 double ccprm0,iccprm0;
78 double ce0,ice0;
79 double ceprm0,iceprm0;
80 double cs0,ics0;
81 double DvDp = 0.0;
82 int iparmno,i;
83 SENstruct *info;
84
85
86 #ifdef SENSDEBUG
87 printf("BJTsenacload \n");
88 printf("BJTsenacload \n");
89 #endif /* SENSDEBUG */
90
91 info = ckt->CKTsenInfo;
92 info->SENstatus = PERTURBATION;
93
94 /* loop through all the models */
95 for( ; model != NULL; model = BJTnextModel(model)) {
96
97 /* loop through all the instances of the model */
98 for (here = BJTinstances(model); here != NULL ;
99 here=BJTnextInstance(here)) {
100
101
102 /* save the unperturbed values in the state vector */
103 for(i=0; i <= 20; i++) {
104 *(SaveState + i) = *(ckt->CKTstate0 + here->BJTstate + i);
105 }
106
107 vcpr = *(ckt->CKTrhsOld + here->BJTcolNode)
108 - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ;
109 ivcpr = *(ckt->CKTirhsOld + here->BJTcolNode)
110 - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ;
111 vepr = *(ckt->CKTrhsOld + here->BJTemitNode)
112 - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ;
113 ivepr = *(ckt->CKTirhsOld + here->BJTemitNode)
114 - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ;
115 vx = *(ckt->CKTrhsOld + here->BJTbaseNode)
116 - *(ckt->CKTrhsOld + here->BJTbasePrimeNode) ;/* vb_bprm */
117 ivx = *(ckt->CKTirhsOld + here->BJTbaseNode)
118 - *(ckt->CKTirhsOld + here->BJTbasePrimeNode) ;/* ivb_bprm */
119 vcs = *(ckt->CKTrhsOld + here->BJTcolPrimeNode)
120 - *(ckt->CKTrhsOld + here->BJTsubstNode) ;
121 ivcs = *(ckt->CKTirhsOld + here->BJTcolPrimeNode)
122 - *(ckt->CKTirhsOld + here->BJTsubstNode) ;
123 vbc = *(ckt->CKTrhsOld + here->BJTbasePrimeNode)
124 - *(ckt->CKTrhsOld + here->BJTcolPrimeNode) ;/* vbprm_cprm */
125 ivbc = *(ckt->CKTirhsOld + here->BJTbasePrimeNode)
126 - *(ckt->CKTirhsOld + here->BJTcolPrimeNode) ;/* ivbprm_cprm */
127 vbe = *(ckt->CKTrhsOld + here->BJTbasePrimeNode)
128 - *(ckt->CKTrhsOld + here->BJTemitPrimeNode) ;/* vbprm_eprm */
129 ivbe = *(ckt->CKTirhsOld + here->BJTbasePrimeNode)
130 - *(ckt->CKTirhsOld + here->BJTemitPrimeNode) ;/* ivbprm_eprm */
131 vce = vbe - vbc ;
132 ivce = ivbe - ivbc ;
133 vbx = vx + vbc ;
134 ivbx = ivx + ivbc ;
135
136
137
138 vbeOp =model->BJTtype * ( *(ckt->CKTrhsOp + here->BJTbasePrimeNode)
139 - *(ckt->CKTrhsOp + here->BJTemitPrimeNode));
140 vbcOp =model->BJTtype * ( *(ckt->CKTrhsOp + here->BJTbasePrimeNode)
141 - *(ckt->CKTrhsOp + here->BJTcolPrimeNode));
142
143 #ifdef SENSDEBUG
144 printf("\n without perturbation\n");
145 #endif /* SENSDEBUG */
146 /* without perturbation */
147 A0 = here->BJTarea;
148 here->BJTsenPertFlag = ON;
149 *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
150 *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
151 /* info->SENacpertflag == 1 only for first frequency */
152
153 if(info->SENacpertflag == 1){
154
155 /* store the unperturbed values of small signal parameters */
156
157 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
158 return(error);
159
160 *(here->BJTsenGpi)= *(ckt->CKTstate0 + here->BJTgpi);
161 *(here->BJTsenGmu)= *(ckt->CKTstate0 + here->BJTgmu);
162 *(here->BJTsenGm)= *(ckt->CKTstate0 + here->BJTgm);
163 *(here->BJTsenGo)= *(ckt->CKTstate0 + here->BJTgo);
164 *(here->BJTsenGx)= *(ckt->CKTstate0 + here->BJTgx);
165 *(here->BJTsenCpi)= *(ckt->CKTstate0 + here->BJTcqbe);
166 *(here->BJTsenCmu)= *(ckt->CKTstate0 + here->BJTcqbc);
167 *(here->BJTsenCbx)= *(ckt->CKTstate0 + here->BJTcqbx);
168 *(here->BJTsenCsub)= *(ckt->CKTstate0 + here->BJTcqsub);
169 *(here->BJTsenCmcb)= *(ckt->CKTstate0 + here->BJTcexbc);
170 }
171 gcpr = here->BJTtcollectorConduct * A0;
172 gepr = here->BJTtemitterConduct * A0;
173 gpi= *(here->BJTsenGpi);
174 gmu= *(here->BJTsenGmu);
175 gm= *(here->BJTsenGm);
176 go= *(here->BJTsenGo);
177 gx= *(here->BJTsenGx);
178 xgm=0;
179 td=model->BJTexcessPhase;
180 if(td != 0) {
181 arg = td*ckt->CKTomega;
182 gm = gm+go;
183 xgm = -gm * sin(arg);
184 gm = gm * cos(arg)-go;
185 }
186 xcpi= *(here->BJTsenCpi) * ckt->CKTomega;
187 xcmu= *(here->BJTsenCmu) * ckt->CKTomega;
188 xcbx= *(here->BJTsenCbx) * ckt->CKTomega;
189 xccs= *(here->BJTsenCsub) * ckt->CKTomega;
190 xcmcb= *(here->BJTsenCmcb) * ckt->CKTomega;
191
192
193 cx=gx * vx ;
194 icx=gx * ivx;
195 cbx=( -xcbx * ivbx) ;
196 icbx= xcbx * vbx ;
197 ccs=( -xccs * ivcs) ;
198 iccs= xccs * vcs ;
199 cbc=(gmu * vbc -xcmu * ivbc) ;
200 icbc=xcmu * vbc + gmu * ivbc ;
201 cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ;
202 icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc;
203 cce= go * vce + gm * vbe - xgm * ivbe;
204 icce=go * ivce + gm * ivbe + xgm * vbe ;
205
206 cc0=gcpr * vcpr ;
207 icc0=gcpr * ivcpr ;
208 ce0=gepr * vepr;
209 ice0=gepr * ivepr ;
210 cb0 = cx + cbx;
211 icb0 = icx + icbx;
212 if(here->BJTbaseNode != here->BJTbasePrimeNode){
213 cbprm0 = (- cx + cbe + cbc);
214 icbprm0 = (- icx + icbe + icbc);
215 }
216 else{
217 cbprm0 = ( cbx + cbe + cbc);
218 icbprm0 = (icbx + icbe + icbc);
219 }
220 ccprm0 = (- cbx - cc0 + ccs + cce - cbc);
221 iccprm0 = (- icbx - icc0 + iccs + icce - icbc);
222 ceprm0 = (- cbe - cce - ce0);
223 iceprm0 = (- icbe - icce - ice0);
224 cs0 = (- ccs) ;
225 ics0 = (- iccs) ;
226
227 #ifdef SENSDEBUG
228 printf("gepr0 = %.7e , gcpr0 = %.7e , gmu0 = %.7e, gpi0 = %.7e\n",
229 gepr,gcpr,gmu,gpi);
230 printf("gm0 = %.7e , go0 = %.7e , gx0 = %.7e, xcpi0 = %.7e\n",
231 gm,go,gx,xcpi);
232 printf("xcmu0 = %.7e , xcbx0 = %.7e , xccs0 = %.7e, xcmcb0 = %.7e\n"
233 ,xcmu,xcbx,xccs,xcmcb);
234 printf("vepr = %.7e + j%.7e , vcpr = %.7e + j%.7e\n",
235 vepr,ivepr,vcpr,ivcpr);
236 printf("vbx = %.7e + j%.7e , vx = %.7e + j%.7e\n",
237 vbx,ivbx,vx,ivx);
238 printf("vbc = %.7e + j%.7e , vbe = %.7e + j%.7e\n",
239 vbc,ivbc,vbe,ivbe);
240 printf("vce = %.7e + j%.7e , vcs = %.7e + j%.7e\n",
241 vce,ivce,vcs,ivcs);
242 printf("cce0 = %.7e + j%.7e , cbe0 = %.7e + j%.7e\n",
243 cce,icce,cbe,icbe);
244 printf("cbc0 = %.7e + j%.7e\n",
245 cbc,icbc);
246 printf("cc0 = %.7e + j%.7e , ce0 = %.7e + j%.7e\n",
247 cc0,icc0,ce0,ice0);
248 printf("cb0 = %.7e + j%.7e , cs0 = %.7e + j%.7e\n",
249 cb0,icb0,cs0,ics0);
250 printf("cbprm0 = %.7e + j%.7e , ceprm0 = %.7e + j%.7e\n",
251 cbprm0,icbprm0,ceprm0,iceprm0);
252 printf("ccprm0 = %.7e + j%.7e \n",
253 ccprm0,iccprm0);
254 printf("\nPerturbation of Area\n");
255 #endif /* SENSDEBUG */
256 /* Perturbation of Area */
257 if(here->BJTsenParmNo == 0){
258 flag = 0;
259 goto next1;
260 }
261
262 DELA = info->SENpertfac * A0;
263 Apert = A0 + DELA;
264 DELAinv = 1.0/DELA;
265 here->BJTarea = Apert;
266
267 *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
268 *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
269 if(info->SENacpertflag == 1){
270
271 /* store the small signal parameters
272 * corresponding to perturbed area
273 */
274 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
275 return(error);
276
277 *(here->BJTsenGpi + 1)= *(ckt->CKTstate0 + here->BJTgpi);
278 *(here->BJTsenGmu + 1)= *(ckt->CKTstate0 + here->BJTgmu);
279 *(here->BJTsenGm + 1)= *(ckt->CKTstate0 + here->BJTgm);
280 *(here->BJTsenGo + 1)= *(ckt->CKTstate0 + here->BJTgo);
281 *(here->BJTsenGx + 1)= *(ckt->CKTstate0 + here->BJTgx);
282 *(here->BJTsenCpi + 1)= *(ckt->CKTstate0 + here->BJTcqbe);
283 *(here->BJTsenCmu + 1)= *(ckt->CKTstate0 + here->BJTcqbc);
284 *(here->BJTsenCbx + 1)= *(ckt->CKTstate0 + here->BJTcqbx);
285 *(here->BJTsenCsub + 1)= *(ckt->CKTstate0 + here->BJTcqsub);
286 *(here->BJTsenCmcb + 1)= *(ckt->CKTstate0 + here->BJTcexbc);
287 }
288
289
290 flag = 0;
291 goto load;
292
293
294
295 pertvbx: /* Perturbation of vbx */
296 #ifdef SENSDEBUG
297 printf("\nPerturbation of vbx\n");
298 #endif /* SENSDEBUG */
299 here->BJTarea = A0;
300 A0 = model->BJTtype * (*(ckt->CKTrhsOp + here->BJTbaseNode)
301 - *(ckt->CKTrhsOp + here->BJTcolPrimeNode));
302 DELA = info->SENpertfac * A0 + 1e-8;
303 Apert = A0 + DELA;
304 DELAinv = model->BJTtype * 1.0/DELA;
305 *(ckt->CKTrhsOp + here->BJTbaseNode) += DELA;
306 *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
307 *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
308
309 if(info->SENacpertflag == 1){
310
311 /* store the small signal parameters
312 * corresponding to perturbed vbx
313 */
314 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
315 return(error);
316
317 *(here->BJTsenGpi + 2)= *(ckt->CKTstate0 + here->BJTgpi);
318 *(here->BJTsenGmu + 2)= *(ckt->CKTstate0 + here->BJTgmu);
319 *(here->BJTsenGm + 2)= *(ckt->CKTstate0 + here->BJTgm);
320 *(here->BJTsenGo + 2)= *(ckt->CKTstate0 + here->BJTgo);
321 *(here->BJTsenGx + 2)= *(ckt->CKTstate0 + here->BJTgx);
322 *(here->BJTsenCpi + 2)= *(ckt->CKTstate0 + here->BJTcqbe);
323 *(here->BJTsenCmu + 2)= *(ckt->CKTstate0 + here->BJTcqbc);
324 *(here->BJTsenCbx + 2)= *(ckt->CKTstate0 + here->BJTcqbx);
325 *(here->BJTsenCsub + 2)= *(ckt->CKTstate0 + here->BJTcqsub);
326 *(here->BJTsenCmcb + 2)= *(ckt->CKTstate0 + here->BJTcexbc);
327 }
328
329
330 flag = 1;
331 goto load;
332
333
334 pertvbe: /* Perturbation of vbe */
335 #ifdef SENSDEBUG
336 printf("\nPerturbation of vbe\n");
337 #endif /* SENSDEBUG */
338 if (*(here->BJTsenCbx) != 0){
339 *(ckt->CKTrhsOp + here ->BJTbaseNode) -= DELA;
340 }
341 vte=model->BJTleakBEemissionCoeff*CONSTvt0;
342 A0 = vbeOp;
343 DELA = info->SENpertfac * vte ;
344 Apert = A0 + DELA;
345 DELAinv = 1.0/DELA;
346 *(ckt->CKTstate0 + here->BJTvbe) = Apert;
347 *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
348
349 if(info->SENacpertflag == 1){
350
351 /* store the small signal parameters
352 * corresponding to perturbed vbe
353 */
354 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
355 return(error);
356
357 *(here->BJTsenGpi + 3)= *(ckt->CKTstate0 + here->BJTgpi);
358 *(here->BJTsenGmu + 3)= *(ckt->CKTstate0 + here->BJTgmu);
359 *(here->BJTsenGm + 3)= *(ckt->CKTstate0 + here->BJTgm);
360 *(here->BJTsenGo + 3)= *(ckt->CKTstate0 + here->BJTgo);
361 *(here->BJTsenGx + 3)= *(ckt->CKTstate0 + here->BJTgx);
362 *(here->BJTsenCpi + 3)= *(ckt->CKTstate0 + here->BJTcqbe);
363 *(here->BJTsenCmu + 3)= *(ckt->CKTstate0 + here->BJTcqbc);
364 *(here->BJTsenCbx + 3)= *(ckt->CKTstate0 + here->BJTcqbx);
365 *(here->BJTsenCsub + 3)= *(ckt->CKTstate0 + here->BJTcqsub);
366 *(here->BJTsenCmcb + 3)= *(ckt->CKTstate0 + here->BJTcexbc);
367 }
368
369
370 flag = 2;
371 goto load;
372
373
374 pertvbc: /* Perturbation of vbc */
375 #ifdef SENSDEBUG
376 printf("\nPerturbation of vbc\n");
377 #endif /* SENSDEBUG */
378 *(ckt->CKTstate0 + here->BJTvbe) = A0;
379
380 A0 = vbcOp;
381 DELA = info->SENpertfac * vte ;
382 Apert = A0 + DELA;
383 DELAinv = 1.0/DELA;
384
385
386 *(ckt->CKTstate0 + here->BJTvbc) = Apert;
387
388 *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
389
390
391
392 if(info->SENacpertflag == 1){
393
394 /* store the small signal parameters
395 * corresponding to perturbed vbc
396 */
397 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
398 return(error);
399 *(here->BJTsenGpi + 4)= *(ckt->CKTstate0 + here->BJTgpi);
400 *(here->BJTsenGmu + 4)= *(ckt->CKTstate0 + here->BJTgmu);
401 *(here->BJTsenGm + 4)= *(ckt->CKTstate0 + here->BJTgm);
402 *(here->BJTsenGo + 4)= *(ckt->CKTstate0 + here->BJTgo);
403 *(here->BJTsenGx + 4)= *(ckt->CKTstate0 + here->BJTgx);
404 *(here->BJTsenCpi + 4)= *(ckt->CKTstate0 + here->BJTcqbe);
405 *(here->BJTsenCmu + 4)= *(ckt->CKTstate0 + here->BJTcqbc);
406 *(here->BJTsenCbx + 4)= *(ckt->CKTstate0 + here->BJTcqbx);
407 *(here->BJTsenCsub + 4)= *(ckt->CKTstate0 + here->BJTcqsub);
408 *(here->BJTsenCmcb + 4)= *(ckt->CKTstate0 + here->BJTcexbc);
409
410 }
411
412
413 flag = 3;
414 goto load;
415
416
417
418 pertvcs: /* Perturbation of vcs */
419 #ifdef SENSDEBUG
420 printf("\nPerturbation of vcs\n");
421 #endif /* SENSDEBUG */
422 *(ckt->CKTstate0 + here->BJTvbc) = A0;
423 A0 = model->BJTtype * (*(ckt->CKTrhsOp + here->BJTsubstNode)
424 - *(ckt->CKTrhsOp + here->BJTcolPrimeNode));
425 DELA = info->SENpertfac * A0 + 1e-8;
426 Apert = A0 + DELA;
427 DELAinv = model->BJTtype * 1.0/DELA;
428 *(ckt->CKTrhsOp + here->BJTsubstNode) += DELA;
429 *(ckt->CKTstate0 + here->BJTvbe) = vbeOp;
430 *(ckt->CKTstate0 + here->BJTvbc) = vbcOp;
431
432 if(info->SENacpertflag == 1){
433
434 /* store the small signal parameters
435 * corresponding to perturbed vcs
436 */
437 if ((error = BJTload((GENmodel*)model,ckt)) != 0)
438 return(error);
439 *(here->BJTsenCsub + 5)= *(ckt->CKTstate0 + here->BJTcqsub);
440
441 }
442
443
444 flag = 4;
445
446 *(ckt->CKTrhsOp + here->BJTsubstNode) -= DELA;
447 xccs= *(here->BJTsenCsub + 5) * ckt->CKTomega;
448
449 ccs=( -xccs * ivcs) ;
450 iccs= xccs * vcs ;
451 cs = -ccs;
452 ics = -iccs;
453 ccprm = ccprm0 + cs0 - cs;
454 iccprm = iccprm0 + ics0 - ics;
455 cbprm = cbprm0;
456 icbprm = icbprm0;
457 ceprm = ceprm0;
458 iceprm = iceprm0;
459 cc = cc0;
460 icc = icc0;
461 ce = ce0;
462 ice = ice0;
463 cb = cb0;
464 icb = icb0;
465 goto next2;
466
467 load:
468 gcpr=here->BJTtcollectorConduct * here->BJTarea;
469 gepr=here->BJTtemitterConduct * here->BJTarea;
470 gpi= *(here->BJTsenGpi + flag+1);
471 gmu= *(here->BJTsenGmu + flag+1);
472 gm= *(here->BJTsenGm + flag+1);
473 go= *(here->BJTsenGo + flag+1);
474 gx= *(here->BJTsenGx + flag+1);
475 xgm=0;
476 td=model->BJTexcessPhase;
477 if(td != 0) {
478 arg = td*ckt->CKTomega;
479 gm = gm+go;
480 xgm = -gm * sin(arg);
481 gm = gm * cos(arg)-go;
482 }
483 xcpi= *(here->BJTsenCpi + flag+1) * ckt->CKTomega;
484 xcmu= *(here->BJTsenCmu + flag+1) * ckt->CKTomega;
485 xcbx= *(here->BJTsenCbx + flag+1) * ckt->CKTomega;
486 xccs= *(here->BJTsenCsub + flag+1) * ckt->CKTomega;
487 xcmcb= *(here->BJTsenCmcb + flag+1) * ckt->CKTomega;
488
489
490 cc=gcpr * vcpr ;
491 icc=gcpr * ivcpr ;
492 ce=gepr * vepr;
493 ice=gepr * ivepr ;
494 cx=gx * vx ;
495 icx=gx * ivx;
496 cbx=( -xcbx * ivbx) ;
497 icbx= xcbx * vbx ;
498 ccs=( -xccs * ivcs) ;
499 iccs= xccs * vcs ;
500 cbc=(gmu * vbc -xcmu * ivbc) ;
501 icbc=xcmu * vbc + gmu * ivbc ;
502 cbe=gpi * vbe -xcpi * ivbe - xcmcb * ivbc ;
503 icbe=xcpi * vbe + gpi * ivbe + xcmcb * vbc;
504 cce= go * vce + gm * vbe - xgm * ivbe;
505 icce=go * ivce + gm * ivbe + xgm * vbe ;
506
507
508 cb= cx + cbx;
509 icb= icx + icbx;
510 if(here->BJTbaseNode != here->BJTbasePrimeNode){
511 cbprm=(- cx + cbe + cbc);
512 icbprm=(- icx + icbe + icbc);
513 }
514 else{
515 cbprm=( cbx + cbe + cbc);
516 icbprm=(icbx + icbe + icbc);
517 }
518 ccprm=(- cbx - cc + ccs + cce - cbc);
519 iccprm=(- icbx - icc + iccs + icce - icbc);
520 ceprm=(- cbe - cce - ce);
521 iceprm=(- icbe - icce - ice);
522 cs= (- ccs) ;
523 ics= (- iccs) ;
524
525 #ifdef SENSDEBUG
526 printf("A0 = %.7e , Apert = %.7e , DELA = %.7e\n"
527 ,A0,Apert,DELA);
528 printf("gepr = %.7e , gcpr = %.7e , gmu = %.7e, gpi = %.7e\n"
529 ,gepr,gcpr,gmu,gpi);
530 printf("gm = %.7e , go = %.7e , gx = %.7e, xcpi = %.7e\n"
531 ,gm,go,gx,xcpi);
532 printf("xcmu = %.7e , xcbx = %.7e , xccs = %.7e, xcmcb = %.7e\n"
533 ,xcmu,xcbx,xccs,xcmcb);
534
535 printf("cx = %.7e + j%.7e , cbx = %.7e + j%.7e\n"
536 ,cx,icx,cbx,icbx);
537 printf("ccs %.7e + j%.7e , cbc = %.7e + j%.7e"
538 ,ccs,iccs,cbc,icbc);
539 printf("cbe %.7e + j%.7e , cce = %.7e + j%.7e\n"
540 ,cbe,icbe,cce,icce);
541
542 printf("cc = %.7e + j%.7e , ce = %.7e + j%.7e,",
543 cc,icc,ce,ice);
544 printf("ccprm = %.7e + j%.7e , ceprm = %.7e + j%.7e",
545 ccprm,iccprm,ceprm,iceprm);
546 printf("cb = %.7e + j%.7e , cbprm = %.7e + j%.7e , ",
547 cb,icb,cbprm,icbprm);
548 printf("cs = %.7e + j%.7e\n",
549 cs,ics);
550 #endif /* SENSDEBUG */
551
552
553 /* load the RHS matrix */
554 next2:
555 for(iparmno = 1;iparmno<=info->SENparms;iparmno++){
556 if( (!flag) && (iparmno != here->BJTsenParmNo) ) continue;
557 switch(flag){
558
559 case 0:
560 /* area : so no DC sensitivity term involved */
561 DvDp = 1.0;
562
563 break;
564 /* calculate the DC sensitivities of operating points */
565 case 1:
566 DvDp = model->BJTtype *
567 (info->SEN_Sap[here->BJTbaseNode][iparmno]
568 - info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
569 break;
570 case 2:
571 DvDp = model->BJTtype *
572 (info->SEN_Sap[here->BJTbasePrimeNode][iparmno]
573 - info->SEN_Sap[here->BJTemitPrimeNode][iparmno]);
574 break;
575 case 3:
576 DvDp = model->BJTtype *
577 (info->SEN_Sap[here->BJTbasePrimeNode][iparmno]
578 - info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
579 break;
580 case 4:
581 DvDp = model->BJTtype *
582 (info->SEN_Sap[here->BJTsubstNode][iparmno]
583 - info->SEN_Sap[here->BJTcolPrimeNode][iparmno]);
584 break;
585 }
586 #ifdef SENSDEBUG
587 printf("before loading\n");
588 printf("BJTtype = %d\n",model->BJTtype);
589 printf("DvDp = %.7e , flag = %d , iparmno = %d,senparmno = %d\n"
590 ,DvDp,flag,iparmno,here->BJTsenParmNo);
591 printf("senb = %.7e + j%.7e\n "
592 ,*(info->SEN_RHS[here->BJTbaseNode] + iparmno),
593 *(info->SEN_iRHS[here->BJTbaseNode] + iparmno));
594 printf("senbrm = %.7e + j%.7e\n "
595 ,*(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno),
596 *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno));
597 printf("senc = %.7e + j%.7e\n "
598 ,*(info->SEN_RHS[here->BJTcolNode] + iparmno),
599 *(info->SEN_iRHS[here->BJTcolNode] + iparmno));
600 printf("sencprm = %.7e + j%.7e\n "
601 ,*(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno),
602 *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno));
603 printf("sene = %.7e + j%.7e\n "
604 ,*(info->SEN_RHS[here->BJTemitNode] + iparmno),
605 *(info->SEN_iRHS[here->BJTemitNode] + iparmno));
606 printf("seneprm = %.7e + j%.7e\n "
607 ,*(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno),
608 *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno));
609 printf("sens = %.7e + j%.7e\n "
610 ,*(info->SEN_RHS[here->BJTsubstNode] + iparmno),
611 *(info->SEN_iRHS[here->BJTsubstNode] + iparmno));
612 #endif /* SENSDEBUG */
613
614
615 if(here->BJTbaseNode != here->BJTbasePrimeNode){
616 *(info->SEN_RHS[here->BJTbaseNode] + iparmno) -=
617 ( cb - cb0) * DELAinv * DvDp;
618 *(info->SEN_iRHS[here->BJTbaseNode] + iparmno) -=
619 ( icb - icb0) * DELAinv * DvDp;
620 }
621
622 *(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno) -=
623 ( cbprm - cbprm0) * DELAinv * DvDp;
624 *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno) -=
625 ( icbprm - icbprm0) * DELAinv * DvDp;
626
627 if(here->BJTcolNode != here->BJTcolPrimeNode){
628 *(info->SEN_RHS[here->BJTcolNode] + iparmno) -=
629 ( cc - cc0) * DELAinv * DvDp;
630 *(info->SEN_iRHS[here->BJTcolNode] + iparmno) -=
631 ( icc - icc0) * DELAinv * DvDp;
632 }
633
634 *(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno) -=
635 ( ccprm - ccprm0) * DELAinv * DvDp;
636 *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno) -=
637 ( iccprm - iccprm0) * DELAinv * DvDp;
638
639 if(here->BJTemitNode != here->BJTemitPrimeNode){
640 *(info->SEN_RHS[here->BJTemitNode] + iparmno) -=
641 ( ce - ce0) * DELAinv * DvDp;
642 *(info->SEN_iRHS[here->BJTemitNode] + iparmno) -=
643 ( ice - ice0) * DELAinv * DvDp;
644 }
645
646 *(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno) -=
647 ( ceprm - ceprm0) * DELAinv * DvDp;
648 *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno) -=
649 ( iceprm - iceprm0) * DELAinv * DvDp;
650 *(info->SEN_RHS[here->BJTsubstNode] + iparmno) -=
651 ( cs - cs0) * DELAinv * DvDp;
652 *(info->SEN_iRHS[here->BJTsubstNode] + iparmno) -=
653 ( ics - ics0) * DELAinv * DvDp;
654 #ifdef SENSDEBUG
655 printf("after loading\n");
656
657 printf("senb = %.7e + j%.7e\n "
658 ,*(info->SEN_RHS[here->BJTbaseNode] + iparmno),
659 *(info->SEN_iRHS[here->BJTbaseNode] + iparmno));
660 printf("senbrm = %.7e + j%.7e\n "
661 ,*(info->SEN_RHS[here->BJTbasePrimeNode] + iparmno),
662 *(info->SEN_iRHS[here->BJTbasePrimeNode] + iparmno));
663 printf("senc = %.7e + j%.7e\n "
664 ,*(info->SEN_RHS[here->BJTcolNode] + iparmno),
665 *(info->SEN_iRHS[here->BJTcolNode] + iparmno));
666 printf("sencprm = %.7e + j%.7e\n "
667 ,*(info->SEN_RHS[here->BJTcolPrimeNode] + iparmno),
668 *(info->SEN_iRHS[here->BJTcolPrimeNode] + iparmno));
669 printf("sene = %.7e + j%.7e\n "
670 ,*(info->SEN_RHS[here->BJTemitNode] + iparmno),
671 *(info->SEN_iRHS[here->BJTemitNode] + iparmno));
672 printf("seneprm = %.7e + j%.7e\n "
673 ,*(info->SEN_RHS[here->BJTemitPrimeNode] + iparmno),
674 *(info->SEN_iRHS[here->BJTemitPrimeNode] + iparmno));
675 printf("sens = %.7e + j%.7e\n "
676 ,*(info->SEN_RHS[here->BJTsubstNode] + iparmno),
677 *(info->SEN_iRHS[here->BJTsubstNode] + iparmno));
678 #endif /* SENSDEBUG */
679
680 }
681
682
683 next1:
684 switch(flag){
685 case 0:
686 if (*(here->BJTsenCbx) == 0){
687 here->BJTarea = A0;
688 goto pertvbe ;
689 }
690 else{
691 goto pertvbx;
692 }
693 case 1:
694 goto pertvbe ;
695 case 2:
696 goto pertvbc ;
697 case 3:
698 goto pertvcs ;
699 case 4:
700 break;
701 }
702
703 /* put the unperturbed values back into the state vector */
704 for(i=0; i <= 20; i++) {
705 *(ckt->CKTstate0 + here->BJTstate + i) = *(SaveState + i);
706 }
707 here->BJTsenPertFlag = OFF;
708 }
709
710 }
711 info->SENstatus = NORMAL;
712 #ifdef SENSDEBUG
713 printf("BJTsenacload end\n");
714 #endif /* SENSDEBUG */
715 return(OK);
716 }
717
718