Branch data Line data Source code
1 : : /*
2 : : * phototransistor.core.cpp - device implementations for phototransistor module
3 : : *
4 : : * This is free software; you can redistribute it and/or modify
5 : : * it under the terms of the GNU General Public License as published by
6 : : * the Free Software Foundation; either version 2, or (at your option)
7 : : * any later version.
8 : : *
9 : : */
10 : :
11 : : #if HAVE_CONFIG_H
12 : : #include <config.h>
13 : : #endif
14 : :
15 : : #include "phototransistor.analogfunction.h"
16 : : #include "component.h"
17 : : #include "device.h"
18 : : #include "phototransistor.core.h"
19 : :
20 : : #ifndef CIR_phototransistor
21 : : #define CIR_phototransistor -1
22 : : #endif
23 : :
24 : : // external nodes
25 : : #define Collector 0
26 : : #define Base 1
27 : : #define Emitter 2
28 : : #define Power 3
29 : : #define Wavelength 4
30 : : // internal nodes
31 : : #define CI 5
32 : : #define BI 6
33 : : #define BI2 7
34 : : #define EI 8
35 : :
36 : : // useful macro definitions
37 : : #define NP(node) real (getV (node))
38 : : #define BP(pnode,nnode) (NP(pnode) - NP(nnode))
39 : : #define _load_static_residual2(pnode,nnode,current)\
40 : : _rhs[pnode] -= current;\
41 : : _rhs[nnode] += current;
42 : : #define _load_static_augmented_residual2(pnode,nnode,current)\
43 : : _rhs[pnode] -= current;\
44 : : _rhs[nnode] += current;
45 : : #define _load_static_residual1(node,current)\
46 : : _rhs[node] -= current;
47 : : #define _load_static_augmented_residual1(node,current)\
48 : : _rhs[node] -= current;
49 : : #define _load_static_jacobian4(pnode,nnode,vpnode,vnnode,conductance)\
50 : : _jstat[pnode][vpnode] += conductance;\
51 : : _jstat[nnode][vnnode] += conductance;\
52 : : _jstat[pnode][vnnode] -= conductance;\
53 : : _jstat[nnode][vpnode] -= conductance;\
54 : : if (doHB) {\
55 : : _ghs[pnode] += conductance * BP(vpnode,vnnode);\
56 : : _ghs[nnode] -= conductance * BP(vpnode,vnnode);\
57 : : } else {\
58 : : _rhs[pnode] += conductance * BP(vpnode,vnnode);\
59 : : _rhs[nnode] -= conductance * BP(vpnode,vnnode);\
60 : : }
61 : : #define _load_static_jacobian2p(node,vpnode,vnnode,conductance)\
62 : : _jstat[node][vpnode] += conductance;\
63 : : _jstat[node][vnnode] -= conductance;\
64 : : if (doHB) {\
65 : : _ghs[node] += conductance * BP(vpnode,vnnode);\
66 : : } else {\
67 : : _rhs[node] += conductance * BP(vpnode,vnnode);\
68 : : }
69 : : #define _load_static_jacobian2s(pnode,nnode,node,conductance)\
70 : : _jstat[pnode][node] += conductance;\
71 : : _jstat[nnode][node] -= conductance;\
72 : : if (doHB) {\
73 : : _ghs[pnode] += conductance * NP(node);\
74 : : _ghs[nnode] -= conductance * NP(node);\
75 : : } else {\
76 : : _rhs[pnode] += conductance * NP(node);\
77 : : _rhs[nnode] -= conductance * NP(node);\
78 : : }
79 : : #define _load_static_jacobian1(node,vnode,conductance)\
80 : : _jstat[node][vnode] += conductance;\
81 : : if (doHB) {\
82 : : _ghs[node] += conductance * NP(vnode);\
83 : : } else {\
84 : : _rhs[node] += conductance * NP(vnode);\
85 : : }
86 : : #define _load_dynamic_residual2(pnode,nnode,charge)\
87 : : if (doTR) _charges[pnode][nnode] += charge;\
88 : : if (doHB) {\
89 : : _qhs[pnode] -= charge;\
90 : : _qhs[nnode] += charge;\
91 : : }
92 : : #define _load_dynamic_residual1(node,charge)\
93 : : if (doTR) _charges[node][node] += charge;\
94 : : if (doHB) {\
95 : : _qhs[node] -= charge;\
96 : : }
97 : : #define _load_dynamic_jacobian4(pnode,nnode,vpnode,vnnode,capacitance)\
98 : : if (doAC) {\
99 : : _jdyna[pnode][vpnode] += capacitance;\
100 : : _jdyna[nnode][vnnode] += capacitance;\
101 : : _jdyna[pnode][vnnode] -= capacitance;\
102 : : _jdyna[nnode][vpnode] -= capacitance;\
103 : : }\
104 : : if (doTR) {\
105 : : _caps[pnode][nnode][vpnode][vnnode] += capacitance;\
106 : : }\
107 : : if (doHB) {\
108 : : _chs[pnode] += capacitance * BP(vpnode,vnnode);\
109 : : _chs[nnode] -= capacitance * BP(vpnode,vnnode);\
110 : : }
111 : : #define _load_dynamic_jacobian2s(pnode,nnode,vnode,capacitance)\
112 : : if (doAC) {\
113 : : _jdyna[pnode][vnode] += capacitance;\
114 : : _jdyna[nnode][vnode] -= capacitance;\
115 : : }\
116 : : if (doTR) {\
117 : : _caps[pnode][nnode][vnode][vnode] += capacitance;\
118 : : }\
119 : : if (doHB) {\
120 : : _chs[pnode] += capacitance * NP(vnode);\
121 : : _chs[nnode] -= capacitance * NP(vnode);\
122 : : }
123 : : #define _load_dynamic_jacobian2p(node,vpnode,vnnode,capacitance)\
124 : : if (doAC) {\
125 : : _jdyna[node][vpnode] += capacitance;\
126 : : _jdyna[node][vnnode] -= capacitance;\
127 : : }\
128 : : if (doTR) {\
129 : : _caps[node][node][vpnode][vnnode] += capacitance;\
130 : : }\
131 : : if (doHB) {\
132 : : _chs[node] += capacitance * BP(vpnode,vnnode);\
133 : : }
134 : : #define _load_dynamic_jacobian1(node,vnode,capacitance)\
135 : : if (doAC) {\
136 : : _jdyna[node][vnode] += capacitance;\
137 : : }\
138 : : if (doTR) {\
139 : : _caps[node][node][vnode][vnode] += capacitance;\
140 : : }\
141 : : if (doHB) {\
142 : : _chs[node] += capacitance * NP(vnode);\
143 : : }
144 : :
145 : : #define _save_whitenoise1(n1,pwr,type)\
146 : : _white_pwr[n1][n1] += pwr;
147 : : #define _save_whitenoise2(n1,n2,pwr,type)\
148 : : _white_pwr[n1][n2] += pwr;
149 : : #define _save_flickernoise1(n1,pwr,exp,type)\
150 : : _flicker_pwr[n1][n1] += pwr;\
151 : : _flicker_exp[n1][n1] += exp;
152 : : #define _save_flickernoise2(n1,n2,pwr,exp,type)\
153 : : _flicker_pwr[n1][n2] += pwr;\
154 : : _flicker_exp[n1][n2] += exp;
155 : : #define _load_whitenoise2(n1,n2,pwr)\
156 : : cy (n1,n2) -= pwr/kB/T0; cy (n2,n1) -= pwr/kB/T0;\
157 : : cy (n1,n1) += pwr/kB/T0; cy (n2,n2) += pwr/kB/T0;
158 : : #define _load_whitenoise1(n1,pwr)\
159 : : cy (n1,n1) += pwr/kB/T0;
160 : : #define _load_flickernoise2(n1,n2,pwr,exp)\
161 : : cy (n1,n2) -= pwr*pow(_freq,-exp)/kB/T0;\
162 : : cy (n2,n1) -= pwr*pow(_freq,-exp)/kB/T0;\
163 : : cy (n1,n1) += pwr*pow(_freq,-exp)/kB/T0;\
164 : : cy (n2,n2) += pwr*pow(_freq,-exp)/kB/T0;
165 : : #define _load_flickernoise1(n1,pwr,exp)\
166 : : cy (n1,n1) += pwr*pow(_freq,-exp)/kB/T0;
167 : :
168 : : // derivative helper macros
169 : : // transcendental LRM p. 59
170 : : #define m00_cos(v00,x) v00 = cos(x);
171 : : #define m10_cos(v10,v00,x) v10 = (-sin(x));
172 : : #define m00_sin(v00,x) v00 = sin(x);
173 : : #define m10_sin(v10,v00,x) v10 = (cos(x));
174 : : #define m00_tan(v00,x) v00 = tan(x);
175 : : #define m10_tan(v10,v00,x) v10 = (1.0/cos(x)/cos(x));
176 : : #define m00_cosh(v00,x) v00 = cosh(x);
177 : : #define m10_cosh(v10,v00,x) v10 = (sinh(x));
178 : : #define m00_sinh(v00,x) v00 = sinh(x);
179 : : #define m10_sinh(v10,v00,x) v10 = (cosh(x));
180 : : #define m00_tanh(v00,x) v00 = tanh(x);
181 : : #define m10_tanh(v10,v00,x) v10 = (1.0/cosh(x)/cosh(x));
182 : : #define m00_acos(v00,x) v00 = acos(x);
183 : : #define m10_acos(v10,v00,x) v10 = (-1.0/sqrt(1-x*x));
184 : : #define m00_asin(v00,x) v00 = asin(x);
185 : : #define m10_asin(v10,v00,x) v10 = (+1.0/sqrt(1-x*x));
186 : : #define m00_atan(v00,x) v00 = atan(x);
187 : : #define m10_atan(v10,v00,x) v10 = (+1.0/(1+x*x));
188 : : #define m00_hypot(v00,x,y) v00 = sqrt((x)*(x)+(y)*(y));
189 : : #define m10_hypot(v10,v00,x,y) v10 = (x)/(v00);
190 : : #define m11_hypot(v11,v00,x,y) v11 = (y)/(v00);
191 : : #define m00_atan2(v00,x,y) v00 = atan2(x,y);
192 : : // TODO atan2 derivatives ?
193 : : #define m00_acosh(v00,x) v00 = acosh(x);
194 : : #define m10_acosh(v10,v00,x) v10 = (1.0/(sqrt(x-1)*sqrt(x+1)));
195 : : #define m00_asinh(v00,x) v00 = asinh(x);
196 : : #define m10_asinh(v10,v00,x) v10 = (1.0/(sqrt(x*x+1)));
197 : : #define m00_atanh(v00,x) v00 = atanh(x);
198 : : #define m10_atanh(v10,v00,x) v10 = (1.0/(1-x*x));
199 : :
200 : :
201 : : // standard functions LRM p.58
202 : : #define m00_logE(v00,x) v00 = log(x);
203 : : #define m10_logE(v10,v00,x) v10 = (1.0/x);
204 : : #define m00_log10(v00,x) v00 = log10(x);
205 : : #define m10_log10(v10,v00,x) v10 = (1.0/x/M_LN10);
206 : : #define m00_exp(v00,x) v00 = exp(x);
207 : : #define m10_exp(v10,v00,x) v10 = v00;
208 : : #define m00_sqrt(v00,x) v00 = sqrt(x);
209 : : #define m10_sqrt(v10,v00,x) v10 = (0.5/v00);
210 : : #define m00_min(v00,x,y) v00 = ((x)<(y))?(x):(y);
211 : : #define m10_min(v10,v00,x,y) v10 = ((x)<(y))?1.0:0.0;
212 : : #define m11_min(v11,v00,x,y) v11 = ((x)<(y))?0.0:1.0;
213 : : #define m00_max(v00,x,y) v00 = ((x)>(y))?(x):(y);
214 : : #define m10_max(v10,v00,x,y) v10 = ((x)>(y))?1.0:0.0;
215 : : #define m11_max(v11,v00,x,y) v11 = ((x)>(y))?0.0:1.0;
216 : : #define m00_pow(v00,x,y) v00 = pow(x,y);
217 : : #define m10_pow(v10,v00,x,y) v10 = (x==0.0)?0.0:(v00)*(y)/(x);
218 : : #define m11_pow(v11,v00,x,y) v11 = (x==0.0)?0.0:(log(x)*(v00));
219 : : #define m00_abs(v00,x) v00 = ((x)<(0)?(-(x)):(x));
220 : : #define m10_abs(v10,v00,x) v10 = (((x)>=0)?(+1.0):(-1.0));
221 : : #define m00_floor(v00,x) v00 = floor(x);
222 : : #define m10_floor(v10,v00,x) v10 = 1.0;
223 : :
224 : : #define m00_ceil(v00,x) v00 = ceil(x);
225 : : // TODO ceil derivative, needed?
226 : :
227 : : // analog operator, LRM p.61
228 : : #define m00_limexp(v00,x) v00 = ((x)<80.0?exp(x):exp(80.0)*(x-79.0));
229 : : #define m10_limexp(v10,v00,x) v10 = ((x)<80.0?(v00):exp(80.0));
230 : :
231 : : // analog kernel parameter system functions, LRM p.215
232 : : #define m00_vt(x) (kBoverQ*(x))
233 : : #define m10_vt(x) (kBoverQ)
234 : :
235 : : // extra functions (?)
236 : : #define m00_div(v00,v10,x,y) double v10=1/(y); double v00=(x)*v10;
237 : : #define m10_div(v10,v00,vv,x,y)
238 : : #define m11_div(v11,v00,vv,x,y) double v11 = -v00*vv;
239 : : #define m00_mult(v00,v10,v11,x,y) double v10=(x); double v11=(y); double v00=v10*v11;
240 : : #define m00_add(v00,x,y) double v00=(x)+(y);
241 : :
242 : : // second derivatives
243 : : #define m20_logE(v00) (-1.0/v00/v00)
244 : : #define m20_exp(v00) exp(v00)
245 : : #define m20_limexp(v00) ((v00)<80.0?exp(v00):0.0)
246 : : #define m20_sqrt(v00) (-0.25/(v00)/sqrt(v00))
247 : : #define m20_abs(v00) 0.0
248 : : #define m20_pow(x,y) ((y)*((y)-1.0)*pow(x,y)/(x)/(x))
249 : :
250 : :
251 : : // simulator specific definitions
252 : : #define _modelname "phototransistor"
253 : : #define _instancename getName()
254 : : #define _circuit_temp (getPropertyDouble("Temp")+273.15)
255 : : #define _param_given(p) (isPropertyGiven(p)?1:0)
256 : :
257 : :
258 : : // $vt and $vt() functions
259 : : #define _vt_nom (kBoverQ*_circuit_temp)
260 : :
261 : : using namespace qucs::device;
262 : : using qucs::matrix;
263 : :
264 : : /* Device constructor. */
265 : 0 : phototransistor::phototransistor() : circuit (9)
266 : : {
267 : 0 : type = CIR_phototransistor;
268 : 0 : }
269 : :
270 : : /* Initialization of model. */
271 : 0 : void phototransistor::initModel (void)
272 : : {
273 : : // create internal nodes
274 : 0 : setInternalNode (CI, "CI");
275 : 0 : setInternalNode (BI, "BI");
276 : 0 : setInternalNode (BI2, "BI2");
277 : 0 : setInternalNode (EI, "EI");
278 : :
279 : : // get device model parameters
280 : 0 : loadVariables ();
281 : : // evaluate global model equations
282 : 0 : initializeModel ();
283 : : // evaluate initial step equations
284 : 0 : initialStep ();
285 : : // evaluate global instance equations
286 : 0 : initializeInstance ();
287 : 0 : }
288 : :
289 : : /* Initialization of DC analysis. */
290 : 0 : void phototransistor::initDC (void)
291 : : {
292 : 0 : allocMatrixMNA ();
293 : 0 : initModel ();
294 : 0 : pol = 1;
295 : 0 : restartDC ();
296 : 0 : doAC = 1;
297 : 0 : doTR = 0;
298 : 0 : doHB = 0;
299 : 0 : }
300 : :
301 : : /* Run when DC is restarted (fallback algorithms). */
302 : 0 : void phototransistor::restartDC (void)
303 : : {
304 : 0 : }
305 : :
306 : : /* Initialize Verilog-AMS code. */
307 : 0 : void phototransistor::initVerilog (void)
308 : : {
309 : : // initialization of noise variables
310 : 0 : _white_pwr[CI][EI] = 0.0;
311 : 0 : _white_pwr[BI][EI] = 0.0;
312 : 0 : _white_pwr[EI][Emitter] = 0.0;
313 : 0 : _white_pwr[BI2][BI] = 0.0;
314 : 0 : _white_pwr[Base][BI2] = 0.0;
315 : 0 : _white_pwr[Collector][CI] = 0.0;
316 : 0 : _flicker_pwr[BI][EI] = 0.0;
317 : 0 : _flicker_exp[BI][EI] = 0.0;
318 : :
319 : : int i1, i2, i3, i4;
320 : :
321 : : // zero charges
322 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
323 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
324 : 0 : _charges[i1][i2] = 0.0;
325 : : } }
326 : :
327 : : // zero capacitances
328 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
329 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
330 [ # # ]: 0 : for (i3 = 0; i3 < 9; i3++) {
331 [ # # ]: 0 : for (i4 = 0; i4 < 9; i4++) {
332 : 0 : _caps[i1][i2][i3][i4] = 0.0;
333 : : } } } }
334 : :
335 : : // zero right hand side, static and dynamic jacobian
336 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
337 : 0 : _rhs[i1] = 0.0;
338 : 0 : _qhs[i1] = 0.0;
339 : 0 : _chs[i1] = 0.0;
340 : 0 : _ghs[i1] = 0.0;
341 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
342 : 0 : _jstat[i1][i2] = 0.0;
343 : 0 : _jdyna[i1][i2] = 0.0;
344 : : }
345 : : }
346 : 0 : }
347 : :
348 : : /* Load device model input parameters. */
349 : 0 : void phototransistor::loadVariables (void)
350 : : {
351 : 0 : Bf = getPropertyDouble ("Bf");
352 : 0 : Br = getPropertyDouble ("Br");
353 : 0 : Is = getPropertyDouble ("Is");
354 : 0 : Nf = getPropertyDouble ("Nf");
355 : 0 : Nr = getPropertyDouble ("Nr");
356 : 0 : Vaf = getPropertyDouble ("Vaf");
357 : 0 : Var = getPropertyDouble ("Var");
358 : 0 : Mje = getPropertyDouble ("Mje");
359 : 0 : Vje = getPropertyDouble ("Vje");
360 : 0 : Cje = getPropertyDouble ("Cje");
361 : 0 : Mjc = getPropertyDouble ("Mjc");
362 : 0 : Vjc = getPropertyDouble ("Vjc");
363 : 0 : Cjc = getPropertyDouble ("Cjc");
364 : 0 : Tr = getPropertyDouble ("Tr");
365 : 0 : Tf = getPropertyDouble ("Tf");
366 : 0 : Ikf = getPropertyDouble ("Ikf");
367 : 0 : Ikr = getPropertyDouble ("Ikr");
368 : 0 : Rc = getPropertyDouble ("Rc");
369 : 0 : Re = getPropertyDouble ("Re");
370 : 0 : Rb = getPropertyDouble ("Rb");
371 : 0 : Kf = getPropertyDouble ("Kf");
372 : 0 : Ffe = getPropertyDouble ("Ffe");
373 : 0 : Af = getPropertyDouble ("Af");
374 : 0 : Responsivity = getPropertyDouble ("Responsivity");
375 : 0 : P0 = getPropertyDouble ("P0");
376 : 0 : P1 = getPropertyDouble ("P1");
377 : 0 : P2 = getPropertyDouble ("P2");
378 : 0 : P3 = getPropertyDouble ("P3");
379 : 0 : P4 = getPropertyDouble ("P4");
380 : 0 : }
381 : :
382 : : /* #define's for translated code */
383 : : #undef _DDT
384 : : #define _DDT(q) q
385 : : #define _DYNAMIC
386 : : #define _DERIVATE
387 : : #define _DDX
388 : : #define _DERIVATEFORDDX
389 : :
390 : : /* Evaluate Verilog-AMS equations in model initialization. */
391 : 0 : void phototransistor::initializeModel (void)
392 : : {
393 : 0 : }
394 : :
395 : : /* Evaluate Verilog-AMS equations in instance initialization. */
396 : 0 : void phototransistor::initializeInstance (void)
397 : : {
398 : 0 : }
399 : :
400 : : /* Evaluate Verilog-AMS equations in initial step. */
401 : 0 : void phototransistor::initialStep (void)
402 : : {
403 : : double con7;
404 : : #if defined(_DYNAMIC)
405 : : #endif
406 : : #if defined(_DYNAMIC)
407 : : #endif
408 : : #if defined(_DYNAMIC)
409 : : #endif
410 : : #if defined(_DYNAMIC)
411 : : #endif
412 : : double VT;
413 : : {
414 : 0 : VT=((1.3806503e-23*300)/1.602176462e-19);
415 : 0 : con1=(1/(Nf*VT));
416 : 0 : con2=(1/(Nr*VT));
417 : : #if defined(_DYNAMIC)
418 : 0 : con3=(1-Mje);
419 : : #endif
420 : : #if defined(_DYNAMIC)
421 : 0 : con4=(1-Mjc);
422 : : #endif
423 : : #if defined(_DYNAMIC)
424 : : {
425 : 0 : double m00_pow(d00_pow0,2,Mje)
426 : 0 : con5=d00_pow0;
427 : : }
428 : : #endif
429 : : #if defined(_DYNAMIC)
430 : : {
431 : 0 : double m00_pow(d00_pow0,2,Mjc)
432 : 0 : con6=d00_pow0;
433 : : }
434 : : #endif
435 : : #if defined(_DYNAMIC)
436 : 0 : con7=(Rb/2);
437 : : #endif
438 : 0 : con8=(2/Rb);
439 : 0 : con9=(1/Rc);
440 : 0 : con10=(1/Re);
441 : 0 : TwoQ=(2*1.602176462e-19);
442 : 0 : FourKT=((4*1.3806503e-23)*_circuit_temp);
443 : 0 : GMIN=1e-12;
444 : : }
445 : 0 : }
446 : :
447 : : /* Evaluate Verilog-AMS equations in final step. */
448 : 0 : void phototransistor::finalStep (void)
449 : : {
450 : 0 : }
451 : :
452 : : /* Evaluate Verilog-AMS equations in analog block. */
453 : 0 : void phototransistor::calcVerilog (void)
454 : : {
455 : :
456 : : /* ----------------- evaluate verilog analog equations -------------------- */
457 : : double RelSensitivity;
458 : : #if defined(_DERIVATE)
459 : : double RelSensitivity_VWavelength_GND;
460 : : #endif
461 : : #if defined(_DYNAMIC)
462 : : double Q1;
463 : : #if defined(_DERIVATE)
464 : : double Q1_VBI_EI;
465 : : double Q1_VBI_CI;
466 : : #endif
467 : : #endif
468 : : double IE;
469 : : #if defined(_DERIVATE)
470 : : double IE_VEI_Emitter;
471 : : #endif
472 : : double IC;
473 : : #if defined(_DERIVATE)
474 : : double IC_VCollector_CI;
475 : : #endif
476 : : double IB;
477 : : #if defined(_DERIVATE)
478 : : double IB_VBI2_BI;
479 : : #endif
480 : : double q2;
481 : : #if defined(_DERIVATE)
482 : : double q2_VBI_EI;
483 : : double q2_VBI_CI;
484 : : #endif
485 : : double q1;
486 : : #if defined(_DERIVATE)
487 : : double q1_VBI_CI;
488 : : double q1_VBI_EI;
489 : : #endif
490 : : double IEC;
491 : : #if defined(_DERIVATE)
492 : : double IEC_VBI_CI;
493 : : #endif
494 : : double ICC;
495 : : #if defined(_DERIVATE)
496 : : double ICC_VBI_EI;
497 : : #endif
498 : : {
499 [ # # ][ # # ]: 0 : double m00_limexp(d00_limexp0,(BP(BI,EI)*con1))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
500 : : #if defined(_DERIVATE)
501 [ # # ][ # # ]: 0 : double m10_limexp(d10_limexp0,d00_limexp0,(BP(BI,EI)*con1))
502 : : #endif
503 : : #if defined(_DERIVATE)
504 : 0 : ICC_VBI_EI=(Is*(con1)*d10_limexp0);
505 : : #endif
506 : 0 : ICC=(Is*(d00_limexp0-1));
507 : : }
508 : : {
509 [ # # ][ # # ]: 0 : double m00_limexp(d00_limexp0,(BP(BI,CI)*con2))
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
510 : : #if defined(_DERIVATE)
511 [ # # ][ # # ]: 0 : double m10_limexp(d10_limexp0,d00_limexp0,(BP(BI,CI)*con2))
512 : : #endif
513 : : #if defined(_DERIVATE)
514 : 0 : IEC_VBI_CI=(Is*(con2)*d10_limexp0);
515 : : #endif
516 : 0 : IEC=(Is*(d00_limexp0-1));
517 : : }
518 : : #if defined(_DERIVATE)
519 : 0 : q1_VBI_CI=(1/Vaf);
520 : 0 : q1_VBI_EI=(1/Var);
521 : : #endif
522 [ # # ][ # # ]: 0 : q1=((1+(BP(BI,CI)/Vaf))+(BP(BI,EI)/Var));
[ # # ]
523 : : #if defined(_DERIVATE)
524 : 0 : q2_VBI_EI=(ICC_VBI_EI/Ikf);
525 : 0 : q2_VBI_CI=(IEC_VBI_CI/Ikr);
526 : : #endif
527 : 0 : q2=((ICC/Ikf)+(IEC/Ikr));
528 : : #if defined(_DERIVATE)
529 : 0 : IB_VBI2_BI=(con8);
530 : : #endif
531 [ # # ]: 0 : IB=(BP(BI2,BI)*con8);
532 : : #if defined(_DERIVATE)
533 : 0 : IC_VCollector_CI=(con9);
534 : : #endif
535 [ # # ]: 0 : IC=(BP(Collector,CI)*con9);
536 : : #if defined(_DERIVATE)
537 : 0 : IE_VEI_Emitter=(con10);
538 : : #endif
539 [ # # ]: 0 : IE=(BP(EI,Emitter)*con10);
540 : 0 : _load_static_residual2(Collector,CI,IC);
541 : : #if defined(_DERIVATE)
542 [ # # ][ # # ]: 0 : _load_static_jacobian4(Collector,CI,Collector,CI,IC_VCollector_CI);
[ # # ][ # # ]
[ # # ]
543 : : #endif
544 [ # # ][ # # ]: 0 : _load_static_residual2(Base,BI2,(BP(Base,BI2)*con8));
545 : : #if defined(_DERIVATE)
546 [ # # ][ # # ]: 0 : _load_static_jacobian4(Base,BI2,Base,BI2,(con8));
[ # # ][ # # ]
[ # # ]
547 : : #endif
548 : 0 : _load_static_residual2(BI2,BI,IB);
549 : : #if defined(_DERIVATE)
550 [ # # ][ # # ]: 0 : _load_static_jacobian4(BI2,BI,BI2,BI,IB_VBI2_BI);
[ # # ][ # # ]
[ # # ]
551 : : #endif
552 : 0 : _load_static_residual2(EI,Emitter,IE);
553 : : #if defined(_DERIVATE)
554 [ # # ][ # # ]: 0 : _load_static_jacobian4(EI,Emitter,EI,Emitter,IE_VEI_Emitter);
[ # # ][ # # ]
[ # # ]
555 : : #endif
556 [ # # ][ # # ]: 0 : _load_static_residual2(BI,CI,((IEC/Br)+(GMIN*BP(BI,CI))));
557 : : #if defined(_DERIVATE)
558 [ # # ][ # # ]: 0 : _load_static_jacobian4(BI,CI,BI,CI,((IEC_VBI_CI/Br)+(GMIN)));
[ # # ][ # # ]
[ # # ]
559 : : #endif
560 [ # # ][ # # ]: 0 : _load_static_residual2(BI,EI,((ICC/Bf)+(GMIN*BP(BI,EI))));
561 : : #if defined(_DERIVATE)
562 [ # # ][ # # ]: 0 : _load_static_jacobian4(BI,EI,BI,EI,((ICC_VBI_EI/Bf)+(GMIN)));
[ # # ][ # # ]
[ # # ]
563 : : #endif
564 : : {
565 : 0 : double m00_sqrt(d00_sqrt0,(1+(4*q2)))
566 : : #if defined(_DERIVATE)
567 : 0 : double m10_sqrt(d10_sqrt0,d00_sqrt0,(1+(4*q2)))
568 : : #endif
569 : 0 : _load_static_residual2(CI,EI,((ICC-IEC)/(1e-20+((q1/2)*(1+d00_sqrt0)))));
570 : : #if defined(_DERIVATE)
571 [ # # ][ # # ]: 0 : _load_static_jacobian4(CI,EI,BI,CI,(((-IEC_VBI_CI)*(1e-20+((q1/2)*(1+d00_sqrt0)))-(ICC-IEC)*(((q1_VBI_CI/2)*(1+d00_sqrt0))+((q1/2)*(4*q2_VBI_CI)*d10_sqrt0)))/(1e-20+((q1/2)*(1+d00_sqrt0)))/(1e-20+((q1/2)*(1+d00_sqrt0)))));
[ # # ][ # # ]
[ # # ]
572 [ # # ][ # # ]: 0 : _load_static_jacobian4(CI,EI,BI,EI,((ICC_VBI_EI*(1e-20+((q1/2)*(1+d00_sqrt0)))-(ICC-IEC)*(((q1_VBI_EI/2)*(1+d00_sqrt0))+((q1/2)*(4*q2_VBI_EI)*d10_sqrt0)))/(1e-20+((q1/2)*(1+d00_sqrt0)))/(1e-20+((q1/2)*(1+d00_sqrt0)))));
[ # # ][ # # ]
[ # # ]
573 : : #endif
574 : : }
575 : : #if defined(_DYNAMIC)
576 : : {
577 [ # # ]: 0 : double m00_pow(d00_pow0,(1-BP(BI,CI)),con4)
578 : : #if defined(_DERIVATE)
579 [ # # ][ # # ]: 0 : double m10_pow(d10_pow0,d00_pow0,(1-BP(BI,CI)),con4)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
580 : : #endif
581 : : #if defined(_DERIVATE)
582 : 0 : Q1_VBI_EI=0.0;
583 [ # # ][ # # ]: 0 : Q1_VBI_CI=((BP(BI,CI)>(Vjc/2))?((Tr*IEC_VBI_CI)+((Cjc*con6)*(((((Mjc)*BP(BI,CI))+(Mjc*BP(BI,CI)))/Vjc)+(con4)))):((Tr*IEC_VBI_CI)+(Cjc*((Vjc/con4)*(-(d10_pow0*(-1.0)))))));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
584 : : #endif
585 [ # # ][ # # ]: 0 : Q1=((BP(BI,CI)>(Vjc/2))?((Tr*IEC)+((Cjc*con6)*((((Mjc*BP(BI,CI))*BP(BI,CI))/Vjc)+(con4*BP(BI,CI))))):((Tr*IEC)+(Cjc*((Vjc/con4)*(1-d00_pow0)))));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # #
# # # ]
586 : : }
587 : : #endif
588 : : #if defined(_DYNAMIC)
589 [ # # ][ # # ]: 0 : _load_dynamic_residual2(BI,CI,_DDT(Q1));
590 : : #if defined(_DERIVATE)
591 [ # # ][ # # ]: 0 : _load_dynamic_jacobian4(BI,CI,BI,CI,Q1_VBI_CI);
[ # # ][ # # ]
[ # # ]
592 : : #endif
593 : : #endif
594 : : #if defined(_DYNAMIC)
595 : : {
596 [ # # ]: 0 : double m00_pow(d00_pow0,(1-BP(BI,EI)),con3)
597 : : #if defined(_DERIVATE)
598 [ # # ][ # # ]: 0 : double m10_pow(d10_pow0,d00_pow0,(1-BP(BI,EI)),con3)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
599 : : #endif
600 : : #if defined(_DERIVATE)
601 [ # # ][ # # ]: 0 : Q1_VBI_EI=((BP(BI,EI)>(Vje/2))?((Tf*ICC_VBI_EI)+((Cje*con5)*(((((Mje)*BP(BI,EI))+(Mje*BP(BI,EI)))/Vje)+(con3)))):((Tf*ICC_VBI_EI)+(Cje*((Vje/con3)*(-(d10_pow0*(-1.0)))))));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # ]
602 : 0 : Q1_VBI_CI=0.0;
603 : : #endif
604 [ # # ][ # # ]: 0 : Q1=((BP(BI,EI)>(Vje/2))?((Tf*ICC)+((Cje*con5)*((((Mje*BP(BI,EI))*BP(BI,EI))/Vje)+(con3*BP(BI,EI))))):((Tf*ICC)+(Cje*((Vje/con3)*(1-d00_pow0)))));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # #
# # # # #
# # # ]
605 : : }
606 : : #endif
607 : : #if defined(_DYNAMIC)
608 [ # # ][ # # ]: 0 : _load_dynamic_residual2(BI,EI,_DDT(Q1));
609 : : #if defined(_DERIVATE)
610 [ # # ][ # # ]: 0 : _load_dynamic_jacobian4(BI,EI,BI,CI,Q1_VBI_CI);
[ # # ][ # # ]
[ # # ]
611 [ # # ][ # # ]: 0 : _load_dynamic_jacobian4(BI,EI,BI,EI,Q1_VBI_EI);
[ # # ][ # # ]
[ # # ]
612 : : #endif
613 : : #endif
614 : : {
615 : 0 : double m00_pow(d00_pow0,NP(Wavelength),2.0)
616 : 0 : double m00_pow(d00_pow1,NP(Wavelength),3.0)
617 : 0 : double m00_pow(d00_pow2,NP(Wavelength),4.0)
618 : : #if defined(_DERIVATE)
619 [ # # ][ # # ]: 0 : double m10_pow(d10_pow0,d00_pow0,NP(Wavelength),2.0)
[ # # ][ # # ]
620 [ # # ][ # # ]: 0 : double m10_pow(d10_pow1,d00_pow1,NP(Wavelength),3.0)
[ # # ][ # # ]
621 [ # # ][ # # ]: 0 : double m10_pow(d10_pow2,d00_pow2,NP(Wavelength),4.0)
[ # # ][ # # ]
622 : : #endif
623 : : #if defined(_DERIVATE)
624 : 0 : RelSensitivity_VWavelength_GND=((((P1)+(P2*(d10_pow0*1.0)))+(P3*(d10_pow1*1.0)))+(P4*(d10_pow2*1.0)));
625 : : #endif
626 : 0 : RelSensitivity=((((P0+(P1*NP(Wavelength)))+(P2*d00_pow0))+(P3*d00_pow1))+(P4*d00_pow2));
627 : : }
628 : 0 : _load_static_residual2(CI,BI2,(((Responsivity*RelSensitivity)/(Bf*100))*NP(Power)));
629 : : #if defined(_DERIVATE)
630 [ # # ]: 0 : _load_static_jacobian2s(CI,BI2,Power,(((Responsivity*RelSensitivity)/(Bf*100))));
631 [ # # ][ # # ]: 0 : _load_static_jacobian2s(CI,BI2,Wavelength,((Responsivity*RelSensitivity_VWavelength_GND)/(Bf*100))*NP(Power));
[ # # ][ # # ]
[ # # ]
632 : : #endif
633 : 0 : _save_whitenoise2(Collector,CI,(FourKT*con9),"thermal");
634 : 0 : _save_whitenoise2(Base,BI2,(FourKT*con8),"thermal");
635 : 0 : _save_whitenoise2(BI2,BI,(FourKT*con8),"thermal");
636 : 0 : _save_whitenoise2(EI,Emitter,(FourKT*con10),"thermal");
637 : 0 : _save_whitenoise2(CI,EI,(TwoQ*IC),"shot");
638 : 0 : _save_whitenoise2(BI,EI,(TwoQ*IB),"shot");
639 : 0 : _save_flickernoise2(BI,EI,(Kf*pow(IB,Af)),Ffe,"flicker");
640 : :
641 : : /* ------------------ end of verilog analog equations --------------------- */
642 : :
643 : : /* ------------------ evaluate verilog noise equations -------------------- */
644 : :
645 : : /* ------------------- end of verilog noise equations --------------------- */
646 : 0 : }
647 : :
648 : : /* Perform DC iteration. */
649 : 0 : void phototransistor::calcDC (void)
650 : : {
651 : : // evaluate Verilog code
652 : 0 : initVerilog ();
653 : 0 : calcVerilog ();
654 : :
655 : : // fill right hand side and static jacobian
656 [ # # ]: 0 : for (int i1 = 0; i1 < 9; i1++) {
657 [ # # ]: 0 : setI (i1, _rhs[i1]);
658 [ # # ]: 0 : for (int i2 = 0; i2 < 9; i2++) {
659 [ # # ]: 0 : setY (i1, i2, _jstat[i1][i2]);
660 : : }
661 : : }
662 : 0 : }
663 : :
664 : : /* Save operating points. */
665 : 0 : void phototransistor::saveOperatingPoints (void)
666 : : {
667 : : // save global instance operating points
668 : 0 : setOperatingPoint ("con1", con1);
669 : 0 : setOperatingPoint ("con2", con2);
670 : 0 : setOperatingPoint ("con3", con3);
671 : 0 : setOperatingPoint ("con4", con4);
672 : 0 : setOperatingPoint ("con5", con5);
673 : 0 : setOperatingPoint ("con6", con6);
674 : 0 : setOperatingPoint ("con8", con8);
675 : 0 : setOperatingPoint ("con9", con9);
676 : 0 : setOperatingPoint ("con10", con10);
677 : 0 : setOperatingPoint ("TwoQ", TwoQ);
678 : 0 : setOperatingPoint ("FourKT", FourKT);
679 : 0 : setOperatingPoint ("GMIN", GMIN);
680 : 0 : }
681 : :
682 : : /* Load operating points. */
683 : 0 : void phototransistor::loadOperatingPoints (void)
684 : : {
685 : 0 : }
686 : :
687 : : /* Calculate operating points. */
688 : 0 : void phototransistor::calcOperatingPoints (void)
689 : : {
690 : 0 : }
691 : :
692 : : /* Initialization of AC analysis. */
693 : 0 : void phototransistor::initAC (void)
694 : : {
695 : 0 : allocMatrixMNA ();
696 : 0 : }
697 : :
698 : : /* Perform AC calculations. */
699 : 0 : void phototransistor::calcAC (nr_double_t frequency)
700 : : {
701 [ # # ]: 0 : setMatrixY (calcMatrixY (frequency));
702 : 0 : }
703 : :
704 : : /* Compute Y-matrix for AC analysis. */
705 : 0 : matrix phototransistor::calcMatrixY (nr_double_t frequency)
706 : : {
707 : 0 : _freq = frequency;
708 : 0 : saveOperatingPoints ();
709 : 0 : matrix y (9);
710 : :
711 [ # # ]: 0 : for (int i1 = 0; i1 < 9; i1++) {
712 [ # # ]: 0 : for (int i2 = 0; i2 < 9; i2++) {
713 : 0 : y (i1,i2) = nr_complex_t (_jstat[i1][i2], _jdyna[i1][i2] * 2 * M_PI * _freq);
714 : : }
715 : : }
716 : :
717 : 0 : return y;
718 : : }
719 : :
720 : : /* Initialization of S-parameter analysis. */
721 : 0 : void phototransistor::initSP (void)
722 : : {
723 : 0 : allocMatrixS ();
724 : 0 : }
725 : :
726 : : /* Perform S-parameter calculations. */
727 : 0 : void phototransistor::calcSP (nr_double_t frequency)
728 : : {
729 [ # # ][ # # ]: 0 : setMatrixS (ytos (calcMatrixY (frequency)));
[ # # ][ # # ]
[ # # ]
730 : 0 : }
731 : :
732 : : /* Initialization of transient analysis. */
733 : 0 : void phototransistor::initTR (void)
734 : : {
735 : 0 : setStates (2 * 9 * 9);
736 : 0 : initDC ();
737 : 0 : }
738 : :
739 : : /* Perform transient analysis iteration step. */
740 : 0 : void phototransistor::calcTR (nr_double_t)
741 : : {
742 : 0 : doHB = 0;
743 : 0 : doAC = 1;
744 : 0 : doTR = 1;
745 : 0 : calcDC ();
746 : :
747 : : int i1, i2, i3, i4, state;
748 : :
749 : : // 2-node charge integrations
750 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
751 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
752 : 0 : state = 2 * (i2 + 9 * i1);
753 [ # # ]: 0 : if (i1 != i2)
754 [ # # ]: 0 : if (_charges[i1][i2] != 0.0)
755 : 0 : transientCapacitanceQ (state, i1, i2, _charges[i1][i2]);
756 : : } }
757 : :
758 : : // 1-node charge integrations
759 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
760 : 0 : state = 2 * (i1 + 9 * i1);
761 [ # # ]: 0 : if (_charges[i1][i1] != 0.0)
762 : 0 : transientCapacitanceQ (state, i1, _charges[i1][i1]);
763 : : }
764 : :
765 : : // charge: 2-node, voltage: 2-node
766 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
767 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
768 [ # # ]: 0 : if (i1 != i2)
769 [ # # ]: 0 : for (i3 = 0; i3 < 9; i3++) {
770 [ # # ]: 0 : for (i4 = 0; i4 < 9; i4++) {
771 [ # # ]: 0 : if (i3 != i4)
772 [ # # ]: 0 : if (_caps[i1][i2][i3][i4] != 0.0)
773 [ # # ][ # # ]: 0 : transientCapacitanceC (i1, i2, i3, i4, _caps[i1][i2][i3][i4], BP(i3,i4));
774 : : } } } }
775 : :
776 : : // charge: 2-node, voltage: 1-node
777 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
778 [ # # ]: 0 : for (i2 = 0; i2 < 9; i2++) {
779 [ # # ]: 0 : if (i1 != i2)
780 [ # # ]: 0 : for (i3 = 0; i3 < 9; i3++) {
781 [ # # ]: 0 : if (_caps[i1][i2][i3][i3] != 0.0)
782 [ # # ]: 0 : transientCapacitanceC2Q (i1, i2, i3, _caps[i1][i2][i3][i3], NP(i3));
783 : : } } }
784 : :
785 : : // charge: 1-node, voltage: 2-node
786 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
787 [ # # ]: 0 : for (i3 = 0; i3 < 9; i3++) {
788 [ # # ]: 0 : for (i4 = 0; i4 < 9; i4++) {
789 [ # # ]: 0 : if (i3 != i4)
790 [ # # ]: 0 : if (_caps[i1][i1][i3][i4] != 0.0)
791 [ # # ][ # # ]: 0 : transientCapacitanceC2V (i1, i3, i4, _caps[i1][i1][i3][i4], BP(i3,i4));
792 : : } } }
793 : :
794 : : // charge: 1-node, voltage: 1-node
795 [ # # ]: 0 : for (i1 = 0; i1 < 9; i1++) {
796 [ # # ]: 0 : for (i3 = 0; i3 < 9; i3++) {
797 [ # # ]: 0 : if (_caps[i1][i1][i3][i3] != 0.0)
798 [ # # ]: 0 : transientCapacitanceC (i1, i3, _caps[i1][i1][i3][i3], NP(i3));
799 : : } }
800 : 0 : }
801 : :
802 : : /* Compute Cy-matrix for AC noise analysis. */
803 : 0 : matrix phototransistor::calcMatrixCy (nr_double_t frequency)
804 : : {
805 : 0 : _freq = frequency;
806 : 0 : matrix cy (9);
807 : :
808 : 0 : _load_flickernoise2 (BI,EI,_flicker_pwr[BI][EI],_flicker_exp[BI][EI]);
809 : 0 : _load_whitenoise2 (CI,EI,_white_pwr[CI][EI]);
810 : 0 : _load_whitenoise2 (BI,EI,_white_pwr[BI][EI]);
811 : 0 : _load_whitenoise2 (EI,Emitter,_white_pwr[EI][Emitter]);
812 : 0 : _load_whitenoise2 (BI2,BI,_white_pwr[BI2][BI]);
813 : 0 : _load_whitenoise2 (Base,BI2,_white_pwr[Base][BI2]);
814 : 0 : _load_whitenoise2 (Collector,CI,_white_pwr[Collector][CI]);
815 : :
816 : 0 : return cy;
817 : : }
818 : :
819 : : /* Perform AC noise computations. */
820 : 0 : void phototransistor::calcNoiseAC (nr_double_t frequency)
821 : : {
822 [ # # ]: 0 : setMatrixN (calcMatrixCy (frequency));
823 : 0 : }
824 : :
825 : : /* Perform S-parameter noise computations. */
826 : 0 : void phototransistor::calcNoiseSP (nr_double_t frequency)
827 : : {
828 [ # # ][ # # ]: 0 : setMatrixN (cytocs (calcMatrixCy (frequency) * z0, getMatrixS ()));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
829 : 0 : }
830 : :
831 : : /* Initialization of HB analysis. */
832 : 0 : void phototransistor::initHB (int)
833 : : {
834 : 0 : initDC ();
835 : 0 : allocMatrixHB ();
836 : 0 : }
837 : :
838 : : /* Perform HB analysis. */
839 : 0 : void phototransistor::calcHB (int)
840 : : {
841 : 0 : doHB = 1;
842 : 0 : doAC = 1;
843 : 0 : doTR = 0;
844 : :
845 : : // jacobian dI/dV and currents get filled
846 : 0 : calcDC ();
847 : 0 : saveOperatingPoints ();
848 : :
849 : : // fill in HB matrices
850 [ # # ]: 0 : for (int i1 = 0; i1 < 9; i1++) {
851 [ # # ]: 0 : setQ (i1, _qhs[i1]); // charges
852 [ # # ]: 0 : setCV (i1, _chs[i1]); // jacobian dQ/dV * V
853 [ # # ]: 0 : setGV (i1, _ghs[i1]); // jacobian dI/dV * V
854 [ # # ]: 0 : for (int i2 = 0; i2 < 9; i2++) {
855 [ # # ]: 0 : setQV (i1, i2, _jdyna[i1][i2]); // jacobian dQ/dV
856 : : }
857 : : }
858 : 0 : }
859 : :
860 : : #include "phototransistor.defs.h"
861 : :
|