1 /**********
2 Based on jfetload.c
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Author: 1985 Thomas L. Quarles
5
6 Modified to add PS model and new parameter definitions ( Anthony E. Parker )
7 Copyright 1994 Macquarie University, Sydney Australia.
8 10 Feb 1994: New code added to call psmodel.c routines
9 **********/
10
11 #include "ngspice/ngspice.h"
12 #include "ngspice/cktdefs.h"
13 #include "jfet2defs.h"
14 #include "ngspice/const.h"
15 #include "ngspice/trandefs.h"
16 #include "ngspice/sperror.h"
17 #include "ngspice/devdefs.h"
18 #include "psmodel.h"
19 #include "ngspice/suffix.h"
20
21 int
JFET2load(GENmodel * inModel,CKTcircuit * ckt)22 JFET2load(GENmodel *inModel, CKTcircuit *ckt)
23 /* actually load the current resistance value into the
24 * sparse matrix previously provided
25 */
26 {
27 JFET2model *model = (JFET2model*)inModel;
28 JFET2instance *here;
29 double capgd;
30 double capgs;
31 double cd;
32 double cdhat = 0.0;
33 double cdreq;
34 double ceq;
35 double ceqgd;
36 double ceqgs;
37 double cg;
38 double cgd;
39 double cghat = 0.0;
40 double delvds;
41 double delvgd;
42 double delvgs;
43 double gdpr;
44 double gds;
45 double geq;
46 double ggd;
47 double ggs;
48 double gm;
49 double gspr;
50 double vds;
51 double vgd;
52 double vgs;
53 #ifndef PREDICTOR
54 double xfact;
55 #endif
56 int icheck;
57 int ichk1;
58 int error;
59
60 double m;
61
62 /* loop through all the models */
63 for( ; model != NULL; model = JFET2nextModel(model)) {
64
65 /* loop through all the instances of the model */
66 for (here = JFET2instances(model); here != NULL ;
67 here=JFET2nextInstance(here)) {
68 /*
69 * dc model parameters
70 */
71 gdpr=model->JFET2drainConduct*here->JFET2area;
72 gspr=model->JFET2sourceConduct*here->JFET2area;
73 /*
74 * initialization
75 */
76 icheck=1;
77 if( ckt->CKTmode & MODEINITSMSIG) {
78 vgs= *(ckt->CKTstate0 + here->JFET2vgs);
79 vgd= *(ckt->CKTstate0 + here->JFET2vgd);
80 } else if (ckt->CKTmode & MODEINITTRAN) {
81 vgs= *(ckt->CKTstate1 + here->JFET2vgs);
82 vgd= *(ckt->CKTstate1 + here->JFET2vgd);
83 } else if ( (ckt->CKTmode & MODEINITJCT) &&
84 (ckt->CKTmode & MODETRANOP) &&
85 (ckt->CKTmode & MODEUIC) ) {
86 vds=model->JFET2type*here->JFET2icVDS;
87 vgs=model->JFET2type*here->JFET2icVGS;
88 vgd=vgs-vds;
89 } else if ( (ckt->CKTmode & MODEINITJCT) &&
90 (here->JFET2off == 0) ) {
91 vgs = -1;
92 vgd = -1;
93 } else if( (ckt->CKTmode & MODEINITJCT) ||
94 ((ckt->CKTmode & MODEINITFIX) && (here->JFET2off))) {
95 vgs = 0;
96 vgd = 0;
97 } else {
98 #ifndef PREDICTOR
99 if(ckt->CKTmode & MODEINITPRED) {
100 xfact=ckt->CKTdelta/ckt->CKTdeltaOld[1];
101 *(ckt->CKTstate0 + here->JFET2vgs)=
102 *(ckt->CKTstate1 + here->JFET2vgs);
103 vgs=(1+xfact)* *(ckt->CKTstate1 + here->JFET2vgs)-xfact*
104 *(ckt->CKTstate2 + here->JFET2vgs);
105 *(ckt->CKTstate0 + here->JFET2vgd)=
106 *(ckt->CKTstate1 + here->JFET2vgd);
107 vgd=(1+xfact)* *(ckt->CKTstate1 + here->JFET2vgd)-xfact*
108 *(ckt->CKTstate2 + here->JFET2vgd);
109 *(ckt->CKTstate0 + here->JFET2cg)=
110 *(ckt->CKTstate1 + here->JFET2cg);
111 *(ckt->CKTstate0 + here->JFET2cd)=
112 *(ckt->CKTstate1 + here->JFET2cd);
113 *(ckt->CKTstate0 + here->JFET2cgd)=
114 *(ckt->CKTstate1 + here->JFET2cgd);
115 *(ckt->CKTstate0 + here->JFET2gm)=
116 *(ckt->CKTstate1 + here->JFET2gm);
117 *(ckt->CKTstate0 + here->JFET2gds)=
118 *(ckt->CKTstate1 + here->JFET2gds);
119 *(ckt->CKTstate0 + here->JFET2ggs)=
120 *(ckt->CKTstate1 + here->JFET2ggs);
121 *(ckt->CKTstate0 + here->JFET2ggd)=
122 *(ckt->CKTstate1 + here->JFET2ggd);
123 } else {
124 #endif /*PREDICTOR*/
125 /*
126 * compute new nonlinear branch voltages
127 */
128 vgs=model->JFET2type*
129 (*(ckt->CKTrhsOld+ here->JFET2gateNode)-
130 *(ckt->CKTrhsOld+
131 here->JFET2sourcePrimeNode));
132 vgd=model->JFET2type*
133 (*(ckt->CKTrhsOld+here->JFET2gateNode)-
134 *(ckt->CKTrhsOld+
135 here->JFET2drainPrimeNode));
136 #ifndef PREDICTOR
137 }
138 #endif /*PREDICTOR*/
139 delvgs=vgs- *(ckt->CKTstate0 + here->JFET2vgs);
140 delvgd=vgd- *(ckt->CKTstate0 + here->JFET2vgd);
141 delvds=delvgs-delvgd;
142 cghat= *(ckt->CKTstate0 + here->JFET2cg)+
143 *(ckt->CKTstate0 + here->JFET2ggd)*delvgd+
144 *(ckt->CKTstate0 + here->JFET2ggs)*delvgs;
145 cdhat= *(ckt->CKTstate0 + here->JFET2cd)+
146 *(ckt->CKTstate0 + here->JFET2gm)*delvgs+
147 *(ckt->CKTstate0 + here->JFET2gds)*delvds-
148 *(ckt->CKTstate0 + here->JFET2ggd)*delvgd;
149 /*
150 * bypass if solution has not changed
151 */
152 if((ckt->CKTbypass) &&
153 (!(ckt->CKTmode & MODEINITPRED)) &&
154 (fabs(delvgs) < ckt->CKTreltol*MAX(fabs(vgs),
155 fabs(*(ckt->CKTstate0 + here->JFET2vgs)))+
156 ckt->CKTvoltTol) )
157 if ( (fabs(delvgd) < ckt->CKTreltol*MAX(fabs(vgd),
158 fabs(*(ckt->CKTstate0 + here->JFET2vgd)))+
159 ckt->CKTvoltTol))
160 if ( (fabs(cghat-*(ckt->CKTstate0 + here->JFET2cg))
161 < ckt->CKTreltol*MAX(fabs(cghat),
162 fabs(*(ckt->CKTstate0 + here->JFET2cg)))+
163 ckt->CKTabstol) ) if ( /* hack - expression too big */
164 (fabs(cdhat-*(ckt->CKTstate0 + here->JFET2cd))
165 < ckt->CKTreltol*MAX(fabs(cdhat),
166 fabs(*(ckt->CKTstate0 + here->JFET2cd)))+
167 ckt->CKTabstol) ) {
168
169 /* we can do a bypass */
170 vgs= *(ckt->CKTstate0 + here->JFET2vgs);
171 vgd= *(ckt->CKTstate0 + here->JFET2vgd);
172 vds= vgs-vgd;
173 cg= *(ckt->CKTstate0 + here->JFET2cg);
174 cd= *(ckt->CKTstate0 + here->JFET2cd);
175 cgd= *(ckt->CKTstate0 + here->JFET2cgd);
176 gm= *(ckt->CKTstate0 + here->JFET2gm);
177 gds= *(ckt->CKTstate0 + here->JFET2gds);
178 ggs= *(ckt->CKTstate0 + here->JFET2ggs);
179 ggd= *(ckt->CKTstate0 + here->JFET2ggd);
180 goto load;
181 }
182 /*
183 * limit nonlinear branch voltages
184 */
185 ichk1=1;
186 vgs = DEVpnjlim(vgs,*(ckt->CKTstate0 + here->JFET2vgs),
187 (here->JFET2temp*CONSTKoverQ), here->JFET2vcrit, &icheck);
188 vgd = DEVpnjlim(vgd,*(ckt->CKTstate0 + here->JFET2vgd),
189 (here->JFET2temp*CONSTKoverQ), here->JFET2vcrit,&ichk1);
190 if (ichk1 == 1) {
191 icheck=1;
192 }
193 vgs = DEVfetlim(vgs,*(ckt->CKTstate0 + here->JFET2vgs),
194 model->JFET2vto);
195 vgd = DEVfetlim(vgd,*(ckt->CKTstate0 + here->JFET2vgd),
196 model->JFET2vto);
197 }
198 /*
199 * determine dc current and derivatives
200 */
201 vds=vgs-vgd;
202 if (vds < 0.0) {
203 cd = -PSids(ckt, model, here, vgd, vgs,
204 &cgd, &cg, &ggd, &ggs, &gm, &gds);
205 gds += gm;
206 gm = -gm;
207 } else {
208 cd = PSids(ckt, model, here, vgs, vgd,
209 &cg, &cgd, &ggs, &ggd, &gm, &gds);
210 }
211 cg = cg + cgd;
212 cd = cd - cgd;
213
214 if ( (ckt->CKTmode & (MODETRAN | MODEAC | MODEINITSMSIG) ) ||
215 ((ckt->CKTmode & MODETRANOP) && (ckt->CKTmode & MODEUIC)) ){
216 /*
217 * charge storage elements
218 */
219 double capds = model->JFET2capds*here->JFET2area;
220
221 PScharge(ckt, model, here, vgs, vgd, &capgs, &capgd);
222
223 *(ckt->CKTstate0 + here->JFET2qds) = capds * vds;
224
225 /*
226 * store small-signal parameters
227 */
228 if( (!(ckt->CKTmode & MODETRANOP)) ||
229 (!(ckt->CKTmode & MODEUIC)) ) {
230 if(ckt->CKTmode & MODEINITSMSIG) {
231 *(ckt->CKTstate0 + here->JFET2qgs) = capgs;
232 *(ckt->CKTstate0 + here->JFET2qgd) = capgd;
233 *(ckt->CKTstate0 + here->JFET2qds) = capds;
234 continue; /*go to 1000*/
235 }
236 /*
237 * transient analysis
238 */
239 if(ckt->CKTmode & MODEINITTRAN) {
240 *(ckt->CKTstate1 + here->JFET2qgs) =
241 *(ckt->CKTstate0 + here->JFET2qgs);
242 *(ckt->CKTstate1 + here->JFET2qgd) =
243 *(ckt->CKTstate0 + here->JFET2qgd);
244 *(ckt->CKTstate1 + here->JFET2qds) =
245 *(ckt->CKTstate0 + here->JFET2qds);
246 }
247 error = NIintegrate(ckt,&geq,&ceq,capgs,here->JFET2qgs);
248 if(error) return(error);
249 ggs = ggs + geq;
250 cg = cg + *(ckt->CKTstate0 + here->JFET2cqgs);
251 error = NIintegrate(ckt,&geq,&ceq,capgd,here->JFET2qgd);
252 if(error) return(error);
253 ggd = ggd + geq;
254 cg = cg + *(ckt->CKTstate0 + here->JFET2cqgd);
255 cd = cd - *(ckt->CKTstate0 + here->JFET2cqgd);
256 cgd = cgd + *(ckt->CKTstate0 + here->JFET2cqgd);
257 error = NIintegrate(ckt,&geq,&ceq,capds,here->JFET2qds);
258 cd = cd + *(ckt->CKTstate0 + here->JFET2cqds);
259 if(error) return(error);
260 if (ckt->CKTmode & MODEINITTRAN) {
261 *(ckt->CKTstate1 + here->JFET2cqgs) =
262 *(ckt->CKTstate0 + here->JFET2cqgs);
263 *(ckt->CKTstate1 + here->JFET2cqgd) =
264 *(ckt->CKTstate0 + here->JFET2cqgd);
265 *(ckt->CKTstate1 + here->JFET2cqds) =
266 *(ckt->CKTstate0 + here->JFET2cqds);
267 }
268 }
269 }
270 /*
271 * check convergence
272 */
273 if( (!(ckt->CKTmode & MODEINITFIX)) | (!(ckt->CKTmode & MODEUIC))) {
274 if((icheck == 1) ||
275 (fabs(cghat-cg) >= ckt->CKTreltol*
276 MAX(fabs(cghat),fabs(cg))+ckt->CKTabstol) ||
277 (fabs(cdhat-cd) > ckt->CKTreltol*
278 MAX(fabs(cdhat),fabs(cd))+ckt->CKTabstol)) {
279 ckt->CKTnoncon++;
280 ckt->CKTtroubleElt = (GENinstance *) here;
281 }
282 }
283 *(ckt->CKTstate0 + here->JFET2vgs) = vgs;
284 *(ckt->CKTstate0 + here->JFET2vgd) = vgd;
285 *(ckt->CKTstate0 + here->JFET2cg) = cg;
286 *(ckt->CKTstate0 + here->JFET2cd) = cd;
287 *(ckt->CKTstate0 + here->JFET2cgd) = cgd;
288 *(ckt->CKTstate0 + here->JFET2gm) = gm;
289 *(ckt->CKTstate0 + here->JFET2gds) = gds;
290 *(ckt->CKTstate0 + here->JFET2ggs) = ggs;
291 *(ckt->CKTstate0 + here->JFET2ggd) = ggd;
292 /*
293 * load current vector
294 */
295 load:
296
297 m = here->JFET2m;
298
299 ceqgd=model->JFET2type*(cgd-ggd*vgd);
300 ceqgs=model->JFET2type*((cg-cgd)-ggs*vgs);
301 cdreq=model->JFET2type*((cd+cgd)-gds*vds-gm*vgs);
302 *(ckt->CKTrhs + here->JFET2gateNode) += m * (-ceqgs-ceqgd);
303 *(ckt->CKTrhs + here->JFET2drainPrimeNode) +=
304 m * (-cdreq+ceqgd);
305 *(ckt->CKTrhs + here->JFET2sourcePrimeNode) +=
306 m * (cdreq+ceqgs);
307 /*
308 * load y matrix
309 */
310 *(here->JFET2drainDrainPrimePtr) += m * (-gdpr);
311 *(here->JFET2gateDrainPrimePtr) += m * (-ggd);
312 *(here->JFET2gateSourcePrimePtr) += m * (-ggs);
313 *(here->JFET2sourceSourcePrimePtr) += m * (-gspr);
314 *(here->JFET2drainPrimeDrainPtr) += m * (-gdpr);
315 *(here->JFET2drainPrimeGatePtr) += m * (gm-ggd);
316 *(here->JFET2drainPrimeSourcePrimePtr) += m * (-gds-gm);
317 *(here->JFET2sourcePrimeGatePtr) += m * (-ggs-gm);
318 *(here->JFET2sourcePrimeSourcePtr) += m * (-gspr);
319 *(here->JFET2sourcePrimeDrainPrimePtr) += m * (-gds);
320 *(here->JFET2drainDrainPtr) += m * (gdpr);
321 *(here->JFET2gateGatePtr) += m * (ggd+ggs);
322 *(here->JFET2sourceSourcePtr) += m * (gspr);
323 *(here->JFET2drainPrimeDrainPrimePtr) += m * (gdpr+gds+ggd);
324 *(here->JFET2sourcePrimeSourcePrimePtr) += m * (gspr+gds+gm+ggs);
325 }
326 }
327 return(OK);
328 }
329