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