Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / elp / elp_util.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI Alliance */
4 /* */
5 /* Produit : ELP Verison 1 */
6 /* Fichier : elp_util.c */
7 /* */
8 /* (c) copyright 1991-1995 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail cao-vlsi@masi.ibp.fr */
11 /* */
12 /* Auteur(s) : Payam KIANI */
13 /* */
14 /****************************************************************************/
15 /* caracterisation electrique des netlists en fonction des parametres elp */
16 /****************************************************************************/
17
18 #include <stdlib.h>
19 #include <string.h>
20 #include AVT_H
21 #include ELP_H
22
23 //int ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
24 //double ELP_MULU0_MARGIN = -1.0;
25 //double ELP_DELVT0_MARGIN = -1.0;
26 //double ELP_SA_MARGIN = -1.0;
27 //double ELP_SB_MARGIN = -1.0;
28 //double ELP_SD_MARGIN = -1.0;
29 double ELP_NF_MARGIN = -1.0;
30 double ELP_M_MARGIN = -1.0;
31 double ELP_NRS_MARGIN = -1.0;
32 double ELP_NRD_MARGIN = -1.0;
33 extern FILE *elpin ;
34 int ELPLINE ;
35 //int ELP_DRV_FILE = 0;
36 int ELP_GENPARAM = 0 ;
37 int ELP_LOAD_FILE_TYPE = ELP_LOADELP_FILE ;
38 char *elpoldtechnofilename = NULL;
39 int elpres_load;
40 char elpTechnoName[elpSTRINGSIZE] ;
41 char elpTechnoFile[elpSTRINGSIZE] ;
42 char elpGenTechnoFile[elpSTRINGSIZE] ; // auto generated techno
43 double elpTechnoVersion ;
44 char elpEsimName[elpSTRINGSIZE] ;
45 double elpGeneral[elpGENERALNUM] = {0.0,ELPINITTEMP,200.0,ELPMINVOLTAGE,ELPMINVOLTAGE,ELPMINVOLTAGE,ELPINITTHR,ELPINITTHR,ELPINITTHR} ;
46 elpmodel_list *ELP_MODEL_LIST = NULL ;
47 elptree_list *ELP_HEAD_TREE = NULL ;
48 char elpLang = elpDEFLANG ;
49 extern int elpparse() ;
50 int ELP_CAPA_DIFF = 0 ;
51 int ELP_CALC_ONLY_CAPA = 0;
52 void (*elpCalcPAFct)(lotrs_list*,char*,int,int,double,elp_lotrs_param*,double*,double*,double*,double*);
53
54 char *elpTabTechnoName[] = { "No techno", "Bsim3v3", "Bsim4", "Psp", "Mos2", "MM9" };
55
56 /****************************************************************************\
57 FUNCTION : elpSameSD_sig
58 \****************************************************************************/
59 int elpSameSD_sig ( lotrs_list *lotrs )
60 {
61 int same_SD = 0;
62 int vddsource=0, vsssource=0, vdddrain=0, vssdrain=0 ;
63
64 if ( mbk_LosigIsVDD(lotrs->DRAIN->SIG) ) vdddrain=1;
65 if ( mbk_LosigIsVSS(lotrs->DRAIN->SIG) ) vssdrain=1;
66 if ( mbk_LosigIsVDD(lotrs->SOURCE->SIG) ) vddsource=1;
67 if ( mbk_LosigIsVSS(lotrs->SOURCE->SIG) ) vsssource=1;
68
69 if ( (lotrs->DRAIN->SIG == lotrs->SOURCE->SIG) ||
70 ( vdddrain && vddsource ) ||
71 ( vssdrain && vsssource )
72 )
73 same_SD = 1;
74 return same_SD;
75 }
76
77 /****************************************************************************\
78 FUNCTION : elpGetVddFromCorner
79 \****************************************************************************/
80 double elpGetVddFromCorner ( lotrs_list *lotrs, int corner )
81 {
82 double vdd;
83 float alim;
84
85 if(cns_getlotrsalim(lotrs, 'M', &alim)){
86 vdd = (double)alim;
87 }else{
88 switch ( corner ) {
89 case elpBEST : vdd = elpGeneral[elpGVDDBEST];
90 break;
91 case elpWORST: vdd = elpGeneral[elpGVDDWORST];
92 break;
93 default : vdd = elpGeneral[elpGVDDMAX];
94 break;
95 }
96 }
97 return vdd;
98 }
99
100 /*****************************************************************************/
101 /* function elpDouble2Int */
102 /*****************************************************************************/
103 elpFCT int elpDouble2Int ( value )
104 double value;
105 {
106 return (int)(value+0.5);
107 }
108
109 /*****************************************************************************/
110 /* function elpDouble2Long */
111 /*****************************************************************************/
112 elpFCT long elpDouble2Long (value)
113 double value;
114 {
115 return (long)(value+0.5);
116 }
117
118 /*****************************************************************************/
119 /* function elpShrinkSize() */
120 /*****************************************************************************/
121 elpFCT long elpShrinkSize(size,delta,mlt)
122 long size ;
123 double delta ;
124 double mlt ;
125 {
126
127 if((size == 0) || (size == ELPMAXLONG))
128 return(size) ;
129 delta = delta * (double)SCALE_X ;
130 size = elpDouble2Long(mlt*(double)size + delta) ;
131 return(size) ;
132 }
133
134 /*****************************************************************************/
135 /* function elpAddTree() */
136 /*****************************************************************************/
137
138 void elp_get_key(lotrs_list *lt, chain_list **longkey)
139 {
140 ptype_list *pt;
141 *longkey=NULL;
142 if (lt!=NULL && (pt=getptype(lt->USER, MCC_COMPUTED_KEY))!=NULL)
143 *longkey=(chain_list *)pt->DATA;
144 }
145
146 int elp_is_same_paramcontext(chain_list *longkey0, chain_list *longkey1)
147 {
148 while (longkey0!=NULL && longkey1!=NULL && mbk_cmpdouble(*(float *)&longkey0->DATA,*(float *)&longkey1->DATA, EQT_PRECISION)==0)
149 {
150 longkey0=longkey0->NEXT;
151 longkey1=longkey1->NEXT;
152 }
153 if (longkey0!=NULL || longkey1!=NULL) return 0;
154 return 1;
155 }
156
157 elpFCT elptree_list *elpAddTree(head,model,level)
158 elptree_list *head ;
159 elpmodel_list *model ;
160 int level ;
161 {
162 elptree_list *tree ;
163 long mulu0,delvt0,sa,sb,sd,nf,val;
164 long sc,sca,scb,scc;
165
166 tree = (elptree_list *)mbkalloc(sizeof(elptree_list)) ;
167 tree->LEVEL = level ;
168 tree->DOWN = NULL ;
169 tree->NEXT = head ;
170
171 switch(level)
172 {
173 case elpNameLevel : tree->DATA1 = (long)model->elpModelName ;
174 tree->DATA2 = (long)model->elpModelNameAlias ;
175 break ;
176 case elpLengthLevel :
177 tree->DATA1 = model->elpRange[elpLMIN] ;
178 tree->DATA2 = model->elpRange[elpLMAX] ;
179 break ;
180 case elpWidthLevel :
181 tree->DATA1 = model->elpRange[elpWMIN] ;
182 tree->DATA2 = model->elpRange[elpWMAX] ;
183 break ;
184 case elpVDDLevel : tree->DATA1 = elpDouble2Long(model->elpVoltage[elpVDDMAX]*SCALE_X ) ;
185 tree->DATA2 = (long)NULL ;
186 break ;
187 case elpMULU0Level : if ( V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE < 0.0 ) {
188 tree->DATA1 = elpDouble2Long(model->elpModel[elpMULU0]*ELPPRECISION) ;
189 tree->DATA2 = (long)NULL ;
190 }
191 else {
192 mulu0 = elpDouble2Long(model->elpModel[elpMULU0]*ELPPRECISION) ;
193 if ( mulu0 >= 0 ) {
194 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE) * mulu0);
195 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE) * mulu0);
196 }
197 else {
198 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE) * mulu0);
199 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE) * mulu0);
200 }
201 }
202 break ;
203 case elpDELVT0Level : if ( V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE < 0.0 ) {
204 tree->DATA1 = elpDouble2Long (model->elpModel[elpDELVT0]*ELPPRECISION);
205 tree->DATA2 = (long)NULL ;
206 }
207 else {
208 delvt0 = elpDouble2Long (model->elpModel[elpDELVT0]*ELPPRECISION);
209 if ( delvt0 >= 0 ) {
210 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) * delvt0);
211 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) * delvt0);
212 }
213 else {
214 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) * delvt0);
215 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) * delvt0);
216 }
217 }
218 break ;
219 case elpSALevel : if ( model->elpModel[elpSA] < ELPMINVALUE ) {
220 tree->DATA1 = (long)NULL ;
221 tree->DATA2 = (long)NULL ;
222 }
223 else {
224 if ( V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE < 0.0 ) {
225 tree->DATA1 = elpDouble2Long (model->elpModel[elpSA]*ELPPRECISION2);
226 tree->DATA2 = (long)NULL ;
227 }
228 else {
229 sa = elpDouble2Long (model->elpModel[elpSA]*ELPPRECISION2);
230 if ( sa >= 0 ) {
231 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) * sa);
232 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) * sa);
233 }
234 else {
235 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) * sa);
236 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) * sa);
237 }
238 }
239 }
240 break ;
241 case elpSBLevel : if ( model->elpModel[elpSB] < ELPMINVALUE ) {
242 tree->DATA1 = (long)NULL ;
243 tree->DATA2 = (long)NULL ;
244 }
245 else {
246 if ( V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE < 0.0 ) {
247 tree->DATA1 = elpDouble2Long (model->elpModel[elpSB]*ELPPRECISION2);
248 tree->DATA2 = (long)NULL ;
249 }
250 else {
251 sb = elpDouble2Long (model->elpModel[elpSB]*ELPPRECISION2);
252 if ( sb >= 0 ) {
253 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) * sb);
254 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) * sb);
255 }
256 else {
257 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) * sb);
258 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) * sb);
259 }
260 }
261 }
262 break ;
263 case elpSDLevel : if ( model->elpModel[elpSD] < ELPMINVALUE ) {
264 tree->DATA1 = (long)NULL ;
265 tree->DATA2 = (long)NULL ;
266 }
267 else {
268 if ( V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE < 0.0 ) {
269 tree->DATA1 = elpDouble2Long (model->elpModel[elpSD]*ELPPRECISION2);
270 tree->DATA2 = (long)NULL ;
271 }
272 else {
273 sd = elpDouble2Long (model->elpModel[elpSD]*ELPPRECISION2);
274 if ( sd >= 0 ) {
275 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) * sd);
276 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) * sd);
277 }
278 else {
279 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) * sd);
280 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) * sd);
281 }
282 }
283 }
284 break ;
285 case elpNFLevel : if ( model->elpModel[elpNF] < ELPMINVALUE ) {
286 tree->DATA1 = (long)NULL ;
287 tree->DATA2 = (long)NULL ;
288 }
289 else {
290 if ( ELP_NF_MARGIN < 0.0 ) {
291 tree->DATA1 = elpDouble2Long (model->elpModel[elpNF]);
292 tree->DATA2 = (long)NULL ;
293 }
294 else {
295 nf = elpDouble2Long (model->elpModel[elpNF]);
296 if ( nf >= 0 ) {
297 tree->DATA1 = elpDouble2Long((1.0 - ELP_NF_MARGIN) * nf);
298 tree->DATA2 = elpDouble2Long((1.0 + ELP_NF_MARGIN) * nf);
299 }
300 else {
301 tree->DATA1 = elpDouble2Long((1.0 + ELP_NF_MARGIN) * nf);
302 tree->DATA2 = elpDouble2Long((1.0 - ELP_NF_MARGIN) * nf);
303 }
304 }
305 }
306 break ;
307 case elpMLevel : if ( model->elpModel[elpM] < ELPMINVALUE ) {
308 tree->DATA1 = (long)NULL ;
309 tree->DATA2 = (long)NULL ;
310 }
311 else {
312 if ( ELP_M_MARGIN < 0.0 ) {
313 tree->DATA1 = elpDouble2Long (model->elpModel[elpM]);
314 tree->DATA2 = (long)NULL ;
315 }
316 else {
317 val = elpDouble2Long (model->elpModel[elpM]);
318 if ( val >= 0 ) {
319 tree->DATA1 = elpDouble2Long((1.0 - ELP_M_MARGIN) * val);
320 tree->DATA2 = elpDouble2Long((1.0 + ELP_M_MARGIN) * val);
321 }
322 else {
323 tree->DATA1 = elpDouble2Long((1.0 + ELP_M_MARGIN) * val);
324 tree->DATA2 = elpDouble2Long((1.0 - ELP_M_MARGIN) * val);
325 }
326 }
327 }
328 break ;
329 case elpNRSLevel : if ( model->elpModel[elpNRS] < ELPMINVALUE ) {
330 tree->DATA1 = (long)NULL ;
331 tree->DATA2 = (long)NULL ;
332 }
333 else {
334 if ( ELP_M_MARGIN < 0.0 ) {
335 tree->DATA1 = elpDouble2Long (model->elpModel[elpNRS]*ELPPRECISION);
336 tree->DATA2 = (long)NULL ;
337 }
338 else {
339 val = elpDouble2Long (model->elpModel[elpNRS]*ELPPRECISION);
340 if ( val >= 0 ) {
341 tree->DATA1 = elpDouble2Long((1.0 - ELP_NRS_MARGIN) * val);
342 tree->DATA2 = elpDouble2Long((1.0 + ELP_NRS_MARGIN) * val);
343 }
344 else {
345 tree->DATA1 = elpDouble2Long((1.0 + ELP_NRS_MARGIN) * val);
346 tree->DATA2 = elpDouble2Long((1.0 - ELP_NRS_MARGIN) * val);
347 }
348 }
349 }
350 break ;
351 case elpNRDLevel : if ( model->elpModel[elpNRD] < ELPMINVALUE ) {
352 tree->DATA1 = (long)NULL ;
353 tree->DATA2 = (long)NULL ;
354 }
355 else {
356 if ( ELP_M_MARGIN < 0.0 ) {
357 tree->DATA1 = elpDouble2Long (model->elpModel[elpNRD]*ELPPRECISION);
358 tree->DATA2 = (long)NULL ;
359 }
360 else {
361 val = elpDouble2Long (model->elpModel[elpNRD]*ELPPRECISION);
362 if ( val >= 0 ) {
363 tree->DATA1 = elpDouble2Long((1.0 - ELP_NRD_MARGIN) * val);
364 tree->DATA2 = elpDouble2Long((1.0 + ELP_NRD_MARGIN) * val);
365 }
366 else {
367 tree->DATA1 = elpDouble2Long((1.0 + ELP_NRD_MARGIN) * val);
368 tree->DATA2 = elpDouble2Long((1.0 - ELP_NRD_MARGIN) * val);
369 }
370 }
371 }
372 break ;
373 case elpSCLevel : if ( model->elpModel[elpSC] < ELPMINVALUE ) {
374 tree->DATA1 = (long)NULL ;
375 tree->DATA2 = (long)NULL ;
376 }
377 else {
378 if ( V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE < 0.0 ) {
379 tree->DATA1 = elpDouble2Long (model->elpModel[elpSC]*ELPPRECISION2);
380 tree->DATA2 = (long)NULL ;
381 }
382 else {
383 sc = elpDouble2Long (model->elpModel[elpSC]*ELPPRECISION2);
384 if ( sc >= 0 ) {
385 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) * sc);
386 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) * sc);
387 }
388 else {
389 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) * sc);
390 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) * sc);
391 }
392 }
393 }
394 break ;
395 case elpSCALevel : if ( model->elpModel[elpSCA] < ELPMINVALUE ) {
396 tree->DATA1 = (long)NULL ;
397 tree->DATA2 = (long)NULL ;
398 }
399 else {
400 if ( V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE < 0.0 ) {
401 tree->DATA1 = elpDouble2Long (model->elpModel[elpSCA]*ELPPRECISION2);
402 tree->DATA2 = (long)NULL ;
403 }
404 else {
405 sca = elpDouble2Long (model->elpModel[elpSCA]*ELPPRECISION2);
406 if ( sca >= 0 ) {
407 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) * sca);
408 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) * sca);
409 }
410 else {
411 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) * sca);
412 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) * sca);
413 }
414 }
415 }
416 break ;
417 case elpSCBLevel : if ( model->elpModel[elpSCB] < ELPMINVALUE ) {
418 tree->DATA1 = (long)NULL ;
419 tree->DATA2 = (long)NULL ;
420 }
421 else {
422 if ( V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE < 0.0 ) {
423 tree->DATA1 = elpDouble2Long (model->elpModel[elpSCB]*ELPPRECISION2);
424 tree->DATA2 = (long)NULL ;
425 }
426 else {
427 scb = elpDouble2Long (model->elpModel[elpSCB]*ELPPRECISION2);
428 if ( scb >= 0 ) {
429 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) * scb);
430 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) * scb);
431 }
432 else {
433 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) * scb);
434 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) * scb);
435 }
436 }
437 }
438 break ;
439 case elpSCCLevel : if ( model->elpModel[elpSCC] < ELPMINVALUE ) {
440 tree->DATA1 = (long)NULL ;
441 tree->DATA2 = (long)NULL ;
442 }
443 else {
444 if ( V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE < 0.0 ) {
445 tree->DATA1 = elpDouble2Long (model->elpModel[elpSCC]*ELPPRECISION2);
446 tree->DATA2 = (long)NULL ;
447 }
448 else {
449 sca = elpDouble2Long (model->elpModel[elpSCC]*ELPPRECISION2);
450 if ( sca >= 0 ) {
451 tree->DATA1 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) * scc);
452 tree->DATA2 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) * scc);
453 }
454 else {
455 tree->DATA1 = elpDouble2Long((1.0 + V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) * scc);
456 tree->DATA2 = elpDouble2Long((1.0 - V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) * scc);
457 }
458 }
459 }
460 break ;
461 case elpVBULKLevel : tree->DATA1 = elpDouble2Long(model->elpVoltage[elpVBULK]*SCALE_X ) ;
462 tree->DATA2 = (long)NULL ;
463 break ;
464 case elpParamContextLevel :
465 tree->DATA1 = (long)model->longkey;
466 tree->DATA2 = (long)NULL ;
467 break;
468 case elpCaseLevel : tree->DATA1 = (long)model->elpTransCase ;
469 tree->DATA2 = (long)NULL ;
470 break ;
471 }
472
473 return tree ;
474 }
475
476 /*****************************************************************************/
477 /* function elpCmpTreeModel() */
478 /*****************************************************************************/
479 elpFCT int elpCmpTreeModel(tree,model,level)
480 elptree_list *tree ;
481 elpmodel_list *model ;
482 int level ;
483 {
484 int res = 0 ;
485 long mulu0,delvt0,sa,sb,sd,nf,val,sc,sca,scb,scc;
486
487 switch(level)
488 {
489 case elpNameLevel : if(tree->DATA1 == (long)model->elpModelName)
490 res = 1 ;
491 break ;
492 case elpLengthLevel :
493 if((tree->DATA1 == model->elpRange[elpLMIN]) &&
494 (tree->DATA2 == model->elpRange[elpLMAX]))
495 res = 1 ;
496 break ;
497 case elpWidthLevel :
498 if((tree->DATA1 == model->elpRange[elpWMIN]) &&
499 (tree->DATA2 == model->elpRange[elpWMAX]))
500 res = 1 ;
501 break ;
502 case elpVDDLevel : if(tree->DATA1 == elpDouble2Long (model->elpVoltage[elpVDDMAX]*SCALE_X ))
503 res = 1 ;
504 break ;
505 case elpMULU0Level : if ( V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE < 0.0 ) {
506 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpMULU0]*ELPPRECISION))
507 res = 1;
508 }
509 else {
510 mulu0 = elpDouble2Long (model->elpModel[elpMULU0]*ELPPRECISION);
511 if ( mulu0 >= tree->DATA1 && mulu0 <= tree->DATA2 )
512 res = 1;
513 }
514 break ;
515 case elpDELVT0Level : if ( V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE < 0.0 ) {
516 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpDELVT0]*ELPPRECISION))
517 res = 1;
518 }
519 else {
520 delvt0 = elpDouble2Long (model->elpModel[elpDELVT0]*ELPPRECISION);
521 if ( delvt0 >= tree->DATA1 && delvt0 <= tree->DATA2 )
522 res = 1;
523 }
524 break ;
525 case elpSALevel : if ( model->elpModel[elpSA] < ELPMINVALUE )
526 res = 1;
527 else {
528 if ( V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE < 0.0 ) {
529 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSA]*ELPPRECISION2))
530 res = 1;
531 }
532 else {
533 sa = elpDouble2Long (model->elpModel[elpSA]*ELPPRECISION2);
534 if ( sa >= tree->DATA1 && sa <= tree->DATA2 )
535 res = 1;
536 }
537 }
538 break ;
539 case elpSBLevel : if ( model->elpModel[elpSB] < ELPMINVALUE )
540 res = 1;
541 else {
542 if ( V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE < 0.0 ) {
543 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSB]*ELPPRECISION2))
544 res = 1;
545 }
546 else {
547 sb = elpDouble2Long (model->elpModel[elpSB]*ELPPRECISION2);
548 if ( sb >= tree->DATA1 && sb <= tree->DATA2 )
549 res = 1;
550 }
551 }
552 break ;
553 case elpSDLevel : if ( model->elpModel[elpSD] < ELPMINVALUE )
554 res = 1;
555 else {
556 if ( V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE < 0.0 ) {
557 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSD]*ELPPRECISION2))
558 res = 1;
559 }
560 else {
561 sd = elpDouble2Long (model->elpModel[elpSD]*ELPPRECISION2);
562 if ( sd >= tree->DATA1 && sd <= tree->DATA2 )
563 res = 1;
564 }
565 }
566 break ;
567 case elpNFLevel : if ( model->elpModel[elpNF] < ELPMINVALUE )
568 res = 1;
569 else {
570 if ( ELP_NF_MARGIN < 0.0 ) {
571 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpNF]))
572 res = 1;
573 }
574 else {
575 nf = elpDouble2Long (model->elpModel[elpNF]);
576 if ( nf >= tree->DATA1 && nf <= tree->DATA2 )
577 res = 1;
578 }
579 }
580 break ;
581 case elpMLevel : if ( model->elpModel[elpM] < ELPMINVALUE )
582 res = 1;
583 else {
584 if ( ELP_M_MARGIN < 0.0 ) {
585 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpM]))
586 res = 1;
587 }
588 else {
589 val = elpDouble2Long (model->elpModel[elpM]);
590 if ( val >= tree->DATA1 && val <= tree->DATA2 )
591 res = 1;
592 }
593 }
594 break ;
595 case elpNRSLevel : if ( model->elpModel[elpNRS] < ELPMINVALUE )
596 res = 1;
597 else {
598 if ( ELP_NRS_MARGIN < 0.0 ) {
599 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpNRS]*ELPPRECISION))
600 res = 1;
601 }
602 else {
603 val = elpDouble2Long (model->elpModel[elpNRS]*ELPPRECISION);
604 if ( val >= tree->DATA1 && val <= tree->DATA2 )
605 res = 1;
606 }
607 }
608 break ;
609 case elpNRDLevel : if ( model->elpModel[elpNRD] < ELPMINVALUE )
610 res = 1;
611 else {
612 if ( ELP_NRD_MARGIN < 0.0 ) {
613 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpNRD]*ELPPRECISION))
614 res = 1;
615 }
616 else {
617 val = elpDouble2Long (model->elpModel[elpNRD]*ELPPRECISION);
618 if ( val >= tree->DATA1 && val <= tree->DATA2 )
619 res = 1;
620 }
621 }
622 break ;
623 case elpVBULKLevel : if(tree->DATA1 == elpDouble2Long (model->elpVoltage[elpVBULK]*SCALE_X))
624 res = 1 ;
625 break ;
626 case elpParamContextLevel :
627 if(elp_is_same_paramcontext((chain_list *)tree->DATA1,model->longkey))
628 res=1;
629 break;
630 case elpCaseLevel : if(tree->DATA1 == (long)model->elpTransCase)
631 res = 1 ;
632 break ;
633 case elpSCLevel : if ( model->elpModel[elpSC] < ELPMINVALUE )
634 res = 1;
635 else {
636 if ( V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE < 0.0 ) {
637 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSC]*ELPPRECISION2))
638 res = 1;
639 }
640 else {
641 sc = elpDouble2Long (model->elpModel[elpSC]*ELPPRECISION2);
642 if ( sc >= tree->DATA1 && sc <= tree->DATA2 )
643 res = 1;
644 }
645 }
646 break ;
647 case elpSCALevel : if ( model->elpModel[elpSCA] < ELPMINVALUE )
648 res = 1;
649 else {
650 if ( V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE < 0.0 ) {
651 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSCA]*ELPPRECISION2))
652 res = 1;
653 }
654 else {
655 sca = elpDouble2Long (model->elpModel[elpSCA]*ELPPRECISION2);
656 if ( sca >= tree->DATA1 && sca <= tree->DATA2 )
657 res = 1;
658 }
659 }
660 break ;
661 case elpSCBLevel : if ( model->elpModel[elpSCB] < ELPMINVALUE )
662 res = 1;
663 else {
664 if ( V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE < 0.0 ) {
665 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSCB]*ELPPRECISION2))
666 res = 1;
667 }
668 else {
669 scb = elpDouble2Long (model->elpModel[elpSCB]*ELPPRECISION2);
670 if ( scb >= tree->DATA1 && scb <= tree->DATA2 )
671 res = 1;
672 }
673 }
674 break ;
675 case elpSCCLevel : if ( model->elpModel[elpSCC] < ELPMINVALUE )
676 res = 1;
677 else {
678 if ( V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE < 0.0 ) {
679 if (tree->DATA1 == elpDouble2Long (model->elpModel[elpSCC]*ELPPRECISION2))
680 res = 1;
681 }
682 else {
683 scc = elpDouble2Long (model->elpModel[elpSCC]*ELPPRECISION2);
684 if ( scc >= tree->DATA1 && scc <= tree->DATA2 )
685 res = 1;
686 }
687 }
688 break ;
689 }
690
691 return(res) ;
692 }
693
694 /*****************************************************************************/
695 /* function elpDiffTree() */
696 /*****************************************************************************/
697 elpFCT int elpDiffTree(model,tree,level)
698 elpmodel_list *model ;
699 elptree_list *tree ;
700 int level ;
701 {
702
703 switch(level)
704 {
705 case elpNameLevel : return 0 ;
706 case elpLengthLevel :
707 if(model->elpRange[elpLMAX] > tree->DATA2)
708 return 1 ;
709 else
710 return 0 ;
711 case elpWidthLevel :
712 if(model->elpRange[elpWMAX] > tree->DATA2)
713 return 1 ;
714 else
715 return 0 ;
716 case elpVDDLevel : return 0 ;
717 case elpMULU0Level : return 0 ;
718 case elpDELVT0Level : return 0 ;
719 case elpSALevel : return 0 ;
720 case elpSBLevel : return 0 ;
721 case elpSDLevel : return 0 ;
722 case elpNFLevel : return 0 ;
723 case elpMLevel : return 0 ;
724 case elpNRSLevel : return 0 ;
725 case elpNRDLevel : return 0 ;
726 case elpVBULKLevel : return 0 ;
727 case elpParamContextLevel : return 0 ;
728 case elpCaseLevel : return 0 ;
729 case elpSCLevel : return 0 ;
730 case elpSCALevel : return 0 ;
731 case elpSCBLevel : return 0 ;
732 case elpSCCLevel : return 0 ;
733 }
734
735 return 0 ;
736 }
737
738 /*****************************************************************************/
739 /* function elpBuiltTreeModel() */
740 /*****************************************************************************/
741 elpFCT elptree_list *elpBuiltTreeModel(head,model,level)
742 elptree_list *head ;
743 elpmodel_list *model ;
744 int level ;
745 {
746 elptree_list *tree ;
747 elptree_list *pt ;
748
749 for(tree = head ; tree != NULL ; tree = tree->NEXT)
750 {
751 if(elpCmpTreeModel(tree,model,level) == 1)
752 break ;
753 }
754
755 if(tree == NULL)
756 {
757 if(head == NULL)
758 {
759 head = elpAddTree(head,model,level) ;
760 tree = head ;
761 }
762 else
763 {
764 tree = head ;
765 pt = tree ;
766 while(tree != NULL)
767 {
768 if(elpDiffTree(model,tree,level) == 1)
769 {
770 pt = tree ;
771 tree = tree->NEXT ;
772 continue ;
773 }
774 else
775 {
776 if(tree == head)
777 {
778 head = elpAddTree(head,model,level) ;
779 tree = head ;
780 }
781 else
782 {
783 pt->NEXT = elpAddTree(pt->NEXT,model,level) ;
784 tree = pt->NEXT ;
785 }
786 break ;
787 }
788 }
789 if(tree == NULL)
790 {
791 pt->NEXT = elpAddTree(pt->NEXT,model,level) ;
792 tree = pt->NEXT ;
793 }
794 }
795 }
796 else
797 {
798 if(level == elpCaseLevel)
799 return(head) ;
800 }
801
802 if(level != elpCaseLevel)
803 tree->DOWN = elpBuiltTreeModel(tree->DOWN,model,level+1) ;
804 else
805 tree->DOWN = model ;
806
807 return(head) ;
808 }
809
810 /*****************************************************************************/
811 /* function elpaddmodel() */
812 /*****************************************************************************/
813 elpFCT elpmodel_list *elpAddModel(name,name_alias,type,index,lmin,lmax,
814 wmin,wmax,dl,dw,ml,mw,vdd,trcase, trtechno,
815 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,longkey)
816 char *name ;
817 chain_list *name_alias;
818 int type ;
819 int index ;
820 long lmin ;
821 long lmax ;
822 long wmin ;
823 long wmax ;
824 double dl ;
825 double dw ;
826 double ml ;
827 double mw ;
828 double vdd ;
829 int trcase ;
830 int trtechno ;
831 double mulu0 ;
832 double delvt0;
833 double sa;
834 double sb;
835 double sd;
836 double nf;
837 double m;
838 double nrs;
839 double nrd;
840 double vbulk;
841 double sc;
842 double sca;
843 double scb;
844 double scc;
845 chain_list *longkey;
846 {
847 elpmodel_list *model ;
848 int i ;
849 static int warn_displayed=0 ;
850
851 if( nf >=2 && (wmin != wmax || lmin != lmax ) ) {
852 if( ! warn_displayed ) {
853 warn_displayed = 1 ;
854 fprintf( stderr, "warning : setting avtCharacForEachSize to a value different than yes for transistor with nf parameter greater than 1 can lead to unpredictable results !\n" );
855 }
856 }
857
858 model = (elpmodel_list *)mbkalloc(sizeof(elpmodel_list)) ;
859
860 if(ELP_MODEL_LIST == NULL)
861 model->elpModelIndex = 0 ;
862 else
863 model->elpModelIndex = ELP_MODEL_LIST->elpModelIndex + 1 ;
864
865 model->NEXT = ELP_MODEL_LIST ;
866 ELP_MODEL_LIST = model ;
867
868 model->elpTransType = type ;
869 model->elpTransModel = elpMOS ;
870 model->elpTransIndex = index ;
871 model->elpVoltage[elpVDDMAX] = vdd ;
872 model->elpVoltage[elpVBULK] = vbulk;
873 model->elpTransCase = trcase ;
874 model->elpTransTechno = trtechno ;
875 model->elpModelNameAlias = name_alias;
876
877 if(name != NULL) {
878 model->elpModelName = namealloc(name) ;
879 if (type == elpNMOS && !mbk_istransn(model->elpModelName)) TNMOS = addchain(TNMOS, model->elpModelName);
880 else if (type == elpPMOS && !mbk_istransp(model->elpModelName)) TPMOS = addchain(TPMOS, model->elpModelName);
881 }
882 else
883 {
884 if(type == elpNMOS)
885 {
886 model->elpModelName = namealloc("TN") ;
887 if (!mbk_istransn(model->elpModelName)) TNMOS = addchain(TNMOS, model->elpModelName);
888 }
889 else
890 {
891 model->elpModelName = namealloc("TP") ;
892 if (!mbk_istransp(model->elpModelName)) TPMOS = addchain(TPMOS, model->elpModelName);
893 }
894 }
895
896 /* Initialisation des parametres du modele */
897
898 model->elpShrink[elpLMLT] = ml ;
899 model->elpShrink[elpWMLT] = mw ;
900 model->elpShrink[elpDL] = dl ;
901 model->elpShrink[elpDW] = dw ;
902 model->elpShrink[elpDLC] = dl ;
903 model->elpShrink[elpDWC] = dw ;
904 model->elpShrink[elpDWCJ] = dw ;
905
906 model->elpRange[elpLMIN] = lmin ;
907 model->elpRange[elpLMAX] = lmax ;
908 model->elpRange[elpWMIN] = wmin ;
909 model->elpRange[elpWMAX] = wmax ;
910
911 model->elpTemp = ELPINITTEMP ;
912
913 for (i = 0 ; i < elpMODELNUM ; i++)
914 model->elpModel[i] = 0.0 ;
915 model->elpModel[elpMULU0] = mulu0;
916 model->elpModel[elpDELVT0] = delvt0;
917 model->elpModel[elpSA] = sa;
918 model->elpModel[elpSB] = sb;
919 model->elpModel[elpSD] = sd;
920 model->elpModel[elpNF] = nf;
921 model->elpModel[elpM] = m;
922 model->elpModel[elpNRS] = nrs;
923 model->elpModel[elpNRD] = nrd;
924 model->elpModel[elpSC] = sc;
925 model->elpModel[elpSCA] = sca;
926 model->elpModel[elpSCB] = scb;
927 model->elpModel[elpSCC] = scc;
928 model->longkey=dupchainlst(longkey);
929
930 model->elpVoltage[elpVDEG] = ELPMINVOLTAGE ;
931 model->elpVoltage[elpVTI] = ELPMINVOLTAGE ;
932
933 for (i = 0 ; i < elpCAPANUM ; i++)
934 model->elpCapa[i] = 0.0 ;
935
936 for (i = 0 ; i < elpRSSNUM ; i++)
937 model->elpRss[i] = 0.0 ;
938
939 ELP_HEAD_TREE = elpBuiltTreeModel(ELP_HEAD_TREE,model,elpNameLevel) ;
940
941 return model ;
942 }
943
944 /*****************************************************************************/
945 /* function elpFreeTreeModel() */
946 /*****************************************************************************/
947 elpFCT void elpFreeTreeModel(head,level)
948 elptree_list *head ;
949 int level ;
950 {
951 elptree_list *tree ;
952
953 while(head != NULL)
954 {
955 tree = head->NEXT ;
956 if(level != elpCaseLevel)
957 elpFreeTreeModel(head->DOWN,level + 1) ;
958 mbkfree(head) ;
959 head = tree ;
960 }
961 }
962
963
964 /*****************************************************************************/
965 /* function elpPrintData() */
966 /*****************************************************************************/
967 elpFCT void elpPrintData(elptree_list *tree, int level)
968 {
969 chain_list *chain,*chain_alias;
970 ptype_list *pt;
971
972 switch(level)
973 {
974 case elpNameLevel : fprintf(stdout, "Model Name : %s\n", (char *)tree->DATA1) ;
975 chain_alias = (chain_list*)tree->DATA2;
976 if (chain_alias)
977 {
978 fprintf (stdout,"Alias ");
979 for (chain = chain_alias ; chain ; chain = chain->NEXT)
980 fprintf(stdout,": %s ",(char*)chain->DATA);
981 fprintf (stdout,"\n");
982 }
983 break ;
984 case elpLengthLevel : fprintf(stdout, "LMIN = %ld\n", tree->DATA1) ;
985 fprintf(stdout, "LMAX = %ld\n", tree->DATA2) ;
986 break ;
987 case elpWidthLevel : fprintf(stdout, "WMIN = %ld\n", tree->DATA1) ;
988 fprintf(stdout, "WMAX = %ld\n", tree->DATA2) ;
989 break ;
990 case elpVDDLevel : fprintf(stdout, "VDDMAX = %ld\n", tree->DATA1) ;
991 break ;
992 case elpMULU0Level : fprintf(stdout, "MULU0 = %ld\n", tree->DATA1) ;
993 break ;
994 case elpDELVT0Level : fprintf(stdout, "DELVT0 = %ld\n", tree->DATA1) ;
995 break ;
996 case elpSALevel : fprintf(stdout, "SA = %ld\n", tree->DATA1) ;
997 break ;
998 case elpSBLevel : fprintf(stdout, "SB = %ld\n", tree->DATA1) ;
999 break ;
1000 case elpSDLevel : fprintf(stdout, "SD = %ld\n", tree->DATA1) ;
1001 break ;
1002 case elpNFLevel : fprintf(stdout, "NF = %ld\n", tree->DATA1) ;
1003 break ;
1004 case elpVBULKLevel : fprintf(stdout, "VBULK = %ld\n", tree->DATA1) ;
1005 break ;
1006 case elpParamContextLevel :
1007 fprintf(stdout, "ParamContext :");
1008 for (pt=(ptype_list *)tree->DATA1; pt!=NULL; pt=pt->NEXT)
1009 {
1010 if ((long)pt==tree->DATA1)
1011 fprintf(stdout," %s (fastkey=%ld)", (char *)pt->DATA, pt->TYPE);
1012 else
1013 fprintf(stdout," %s=%g", (char *)pt->DATA, *(float *)&pt->TYPE);
1014 }
1015 fprintf(stdout,"\n");
1016 break;
1017
1018 case elpCaseLevel : fprintf(stdout, "Case value : %ld\n", tree->DATA1) ;
1019 break ;
1020 case elpSCLevel : fprintf(stdout, "SC = %ld\n", tree->DATA1) ;
1021 break ;
1022 case elpSCALevel : fprintf(stdout, "SCA = %ld\n", tree->DATA1) ;
1023 break ;
1024 case elpSCBLevel : fprintf(stdout, "SCB = %ld\n", tree->DATA1) ;
1025 break ;
1026 case elpSCCLevel : fprintf(stdout, "SCC = %ld\n", tree->DATA1) ;
1027 break ;
1028 }
1029
1030 }
1031
1032
1033 /*****************************************************************************/
1034 /* function elpPrintTreeModel() */
1035 /*****************************************************************************/
1036 elpFCT void elpPrintTreeModel(head,level)
1037 elptree_list *head ;
1038 int level ;
1039 {
1040 elptree_list *tree ;
1041
1042 if (!head) {
1043 fprintf(stdout, "Empty tree!!!\n") ;
1044 return ;
1045 }
1046
1047 for (tree = head ; tree ; tree = tree->NEXT) {
1048 elpPrintData(tree, level) ;
1049 if(level != elpCaseLevel)
1050 elpPrintTreeModel(tree->DOWN, level + 1) ;
1051 }
1052 }
1053
1054 /*****************************************************************************/
1055 /* function elpFreemodel() */
1056 /*****************************************************************************/
1057 elpFCT void elpFreeModel()
1058 {
1059 elpmodel_list *model ;
1060
1061 while(ELP_MODEL_LIST != NULL)
1062 {
1063 model = ELP_MODEL_LIST ;
1064 ELP_MODEL_LIST = ELP_MODEL_LIST->NEXT ;
1065 freechain (model->elpModelNameAlias) ;
1066 freechain(model->longkey);
1067 mbkfree(model) ;
1068 }
1069
1070 ELP_MODEL_LIST = NULL ;
1071 elpFreeTreeModel(ELP_HEAD_TREE,elpNameLevel) ;
1072 ELP_HEAD_TREE = NULL ;
1073
1074 elpGeneral[elpACM] = 0.0 ;
1075 elpGeneral[elpTEMP] = ELPINITTEMP ;
1076 elpGeneral[elpSLOPE] = 200.0 ;
1077 elpGeneral[elpGVDDMAX] = ELPMINVOLTAGE ;
1078 elpGeneral[elpGVDDBEST] = ELPMINVOLTAGE ;
1079 elpGeneral[elpGVDDWORST] = ELPMINVOLTAGE ;
1080 elpGeneral[elpGDTHR] = ELPINITTHR ;
1081 elpGeneral[elpGSHTHR] = ELPINITTHR ;
1082 elpGeneral[elpGSLTHR] = ELPINITTHR ;
1083 }
1084
1085 /*****************************************************************************/
1086 /* function elpCmpTreeLotrs() */
1087 /*****************************************************************************/
1088 elpFCT int elpCmpTreeLotrs (tree,lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,
1089 nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level,longkey)
1090 elptree_list *tree ;
1091 lotrs_list *lotrs ;
1092 double vdd ;
1093 int transcase ;
1094 double mulu0;
1095 double delvt0;
1096 double sa;
1097 double sb;
1098 double sd;
1099 double nf;
1100 double m;
1101 double nrs;
1102 double nrd;
1103 double vbulk;
1104 double sc;
1105 double sca;
1106 double scb;
1107 double scc;
1108 int level ;
1109 chain_list *longkey;
1110 {
1111 int res = 0 ;
1112 char *name ;
1113 chain_list *chain;
1114
1115 switch(level)
1116 {
1117 case elpNameLevel : name = getlotrsmodel(lotrs) ;
1118 if((tree->DATA1 == (long)NULL) ||
1119 (tree->DATA1 == (long)name))
1120 res = 1 ;
1121 if (res == 0)
1122 {
1123 for (chain = (chain_list*)tree->DATA2 ; chain ;
1124 chain = chain->NEXT)
1125 if ((char*)chain->DATA == name)
1126 res = 1 ;
1127 }
1128 break ;
1129 case elpLengthLevel : if((lotrs->LENGTH >= tree->DATA1) &&
1130 ((lotrs->LENGTH <= tree->DATA2) ||
1131 ((lotrs->LENGTH == tree->DATA2) &&
1132 (tree->DATA1 == tree->DATA2))))
1133 {
1134 if(lotrs->LENGTH > tree->DATA2)
1135 res = 2 ;
1136 else
1137 res = 1 ;
1138 }
1139 break ;
1140 case elpWidthLevel : if((lotrs->WIDTH >= tree->DATA1) &&
1141 ((lotrs->WIDTH <= tree->DATA2) ||
1142 ((lotrs->WIDTH == tree->DATA2) &&
1143 (tree->DATA1 == tree->DATA2))))
1144 {
1145 if(lotrs->WIDTH > tree->DATA2)
1146 res = 2 ;
1147 else
1148 res = 1 ;
1149 }
1150 break ;
1151 case elpVDDLevel : if(tree->DATA1 == elpDouble2Long(vdd*SCALE_X))
1152 res = 1 ;
1153 else if(tree->DATA1 < 0) {
1154 if (elpDouble2Long (vdd*SCALE_X ) ==
1155 elpDouble2Long(elpGeneral[elpGVDDMAX]*SCALE_X))
1156 res = 1 ;
1157 }
1158 break ;
1159 case elpMULU0Level : if ( V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE < 0.0 ) {
1160 if (tree->DATA1 == elpDouble2Long (mulu0*ELPPRECISION))
1161 res = 1;
1162 }
1163 else {
1164 mulu0 = elpDouble2Long (mulu0*ELPPRECISION);
1165 if ( mulu0 >= tree->DATA1 && mulu0 <= tree->DATA2 )
1166 res = 1;
1167 }
1168 break ;
1169 case elpDELVT0Level : if ( V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE < 0.0 ) {
1170 if (tree->DATA1 == elpDouble2Long (delvt0*ELPPRECISION))
1171 res = 1;
1172 }
1173 else {
1174 delvt0 = elpDouble2Long (delvt0*ELPPRECISION);
1175 if ( delvt0 >= tree->DATA1 && delvt0 <= tree->DATA2 )
1176 res = 1;
1177 }
1178 break ;
1179 case elpSALevel : if ( sa < ELPMINVALUE )
1180 res = 1;
1181 else {
1182 if ( V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE < 0.0 ) {
1183 if (tree->DATA1 == elpDouble2Long (sa*ELPPRECISION2))
1184 res = 1;
1185 }
1186 else {
1187 sa = elpDouble2Long (sa*ELPPRECISION2);
1188 if ( sa >= tree->DATA1 && sa <= tree->DATA2 )
1189 res = 1;
1190 }
1191 }
1192 break ;
1193 case elpSBLevel : if ( sb < ELPMINVALUE )
1194 res = 1;
1195 else {
1196 if ( V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE < 0.0 ) {
1197 if (tree->DATA1 == elpDouble2Long (sb*ELPPRECISION2))
1198 res = 1;
1199 }
1200 else {
1201 sb = elpDouble2Long (sb*ELPPRECISION2);
1202 if ( sb >= tree->DATA1 && sb <= tree->DATA2 )
1203 res = 1;
1204 }
1205 }
1206 break ;
1207 case elpSDLevel : if ( sd < ELPMINVALUE )
1208 res = 1;
1209 else {
1210 if ( V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE < 0.0 ) {
1211 if (tree->DATA1 == elpDouble2Long (sd*ELPPRECISION2))
1212 res = 1;
1213 }
1214 else {
1215 sd = elpDouble2Long (sd*ELPPRECISION2);
1216 if ( sd >= tree->DATA1 && sd <= tree->DATA2 )
1217 res = 1;
1218 }
1219 }
1220 break ;
1221 case elpNFLevel : if ( nf < ELPMINVALUE )
1222 res = 1;
1223 else {
1224 if ( ELP_NF_MARGIN < 0.0 ) {
1225 if (tree->DATA1 == elpDouble2Long (nf))
1226 res = 1;
1227 }
1228 else {
1229 nf = elpDouble2Long (nf);
1230 if ( nf >= tree->DATA1 && nf <= tree->DATA2 )
1231 res = 1;
1232 }
1233 }
1234 break ;
1235 case elpMLevel : if ( ELP_M_MARGIN < 0.0 ) {
1236 if (tree->DATA1 == elpDouble2Long (m))
1237 res = 1;
1238 }
1239 else {
1240 m = elpDouble2Long (m);
1241 if ( m >= tree->DATA1 && m <= tree->DATA2 )
1242 res = 1;
1243 }
1244 break ;
1245 case elpNRSLevel : if ( nrs < ELPMINVALUE )
1246 res = 1;
1247 else {
1248 if ( ELP_NRS_MARGIN < 0.0 ) {
1249 if (tree->DATA1 == elpDouble2Long (nrs*ELPPRECISION))
1250 res = 1;
1251 }
1252 else {
1253 nrs = elpDouble2Long (nrs*ELPPRECISION);
1254 if ( nrs >= tree->DATA1 && nrs <= tree->DATA2 )
1255 res = 1;
1256 }
1257 }
1258 break ;
1259 case elpNRDLevel : if ( nrd < ELPMINVALUE )
1260 res = 1;
1261 else {
1262 if ( ELP_NRD_MARGIN < 0.0 ) {
1263 if (tree->DATA1 == elpDouble2Long (nrd*ELPPRECISION))
1264 res = 1;
1265 }
1266 else {
1267 nrd = elpDouble2Long (nrd*ELPPRECISION);
1268 if ( nrd >= tree->DATA1 && nrd <= tree->DATA2 )
1269 res = 1;
1270 }
1271 }
1272 break ;
1273 case elpVBULKLevel : if(tree->DATA1 == elpDouble2Long (vbulk*SCALE_X))
1274 res = 1 ;
1275 else if(tree->DATA1 < ELPMINVBULK ) {
1276 if (MLO_IS_TRANSP(lotrs->TYPE) && (elpDouble2Long (vbulk*SCALE_X )) ==
1277 elpDouble2Long(elpGeneral[elpGVDDMAX]*SCALE_X))
1278 res = 1 ;
1279 if (MLO_IS_TRANSN(lotrs->TYPE) && (elpDouble2Long (vbulk*SCALE_X ) == 0))
1280 res = 1 ;
1281 }
1282 break ;
1283 case elpParamContextLevel : if(elp_is_same_paramcontext((chain_list *)tree->DATA1,longkey))
1284 res = 1 ;
1285 break ;
1286 case elpCaseLevel : if((tree->DATA1 == (long)transcase) ||
1287 //(tree->DATA1 == elpTYPICAL) ||
1288 (transcase == elpTYPICAL))
1289 res = 1 ;
1290 break ;
1291 case elpSCLevel : if ( sc < ELPMINVALUE )
1292 res = 1;
1293 else {
1294 if ( V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE < 0.0 ) {
1295 if (tree->DATA1 == elpDouble2Long (sc*ELPPRECISION2))
1296 res = 1;
1297 }
1298 else {
1299 sc = elpDouble2Long (sc*ELPPRECISION2);
1300 if ( sc >= tree->DATA1 && sc <= tree->DATA2 )
1301 res = 1;
1302 }
1303 }
1304 break ;
1305 case elpSCALevel : if ( sca < ELPMINVALUE )
1306 res = 1;
1307 else {
1308 if ( V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE < 0.0 ) {
1309 if (tree->DATA1 == elpDouble2Long (sca*ELPPRECISION2))
1310 res = 1;
1311 }
1312 else {
1313 sca = elpDouble2Long (sca*ELPPRECISION2);
1314 if ( sca >= tree->DATA1 && sca <= tree->DATA2 )
1315 res = 1;
1316 }
1317 }
1318 break ;
1319 case elpSCBLevel : if ( scb < ELPMINVALUE )
1320 res = 1;
1321 else {
1322 if ( V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE < 0.0 ) {
1323 if (tree->DATA1 == elpDouble2Long (scb*ELPPRECISION2))
1324 res = 1;
1325 }
1326 else {
1327 scb = elpDouble2Long (scb*ELPPRECISION2);
1328 if ( scb >= tree->DATA1 && scb <= tree->DATA2 )
1329 res = 1;
1330 }
1331 }
1332 break ;
1333 case elpSCCLevel : if ( scc < ELPMINVALUE )
1334 res = 1;
1335 else {
1336 if ( V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE < 0.0 ) {
1337 if (tree->DATA1 == elpDouble2Long (scc*ELPPRECISION2))
1338 res = 1;
1339 }
1340 else {
1341 scc = elpDouble2Long (scc*ELPPRECISION2);
1342 if ( scc >= tree->DATA1 && scc <= tree->DATA2 )
1343 res = 1;
1344 }
1345 }
1346 break ;
1347 }
1348
1349 return res ;
1350 }
1351
1352 /*****************************************************************************\
1353 function elpDupModel
1354 \*****************************************************************************/
1355 elpFCT elpmodel_list *elpDupModel (lotrs_list *lotrs,elpmodel_list *model,int type,double vdd,int transcase,
1356 double mulu0,double delvt0,double sa,double sb,double sd,double nf,double m,
1357 double nrs,double nrd,double vbulk,double sc,double sca,double scb,double scc)
1358 /*lotrs_list *lotrs;
1359 elpmodel_list *model;
1360 int type;
1361 double vdd;
1362 int transcase;
1363 double mulu0;
1364 double delvt0;
1365 double sa;
1366 double sb;
1367 double sd;
1368 double nf;
1369 double m;
1370 double nrs;
1371 double nrd;
1372 double vbulk;
1373 double sc;
1374 double sca;
1375 double scb;
1376 double scc;*/
1377 {
1378 elpmodel_list *nmodel ;
1379
1380 nmodel = elpAddModel(getlotrsmodel(lotrs),model->elpModelNameAlias,type,elpNOINDEX,
1381 lotrs->LENGTH,
1382 lotrs->LENGTH,
1383 lotrs->WIDTH,
1384 lotrs->WIDTH,
1385 model->elpShrink[elpDL],
1386 model->elpShrink[elpDW],
1387 model->elpShrink[elpLMLT],
1388 model->elpShrink[elpWMLT],
1389 vdd, transcase,
1390 model->elpTransTechno,
1391 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,model->longkey
1392 ) ;
1393 nmodel->elpTransModel = model->elpTransModel ;
1394 nmodel->elpTemp = model->elpTemp ;
1395 nmodel->elpModel[elpVT] = model->elpModel[elpVT] ;
1396 nmodel->elpModel[elpVT0] = model->elpModel[elpVT0] ;
1397 nmodel->elpModel[elpKT] = model->elpModel[elpKT] ;
1398 nmodel->elpModel[elpKS] = model->elpModel[elpKS] ;
1399 nmodel->elpModel[elpKR] = model->elpModel[elpKR] ;
1400 nmodel->elpModel[elpMULU0] = model->elpModel[elpMULU0] ;
1401 nmodel->elpModel[elpDELVT0] = model->elpModel[elpDELVT0] ;
1402 nmodel->elpModel[elpSA] = model->elpModel[elpSA] ;
1403 nmodel->elpModel[elpSB] = model->elpModel[elpSB] ;
1404 nmodel->elpModel[elpSD] = model->elpModel[elpSD] ;
1405 nmodel->elpModel[elpNF] = model->elpModel[elpNF] ;
1406 nmodel->elpModel[elpM] = model->elpModel[elpM] ;
1407 nmodel->elpModel[elpNRS] = model->elpModel[elpNRS] ;
1408 nmodel->elpModel[elpNRD] = model->elpModel[elpNRD] ;
1409 nmodel->elpModel[elpA] = model->elpModel[elpA] ;
1410 nmodel->elpModel[elpB] = model->elpModel[elpB] ;
1411 nmodel->elpModel[elpRT] = model->elpModel[elpRT] ;
1412 nmodel->elpModel[elpKRT] = model->elpModel[elpKRT] ;
1413 nmodel->elpModel[elpRS] = model->elpModel[elpRS] ;
1414 nmodel->elpModel[elpKRS] = model->elpModel[elpKRS] ;
1415 nmodel->elpModel[elpSC] = model->elpModel[elpSC] ;
1416 nmodel->elpModel[elpSCA] = model->elpModel[elpSCA] ;
1417 nmodel->elpModel[elpSCB] = model->elpModel[elpSCB] ;
1418 nmodel->elpModel[elpSCC] = model->elpModel[elpSCC] ;
1419 nmodel->elpVoltage[elpVDEG] = model->elpVoltage[elpVDEG] ;
1420 nmodel->elpVoltage[elpVTI] = model->elpVoltage[elpVTI] ;
1421 nmodel->elpCapa[elpCGS] = model->elpCapa[elpCGS] ;
1422 nmodel->elpCapa[elpCGS0] = model->elpCapa[elpCGS0] ;
1423 nmodel->elpCapa[elpCGSU] = model->elpCapa[elpCGSU] ;
1424 nmodel->elpCapa[elpCGSU0] = model->elpCapa[elpCGSU0] ;
1425 nmodel->elpCapa[elpCGSUMIN] = model->elpCapa[elpCGSUMIN] ;
1426 nmodel->elpCapa[elpCGSUMAX] = model->elpCapa[elpCGSUMAX] ;
1427 nmodel->elpCapa[elpCGSD] = model->elpCapa[elpCGSD] ;
1428 nmodel->elpCapa[elpCGSD0] = model->elpCapa[elpCGSD0] ;
1429 nmodel->elpCapa[elpCGSDMIN] = model->elpCapa[elpCGSDMIN] ;
1430 nmodel->elpCapa[elpCGSDMAX] = model->elpCapa[elpCGSDMAX] ;
1431 nmodel->elpCapa[elpCGP] = model->elpCapa[elpCGP] ;
1432 nmodel->elpCapa[elpCGPUMIN] = model->elpCapa[elpCGPUMIN] ;
1433 nmodel->elpCapa[elpCGPUMAX] = model->elpCapa[elpCGPUMAX] ;
1434 nmodel->elpCapa[elpCGPDMIN] = model->elpCapa[elpCGPDMIN] ;
1435 nmodel->elpCapa[elpCGPDMAX] = model->elpCapa[elpCGPDMAX] ;
1436 nmodel->elpCapa[elpCGPO] = model->elpCapa[elpCGPO];
1437 nmodel->elpCapa[elpCGPOC] = model->elpCapa[elpCGPOC];
1438 nmodel->elpCapa[elpCGD] = model->elpCapa[elpCGD] ;
1439 nmodel->elpCapa[elpCGD0] = model->elpCapa[elpCGD0] ;
1440 nmodel->elpCapa[elpCGD1] = model->elpCapa[elpCGD1] ;
1441 nmodel->elpCapa[elpCGD2] = model->elpCapa[elpCGD2] ;
1442 nmodel->elpCapa[elpCGDC] = model->elpCapa[elpCGDC] ;
1443 nmodel->elpCapa[elpCGDC0] = model->elpCapa[elpCGDC0] ;
1444 nmodel->elpCapa[elpCGDC1] = model->elpCapa[elpCGDC1] ;
1445 nmodel->elpCapa[elpCGDC2] = model->elpCapa[elpCGDC2] ;
1446 nmodel->elpCapa[elpCGSI] = model->elpCapa[elpCGSI] ;
1447 nmodel->elpCapa[elpCGSIC] = model->elpCapa[elpCGSIC] ;
1448 nmodel->elpCapa[elpCDS] = model->elpCapa[elpCDS] ;
1449 nmodel->elpCapa[elpCDSU] = model->elpCapa[elpCDSU] ;
1450 nmodel->elpCapa[elpCDSD] = model->elpCapa[elpCDSD] ;
1451 nmodel->elpCapa[elpCDP] = model->elpCapa[elpCDP] ;
1452 nmodel->elpCapa[elpCDPU] = model->elpCapa[elpCDPU] ;
1453 nmodel->elpCapa[elpCDPD] = model->elpCapa[elpCDPD] ;
1454 nmodel->elpCapa[elpCDW] = model->elpCapa[elpCDW] ;
1455 nmodel->elpCapa[elpCDWU] = model->elpCapa[elpCDWU] ;
1456 nmodel->elpCapa[elpCDWD] = model->elpCapa[elpCDWD] ;
1457 nmodel->elpCapa[elpCSS] = model->elpCapa[elpCSS] ;
1458 nmodel->elpCapa[elpCSSU] = model->elpCapa[elpCSSU] ;
1459 nmodel->elpCapa[elpCSSD] = model->elpCapa[elpCSSD] ;
1460 nmodel->elpCapa[elpCSP] = model->elpCapa[elpCSP] ;
1461 nmodel->elpCapa[elpCSPU] = model->elpCapa[elpCSPU] ;
1462 nmodel->elpCapa[elpCSPD] = model->elpCapa[elpCSPD] ;
1463 nmodel->elpCapa[elpCSW] = model->elpCapa[elpCSW] ;
1464 nmodel->elpCapa[elpCSWU] = model->elpCapa[elpCSWU] ;
1465 nmodel->elpCapa[elpCSWD] = model->elpCapa[elpCSWD] ;
1466 nmodel->elpRacc[elpRACCS] = model->elpRacc[elpRACCS] ;
1467 nmodel->elpRacc[elpRACCD] = model->elpRacc[elpRACCD] ;
1468
1469 return nmodel;
1470 }
1471
1472 /*****************************************************************************\
1473 function elpDelModel2Lotrs()
1474 \*****************************************************************************/
1475 elpFCT void elpDelModel2Lotrs (lotrs_list *lotrs)
1476 {
1477 if ( lotrs ) {
1478 if ( getptype (lotrs->USER, ELP_LOTRS_MODEL ) != NULL )
1479 lotrs->USER = delptype (lotrs->USER, ELP_LOTRS_MODEL);
1480 }
1481 }
1482
1483 /*****************************************************************************\
1484 function elpSetModel2Lotrs()
1485 \*****************************************************************************/
1486 elpFCT int elpSetModel2Lotrs (elpmodel_list *model, lotrs_list *lotrs)
1487 {
1488 int set=0;
1489
1490 if ( model && lotrs ) {
1491 if ( !getptype (lotrs->USER, ELP_LOTRS_MODEL ) ) {
1492 lotrs->USER = addptype (lotrs->USER, ELP_LOTRS_MODEL, model);
1493 set=1;
1494 }
1495 }
1496 return set;
1497 }
1498
1499 /*****************************************************************************\
1500 function elpGetModelFromLotrs()
1501 \*****************************************************************************/
1502 elpFCT elpmodel_list *elpGetModelFromLotrs (lotrs_list *lotrs)
1503 {
1504 elpmodel_list *model=NULL;
1505 ptype_list *ptype;
1506
1507 if ( lotrs ) {
1508 if ( (ptype = getptype (lotrs->USER, ELP_LOTRS_MODEL )) )
1509 model = (elpmodel_list*)ptype->DATA;
1510 }
1511 return model;
1512 }
1513
1514 /*****************************************************************************/
1515 /* function elpGetModelList() */
1516 /*****************************************************************************/
1517 elpFCT elpmodel_list *elpGetModelList (lotrs_list *lotrs,double vdd,int transcase,
1518 double mulu0,double delvt0,double sa,double sb,double sd,double nf,
1519 double m,double nrs,double nrd,double vbulk,double sc,double sca,double scb,double scc)
1520 /*lotrs_list *lotrs ;
1521 double vdd ;
1522 int transcase ;
1523 double mulu0;
1524 double delvt0;
1525 double sa;
1526 double sb;
1527 double sd;
1528 double nf;
1529 double m;
1530 double nrs;
1531 double nrd;
1532 double vbulk;
1533 double sc;
1534 double sca;
1535 double scb;
1536 double scc;*/
1537 {
1538 elpmodel_list *model = NULL ;
1539 char *modelname;
1540 int type = (MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS) ;
1541
1542 modelname = getlotrsmodel (lotrs);
1543 // first : try to get the same model name...
1544 for(model = ELP_MODEL_LIST ; model != NULL ; model = model->NEXT)
1545 {
1546 if((modelname == model->elpModelName) &&
1547 (elpDouble2Long(vdd*SCALE_X ) ==
1548 elpDouble2Long(model->elpVoltage[elpVDDMAX]*SCALE_X ) ) &&
1549 (elp_is_valcomprise (elpDouble2Long(mulu0*ELPPRECISION) ,
1550 elpDouble2Long(model->elpModel[elpMULU0]*ELPPRECISION),V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE )) &&
1551 (elp_is_valcomprise(elpDouble2Long(delvt0*ELPPRECISION) ,
1552 elpDouble2Long(model->elpModel[elpDELVT0]*ELPPRECISION),V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) ) &&
1553 (elp_is_valcomprise(elpDouble2Long(sa*ELPPRECISION2) ,
1554 elpDouble2Long(model->elpModel[elpSA]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) ) &&
1555 (elp_is_valcomprise(elpDouble2Long(sb*ELPPRECISION2) ,
1556 elpDouble2Long(model->elpModel[elpSB]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) ) &&
1557 (elp_is_valcomprise(elpDouble2Long(sd*ELPPRECISION2) ,
1558 elpDouble2Long(model->elpModel[elpSD]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) ) &&
1559 (elp_is_valcomprise(elpDouble2Long(nf) ,
1560 elpDouble2Long(model->elpModel[elpNF]),ELP_NF_MARGIN) ) &&
1561 (elp_is_valcomprise(elpDouble2Long(m) ,
1562 elpDouble2Long(model->elpModel[elpM]),ELP_M_MARGIN) ) &&
1563 (elp_is_valcomprise(elpDouble2Long(nrs*ELPPRECISION) ,
1564 elpDouble2Long(model->elpModel[elpNRS]*ELPPRECISION),ELP_NRS_MARGIN) ) &&
1565 (elp_is_valcomprise(elpDouble2Long(nrd*ELPPRECISION) ,
1566 elpDouble2Long(model->elpModel[elpNRD]*ELPPRECISION),ELP_NRD_MARGIN) ) &&
1567 (elp_is_valcomprise(elpDouble2Long(sc*ELPPRECISION2) ,
1568 elpDouble2Long(model->elpModel[elpSC]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) ) &&
1569 (elp_is_valcomprise(elpDouble2Long(sca*ELPPRECISION2) ,
1570 elpDouble2Long(model->elpModel[elpSCA]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) ) &&
1571 (elp_is_valcomprise(elpDouble2Long(scb*ELPPRECISION2) ,
1572 elpDouble2Long(model->elpModel[elpSCB]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) ) &&
1573 (elp_is_valcomprise(elpDouble2Long(scc*ELPPRECISION2) ,
1574 elpDouble2Long(model->elpModel[elpSCC]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) ) &&
1575 (elpDouble2Long(vbulk*SCALE_X ) ==
1576 elpDouble2Long(model->elpVoltage[elpVBULK]*SCALE_X ) ) &&
1577 ((transcase == model->elpTransCase) || (model->elpTransCase == elpTYPICAL)))
1578 {
1579 // if (!mbk_isdioden(getlotrsmodel(lotrs)) && !mbk_isdiodep(getlotrsmodel(lotrs)))
1580 {
1581 if(lotrs->TRNAME != NULL)
1582 avt_errmsg(ELP_ERRMSG, "007", AVT_ERROR, lotrs->TRNAME, model->elpModelName);
1583 // elpError(1007,lotrs->TRNAME,model->elpModelName) ;
1584 else
1585 avt_errmsg(ELP_ERRMSG, "007", AVT_ERROR, modelname, model->elpModelName);
1586 // elpError(1007,modelname,model->elpModelName) ;
1587 }
1588 elpDupModel (lotrs,model,type,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc);
1589 break ;
1590 }
1591 }
1592 if ( !model )
1593 for(model = ELP_MODEL_LIST ; model != NULL ; model = model->NEXT)
1594 {
1595 if((type == model->elpTransType) &&
1596 (elpDouble2Long(vdd*SCALE_X ) ==
1597 elpDouble2Long(model->elpVoltage[elpVDDMAX]*SCALE_X ) ) &&
1598 (elp_is_valcomprise (elpDouble2Long(mulu0*ELPPRECISION) ,
1599 elpDouble2Long(model->elpModel[elpMULU0]*ELPPRECISION),V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE )) &&
1600 (elp_is_valcomprise(elpDouble2Long(delvt0*ELPPRECISION) ,
1601 elpDouble2Long(model->elpModel[elpDELVT0]*ELPPRECISION),V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE) ) &&
1602 (elp_is_valcomprise(elpDouble2Long(sa*ELPPRECISION2) ,
1603 elpDouble2Long(model->elpModel[elpSA]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE) ) &&
1604 (elp_is_valcomprise(elpDouble2Long(sb*ELPPRECISION2) ,
1605 elpDouble2Long(model->elpModel[elpSB]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE) ) &&
1606 (elp_is_valcomprise(elpDouble2Long(sd*ELPPRECISION2) ,
1607 elpDouble2Long(model->elpModel[elpSD]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE) ) &&
1608 (elp_is_valcomprise(elpDouble2Long(sc*ELPPRECISION2) ,
1609 elpDouble2Long(model->elpModel[elpSC]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SC_MARGIN].VALUE) ) &&
1610 (elp_is_valcomprise(elpDouble2Long(sca*ELPPRECISION2) ,
1611 elpDouble2Long(model->elpModel[elpSCA]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCA_MARGIN].VALUE) ) &&
1612 (elp_is_valcomprise(elpDouble2Long(scb*ELPPRECISION2) ,
1613 elpDouble2Long(model->elpModel[elpSCB]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCB_MARGIN].VALUE) ) &&
1614 (elp_is_valcomprise(elpDouble2Long(scc*ELPPRECISION2) ,
1615 elpDouble2Long(model->elpModel[elpSCC]*ELPPRECISION2),V_FLOAT_TAB[__ELP_SCC_MARGIN].VALUE) ) &&
1616 (elp_is_valcomprise(elpDouble2Long(nf) ,
1617 elpDouble2Long(model->elpModel[elpNF]),ELP_NF_MARGIN) ) &&
1618 (elp_is_valcomprise(elpDouble2Long(m) ,
1619 elpDouble2Long(model->elpModel[elpM]),ELP_M_MARGIN) ) &&
1620 (elp_is_valcomprise(elpDouble2Long(nrs*ELPPRECISION) ,
1621 elpDouble2Long(model->elpModel[elpNRS]*ELPPRECISION),ELP_NRS_MARGIN) ) &&
1622 (elp_is_valcomprise(elpDouble2Long(nrd*ELPPRECISION) ,
1623 elpDouble2Long(model->elpModel[elpNRD]*ELPPRECISION),ELP_NRD_MARGIN) ) &&
1624 (elpDouble2Long(vbulk*SCALE_X ) ==
1625 elpDouble2Long(model->elpVoltage[elpVBULK]*SCALE_X ) ) &&
1626 ((transcase == model->elpTransCase) || (model->elpTransCase == elpTYPICAL)))
1627 {
1628 // if (!mbk_isdioden(getlotrsmodel(lotrs)) && !mbk_isdiodep(getlotrsmodel(lotrs)))
1629 {
1630 if(lotrs->TRNAME != NULL)
1631 avt_errmsg(ELP_ERRMSG, "007", AVT_ERROR, lotrs->TRNAME, model->elpModelName);
1632 //elpError(1007,lotrs->TRNAME,model->elpModelName) ;
1633 else
1634 avt_errmsg(ELP_ERRMSG, "007", AVT_ERROR, modelname, model->elpModelName);
1635 //elpError(1007,modelname,model->elpModelName) ;
1636 }
1637 elpDupModel (lotrs,model,type,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc);
1638 break ;
1639 }
1640 }
1641
1642 elpSetModel2Lotrs ( model, lotrs );
1643
1644 return model ;
1645 }
1646
1647 /*****************************************************************************/
1648 /* function elpGetModelTree() */
1649 /*****************************************************************************/
1650 static elpFCT elpmodel_list *elpGetModelTree_int(head,lotrs,vdd,transcase,
1651 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level,longkey)
1652 elptree_list *head ;
1653 lotrs_list *lotrs ;
1654 double vdd ;
1655 int transcase ;
1656 double mulu0;
1657 double delvt0;
1658 double sa;
1659 double sb;
1660 double sd;
1661 double nf;
1662 double m;
1663 double nrs;
1664 double nrd;
1665 double vbulk;
1666 double sc;
1667 double sca;
1668 double scb;
1669 double scc;
1670 int level ;
1671 chain_list *longkey;
1672 {
1673 elptree_list *tree ;
1674 elpmodel_list *resmodel ;
1675 int ret;
1676
1677 for(tree = head ; tree != NULL ; tree = tree->NEXT)
1678 {
1679
1680 if((ret=elpCmpTreeLotrs(tree,lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level,longkey)) == 2)
1681 {
1682 tree = NULL ;
1683 break ;
1684 }
1685 if(ret == 1)
1686 {
1687 if(level != elpCaseLevel)
1688 {
1689 resmodel = elpGetModelTree_int(tree->DOWN,lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level+1,longkey) ;
1690 if((resmodel != NULL) || (level == elpNameLevel))
1691 return(resmodel) ;
1692 }
1693 else
1694 return(tree->DOWN) ;
1695 }
1696 }
1697 return(NULL) ;
1698 }
1699
1700 elpFCT elpmodel_list *elpGetModelTree(head,lotrs,vdd,transcase,
1701 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level)
1702 elptree_list *head ;
1703 lotrs_list *lotrs ;
1704 double vdd ;
1705 int transcase ;
1706 double mulu0;
1707 double delvt0;
1708 double sa;
1709 double sb;
1710 double sd;
1711 double nf;
1712 double m;
1713 double nrs;
1714 double nrd;
1715 double vbulk;
1716 double sc ;
1717 double sca ;
1718 double scb ;
1719 double scc ;
1720 int level ;
1721 {
1722 chain_list *longkey;
1723 elpmodel_list *em;
1724 elp_get_key(lotrs, &longkey);
1725 em=elpGetModelTree_int(head,lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,level,longkey);
1726 return em;
1727 }
1728
1729
1730 void fill_elp_lotrs_param( elp_lotrs_param *pt,
1731 double mulu0,
1732 double delvt0,
1733 double sa,
1734 double sb,
1735 double sd,
1736 double nf,
1737 double m,
1738 double nrs,
1739 double nrd,
1740 double vbulk,
1741 double sc,
1742 double sca,
1743 double scb,
1744 double scc,
1745 lotrs_list *lt
1746 )
1747 {
1748 chain_list *longkey;
1749 int i;
1750 pt->PARAM[elpMULU0] = mulu0;
1751 pt->PARAM[elpDELVT0] = delvt0;
1752 pt->PARAM[elpSA] = sa;
1753 pt->PARAM[elpSB] = sb;
1754 pt->PARAM[elpSD] = sd;
1755 pt->PARAM[elpNF] = nf;
1756 pt->PARAM[elpM] = m;
1757 pt->PARAM[elpNRS] = nrs;
1758 pt->PARAM[elpNRD] = nrd;
1759 pt->PARAM[elpSC] = sc;
1760 pt->PARAM[elpSCA] = sca;
1761 pt->PARAM[elpSCB] = scb;
1762 pt->PARAM[elpSCC] = scc;
1763 pt->VBULK = vbulk;
1764 pt->ISVBSSET = 0;
1765 elp_get_key(lt, &longkey);
1766 pt->longkey=dupchainlst(longkey);
1767 for (i = 0 ; i < __MCC_LAST_SAVED ; i++)
1768 pt->MCC_SAVED[i] = ELPINITVALUE;
1769
1770 }
1771
1772 /*****************************************************************************/
1773 /* function elpSearchOrGenModel */
1774 /*****************************************************************************/
1775 elpFCT elpmodel_list *elpSearchOrGenModel (lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc)
1776 lotrs_list *lotrs ;
1777 double vdd ;
1778 int transcase ;
1779 double mulu0 ;
1780 double delvt0 ;
1781 double sa;
1782 double sb;
1783 double sd;
1784 double nf;
1785 double m;
1786 double nrs;
1787 double nrd;
1788 double vbulk;
1789 double sc;
1790 double sca;
1791 double scb;
1792 double scc;
1793 {
1794 elpmodel_list *model = NULL;
1795 int lotrstype ;
1796 elp_lotrs_param ptlotrs_param;
1797 #ifdef DELAY_DEBUG_STAT
1798 static int cnt=0;
1799 #endif
1800
1801 model = elpGetModelTree(ELP_HEAD_TREE,lotrs,vdd,transcase,
1802 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,elpNameLevel) ;
1803
1804 if((model == NULL) && (ELP_LOAD_FILE_TYPE || ELP_GENPARAM ))
1805 {
1806 lotrstype = MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS ;
1807
1808 fill_elp_lotrs_param( &ptlotrs_param, mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc, lotrs );
1809
1810 elpGenParam(getlotrsmodel(lotrs), lotrstype,(double)lotrs->LENGTH/(double)(SCALE_X),
1811 (double)lotrs->WIDTH/(double)(SCALE_X),vdd,lotrs,transcase,&ptlotrs_param) ;
1812
1813 freechain(ptlotrs_param.longkey);
1814 model = elpGetModelTree (ELP_HEAD_TREE,lotrs,vdd,transcase,
1815 mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc,elpNameLevel) ;
1816 #ifdef DELAY_DEBUG_STAT
1817 cnt++;
1818 if ((cnt % 100)==0)
1819 fprintf(stdout,"\relp: %05d\r", cnt); fflush(stdout);
1820 #endif
1821 if(model == NULL) {
1822 if((model = elpGetModelList(lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc)) == NULL)
1823 {
1824 if(lotrs->TRNAME != NULL)
1825 {
1826 avt_errmsg(ELP_ERRMSG, "009", AVT_ERROR, lotrs->TRNAME);
1827 //elpError(1009,lotrs->TRNAME) ;
1828 EXIT(1);
1829 }
1830 else
1831 {
1832 avt_errmsg(ELP_ERRMSG, "009", AVT_ERROR, getlotrsmodel(lotrs));
1833 //elpError(1009,getlotrsmodel(lotrs)) ;
1834 EXIT(1);
1835 }
1836 }
1837 }
1838 }
1839 else if(model == NULL)
1840 {
1841 if((model = elpGetModelList(lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc)) == NULL)
1842 {
1843 if(lotrs->TRNAME != NULL)
1844 {
1845 avt_errmsg(ELP_ERRMSG, "009", AVT_ERROR, lotrs->TRNAME);
1846 //elpError(1009,lotrs->TRNAME) ;
1847 EXIT(1);
1848 }
1849 else
1850 {
1851 avt_errmsg(ELP_ERRMSG, "009", AVT_ERROR, getlotrsmodel(lotrs));
1852 //elpError(1009,getlotrsmodel(lotrs)) ;
1853 EXIT(1);
1854 }
1855 }
1856 }
1857
1858 return model;
1859 }
1860
1861
1862 /*****************************************************************************/
1863 /* function elpGetModelWithLotrsParams () */
1864 /*****************************************************************************/
1865 elpFCT elpmodel_list *elpGetModelWithLotrsParams(lotrs,lotrsparams,vdd,transcase)
1866 lotrs_list *lotrs ;
1867 double vdd ;
1868 int transcase ;
1869 elp_lotrs_param *lotrsparams;
1870 {
1871 elpmodel_list *model ;
1872 double mulu0,delvt0,sa,sb,sd,nf,vbulk,sc,sca,scb,scc;
1873 double m,nrs,nrd;
1874
1875 mulu0 = lotrsparams->PARAM[elpMULU0];
1876 delvt0 = lotrsparams->PARAM[elpDELVT0];
1877 sa = lotrsparams->PARAM[elpSA];
1878 sb = lotrsparams->PARAM[elpSB];
1879 sd = lotrsparams->PARAM[elpSD];
1880 sc = lotrsparams->PARAM[elpSC];
1881 sca = lotrsparams->PARAM[elpSCA];
1882 scb = lotrsparams->PARAM[elpSCB];
1883 scc = lotrsparams->PARAM[elpSCC];
1884 nf = lotrsparams->PARAM[elpNF];
1885 m = lotrsparams->PARAM[elpM];
1886 nrs = lotrsparams->PARAM[elpNRS];
1887 nrd = lotrsparams->PARAM[elpNRD];
1888 vbulk = lotrsparams->VBULK;
1889
1890 model = elpSearchOrGenModel (lotrs,vdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc);
1891
1892 return model ;
1893 }
1894
1895 /*****************************************************************************/
1896 /* function elpGetVdd4UnusedLotrs() */
1897 /*****************************************************************************/
1898 elpFCT double elpGetVdd4UnusedLotrs(lotrs_list *lotrs)
1899 {
1900 double vdd=-1.0;
1901 float vbulk;
1902
1903 if (MLO_IS_TRANSP(lotrs->TYPE) ) {
1904 if ( lotrs->BULK && lotrs->BULK->SIG &&
1905 getlosigalim(lotrs->BULK->SIG, &vbulk) )
1906 vdd = vbulk;
1907 }
1908 if ( vdd <= 0.0 )
1909 vdd = V_FLOAT_TAB[__SIM_POWER_SUPPLY].VALUE;
1910
1911 return vdd;
1912 }
1913
1914 /*****************************************************************************/
1915 /* function elpGetModel() */
1916 /*****************************************************************************/
1917 elpFCT elpmodel_list *elpGetModel(lotrs,vdd,transcase)
1918 lotrs_list *lotrs ;
1919 double vdd ;
1920 int transcase ;
1921 {
1922 elpmodel_list *model ;
1923 double mulu0,delvt0,vbulk,sa,sb,sd,nf,sc,sca,scb,scc;
1924 double m,nrs,nrd;
1925 char *trsmodel;
1926 double newvdd;
1927 float alim;
1928
1929 if ( (model = elpGetModelFromLotrs (lotrs)) )
1930 return model;
1931
1932 trsmodel = getlotrsmodel(lotrs);
1933 /*
1934 if (mbk_isdioden(trsmodel) || mbk_isdiodep(trsmodel))
1935 // don t try to get diode model, get only the equivalent transistor from type of diode
1936 return elpGetModelType(lotrs->TYPE);
1937 */
1938 elp_lotrs_param_get (lotrs,&mulu0,&delvt0,&sa,&sb,&sd,&nf,&m,&nrs,&nrd,&vbulk,&sc,&sca,&scb,&scc);
1939
1940 if ( transcase != elpTYPICAL ) {
1941 newvdd = elpGetVddFromCorner (lotrs, transcase);
1942 if (MLO_IS_TRANSP(lotrs->TYPE) )
1943 vbulk = newvdd; // because bulk voltage was also updated to newvdd
1944 }
1945 else
1946 newvdd = vdd;
1947
1948 if ( getptype (lotrs->USER, CNS_UNUSED) && !cns_getlotrsalim(lotrs, 'M', &alim)) {
1949 newvdd = elpGetVdd4UnusedLotrs(lotrs);
1950 if (MLO_IS_TRANSP(lotrs->TYPE) )
1951 vbulk = newvdd; // to keep vbs=0.0
1952 else
1953 vbulk = 0.0;
1954 }
1955 else if (MLO_IS_TRANSP(lotrs->TYPE) ) {
1956 if ( newvdd > vbulk && vbulk > 0 )
1957 newvdd = vbulk;
1958 }
1959
1960 model = elpSearchOrGenModel (lotrs,newvdd,transcase,mulu0,delvt0,sa,sb,sd,nf,m,nrs,nrd,vbulk,sc,sca,scb,scc);
1961
1962 elpSetModel2Lotrs (model, lotrs);
1963
1964 return model ;
1965 }
1966
1967 /*****************************************************************************/
1968 /* function elpGetParamModel() */
1969 /*****************************************************************************/
1970 elpFCT elpmodel_list *elpGetParamModel(name,l,w,type,vdd,transcase,params)
1971 char *name ;
1972 double l ;
1973 double w ;
1974 char type ;
1975 double vdd ;
1976 int transcase ;
1977 elp_lotrs_param *params;
1978 {
1979 lotrs_list lotrs ;
1980 elpmodel_list *em;
1981
1982 lotrs.TRNAME = NULL;
1983 lotrs.LENGTH = elpDouble2Long (l * SCALE_X ) ;
1984 lotrs.WIDTH = elpDouble2Long (w * SCALE_X ) ;
1985 lotrs.TYPE = type ;
1986 lotrs.USER = NULL;
1987 lotrs.BULK = NULL;
1988 lotrs.GRID = NULL;
1989 lotrs.SOURCE = NULL;
1990 lotrs.DRAIN= NULL;
1991 addlotrsmodel(&lotrs,name) ;
1992
1993 if (params->SUBCKTNAME!=NULL)
1994 lotrs.USER =addptype(lotrs.USER, TRANS_FIGURE, params->SUBCKTNAME);
1995 em=elpGetModelWithLotrsParams(&lotrs,params,vdd,transcase);
1996 freeptype(lotrs.USER);
1997 return em ;
1998 }
1999
2000 /*****************************************************************************/
2001 /* function elpGetModelType() */
2002 /*****************************************************************************/
2003 elpFCT elpmodel_list *elpGetModelType(typet)
2004 char typet ;
2005 {
2006 elpmodel_list *model ;
2007 int type = (MLO_IS_TRANSN(typet) ? elpNMOS : elpPMOS) ;
2008
2009 for(model = ELP_MODEL_LIST ; model != NULL ; model = model->NEXT)
2010 {
2011 if(type == model->elpTransType)
2012 break ;
2013 }
2014 if((model == NULL) && (ELP_LOAD_FILE_TYPE || ELP_GENPARAM ))
2015 {
2016 elpGenParam(NULL,type,elpBADLW,elpBADLW,ELPMINVOLTAGE,NULL,elpTYPICAL,NULL) ;
2017 model = ELP_MODEL_LIST ;
2018 }
2019
2020 return(model) ;
2021 }
2022
2023 /*****************************************************************************/
2024 /* function elpGetModelIndex() */
2025 /*****************************************************************************/
2026 elpFCT elpmodel_list *elpGetModelIndex(index)
2027 int index ;
2028 {
2029 elpmodel_list *model ;
2030
2031 for(model = ELP_MODEL_LIST ; model != NULL ; model = model->NEXT)
2032 {
2033 if(index == model->elpModelIndex)
2034 break ;
2035 }
2036
2037 return(model) ;
2038 }
2039
2040 /*****************************************************************************/
2041 /* function elpenv() */
2042 /* recuperation du nom du fichier elp a partir de la variable: */
2043 /* ELP_TECHNO_NAME. */
2044 /* */
2045 /* Parametres en entree: */
2046 /* -------------------- */
2047 /* Aucun! */
2048 /* */
2049 /* Parametre en sortie: */
2050 /* ------------------- */
2051 /* Aucun! */
2052 /*****************************************************************************/
2053 elpFCT int elpenv()
2054 {
2055 char *str ;
2056 float val;
2057 static int doneonce=0;
2058
2059 if (!doneonce)
2060 {
2061 elpTechnoName[0] = '\0';
2062 elpGenTechnoFile[0] = '\0';
2063 if (elpoldtechnofilename) mbkfree(elpoldtechnofilename);
2064 elpoldtechnofilename = NULL;
2065 elpres_load = 1;
2066 doneonce=1;
2067 }
2068
2069 str = V_STR_TAB[__ELP_GEN_TECHNO_NAME].VALUE ;
2070 if(str != NULL)
2071 strcpy(elpGenTechnoFile,str) ;
2072 else
2073 strcpy(elpGenTechnoFile,"techno.elp") ;
2074
2075 str = V_STR_TAB[__ELP_LOAD_FILE].VALUE ;
2076
2077 /*
2078 if ( (str = V_INT_TAB[__ELP_CAPA_LEVEL].VALUE) ) {
2079 level = atoi ( str );
2080 switch ( level ) {
2081 case 0 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL0;
2082 break;
2083 case 1 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2084 break;
2085 case 2 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL2;
2086 break;
2087 default: ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2088 break;
2089 }
2090 }
2091 else
2092 ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2093 */
2094
2095 /*
2096 str = V_BOOL_TAB[__ELP_DRV_FILE].VALUE ;
2097 if((str != NULL) && (strcmp(str,"yes") == 0))
2098 {
2099 ELP_DRV_FILE = 1 ;
2100 }
2101 else
2102 {
2103 ELP_DRV_FILE = 0 ;
2104 }
2105 */
2106 str = V_STR_TAB[__ELP_TECHNO_NAME].VALUE ;
2107 if(str != NULL)
2108 {
2109 strcpy(elpTechnoFile,str) ;
2110 str = V_STR_TAB[__ELP_LOAD_FILE].VALUE ;
2111 if((str != NULL) && (strcmp(str,"yes") != 0))
2112 {
2113 if( !strcmp(str,"no") )
2114 {
2115 strcpy(elpTechnoFile,elpGenTechnoFile) ;
2116 ELP_LOAD_FILE_TYPE = ELP_DONTLOAD_FILE ;
2117 }
2118 else if( !strcmp(str,"default") )
2119 {
2120 strcpy(elpTechnoFile,elpGenTechnoFile) ;
2121 ELP_LOAD_FILE_TYPE = ELP_DEFAULTLOAD_FILE ;
2122 }
2123 else
2124 {
2125 ELP_LOAD_FILE_TYPE = ELP_LOADELP_FILE ;
2126 }
2127 }
2128 else
2129 {
2130 ELP_LOAD_FILE_TYPE = ELP_LOADELP_FILE ;
2131 }
2132 }
2133 else
2134 {
2135 str = getenv("AVT_TOOLS_DIR") ;
2136 if(str != NULL)
2137 {
2138 sprintf(elpTechnoFile,"%s%s",str,TECHNOLOGY) ;
2139 }
2140 else if((str = getenv("AVERTEC_TOP")) != NULL)
2141 {
2142 sprintf(elpTechnoFile,"%s%s",str,TECHNOLOGY) ;
2143 }
2144 else
2145 {
2146 sprintf(elpTechnoFile,"AvtTools%s",TECHNOLOGY) ;
2147 }
2148 str = V_STR_TAB[__ELP_LOAD_FILE].VALUE ;
2149 if((str != NULL) && (strcmp(str,"yes") != 0))
2150 {
2151 if( !strcmp(str,"no") )
2152 {
2153 strcpy(elpTechnoFile,elpGenTechnoFile) ;
2154 ELP_LOAD_FILE_TYPE = ELP_DONTLOAD_FILE ;
2155 }
2156 else if( !strcmp(str,"default") )
2157 {
2158 strcpy(elpTechnoFile,elpGenTechnoFile) ;
2159 ELP_LOAD_FILE_TYPE = ELP_DEFAULTLOAD_FILE ;
2160 }
2161 else
2162 {
2163 ELP_LOAD_FILE_TYPE = ELP_LOADELP_FILE ;
2164 }
2165 }
2166 else
2167 {
2168 strcpy(elpTechnoFile,elpGenTechnoFile) ;
2169 ELP_LOAD_FILE_TYPE = ELP_DONTLOAD_FILE ;
2170 }
2171 }
2172 ELP_GENPARAM = V_BOOL_TAB[__ELP_GEN_PARAM].VALUE ;
2173 ELP_CAPA_DIFF = V_BOOL_TAB[__ELP_DEDUCE_DIFFSIZE].VALUE ;
2174 /*
2175 str = V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE ;
2176 if ( str )
2177 {
2178 val = atof (str);
2179 if ( val >= 0.0 && val <= 1.0)
2180 ELP_MULU0_MARGIN = val;
2181 }
2182 STR = V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE ;
2183 if ( str )
2184 {
2185 val = atof (str);
2186 if ( val >= 0.0 && val <= 1.0)
2187 ELP_DELVT0_MARGIN = val;
2188 }
2189 str = V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE ;
2190 if ( str )
2191 {
2192 val = atof (str);
2193 if ( val >= 0.0 && val <= 1.0)
2194 ELP_SA_MARGIN = val;
2195 }
2196 str = V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE ;
2197 if ( str )
2198 {
2199 val = atof (str);
2200 if ( val >= 0.0 && val <= 1.0)
2201 ELP_SB_MARGIN = val;
2202 }
2203 str = V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE ;
2204 if ( str )
2205 {
2206 val = atof (str);
2207 if ( val >= 0.0 && val <= 1.0)
2208 ELP_SD_MARGIN = val;
2209 }
2210 */
2211 V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE = -1.0;
2212 V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE = -1.0;
2213 V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE = -1.0;
2214 V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE = -1.0;
2215 V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE = -1.0;
2216
2217 str = getenv("ELP_NF_MARGIN") ;
2218 if ( str )
2219 {
2220 val = atof (str);
2221 if ( val >= 0.0 && val <= 1.0)
2222 ELP_NF_MARGIN = val;
2223 }
2224
2225 return 1 ;
2226 }
2227
2228 /*****************************************************************************/
2229 /* function VerifModel() */
2230 /* */
2231 /* Parametres en entree: */
2232 /* -------------------- */
2233 /* model de transistor */
2234 /* */
2235 /* Parametre en sortie: */
2236 /* ------------------- */
2237 /* verifie le model */
2238 /*****************************************************************************/
2239 elpFCT int elpVerifModel(model)
2240 elpmodel_list *model ;
2241 {
2242 int i ;
2243
2244 for( i=0 ; i<elpSHRINKNUM ; i++ )
2245 if( !finite(model->elpShrink[i]) ) //elpError(1004,elpTechnoFile) ;
2246 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2247 for( i=0 ; i<elpMODELNUM ; i++ )
2248 if( !finite(model->elpModel[i]) ) //elpError(1004,elpTechnoFile) ;
2249 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2250 for( i=0 ; i<elpVOLTNUM ; i++ )
2251 if( !finite(model->elpVoltage[i]) ) //elpError(1004,elpTechnoFile) ;
2252 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2253 for( i=0 ; i<elpCAPANUM ; i++ )
2254 if( !finite(model->elpCapa[i]) ) //elpError(1004,elpTechnoFile) ;
2255 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2256 for( i=0 ; i<elpRSSNUM ; i++ )
2257 if( !finite(model->elpRss[i]) ) //elpError(1004,elpTechnoFile) ;
2258 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2259 for( i=0 ; i<elpRACCNUM ; i++ )
2260 if( !finite(model->elpRacc[i]) ) //elpError(1004,elpTechnoFile) ;
2261 avt_errmsg(ELP_ERRMSG, "004", AVT_ERROR, elpTechnoFile);
2262
2263 if(
2264 ((model->elpTransModel == elpMOS) && (
2265 (model->elpModel[elpVT] == 0.0 ) ||
2266 (model->elpModel[elpVT0] == 0.0 ) ||
2267 (model->elpModel[elpA] == 0.0 ) ||
2268 (model->elpModel[elpB] == 0.0 ) ||
2269 (model->elpModel[elpRT] == 0.0 ) ||
2270 ((model->elpVoltage[elpVDDMAX] < 0.0 )&&(elpGeneral[elpGVDDMAX] < 0.0)) ||
2271 (model->elpCapa[elpCGS] == 0.0 ) ||
2272 (model->elpCapa[elpCGSU] == 0.0 ) ||
2273 (model->elpCapa[elpCGSUMIN] == 0.0 ) ||
2274 (model->elpCapa[elpCGSUMAX] == 0.0 ) ||
2275 (model->elpCapa[elpCGSD] == 0.0 ) ||
2276 (model->elpCapa[elpCGSDMIN] == 0.0 ) ||
2277 (model->elpCapa[elpCGSDMAX] == 0.0 ) ||
2278 (model->elpCapa[elpCGP] == 0.0 ) ||
2279 (model->elpCapa[elpCGPUMIN] == 0.0 ) ||
2280 (model->elpCapa[elpCGPUMAX] == 0.0 ) ||
2281 (model->elpCapa[elpCGPDMIN] == 0.0 ) ||
2282 (model->elpCapa[elpCGPDMAX] == 0.0 ) ||
2283 (elpEsimName[0] == '\0') ||
2284 (model->elpTransTechno == 0.0 ) ||
2285 ((model->elpTemp < ELPMINTEMP ) && (elpGeneral[elpTEMP] < ELPMINTEMP))))
2286 )
2287 if( (model->elpTransModel == elpMOS)) {
2288 if (model->elpModel[elpVT] == 0.0 ) {
2289 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "VT", model->elpModel[elpVT]);
2290 return 1004 ;
2291 }
2292 if (model->elpModel[elpVT0] == 0.0 ) {
2293 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "VT0", model->elpModel[elpVT0]);
2294 return 1004 ;
2295 }
2296 if (model->elpModel[elpA] == 0.0 ) {
2297 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "A", model->elpModel[elpA]);
2298 return 1004 ;
2299 }
2300 if (model->elpModel[elpB] == 0.0 ) {
2301 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "B", model->elpModel[elpB]);
2302 return 1004 ;
2303 }
2304 if (model->elpModel[elpRT] == 0.0 ) {
2305 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "RT", model->elpModel[elpRT]);
2306 return 1004 ;
2307 }
2308 if ((model->elpVoltage[elpVDDMAX] < 0.0 ) && (elpGeneral[elpGVDDMAX] < 0.0)) {
2309 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "VDDMAX", model->elpModel[elpVDDMAX]);
2310 return 1004 ;
2311 }
2312 if (model->elpCapa[elpCGS] == 0.0 ) {
2313 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGS", model->elpModel[elpCGS]);
2314 return 1004 ;
2315 }
2316 if ((model->elpCapa[elpCGSUMIN] == 0.0 ) &&
2317 (model->elpCapa[elpCGSUMAX] == 0.0 ) &&
2318 (model->elpCapa[elpCGSDMIN] == 0.0 ) &&
2319 (model->elpCapa[elpCGSDMAX] == 0.0 )) {
2320 model->elpCapa[elpCGSUMIN] = model->elpCapa[elpCGSU];
2321 model->elpCapa[elpCGSUMAX] = model->elpCapa[elpCGSU];
2322 model->elpCapa[elpCGSDMIN] = model->elpCapa[elpCGSD];
2323 model->elpCapa[elpCGSDMAX] = model->elpCapa[elpCGSD];
2324 }
2325 if (model->elpCapa[elpCGSU] == 0.0 ) {
2326 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSU", model->elpModel[elpCGSU]);
2327 return 1004 ;
2328 }
2329 if (model->elpCapa[elpCGSUMIN] == 0.0 ) {
2330 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSUMIN", model->elpModel[elpCGSUMIN]);
2331 return 1004 ;
2332 }
2333 if (model->elpCapa[elpCGSUMAX] == 0.0 ) {
2334 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSUMAX", model->elpModel[elpCGSUMAX]);
2335 return 1004 ;
2336 }
2337 if (model->elpCapa[elpCGSDMIN] == 0.0 ) {
2338 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSDMIN", model->elpModel[elpCGSDMIN]);
2339 return 1004 ;
2340 }
2341 if (model->elpCapa[elpCGSDMAX] == 0.0 ) {
2342 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSDMAX", model->elpModel[elpCGSDMAX]);
2343 return 1004 ;
2344 }
2345 if (model->elpCapa[elpCGSD] == 0.0 ) {
2346 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGSD", model->elpModel[elpCGSD]);
2347 return 1004 ;
2348 }
2349 if ((model->elpCapa[elpCGP] == 0.0 )) {
2350 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGP", model->elpModel[elpCGP]);
2351 return 1004 ;
2352 }
2353 if ((model->elpCapa[elpCGPUMIN] == 0.0 ) &&
2354 (model->elpCapa[elpCGPUMAX] == 0.0 ) &&
2355 (model->elpCapa[elpCGPDMIN] == 0.0 ) &&
2356 (model->elpCapa[elpCGPDMAX] == 0.0 )) {
2357 model->elpCapa[elpCGPUMIN] = model->elpCapa[elpCGP];
2358 model->elpCapa[elpCGPUMAX] = model->elpCapa[elpCGP];
2359 model->elpCapa[elpCGPDMIN] = model->elpCapa[elpCGP];
2360 model->elpCapa[elpCGPDMAX] = model->elpCapa[elpCGP];
2361 }
2362 if ((model->elpCapa[elpCGPUMIN] == 0.0 )) {
2363 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGPUMIN", model->elpModel[elpCGPUMIN]);
2364 return 1004 ;
2365 }
2366 if ((model->elpCapa[elpCGPUMAX] == 0.0 )) {
2367 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGPUMAX", model->elpModel[elpCGPUMAX]);
2368 return 1004 ;
2369 }
2370 if ((model->elpCapa[elpCGPDMIN] == 0.0 )) {
2371 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGPDMIN", model->elpModel[elpCGPDMIN]);
2372 return 1004 ;
2373 }
2374 if ((model->elpCapa[elpCGPDMAX] == 0.0 )) {
2375 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "CGPDMAX", model->elpModel[elpCGPDMAX]);
2376 return 1004 ;
2377 }
2378 if (elpEsimName[0] == '\0') {
2379 return 1004 ;
2380 }
2381 if (model->elpTransTechno == 0.0 ) {
2382 fprintf (stderr, "model %s: Techno = 0\n", model->elpModelName);
2383 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "Techno", model->elpTransTechno);
2384 return 1004 ;
2385 }
2386 if ((model->elpTemp < ELPMINTEMP ) && (elpGeneral[elpTEMP] < ELPMINTEMP)) {
2387 avt_errmsg(ELP_ERRMSG, "010", AVT_ERROR, elpTechnoFile, model->elpModelName, "Temperature", model->elpTemp);
2388 return 1004 ;
2389 }
2390 }
2391
2392 if(model->elpTemp < ELPMINTEMP)
2393 model->elpTemp = elpGeneral[elpTEMP] ;
2394
2395 if(elpGeneral[elpTEMP] < ELPMINTEMP)
2396 elpGeneral[elpTEMP] = model->elpTemp ;
2397
2398 if(elpGeneral[elpGVDDMAX] < 0.0)
2399 elpGeneral[elpGVDDMAX] = model->elpVoltage[elpVDDMAX] ;
2400
2401 if(elpGeneral[elpGVDDBEST] < 0.0)
2402 elpGeneral[elpGVDDBEST] = model->elpVoltage[elpVDDMAX] ;
2403
2404 if(elpGeneral[elpGVDDWORST] < 0.0)
2405 elpGeneral[elpGVDDWORST] = model->elpVoltage[elpVDDMAX] ;
2406
2407 if(model->elpVoltage[elpVDDMAX] < 0.0)
2408 model->elpVoltage[elpVDDMAX] = elpGeneral[elpGVDDMAX] ;
2409
2410 if (model->elpVoltage[elpVBULK] < ELPMINVBULK ) {
2411 if ( model->elpTransType == elpPMOS )
2412 model->elpVoltage[elpVBULK] = model->elpVoltage[elpVDDMAX];
2413 else
2414 model->elpVoltage[elpVBULK] = 0;
2415 }
2416
2417 if(elpGeneral[elpGDTHR] < 0.0)
2418 elpGeneral[elpGDTHR] = 0.5 ;
2419
2420 if((model->elpTransType == elpPMOS) && (model->elpVoltage[elpVDEG] < 0.0))
2421 model->elpVoltage[elpVDEG] = 1.5*model->elpModel[elpVT] ;
2422 if((model->elpTransType == elpPMOS) && (model->elpVoltage[elpVTI] < 0.0))
2423 model->elpVoltage[elpVTI] = 1.5*model->elpModel[elpVT] ;
2424
2425 if((model->elpTransType == elpNMOS) && (model->elpVoltage[elpVDEG] < 0.0))
2426 model->elpVoltage[elpVDEG] = model->elpVoltage[elpVDDMAX] - 1.5*model->elpModel[elpVT] ;
2427 if((model->elpTransType == elpNMOS) && (model->elpVoltage[elpVTI] < 0.0))
2428 model->elpVoltage[elpVTI] = model->elpVoltage[elpVDDMAX] - 1.5*model->elpModel[elpVT] ;
2429
2430 return(0) ;
2431 }
2432
2433 /*****************************************************************************/
2434 /* function LoadElp() */
2435 /* chargement du fichier techno sous forme structure ELP. En cas d'erreur la */
2436 /* fonction affiche un message et renvoie le numero d'erreur. Sinon le code */
2437 /* de retour est 0. */
2438 /* */
2439 /* Parametres en entree: */
2440 /* -------------------- */
2441 /* Aucun! */
2442 /* */
2443 /* Parametre en sortie: */
2444 /* ------------------- */
2445 /* La fonction renvoie 0 si le chargement s'est bien effectue, le numero */
2446 /* d'erreur sinon. */
2447 /*****************************************************************************/
2448 elpFCT short elpLoadElp()
2449 {
2450 elpmodel_list *model ;
2451 int res ;
2452 /* ouverture du fichier techno */
2453
2454 elpFreeModel() ;
2455
2456 if ( ELP_LOAD_FILE_TYPE == ELP_DONTLOAD_FILE )
2457 elpin = NULL;
2458 else
2459 elpin = fopen(elpTechnoFile,"r") ;
2460
2461 ELPLINE = 1 ;
2462
2463 /* appel au parser pour chargement */
2464 if ( elpin )
2465 if(elpparse() != 0)
2466 {
2467 avt_errmsg(ELP_ERRMSG, "002", AVT_ERROR, elpTechnoFile);
2468 // elpError(1002,elpTechnoFile) ; /* si erreur chergement => erreur 1002 */
2469 return 1002 ; /* arret de la procedure elp */
2470 }
2471
2472 /* fermeture du fichier techno */
2473 if ( elpin )
2474 if( fclose(elpin) != 0)
2475 {
2476 avt_errmsg(ELP_ERRMSG, "003", AVT_ERROR, elpTechnoFile);
2477 //elpError(1003,elpTechnoFile) ; /* si fermeture ko => erreur 1003 */
2478 }
2479
2480 /*-------------------------------------------------------------------*/
2481 /* Si le fichier elp n existe pas, ni le fichier techno (spice) */
2482 /* alors retourne 1 */
2483 /*-------------------------------------------------------------------*/
2484 if ( !ELP_MODEL_LIST ) {
2485 if (elpSetDefaultParam!=NULL) elpSetDefaultParam ();
2486 return 1;
2487 }
2488
2489 /*-------------------------------------------------------------------*/
2490 /* verification des parametres obligatoires et calcul des parametres */
2491 /* optionnels. */
2492 /*-------------------------------------------------------------------*/
2493 model = ELP_MODEL_LIST ;
2494 while(model){
2495 res = elpVerifModel(model) ;
2496 if(res != 0)
2497 return(res) ;
2498 model = model -> NEXT ;
2499 }
2500
2501 return 0 ; /* bon chargement */
2502 }
2503
2504 /*****************************************************************************/
2505 /* function DriveElp() */
2506 /* sauvegarde le fichier elp */
2507 /* */
2508 /* Parametres en entree: */
2509 /* -------------------- */
2510 /* Nom du fichier elp */
2511 /* */
2512 /* Parametre en sortie: */
2513 /* ------------------- */
2514 /* La fonction renvoie 0 si le chargement s'est bien effectue, le numero */
2515 /* d'erreur sinon. */
2516 /*****************************************************************************/
2517 elpFCT void elpDriveElp(char *filename)
2518 {
2519 FILE *file ;
2520 elpmodel_list *model ;
2521
2522 sprintf(filename, "%s%s",filename,".elp") ;
2523 file = fopen(filename,"w") ;
2524 if(file == NULL)
2525 {
2526 fprintf(stderr, "elp error: can't open file %s to drive!!!\n",filename) ;
2527 return ;
2528 }
2529
2530 model = ELP_MODEL_LIST ;
2531
2532 while(model){
2533 elpVerifModel(model) ;
2534 model = model -> NEXT ;
2535 }
2536
2537 model = ELP_MODEL_LIST ;
2538
2539 fprintf(file, "#TAS PARAMETER FILE\n\n") ;
2540 fprintf(file, "Technologie: %s Version: %g\n\n", elpTechnoName, elpTechnoVersion) ;
2541 fprintf(file, "#General parameters\n\n") ;
2542 fprintf(file, "#Reference Simulator\n") ;
2543 fprintf(file, "ESIM = %s\n", elpEsimName) ;
2544 fprintf(file, "#simulation parameters\n") ;
2545 if(elpGeneral[elpTEMP] > ELPMINTEMP)
2546 fprintf(file, "TEMP = %g\n", elpGeneral[elpTEMP]) ;
2547 if(elpGeneral[elpGVDDMAX] > 0)
2548 fprintf(file, "VDDmax = %g\n", elpGeneral[elpGVDDMAX]) ;
2549 if(elpGeneral[elpGVDDBEST] > 0)
2550 fprintf(file, "VDDBest = %g\n", elpGeneral[elpGVDDBEST]) ;
2551 if(elpGeneral[elpGVDDWORST] > 0)
2552 fprintf(file, "VDDWorst = %g\n", elpGeneral[elpGVDDWORST]) ;
2553 if(elpGeneral[elpGDTHR] > 0)
2554 fprintf(file, "DTHR = %g\n", elpGeneral[elpGDTHR]) ;
2555 if(elpGeneral[elpGSHTHR] > 0)
2556 fprintf(file, "SHTHR = %g\n", elpGeneral[elpGSHTHR]) ;
2557 if(elpGeneral[elpGSLTHR] > 0)
2558 fprintf(file, "SLTHR = %g\n", elpGeneral[elpGSLTHR]) ;
2559 fprintf(file, "SLOPE = %g\n", elpGeneral[elpSLOPE]) ;
2560 fprintf(file, "ACM = %g\n\n\n", elpGeneral[elpACM]) ;
2561
2562 while (model) {
2563 elpDriveOneModel (file,model);
2564 model = model->NEXT ;
2565 }
2566 fclose(file) ;
2567 }
2568
2569 /****************************************************************************/
2570 /* fonction LotrsCapaDrain() */
2571 /* calcule la capacite de drain d'un transistor MBK passe en parametre. */
2572 /* */
2573 /* Parametres en entree: */
2574 /* -------------------- */
2575 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
2576 /* drain. */
2577 /* */
2578 /* Parametre en sortie: */
2579 /* ------------------- */
2580 /* la fonction renvoie la capcite du drain du transistor en picoF. */
2581 /****************************************************************************/
2582 elpFCT float elpLotrsCapaDrain(lotrs,capatype,transcase)
2583 struct lotrs *lotrs ;
2584 int capatype;
2585 int transcase;
2586 {
2587 double w,wcj,vdd ;
2588 double cds,cdp,cdw;
2589 double cdsval,cdpval,cdwval;
2590 long xd_s,pd_s;
2591 elpmodel_list *model;
2592 double ad, pd, wj, ab, lg, ls, cgp ;
2593 static char displayed=0 ;
2594
2595 vdd = elpGetVddFromCorner ( lotrs, transcase );
2596 model = elpGetModel(lotrs,vdd,transcase) ;
2597 if ( !model ) return 0.0;
2598
2599 /* si les parametres CDxx ou sont manquants => erreur 1005 */
2600 if(model->elpTransModel == elpMOS)
2601 {
2602 if((model->elpCapa[elpCDS] == 0.0) &&
2603 (model->elpCapa[elpCDP] == 0.0) &&
2604 (model->elpCapa[elpCDW] == 0.0))
2605 {
2606 if( !displayed )
2607 avt_errmsg(ELP_ERRMSG, "005", AVT_ERROR, elpTechnoFile);
2608 // elpError(1005,"diffusion") ;
2609 displayed = 1 ;
2610 return 0 ;
2611 }
2612 }
2613
2614 if((lotrs->PD == 0) && (lotrs->XD == 0) && (lotrs->WIDTH == 0))
2615 return(0.0) ;
2616
2617 if(ELP_CAPA_DIFF == 1)
2618 {
2619 if((lotrs->XD < (long)0) || (lotrs->PD < (long)0))
2620 {
2621 lotrs->XD = model->elpShrink[elpWMLT]*SCALE_X ;
2622 lotrs->PD = elpGetShrinkedWidth(lotrs,model);
2623 }
2624 }
2625
2626 if(lotrs->WIDTH == 0)
2627 wcj = w = ((double)lotrs->PD / (double)4.0) ;
2628 else {
2629 w = (double)elpGetShrinkedWidth(lotrs,model);
2630 wcj = elpShrinkSize(lotrs->WIDTH,model->elpShrink[elpDWCJ],1.0) ;
2631 }
2632
2633 switch ( capatype ) {
2634 case ELP_CAPA_UP:
2635 case ELP_CAPA_UP_MIN:
2636 case ELP_CAPA_UP_MAX: cds = model->elpCapa[elpCDSU];
2637 cdp = model->elpCapa[elpCDPU];
2638 cdw = model->elpCapa[elpCDWU];
2639 cgp = model->elpCapa[elpCGP];
2640 break;
2641 case ELP_CAPA_DN:
2642 case ELP_CAPA_DN_MIN:
2643 case ELP_CAPA_DN_MAX: cds = model->elpCapa[elpCDSD];
2644 cdp = model->elpCapa[elpCDPD];
2645 cdw = model->elpCapa[elpCDWD];
2646 cgp = model->elpCapa[elpCGP];
2647 break;
2648 default : cds = model->elpCapa[elpCDS];
2649 cdp = model->elpCapa[elpCDP];
2650 cdw = model->elpCapa[elpCDW];
2651 cgp = model->elpCapa[elpCGP];
2652 break;
2653 }
2654 /*---------------------------------------------------------------------------*/
2655 /* Methode de calcul des capacites: si le perimetre est manquant, la contri- */
2656 /* bution en perimetre sera remplacee par la contribution en largeur. Sinon, */
2657 /* seul le perimetre sera pris en compte. */
2658 /*---------------------------------------------------------------------------*/
2659 if(model->elpTransModel == elpMOS)
2660 {
2661 elpLotrsGetShrinkDim(lotrs,NULL,NULL,NULL,&xd_s,NULL,&pd_s,NULL,NULL, transcase);
2662
2663 if( model->elpTransTechno == elpPSP ) {
2664
2665 ad = (double)xd_s*w / (double)(SCALE_X*SCALE_X) ;
2666 pd = pd_s / (double)SCALE_X ;
2667 wj = wcj / (double)SCALE_X ;
2668
2669 switch( model->elpSWJUNCAP ) {
2670 case 0 :
2671 ab = 0.0 ;
2672 ls = 0.0 ;
2673 lg = 0.0 ;
2674 break ;
2675 case 1 :
2676 ab = getlotrsparam( lotrs, MBK_ABDRAIN, NULL, NULL );
2677 ls = getlotrsparam( lotrs, MBK_LSDRAIN, NULL, NULL );
2678 lg = getlotrsparam( lotrs, MBK_LGDRAIN, NULL, NULL );
2679 break ;
2680 case 2 :
2681 ab = ad ;
2682 ls = pd ;
2683 lg = wj ;
2684 break ;
2685 case 3 :
2686 ab = ad ;
2687 ls = pd-wj ;
2688 lg = wj ;
2689 break ;
2690 }
2691 cdsval = ab*cds ;
2692 cdpval = ls*cdp ;
2693 cdwval = lg*cdw + cgp*w ;
2694 }
2695 else {
2696 if ( model->elpTransTechno == elpBSIM3V3 && pd_s < wcj ) {
2697 cdsval = ((double)xd_s*w / (double)(SCALE_X*SCALE_X)) * cds ;
2698 cdpval = (pd_s / (double)SCALE_X ) * ( cdw + cdp - model->elpCapa[elpCGP] ) ;
2699 cdwval = (wcj / (double)SCALE_X) * model->elpCapa[elpCGP] ;
2700 }
2701 else {
2702 cdsval = ((double)xd_s*w / (double)(SCALE_X*SCALE_X)) * cds ;
2703 cdpval = ((double)pd_s / (double)SCALE_X ) * cdp ;
2704 cdwval = (wcj / (double)SCALE_X ) * cdw ;
2705 }
2706 }
2707
2708 return (float)(cdsval+cdpval+cdwval);
2709 }
2710 else
2711 {
2712 return(0.0) ;
2713 }
2714
2715 }
2716
2717
2718 /****************************************************************************/
2719 /* fonction LotrsCapaSource() */
2720 /* calcule la capacite de source d'un transistor MBK passe en parametre. */
2721 /* */
2722 /* Parametres en entree: */
2723 /* -------------------- */
2724 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
2725 /* source. */
2726 /* */
2727 /* Parametre en sortie: */
2728 /* ------------------- */
2729 /* la fonction renvoie la capcite de la source du transistor en picoF. */
2730 /****************************************************************************/
2731 elpFCT float elpLotrsCapaSource(lotrs,capatype,transcase)
2732 struct lotrs *lotrs ;
2733 int capatype;
2734 int transcase;
2735 {
2736 double w,wcj,vdd;
2737 double css,csp,csw;
2738 long xs_s,ps_s;
2739 double cssval,cspval,cswval;
2740 elpmodel_list *model;
2741 double as, ps, wj, ab, lg, ls, cgp ;
2742 static char displayed=0;
2743
2744 vdd = elpGetVddFromCorner ( lotrs, transcase );
2745 model = elpGetModel(lotrs,vdd,transcase) ;
2746 if ( !model ) return 0.0;
2747
2748 /* si les parametres CDxx ou CSxx sont manquants => erreur 1005 */
2749 if(model->elpTransModel == elpMOS)
2750 {
2751 if((model->elpCapa[elpCSS] == 0.0) &&
2752 (model->elpCapa[elpCSP] == 0.0) &&
2753 (model->elpCapa[elpCSW] == 0.0))
2754 {
2755 if( !displayed )
2756 avt_errmsg(ELP_ERRMSG, "002", AVT_ERROR, elpTechnoFile);
2757 // elpError(1005,"diffusion") ;
2758 displayed = 1 ;
2759 return 0 ;
2760 }
2761 }
2762
2763 if((lotrs->PS == 0) && (lotrs->XS == 0) && (lotrs->WIDTH == 0))
2764 return(0.0) ;
2765
2766 if(ELP_CAPA_DIFF == 1)
2767 {
2768 if((lotrs->XS<0) || (lotrs->PS<0))
2769 {
2770 lotrs->XS = model->elpShrink[elpWMLT]*SCALE_X ;
2771 lotrs->PS = elpGetShrinkedWidth(lotrs,model);
2772 }
2773 }
2774
2775 if(lotrs->WIDTH == 0)
2776 wcj = w = ((double)lotrs->PS / (double)4.0) ;
2777 else {
2778 w = (double)elpGetShrinkedWidth(lotrs,model);
2779 wcj = elpShrinkSize(lotrs->WIDTH,model->elpShrink[elpDWCJ],1.0) ;
2780 }
2781
2782 switch ( capatype ) {
2783 case ELP_CAPA_UP:
2784 case ELP_CAPA_UP_MIN:
2785 case ELP_CAPA_UP_MAX: css = model->elpCapa[elpCSSU];
2786 csp = model->elpCapa[elpCSPU];
2787 csw = model->elpCapa[elpCSWU];
2788 cgp = model->elpCapa[elpCGP];
2789 break;
2790 case ELP_CAPA_DN:
2791 case ELP_CAPA_DN_MIN:
2792 case ELP_CAPA_DN_MAX: css = model->elpCapa[elpCSSD];
2793 csp = model->elpCapa[elpCSPD];
2794 csw = model->elpCapa[elpCSWD];
2795 cgp = model->elpCapa[elpCGP];
2796 break;
2797 default : css = model->elpCapa[elpCSS];
2798 csp = model->elpCapa[elpCSP];
2799 csw = model->elpCapa[elpCSW];
2800 cgp = model->elpCapa[elpCGP];
2801 break;
2802 }
2803 /*---------------------------------------------------------------------------*/
2804 /* Methode de calcul des capacites: si le perimetre est manquant, la contri- */
2805 /* bution en perimetre sera remplacee par la contribution en largeur. Sinon, */
2806 /* seul le perimetre sera pris en compte. */
2807 /*---------------------------------------------------------------------------*/
2808 if(model->elpTransModel == elpMOS)
2809 {
2810 elpLotrsGetShrinkDim(lotrs,NULL,NULL,&xs_s,NULL,&ps_s,NULL,NULL,NULL, transcase);
2811
2812 if( model->elpTransTechno == elpPSP ) {
2813
2814 as = (double)xs_s*w / (double)(SCALE_X*SCALE_X) ;
2815 ps = ps_s / (double)SCALE_X ;
2816 wj = wcj / (double)SCALE_X ;
2817
2818 switch( model->elpSWJUNCAP ) {
2819 case 0 :
2820 ab = 0.0 ;
2821 ls = 0.0 ;
2822 lg = 0.0 ;
2823 break ;
2824 case 1 :
2825 ab = getlotrsparam( lotrs, MBK_ABSOURCE, NULL, NULL );
2826 ls = getlotrsparam( lotrs, MBK_LSSOURCE, NULL, NULL );
2827 lg = getlotrsparam( lotrs, MBK_LGSOURCE, NULL, NULL );
2828 break ;
2829 case 2 :
2830 ab = as ;
2831 ls = ps ;
2832 lg = wj ;
2833 break ;
2834 case 3 :
2835 ab = as ;
2836 ls = ps-wj ;
2837 lg = wj ;
2838 break ;
2839 }
2840 cssval = ab*css ;
2841 cspval = ls*csp ;
2842 cswval = lg*csw + cgp*w ;
2843 }
2844 else {
2845
2846 if ( model->elpTransTechno == elpBSIM3V3 && ps_s < wcj ) {
2847 cssval = ((double)xs_s*(double)w / (double)(SCALE_X*SCALE_X)) * css ;
2848 cspval = (ps_s / (double)SCALE_X ) * ( csw + csp - model->elpCapa[elpCGP] ) ;
2849 cswval = (wcj / (double)SCALE_X) * model->elpCapa[elpCGP] ;
2850 }
2851 else {
2852 cssval = ((double)xs_s*(double)w / (double)(SCALE_X*SCALE_X)) * css ;
2853 cspval = ((double)ps_s / (double)SCALE_X ) * csp ;
2854 cswval = (wcj / (double)SCALE_X ) * csw ;
2855 }
2856 }
2857 return cssval + cspval + cswval ;
2858 }
2859 else
2860 {
2861 return(0.0) ;
2862 }
2863
2864 }
2865
2866 /****************************************************************************/
2867 /* fonction LotrsCapaGrid() */
2868 /* calcule la capacite de grille d'un transistor MBK passe en parametre. */
2869 /* */
2870 /* Parametres en entree: */
2871 /* -------------------- */
2872 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
2873 /* grille. */
2874 /* */
2875 /* Parametre en sortie: */
2876 /* ------------------- */
2877 /* la fonction renvoie la capcite de la grille du transistor en picoF. */
2878 /****************************************************************************/
2879 elpFCT float elpLotrsCapaGrid(lotrs,transcase)
2880 struct lotrs *lotrs ;
2881 int transcase;
2882
2883 {
2884 long l,w ;
2885 elpmodel_list *model;
2886 double vdd,cgs;
2887 int same_SD;
2888
2889 vdd = elpGetVddFromCorner ( lotrs, transcase );
2890 model = elpGetModel(lotrs,vdd,transcase) ;
2891 if ( !model ) return 0.0;
2892
2893 same_SD = elpSameSD_sig (lotrs);
2894
2895 l = elpShrinkSize(elpGetShrinkedLength(lotrs,model),-model->elpShrink[elpDL],1.0) ;
2896 l = elpShrinkSize(l,model->elpShrink[elpDLC],1.0) ;
2897 w = elpShrinkSize(elpGetShrinkedWidth(lotrs,model),-model->elpShrink[elpDW],1.0) ;
2898 w = elpShrinkSize(w,model->elpShrink[elpDWC],1.0) ;
2899
2900 cgs = (same_SD == 0) ? model->elpCapa[elpCGS] : model->elpCapa[elpCGS0];
2901
2902 /* les parametres CGxx sont obligatoires et ne sont donc pas manquant */
2903
2904 if(model->elpTransModel == elpMOS)
2905 {
2906 return(float)(
2907 /* contribution en surface */
2908 ((double)w*(double)l / (double)(SCALE_X*SCALE_X))
2909 *cgs +
2910 /* contribution en perimetre */
2911 (2.0*(double)w / (double)SCALE_X)*model->elpCapa[elpCGP]) ;
2912 }
2913 else
2914 {
2915 return(0.0) ;
2916 }
2917
2918 }
2919
2920 /****************************************************************************/
2921 /* fonction LotrsInCapa () */
2922 /* calcule la capacite d'entree d'un transistor MBK passe en parametre. */
2923 /* */
2924 /* Parametres en entree: */
2925 /* -------------------- */
2926 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
2927 /* grille. */
2928 /* */
2929 /* Parametre en sortie: */
2930 /* ------------------- */
2931 /* la fonction renvoie la capcite de la grille du transistor en picoF. */
2932 /****************************************************************************/
2933 elpFCT float elpLotrsInCapa( lofig_list *lofig,
2934 lotrs_list *lotrs,
2935 int capatype,
2936 int transcase,
2937 int correct
2938 )
2939 {
2940 long l,w ;
2941 double cgs=0.0, cgp=0.0,vdd;
2942 double cc, cm, c ;
2943 elpmodel_list *model;
2944 int same_SD=0;
2945
2946 vdd = elpGetVddFromCorner ( lotrs, transcase );
2947 model = elpGetModel(lotrs,vdd,transcase) ;
2948 if ( !model || model->elpTransModel != elpMOS ) return 0.0;
2949
2950 l = elpShrinkSize(elpGetShrinkedLength(lotrs,model),-model->elpShrink[elpDL],1.0) ;
2951 l = elpShrinkSize(l,model->elpShrink[elpDLC],1.0) ;
2952 w = elpShrinkSize(elpGetShrinkedWidth(lotrs,model),-model->elpShrink[elpDW],1.0) ;
2953 w = elpShrinkSize(w,model->elpShrink[elpDWC],1.0) ;
2954
2955 same_SD = elpSameSD_sig ( lotrs );
2956
2957 switch ( capatype ) {
2958 case ELP_CAPA_UP : if (!same_SD)
2959 cgs = model->elpCapa[elpCGSU];
2960 else
2961 cgs = model->elpCapa[elpCGSU0];
2962 cgp = model->elpCapa[elpCGPUMIN];
2963 break;
2964 case ELP_CAPA_UPF : if (!same_SD)
2965 cgs = model->elpCapa[elpCGSUF];
2966 else
2967 cgs = model->elpCapa[elpCGSU0];
2968 cgp = model->elpCapa[elpCGPUMIN];
2969 break;
2970 case ELP_CAPA_UP_MIN : cgs = model->elpCapa[elpCGSUMIN];
2971 cgp = model->elpCapa[elpCGPUMIN];
2972 break;
2973 case ELP_CAPA_UP_MAX : cgs = model->elpCapa[elpCGSUMAX];
2974 cgp = model->elpCapa[elpCGPUMAX];
2975 break;
2976 case ELP_CAPA_DN : if (!same_SD)
2977 cgs = model->elpCapa[elpCGSD];
2978 else
2979 cgs = model->elpCapa[elpCGSD0];
2980 cgp = model->elpCapa[elpCGPDMIN];
2981 break;
2982 case ELP_CAPA_DNF : if (!same_SD)
2983 cgs = model->elpCapa[elpCGSDF];
2984 else
2985 cgs = model->elpCapa[elpCGSD0];
2986 cgp = model->elpCapa[elpCGPDMIN];
2987 break;
2988 case ELP_CAPA_DN_MIN : cgs = model->elpCapa[elpCGSDMIN];
2989 cgp = model->elpCapa[elpCGPDMIN];
2990 break;
2991 case ELP_CAPA_DN_MAX : cgs = model->elpCapa[elpCGSDMAX];
2992 cgp = model->elpCapa[elpCGPDMAX];
2993 break;
2994 case ELP_CAPA_TYPICAL: if (!same_SD)
2995 cgs = model->elpCapa[elpCGS];
2996 else
2997 cgs = model->elpCapa[elpCGS0];
2998 cgp = model->elpCapa[elpCGP];
2999 break;
3000 }
3001
3002 c = ((double)w*(double)l / (double)(SCALE_X*SCALE_X)) * cgs ;
3003
3004 cc = ((double)w) / ((double)SCALE_X) * cgp ;
3005
3006 /* Source side */
3007 if( correct
3008 && !mbk_LosigIsVSS(lotrs->SOURCE->SIG)
3009 && !mbk_LosigIsVDD(lotrs->SOURCE->SIG) )
3010 cm = elpGetCapaSig( lofig, lotrs->SOURCE->SIG, ELP_CAPA_TYPICAL ) - cc ;
3011 else
3012 cm = -1.0 ;
3013
3014 if( cm > 0.0 )
3015 c = c + cc*cm/(cc+cm);
3016 else
3017 c = c + cc ;
3018
3019 /* Drain Side */
3020 if( correct
3021 && !mbk_LosigIsVSS(lotrs->DRAIN->SIG)
3022 && !mbk_LosigIsVSS(lotrs->DRAIN->SIG) )
3023 cm = elpGetCapaSig( lofig, lotrs->DRAIN->SIG, ELP_CAPA_TYPICAL ) - cc ;
3024 else
3025 cm = -1.0 ;
3026
3027 if( cm > 0.0 )
3028 c = c + cc*cm/(cc+cm);
3029 else
3030 c = c + cc ;
3031
3032 return (float)c ;
3033 }
3034
3035 /****************************************************************************/
3036 /* fonction LofigCapaDiff() */
3037 /* calcule les capas de diffusion des transistors de la figure lofig */
3038 /* */
3039 /* Parametres en entree: */
3040 /* -------------------- */
3041 /* 1) lofig: figure logique MBK dont dans laquelle il faut ajouter les */
3042 /* capas de diffusion. */
3043 /* */
3044 /* Parametre en sortie: */
3045 /* ------------------- */
3046 /* Aucun! */
3047 /****************************************************************************/
3048 elpFCT void elpLofigCapaDiff(lofig,transcase)
3049 struct lofig*lofig ;
3050 int transcase;
3051
3052 {
3053 lotrs_list *lotrs ;
3054 float capadrain;
3055 float capasource;
3056
3057 for(lotrs = lofig->LOTRS ; lotrs != NULL ; lotrs = lotrs->NEXT)
3058 {
3059 /* if (mbk_isdioden(getlotrsmodel(lotrs)) || mbk_isdiodep(getlotrsmodel(lotrs)))
3060 continue;*/
3061 if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL0 )
3062 {
3063 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_TYPICAL,transcase);
3064 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_TYPICAL,transcase);
3065 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_TYPICAL ) ;
3066 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_TYPICAL ) ;
3067 }
3068 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL1 )
3069 {
3070 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_TYPICAL,transcase);
3071 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_TYPICAL,transcase);
3072 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_TYPICAL ) ;
3073 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_TYPICAL ) ;
3074
3075 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_UP,transcase);
3076 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_UP,transcase);
3077 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_UP) ;
3078 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_UP) ;
3079 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_DN,transcase);
3080 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_DN,transcase);
3081 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_DN) ;
3082 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_DN) ;
3083 }
3084 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 )
3085 {
3086 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_TYPICAL,transcase);
3087 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_TYPICAL,transcase);
3088 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_TYPICAL ) ;
3089 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_TYPICAL ) ;
3090
3091 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_UP,transcase);
3092 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_UP,transcase);
3093 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_UP) ;
3094 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_UP) ;
3095 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_UP_MIN) ;
3096 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_UP_MIN) ;
3097 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_UP_MAX) ;
3098 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_UP_MAX) ;
3099
3100 capasource = elpLotrsCapaSource(lotrs,ELP_CAPA_DN,transcase);
3101 capadrain = elpLotrsCapaDrain(lotrs,ELP_CAPA_DN,transcase);
3102 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_DN) ;
3103 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_DN) ;
3104 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_DN_MIN) ;
3105 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_DN_MIN) ;
3106 elpAddCapaSig( lofig, lotrs->SOURCE->SIG, capasource, ELP_CAPA_DN_MAX) ;
3107 elpAddCapaSig( lofig, lotrs->DRAIN->SIG, capadrain, ELP_CAPA_DN_MAX) ;
3108 }
3109 }
3110
3111 return ;
3112 }
3113
3114 /****************************************************************************\
3115 *
3116 * FUNC : elpLofigAddCapas
3117 *
3118 * Annotate the lofig with the grid and diffusion capacitance
3119 *
3120 \****************************************************************************/
3121 void elpLofigAddCapas ( lofig_list *lofig, int transcase )
3122 {
3123 ptype_list *ptype;
3124 char *techno = namealloc ( elpTechnoFile );
3125
3126 ptype = getptype ( lofig->USER, ELP_LOFIG_CAPAS_ID);
3127 if ( !ptype || ( ptype && ( (char*)ptype->DATA != techno ) )) {
3128 elpFreeCapaLofig ( lofig );
3129 elpLofigCapaGrid ( lofig, transcase );
3130 elpLofigCapaDiff ( lofig, transcase );
3131 if ( ptype )
3132 ptype->DATA = techno;
3133 else
3134 lofig->USER = addptype ( lofig->USER, ELP_LOFIG_CAPAS_ID, techno);
3135 }
3136 }
3137
3138 /****************************************************************************/
3139 /* fonction LofigCapaGrid() */
3140 /* calcule les capas de grille. */
3141 /* */
3142 /* Parametres en entree: */
3143 /* -------------------- */
3144 /* 1) lofig: figure logique MBK dont dans laquelle il faut ajouter les */
3145 /* capas de grille. */
3146 /* */
3147 /* Parametre en sortie: */
3148 /* ------------------- */
3149 /* Aucun! */
3150 /****************************************************************************/
3151 elpFCT void elpLofigCapaGrid(lofig,transcase)
3152 struct lofig *lofig ;
3153 int transcase;
3154
3155 {
3156 lotrs_list *lotrs ;
3157 char *trsmodel;
3158
3159 for(lotrs = lofig->LOTRS ; lotrs != NULL ; lotrs = lotrs->NEXT)
3160 {
3161 trsmodel = getlotrsmodel(lotrs);
3162 /* if (mbk_isdioden(trsmodel) || mbk_isdiodep(trsmodel))
3163 continue;
3164 */
3165 if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL0 )
3166 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_TYPICAL,transcase,0), ELP_CAPA_TYPICAL);
3167 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL1 )
3168 {
3169 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_TYPICAL,transcase,0), ELP_CAPA_TYPICAL);
3170
3171 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_UP,transcase,0), ELP_CAPA_UP);
3172 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_DN,transcase,0), ELP_CAPA_DN);
3173 }
3174 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 )
3175 {
3176 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_TYPICAL,transcase,0), ELP_CAPA_TYPICAL);
3177
3178 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_UP,transcase,0), ELP_CAPA_UP);
3179 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_DN,transcase,0), ELP_CAPA_DN);
3180 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_UP_MIN,transcase,0), ELP_CAPA_UP_MIN);
3181 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_UP_MAX,transcase,0), ELP_CAPA_UP_MAX);
3182 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_DN_MIN,transcase,0), ELP_CAPA_DN_MIN);
3183 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_DN_MAX,transcase,0), ELP_CAPA_DN_MAX);
3184 }
3185 else
3186 {
3187 elpAddCapaSig( lofig, lotrs->GRID->SIG, elpLotrsInCapa(lofig,lotrs,ELP_CAPA_TYPICAL,transcase,0), ELP_CAPA_TYPICAL);
3188 }
3189 }
3190 return ;
3191 }
3192
3193 /****************************************************************************/
3194 /* fonction elpLotrsResiCanal() */
3195 /* Calcule la résistance en petit signaux du transistor passé en parametre. */
3196 /* Hypothèse : le transistor est bien sûr supposé être en régime linéaire. */
3197 /* */
3198 /* Parametres en entree: */
3199 /* -------------------- */
3200 /* 1) lotrs: Transistor dont on veut obtenir la résistance. */
3201 /* */
3202 /* Parametre en sortie: */
3203 /* ------------------- */
3204 /* La résistance en ohms. */
3205 /****************************************************************************/
3206
3207 elpFCT double elpLotrsResiCanal(lotrs,transcase)
3208 struct lotrs *lotrs;
3209 int transcase;
3210 {
3211 double a, b, c ;
3212 double w, l ;
3213 double r,vdd ;
3214 elpmodel_list *model;
3215
3216 vdd = elpGetVddFromCorner ( lotrs, transcase );
3217 model = elpGetModel(lotrs,vdd,transcase) ;
3218 if ( !model ) return 0.0;
3219
3220 a = model->elpRss[elpRSSL] ;
3221 b = model->elpRss[elpRSSC] ;
3222 c = model->elpRss[elpRSSW] ;
3223
3224 w = ((float)elpGetShrinkedWidth(lotrs,model))/((float)SCALE_X)*1e-6 ;
3225 l = ((float)elpGetShrinkedLength(lotrs,model))/((float)SCALE_X)*1e-6 ;
3226
3227 if( a == 0.0 || b == 0.0 || c == 0.0 )
3228 r = model->elpModel[elpRT]*l/w; /* Modèle approché utilisant MCC */
3229 else
3230 r = ( a*l + b ) / ( c*w + 1.0 ) ; /* Modèle fin */
3231
3232 return r ;
3233 }
3234
3235
3236 /****************************************************************************/
3237
3238 double elpScm2Thr (double f, double smin, double smax, double Vt, double Vfinal, double Vdd, int type)
3239 {
3240 double v0, v1;
3241 double x0, x1;
3242 double ff;
3243
3244 if (smin < 0 && smax < 0) {
3245 ff = f;
3246 }
3247 else
3248 if (type == elpRISE) {
3249 v0 = smin * Vfinal;
3250 v1 = smax * Vfinal;
3251 if(v0 >= Vt){
3252 x0 = (atanh ((v0 - Vt) / (Vfinal - Vt)));
3253 x1 = (atanh ((v1 - Vt) / (Vfinal - Vt)));
3254 }else if(v1 >= Vt){
3255 x0 = (v0 - Vt) / (Vfinal - Vt);
3256 x1 = (atanh ((v1 - Vt) / (Vfinal - Vt)));
3257 }else{
3258 x0 = (v0 - Vt) / (Vfinal - Vt);
3259 x1 = (v1 - Vt) / (Vfinal - Vt);
3260 }
3261 ff = f * (x1 - x0);
3262 }
3263 else
3264 if (type == elpFALL) {
3265 v1 = smax * (Vdd - Vfinal) + Vfinal;
3266 v0 = smin * (Vdd - Vfinal) + Vfinal;
3267 if(v1 < Vdd - Vt){
3268 x1 = (atanh ((v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3269 x0 = (atanh ((v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3270 }else if(v0 < Vdd - Vt){
3271 x1 = (v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3272 x0 = (atanh ((v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3273 }else{
3274 x1 = (v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3275 x0 = (v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3276 }
3277 ff = f * (x0 - x1);
3278 }
3279 else {
3280 fprintf (stderr, "elp error : wrong transistion type\n");
3281 ff = f;
3282 }
3283
3284 return ff;
3285 }
3286
3287 /****************************************************************************/
3288
3289 double elpThr2Scm (double f, double smin, double smax, double Vt, double Vfinal, double Vdd, int type)
3290 {
3291 double v0, v1;
3292 double x0, x1;
3293 double ff;
3294
3295 if (smin < 0 && smax < 0) {
3296 ff = f;
3297 }
3298 else
3299 if (type == elpRISE) {
3300 v0 = smin * Vfinal;
3301 v1 = smax * Vfinal;
3302 if(v0 >= Vt){
3303 x0 = (atanh ((v0 - Vt) / (Vfinal - Vt)));
3304 x1 = (atanh ((v1 - Vt) / (Vfinal - Vt)));
3305 }else if(v1 >= Vt){
3306 x0 = (v0 - Vt) / (Vfinal - Vt);
3307 x1 = (atanh ((v1 - Vt) / (Vfinal - Vt)));
3308 }else{
3309 x0 = (v0 - Vt) / (Vfinal - Vt);
3310 x1 = (v1 - Vt) / (Vfinal - Vt);
3311 }
3312 ff = f / (x1 - x0);
3313 }
3314 else
3315 if (type == elpFALL) {
3316 v1 = smax * (Vdd - Vfinal) + Vfinal;
3317 v0 = smin * (Vdd - Vfinal) + Vfinal;
3318 if(v1 < Vdd - Vt){
3319 x1 = (atanh ((v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3320 x0 = (atanh ((v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3321 }else if(v0 < Vdd - Vt){
3322 x1 = (v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3323 x0 = (atanh ((v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt))));
3324 }else{
3325 x1 = (v1 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3326 x0 = (v0 - (Vdd - Vt)) / (Vfinal - (Vdd - Vt));
3327 }
3328 ff = f / (x0 - x1);
3329 }
3330 else {
3331 fprintf (stderr, "elp error : wrong transistion type\n");
3332 ff = f;
3333 }
3334
3335 return ff;
3336 }
3337
3338 /****************************************************************************/
3339 void (*elpSetDefaultParam) ( void ) ;
3340
3341 /****************************************************************************/
3342 void elpdefaultfct2 ( void )
3343 {
3344 return;
3345 }
3346
3347 /****************************************************************************/
3348 void elpSetFct2 (void (*f)( void ))
3349 {
3350 if (f)
3351 elpSetDefaultParam = f;
3352 else
3353 elpSetDefaultParam = elpdefaultfct2;
3354 }
3355
3356
3357 /****************************************************************************/
3358 void (*elpGenParam)(char* tname, int type, double l, double w, double vdd,
3359 lotrs_list *lotrs, int transcase, elp_lotrs_param *ptlotrs_param) ;
3360
3361 /****************************************************************************/
3362 void elpdefault (char* tname, int type, double l, double w, double vdd,
3363 lotrs_list *lotrs, int transcase, elp_lotrs_param *ptlotrs_param)
3364 {
3365 #ifndef __ALL__WARNING__
3366 tname = NULL;
3367 type = 0;
3368 l = 0.0;
3369 w = 0.0;
3370 vdd = 0.0;
3371 lotrs = NULL;
3372 transcase = elpTYPICAL;
3373 ptlotrs_param = NULL;
3374 #endif
3375
3376 return;
3377 }
3378
3379 /****************************************************************************/
3380 void elpSetFct(void (*f)(char* p0, int p1, double p2, double p3, double p4,
3381 lotrs_list *, int, elp_lotrs_param *ptlotrs_param))
3382 {
3383 if (f)
3384 elpGenParam = f;
3385 else
3386 elpGenParam = elpdefault;
3387 }
3388
3389 /****************************************************************************/
3390 double (*elpCalcIleak)(char* tname, int type, double l, double w,
3391 lotrs_list *lotrs, int transcase,
3392 double vgs, double vds, double vbs,
3393 double AD, double PD, double AS, double PS,
3394 double *BLeak, double *DLeak, double *SLeak,
3395 elp_lotrs_param *ptlotrs_param) ;
3396
3397 /****************************************************************************/
3398 double elpLeakDfltFct (char* tname, int type, double l, double w,
3399 lotrs_list *lotrs, int transcase,
3400 double vgs, double vds, double vbs,
3401 double AD, double PD, double AS, double PS,
3402 double *BLeak, double *DLeak, double *SLeak,
3403 elp_lotrs_param *ptlotrs_param)
3404 {
3405 #ifndef __ALL__WARNING__
3406 tname = NULL;
3407 type = 0;
3408 l = 0.0;
3409 w = 0.0;
3410 vgs = 0.0;
3411 vds = 0.0;
3412 vbs = 0.0;
3413 AD = 0.0;
3414 PD = 0.0;
3415 AS = 0.0;
3416 PS = 0.0;
3417 BLeak = NULL;
3418 DLeak = NULL;
3419 SLeak = NULL;
3420 lotrs = NULL;
3421 transcase = elpTYPICAL;
3422 ptlotrs_param = NULL;
3423 #endif
3424
3425 return 0.0;
3426 }
3427
3428 /****************************************************************************/
3429 void elpSetLeakFct(double (*f)(char* p0, int p1, double p2, double p3,
3430 lotrs_list *, int, double p4, double p5, double p6,
3431 double p7, double p8, double p9, double p10,
3432 double *t0, double *t1, double *t2,
3433 elp_lotrs_param *ptlotrs_param))
3434 {
3435 if (f)
3436 elpCalcIleak = f;
3437 else
3438 elpCalcIleak = elpLeakDfltFct;
3439 }
3440 /****************************************************************************/
3441 extern void elpSetCalcPAFct( void(*f)(lotrs_list*,char*,int,int,double,elp_lotrs_param*,double*,double*,double*,double*) )
3442 {
3443 elpCalcPAFct = f ;
3444 }
3445
3446 /****************************************************************************/
3447 elpFCT int elpLoadOnceElp ()
3448 {
3449
3450 if (!elpoldtechnofilename ||
3451 (strcasecmp(elpoldtechnofilename,elpTechnoFile))) {
3452 elpres_load = elpLoadElp();
3453 if (elpoldtechnofilename) mbkfree(elpoldtechnofilename);
3454 elpoldtechnofilename = mbkstrdup(elpTechnoFile);
3455 }
3456 return elpres_load;
3457 }
3458
3459 /****************************************************************************/
3460 elpFCT float elpGetCapaFromLocon (locon,capatype,transcase)
3461 locon_list *locon;
3462 int capatype;
3463 int transcase;
3464 {
3465 lotrs_list *lotrs;
3466 float capa = 0.0;
3467
3468 if ((!locon) || (locon->TYPE != 'T'))
3469 return 0.0;
3470 else {
3471 ELP_CALC_ONLY_CAPA = 1;
3472 lotrs = (lotrs_list*)locon->ROOT;
3473 elpLoadOnceElp();
3474 if (lotrs->DRAIN == locon)
3475 capa = elpLotrsCapaDrain (lotrs,capatype,transcase);
3476 else if (lotrs->SOURCE == locon)
3477 capa = elpLotrsCapaSource (lotrs,capatype,transcase);
3478 else if (lotrs->GRID == locon)
3479 capa = elpLotrsInCapa(NULL,lotrs,capatype,transcase,0);
3480 else
3481 capa = 0.0;
3482 ELP_CALC_ONLY_CAPA = 0;
3483 }
3484 return capa;
3485 }
3486
3487 /******************************************************************************\
3488 elpGetCapaSig : Renvoie la capacité mémorisée sur un signal, ou 0.0 si rien n'a
3489 été mémorisé.
3490 \******************************************************************************/
3491
3492 elpFCT float elpGetCapaSig ( lofig, losig, type )
3493 lofig_list *lofig;
3494 losig_list *losig;
3495 int type;
3496 {
3497 ptype_list *ptl;
3498 float capa;
3499 struct elpcapa *capas;
3500 int pos;
3501
3502
3503 ptl = getptype( lofig->USER, ELP_LOFIG_TABCAPA );
3504 if( !ptl )
3505 capa = ELP_NOCAPA;
3506 else {
3507 capas = (struct elpcapa*)(ptl->DATA);
3508 pos = losig->INDEX - 1;
3509
3510 if( pos < 0 || pos >= capas->NBSIG ) {
3511 fflush( stdout );
3512 fprintf( stderr, "\nelp error : bad index for signal %s\n",
3513 getsigname( losig )
3514 );
3515 capa = ELP_NOCAPA;
3516 }
3517 else {
3518 switch ( type ) {
3519 case ELP_CAPA_TYPICAL : capa = capas->TAB[pos];
3520 break;
3521 case ELP_CAPA_UP : capa = capas->TAB_UP[pos];
3522 break;
3523 case ELP_CAPA_UP_MIN : capa = capas->TAB_UP_MIN[pos];
3524 break;
3525 case ELP_CAPA_UP_MAX : capa = capas->TAB_UP_MAX[pos];
3526 break;
3527 case ELP_CAPA_DN : capa = capas->TAB_DN[pos];
3528 break;
3529 case ELP_CAPA_DN_MIN : capa = capas->TAB_DN_MIN[pos];
3530 break;
3531 case ELP_CAPA_DN_MAX : capa = capas->TAB_DN_MAX[pos];
3532 break;
3533 }
3534 }
3535 }
3536
3537 if( capa == ELP_NOCAPA )
3538 return 0.0;
3539
3540 return capa;
3541 }
3542
3543
3544 /******************************************************************************\
3545 elpGetTotalCapaSig : Renvoie toutes les capacités sur un signal.
3546 \******************************************************************************/
3547
3548 elpFCT float elpGetTotalCapaSig( lofig, losig, type )
3549 lofig_list *lofig;
3550 losig_list *losig;
3551 int type;
3552 {
3553 float capa=0.0, c ;
3554
3555 c = rcn_getcapa( lofig, losig );
3556 capa = capa + c;
3557 c = elpGetCapaSig( lofig, losig, type );
3558 capa = capa + c;
3559
3560 return capa;
3561 }
3562
3563 /******************************************************************************\
3564 elpSetCapaSig : Mémorise une capacité sur un signal.
3565 \******************************************************************************/
3566
3567 elpFCT void elpSetCapaSig ( lofig, losig, capa, type )
3568 lofig_list *lofig;
3569 losig_list *losig;
3570 float capa;
3571 int type;
3572 {
3573 ptype_list *ptl;
3574 struct elpcapa *capas;
3575 int n;
3576 int pos;
3577
3578 ptl = getptype( lofig->USER, ELP_LOFIG_TABCAPA );
3579
3580 if( !ptl ) {
3581
3582 lofig->USER = addptype( lofig->USER, ELP_LOFIG_TABCAPA, NULL );
3583 ptl = lofig->USER;
3584
3585 capas = (struct elpcapa*)mbkalloc( sizeof( struct elpcapa ) );
3586 capas->NBSIG = getnumberoflosig( lofig );
3587 capas->TAB = NULL;
3588 capas->TAB_UP = NULL;
3589 capas->TAB_DN = NULL;
3590 capas->TAB_UP_MIN = NULL;
3591 capas->TAB_UP_MAX = NULL;
3592 capas->TAB_DN_MIN = NULL;
3593 capas->TAB_DN_MAX = NULL;
3594
3595 if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL0 )
3596 {
3597 capas->TAB = mbkalloc( sizeof( float ) * capas->NBSIG );
3598
3599 for( n=0 ; n<capas->NBSIG ; n++ )
3600 capas->TAB[n] = ELP_NOCAPA;
3601 }
3602 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL1 )
3603 {
3604 capas->TAB = mbkalloc( sizeof( float ) * capas->NBSIG );
3605
3606 capas->TAB_UP = mbkalloc( sizeof( float ) * capas->NBSIG );
3607 capas->TAB_DN = mbkalloc( sizeof( float ) * capas->NBSIG );
3608
3609 for( n=0 ; n<capas->NBSIG ; n++ )
3610 {
3611 capas->TAB[n] = ELP_NOCAPA;
3612
3613 capas->TAB_UP[n] = ELP_NOCAPA;
3614 capas->TAB_DN[n] = ELP_NOCAPA;
3615 }
3616 }
3617 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 )
3618 {
3619 capas->TAB = mbkalloc( sizeof( float ) * capas->NBSIG );
3620
3621 capas->TAB_UP = mbkalloc( sizeof( float ) * capas->NBSIG );
3622 capas->TAB_DN = mbkalloc( sizeof( float ) * capas->NBSIG );
3623 capas->TAB_UP_MIN = mbkalloc( sizeof( float ) * capas->NBSIG );
3624 capas->TAB_UP_MAX = mbkalloc( sizeof( float ) * capas->NBSIG );
3625 capas->TAB_DN_MIN = mbkalloc( sizeof( float ) * capas->NBSIG );
3626 capas->TAB_DN_MAX = mbkalloc( sizeof( float ) * capas->NBSIG );
3627
3628 for( n=0 ; n<capas->NBSIG ; n++ )
3629 {
3630 capas->TAB[n] = ELP_NOCAPA;
3631
3632 capas->TAB_UP[n] = ELP_NOCAPA;
3633 capas->TAB_DN[n] = ELP_NOCAPA;
3634 capas->TAB_UP_MIN[n] = ELP_NOCAPA;
3635 capas->TAB_UP_MAX[n] = ELP_NOCAPA;
3636 capas->TAB_DN_MIN[n] = ELP_NOCAPA;
3637 capas->TAB_DN_MAX[n] = ELP_NOCAPA;
3638 }
3639 }
3640 else
3641 {
3642 capas->TAB = mbkalloc( sizeof( float ) * capas->NBSIG );
3643
3644 for( n=0 ; n<capas->NBSIG ; n++ )
3645 capas->TAB[n] = ELP_NOCAPA;
3646 }
3647
3648 ptl->DATA = capas;
3649 }
3650 else
3651 capas = (struct elpcapa*)ptl->DATA;
3652
3653 pos = losig->INDEX - 1;
3654 if( pos < 0 || pos >= capas->NBSIG ) {
3655 fflush( stdout );
3656 fprintf( stderr, "\nelp error : bad index for signal %s\n",
3657 getsigname( losig )
3658 );
3659 }
3660 else {
3661 switch ( type ) {
3662 case ELP_CAPA_TYPICAL : capas->TAB[pos] = capa;
3663 break;
3664 case ELP_CAPA_UP : capas->TAB_UP[pos] = capa;
3665 break;
3666 case ELP_CAPA_UP_MIN : capas->TAB_UP_MIN[pos] = capa;
3667 break;
3668 case ELP_CAPA_UP_MAX : capas->TAB_UP_MAX[pos] = capa;
3669 break;
3670 case ELP_CAPA_DN : capas->TAB_DN[pos] = capa;
3671 break;
3672 case ELP_CAPA_DN_MIN : capas->TAB_DN_MIN[pos] = capa;
3673 break;
3674 case ELP_CAPA_DN_MAX : capas->TAB_DN_MAX[pos] = capa;
3675 break;
3676 }
3677 }
3678 }
3679
3680 /******************************************************************************\
3681 elpIsCapaSig : Renvoie 1 si on a déjà mémorisé une capacité sur le signal.
3682 \******************************************************************************/
3683
3684 elpFCT char elpIsCapaSig( lofig, losig, type )
3685 lofig_list *lofig;
3686 losig_list *losig;
3687 int type;
3688 {
3689 ptype_list *ptl;
3690 struct elpcapa *capas;
3691 int pos,res;
3692
3693 ptl = getptype( lofig->USER, ELP_LOFIG_TABCAPA );
3694 if( !ptl )
3695 return 0;
3696
3697 capas = (struct elpcapa*)(ptl->DATA);
3698 pos = losig->INDEX - 1;
3699
3700 if( pos < 0 || pos >= capas->NBSIG ) {
3701 fflush( stdout );
3702 fprintf( stderr, "\nelp error : bad index for signal %s\n",
3703 getsigname( losig )
3704 );
3705 return 0;
3706 }
3707
3708 res = 1;
3709 switch ( type ) {
3710 case ELP_CAPA_TYPICAL : if( !capas->TAB || capas->TAB[pos] == ELP_NOCAPA )
3711 res = 0;
3712 break;
3713 case ELP_CAPA_UP : if( !capas->TAB_UP || capas->TAB_UP[pos] == ELP_NOCAPA )
3714 res = 0;
3715 break;
3716 case ELP_CAPA_UP_MIN : if (!capas->TAB_UP_MIN || capas->TAB_UP_MIN[pos] == ELP_NOCAPA)
3717 res = 0;
3718 break;
3719 case ELP_CAPA_UP_MAX : if (!capas->TAB_UP_MAX || capas->TAB_UP_MAX[pos] == ELP_NOCAPA)
3720 res = 0;
3721 break;
3722 case ELP_CAPA_DN : if(!capas->TAB_DN || capas->TAB_DN[pos] == ELP_NOCAPA )
3723 res = 0;
3724 break;
3725 case ELP_CAPA_DN_MIN : if (!capas->TAB_DN_MIN || capas->TAB_DN_MIN[pos] == ELP_NOCAPA)
3726 res = 0;
3727 break;
3728 case ELP_CAPA_DN_MAX : if (!capas->TAB_DN_MAX || capas->TAB_DN_MAX[pos] == ELP_NOCAPA)
3729 res = 0;
3730 break;
3731 }
3732 return res;
3733 }
3734
3735 /******************************************************************************\
3736 elpAddCapaSig : Ajoute une capacité sur un signal dans la capacité mémorisée.
3737 \******************************************************************************/
3738
3739 elpFCT float elpAddCapaSig( lofig, losig, capa, type )
3740 lofig_list *lofig;
3741 losig_list *losig;
3742 float capa;
3743 int type;
3744 {
3745 float newcapa;
3746
3747 newcapa = capa + elpGetCapaSig( lofig, losig, type );
3748 elpSetCapaSig( lofig, losig, newcapa, type );
3749
3750 return newcapa;
3751 }
3752
3753 /******************************************************************************\
3754 elpFreeCapaLofig : Efface toutes les capacités de la lofig
3755 \******************************************************************************/
3756 elpFCT void elpFreeCapaLofig( lofig )
3757 lofig_list *lofig;
3758 {
3759 ptype_list *ptl;
3760 struct elpcapa *capas;
3761
3762 ptl = getptype( lofig->USER, ELP_LOFIG_TABCAPA );
3763 if( !ptl ) return;
3764 capas = (struct elpcapa*)(ptl->DATA);
3765
3766 if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL0 )
3767 mbkfree( capas->TAB );
3768 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL1 )
3769 {
3770 mbkfree( capas->TAB );
3771
3772 mbkfree( capas->TAB_UP);
3773 mbkfree( capas->TAB_DN);
3774 }
3775 else if ( V_INT_TAB[__ELP_CAPA_LEVEL].VALUE == ELP_CAPA_LEVEL2 )
3776 {
3777 mbkfree( capas->TAB );
3778
3779 mbkfree( capas->TAB_UP);
3780 mbkfree( capas->TAB_DN);
3781 mbkfree( capas->TAB_UP_MIN );
3782 mbkfree( capas->TAB_UP_MAX );
3783 mbkfree( capas->TAB_DN_MIN );
3784 mbkfree( capas->TAB_DN_MAX );
3785 }
3786 else
3787 mbkfree( capas->TAB );
3788
3789 mbkfree( capas );
3790
3791 lofig->USER = delptype( lofig->USER, ELP_LOFIG_TABCAPA );
3792 }
3793
3794 /****************************************************************************/
3795 /* fonction LofigUnShrink() */
3796 /* */
3797 /* Repositionne les vrais tailles des transistors */
3798 /* */
3799 /* Parametres en entree: */
3800 /* -------------------- */
3801 /* 1) lofig: figure logique MBK dont dans laquelle il faut modifier les */
3802 /* dimensions des transistors. */
3803 /* */
3804 /* Parametre en sortie: */
3805 /* ------------------- */
3806 /* Aucun! */
3807 /****************************************************************************/
3808 elpFCT void elpLofigUnShrink(lofig,transcase)
3809 struct lofig *lofig ;
3810 int transcase;
3811
3812 {
3813 lotrs_list *lotrs ;
3814
3815 for(lotrs = lofig->LOTRS ; lotrs != NULL ; lotrs = lotrs->NEXT)
3816 elpLotrsUnShrink(lotrs,transcase) ;
3817
3818 return ;
3819 }
3820
3821 /****************************************************************************/
3822 /* fonction LotrsUnShrink() */
3823 /* modifie les dimensions du transistor en fonction des parametres de */
3824 /* shrink et du parametre ACM. */
3825 /* */
3826 /* Parametres en entree: */
3827 /* -------------------- */
3828 /* 1) lotrs: transistor logique MBK dont on veut modifier les dimensions */
3829 /* */
3830 /* Parametre en sortie: */
3831 /* ------------------- */
3832 /* Aucun! */
3833 /****************************************************************************/
3834 elpFCT void elpLotrsUnShrink(lotrs,transcase)
3835 struct lotrs *lotrs ;
3836 int transcase;
3837
3838 {
3839 double deltal , vdd,
3840 deltaw ;
3841 elpmodel_list *model;
3842
3843 vdd = elpGetVddFromCorner ( lotrs, transcase );
3844 model = elpGetModel(lotrs,vdd,transcase) ;
3845 if ( !model ) return;
3846
3847 if((lotrs->WIDTH == 0) || (lotrs->LENGTH == 0))
3848 return ;
3849
3850 if(model->elpTransModel == elpMOS)
3851 {
3852 deltal = model->elpShrink[elpDL] * (double)SCALE_X ;
3853 deltaw = model->elpShrink[elpDW] * (double)SCALE_X ;
3854 }
3855 lotrs->LENGTH = elpDouble2Long((((double)lotrs->LENGTH - deltal) / model->elpShrink[elpLMLT])) ;
3856 lotrs->WIDTH = elpDouble2Long((((double)lotrs->WIDTH - deltaw) / model->elpShrink[elpWMLT]));
3857 lotrs->XS = elpDouble2Long(((double)lotrs->XS / (model->elpShrink[elpWMLT] + deltaw/(double)lotrs->WIDTH))) ;
3858 lotrs->XD = elpDouble2Long(((double)lotrs->XD / (model->elpShrink[elpWMLT] + deltaw/(double)lotrs->WIDTH))) ;
3859
3860 if(elpGeneral[elpACM] == 1.0)
3861 {
3862 lotrs->XS = lotrs->XD = elpDouble2Long((model->elpShrink[elpWMLT] * (double)SCALE_X)) ;
3863 lotrs->PS = lotrs->PD = lotrs->WIDTH ;
3864 }
3865
3866 return ;
3867 }
3868
3869 //-------------------------------------------------------------------------
3870 elpFCT void elpLotrsGetUnShrinkDim( lotrs, length, width, length_s, width_s, transcase )
3871 struct lotrs *lotrs ;
3872 long length, width, *length_s, *width_s ;
3873 int transcase;
3874 {
3875 double deltal ,vdd,
3876 deltaw ;
3877 elpmodel_list *model;
3878
3879 vdd = elpGetVddFromCorner ( lotrs, transcase );
3880 model = elpGetModel(lotrs,vdd,transcase) ;
3881 if ( !model ) return;
3882
3883 if((lotrs->WIDTH == 0) || (lotrs->LENGTH == 0))
3884 return ;
3885
3886 if(model->elpTransModel == elpMOS)
3887 {
3888 deltal = model->elpShrink[elpDL] * (double)SCALE_X ;
3889 deltaw = model->elpShrink[elpDW] * (double)SCALE_X ;
3890 }
3891
3892 if( length_s )
3893 *length_s = elpDouble2Long((((double)length - deltal) / model->elpShrink[elpLMLT])) ;
3894 if( width_s )
3895 *width_s = elpDouble2Long((((double)width - deltaw) / model->elpShrink[elpWMLT]));
3896
3897 return ;
3898
3899 }
3900
3901 /****************************************************************************/
3902 /* fonction LotrsGetShrinkDim() */
3903 /* modifie les dimensions du transistor en fonction des parametres de */
3904 /* shrink et du parametre ACM. */
3905 /* */
3906 /* Parametres en entree: */
3907 /* -------------------- */
3908 /* 1) lotrs: transistor logique MBK dont on veut modifier les dimensions */
3909 /* */
3910 /* Parametre en sortie: */
3911 /* ------------------- */
3912 /* Aucun! */
3913 /****************************************************************************/
3914 elpFCT void elpLotrsGetShrinkDim (lotrs,length_s,width_s,xs_s,xd_s,
3915 ps_s,pd_s,ptlactive,ptwactive,transcase)
3916 struct lotrs *lotrs ;
3917 long *length_s;
3918 long *width_s;
3919 long *xs_s;
3920 long *xd_s;
3921 long *ps_s;
3922 long *pd_s;
3923 long *ptlactive;
3924 long *ptwactive;
3925 int transcase;
3926 {
3927 long l_s,w_s;
3928 long lactive,wactive;
3929 double deltal, deltaw, dla, dwa,vdd;
3930
3931 double as=0.0, ad=0.0, ps=0.0, pd=0.0, xs=0.0, xd=0.0 ;
3932 double mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc ;
3933 int ptlotrs_param_filled ;
3934 elp_lotrs_param ptlotrs_param;
3935
3936 elpmodel_list *model;
3937
3938 vdd = elpGetVddFromCorner ( lotrs, transcase );
3939 model = elpGetModel(lotrs,vdd,transcase) ;
3940 if ( !model ) return;
3941
3942 if((lotrs->WIDTH == 0) || (lotrs->LENGTH == 0)){
3943 if (xs_s != NULL)
3944 *xs_s = elpDouble2Long( (double)lotrs->XS) ;
3945 if (xd_s != NULL)
3946 *xd_s = elpDouble2Long( (double)lotrs->XD) ;
3947 if (ps_s != NULL)
3948 *ps_s = elpDouble2Long( (double)lotrs->PS) ;
3949 if (pd_s != NULL)
3950 *pd_s = elpDouble2Long( (double)lotrs->PD) ;
3951 }else{
3952 if(model->elpTransModel == elpMOS) {
3953 deltal = model->elpShrink[elpDL] * (double)SCALE_X ;
3954 deltaw = model->elpShrink[elpDW] * (double)SCALE_X ;
3955 dla = model->elpShrink[elpDLC] * (double)SCALE_X ;
3956 dwa = model->elpShrink[elpDWC] * (double)SCALE_X ;
3957 }
3958 l_s = elpDouble2Long((model->elpShrink[elpLMLT]*(double)lotrs->LENGTH + deltal)) ;
3959 w_s = elpDouble2Long((model->elpShrink[elpWMLT]*(double)lotrs->WIDTH + deltaw)) ;
3960 lactive = elpDouble2Long((model->elpShrink[elpLMLT]*(double)lotrs->LENGTH + dla)) ;
3961 wactive = elpDouble2Long((model->elpShrink[elpWMLT]*(double)lotrs->WIDTH + dwa)) ;
3962 if (length_s != NULL)
3963 *length_s = l_s;
3964 if (width_s != NULL)
3965 *width_s = w_s;
3966 if (ptlactive != NULL)
3967 *ptlactive = lactive;
3968 if (ptwactive != NULL)
3969 *ptwactive = wactive;
3970
3971 ptlotrs_param_filled = 0 ;
3972
3973 /******************************************************************************************************/
3974 if (xs_s != NULL) {
3975 if( lotrs->XS<0 ) {
3976 if( !ptlotrs_param_filled ) {
3977 elp_lotrs_param_get (lotrs,&mulu0,&delvt0,&sa,&sb,&sd,&nf,&m,&nrs,&nrd,&vbulk,&sc,&sca,&scb,&scc);
3978 fill_elp_lotrs_param( &ptlotrs_param, mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc, NULL );
3979 ptlotrs_param_filled = 1 ;
3980 }
3981 elpCalcPAFct( lotrs,
3982 getlotrsmodel( lotrs ),
3983 MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS,
3984 transcase,
3985 vdd,
3986 &ptlotrs_param,
3987 &as,
3988 NULL,
3989 NULL,
3990 NULL
3991 );
3992 xs = as * SCALE_X * SCALE_X * 1.0e12 / lotrs->WIDTH ;
3993 }
3994 else
3995 xs = lotrs->XS ;
3996 *xs_s = elpDouble2Long(((model->elpShrink[elpWMLT] - deltaw/(double)w_s) * xs)) ;
3997 }
3998
3999 /******************************************************************************************************/
4000 if (xd_s != NULL) {
4001 if( lotrs->XD<0) {
4002 if( !ptlotrs_param_filled ) {
4003 elp_lotrs_param_get (lotrs,&mulu0,&delvt0,&sa,&sb,&sd,&nf,&m,&nrs,&nrd,&vbulk,&sc,&sca,&scb,&scc);
4004 fill_elp_lotrs_param( &ptlotrs_param, mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc, NULL );
4005 ptlotrs_param_filled = 1 ;
4006 }
4007 elpCalcPAFct( lotrs,
4008 getlotrsmodel( lotrs ),
4009 MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS,
4010 transcase,
4011 vdd,
4012 &ptlotrs_param,
4013 NULL,
4014 &ad,
4015 NULL,
4016 NULL
4017 );
4018 xd = ad * SCALE_X * SCALE_X * 1.0e12 / lotrs->WIDTH ;
4019 }
4020 else
4021 xd = lotrs->XD ;
4022 *xd_s = elpDouble2Long(((model->elpShrink[elpWMLT] - deltaw/(double)w_s) * xd)) ;
4023 }
4024
4025 /******************************************************************************************************/
4026 if (ps_s != NULL) {
4027 if( lotrs->PS<0 ) {
4028 if( !ptlotrs_param_filled ) {
4029 elp_lotrs_param_get (lotrs,&mulu0,&delvt0,&sa,&sb,&sd,&nf,&m,&nrs,&nrd,&vbulk,&sc,&sca,&scb,&scc);
4030 fill_elp_lotrs_param( &ptlotrs_param, mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc, NULL );
4031 ptlotrs_param_filled = 1 ;
4032 }
4033
4034 elpCalcPAFct( lotrs,
4035 getlotrsmodel( lotrs ),
4036 MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS,
4037 transcase,
4038 vdd,
4039 &ptlotrs_param,
4040 NULL,
4041 NULL,
4042 &ps,
4043 NULL
4044 );
4045 /*
4046 Ps et pd sont les dimensions efficace. Dans les champs PS et PD du
4047 lotrs, ce sont les dimensions telles qu'elles apparaissent dans le
4048 fichier Spice.
4049 Le passage de l'un à l'autre s'effectue à l'aide le la relation
4050 de la doc bsim4v30.pdf p 115.
4051 */
4052
4053 ps = ps * SCALE_X * 1.0e6 + lotrs->WIDTH ;
4054 }
4055 else
4056 ps = lotrs->PS<0?0:lotrs->PS ;
4057 *ps_s = ps ;
4058 }
4059
4060 /******************************************************************************************************/
4061 if (pd_s != NULL) {
4062 if( lotrs->PD<0 ) {
4063 if( !ptlotrs_param_filled ) {
4064 elp_lotrs_param_get (lotrs,&mulu0,&delvt0,&sa,&sb,&sd,&nf,&m,&nrs,&nrd,&vbulk,&sc,&sca,&scb,&scc);
4065 vdd = elpGetVddFromCorner ( lotrs, transcase );
4066 fill_elp_lotrs_param( &ptlotrs_param, mulu0, delvt0, sa, sb, sd, nf, m ,nrs, nrd, vbulk, sc, sca, scb, scc, NULL );
4067 ptlotrs_param_filled = 1 ;
4068 }
4069 elpCalcPAFct( lotrs,
4070 getlotrsmodel( lotrs ),
4071 MLO_IS_TRANSN(lotrs->TYPE) ? elpNMOS : elpPMOS,
4072 transcase,
4073 vdd,
4074 &ptlotrs_param,
4075 NULL,
4076 NULL,
4077 NULL,
4078 &pd
4079 );
4080 /*
4081 Ps et pd sont les dimensions efficace. Dans les champs PS et PD du
4082 lotrs, ce sont les dimensions telles qu'elles apparaissent dans le
4083 fichier Spice.
4084 Le passage de l'un à l'autre s'effectue à l'aide le la relation
4085 de la doc bsim4v30.pdf p 115.
4086 */
4087
4088 pd = pd * SCALE_X * 1.0e6 + lotrs->WIDTH ;
4089 }
4090 else
4091 pd = lotrs->PD<0?0:lotrs->PD;
4092 *pd_s = pd;
4093 }
4094
4095 if(elpGeneral[elpACM] == 1.0) {
4096 if (xs_s != NULL)
4097 *xs_s = elpDouble2Long((model->elpShrink[elpWMLT] * (double)SCALE_X)) ;
4098 if (xd_s != NULL)
4099 *xd_s = elpDouble2Long((model->elpShrink[elpWMLT] * (double)SCALE_X)) ;
4100 if (ps_s != NULL)
4101 *ps_s = w_s ;
4102 if (pd_s != NULL)
4103 *pd_s = w_s ;
4104 }
4105 }
4106
4107 return ;
4108 }
4109
4110 /****************************************************************************/
4111 /* fonction elpGetDeltaShrinkWidth */
4112 /****************************************************************************/
4113 elpFCT void elpGetDeltaShrinkWidth (lotrs,ptdeff,ptdactive,ptwmlt,transcase)
4114 struct lotrs *lotrs ;
4115 long *ptdeff;
4116 long *ptdactive;
4117 long *ptwmlt;
4118 int transcase;
4119 {
4120 long deltaw=0, dwa=0;
4121 double vdd;
4122 elpmodel_list *model;
4123
4124 vdd = elpGetVddFromCorner ( lotrs, transcase );
4125 model = elpGetModel(lotrs,vdd,transcase) ;
4126 if ( !model ) return;
4127
4128 if((lotrs->WIDTH == 0) || (lotrs->LENGTH == 0)){
4129 if (ptdeff != NULL)
4130 *ptdeff = 0 ;
4131 if (ptdactive != NULL)
4132 *ptdactive = 0 ;
4133 if (ptwmlt != NULL)
4134 *ptwmlt = 0 ;
4135 }else{
4136 if(model->elpTransModel == elpMOS) {
4137 deltaw = elpDouble2Long(model->elpShrink[elpDW] * (double)SCALE_X) ;
4138 dwa = elpDouble2Long(model->elpShrink[elpDWC] * (double)SCALE_X) ;
4139 }
4140 if (ptdeff != NULL)
4141 *ptdeff = deltaw;
4142 if (ptdactive != NULL)
4143 *ptdactive = dwa;
4144 if (ptwmlt != NULL)
4145 *ptwmlt = elpDouble2Long(model->elpShrink[elpWMLT]);
4146 }
4147
4148 return ;
4149 }
4150
4151 // Func : elpGetShrinkedLength
4152 // Obtient la longueur shrinkee d'un transistor
4153
4154 long elpGetShrinkedLength (lotrs_list *lotrs, elpmodel_list *model)
4155 {
4156 double deltal;
4157 long length_s = 0;
4158
4159 if (!lotrs || !model) return 0;
4160 if (lotrs->LENGTH == 0) return 0;
4161 if(model->elpTransModel == elpMOS)
4162 deltal = model->elpShrink[elpDL] * (double)SCALE_X ;
4163 length_s = elpDouble2Long((model->elpShrink[elpLMLT]*(double)lotrs->LENGTH + deltal)) ;
4164
4165 return length_s;
4166 }
4167
4168 // Func : elpGetShrinkedWidth
4169 // Obtient la largueur shrinkee d'un transistor
4170
4171 long elpGetShrinkedWidth (lotrs_list *lotrs, elpmodel_list *model)
4172 {
4173 double deltaw;
4174 long width_s = 0;
4175
4176 if (!lotrs || !model) return 0;
4177 if (lotrs->WIDTH == 0) return 0;
4178 if(model->elpTransModel == elpMOS)
4179 deltaw = model->elpShrink[elpDW] * (double)SCALE_X ;
4180 width_s = elpDouble2Long((model->elpShrink[elpWMLT]*(double)lotrs->WIDTH + deltaw)) ;
4181 return width_s;
4182 }
4183
4184 /****************************************************************************\
4185 FUNCTION : elp_lotrs_param_alloc
4186 \****************************************************************************/
4187 elp_lotrs_param *elp_lotrs_param_alloc ( void )
4188 {
4189 elp_lotrs_param *ptlotrs_param;
4190 int i;
4191
4192 ptlotrs_param = (elp_lotrs_param*) mbkalloc (sizeof (elp_lotrs_param));
4193
4194 for (i = 0 ; i < elpPARAMNUM ; i++)
4195 ptlotrs_param->PARAM[i] = ELPINITVALUE;
4196 for (i = 0 ; i < __MCC_LAST_SAVED ; i++)
4197 ptlotrs_param->MCC_SAVED[i] = ELPINITVALUE;
4198
4199 ptlotrs_param->VBULK = ELPINITVBULK;
4200 ptlotrs_param->ISVBSSET = 0;
4201 ptlotrs_param->longkey = NULL;
4202 return ptlotrs_param;
4203 }
4204
4205 /******************************************************************************\
4206 FUNCTION : elp_lotrs_param_free
4207 \******************************************************************************/
4208 void elp_lotrs_param_free (elp_lotrs_param *ptlotrs_param)
4209 {
4210 if (ptlotrs_param)
4211 {
4212 freechain(ptlotrs_param->longkey);
4213 mbkfree (ptlotrs_param);
4214 }
4215 }
4216
4217 /******************************************************************************\
4218 FUNCTION : elp_lotrs_param_create
4219
4220 Cree une structure d'instance avec des parametres specifiques si le transistor
4221 en comporte
4222 \******************************************************************************/
4223 elp_lotrs_param *elp_lotrs_param_create (lotrs_list *lotrs)
4224 {
4225 elp_lotrs_param *ptlotrs_param = NULL;
4226 float delvt0, mulu0,val;
4227 float sa, sb, sd, nf, vbulk;
4228 float sc, sca, scb, scc;
4229 int status;
4230
4231 ptlotrs_param = elp_lotrs_param_alloc ();
4232
4233 mulu0 = getlotrsparam (lotrs,MBK_MULU0,NULL,&status);
4234 if ( status == 1 )
4235 ptlotrs_param->PARAM[elpMULU0] = mulu0;
4236 else
4237 ptlotrs_param->PARAM[elpMULU0] = 1.0;
4238
4239 delvt0 = getlotrsparam (lotrs,MBK_DELVT0,NULL,&status);
4240 if ( status == 1 ) {
4241 ptlotrs_param->PARAM[elpDELVT0] = delvt0;
4242 }
4243 else
4244 ptlotrs_param->PARAM[elpDELVT0] = 0.0;
4245
4246 sa = getlotrsparam (lotrs,MBK_SA,NULL,&status);
4247 if ( status == 1 )
4248 ptlotrs_param->PARAM[elpSA] = sa;
4249
4250 sb = getlotrsparam (lotrs,MBK_SB,NULL,&status);
4251 if ( status == 1 )
4252 ptlotrs_param->PARAM[elpSB] = sb;
4253
4254 sd = getlotrsparam (lotrs,MBK_SD,NULL,&status);
4255 if ( status == 1 )
4256 ptlotrs_param->PARAM[elpSD] = sd;
4257
4258 sc = getlotrsparam (lotrs,MBK_SC,NULL,&status);
4259 if ( status == 1 )
4260 ptlotrs_param->PARAM[elpSC] = sc;
4261
4262 sca = getlotrsparam (lotrs,MBK_SCA,NULL,&status);
4263 if ( status == 1 )
4264 ptlotrs_param->PARAM[elpSCA] = sca;
4265
4266 scb = getlotrsparam (lotrs,MBK_SCB,NULL,&status);
4267 if ( status == 1 )
4268 ptlotrs_param->PARAM[elpSCB] = scb;
4269
4270 scc = getlotrsparam (lotrs,MBK_SCC,NULL,&status);
4271 if ( status == 1 )
4272 ptlotrs_param->PARAM[elpSCC] = scc;
4273
4274 nf = getlotrsparam (lotrs,MBK_NF,NULL,&status);
4275 if ( status == 1 )
4276 ptlotrs_param->PARAM[elpNF] = nf;
4277 else {
4278 nf = getlotrsparam (lotrs,MBK_NFING,NULL,&status);
4279 if ( status == 1 )
4280 ptlotrs_param->PARAM[elpNF] = nf;
4281 }
4282
4283 val = getlotrsparam (lotrs,MBK_M,NULL,&status);
4284 if ( status == 1 )
4285 ptlotrs_param->PARAM[elpM] = val;
4286 else
4287 val = getlotrsparam (lotrs,MBK_MULT,NULL,&status);
4288 if( status == 1 )
4289 ptlotrs_param->PARAM[elpM] = val;
4290 else
4291 ptlotrs_param->PARAM[elpM] = 1.0;
4292
4293 val = getlotrsparam (lotrs,MBK_NRS,NULL,&status);
4294 if ( status == 1 )
4295 ptlotrs_param->PARAM[elpNRS] = val;
4296
4297 val = getlotrsparam (lotrs,MBK_NRD,NULL,&status);
4298 if ( status == 1 )
4299 ptlotrs_param->PARAM[elpNRD] = val;
4300
4301 if ( lotrs->BULK && lotrs->BULK->SIG && getlosigalim(lotrs->BULK->SIG, &vbulk) )
4302 ptlotrs_param->VBULK = vbulk;
4303
4304 ptlotrs_param->ISVBSSET=0;
4305 ptlotrs_param->longkey=NULL;
4306 return ptlotrs_param;
4307 }
4308
4309 /****************************************************************************\
4310 FUNCTION : elp_lotrs_param_dup
4311 \****************************************************************************/
4312 elp_lotrs_param *elp_lotrs_param_dup ( elp_lotrs_param *src )
4313 {
4314 elp_lotrs_param *dest = NULL ;
4315
4316 if ( src ) {
4317 dest = (elp_lotrs_param*) mbkalloc (sizeof (elp_lotrs_param));
4318 memcpy(dest, src, sizeof(elp_lotrs_param));
4319 /* dest->PARAM[elpMULU0] = src->PARAM[elpMULU0];
4320 dest->PARAM[elpDELVT0] = src->PARAM[elpDELVT0];
4321 dest->PARAM[elpSA] = src->PARAM[elpSA];
4322 dest->PARAM[elpSB] = src->PARAM[elpSB];
4323 dest->PARAM[elpSD] = src->PARAM[elpSD];
4324 dest->PARAM[elpSC] = src->PARAM[elpSC];
4325 dest->PARAM[elpSCA] = src->PARAM[elpSCA];
4326 dest->PARAM[elpSCB] = src->PARAM[elpSCB];
4327 dest->PARAM[elpSCC] = src->PARAM[elpSCC];
4328 dest->PARAM[elpNF] = src->PARAM[elpNF];
4329 dest->PARAM[elpM] = src->PARAM[elpM];
4330 dest->PARAM[elpNRS] = src->PARAM[elpNRS];
4331 dest->PARAM[elpNRD] = src->PARAM[elpNRD];
4332 dest->VBULK = src->VBULK;
4333 dest->ISVBSSET = src->ISVBSSET ;
4334 dest->VBS = src->VBS ;*/
4335 dest->longkey = dupchainlst(src->longkey) ;
4336
4337 }
4338 return dest;
4339 }
4340
4341 /******************************************************************************\
4342 FUNCTION : elp_lotrs_param_get
4343
4344 \******************************************************************************/
4345 void elp_lotrs_param_get (lotrs_list *lotrs,
4346 double *ptmulu0,
4347 double *ptdelvt0,
4348 double *ptsa,
4349 double *ptsb,
4350 double *ptsd,
4351 double *ptnf,
4352 double *ptm,
4353 double *ptnrs,
4354 double *ptnrd,
4355 double *ptvbulk,
4356 double *ptsc,
4357 double *ptsca,
4358 double *ptscb,
4359 double *ptscc
4360 )
4361 {
4362 double delvt0, mulu0;
4363 double sa, sb, sd,nf;
4364 double sca, scb, scc, sc ;
4365 double val;
4366 float vbulk;
4367 int status;
4368
4369 if ( ptdelvt0 ) {
4370 delvt0 = getlotrsparam (lotrs,MBK_DELVT0,NULL,&status);
4371 if ( status == 1 )
4372 *ptdelvt0 = delvt0;
4373 else
4374 *ptdelvt0 = 0.0;
4375 }
4376 if ( ptmulu0 ) {
4377 mulu0 = getlotrsparam (lotrs,MBK_MULU0,NULL,&status);
4378 if ( status == 1 )
4379 *ptmulu0 = mulu0;
4380 else
4381 *ptmulu0 = 1.0;
4382 }
4383 if ( ptsa ) {
4384 sa = getlotrsparam (lotrs,MBK_SA,NULL,&status);
4385 if ( status == 1 )
4386 *ptsa = sa;
4387 else
4388 *ptsa = ELPINITVALUE;
4389 }
4390 if ( ptsb ) {
4391 sb = getlotrsparam (lotrs,MBK_SB,NULL,&status);
4392 if ( status == 1 )
4393 *ptsb = sb;
4394 else
4395 *ptsb = ELPINITVALUE;
4396 }
4397 if ( ptsd ) {
4398 sd = getlotrsparam (lotrs,MBK_SD,NULL,&status);
4399 if ( status == 1 )
4400 *ptsd = sd;
4401 else
4402 *ptsd = ELPINITVALUE;
4403 }
4404 if ( ptnf ) {
4405 nf = getlotrsparam (lotrs,MBK_NF,NULL,&status);
4406 if ( status == 1 )
4407 *ptnf = nf;
4408 else {
4409 nf = getlotrsparam (lotrs,MBK_NFING,NULL,&status);
4410 if ( status == 1 )
4411 *ptnf = nf;
4412 else
4413 *ptnf = 1.0;
4414 }
4415 }
4416 if ( ptm ) {
4417 val = getlotrsparam (lotrs,MBK_M,NULL,&status);
4418 if ( status == 1 )
4419 *ptm = val;
4420 else {
4421 val = getlotrsparam (lotrs,MBK_MULT,NULL,&status);
4422 if ( status == 1 )
4423 *ptm = val ;
4424 else
4425 *ptm = 1.0;
4426 }
4427 }
4428 if ( ptnrs ) {
4429 val = getlotrsparam (lotrs,MBK_NRS,NULL,&status);
4430 if ( status == 1 )
4431 *ptnrs = val;
4432 else
4433 *ptnrs = 0.0;
4434 }
4435 if ( ptnrd ) {
4436 val = getlotrsparam (lotrs,MBK_NRD,NULL,&status);
4437 if ( status == 1 )
4438 *ptnrd = val;
4439 else
4440 *ptnrd = 0.0;
4441 }
4442 if ( ptvbulk ) {
4443 if ( lotrs->BULK && lotrs->BULK->SIG && getlosigalim(lotrs->BULK->SIG, &vbulk) )
4444 *ptvbulk = vbulk;
4445 else {
4446 if ( MLO_IS_TRANSN(lotrs->TYPE ) )
4447 *ptvbulk = 0.0;
4448 else
4449 *ptvbulk = elpGeneral[elpGVDDMAX];
4450 }
4451 }
4452 if ( ptsc ) {
4453 sc = getlotrsparam (lotrs,MBK_SC,NULL,&status);
4454 if ( status == 1 )
4455 *ptsc = sc;
4456 else
4457 *ptsc = ELPINITVALUE;
4458 }
4459 if ( ptsca ) {
4460 sca = getlotrsparam (lotrs,MBK_SCA,NULL,&status);
4461 if ( status == 1 )
4462 *ptsca = sca;
4463 else
4464 *ptsca = ELPINITVALUE;
4465 }
4466 if ( ptscb ) {
4467 scb = getlotrsparam (lotrs,MBK_SCB,NULL,&status);
4468 if ( status == 1 )
4469 *ptscb = scb;
4470 else
4471 *ptscb = ELPINITVALUE;
4472 }
4473 if ( ptscc ) {
4474 scc = getlotrsparam (lotrs,MBK_SCC,NULL,&status);
4475 if ( status == 1 )
4476 *ptscc = scc;
4477 else
4478 *ptscc = ELPINITVALUE;
4479 }
4480 }
4481
4482 /****************************************************************************\
4483 FUNCTION : elp_is_valcomprise
4484 Renvoie 1 si la valeur est comprise dans l'intervalle definit
4485 par la precision definit entre 0 et 1
4486 Si la precision est < 0.0 , il faut une stricte egalitee
4487 \****************************************************************************/
4488 int elp_is_valcomprise ( long val1, long val2, double precision )
4489 {
4490 int res = 0;
4491 long min,max;
4492 long abs_val1;
4493 long abs_val2;
4494
4495 if ( precision < 0.0 ) {
4496 if ( val1 == val2 )
4497 res = 1;
4498 }
4499 else {
4500 abs_val1 = abs (val1);
4501 abs_val2 = abs (val2);
4502 min = elpDouble2Long (abs_val2 * (1.0 - precision));
4503 max = elpDouble2Long (abs_val2 * (1.0 + precision));
4504 if ( abs_val1 >= min && abs_val1 <= max )
4505 res = 1;
4506 }
4507 return res;
4508 }
4509
4510 /****************************************************************************\
4511 FUNCTION : elp_scale_vth
4512 \****************************************************************************/
4513 double elp_scale_vth ( lotrs_list *lotrs, elpmodel_list *model )
4514 {
4515 double delvt0;
4516 double vt,res,delta;
4517
4518 if ( lotrs && model ) {
4519 vt = model->elpModel[elpVT];
4520 res = vt;
4521 elp_lotrs_param_get (lotrs,NULL,&delvt0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
4522 if ( elpDouble2Long (SCALE_X*SCALE_X*delvt0) !=
4523 elpDouble2Long (SCALE_X*SCALE_X*model->elpModel[elpDELVT0]) ) {
4524 delta = delvt0 - model->elpModel[elpDELVT0];
4525 res = MLO_IS_TRANSN(lotrs->TYPE) ? vt + delta : vt - delta;
4526 }
4527 }
4528 return res;
4529 }
4530
4531 /****************************************************************************\
4532 FUNCTION : elp_scale_a
4533 \****************************************************************************/
4534 double elp_scale_a ( lotrs_list *lotrs, elpmodel_list *model )
4535 {
4536 double mulu0;
4537 double a,res,rap;
4538
4539 if ( lotrs && model ) {
4540 a = model->elpModel[elpA];
4541 res = a;
4542 elp_lotrs_param_get (lotrs,&mulu0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
4543 if ( elpDouble2Long (SCALE_X*SCALE_X*mulu0) !=
4544 elpDouble2Long (SCALE_X*SCALE_X*model->elpModel[elpMULU0]) ) {
4545 rap = mulu0 / model->elpModel[elpMULU0] ;
4546 res = a*rap;
4547 }
4548 }
4549 return res;
4550 }
4551
4552
4553 /****************************************************************************\
4554 FUNCTION : elpDriveModel
4555 \****************************************************************************/
4556 void elpDriveModel (char *filename, elpmodel_list *model)
4557 {
4558 FILE *file ;
4559
4560 sprintf(filename, "%s%s",filename,".elp") ;
4561 file = fopen(filename,"a") ;
4562 if(file == NULL) {
4563 fprintf(stderr, "elp error: can't open file %s to drive!!!\n",filename) ;
4564 return ;
4565 }
4566
4567 elpVerifModel(model) ;
4568 elpDriveOneModel (file, model);
4569
4570 if (fclose(file) != 0)
4571 avt_errmsg(ELP_ERRMSG, "003", AVT_ERROR, filename);
4572 // elpError(1003,filename) ;
4573 }
4574
4575 /****************************************************************************\
4576 FUNCTION : elpDriveModel
4577 \****************************************************************************/
4578 void elpDriveOneModel (FILE *file, elpmodel_list *model)
4579 {
4580 if ( !model ) return;
4581 if(model->elpTransIndex == elpNOINDEX)
4582 fprintf(file, "BEGIN %s\n\n",model->elpModelName) ;
4583 else
4584 fprintf(file, "BEGIN %s [%d]\n\n",model->elpModelName, model->elpTransIndex) ;
4585 fprintf(file, "#transistor identification\n") ;
4586 fprintf(file, "TECHNO = %d\n", model->elpTransTechno );
4587 if (model->elpTransType == elpNMOS)
4588 fprintf(file, "TYPE = NMOS\n\n") ;
4589 else if (model->elpTransType == elpPMOS)
4590 fprintf(file, "TYPE = PMOS\n\n") ;
4591 else
4592 fprintf(file, "TYPE = NMOS\n\n") ;
4593
4594 if (model->elpTransCase == elpTYPICAL) {
4595 fprintf(file, "#model for best, typical or worst case\n") ;
4596 fprintf(file, "CASE = TYPICAL\n\n") ;
4597 }
4598 if(model->elpTransCase != elpTYPICAL)
4599 {
4600 fprintf(file, "#model for best, typical or worst case\n") ;
4601 fprintf(file, "CASE = %s\n\n",(model->elpTransCase == elpWORST) ? "WORST" : "BEST") ;
4602 }
4603
4604 fprintf(file, "#voltage and temperature characteristics\n") ;
4605 fprintf(file, "VDDmax = %g\n", model->elpVoltage[elpVDDMAX]) ;
4606 fprintf(file, "VDEG = %g\n", model->elpVoltage[elpVDEG]) ;
4607 fprintf(file, "VTI = %g\n", model->elpVoltage[elpVTI]) ;
4608 fprintf(file, "VBULK = %g\n", model->elpVoltage[elpVBULK]) ;
4609 fprintf(file, "TEMP = %g\n\n", model->elpTemp) ;
4610
4611
4612 if((model->elpRange[elpLMIN] != (long)0) ||
4613 (model->elpRange[elpLMAX] != (long)ELPMAXLONG) ||
4614 (model->elpRange[elpWMIN] != (long)0) ||
4615 (model->elpRange[elpWMAX] != (long)ELPMAXLONG))
4616 fprintf(file, "#dimension range (micron)\n") ;
4617
4618 if(model->elpRange[elpLMIN] != (long)0)
4619 fprintf(file, "LMIN = %g\n",(double)model->elpRange[elpLMIN]/(double)SCALE_X) ;
4620 if(model->elpRange[elpLMAX] != (long)ELPMAXLONG)
4621 fprintf(file, "LMAX = %g\n", (double)model->elpRange[elpLMAX]/(double)SCALE_X) ;
4622 if(model->elpRange[elpWMIN] != (long)0)
4623 fprintf(file, "WMIN = %g\n", (double)model->elpRange[elpWMIN]/(double)SCALE_X) ;
4624 if(model->elpRange[elpWMAX] != (long)ELPMAXLONG)
4625 fprintf(file, "WMAX = %g\n\n", (double)model->elpRange[elpWMAX]/(double)SCALE_X) ;
4626
4627 fprintf(file, "#shrink parameters (micron)\n") ;
4628 fprintf(file, "DL = %g\n", model->elpShrink[elpDL]) ;
4629 fprintf(file, "DW = %g\n", model->elpShrink[elpDW]) ;
4630 fprintf(file, "DLC = %g\n", model->elpShrink[elpDLC]) ;
4631 fprintf(file, "DWC = %g\n", model->elpShrink[elpDWC]) ;
4632 fprintf(file, "DWCJ = %g\n\n", model->elpShrink[elpDWCJ]) ;
4633
4634 fprintf(file, "#mult factor on dimension\n") ;
4635 fprintf(file, "LMLT = %g\n", model->elpShrink[elpLMLT]) ;
4636 fprintf(file, "WMLT = %g\n\n", model->elpShrink[elpWMLT]) ;
4637
4638 fprintf(file, "#transistor characteristics\n") ;
4639 fprintf(file, "VT = %g\n", model->elpModel[elpVT]) ;
4640 fprintf(file, "VT0 = %g\n", model->elpModel[elpVT0]) ;
4641 fprintf(file, "KT = %g\n", model->elpModel[elpKT]) ;
4642 fprintf(file, "A = %g\n", model->elpModel[elpA]) ;
4643 fprintf(file, "B = %g\n", model->elpModel[elpB]) ;
4644 fprintf(file, "RT = %g\n", model->elpModel[elpRT]) ;
4645 fprintf(file, "KRT = %g\n", model->elpModel[elpKRT]) ;
4646 fprintf(file, "RS = %g\n", model->elpModel[elpRS]) ;
4647 fprintf(file, "KRS = %g\n", model->elpModel[elpKRS]) ;
4648 fprintf(file, "KS = %g\n", model->elpModel[elpKS]) ;
4649 fprintf(file, "KR = %g\n", model->elpModel[elpKR]) ;
4650 if ( model->elpModel[elpSA] > ELPMINVALUE )
4651 fprintf(file, "SA = %g\n", model->elpModel[elpSA]);
4652 if ( model->elpModel[elpSB] > ELPMINVALUE )
4653 fprintf(file, "SB = %g\n", model->elpModel[elpSB]);
4654 if ( model->elpModel[elpSD] > ELPMINVALUE )
4655 fprintf(file, "SD = %g\n", model->elpModel[elpSD]);
4656 if ( model->elpModel[elpSC] > ELPMINVALUE )
4657 fprintf(file, "SC = %g\n", model->elpModel[elpSC]);
4658 if ( model->elpModel[elpSCA] > ELPMINVALUE )
4659 fprintf(file, "SCA = %g\n", model->elpModel[elpSCA]);
4660 if ( model->elpModel[elpSCB] > ELPMINVALUE )
4661 fprintf(file, "SCB = %g\n", model->elpModel[elpSCB]);
4662 if ( model->elpModel[elpSCC] > ELPMINVALUE )
4663 fprintf(file, "SCC = %g\n", model->elpModel[elpSCC]);
4664 if ( model->elpModel[elpNF] > ELPMINVALUE )
4665 fprintf(file, "NF = %g\n", model->elpModel[elpNF]);
4666 if ( model->elpModel[elpNRS] > ELPMINVALUE )
4667 fprintf(file, "NRS = %g\n", model->elpModel[elpNRS]);
4668 if ( model->elpModel[elpNRD] > ELPMINVALUE )
4669 fprintf(file, "NRD = %g\n", model->elpModel[elpNRD]);
4670 fprintf(file, "M = %g\n", model->elpModel[elpM]) ;
4671 fprintf(file, "MULU0 = %g\n", model->elpModel[elpMULU0]) ;
4672 fprintf(file, "DELVT0 = %g\n\n", model->elpModel[elpDELVT0]) ;
4673
4674 fprintf(file, "#dynamic capacitance: grid capacitance (in pF/u and pF/u2)\n") ;
4675 fprintf(file, "CGS = %g\n", model->elpCapa[elpCGS]) ;
4676 fprintf(file, "CGS0 = %g\n", model->elpCapa[elpCGS0]) ;
4677 fprintf(file, "CGSU = %g\n", model->elpCapa[elpCGSU]) ;
4678 fprintf(file, "CGSUF = %g\n", model->elpCapa[elpCGSUF]) ;
4679 fprintf(file, "CGSU0 = %g\n", model->elpCapa[elpCGSU0]) ;
4680 fprintf(file, "CGSUMIN = %g\n", model->elpCapa[elpCGSUMIN]) ;
4681 fprintf(file, "CGSUMAX = %g\n", model->elpCapa[elpCGSUMAX]) ;
4682 fprintf(file, "CGSD = %g\n", model->elpCapa[elpCGSD]) ;
4683 fprintf(file, "CGSDF = %g\n", model->elpCapa[elpCGSDF]) ;
4684 fprintf(file, "CGSD0 = %g\n", model->elpCapa[elpCGSD0]) ;
4685 fprintf(file, "CGSDMIN = %g\n", model->elpCapa[elpCGSDMIN]) ;
4686 fprintf(file, "CGSDMAX = %g\n", model->elpCapa[elpCGSDMAX]) ;
4687 fprintf(file, "CGP = %g\n", model->elpCapa[elpCGP]) ;
4688 fprintf(file, "CGPUMIN = %g\n", model->elpCapa[elpCGPUMIN]) ;
4689 fprintf(file, "CGPUMAX = %g\n", model->elpCapa[elpCGPUMAX]) ;
4690 fprintf(file, "CGPDMIN = %g\n", model->elpCapa[elpCGPDMIN]) ;
4691 fprintf(file, "CGPDMAX = %g\n", model->elpCapa[elpCGPDMAX]) ;
4692 fprintf(file, "CGD = %g\n", model->elpCapa[elpCGD]) ;
4693 fprintf(file, "CGD0 = %g\n", model->elpCapa[elpCGD0]) ;
4694 fprintf(file, "CGD1 = %g\n", model->elpCapa[elpCGD1]) ;
4695 fprintf(file, "CGD2 = %g\n", model->elpCapa[elpCGD2]) ;
4696 fprintf(file, "CGDC = %g\n", model->elpCapa[elpCGDC]) ;
4697 fprintf(file, "CGDC0 = %g\n", model->elpCapa[elpCGDC0]) ;
4698 fprintf(file, "CGDC1 = %g\n", model->elpCapa[elpCGDC1]) ;
4699 fprintf(file, "CGDC2 = %g\n", model->elpCapa[elpCGDC2]) ;
4700 fprintf(file, "CGSI = %g\n", model->elpCapa[elpCGSI]) ;
4701 fprintf(file, "CGSIC = %g\n\n", model->elpCapa[elpCGSIC]) ;
4702
4703 fprintf(file, "#dynamic capacitance: drain capacitance (in pF/u and pF/u2)\n") ;
4704 fprintf(file, "CDS = %g\n", model->elpCapa[elpCDS]) ;
4705 fprintf(file, "CDSU = %g\n", model->elpCapa[elpCDSU]) ;
4706 fprintf(file, "CDSD = %g\n", model->elpCapa[elpCDSD]) ;
4707 fprintf(file, "CDP = %g\n", model->elpCapa[elpCDP]) ;
4708 fprintf(file, "CDPU = %g\n", model->elpCapa[elpCDPU]) ;
4709 fprintf(file, "CDPD = %g\n", model->elpCapa[elpCDPD]) ;
4710 fprintf(file, "CDW = %g\n", model->elpCapa[elpCDW]) ;
4711 fprintf(file, "CDWU = %g\n", model->elpCapa[elpCDWU]) ;
4712 fprintf(file, "CDWD = %g\n", model->elpCapa[elpCDWD]) ;
4713
4714 fprintf(file, "#dynamic capacitance: source capacitance (in pF/u and pF/u2)\n") ;
4715 fprintf(file, "CSS = %g\n", model->elpCapa[elpCSS]) ;
4716 fprintf(file, "CSSU = %g\n", model->elpCapa[elpCSSU]) ;
4717 fprintf(file, "CSSD = %g\n", model->elpCapa[elpCSSD]) ;
4718 fprintf(file, "CSP = %g\n", model->elpCapa[elpCSP]) ;
4719 fprintf(file, "CSPU = %g\n", model->elpCapa[elpCSPU]) ;
4720 fprintf(file, "CSPD = %g\n", model->elpCapa[elpCSPD]) ;
4721 fprintf(file, "CSW = %g\n", model->elpCapa[elpCSW]) ;
4722 fprintf(file, "CSWU = %g\n", model->elpCapa[elpCSWU]) ;
4723 fprintf(file, "CSWD = %g\n\n", model->elpCapa[elpCSWD]) ;
4724
4725 fprintf(file, "#access resistance (in ohm)\n");
4726 fprintf(file, "RACCS = %g\n", model->elpRacc[elpRACCS]) ;
4727 fprintf(file, "RACCD = %g\n", model->elpRacc[elpRACCD]) ;
4728
4729 if(model->elpTransIndex == elpNOINDEX)
4730 fprintf(file, "END %s\n\n",model->elpModelName) ;
4731 else
4732 fprintf(file, "END %s [%d]\n\n",model->elpModelName, model->elpTransIndex) ;
4733 }
4734
4735 /*******************************************************************************
4736 * function elp_getlotrsalim *
4737 *******************************************************************************/
4738 double elpCalcIleakage( lotrs_list *lotrs,
4739 int lotrstype,
4740 int transcase,
4741 double vgs, double vds, double vbs,
4742 double *BLeak, double *DLeak, double *SLeak
4743 )
4744 {
4745 double vdd;
4746 long xs_s,ps_s,xd_s,pd_s;
4747 double AD,PD,AS,PS;
4748 double Ileak=0.0,w;
4749 elpmodel_list *model ;
4750 elp_lotrs_param *ptlotrs_param;
4751
4752 vdd = elpGetVddFromCorner ( lotrs, transcase );
4753 model = elpGetModel(lotrs,vdd,transcase) ;
4754 if (!model) return 0.0;
4755
4756 elpLotrsGetShrinkDim(lotrs,NULL,NULL,
4757 &xs_s,&xd_s,&ps_s,&pd_s,
4758 NULL,NULL, transcase);
4759
4760 ptlotrs_param = elp_lotrs_param_create (lotrs);
4761
4762 if(lotrs->WIDTH == 0)
4763 w = ((double)lotrs->PS / (double)4.0) ;
4764 else
4765 w = (double)elpGetShrinkedWidth(lotrs,model);
4766
4767 AD = (double)xd_s*w / (double)(SCALE_X*SCALE_X);
4768 AS = (double)xs_s*w / (double)(SCALE_X*SCALE_X);
4769 PD = pd_s / (double)SCALE_X;
4770 PS = ps_s / (double)SCALE_X;
4771
4772 Ileak = elpCalcIleak(getlotrsmodel(lotrs), lotrstype,
4773 (double)lotrs->LENGTH/(double)(SCALE_X),
4774 (double)lotrs->WIDTH/(double)(SCALE_X),
4775 lotrs, transcase,
4776 vgs, vds, vbs,
4777 AD,PD,AS,PS,
4778 BLeak,DLeak,SLeak,
4779 ptlotrs_param) ;
4780
4781 elp_lotrs_param_free (ptlotrs_param);
4782
4783 return Ileak;
4784 }
4785
4786 int elpHack_GetNodeLocon( locon_list *locon )
4787 {
4788 int node ;
4789
4790 if( !locon->SIG->PRCN )
4791 addlorcnet( locon->SIG );
4792
4793 node = -1 ;
4794 if( locon->PNODE )
4795 node = locon->PNODE->DATA ;
4796
4797 if( node < 0 ) {
4798 if( locon->SIG->PRCN->PWIRE )
4799 node = locon->SIG->PRCN->PWIRE->NODE1 ;
4800 }
4801
4802 if( node < 0 ) {
4803 if( locon->SIG->PRCN->PCTC )
4804 node = rcn_ctcnode( (loctc_list*)(locon->SIG->PRCN->PCTC->DATA), locon->SIG );
4805 }
4806
4807 if( node < 0 ) {
4808 node = 1 ;
4809 setloconnode( locon, node );
4810 }
4811
4812 return node ;
4813 }
4814
4815 void elpHack_AddCapa( lotrs_list *lotrs, losig_list *vss, char where, float capa )
4816 {
4817 locon_list *locon ;
4818 int node ;
4819
4820 switch( where ) {
4821 case 'g' :
4822 locon = lotrs->GRID ;
4823 break ;
4824 case 's' :
4825 locon = lotrs->SOURCE ;
4826 break ;
4827 case 'd' :
4828 locon = lotrs->DRAIN ;
4829 break ;
4830 }
4831
4832 if( locon->SIG == vss )
4833 return ;
4834
4835 node = elpHack_GetNodeLocon( locon );
4836
4837 addloctc( locon->SIG, node, vss, 1, capa*V_FLOAT_TAB[__AVT_HACK_COEF_CGND].VALUE );
4838 }
4839
4840 void elpHack_AddCtcCapa( locon_list *locon1, locon_list *locon2, float capa )
4841 {
4842 int node1 ;
4843 int node2 ;
4844
4845 if( !locon1->SIG->PRCN )
4846 addlorcnet( locon1->SIG );
4847
4848 node1 = elpHack_GetNodeLocon( locon1 );
4849 node2 = elpHack_GetNodeLocon( locon2 );
4850
4851 addloctc( locon1->SIG, node1, locon2->SIG, node2, capa*V_FLOAT_TAB[__AVT_HACK_COEF_CCTK].VALUE );
4852 }
4853
4854 void elpHackNetlistResi( lofig_list *lofig )
4855 {
4856 losig_list *losig ;
4857 locon_list *locon ;
4858 chain_list *chain ;
4859 ptype_list *ptl ;
4860 loctc_list *loctc ;
4861
4862 for( losig = lofig->LOSIG ; losig ; losig = losig->NEXT ) {
4863
4864 if( losig->PRCN ) {
4865
4866 freetable( losig );
4867
4868 /* remove all resistance */
4869 while( losig->PRCN->PWIRE )
4870 dellowire( losig, losig->PRCN->PWIRE->NODE1, losig->PRCN->PWIRE->NODE2 );
4871
4872 /* set all locon to node 1 */
4873 ptl = getptype( losig->USER, LOFIGCHAIN );
4874 if( ptl ) {
4875 for( chain = (chain_list*)ptl->DATA ; chain ; chain = chain->NEXT ) {
4876 locon = (locon_list*)chain->DATA ;
4877 while( locon->PNODE )
4878 delloconnode( locon, locon->PNODE->DATA );
4879 freenum( locon->PNODE );
4880 setloconnode( locon, 1 );
4881 }
4882 }
4883
4884 /* set all capacitance node to 1 */
4885 for( chain = losig->PRCN->PCTC ; chain ; chain = chain->NEXT ) {
4886 loctc = (loctc_list*)chain->DATA ;
4887 rcn_ctcnode_set( loctc, losig, 1 );
4888 }
4889 }
4890 }
4891 }
4892
4893 void elpHackNetlistCapa( lofig_list *hackedlofig, int whatjob )
4894 {
4895 losig_list *sig_vss ;
4896 losig_list *sig_vss_backup ;
4897 losig_list *sig_vdd ;
4898 losig_list *sig_vdd_backup ;
4899 losig_list *sig_supply ;
4900 losig_list *losig ;
4901 lotrs_list *lotrs ;
4902 float vdd ;
4903 elpmodel_list *elpmodel ;
4904 long la ;
4905 long wa ;
4906 float cs ;
4907 float cd ;
4908 float cgi ;
4909 float cdi ;
4910 float csi ;
4911 float cgs ;
4912 float cgd ;
4913 ptype_list *ptl ;
4914
4915 sig_vss = NULL ;
4916 sig_vdd = NULL ;
4917 sig_vss_backup = NULL ;
4918 sig_vdd_backup = NULL ;
4919
4920 for( losig = hackedlofig->LOSIG ; losig ; losig = losig->NEXT ) {
4921 if( mbk_LosigIsVSS( losig ) ) {
4922 if( losig->PRCN && losig->PRCN->PCTC )
4923 sig_vss = losig ;
4924 else {
4925 ptl = getptype( losig->USER, LOFIGCHAIN );
4926 if( ptl && ptl->DATA )
4927 sig_vss_backup = losig ;
4928 }
4929 }
4930 if( mbk_LosigIsVDD( losig ) ) {
4931 if( losig->PRCN && losig->PRCN->PCTC )
4932 sig_vdd = losig ;
4933 else {
4934 ptl = getptype( losig->USER, LOFIGCHAIN );
4935 if( ptl && ptl->DATA )
4936 sig_vdd_backup = losig ;
4937 }
4938 }
4939 }
4940
4941 if( !sig_vss )
4942 sig_vss = sig_vss_backup ;
4943 if( !sig_vdd )
4944 sig_vdd = sig_vdd_backup ;
4945
4946 if( !sig_vss || !sig_vdd ) {
4947 printf( "can't find supply signal !\n" );
4948 exit(0);
4949 }
4950
4951 for( lotrs = hackedlofig->LOTRS ; lotrs ; lotrs = lotrs->NEXT ) {
4952
4953 if( MLO_IS_TRANSN( lotrs->TYPE ) )
4954 sig_supply = sig_vss ;
4955 else
4956 sig_supply = sig_vdd ;
4957
4958 vdd = elpGetVddFromCorner( lotrs, elpTYPICAL ) ;
4959 elpmodel = elpGetModel( lotrs, vdd, elpTYPICAL ) ;
4960
4961 cs = elpLotrsCapaSource( lotrs, ELP_CAPA_TYPICAL, elpTYPICAL );
4962 cd = elpLotrsCapaDrain( lotrs, ELP_CAPA_TYPICAL, elpTYPICAL );
4963
4964 la = elpShrinkSize( elpGetShrinkedLength( lotrs, elpmodel ), -elpmodel->elpShrink[elpDL], 1.0 ) ;
4965 la = elpShrinkSize( la, elpmodel->elpShrink[elpDLC], 1.0 ) ;
4966 wa = elpShrinkSize( elpGetShrinkedWidth( lotrs, elpmodel ), -elpmodel->elpShrink[elpDW], 1.0 ) ;
4967 wa = elpShrinkSize( wa, elpmodel->elpShrink[elpDWC], 1.0 ) ;
4968
4969 cdi = elpmodel->elpCapa[ elpCGD ] * ((double)wa) * ((double)la) / ((double)(SCALE_X*SCALE_X)) ;
4970 csi = elpmodel->elpCapa[ elpCGSI ] * ((double)wa) * ((double)la) / ((double)(SCALE_X*SCALE_X)) ;
4971 cgi = elpmodel->elpCapa[ elpCGS ] * ((double)wa) * ((double)la) / ((double)(SCALE_X*SCALE_X)) ;
4972 cgs = elpmodel->elpCapa[ elpCGP ] * ((double)wa) / ((double)SCALE_X) ;
4973 cgd = elpmodel->elpCapa[ elpCGP ] * ((double)wa) / ((double)SCALE_X) ;
4974
4975 elpHack_AddCapa( lotrs, sig_supply, 's', cs-cgs );
4976 elpHack_AddCapa( lotrs, sig_supply, 'd', cd-cgd );
4977
4978 elpHack_AddCapa( lotrs, sig_supply, 'g', cgi );
4979
4980 if( whatjob == ELP_HACK_FIX_CAPA_TO_GND ) {
4981
4982 elpHack_AddCapa( lotrs, sig_supply, 's', cgs+csi );
4983 elpHack_AddCapa( lotrs, sig_supply, 'g', cgs+csi );
4984
4985 elpHack_AddCapa( lotrs, sig_supply, 'd', cgd+cdi );
4986 elpHack_AddCapa( lotrs, sig_supply, 'g', cgd+cdi );
4987 }
4988 else {
4989
4990 if( lotrs->GRID != lotrs->DRAIN )
4991 elpHack_AddCtcCapa( lotrs->GRID, lotrs->DRAIN, cgd+cdi );
4992
4993 if( lotrs->GRID != lotrs->SOURCE )
4994 elpHack_AddCtcCapa( lotrs->GRID, lotrs->SOURCE, cgs+csi );
4995 }
4996 }
4997 }
4998