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