1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Hong J. Park, Thomas L. Quarles
4 **********/
5 
6 #include "ngspice/ngspice.h"
7 #include "ngspice/smpdefs.h"
8 #include "ngspice/cktdefs.h"
9 #include "bsim1def.h"
10 #include "ngspice/const.h"
11 #include "ngspice/sperror.h"
12 #include "ngspice/suffix.h"
13 
14 int
B1setup(SMPmatrix * matrix,GENmodel * inModel,CKTcircuit * ckt,int * states)15 B1setup(SMPmatrix *matrix, GENmodel *inModel, CKTcircuit *ckt,
16         int *states)
17         /* load the B1 device structure with those pointers needed later
18          * for fast matrix loading
19          */
20 
21 {
22     B1model *model = (B1model*)inModel;
23     B1instance *here;
24     int error;
25     CKTnode *tmp;
26 
27     /*  loop through all the B1 device models */
28     for( ; model != NULL; model = B1nextModel(model)) {
29 
30 /* Default value Processing for B1 MOSFET Models */
31         if( ! model->B1typeGiven) {
32             model->B1type = NMOS;  /* NMOS */
33         }
34         if( ! model->B1vfb0Given) {
35             model->B1vfb0 = 0.0;
36         }
37         if( ! model->B1vfbLGiven) {
38             model->B1vfbL = 0.0;
39         }
40         if( ! model->B1vfbWGiven) {
41             model->B1vfbW = 0.0;
42         }
43         if( ! model->B1phi0Given) {
44             model->B1phi0 = 0.0;
45         }
46         if( ! model->B1phiLGiven) {
47             model->B1phiL = 0.0;
48         }
49         if( ! model->B1phiWGiven) {
50             model->B1phiW = 0.0;
51         }
52         if( ! model->B1K10Given) {
53             model->B1K10 = 0.0;
54         }
55         if( ! model->B1K1LGiven) {
56             model->B1K1L = 0.0;
57         }
58         if( ! model->B1K1WGiven) {
59             model->B1K1W = 0.0;
60         }
61         if( ! model->B1K20Given) {
62             model->B1K20 = 0.0;
63         }
64         if( ! model->B1K2LGiven) {
65             model->B1K2L = 0.0;
66         }
67         if( ! model->B1K2WGiven) {
68             model->B1K2W = 0.0;
69         }
70         if( ! model->B1eta0Given) {
71             model->B1eta0 = 0.0;
72         }
73         if( ! model->B1etaLGiven) {
74             model->B1etaL = 0.0;
75         }
76         if( ! model->B1etaWGiven) {
77             model->B1etaW = 0.0;
78         }
79         if( ! model->B1mobZeroGiven) {
80             model->B1mobZero = 0.0;
81         }
82         if( ! model->B1deltaLGiven) {
83             model->B1deltaL = 0.0;
84         }
85         if( ! model->B1deltaWGiven) {
86             model->B1deltaW = 0.0;
87         }
88         if( ! model->B1ugs0Given) {
89             model->B1ugs0 = 0.0;
90         }
91         if( ! model->B1ugsLGiven) {
92             model->B1ugsL = 0.0;
93         }
94         if( ! model->B1ugsWGiven) {
95             model->B1ugsW = 0.0;
96         }
97         if( ! model->B1uds0Given) {
98             model->B1uds0 = 0.0;
99         }
100         if( ! model->B1udsLGiven) {
101             model->B1udsL = 0.0;
102         }
103         if( ! model->B1udsWGiven) {
104             model->B1udsW = 0.0;
105         }
106         if( ! model->B1mobZeroB0Given) {
107             model->B1mobZeroB0 = 0.0;
108         }
109         if( ! model->B1mobZeroBlGiven) {
110             model->B1mobZeroBl = 0.0;
111         }
112         if( ! model->B1mobZeroBwGiven) {
113             model->B1mobZeroBw = 0.0;
114         }
115         if( ! model->B1etaB0Given) {
116             model->B1etaB0 = 0.0;
117         }
118         if( ! model->B1etaBlGiven) {
119             model->B1etaBl = 0.0;
120         }
121         if( ! model->B1etaBwGiven) {
122             model->B1etaBw = 0.0;
123         }
124         if( ! model->B1etaD0Given) {
125             model->B1etaD0 = 0.0;
126         }
127         if( ! model->B1etaDlGiven) {
128             model->B1etaDl = 0.0;
129         }
130         if( ! model->B1etaDwGiven) {
131             model->B1etaDw = 0.0;
132         }
133         if( ! model->B1ugsB0Given) {
134             model->B1ugsB0 = 0.0;
135         }
136         if( ! model->B1ugsBLGiven) {
137             model->B1ugsBL = 0.0;
138         }
139         if( ! model->B1ugsBWGiven) {
140             model->B1ugsBW = 0.0;
141         }
142         if( ! model->B1udsB0Given) {
143             model->B1udsB0 = 0.0;
144         }
145         if( ! model->B1udsBLGiven) {
146             model->B1udsBL = 0.0;
147         }
148         if( ! model->B1udsBWGiven) {
149             model->B1udsBW = 0.0;
150         }
151         if( ! model->B1mobVdd0Given) {
152             model->B1mobVdd0 = 0.0;
153         }
154         if( ! model->B1mobVddlGiven) {
155             model->B1mobVddl = 0.0;
156         }
157         if( ! model->B1mobVddwGiven) {
158             model->B1mobVddw = 0.0;
159         }
160         if( ! model->B1mobVddB0Given) {
161             model->B1mobVddB0 = 0.0;
162         }
163         if( ! model->B1mobVddBlGiven) {
164             model->B1mobVddBl = 0.0;
165         }
166         if( ! model->B1mobVddBwGiven) {
167             model->B1mobVddBw = 0.0;
168         }
169         if( ! model->B1mobVddD0Given) {
170             model->B1mobVddD0 = 0.0;
171         }
172         if( ! model->B1mobVddDlGiven) {
173             model->B1mobVddDl = 0.0;
174         }
175         if( ! model->B1mobVddDwGiven) {
176             model->B1mobVddDw = 0.0;
177         }
178         if( ! model->B1udsD0Given) {
179             model->B1udsD0 = 0.0;
180         }
181         if( ! model->B1udsDLGiven) {
182             model->B1udsDL = 0.0;
183         }
184         if( ! model->B1udsDWGiven) {
185             model->B1udsDW = 0.0;
186         }
187         if( ! model->B1oxideThicknessGiven) {
188             model->B1oxideThickness = 0.0;  /* um */
189         }
190         if( ! model->B1tempGiven) {
191             model->B1temp = 0.0;
192         }
193         if( ! model->B1vddGiven) {
194             model->B1vdd = 0.0;
195         }
196         if( ! model->B1gateDrainOverlapCapGiven) {
197             model->B1gateDrainOverlapCap = 0.0;
198         }
199         if( ! model->B1gateSourceOverlapCapGiven) {
200             model->B1gateSourceOverlapCap = 0.0;
201         }
202         if( ! model->B1gateBulkOverlapCapGiven) {
203             model->B1gateBulkOverlapCap = 0.0;
204         }
205         if( ! model->B1channelChargePartitionFlagGiven) {
206             model->B1channelChargePartitionFlag = 0;
207         }
208         if( ! model->B1subthSlope0Given) {
209             model->B1subthSlope0 = 0.0;
210         }
211         if( ! model->B1subthSlopeLGiven) {
212             model->B1subthSlopeL = 0.0;
213         }
214         if( ! model->B1subthSlopeWGiven) {
215             model->B1subthSlopeW = 0.0;
216         }
217         if( ! model->B1subthSlopeB0Given) {
218             model->B1subthSlopeB0 = 0.0;
219         }
220         if( ! model->B1subthSlopeBLGiven) {
221             model->B1subthSlopeBL = 0.0;
222         }
223         if( ! model->B1subthSlopeBWGiven) {
224             model->B1subthSlopeBW = 0.0;
225         }
226         if( ! model->B1subthSlopeD0Given) {
227             model->B1subthSlopeD0 = 0.0;
228         }
229         if( ! model->B1subthSlopeDLGiven) {
230             model->B1subthSlopeDL = 0.0;
231         }
232         if( ! model->B1subthSlopeDWGiven) {
233             model->B1subthSlopeDW = 0.0;
234         }
235         if( ! model->B1sheetResistanceGiven) {
236             model->B1sheetResistance = 0.0;
237         }
238         if( ! model->B1unitAreaJctCapGiven) {
239             model->B1unitAreaJctCap = 0.0;
240         }
241         if( ! model->B1unitLengthSidewallJctCapGiven) {
242             model->B1unitLengthSidewallJctCap = 0.0;
243         }
244         if( ! model->B1jctSatCurDensityGiven) {
245             model->B1jctSatCurDensity = 0.0;
246         }
247         if( ! model->B1bulkJctPotentialGiven) {
248             model->B1bulkJctPotential = 0.0;
249         }
250         if( ! model->B1sidewallJctPotentialGiven) {
251             model->B1sidewallJctPotential = 0.0;
252         }
253         if( ! model->B1bulkJctBotGradingCoeffGiven) {
254             model->B1bulkJctBotGradingCoeff = 0.0;
255         }
256         if( ! model->B1bulkJctSideGradingCoeffGiven) {
257             model->B1bulkJctSideGradingCoeff = 0.0;
258         }
259         if( ! model->B1defaultWidthGiven) {
260             model->B1defaultWidth = 0.0;
261         }
262         if( ! model->B1deltaLengthGiven) {
263             model->B1deltaLength = 0.0;
264         }
265         if( ! model->B1fNcoefGiven) {
266             model->B1fNcoef = 0.0;
267         }
268         if( ! model->B1fNexpGiven) {
269             model->B1fNexp = 1.0;
270         }
271 
272         /* loop through all the instances of the model */
273         for (here = B1instances(model); here != NULL ;
274                 here=B1nextInstance(here)) {
275 
276         CKTnode *tmpNode;
277         IFuid tmpName;
278 
279             /* allocate a chunk of the state vector */
280             here->B1states = *states;
281             *states += B1numStates;
282 
283             /* perform the parameter defaulting */
284             if(!here->B1drainAreaGiven) {
285                 here->B1drainArea = 0;
286             }
287             if(!here->B1drainPerimeterGiven) {
288                 here->B1drainPerimeter = 0;
289             }
290             if(!here->B1drainSquaresGiven) {
291                 here->B1drainSquares = 1;
292             }
293             if(!here->B1icVBSGiven) {
294                 here->B1icVBS = 0;
295             }
296             if(!here->B1icVDSGiven) {
297                 here->B1icVDS = 0;
298             }
299             if(!here->B1icVGSGiven) {
300                 here->B1icVGS = 0;
301             }
302             if(!here->B1lGiven) {
303                 here->B1l = 5e-6;
304             }
305             if(!here->B1sourceAreaGiven) {
306                 here->B1sourceArea = 0;
307             }
308             if(!here->B1sourcePerimeterGiven) {
309                 here->B1sourcePerimeter = 0;
310             }
311             if(!here->B1sourceSquaresGiven) {
312                 here->B1sourceSquares = 1;
313             }
314             if(!here->B1vdsatGiven) {
315                 here->B1vdsat = 0;
316             }
317             if(!here->B1vonGiven) {
318                 here->B1von = 0;
319             }
320             if(!here->B1wGiven) {
321                 here->B1w = 5e-6;
322             }
323             if(!here->B1mGiven) {
324                 here->B1m = 1.0;
325             }
326 
327             /* process drain series resistance */
328             if( (model->B1sheetResistance != 0) &&
329                     (here->B1drainSquares != 0.0 ))
330             {   if(here->B1dNodePrime == 0) {
331                 error = CKTmkVolt(ckt,&tmp,here->B1name,"drain");
332                 if(error) return(error);
333                 here->B1dNodePrime = tmp->number;
334                 if (ckt->CKTcopyNodesets) {
335                   if (CKTinst2Node(ckt,here,1,&tmpNode,&tmpName)==OK) {
336                      if (tmpNode->nsGiven) {
337                        tmp->nodeset=tmpNode->nodeset;
338                        tmp->nsGiven=tmpNode->nsGiven;
339                      }
340                   }
341                 }
342             }
343             } else {
344                     here->B1dNodePrime = here->B1dNode;
345             }
346 
347             /* process source series resistance */
348             if( (model->B1sheetResistance != 0) &&
349                     (here->B1sourceSquares != 0.0 )) {
350                 if(here->B1sNodePrime == 0) {
351                     error = CKTmkVolt(ckt,&tmp,here->B1name,"source");
352                     if(error) return(error);
353                     here->B1sNodePrime = tmp->number;
354                     if (ckt->CKTcopyNodesets) {
355                      if (CKTinst2Node(ckt,here,3,&tmpNode,&tmpName)==OK) {
356                      if (tmpNode->nsGiven) {
357                        tmp->nodeset=tmpNode->nodeset;
358                        tmp->nsGiven=tmpNode->nsGiven;
359                      }
360                   }
361                 }
362                 }
363             } else  {
364                 here->B1sNodePrime = here->B1sNode;
365             }
366 
367         /* set Sparse Matrix Pointers */
368 
369 /* macro to make elements with built in test for out of memory */
370 #define TSTALLOC(ptr,first,second) \
371 do { if((here->ptr = SMPmakeElt(matrix, here->first, here->second)) == NULL){\
372     return(E_NOMEM);\
373 } } while(0)
374 
375             TSTALLOC(B1DdPtr, B1dNode, B1dNode);
376             TSTALLOC(B1GgPtr, B1gNode, B1gNode);
377             TSTALLOC(B1SsPtr, B1sNode, B1sNode);
378             TSTALLOC(B1BbPtr, B1bNode, B1bNode);
379             TSTALLOC(B1DPdpPtr, B1dNodePrime, B1dNodePrime);
380             TSTALLOC(B1SPspPtr, B1sNodePrime, B1sNodePrime);
381             TSTALLOC(B1DdpPtr, B1dNode, B1dNodePrime);
382             TSTALLOC(B1GbPtr, B1gNode, B1bNode);
383             TSTALLOC(B1GdpPtr, B1gNode, B1dNodePrime);
384             TSTALLOC(B1GspPtr, B1gNode, B1sNodePrime);
385             TSTALLOC(B1SspPtr, B1sNode, B1sNodePrime);
386             TSTALLOC(B1BdpPtr, B1bNode, B1dNodePrime);
387             TSTALLOC(B1BspPtr, B1bNode, B1sNodePrime);
388             TSTALLOC(B1DPspPtr, B1dNodePrime, B1sNodePrime);
389             TSTALLOC(B1DPdPtr, B1dNodePrime, B1dNode);
390             TSTALLOC(B1BgPtr, B1bNode, B1gNode);
391             TSTALLOC(B1DPgPtr, B1dNodePrime, B1gNode);
392             TSTALLOC(B1SPgPtr, B1sNodePrime, B1gNode);
393             TSTALLOC(B1SPsPtr, B1sNodePrime, B1sNode);
394             TSTALLOC(B1DPbPtr, B1dNodePrime, B1bNode);
395             TSTALLOC(B1SPbPtr, B1sNodePrime, B1bNode);
396             TSTALLOC(B1SPdpPtr, B1sNodePrime, B1dNodePrime);
397 
398         }
399     }
400     return(OK);
401 }
402 
403 int
B1unsetup(GENmodel * inModel,CKTcircuit * ckt)404 B1unsetup(GENmodel *inModel, CKTcircuit *ckt)
405 {
406     B1model *model;
407     B1instance *here;
408 
409     for (model = (B1model *)inModel; model != NULL;
410 	    model = B1nextModel(model))
411     {
412         for (here = B1instances(model); here != NULL;
413                 here=B1nextInstance(here))
414 	{
415 	    if (here->B1sNodePrime > 0
416 		    && here->B1sNodePrime != here->B1sNode)
417 		CKTdltNNum(ckt, here->B1sNodePrime);
418             here->B1sNodePrime = 0;
419 
420 	    if (here->B1dNodePrime > 0
421 		    && here->B1dNodePrime != here->B1dNode)
422 		CKTdltNNum(ckt, here->B1dNodePrime);
423             here->B1dNodePrime = 0;
424 	}
425     }
426     return OK;
427 }
428