1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: 2000 AlansFixes
5 **********/
6 
7 #include "ngspice/ngspice.h"
8 #include "ngspice/cktdefs.h"
9 #include "mos3defs.h"
10 #include "ngspice/const.h"
11 #include "ngspice/sperror.h"
12 #include "ngspice/suffix.h"
13 
14 /* assuming silicon - make definition for epsilon of silicon */
15 #define EPSSIL (11.7 * 8.854214871e-12)
16 
17 int
MOS3temp(GENmodel * inModel,CKTcircuit * ckt)18 MOS3temp(GENmodel *inModel, CKTcircuit *ckt)
19 {
20     MOS3model *model = (MOS3model *)inModel;
21     MOS3instance *here;
22     double wkfngs;
23     double wkfng;
24     double fermig;
25     double fermis;
26     double vfb;
27     double fact1,fact2;
28     double vt,vtnom;
29     double kt,kt1;
30     double ratio,ratio4;
31     double egfet,egfet1;
32     double pbfact,pbfact1,pbo;
33     double phio;
34     double arg1;
35     double capfact;
36     double gmanew,gmaold;
37     double ni_temp, nifact;
38     /* loop through all the mosfet models */
39     for( ; model != NULL; model = MOS3nextModel(model)) {
40 
41         if(!model->MOS3tnomGiven) {
42             model->MOS3tnom = ckt->CKTnomTemp;
43         }
44         fact1 = model->MOS3tnom/REFTEMP;
45         vtnom = model->MOS3tnom*CONSTKoverQ;
46         kt1 = CONSTboltz * model->MOS3tnom;
47         egfet1 = 1.16-(7.02e-4*model->MOS3tnom*model->MOS3tnom)/
48                 (model->MOS3tnom+1108);
49         arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));
50         pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1);
51         nifact=(model->MOS3tnom/300)*sqrt(model->MOS3tnom/300);
52         nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS3tnom))/
53                                                  CONSTKoverQ);
54         ni_temp=1.45e16*nifact;
55 
56         if (model->MOS3phi <= 0.0) {
57             SPfrontEnd->IFerrorf (ERR_FATAL,
58                "%s: Phi is not positive.", model->MOS3modName);
59             return(E_BADPARM);
60         }
61 
62         model->MOS3oxideCapFactor = 3.9 * 8.854214871e-12/
63                 model->MOS3oxideThickness;
64         if(!model->MOS3surfaceMobilityGiven) model->MOS3surfaceMobility=600;
65         if(!model->MOS3transconductanceGiven) {
66             model->MOS3transconductance = model->MOS3surfaceMobility *
67                     model->MOS3oxideCapFactor * 1e-4;
68         }
69         if(model->MOS3substrateDopingGiven) {
70             if(model->MOS3substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) {
71                 if(!model->MOS3phiGiven) {
72                     model->MOS3phi = 2*vtnom*
73                             log(model->MOS3substrateDoping*
74                            1e6/*(cm**3/m**3)*//ni_temp);
75                     model->MOS3phi = MAX(.1,model->MOS3phi);
76                 }
77                 fermis = model->MOS3type * .5 * model->MOS3phi;
78                 wkfng = 3.2;
79                 if(!model->MOS3gateTypeGiven) model->MOS3gateType=1;
80                 if(model->MOS3gateType != 0) {
81                     fermig = model->MOS3type * model->MOS3gateType*.5*egfet1;
82                     wkfng = 3.25 + .5 * egfet1 - fermig;
83                 }
84                 wkfngs = wkfng - (3.25 + .5 * egfet1 +fermis);
85                 if(!model->MOS3gammaGiven) {
86                     model->MOS3gamma = sqrt(2 * EPSSIL *
87                         CHARGE * model->MOS3substrateDoping*
88                         1e6 /*(cm**3/m**3)*/ )/ model->MOS3oxideCapFactor;
89                 }
90                 if(!model->MOS3vt0Given) {
91                     if(!model->MOS3surfaceStateDensityGiven)
92                             model->MOS3surfaceStateDensity=0;
93                     vfb = wkfngs - model->MOS3surfaceStateDensity * 1e4
94                             * CHARGE/model->MOS3oxideCapFactor;
95                     model->MOS3vt0 = vfb + model->MOS3type *
96                             (model->MOS3gamma * sqrt(model->MOS3phi)+
97                              model->MOS3phi);
98                 } else {
99                     vfb = model->MOS3vt0 - model->MOS3type * (model->MOS3gamma*
100                         sqrt(model->MOS3phi)+model->MOS3phi);
101                 }
102                 model->MOS3alpha = (EPSSIL+EPSSIL)/
103                     (CHARGE*model->MOS3substrateDoping*1e6 /*(cm**3/m**3)*/ );
104                 model->MOS3coeffDepLayWidth = sqrt(model->MOS3alpha);
105             } else {
106                 model->MOS3substrateDoping = 0;
107                 SPfrontEnd->IFerrorf (ERR_FATAL,
108                         "%s: Nsub < Ni ", model->MOS3modName);
109                 return(E_BADPARM);
110             }
111         }
112     /* now model parameter preprocessing */
113         model->MOS3narrowFactor = model->MOS3delta * 0.5 * M_PI * EPSSIL /
114             model->MOS3oxideCapFactor ;
115 
116 
117         /* loop through all instances of the model */
118         for(here = MOS3instances(model); here!= NULL;
119                 here = MOS3nextInstance(here)) {
120 
121             double czbd;    /* zero voltage bulk-drain capacitance */
122             double czbdsw;  /* zero voltage bulk-drain sidewall capacitance */
123             double czbs;    /* zero voltage bulk-source capacitance */
124             double czbssw;  /* zero voltage bulk-source sidewall capacitance */
125             double arg;     /* 1 - fc */
126             double sarg;    /* (1-fc) ^^ (-mj) */
127             double sargsw;  /* (1-fc) ^^ (-mjsw) */
128 
129             /* perform the parameter defaulting */
130 
131              if(!here->MOS3dtempGiven) {
132                 here->MOS3dtemp = 0.0;
133             }
134 
135             if(!here->MOS3tempGiven) {
136                 here->MOS3temp = ckt->CKTtemp + here->MOS3dtemp;
137             }
138             vt = here->MOS3temp * CONSTKoverQ;
139             ratio = here->MOS3temp/model->MOS3tnom;
140             fact2 = here->MOS3temp/REFTEMP;
141             kt = here->MOS3temp * CONSTboltz;
142             egfet = 1.16-(7.02e-4*here->MOS3temp*here->MOS3temp)/
143                     (here->MOS3temp+1108);
144             arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));
145             pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg);
146 
147             if(!here->MOS3mGiven) {
148                 here->MOS3m = ckt->CKTdefaultMosM;
149             }
150             if(!here->MOS3lGiven) {
151                 here->MOS3l = ckt->CKTdefaultMosL;
152             }
153             if(!here->MOS3sourceAreaGiven) {
154                 here->MOS3sourceArea = ckt->CKTdefaultMosAS;
155             }
156             if(!here->MOS3wGiven) {
157                 here->MOS3w = ckt->CKTdefaultMosW;
158             }
159             if(model->MOS3drainResistanceGiven) {
160                 if(model->MOS3drainResistance != 0) {
161                    here->MOS3drainConductance = here->MOS3m /
162                                      model->MOS3drainResistance;
163                 } else {
164                     here->MOS3drainConductance = 0;
165                 }
166             } else if (model->MOS3sheetResistanceGiven) {
167                 if ((model->MOS3sheetResistance != 0) &&
168                                               (here->MOS3drainSquares != 0)) {
169                     here->MOS3drainConductance =
170                        here->MOS3m /
171                           (model->MOS3sheetResistance*here->MOS3drainSquares);
172                 } else {
173                     here->MOS3drainConductance = 0;
174                 }
175             } else {
176                 here->MOS3drainConductance = 0;
177             }
178             if(model->MOS3sourceResistanceGiven) {
179                 if(model->MOS3sourceResistance != 0) {
180                     here->MOS3sourceConductance = here->MOS3m /
181                                                     model->MOS3sourceResistance;
182                 } else {
183                     here->MOS3sourceConductance = 0;
184                 }
185             } else if (model->MOS3sheetResistanceGiven) {
186                 if ((model->MOS3sheetResistance != 0) &&
187                                    (here->MOS3sourceSquares != 0)) {
188                     here->MOS3sourceConductance =
189                        here->MOS3m /
190                           (model->MOS3sheetResistance*here->MOS3sourceSquares);
191                 } else {
192                     here->MOS3sourceConductance = 0;
193                 }
194             } else {
195                 here->MOS3sourceConductance = 0;
196             }
197 
198             if(here->MOS3l - 2 * model->MOS3latDiff +
199                                  model->MOS3lengthAdjust <= 0) {
200                 SPfrontEnd->IFerrorf (ERR_FATAL,
201                         "%s: effective channel length less than zero",
202                         here->MOS3name);
203                 return(E_PARMVAL);
204             }
205 
206             if(here->MOS3w - 2 * model->MOS3widthNarrow +
207                                  model->MOS3widthAdjust <= 0) {
208                 SPfrontEnd->IFerrorf (ERR_FATAL,
209                         "%s: effective channel width less than zero",
210                         here->MOS3name);
211                 return(E_PARMVAL);
212             }
213 
214             ratio4 = ratio * sqrt(ratio);
215             here->MOS3tTransconductance = model->MOS3transconductance / ratio4;
216             here->MOS3tSurfMob = model->MOS3surfaceMobility/ratio4;
217             phio= (model->MOS3phi-pbfact1)/fact1;
218             here->MOS3tPhi = fact2 * phio + pbfact;
219             here->MOS3tVbi =
220                     model->MOS3delvt0 +
221                     model->MOS3vt0 - model->MOS3type *
222                         (model->MOS3gamma* sqrt(model->MOS3phi))
223                     +.5*(egfet1-egfet)
224                     + model->MOS3type*.5* (here->MOS3tPhi-model->MOS3phi);
225             here->MOS3tVto = here->MOS3tVbi + model->MOS3type *
226                     model->MOS3gamma * sqrt(here->MOS3tPhi);
227             here->MOS3tSatCur = model->MOS3jctSatCur*
228                     exp(-egfet/vt+egfet1/vtnom);
229             here->MOS3tSatCurDens = model->MOS3jctSatCurDensity *
230                     exp(-egfet/vt+egfet1/vtnom);
231             pbo = (model->MOS3bulkJctPotential - pbfact1)/fact1;
232             gmaold = (model->MOS3bulkJctPotential-pbo)/pbo;
233             capfact = 1/(1+model->MOS3bulkJctBotGradingCoeff*
234                     (4e-4*(model->MOS3tnom-REFTEMP)-gmaold));
235             here->MOS3tCbd = model->MOS3capBD * capfact;
236             here->MOS3tCbs = model->MOS3capBS * capfact;
237             here->MOS3tCj = model->MOS3bulkCapFactor * capfact;
238             capfact = 1/(1+model->MOS3bulkJctSideGradingCoeff*
239                     (4e-4*(model->MOS3tnom-REFTEMP)-gmaold));
240             here->MOS3tCjsw = model->MOS3sideWallCapFactor * capfact;
241             here->MOS3tBulkPot = fact2 * pbo+pbfact;
242             gmanew = (here->MOS3tBulkPot-pbo)/pbo;
243             capfact = (1+model->MOS3bulkJctBotGradingCoeff*
244                     (4e-4*(here->MOS3temp-REFTEMP)-gmanew));
245             here->MOS3tCbd *= capfact;
246             here->MOS3tCbs *= capfact;
247             here->MOS3tCj *= capfact;
248             capfact = (1+model->MOS3bulkJctSideGradingCoeff*
249                     (4e-4*(here->MOS3temp-REFTEMP)-gmanew));
250             here->MOS3tCjsw *= capfact;
251             here->MOS3tDepCap = model->MOS3fwdCapDepCoeff * here->MOS3tBulkPot;
252 
253             if( (model->MOS3jctSatCurDensity == 0) ||
254                     (here->MOS3drainArea == 0) ||
255                     (here->MOS3sourceArea == 0) ) {
256                 here->MOS3sourceVcrit = here->MOS3drainVcrit =
257                        vt*log(vt/(CONSTroot2*here->MOS3m*here->MOS3tSatCur));
258             } else {
259                 here->MOS3drainVcrit =
260                         vt * log( vt / (CONSTroot2 *
261                         here->MOS3m *
262                         here->MOS3tSatCurDens * here->MOS3drainArea));
263                 here->MOS3sourceVcrit =
264                         vt * log( vt / (CONSTroot2 *
265                         here->MOS3m *
266                         here->MOS3tSatCurDens * here->MOS3sourceArea));
267             }
268             if(model->MOS3capBDGiven) {
269                 czbd = here->MOS3tCbd * here->MOS3m;
270             } else {
271                 if(model->MOS3bulkCapFactorGiven) {
272                     czbd=here->MOS3tCj*here->MOS3drainArea * here->MOS3m;
273                 } else {
274                     czbd=0;
275                 }
276             }
277             if(model->MOS3sideWallCapFactorGiven) {
278                 czbdsw= here->MOS3tCjsw * here->MOS3drainPerimiter *
279                          here->MOS3m;
280             } else {
281                 czbdsw=0;
282             }
283             arg = 1-model->MOS3fwdCapDepCoeff;
284             sarg = exp( (-model->MOS3bulkJctBotGradingCoeff) * log(arg) );
285             sargsw = exp( (-model->MOS3bulkJctSideGradingCoeff) * log(arg) );
286             here->MOS3Cbd = czbd;
287             here->MOS3Cbdsw = czbdsw;
288             here->MOS3f2d = czbd*(1-model->MOS3fwdCapDepCoeff*
289                         (1+model->MOS3bulkJctBotGradingCoeff))* sarg/arg
290                     +  czbdsw*(1-model->MOS3fwdCapDepCoeff*
291                         (1+model->MOS3bulkJctSideGradingCoeff))*
292                         sargsw/arg;
293             here->MOS3f3d = czbd * model->MOS3bulkJctBotGradingCoeff * sarg/arg/
294                         here->MOS3tBulkPot
295                     + czbdsw * model->MOS3bulkJctSideGradingCoeff * sargsw/arg /
296                         here->MOS3tBulkPot;
297             here->MOS3f4d = czbd*here->MOS3tBulkPot*(1-arg*sarg)/
298                         (1-model->MOS3bulkJctBotGradingCoeff)
299                     + czbdsw*here->MOS3tBulkPot*(1-arg*sargsw)/
300                         (1-model->MOS3bulkJctSideGradingCoeff)
301                     -here->MOS3f3d/2*
302                         (here->MOS3tDepCap*here->MOS3tDepCap)
303                     -here->MOS3tDepCap * here->MOS3f2d;
304             if(model->MOS3capBSGiven) {
305                 czbs = here->MOS3tCbs * here->MOS3m;
306             } else {
307                 if(model->MOS3bulkCapFactorGiven) {
308                     czbs=here->MOS3tCj*here->MOS3sourceArea * here->MOS3m;
309                 } else {
310                     czbs=0;
311                 }
312             }
313             if(model->MOS3sideWallCapFactorGiven) {
314                 czbssw = here->MOS3tCjsw * here->MOS3sourcePerimiter *
315                       here->MOS3m;
316             } else {
317                 czbssw=0;
318             }
319             arg = 1-model->MOS3fwdCapDepCoeff;
320             sarg = exp( (-model->MOS3bulkJctBotGradingCoeff) * log(arg) );
321             sargsw = exp( (-model->MOS3bulkJctSideGradingCoeff) * log(arg) );
322             here->MOS3Cbs = czbs;
323             here->MOS3Cbssw = czbssw;
324             here->MOS3f2s = czbs*(1-model->MOS3fwdCapDepCoeff*
325                         (1+model->MOS3bulkJctBotGradingCoeff))* sarg/arg
326                     +  czbssw*(1-model->MOS3fwdCapDepCoeff*
327                         (1+model->MOS3bulkJctSideGradingCoeff))*
328                         sargsw/arg;
329             here->MOS3f3s = czbs * model->MOS3bulkJctBotGradingCoeff * sarg/arg/
330                        here->MOS3tBulkPot
331                     + czbssw * model->MOS3bulkJctSideGradingCoeff * sargsw/arg /
332                         here->MOS3tBulkPot;
333             here->MOS3f4s = czbs*here->MOS3tBulkPot*(1-arg*sarg)/
334                         (1-model->MOS3bulkJctBotGradingCoeff)
335                     + czbssw*here->MOS3tBulkPot*(1-arg*sargsw)/
336                         (1-model->MOS3bulkJctSideGradingCoeff)
337                     -here->MOS3f3s/2*
338                       (here->MOS3tDepCap*here->MOS3tDepCap)
339                     -here->MOS3tDepCap * here->MOS3f2s;
340         }
341     }
342     return(OK);
343 }
344