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: 1988 Jaijeet S Roychowdhury
5 1992 Stephen R. Whiteley
6 ****************************************************************************/
7
8 #include "spice.h"
9 #include <math.h>
10 #include <stdio.h>
11 #include "diodefs.h"
12 #include "distodef.h"
13 #include "util.h"
14 #include "sperror.h"
15 #include "distoext.h"
16
17 int
DIOdisto(mode,genmodel,ckt)18 DIOdisto(mode,genmodel,ckt)
19
20 /* assuming here that ckt->CKTomega has been initialised to
21 * the correct value
22 */
23 GENmodel *genmodel;
24 CKTcircuit *ckt;
25 int mode;
26 {
27 DIOmodel *model = (DIOmodel *) genmodel;
28 DISTOAN* job = (DISTOAN*) ckt->CKTcurJob;
29 double td;
30 DpassStr pass;
31 double g2,g3;
32 double cdiff2,cdiff3;
33 double cjunc2,cjunc3;
34 double r1h1x,i1h1x;
35 double r1h2x, i1h2x;
36 double r1hm2x,i1hm2x;
37 double r2h11x,i2h11x;
38 double r2h1m2x,i2h1m2x;
39 double temp, itemp;
40 DIOinstance *here;
41
42 if (mode == D_SETUP)
43 return (DIOdSetup(model,ckt));
44
45 if ((mode == D_TWOF1) || (mode == D_THRF1) ||
46 (mode == D_F1PF2) || (mode == D_F1MF2) ||
47 (mode == D_2F1MF2)) {
48
49 /* loop through all the DIO models */
50 for ( ; model != NULL; model = model->DIOnextModel) {
51
52 /* loop through all the instances of the model */
53 for (here = model->DIOinstances; here != NULL;
54 here = here->DIOnextInstance) {
55
56 /* loading starts here */
57
58 switch (mode) {
59
60 case D_TWOF1:
61 g2=here->id_x2;
62
63 cdiff2=here->cdif_x2;
64
65 cjunc2=here->cjnc_x2;
66
67 /* getting first order (linear) Volterra kernel */
68 r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
69 *(job->r1H1ptr + (here->DIOnegNode));
70 i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
71 *(job->i1H1ptr + (here->DIOnegNode));
72
73 /* formulae start here */
74
75 temp = D1n2F1(g2,r1h1x,i1h1x);
76 itemp = D1i2F1(g2,r1h1x,i1h1x);
77
78 /* the above are for the memoryless nonlinearity */
79
80 if ((cdiff2 + cjunc2) != 0.0) {
81 temp += - ckt->CKTomega * D1i2F1
82 (cdiff2+cjunc2,r1h1x,i1h1x);
83 itemp += ckt->CKTomega * D1n2F1
84 ((cdiff2 + cjunc2),r1h1x,i1h1x);
85 }
86
87 *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
88 *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
89 *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
90 *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
91
92 break;
93
94 case D_THRF1:
95
96 g2=here->id_x2;
97 g3=here->id_x3;
98
99 cdiff2=here->cdif_x2;
100 cdiff3=here->cdif_x3;
101
102 cjunc2=here->cjnc_x2;
103 cjunc3=here->cjnc_x3;
104
105 /* getting first order (linear) Volterra kernel */
106 r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
107 *(job->r1H1ptr + (here->DIOnegNode));
108 i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
109 *(job->i1H1ptr + (here->DIOnegNode));
110
111 /* getting second order kernel at (F1_F1) */
112 r2h11x = *(job->r2H11ptr + (here->DIOposPrimeNode)) -
113 *(job->r2H11ptr + (here->DIOnegNode));
114 i2h11x = *(job->i2H11ptr + (here->DIOposPrimeNode)) -
115 *(job->i2H11ptr + (here->DIOnegNode));
116
117 /* formulae start here */
118
119 temp = D1n3F1(g2,g3,r1h1x,i1h1x,r2h11x,
120 i2h11x);
121 itemp = D1i3F1(g2,g3,r1h1x,i1h1x,r2h11x,
122 i2h11x);
123
124 /* the above are for the memoryless nonlinearity */
125 /* the following are for the capacitors */
126
127 if ((cdiff2 + cjunc2) != 0.0) {
128 temp += -ckt->CKTomega * D1i3F1
129 (cdiff2+cjunc2,cdiff3+cjunc3,r1h1x,
130 i1h1x,r2h11x,i2h11x);
131
132 itemp += ckt->CKTomega * D1n3F1
133 (cdiff2+cjunc2,cdiff3+cjunc3,r1h1x,
134 i1h1x,r2h11x,i2h11x);
135 }
136
137 /* end of formulae */
138
139 *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
140 *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
141 *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
142 *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
143
144 break;
145
146 case D_F1PF2:
147
148 g2=here->id_x2;
149 g3=here->id_x3;
150
151 cdiff2=here->cdif_x2;
152 cdiff3=here->cdif_x3;
153
154 cjunc2=here->cjnc_x2;
155 cjunc3=here->cjnc_x3;
156
157 /* getting first order (linear) Volterra kernel for F1*/
158 r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
159 *(job->r1H1ptr + (here->DIOnegNode));
160 i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
161 *(job->i1H1ptr + (here->DIOnegNode));
162
163 /* getting first order (linear) Volterra kernel for F2*/
164 r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
165 *(job->r1H2ptr + (here->DIOnegNode));
166 i1h2x = *(job->i1H2ptr + (here->DIOposPrimeNode)) -
167 *(job->i1H2ptr + (here->DIOnegNode));
168
169 /* formulae start here */
170
171 temp = D1nF12(g2,r1h1x,i1h1x,r1h2x,i1h2x);
172 itemp = D1iF12(g2,r1h1x,i1h1x,r1h2x,i1h2x);
173
174 /* the above are for the memoryless nonlinearity */
175 /* the following are for the capacitors */
176
177 if ((cdiff2 + cjunc2) != 0.0) {
178 temp += - ckt->CKTomega * D1iF12
179 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1h2x);
180 itemp += ckt->CKTomega * D1nF12
181 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1h2x);
182 }
183
184 /* end of formulae */
185
186 *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
187 *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
188 *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
189 *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
190
191 break;
192
193 case D_F1MF2:
194
195 g2=here->id_x2;
196 g3=here->id_x3;
197
198 cdiff2=here->cdif_x2;
199 cdiff3=here->cdif_x3;
200
201 cjunc2=here->cjnc_x2;
202 cjunc3=here->cjnc_x3;
203
204 /* getting first order (linear) Volterra kernel for F1*/
205 r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
206 *(job->r1H1ptr + (here->DIOnegNode));
207 i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
208 *(job->i1H1ptr + (here->DIOnegNode));
209
210 /* getting first order (linear) Volterra kernel for F2*/
211 r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
212 *(job->r1H2ptr + (here->DIOnegNode));
213 i1hm2x = -(*(job->i1H2ptr + (here->DIOposPrimeNode)) -
214 *(job->i1H2ptr + (here->DIOnegNode)));
215
216 /* formulae start here */
217
218 temp = D1nF12(g2,r1h1x,i1h1x,r1h2x,i1hm2x);
219 itemp = D1iF12(g2,r1h1x,i1h1x,r1h2x,i1hm2x);
220
221 /* the above are for the memoryless nonlinearity */
222 /* the following are for the capacitors */
223
224 if ((cdiff2 + cjunc2) != 0.0) {
225 temp += - ckt->CKTomega * D1iF12
226 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1hm2x);
227 itemp += ckt->CKTomega * D1nF12
228 (cdiff2+cjunc2,r1h1x,i1h1x,r1h2x,i1hm2x);
229 }
230
231 /* end of formulae */
232
233 *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
234 *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
235 *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
236 *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
237
238 break;
239
240 case D_2F1MF2:
241
242 g2=here->id_x2;
243 g3=here->id_x3;
244
245 cdiff2=here->cdif_x2;
246 cdiff3=here->cdif_x3;
247
248 cjunc2=here->cjnc_x2;
249 cjunc3=here->cjnc_x3;
250
251 /* getting first order (linear) Volterra kernel at F1*/
252 r1h1x = *(job->r1H1ptr + (here->DIOposPrimeNode)) -
253 *(job->r1H1ptr + (here->DIOnegNode));
254 i1h1x = *(job->i1H1ptr + (here->DIOposPrimeNode)) -
255 *(job->i1H1ptr + (here->DIOnegNode));
256
257 /* getting first order (linear) Volterra kernel at minusF2*/
258 r1h2x = *(job->r1H2ptr + (here->DIOposPrimeNode)) -
259 *(job->r1H2ptr + (here->DIOnegNode));
260 i1hm2x = -(*(job->i1H2ptr + (here->DIOposPrimeNode)) -
261 *(job->i1H2ptr + (here->DIOnegNode)));
262
263 /* getting second order kernel at (F1_F1) */
264 r2h11x = *(job->r2H11ptr + (here->DIOposPrimeNode)) -
265 *(job->r2H11ptr + (here->DIOnegNode));
266 i2h11x = *(job->i2H11ptr + (here->DIOposPrimeNode)) -
267 *(job->i2H11ptr + (here->DIOnegNode));
268
269 /* getting second order kernel at (F1_minusF2) */
270 r2h1m2x = *(job->r2H1m2ptr + (here->DIOposPrimeNode)) -
271 *(job->r2H1m2ptr + (here->DIOnegNode));
272 i2h1m2x = *(job->i2H1m2ptr + (here->DIOposPrimeNode)) -
273 *(job->i2H1m2ptr + (here->DIOnegNode));
274
275 /* formulae start here */
276
277 temp = D1n2F12(g2,g3,r1h1x,i1h1x,r1h2x,
278 i1hm2x,r2h11x,i2h11x,
279 r2h1m2x,i2h1m2x);
280 itemp = D1i2F12(g2,g3,r1h1x,i1h1x,
281 r1h2x,i1hm2x,r2h11x,i2h11x,
282 r2h1m2x,i2h1m2x);
283
284 /* the above are for the memoryless nonlinearity */
285 /* the following are for the capacitors */
286
287 if ((cdiff2 + cjunc2) != 0.0) {
288 temp += -ckt->CKTomega *
289 D1i2F12(cdiff2+cjunc2,cdiff3+cjunc3,
290 r1h1x,i1h1x,r1h2x,i1hm2x,r2h11x,
291 i2h11x,r2h1m2x,i2h1m2x);
292 itemp += ckt->CKTomega *
293 D1n2F12(cdiff2+cjunc2,cdiff3+cjunc3,
294 r1h1x,i1h1x,r1h2x,i1hm2x,r2h11x,
295 i2h11x,r2h1m2x,i2h1m2x);
296 }
297
298 /* end of formulae */
299
300 *(ckt->CKTrhs + (here->DIOposPrimeNode)) -= temp;
301 *(ckt->CKTirhs + (here->DIOposPrimeNode)) -= itemp;
302 *(ckt->CKTrhs + (here->DIOnegNode)) += temp;
303 *(ckt->CKTirhs + (here->DIOnegNode)) += itemp;
304
305 break;
306
307 default:
308 ;
309 }
310 }
311 }
312 return(OK);
313 }
314 else
315 return(E_BADPARM);
316 }
317