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