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