1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1985 Thomas L. Quarles
4 Modified: Alan Gillespie
5 **********/
6 
7 #include "ngspice/ngspice.h"
8 #include "ngspice/cktdefs.h"
9 #include "mos9defs.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
MOS9temp(GENmodel * inModel,CKTcircuit * ckt)18 MOS9temp(GENmodel *inModel, CKTcircuit *ckt)
19 {
20     MOS9model *model = (MOS9model *)inModel;
21     MOS9instance *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 = MOS9nextModel(model)) {
40 
41         if(!model->MOS9tnomGiven) {
42             model->MOS9tnom = ckt->CKTnomTemp;
43         }
44         fact1 = model->MOS9tnom/REFTEMP;
45         vtnom = model->MOS9tnom*CONSTKoverQ;
46         kt1 = CONSTboltz * model->MOS9tnom;
47         egfet1 = 1.16-(7.02e-4*model->MOS9tnom*model->MOS9tnom)/
48                 (model->MOS9tnom+1108);
49         arg1 = -egfet1/(kt1+kt1)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));
50         pbfact1 = -2*vtnom *(1.5*log(fact1)+CHARGE*arg1);
51 
52         nifact=(model->MOS9tnom/300)*sqrt(model->MOS9tnom/300);
53         nifact*=exp(0.5*egfet1*((1/(double)300)-(1/model->MOS9tnom))/
54                                                                   CONSTKoverQ);
55         ni_temp=1.45e16*nifact;
56 
57         if (model->MOS9phi <= 0.0) {
58             SPfrontEnd->IFerrorf (ERR_FATAL,
59                "%s: Phi is not positive.", model->MOS9modName);
60             return(E_BADPARM);
61         }
62 
63         model->MOS9oxideCapFactor = 3.9 * 8.854214871e-12/
64                 model->MOS9oxideThickness;
65         if(!model->MOS9surfaceMobilityGiven) model->MOS9surfaceMobility=600;
66         if(!model->MOS9transconductanceGiven) {
67             model->MOS9transconductance = model->MOS9surfaceMobility *
68                     model->MOS9oxideCapFactor * 1e-4;
69         }
70         if(model->MOS9substrateDopingGiven) {
71             if(model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ >ni_temp) {
72 
73                 if(!model->MOS9phiGiven) {
74                     model->MOS9phi = 2*vtnom*
75                             log(model->MOS9substrateDoping*
76 
77                             1e6/*(cm**3/m**3)*//ni_temp);
78 
79                     model->MOS9phi = MAX(.1,model->MOS9phi);
80                 }
81                 fermis = model->MOS9type * .5 * model->MOS9phi;
82                 wkfng = 3.2;
83                 if(!model->MOS9gateTypeGiven) model->MOS9gateType=1;
84                 if(model->MOS9gateType != 0) {
85                     fermig = model->MOS9type * model->MOS9gateType*.5*egfet1;
86                     wkfng = 3.25 + .5 * egfet1 - fermig;
87                 }
88                 wkfngs = wkfng - (3.25 + .5 * egfet1 +fermis);
89                 if(!model->MOS9gammaGiven) {
90                     model->MOS9gamma = sqrt(2 * EPSSIL *
91                         CHARGE * model->MOS9substrateDoping*
92                         1e6 /*(cm**3/m**3)*/ )/ model->MOS9oxideCapFactor;
93                 }
94                 if(!model->MOS9vt0Given) {
95                     if(!model->MOS9surfaceStateDensityGiven)
96                             model->MOS9surfaceStateDensity=0;
97                     vfb = wkfngs - model->MOS9surfaceStateDensity * 1e4
98                             * CHARGE/model->MOS9oxideCapFactor;
99                     model->MOS9vt0 = vfb + model->MOS9type *
100                             (model->MOS9gamma * sqrt(model->MOS9phi)+
101                              model->MOS9phi);
102                 } else {
103                     vfb = model->MOS9vt0 - model->MOS9type * (model->MOS9gamma*
104                         sqrt(model->MOS9phi)+model->MOS9phi);
105                 }
106                 model->MOS9alpha = (EPSSIL+EPSSIL)/
107                     (CHARGE*model->MOS9substrateDoping*1e6 /*(cm**3/m**3)*/ );
108                 model->MOS9coeffDepLayWidth = sqrt(model->MOS9alpha);
109             } else {
110                 model->MOS9substrateDoping = 0;
111                 SPfrontEnd->IFerrorf (ERR_FATAL,
112                         "%s: Nsub < Ni ", model->MOS9modName);
113                 return(E_BADPARM);
114             }
115         }
116     /* now model parameter preprocessing */
117         model->MOS9narrowFactor = model->MOS9delta * 0.5 * M_PI * EPSSIL /
118             model->MOS9oxideCapFactor ;
119 
120 
121         /* loop through all instances of the model */
122         for(here = MOS9instances(model); here!= NULL;
123                 here = MOS9nextInstance(here)) {
124 
125             double czbd;    /* zero voltage bulk-drain capacitance */
126             double czbdsw;  /* zero voltage bulk-drain sidewall capacitance */
127             double czbs;    /* zero voltage bulk-source capacitance */
128             double czbssw;  /* zero voltage bulk-source sidewall capacitance */
129             double arg;     /* 1 - fc */
130             double sarg;    /* (1-fc) ^^ (-mj) */
131             double sargsw;  /* (1-fc) ^^ (-mjsw) */
132 
133             /* perform the parameter defaulting */
134 
135              if(!here->MOS9dtempGiven) {
136                 here->MOS9dtemp = 0.0;
137             }
138 
139             if(!here->MOS9tempGiven) {
140                 here->MOS9temp = ckt->CKTtemp + here->MOS9dtemp;
141             }
142             vt = here->MOS9temp * CONSTKoverQ;
143             ratio = here->MOS9temp/model->MOS9tnom;
144             fact2 = here->MOS9temp/REFTEMP;
145             kt = here->MOS9temp * CONSTboltz;
146             egfet = 1.16-(7.02e-4*here->MOS9temp*here->MOS9temp)/
147                     (here->MOS9temp+1108);
148             arg = -egfet/(kt+kt)+1.1150877/(CONSTboltz*(REFTEMP+REFTEMP));
149             pbfact = -2*vt *(1.5*log(fact2)+CHARGE*arg);
150 
151             if(!here->MOS9mGiven) {
152                 here->MOS9m = ckt->CKTdefaultMosM;
153             }
154 
155             if(!here->MOS9lGiven) {
156                 here->MOS9l = ckt->CKTdefaultMosL;
157             }
158             if(!here->MOS9sourceAreaGiven) {
159                 here->MOS9sourceArea = ckt->CKTdefaultMosAS;
160             }
161             if(!here->MOS9wGiven) {
162                 here->MOS9w = ckt->CKTdefaultMosW;
163             }
164             if(model->MOS9drainResistanceGiven) {
165                 if(model->MOS9drainResistance != 0) {
166                     here->MOS9drainConductance = here->MOS9m /
167                                                    model->MOS9drainResistance;
168                 } else {
169                     here->MOS9drainConductance = 0;
170                 }
171             } else if (model->MOS9sheetResistanceGiven) {
172                 if ((model->MOS9sheetResistance != 0) &&
173                                               (here->MOS9drainSquares != 0)) {
174                     here->MOS9drainConductance =
175                         here->MOS9m /
176                           (model->MOS9sheetResistance*here->MOS9drainSquares);
177                 } else {
178                     here->MOS9drainConductance = 0;
179                 }
180             } else {
181                 here->MOS9drainConductance = 0;
182             }
183             if(model->MOS9sourceResistanceGiven) {
184                 if(model->MOS9sourceResistance != 0) {
185                     here->MOS9sourceConductance = here->MOS9m /
186                                                     model->MOS9sourceResistance;
187                 } else {
188                     here->MOS9sourceConductance = 0;
189                 }
190             } else if (model->MOS9sheetResistanceGiven) {
191                 if ((model->MOS9sheetResistance != 0) &&
192                                               (here->MOS9sourceSquares != 0)) {
193                     here->MOS9sourceConductance =
194                         here->MOS9m /
195                           (model->MOS9sheetResistance*here->MOS9sourceSquares);
196                 } else {
197                     here->MOS9sourceConductance = 0;
198                 }
199             } else {
200                 here->MOS9sourceConductance = 0;
201             }
202 
203             if(here->MOS9l - 2 * model->MOS9latDiff +
204                                  model->MOS9lengthAdjust <1e-6) {
205                 SPfrontEnd->IFerrorf (ERR_FATAL,
206                         "%s: effective channel length less than zero",
207                         here->MOS9name);
208                 return(E_PARMVAL);
209             }
210 
211             if(here->MOS9w - 2 * model->MOS9widthNarrow +
212                                  model->MOS9widthAdjust <1e-6) {
213                 SPfrontEnd->IFerrorf (ERR_FATAL,
214                         "%s: effective channel width less than zero",
215                         here->MOS9name);
216                 return(E_PARMVAL);
217             }
218 
219 
220             ratio4 = ratio * sqrt(ratio);
221             here->MOS9tTransconductance = model->MOS9transconductance / ratio4;
222             here->MOS9tSurfMob = model->MOS9surfaceMobility/ratio4;
223             phio= (model->MOS9phi-pbfact1)/fact1;
224             here->MOS9tPhi = fact2 * phio + pbfact;
225             here->MOS9tVbi =
226                     model->MOS9delvt0 +
227                     model->MOS9vt0 - model->MOS9type *
228                         (model->MOS9gamma* sqrt(model->MOS9phi))
229                     +.5*(egfet1-egfet)
230                     + model->MOS9type*.5* (here->MOS9tPhi-model->MOS9phi);
231             here->MOS9tVto = here->MOS9tVbi + model->MOS9type *
232                     model->MOS9gamma * sqrt(here->MOS9tPhi);
233             here->MOS9tSatCur = model->MOS9jctSatCur*
234                     exp(-egfet/vt+egfet1/vtnom);
235             here->MOS9tSatCurDens = model->MOS9jctSatCurDensity *
236                     exp(-egfet/vt+egfet1/vtnom);
237             pbo = (model->MOS9bulkJctPotential - pbfact1)/fact1;
238             gmaold = (model->MOS9bulkJctPotential-pbo)/pbo;
239             capfact = 1/(1+model->MOS9bulkJctBotGradingCoeff*
240                     (4e-4*(model->MOS9tnom-REFTEMP)-gmaold));
241             here->MOS9tCbd = model->MOS9capBD * capfact;
242             here->MOS9tCbs = model->MOS9capBS * capfact;
243             here->MOS9tCj = model->MOS9bulkCapFactor * capfact;
244             capfact = 1/(1+model->MOS9bulkJctSideGradingCoeff*
245                     (4e-4*(model->MOS9tnom-REFTEMP)-gmaold));
246             here->MOS9tCjsw = model->MOS9sideWallCapFactor * capfact;
247             here->MOS9tBulkPot = fact2 * pbo+pbfact;
248             gmanew = (here->MOS9tBulkPot-pbo)/pbo;
249             capfact = (1+model->MOS9bulkJctBotGradingCoeff*
250                     (4e-4*(here->MOS9temp-REFTEMP)-gmanew));
251             here->MOS9tCbd *= capfact;
252             here->MOS9tCbs *= capfact;
253             here->MOS9tCj *= capfact;
254             capfact = (1+model->MOS9bulkJctSideGradingCoeff*
255                     (4e-4*(here->MOS9temp-REFTEMP)-gmanew));
256             here->MOS9tCjsw *= capfact;
257             here->MOS9tDepCap = model->MOS9fwdCapDepCoeff * here->MOS9tBulkPot;
258 
259             if( (model->MOS9jctSatCurDensity == 0) ||
260                     (here->MOS9drainArea == 0) ||
261                     (here->MOS9sourceArea == 0) ) {
262                 here->MOS9sourceVcrit = here->MOS9drainVcrit =
263                        vt*log(vt/(CONSTroot2*here->MOS9m*here->MOS9tSatCur));
264             } else {
265                 here->MOS9drainVcrit =
266                         vt * log( vt / (CONSTroot2 *
267                         here->MOS9m *
268                         here->MOS9tSatCurDens * here->MOS9drainArea));
269                 here->MOS9sourceVcrit =
270                         vt * log( vt / (CONSTroot2 *
271                         here->MOS9m *
272                         here->MOS9tSatCurDens * here->MOS9sourceArea));
273             }
274             if(model->MOS9capBDGiven) {
275                 czbd = here->MOS9tCbd * here->MOS9m;
276             } else {
277                 if(model->MOS9bulkCapFactorGiven) {
278                     czbd=here->MOS9tCj*here->MOS9drainArea * here->MOS9m;
279                 } else {
280                     czbd=0;
281                 }
282             }
283             if(model->MOS9sideWallCapFactorGiven) {
284                 czbdsw= here->MOS9tCjsw * here->MOS9drainPerimiter *
285                          here->MOS9m;
286             } else {
287                 czbdsw=0;
288             }
289             arg = 1-model->MOS9fwdCapDepCoeff;
290             sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) );
291             sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) );
292             here->MOS9Cbd = czbd;
293             here->MOS9Cbdsw = czbdsw;
294             here->MOS9f2d = czbd*(1-model->MOS9fwdCapDepCoeff*
295                         (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg
296                     +  czbdsw*(1-model->MOS9fwdCapDepCoeff*
297                         (1+model->MOS9bulkJctSideGradingCoeff))*
298                         sargsw/arg;
299             here->MOS9f3d = czbd * model->MOS9bulkJctBotGradingCoeff * sarg/arg/
300                         here->MOS9tBulkPot
301                     + czbdsw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg /
302                         here->MOS9tBulkPot;
303             here->MOS9f4d = czbd*here->MOS9tBulkPot*(1-arg*sarg)/
304                         (1-model->MOS9bulkJctBotGradingCoeff)
305                     + czbdsw*here->MOS9tBulkPot*(1-arg*sargsw)/
306                         (1-model->MOS9bulkJctSideGradingCoeff)
307                     -here->MOS9f3d/2*
308                         (here->MOS9tDepCap*here->MOS9tDepCap)
309                     -here->MOS9tDepCap * here->MOS9f2d;
310             if(model->MOS9capBSGiven) {
311                 czbs = here->MOS9tCbs * here->MOS9m;
312             } else {
313                 if(model->MOS9bulkCapFactorGiven) {
314                     czbs=here->MOS9tCj*here->MOS9sourceArea * here->MOS9m;
315                 } else {
316                     czbs=0;
317                 }
318             }
319             if(model->MOS9sideWallCapFactorGiven) {
320                 czbssw = here->MOS9tCjsw * here->MOS9sourcePerimiter *
321                          here->MOS9m;
322             } else {
323                 czbssw=0;
324             }
325             arg = 1-model->MOS9fwdCapDepCoeff;
326             sarg = exp( (-model->MOS9bulkJctBotGradingCoeff) * log(arg) );
327             sargsw = exp( (-model->MOS9bulkJctSideGradingCoeff) * log(arg) );
328             here->MOS9Cbs = czbs;
329             here->MOS9Cbssw = czbssw;
330             here->MOS9f2s = czbs*(1-model->MOS9fwdCapDepCoeff*
331                         (1+model->MOS9bulkJctBotGradingCoeff))* sarg/arg
332                     +  czbssw*(1-model->MOS9fwdCapDepCoeff*
333                         (1+model->MOS9bulkJctSideGradingCoeff))*
334                         sargsw/arg;
335             here->MOS9f3s = czbs * model->MOS9bulkJctBotGradingCoeff * sarg/arg/
336                         here->MOS9tBulkPot
337                     + czbssw * model->MOS9bulkJctSideGradingCoeff * sargsw/arg /
338                         here->MOS9tBulkPot;
339             here->MOS9f4s = czbs*here->MOS9tBulkPot*(1-arg*sarg)/
340                         (1-model->MOS9bulkJctBotGradingCoeff)
341                     + czbssw*here->MOS9tBulkPot*(1-arg*sargsw)/
342                         (1-model->MOS9bulkJctSideGradingCoeff)
343                     -here->MOS9f3s/2*
344                         (here->MOS9tDepCap*here->MOS9tDepCap)
345                     -here->MOS9tDepCap * here->MOS9f2s;
346         }
347     }
348     return(OK);
349 }
350