1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : ELP Verison 1 */
6 /* Fichier : elp_util.c */
8 /* (c) copyright 1991-1995 Laboratoire MASI equipe CAO & VLSI */
9 /* Tous droits reserves */
10 /* Support : e-mail cao-vlsi@masi.ibp.fr */
12 /* Auteur(s) : Payam KIANI */
14 /****************************************************************************/
15 /* caracterisation electrique des netlists en fonction des parametres elp */
16 /****************************************************************************/
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;
35 //int ELP_DRV_FILE = 0;
36 int ELP_GENPARAM
= 0 ;
37 int ELP_LOAD_FILE_TYPE
= ELP_LOADELP_FILE
;
38 char *elpoldtechnofilename
= NULL
;
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*);
54 char *elpTabTechnoName
[] = { "No techno", "Bsim3v3", "Bsim4", "Psp", "Mos2", "MM9" };
56 /****************************************************************************\
57 FUNCTION : elpSameSD_sig
58 \****************************************************************************/
59 int elpSameSD_sig ( lotrs_list
*lotrs
)
62 int vddsource
=0, vsssource
=0, vdddrain
=0, vssdrain
=0 ;
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;
69 if ( (lotrs
->DRAIN
->SIG
== lotrs
->SOURCE
->SIG
) ||
70 ( vdddrain
&& vddsource
) ||
71 ( vssdrain
&& vsssource
)
77 /****************************************************************************\
78 FUNCTION : elpGetVddFromCorner
79 \****************************************************************************/
80 double elpGetVddFromCorner ( lotrs_list
*lotrs
, int corner
)
85 if(cns_getlotrsalim(lotrs
, 'M', &alim
)){
89 case elpBEST
: vdd
= elpGeneral
[elpGVDDBEST
];
91 case elpWORST
: vdd
= elpGeneral
[elpGVDDWORST
];
93 default : vdd
= elpGeneral
[elpGVDDMAX
];
100 /*****************************************************************************/
101 /* function elpDouble2Int */
102 /*****************************************************************************/
103 elpFCT
int elpDouble2Int ( value
)
106 return (int)(value
+0.5);
109 /*****************************************************************************/
110 /* function elpDouble2Long */
111 /*****************************************************************************/
112 elpFCT
long elpDouble2Long (value
)
115 return (long)(value
+0.5);
118 /*****************************************************************************/
119 /* function elpShrinkSize() */
120 /*****************************************************************************/
121 elpFCT
long elpShrinkSize(size
,delta
,mlt
)
127 if((size
== 0) || (size
== ELPMAXLONG
))
129 delta
= delta
* (double)SCALE_X
;
130 size
= elpDouble2Long(mlt
*(double)size
+ delta
) ;
134 /*****************************************************************************/
135 /* function elpAddTree() */
136 /*****************************************************************************/
138 void elp_get_key(lotrs_list
*lt
, chain_list
**longkey
)
142 if (lt
!=NULL
&& (pt
=getptype(lt
->USER
, MCC_COMPUTED_KEY
))!=NULL
)
143 *longkey
=(chain_list
*)pt
->DATA
;
146 int elp_is_same_paramcontext(chain_list
*longkey0
, chain_list
*longkey1
)
148 while (longkey0
!=NULL
&& longkey1
!=NULL
&& mbk_cmpdouble(*(float *)&longkey0
->DATA
,*(float *)&longkey1
->DATA
, EQT_PRECISION
)==0)
150 longkey0
=longkey0
->NEXT
;
151 longkey1
=longkey1
->NEXT
;
153 if (longkey0
!=NULL
|| longkey1
!=NULL
) return 0;
157 elpFCT elptree_list
*elpAddTree(head
,model
,level
)
159 elpmodel_list
*model
;
163 long mulu0
,delvt0
,sa
,sb
,sd
,nf
,val
;
166 tree
= (elptree_list
*)mbkalloc(sizeof(elptree_list
)) ;
167 tree
->LEVEL
= level
;
173 case elpNameLevel
: tree
->DATA1
= (long)model
->elpModelName
;
174 tree
->DATA2
= (long)model
->elpModelNameAlias
;
176 case elpLengthLevel
:
177 tree
->DATA1
= model
->elpRange
[elpLMIN
] ;
178 tree
->DATA2
= model
->elpRange
[elpLMAX
] ;
181 tree
->DATA1
= model
->elpRange
[elpWMIN
] ;
182 tree
->DATA2
= model
->elpRange
[elpWMAX
] ;
184 case elpVDDLevel
: tree
->DATA1
= elpDouble2Long(model
->elpVoltage
[elpVDDMAX
]*SCALE_X
) ;
185 tree
->DATA2
= (long)NULL
;
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
;
192 mulu0
= elpDouble2Long(model
->elpModel
[elpMULU0
]*ELPPRECISION
) ;
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
);
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
);
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
;
208 delvt0
= elpDouble2Long (model
->elpModel
[elpDELVT0
]*ELPPRECISION
);
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
);
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
);
219 case elpSALevel
: if ( model
->elpModel
[elpSA
] < ELPMINVALUE
) {
220 tree
->DATA1
= (long)NULL
;
221 tree
->DATA2
= (long)NULL
;
224 if ( V_FLOAT_TAB
[__ELP_SA_MARGIN
].VALUE
< 0.0 ) {
225 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSA
]*ELPPRECISION2
);
226 tree
->DATA2
= (long)NULL
;
229 sa
= elpDouble2Long (model
->elpModel
[elpSA
]*ELPPRECISION2
);
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
);
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
);
241 case elpSBLevel
: if ( model
->elpModel
[elpSB
] < ELPMINVALUE
) {
242 tree
->DATA1
= (long)NULL
;
243 tree
->DATA2
= (long)NULL
;
246 if ( V_FLOAT_TAB
[__ELP_SB_MARGIN
].VALUE
< 0.0 ) {
247 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSB
]*ELPPRECISION2
);
248 tree
->DATA2
= (long)NULL
;
251 sb
= elpDouble2Long (model
->elpModel
[elpSB
]*ELPPRECISION2
);
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
);
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
);
263 case elpSDLevel
: if ( model
->elpModel
[elpSD
] < ELPMINVALUE
) {
264 tree
->DATA1
= (long)NULL
;
265 tree
->DATA2
= (long)NULL
;
268 if ( V_FLOAT_TAB
[__ELP_SD_MARGIN
].VALUE
< 0.0 ) {
269 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSD
]*ELPPRECISION2
);
270 tree
->DATA2
= (long)NULL
;
273 sd
= elpDouble2Long (model
->elpModel
[elpSD
]*ELPPRECISION2
);
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
);
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
);
285 case elpNFLevel
: if ( model
->elpModel
[elpNF
] < ELPMINVALUE
) {
286 tree
->DATA1
= (long)NULL
;
287 tree
->DATA2
= (long)NULL
;
290 if ( ELP_NF_MARGIN
< 0.0 ) {
291 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpNF
]);
292 tree
->DATA2
= (long)NULL
;
295 nf
= elpDouble2Long (model
->elpModel
[elpNF
]);
297 tree
->DATA1
= elpDouble2Long((1.0 - ELP_NF_MARGIN
) * nf
);
298 tree
->DATA2
= elpDouble2Long((1.0 + ELP_NF_MARGIN
) * nf
);
301 tree
->DATA1
= elpDouble2Long((1.0 + ELP_NF_MARGIN
) * nf
);
302 tree
->DATA2
= elpDouble2Long((1.0 - ELP_NF_MARGIN
) * nf
);
307 case elpMLevel
: if ( model
->elpModel
[elpM
] < ELPMINVALUE
) {
308 tree
->DATA1
= (long)NULL
;
309 tree
->DATA2
= (long)NULL
;
312 if ( ELP_M_MARGIN
< 0.0 ) {
313 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpM
]);
314 tree
->DATA2
= (long)NULL
;
317 val
= elpDouble2Long (model
->elpModel
[elpM
]);
319 tree
->DATA1
= elpDouble2Long((1.0 - ELP_M_MARGIN
) * val
);
320 tree
->DATA2
= elpDouble2Long((1.0 + ELP_M_MARGIN
) * val
);
323 tree
->DATA1
= elpDouble2Long((1.0 + ELP_M_MARGIN
) * val
);
324 tree
->DATA2
= elpDouble2Long((1.0 - ELP_M_MARGIN
) * val
);
329 case elpNRSLevel
: if ( model
->elpModel
[elpNRS
] < ELPMINVALUE
) {
330 tree
->DATA1
= (long)NULL
;
331 tree
->DATA2
= (long)NULL
;
334 if ( ELP_M_MARGIN
< 0.0 ) {
335 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpNRS
]*ELPPRECISION
);
336 tree
->DATA2
= (long)NULL
;
339 val
= elpDouble2Long (model
->elpModel
[elpNRS
]*ELPPRECISION
);
341 tree
->DATA1
= elpDouble2Long((1.0 - ELP_NRS_MARGIN
) * val
);
342 tree
->DATA2
= elpDouble2Long((1.0 + ELP_NRS_MARGIN
) * val
);
345 tree
->DATA1
= elpDouble2Long((1.0 + ELP_NRS_MARGIN
) * val
);
346 tree
->DATA2
= elpDouble2Long((1.0 - ELP_NRS_MARGIN
) * val
);
351 case elpNRDLevel
: if ( model
->elpModel
[elpNRD
] < ELPMINVALUE
) {
352 tree
->DATA1
= (long)NULL
;
353 tree
->DATA2
= (long)NULL
;
356 if ( ELP_M_MARGIN
< 0.0 ) {
357 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpNRD
]*ELPPRECISION
);
358 tree
->DATA2
= (long)NULL
;
361 val
= elpDouble2Long (model
->elpModel
[elpNRD
]*ELPPRECISION
);
363 tree
->DATA1
= elpDouble2Long((1.0 - ELP_NRD_MARGIN
) * val
);
364 tree
->DATA2
= elpDouble2Long((1.0 + ELP_NRD_MARGIN
) * val
);
367 tree
->DATA1
= elpDouble2Long((1.0 + ELP_NRD_MARGIN
) * val
);
368 tree
->DATA2
= elpDouble2Long((1.0 - ELP_NRD_MARGIN
) * val
);
373 case elpSCLevel
: if ( model
->elpModel
[elpSC
] < ELPMINVALUE
) {
374 tree
->DATA1
= (long)NULL
;
375 tree
->DATA2
= (long)NULL
;
378 if ( V_FLOAT_TAB
[__ELP_SC_MARGIN
].VALUE
< 0.0 ) {
379 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSC
]*ELPPRECISION2
);
380 tree
->DATA2
= (long)NULL
;
383 sc
= elpDouble2Long (model
->elpModel
[elpSC
]*ELPPRECISION2
);
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
);
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
);
395 case elpSCALevel
: if ( model
->elpModel
[elpSCA
] < ELPMINVALUE
) {
396 tree
->DATA1
= (long)NULL
;
397 tree
->DATA2
= (long)NULL
;
400 if ( V_FLOAT_TAB
[__ELP_SCA_MARGIN
].VALUE
< 0.0 ) {
401 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSCA
]*ELPPRECISION2
);
402 tree
->DATA2
= (long)NULL
;
405 sca
= elpDouble2Long (model
->elpModel
[elpSCA
]*ELPPRECISION2
);
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
);
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
);
417 case elpSCBLevel
: if ( model
->elpModel
[elpSCB
] < ELPMINVALUE
) {
418 tree
->DATA1
= (long)NULL
;
419 tree
->DATA2
= (long)NULL
;
422 if ( V_FLOAT_TAB
[__ELP_SCB_MARGIN
].VALUE
< 0.0 ) {
423 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSCB
]*ELPPRECISION2
);
424 tree
->DATA2
= (long)NULL
;
427 scb
= elpDouble2Long (model
->elpModel
[elpSCB
]*ELPPRECISION2
);
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
);
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
);
439 case elpSCCLevel
: if ( model
->elpModel
[elpSCC
] < ELPMINVALUE
) {
440 tree
->DATA1
= (long)NULL
;
441 tree
->DATA2
= (long)NULL
;
444 if ( V_FLOAT_TAB
[__ELP_SCC_MARGIN
].VALUE
< 0.0 ) {
445 tree
->DATA1
= elpDouble2Long (model
->elpModel
[elpSCC
]*ELPPRECISION2
);
446 tree
->DATA2
= (long)NULL
;
449 sca
= elpDouble2Long (model
->elpModel
[elpSCC
]*ELPPRECISION2
);
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
);
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
);
461 case elpVBULKLevel
: tree
->DATA1
= elpDouble2Long(model
->elpVoltage
[elpVBULK
]*SCALE_X
) ;
462 tree
->DATA2
= (long)NULL
;
464 case elpParamContextLevel
:
465 tree
->DATA1
= (long)model
->longkey
;
466 tree
->DATA2
= (long)NULL
;
468 case elpCaseLevel
: tree
->DATA1
= (long)model
->elpTransCase
;
469 tree
->DATA2
= (long)NULL
;
476 /*****************************************************************************/
477 /* function elpCmpTreeModel() */
478 /*****************************************************************************/
479 elpFCT
int elpCmpTreeModel(tree
,model
,level
)
481 elpmodel_list
*model
;
485 long mulu0
,delvt0
,sa
,sb
,sd
,nf
,val
,sc
,sca
,scb
,scc
;
489 case elpNameLevel
: if(tree
->DATA1
== (long)model
->elpModelName
)
492 case elpLengthLevel
:
493 if((tree
->DATA1
== model
->elpRange
[elpLMIN
]) &&
494 (tree
->DATA2
== model
->elpRange
[elpLMAX
]))
498 if((tree
->DATA1
== model
->elpRange
[elpWMIN
]) &&
499 (tree
->DATA2
== model
->elpRange
[elpWMAX
]))
502 case elpVDDLevel
: if(tree
->DATA1
== elpDouble2Long (model
->elpVoltage
[elpVDDMAX
]*SCALE_X
))
505 case elpMULU0Level
: if ( V_FLOAT_TAB
[__ELP_MULU0_MARGIN
].VALUE
< 0.0 ) {
506 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpMULU0
]*ELPPRECISION
))
510 mulu0
= elpDouble2Long (model
->elpModel
[elpMULU0
]*ELPPRECISION
);
511 if ( mulu0
>= tree
->DATA1
&& mulu0
<= tree
->DATA2
)
515 case elpDELVT0Level
: if ( V_FLOAT_TAB
[__ELP_DELVT0_MARGIN
].VALUE
< 0.0 ) {
516 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpDELVT0
]*ELPPRECISION
))
520 delvt0
= elpDouble2Long (model
->elpModel
[elpDELVT0
]*ELPPRECISION
);
521 if ( delvt0
>= tree
->DATA1
&& delvt0
<= tree
->DATA2
)
525 case elpSALevel
: if ( model
->elpModel
[elpSA
] < ELPMINVALUE
)
528 if ( V_FLOAT_TAB
[__ELP_SA_MARGIN
].VALUE
< 0.0 ) {
529 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSA
]*ELPPRECISION2
))
533 sa
= elpDouble2Long (model
->elpModel
[elpSA
]*ELPPRECISION2
);
534 if ( sa
>= tree
->DATA1
&& sa
<= tree
->DATA2
)
539 case elpSBLevel
: if ( model
->elpModel
[elpSB
] < ELPMINVALUE
)
542 if ( V_FLOAT_TAB
[__ELP_SB_MARGIN
].VALUE
< 0.0 ) {
543 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSB
]*ELPPRECISION2
))
547 sb
= elpDouble2Long (model
->elpModel
[elpSB
]*ELPPRECISION2
);
548 if ( sb
>= tree
->DATA1
&& sb
<= tree
->DATA2
)
553 case elpSDLevel
: if ( model
->elpModel
[elpSD
] < ELPMINVALUE
)
556 if ( V_FLOAT_TAB
[__ELP_SD_MARGIN
].VALUE
< 0.0 ) {
557 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSD
]*ELPPRECISION2
))
561 sd
= elpDouble2Long (model
->elpModel
[elpSD
]*ELPPRECISION2
);
562 if ( sd
>= tree
->DATA1
&& sd
<= tree
->DATA2
)
567 case elpNFLevel
: if ( model
->elpModel
[elpNF
] < ELPMINVALUE
)
570 if ( ELP_NF_MARGIN
< 0.0 ) {
571 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpNF
]))
575 nf
= elpDouble2Long (model
->elpModel
[elpNF
]);
576 if ( nf
>= tree
->DATA1
&& nf
<= tree
->DATA2
)
581 case elpMLevel
: if ( model
->elpModel
[elpM
] < ELPMINVALUE
)
584 if ( ELP_M_MARGIN
< 0.0 ) {
585 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpM
]))
589 val
= elpDouble2Long (model
->elpModel
[elpM
]);
590 if ( val
>= tree
->DATA1
&& val
<= tree
->DATA2
)
595 case elpNRSLevel
: if ( model
->elpModel
[elpNRS
] < ELPMINVALUE
)
598 if ( ELP_NRS_MARGIN
< 0.0 ) {
599 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpNRS
]*ELPPRECISION
))
603 val
= elpDouble2Long (model
->elpModel
[elpNRS
]*ELPPRECISION
);
604 if ( val
>= tree
->DATA1
&& val
<= tree
->DATA2
)
609 case elpNRDLevel
: if ( model
->elpModel
[elpNRD
] < ELPMINVALUE
)
612 if ( ELP_NRD_MARGIN
< 0.0 ) {
613 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpNRD
]*ELPPRECISION
))
617 val
= elpDouble2Long (model
->elpModel
[elpNRD
]*ELPPRECISION
);
618 if ( val
>= tree
->DATA1
&& val
<= tree
->DATA2
)
623 case elpVBULKLevel
: if(tree
->DATA1
== elpDouble2Long (model
->elpVoltage
[elpVBULK
]*SCALE_X
))
626 case elpParamContextLevel
:
627 if(elp_is_same_paramcontext((chain_list
*)tree
->DATA1
,model
->longkey
))
630 case elpCaseLevel
: if(tree
->DATA1
== (long)model
->elpTransCase
)
633 case elpSCLevel
: if ( model
->elpModel
[elpSC
] < ELPMINVALUE
)
636 if ( V_FLOAT_TAB
[__ELP_SC_MARGIN
].VALUE
< 0.0 ) {
637 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSC
]*ELPPRECISION2
))
641 sc
= elpDouble2Long (model
->elpModel
[elpSC
]*ELPPRECISION2
);
642 if ( sc
>= tree
->DATA1
&& sc
<= tree
->DATA2
)
647 case elpSCALevel
: if ( model
->elpModel
[elpSCA
] < ELPMINVALUE
)
650 if ( V_FLOAT_TAB
[__ELP_SCA_MARGIN
].VALUE
< 0.0 ) {
651 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSCA
]*ELPPRECISION2
))
655 sca
= elpDouble2Long (model
->elpModel
[elpSCA
]*ELPPRECISION2
);
656 if ( sca
>= tree
->DATA1
&& sca
<= tree
->DATA2
)
661 case elpSCBLevel
: if ( model
->elpModel
[elpSCB
] < ELPMINVALUE
)
664 if ( V_FLOAT_TAB
[__ELP_SCB_MARGIN
].VALUE
< 0.0 ) {
665 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSCB
]*ELPPRECISION2
))
669 scb
= elpDouble2Long (model
->elpModel
[elpSCB
]*ELPPRECISION2
);
670 if ( scb
>= tree
->DATA1
&& scb
<= tree
->DATA2
)
675 case elpSCCLevel
: if ( model
->elpModel
[elpSCC
] < ELPMINVALUE
)
678 if ( V_FLOAT_TAB
[__ELP_SCC_MARGIN
].VALUE
< 0.0 ) {
679 if (tree
->DATA1
== elpDouble2Long (model
->elpModel
[elpSCC
]*ELPPRECISION2
))
683 scc
= elpDouble2Long (model
->elpModel
[elpSCC
]*ELPPRECISION2
);
684 if ( scc
>= tree
->DATA1
&& scc
<= tree
->DATA2
)
694 /*****************************************************************************/
695 /* function elpDiffTree() */
696 /*****************************************************************************/
697 elpFCT
int elpDiffTree(model
,tree
,level
)
698 elpmodel_list
*model
;
705 case elpNameLevel
: return 0 ;
706 case elpLengthLevel
:
707 if(model
->elpRange
[elpLMAX
] > tree
->DATA2
)
712 if(model
->elpRange
[elpWMAX
] > tree
->DATA2
)
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 ;
738 /*****************************************************************************/
739 /* function elpBuiltTreeModel() */
740 /*****************************************************************************/
741 elpFCT elptree_list
*elpBuiltTreeModel(head
,model
,level
)
743 elpmodel_list
*model
;
749 for(tree
= head
; tree
!= NULL
; tree
= tree
->NEXT
)
751 if(elpCmpTreeModel(tree
,model
,level
) == 1)
759 head
= elpAddTree(head
,model
,level
) ;
768 if(elpDiffTree(model
,tree
,level
) == 1)
778 head
= elpAddTree(head
,model
,level
) ;
783 pt
->NEXT
= elpAddTree(pt
->NEXT
,model
,level
) ;
791 pt
->NEXT
= elpAddTree(pt
->NEXT
,model
,level
) ;
798 if(level
== elpCaseLevel
)
802 if(level
!= elpCaseLevel
)
803 tree
->DOWN
= elpBuiltTreeModel(tree
->DOWN
,model
,level
+1) ;
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
)
817 chain_list
*name_alias
;
847 elpmodel_list
*model
;
849 static int warn_displayed
=0 ;
851 if( nf
>=2 && (wmin
!= wmax
|| lmin
!= lmax
) ) {
852 if( ! warn_displayed
) {
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" );
858 model
= (elpmodel_list
*)mbkalloc(sizeof(elpmodel_list
)) ;
860 if(ELP_MODEL_LIST
== NULL
)
861 model
->elpModelIndex
= 0 ;
863 model
->elpModelIndex
= ELP_MODEL_LIST
->elpModelIndex
+ 1 ;
865 model
->NEXT
= ELP_MODEL_LIST
;
866 ELP_MODEL_LIST
= model
;
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
;
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
);
886 model
->elpModelName
= namealloc("TN") ;
887 if (!mbk_istransn(model
->elpModelName
)) TNMOS
= addchain(TNMOS
, model
->elpModelName
);
891 model
->elpModelName
= namealloc("TP") ;
892 if (!mbk_istransp(model
->elpModelName
)) TPMOS
= addchain(TPMOS
, model
->elpModelName
);
896 /* Initialisation des parametres du modele */
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
;
906 model
->elpRange
[elpLMIN
] = lmin
;
907 model
->elpRange
[elpLMAX
] = lmax
;
908 model
->elpRange
[elpWMIN
] = wmin
;
909 model
->elpRange
[elpWMAX
] = wmax
;
911 model
->elpTemp
= ELPINITTEMP
;
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
);
930 model
->elpVoltage
[elpVDEG
] = ELPMINVOLTAGE
;
931 model
->elpVoltage
[elpVTI
] = ELPMINVOLTAGE
;
933 for (i
= 0 ; i
< elpCAPANUM
; i
++)
934 model
->elpCapa
[i
] = 0.0 ;
936 for (i
= 0 ; i
< elpRSSNUM
; i
++)
937 model
->elpRss
[i
] = 0.0 ;
939 ELP_HEAD_TREE
= elpBuiltTreeModel(ELP_HEAD_TREE
,model
,elpNameLevel
) ;
944 /*****************************************************************************/
945 /* function elpFreeTreeModel() */
946 /*****************************************************************************/
947 elpFCT
void elpFreeTreeModel(head
,level
)
956 if(level
!= elpCaseLevel
)
957 elpFreeTreeModel(head
->DOWN
,level
+ 1) ;
964 /*****************************************************************************/
965 /* function elpPrintData() */
966 /*****************************************************************************/
967 elpFCT
void elpPrintData(elptree_list
*tree
, int level
)
969 chain_list
*chain
,*chain_alias
;
974 case elpNameLevel
: fprintf(stdout
, "Model Name : %s\n", (char *)tree
->DATA1
) ;
975 chain_alias
= (chain_list
*)tree
->DATA2
;
978 fprintf (stdout
,"Alias ");
979 for (chain
= chain_alias
; chain
; chain
= chain
->NEXT
)
980 fprintf(stdout
,": %s ",(char*)chain
->DATA
);
981 fprintf (stdout
,"\n");
984 case elpLengthLevel
: fprintf(stdout
, "LMIN = %ld\n", tree
->DATA1
) ;
985 fprintf(stdout
, "LMAX = %ld\n", tree
->DATA2
) ;
987 case elpWidthLevel
: fprintf(stdout
, "WMIN = %ld\n", tree
->DATA1
) ;
988 fprintf(stdout
, "WMAX = %ld\n", tree
->DATA2
) ;
990 case elpVDDLevel
: fprintf(stdout
, "VDDMAX = %ld\n", tree
->DATA1
) ;
992 case elpMULU0Level
: fprintf(stdout
, "MULU0 = %ld\n", tree
->DATA1
) ;
994 case elpDELVT0Level
: fprintf(stdout
, "DELVT0 = %ld\n", tree
->DATA1
) ;
996 case elpSALevel
: fprintf(stdout
, "SA = %ld\n", tree
->DATA1
) ;
998 case elpSBLevel
: fprintf(stdout
, "SB = %ld\n", tree
->DATA1
) ;
1000 case elpSDLevel
: fprintf(stdout
, "SD = %ld\n", tree
->DATA1
) ;
1002 case elpNFLevel
: fprintf(stdout
, "NF = %ld\n", tree
->DATA1
) ;
1004 case elpVBULKLevel
: fprintf(stdout
, "VBULK = %ld\n", tree
->DATA1
) ;
1006 case elpParamContextLevel
:
1007 fprintf(stdout
, "ParamContext :");
1008 for (pt
=(ptype_list
*)tree
->DATA1
; pt
!=NULL
; pt
=pt
->NEXT
)
1010 if ((long)pt
==tree
->DATA1
)
1011 fprintf(stdout
," %s (fastkey=%ld)", (char *)pt
->DATA
, pt
->TYPE
);
1013 fprintf(stdout
," %s=%g", (char *)pt
->DATA
, *(float *)&pt
->TYPE
);
1015 fprintf(stdout
,"\n");
1018 case elpCaseLevel
: fprintf(stdout
, "Case value : %ld\n", tree
->DATA1
) ;
1020 case elpSCLevel
: fprintf(stdout
, "SC = %ld\n", tree
->DATA1
) ;
1022 case elpSCALevel
: fprintf(stdout
, "SCA = %ld\n", tree
->DATA1
) ;
1024 case elpSCBLevel
: fprintf(stdout
, "SCB = %ld\n", tree
->DATA1
) ;
1026 case elpSCCLevel
: fprintf(stdout
, "SCC = %ld\n", tree
->DATA1
) ;
1033 /*****************************************************************************/
1034 /* function elpPrintTreeModel() */
1035 /*****************************************************************************/
1036 elpFCT
void elpPrintTreeModel(head
,level
)
1037 elptree_list
*head
;
1040 elptree_list
*tree
;
1043 fprintf(stdout
, "Empty tree!!!\n") ;
1047 for (tree
= head
; tree
; tree
= tree
->NEXT
) {
1048 elpPrintData(tree
, level
) ;
1049 if(level
!= elpCaseLevel
)
1050 elpPrintTreeModel(tree
->DOWN
, level
+ 1) ;
1054 /*****************************************************************************/
1055 /* function elpFreemodel() */
1056 /*****************************************************************************/
1057 elpFCT
void elpFreeModel()
1059 elpmodel_list
*model
;
1061 while(ELP_MODEL_LIST
!= NULL
)
1063 model
= ELP_MODEL_LIST
;
1064 ELP_MODEL_LIST
= ELP_MODEL_LIST
->NEXT
;
1065 freechain (model
->elpModelNameAlias
) ;
1066 freechain(model
->longkey
);
1070 ELP_MODEL_LIST
= NULL
;
1071 elpFreeTreeModel(ELP_HEAD_TREE
,elpNameLevel
) ;
1072 ELP_HEAD_TREE
= NULL
;
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
;
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
;
1109 chain_list
*longkey
;
1117 case elpNameLevel
: name
= getlotrsmodel(lotrs
) ;
1118 if((tree
->DATA1
== (long)NULL
) ||
1119 (tree
->DATA1
== (long)name
))
1123 for (chain
= (chain_list
*)tree
->DATA2
; chain
;
1124 chain
= chain
->NEXT
)
1125 if ((char*)chain
->DATA
== name
)
1129 case elpLengthLevel
: if((lotrs
->LENGTH
>= tree
->DATA1
) &&
1130 ((lotrs
->LENGTH
<= tree
->DATA2
) ||
1131 ((lotrs
->LENGTH
== tree
->DATA2
) &&
1132 (tree
->DATA1
== tree
->DATA2
))))
1134 if(lotrs
->LENGTH
> tree
->DATA2
)
1140 case elpWidthLevel
: if((lotrs
->WIDTH
>= tree
->DATA1
) &&
1141 ((lotrs
->WIDTH
<= tree
->DATA2
) ||
1142 ((lotrs
->WIDTH
== tree
->DATA2
) &&
1143 (tree
->DATA1
== tree
->DATA2
))))
1145 if(lotrs
->WIDTH
> tree
->DATA2
)
1151 case elpVDDLevel
: if(tree
->DATA1
== elpDouble2Long(vdd
*SCALE_X
))
1153 else if(tree
->DATA1
< 0) {
1154 if (elpDouble2Long (vdd
*SCALE_X
) ==
1155 elpDouble2Long(elpGeneral
[elpGVDDMAX
]*SCALE_X
))
1159 case elpMULU0Level
: if ( V_FLOAT_TAB
[__ELP_MULU0_MARGIN
].VALUE
< 0.0 ) {
1160 if (tree
->DATA1
== elpDouble2Long (mulu0
*ELPPRECISION
))
1164 mulu0
= elpDouble2Long (mulu0
*ELPPRECISION
);
1165 if ( mulu0
>= tree
->DATA1
&& mulu0
<= tree
->DATA2
)
1169 case elpDELVT0Level
: if ( V_FLOAT_TAB
[__ELP_DELVT0_MARGIN
].VALUE
< 0.0 ) {
1170 if (tree
->DATA1
== elpDouble2Long (delvt0
*ELPPRECISION
))
1174 delvt0
= elpDouble2Long (delvt0
*ELPPRECISION
);
1175 if ( delvt0
>= tree
->DATA1
&& delvt0
<= tree
->DATA2
)
1179 case elpSALevel
: if ( sa
< ELPMINVALUE
)
1182 if ( V_FLOAT_TAB
[__ELP_SA_MARGIN
].VALUE
< 0.0 ) {
1183 if (tree
->DATA1
== elpDouble2Long (sa
*ELPPRECISION2
))
1187 sa
= elpDouble2Long (sa
*ELPPRECISION2
);
1188 if ( sa
>= tree
->DATA1
&& sa
<= tree
->DATA2
)
1193 case elpSBLevel
: if ( sb
< ELPMINVALUE
)
1196 if ( V_FLOAT_TAB
[__ELP_SB_MARGIN
].VALUE
< 0.0 ) {
1197 if (tree
->DATA1
== elpDouble2Long (sb
*ELPPRECISION2
))
1201 sb
= elpDouble2Long (sb
*ELPPRECISION2
);
1202 if ( sb
>= tree
->DATA1
&& sb
<= tree
->DATA2
)
1207 case elpSDLevel
: if ( sd
< ELPMINVALUE
)
1210 if ( V_FLOAT_TAB
[__ELP_SD_MARGIN
].VALUE
< 0.0 ) {
1211 if (tree
->DATA1
== elpDouble2Long (sd
*ELPPRECISION2
))
1215 sd
= elpDouble2Long (sd
*ELPPRECISION2
);
1216 if ( sd
>= tree
->DATA1
&& sd
<= tree
->DATA2
)
1221 case elpNFLevel
: if ( nf
< ELPMINVALUE
)
1224 if ( ELP_NF_MARGIN
< 0.0 ) {
1225 if (tree
->DATA1
== elpDouble2Long (nf
))
1229 nf
= elpDouble2Long (nf
);
1230 if ( nf
>= tree
->DATA1
&& nf
<= tree
->DATA2
)
1235 case elpMLevel
: if ( ELP_M_MARGIN
< 0.0 ) {
1236 if (tree
->DATA1
== elpDouble2Long (m
))
1240 m
= elpDouble2Long (m
);
1241 if ( m
>= tree
->DATA1
&& m
<= tree
->DATA2
)
1245 case elpNRSLevel
: if ( nrs
< ELPMINVALUE
)
1248 if ( ELP_NRS_MARGIN
< 0.0 ) {
1249 if (tree
->DATA1
== elpDouble2Long (nrs
*ELPPRECISION
))
1253 nrs
= elpDouble2Long (nrs
*ELPPRECISION
);
1254 if ( nrs
>= tree
->DATA1
&& nrs
<= tree
->DATA2
)
1259 case elpNRDLevel
: if ( nrd
< ELPMINVALUE
)
1262 if ( ELP_NRD_MARGIN
< 0.0 ) {
1263 if (tree
->DATA1
== elpDouble2Long (nrd
*ELPPRECISION
))
1267 nrd
= elpDouble2Long (nrd
*ELPPRECISION
);
1268 if ( nrd
>= tree
->DATA1
&& nrd
<= tree
->DATA2
)
1273 case elpVBULKLevel
: if(tree
->DATA1
== elpDouble2Long (vbulk
*SCALE_X
))
1275 else if(tree
->DATA1
< ELPMINVBULK
) {
1276 if (MLO_IS_TRANSP(lotrs
->TYPE
) && (elpDouble2Long (vbulk
*SCALE_X
)) ==
1277 elpDouble2Long(elpGeneral
[elpGVDDMAX
]*SCALE_X
))
1279 if (MLO_IS_TRANSN(lotrs
->TYPE
) && (elpDouble2Long (vbulk
*SCALE_X
) == 0))
1283 case elpParamContextLevel
: if(elp_is_same_paramcontext((chain_list
*)tree
->DATA1
,longkey
))
1286 case elpCaseLevel
: if((tree
->DATA1
== (long)transcase
) ||
1287 //(tree->DATA1 == elpTYPICAL) ||
1288 (transcase
== elpTYPICAL
))
1291 case elpSCLevel
: if ( sc
< ELPMINVALUE
)
1294 if ( V_FLOAT_TAB
[__ELP_SC_MARGIN
].VALUE
< 0.0 ) {
1295 if (tree
->DATA1
== elpDouble2Long (sc
*ELPPRECISION2
))
1299 sc
= elpDouble2Long (sc
*ELPPRECISION2
);
1300 if ( sc
>= tree
->DATA1
&& sc
<= tree
->DATA2
)
1305 case elpSCALevel
: if ( sca
< ELPMINVALUE
)
1308 if ( V_FLOAT_TAB
[__ELP_SCA_MARGIN
].VALUE
< 0.0 ) {
1309 if (tree
->DATA1
== elpDouble2Long (sca
*ELPPRECISION2
))
1313 sca
= elpDouble2Long (sca
*ELPPRECISION2
);
1314 if ( sca
>= tree
->DATA1
&& sca
<= tree
->DATA2
)
1319 case elpSCBLevel
: if ( scb
< ELPMINVALUE
)
1322 if ( V_FLOAT_TAB
[__ELP_SCB_MARGIN
].VALUE
< 0.0 ) {
1323 if (tree
->DATA1
== elpDouble2Long (scb
*ELPPRECISION2
))
1327 scb
= elpDouble2Long (scb
*ELPPRECISION2
);
1328 if ( scb
>= tree
->DATA1
&& scb
<= tree
->DATA2
)
1333 case elpSCCLevel
: if ( scc
< ELPMINVALUE
)
1336 if ( V_FLOAT_TAB
[__ELP_SCC_MARGIN
].VALUE
< 0.0 ) {
1337 if (tree
->DATA1
== elpDouble2Long (scc
*ELPPRECISION2
))
1341 scc
= elpDouble2Long (scc
*ELPPRECISION2
);
1342 if ( scc
>= tree
->DATA1
&& scc
<= tree
->DATA2
)
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;
1378 elpmodel_list
*nmodel
;
1380 nmodel
= elpAddModel(getlotrsmodel(lotrs
),model
->elpModelNameAlias
,type
,elpNOINDEX
,
1385 model
->elpShrink
[elpDL
],
1386 model
->elpShrink
[elpDW
],
1387 model
->elpShrink
[elpLMLT
],
1388 model
->elpShrink
[elpWMLT
],
1390 model
->elpTransTechno
,
1391 mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
,model
->longkey
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
] ;
1472 /*****************************************************************************\
1473 function elpDelModel2Lotrs()
1474 \*****************************************************************************/
1475 elpFCT
void elpDelModel2Lotrs (lotrs_list
*lotrs
)
1478 if ( getptype (lotrs
->USER
, ELP_LOTRS_MODEL
) != NULL
)
1479 lotrs
->USER
= delptype (lotrs
->USER
, ELP_LOTRS_MODEL
);
1483 /*****************************************************************************\
1484 function elpSetModel2Lotrs()
1485 \*****************************************************************************/
1486 elpFCT
int elpSetModel2Lotrs (elpmodel_list
*model
, lotrs_list
*lotrs
)
1490 if ( model
&& lotrs
) {
1491 if ( !getptype (lotrs
->USER
, ELP_LOTRS_MODEL
) ) {
1492 lotrs
->USER
= addptype (lotrs
->USER
, ELP_LOTRS_MODEL
, model
);
1499 /*****************************************************************************\
1500 function elpGetModelFromLotrs()
1501 \*****************************************************************************/
1502 elpFCT elpmodel_list
*elpGetModelFromLotrs (lotrs_list
*lotrs
)
1504 elpmodel_list
*model
=NULL
;
1508 if ( (ptype
= getptype (lotrs
->USER
, ELP_LOTRS_MODEL
)) )
1509 model
= (elpmodel_list
*)ptype
->DATA
;
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 ;
1538 elpmodel_list
*model
= NULL
;
1540 int type
= (MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
) ;
1542 modelname
= getlotrsmodel (lotrs
);
1543 // first : try to get the same model name...
1544 for(model
= ELP_MODEL_LIST
; model
!= NULL
; model
= model
->NEXT
)
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
)))
1579 // if (!mbk_isdioden(getlotrsmodel(lotrs)) && !mbk_isdiodep(getlotrsmodel(lotrs)))
1581 if(lotrs
->TRNAME
!= NULL
)
1582 avt_errmsg(ELP_ERRMSG
, "007", AVT_ERROR
, lotrs
->TRNAME
, model
->elpModelName
);
1583 // elpError(1007,lotrs->TRNAME,model->elpModelName) ;
1585 avt_errmsg(ELP_ERRMSG
, "007", AVT_ERROR
, modelname
, model
->elpModelName
);
1586 // elpError(1007,modelname,model->elpModelName) ;
1588 elpDupModel (lotrs
,model
,type
,vdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
);
1593 for(model
= ELP_MODEL_LIST
; model
!= NULL
; model
= model
->NEXT
)
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
)))
1628 // if (!mbk_isdioden(getlotrsmodel(lotrs)) && !mbk_isdiodep(getlotrsmodel(lotrs)))
1630 if(lotrs
->TRNAME
!= NULL
)
1631 avt_errmsg(ELP_ERRMSG
, "007", AVT_ERROR
, lotrs
->TRNAME
, model
->elpModelName
);
1632 //elpError(1007,lotrs->TRNAME,model->elpModelName) ;
1634 avt_errmsg(ELP_ERRMSG
, "007", AVT_ERROR
, modelname
, model
->elpModelName
);
1635 //elpError(1007,modelname,model->elpModelName) ;
1637 elpDupModel (lotrs
,model
,type
,vdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
);
1642 elpSetModel2Lotrs ( model
, lotrs
);
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
;
1671 chain_list
*longkey
;
1673 elptree_list
*tree
;
1674 elpmodel_list
*resmodel
;
1677 for(tree
= head
; tree
!= NULL
; tree
= tree
->NEXT
)
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)
1687 if(level
!= elpCaseLevel
)
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
))
1694 return(tree
->DOWN
) ;
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
;
1722 chain_list
*longkey
;
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
);
1730 void fill_elp_lotrs_param( elp_lotrs_param
*pt
,
1748 chain_list
*longkey
;
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
;
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
;
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
)
1794 elpmodel_list
*model
= NULL
;
1796 elp_lotrs_param ptlotrs_param
;
1797 #ifdef DELAY_DEBUG_STAT
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
) ;
1804 if((model
== NULL
) && (ELP_LOAD_FILE_TYPE
|| ELP_GENPARAM
))
1806 lotrstype
= MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
;
1808 fill_elp_lotrs_param( &ptlotrs_param
, mulu0
, delvt0
, sa
, sb
, sd
, nf
, m
,nrs
, nrd
, vbulk
, sc
, sca
, scb
, scc
, lotrs
);
1810 elpGenParam(getlotrsmodel(lotrs
), lotrstype
,(double)lotrs
->LENGTH
/(double)(SCALE_X
),
1811 (double)lotrs
->WIDTH
/(double)(SCALE_X
),vdd
,lotrs
,transcase
,&ptlotrs_param
) ;
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
1819 fprintf(stdout
,"\relp: %05d\r", cnt
); fflush(stdout
);
1822 if((model
= elpGetModelList(lotrs
,vdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
)) == NULL
)
1824 if(lotrs
->TRNAME
!= NULL
)
1826 avt_errmsg(ELP_ERRMSG
, "009", AVT_ERROR
, lotrs
->TRNAME
);
1827 //elpError(1009,lotrs->TRNAME) ;
1832 avt_errmsg(ELP_ERRMSG
, "009", AVT_ERROR
, getlotrsmodel(lotrs
));
1833 //elpError(1009,getlotrsmodel(lotrs)) ;
1839 else if(model
== NULL
)
1841 if((model
= elpGetModelList(lotrs
,vdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
)) == NULL
)
1843 if(lotrs
->TRNAME
!= NULL
)
1845 avt_errmsg(ELP_ERRMSG
, "009", AVT_ERROR
, lotrs
->TRNAME
);
1846 //elpError(1009,lotrs->TRNAME) ;
1851 avt_errmsg(ELP_ERRMSG
, "009", AVT_ERROR
, getlotrsmodel(lotrs
));
1852 //elpError(1009,getlotrsmodel(lotrs)) ;
1862 /*****************************************************************************/
1863 /* function elpGetModelWithLotrsParams () */
1864 /*****************************************************************************/
1865 elpFCT elpmodel_list
*elpGetModelWithLotrsParams(lotrs
,lotrsparams
,vdd
,transcase
)
1869 elp_lotrs_param
*lotrsparams
;
1871 elpmodel_list
*model
;
1872 double mulu0
,delvt0
,sa
,sb
,sd
,nf
,vbulk
,sc
,sca
,scb
,scc
;
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
;
1890 model
= elpSearchOrGenModel (lotrs
,vdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
);
1895 /*****************************************************************************/
1896 /* function elpGetVdd4UnusedLotrs() */
1897 /*****************************************************************************/
1898 elpFCT
double elpGetVdd4UnusedLotrs(lotrs_list
*lotrs
)
1903 if (MLO_IS_TRANSP(lotrs
->TYPE
) ) {
1904 if ( lotrs
->BULK
&& lotrs
->BULK
->SIG
&&
1905 getlosigalim(lotrs
->BULK
->SIG
, &vbulk
) )
1909 vdd
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
1914 /*****************************************************************************/
1915 /* function elpGetModel() */
1916 /*****************************************************************************/
1917 elpFCT elpmodel_list
*elpGetModel(lotrs
,vdd
,transcase
)
1922 elpmodel_list
*model
;
1923 double mulu0
,delvt0
,vbulk
,sa
,sb
,sd
,nf
,sc
,sca
,scb
,scc
;
1929 if ( (model
= elpGetModelFromLotrs (lotrs
)) )
1932 trsmodel
= getlotrsmodel(lotrs
);
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);
1938 elp_lotrs_param_get (lotrs
,&mulu0
,&delvt0
,&sa
,&sb
,&sd
,&nf
,&m
,&nrs
,&nrd
,&vbulk
,&sc
,&sca
,&scb
,&scc
);
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
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
1955 else if (MLO_IS_TRANSP(lotrs
->TYPE
) ) {
1956 if ( newvdd
> vbulk
&& vbulk
> 0 )
1960 model
= elpSearchOrGenModel (lotrs
,newvdd
,transcase
,mulu0
,delvt0
,sa
,sb
,sd
,nf
,m
,nrs
,nrd
,vbulk
,sc
,sca
,scb
,scc
);
1962 elpSetModel2Lotrs (model
, lotrs
);
1967 /*****************************************************************************/
1968 /* function elpGetParamModel() */
1969 /*****************************************************************************/
1970 elpFCT elpmodel_list
*elpGetParamModel(name
,l
,w
,type
,vdd
,transcase
,params
)
1977 elp_lotrs_param
*params
;
1982 lotrs
.TRNAME
= NULL
;
1983 lotrs
.LENGTH
= elpDouble2Long (l
* SCALE_X
) ;
1984 lotrs
.WIDTH
= elpDouble2Long (w
* SCALE_X
) ;
1989 lotrs
.SOURCE
= NULL
;
1991 addlotrsmodel(&lotrs
,name
) ;
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
);
2000 /*****************************************************************************/
2001 /* function elpGetModelType() */
2002 /*****************************************************************************/
2003 elpFCT elpmodel_list
*elpGetModelType(typet
)
2006 elpmodel_list
*model
;
2007 int type
= (MLO_IS_TRANSN(typet
) ? elpNMOS
: elpPMOS
) ;
2009 for(model
= ELP_MODEL_LIST
; model
!= NULL
; model
= model
->NEXT
)
2011 if(type
== model
->elpTransType
)
2014 if((model
== NULL
) && (ELP_LOAD_FILE_TYPE
|| ELP_GENPARAM
))
2016 elpGenParam(NULL
,type
,elpBADLW
,elpBADLW
,ELPMINVOLTAGE
,NULL
,elpTYPICAL
,NULL
) ;
2017 model
= ELP_MODEL_LIST
;
2023 /*****************************************************************************/
2024 /* function elpGetModelIndex() */
2025 /*****************************************************************************/
2026 elpFCT elpmodel_list
*elpGetModelIndex(index
)
2029 elpmodel_list
*model
;
2031 for(model
= ELP_MODEL_LIST
; model
!= NULL
; model
= model
->NEXT
)
2033 if(index
== model
->elpModelIndex
)
2040 /*****************************************************************************/
2041 /* function elpenv() */
2042 /* recuperation du nom du fichier elp a partir de la variable: */
2043 /* ELP_TECHNO_NAME. */
2045 /* Parametres en entree: */
2046 /* -------------------- */
2049 /* Parametre en sortie: */
2050 /* ------------------- */
2052 /*****************************************************************************/
2057 static int doneonce
=0;
2061 elpTechnoName
[0] = '\0';
2062 elpGenTechnoFile
[0] = '\0';
2063 if (elpoldtechnofilename
) mbkfree(elpoldtechnofilename
);
2064 elpoldtechnofilename
= NULL
;
2069 str
= V_STR_TAB
[__ELP_GEN_TECHNO_NAME
].VALUE
;
2071 strcpy(elpGenTechnoFile
,str
) ;
2073 strcpy(elpGenTechnoFile
,"techno.elp") ;
2075 str
= V_STR_TAB
[__ELP_LOAD_FILE
].VALUE
;
2078 if ( (str = V_INT_TAB[__ELP_CAPA_LEVEL].VALUE) ) {
2079 level = atoi ( str );
2081 case 0 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL0;
2083 case 1 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2085 case 2 : ELP_CAPA_LEVEL = ELP_CAPA_LEVEL2;
2087 default: ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2092 ELP_CAPA_LEVEL = ELP_CAPA_LEVEL1;
2096 str = V_BOOL_TAB[__ELP_DRV_FILE].VALUE ;
2097 if((str != NULL) && (strcmp(str,"yes") == 0))
2106 str
= V_STR_TAB
[__ELP_TECHNO_NAME
].VALUE
;
2109 strcpy(elpTechnoFile
,str
) ;
2110 str
= V_STR_TAB
[__ELP_LOAD_FILE
].VALUE
;
2111 if((str
!= NULL
) && (strcmp(str
,"yes") != 0))
2113 if( !strcmp(str
,"no") )
2115 strcpy(elpTechnoFile
,elpGenTechnoFile
) ;
2116 ELP_LOAD_FILE_TYPE
= ELP_DONTLOAD_FILE
;
2118 else if( !strcmp(str
,"default") )
2120 strcpy(elpTechnoFile
,elpGenTechnoFile
) ;
2121 ELP_LOAD_FILE_TYPE
= ELP_DEFAULTLOAD_FILE
;
2125 ELP_LOAD_FILE_TYPE
= ELP_LOADELP_FILE
;
2130 ELP_LOAD_FILE_TYPE
= ELP_LOADELP_FILE
;
2135 str
= getenv("AVT_TOOLS_DIR") ;
2138 sprintf(elpTechnoFile
,"%s%s",str
,TECHNOLOGY
) ;
2140 else if((str
= getenv("AVERTEC_TOP")) != NULL
)
2142 sprintf(elpTechnoFile
,"%s%s",str
,TECHNOLOGY
) ;
2146 sprintf(elpTechnoFile
,"AvtTools%s",TECHNOLOGY
) ;
2148 str
= V_STR_TAB
[__ELP_LOAD_FILE
].VALUE
;
2149 if((str
!= NULL
) && (strcmp(str
,"yes") != 0))
2151 if( !strcmp(str
,"no") )
2153 strcpy(elpTechnoFile
,elpGenTechnoFile
) ;
2154 ELP_LOAD_FILE_TYPE
= ELP_DONTLOAD_FILE
;
2156 else if( !strcmp(str
,"default") )
2158 strcpy(elpTechnoFile
,elpGenTechnoFile
) ;
2159 ELP_LOAD_FILE_TYPE
= ELP_DEFAULTLOAD_FILE
;
2163 ELP_LOAD_FILE_TYPE
= ELP_LOADELP_FILE
;
2168 strcpy(elpTechnoFile
,elpGenTechnoFile
) ;
2169 ELP_LOAD_FILE_TYPE
= ELP_DONTLOAD_FILE
;
2172 ELP_GENPARAM
= V_BOOL_TAB
[__ELP_GEN_PARAM
].VALUE
;
2173 ELP_CAPA_DIFF
= V_BOOL_TAB
[__ELP_DEDUCE_DIFFSIZE
].VALUE
;
2175 str = V_FLOAT_TAB[__ELP_MULU0_MARGIN].VALUE ;
2179 if ( val >= 0.0 && val <= 1.0)
2180 ELP_MULU0_MARGIN = val;
2182 STR = V_FLOAT_TAB[__ELP_DELVT0_MARGIN].VALUE ;
2186 if ( val >= 0.0 && val <= 1.0)
2187 ELP_DELVT0_MARGIN = val;
2189 str = V_FLOAT_TAB[__ELP_SA_MARGIN].VALUE ;
2193 if ( val >= 0.0 && val <= 1.0)
2194 ELP_SA_MARGIN = val;
2196 str = V_FLOAT_TAB[__ELP_SB_MARGIN].VALUE ;
2200 if ( val >= 0.0 && val <= 1.0)
2201 ELP_SB_MARGIN = val;
2203 str = V_FLOAT_TAB[__ELP_SD_MARGIN].VALUE ;
2207 if ( val >= 0.0 && val <= 1.0)
2208 ELP_SD_MARGIN = val;
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;
2217 str
= getenv("ELP_NF_MARGIN") ;
2221 if ( val
>= 0.0 && val
<= 1.0)
2222 ELP_NF_MARGIN
= val
;
2228 /*****************************************************************************/
2229 /* function VerifModel() */
2231 /* Parametres en entree: */
2232 /* -------------------- */
2233 /* model de transistor */
2235 /* Parametre en sortie: */
2236 /* ------------------- */
2237 /* verifie le model */
2238 /*****************************************************************************/
2239 elpFCT
int elpVerifModel(model
)
2240 elpmodel_list
*model
;
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
);
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
))))
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
]);
2292 if (model
->elpModel
[elpVT0
] == 0.0 ) {
2293 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "VT0", model
->elpModel
[elpVT0
]);
2296 if (model
->elpModel
[elpA
] == 0.0 ) {
2297 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "A", model
->elpModel
[elpA
]);
2300 if (model
->elpModel
[elpB
] == 0.0 ) {
2301 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "B", model
->elpModel
[elpB
]);
2304 if (model
->elpModel
[elpRT
] == 0.0 ) {
2305 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "RT", model
->elpModel
[elpRT
]);
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
]);
2312 if (model
->elpCapa
[elpCGS
] == 0.0 ) {
2313 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGS", model
->elpModel
[elpCGS
]);
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
];
2325 if (model
->elpCapa
[elpCGSU
] == 0.0 ) {
2326 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSU", model
->elpModel
[elpCGSU
]);
2329 if (model
->elpCapa
[elpCGSUMIN
] == 0.0 ) {
2330 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSUMIN", model
->elpModel
[elpCGSUMIN
]);
2333 if (model
->elpCapa
[elpCGSUMAX
] == 0.0 ) {
2334 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSUMAX", model
->elpModel
[elpCGSUMAX
]);
2337 if (model
->elpCapa
[elpCGSDMIN
] == 0.0 ) {
2338 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSDMIN", model
->elpModel
[elpCGSDMIN
]);
2341 if (model
->elpCapa
[elpCGSDMAX
] == 0.0 ) {
2342 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSDMAX", model
->elpModel
[elpCGSDMAX
]);
2345 if (model
->elpCapa
[elpCGSD
] == 0.0 ) {
2346 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGSD", model
->elpModel
[elpCGSD
]);
2349 if ((model
->elpCapa
[elpCGP
] == 0.0 )) {
2350 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGP", model
->elpModel
[elpCGP
]);
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
];
2362 if ((model
->elpCapa
[elpCGPUMIN
] == 0.0 )) {
2363 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGPUMIN", model
->elpModel
[elpCGPUMIN
]);
2366 if ((model
->elpCapa
[elpCGPUMAX
] == 0.0 )) {
2367 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGPUMAX", model
->elpModel
[elpCGPUMAX
]);
2370 if ((model
->elpCapa
[elpCGPDMIN
] == 0.0 )) {
2371 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGPDMIN", model
->elpModel
[elpCGPDMIN
]);
2374 if ((model
->elpCapa
[elpCGPDMAX
] == 0.0 )) {
2375 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "CGPDMAX", model
->elpModel
[elpCGPDMAX
]);
2378 if (elpEsimName
[0] == '\0') {
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
);
2386 if ((model
->elpTemp
< ELPMINTEMP
) && (elpGeneral
[elpTEMP
] < ELPMINTEMP
)) {
2387 avt_errmsg(ELP_ERRMSG
, "010", AVT_ERROR
, elpTechnoFile
, model
->elpModelName
, "Temperature", model
->elpTemp
);
2392 if(model
->elpTemp
< ELPMINTEMP
)
2393 model
->elpTemp
= elpGeneral
[elpTEMP
] ;
2395 if(elpGeneral
[elpTEMP
] < ELPMINTEMP
)
2396 elpGeneral
[elpTEMP
] = model
->elpTemp
;
2398 if(elpGeneral
[elpGVDDMAX
] < 0.0)
2399 elpGeneral
[elpGVDDMAX
] = model
->elpVoltage
[elpVDDMAX
] ;
2401 if(elpGeneral
[elpGVDDBEST
] < 0.0)
2402 elpGeneral
[elpGVDDBEST
] = model
->elpVoltage
[elpVDDMAX
] ;
2404 if(elpGeneral
[elpGVDDWORST
] < 0.0)
2405 elpGeneral
[elpGVDDWORST
] = model
->elpVoltage
[elpVDDMAX
] ;
2407 if(model
->elpVoltage
[elpVDDMAX
] < 0.0)
2408 model
->elpVoltage
[elpVDDMAX
] = elpGeneral
[elpGVDDMAX
] ;
2410 if (model
->elpVoltage
[elpVBULK
] < ELPMINVBULK
) {
2411 if ( model
->elpTransType
== elpPMOS
)
2412 model
->elpVoltage
[elpVBULK
] = model
->elpVoltage
[elpVDDMAX
];
2414 model
->elpVoltage
[elpVBULK
] = 0;
2417 if(elpGeneral
[elpGDTHR
] < 0.0)
2418 elpGeneral
[elpGDTHR
] = 0.5 ;
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
] ;
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
] ;
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. */
2439 /* Parametres en entree: */
2440 /* -------------------- */
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()
2450 elpmodel_list
*model
;
2452 /* ouverture du fichier techno */
2456 if ( ELP_LOAD_FILE_TYPE
== ELP_DONTLOAD_FILE
)
2459 elpin
= fopen(elpTechnoFile
,"r") ;
2463 /* appel au parser pour chargement */
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 */
2472 /* fermeture du fichier techno */
2474 if( fclose(elpin
) != 0)
2476 avt_errmsg(ELP_ERRMSG
, "003", AVT_ERROR
, elpTechnoFile
);
2477 //elpError(1003,elpTechnoFile) ; /* si fermeture ko => erreur 1003 */
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 ();
2489 /*-------------------------------------------------------------------*/
2490 /* verification des parametres obligatoires et calcul des parametres */
2492 /*-------------------------------------------------------------------*/
2493 model
= ELP_MODEL_LIST
;
2495 res
= elpVerifModel(model
) ;
2498 model
= model
-> NEXT
;
2501 return 0 ; /* bon chargement */
2504 /*****************************************************************************/
2505 /* function DriveElp() */
2506 /* sauvegarde le fichier elp */
2508 /* Parametres en entree: */
2509 /* -------------------- */
2510 /* Nom du fichier elp */
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
)
2520 elpmodel_list
*model
;
2522 sprintf(filename
, "%s%s",filename
,".elp") ;
2523 file
= fopen(filename
,"w") ;
2526 fprintf(stderr
, "elp error: can't open file %s to drive!!!\n",filename
) ;
2530 model
= ELP_MODEL_LIST
;
2533 elpVerifModel(model
) ;
2534 model
= model
-> NEXT
;
2537 model
= ELP_MODEL_LIST
;
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
]) ;
2563 elpDriveOneModel (file
,model
);
2564 model
= model
->NEXT
;
2569 /****************************************************************************/
2570 /* fonction LotrsCapaDrain() */
2571 /* calcule la capacite de drain d'un transistor MBK passe en parametre. */
2573 /* Parametres en entree: */
2574 /* -------------------- */
2575 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
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
;
2589 double cdsval
,cdpval
,cdwval
;
2591 elpmodel_list
*model
;
2592 double ad
, pd
, wj
, ab
, lg
, ls
, cgp
;
2593 static char displayed
=0 ;
2595 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
2596 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
2597 if ( !model
) return 0.0;
2599 /* si les parametres CDxx ou sont manquants => erreur 1005 */
2600 if(model
->elpTransModel
== elpMOS
)
2602 if((model
->elpCapa
[elpCDS
] == 0.0) &&
2603 (model
->elpCapa
[elpCDP
] == 0.0) &&
2604 (model
->elpCapa
[elpCDW
] == 0.0))
2607 avt_errmsg(ELP_ERRMSG
, "005", AVT_ERROR
, elpTechnoFile
);
2608 // elpError(1005,"diffusion") ;
2614 if((lotrs
->PD
== 0) && (lotrs
->XD
== 0) && (lotrs
->WIDTH
== 0))
2617 if(ELP_CAPA_DIFF
== 1)
2619 if((lotrs
->XD
< (long)0) || (lotrs
->PD
< (long)0))
2621 lotrs
->XD
= model
->elpShrink
[elpWMLT
]*SCALE_X
;
2622 lotrs
->PD
= elpGetShrinkedWidth(lotrs
,model
);
2626 if(lotrs
->WIDTH
== 0)
2627 wcj
= w
= ((double)lotrs
->PD
/ (double)4.0) ;
2629 w
= (double)elpGetShrinkedWidth(lotrs
,model
);
2630 wcj
= elpShrinkSize(lotrs
->WIDTH
,model
->elpShrink
[elpDWCJ
],1.0) ;
2633 switch ( capatype
) {
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
];
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
];
2648 default : cds
= model
->elpCapa
[elpCDS
];
2649 cdp
= model
->elpCapa
[elpCDP
];
2650 cdw
= model
->elpCapa
[elpCDW
];
2651 cgp
= model
->elpCapa
[elpCGP
];
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
)
2661 elpLotrsGetShrinkDim(lotrs
,NULL
,NULL
,NULL
,&xd_s
,NULL
,&pd_s
,NULL
,NULL
, transcase
);
2663 if( model
->elpTransTechno
== elpPSP
) {
2665 ad
= (double)xd_s
*w
/ (double)(SCALE_X
*SCALE_X
) ;
2666 pd
= pd_s
/ (double)SCALE_X
;
2667 wj
= wcj
/ (double)SCALE_X
;
2669 switch( model
->elpSWJUNCAP
) {
2676 ab
= getlotrsparam( lotrs
, MBK_ABDRAIN
, NULL
, NULL
);
2677 ls
= getlotrsparam( lotrs
, MBK_LSDRAIN
, NULL
, NULL
);
2678 lg
= getlotrsparam( lotrs
, MBK_LGDRAIN
, NULL
, NULL
);
2693 cdwval
= lg
*cdw
+ cgp
*w
;
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
] ;
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
;
2708 return (float)(cdsval
+cdpval
+cdwval
);
2718 /****************************************************************************/
2719 /* fonction LotrsCapaSource() */
2720 /* calcule la capacite de source d'un transistor MBK passe en parametre. */
2722 /* Parametres en entree: */
2723 /* -------------------- */
2724 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
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
;
2739 double cssval
,cspval
,cswval
;
2740 elpmodel_list
*model
;
2741 double as
, ps
, wj
, ab
, lg
, ls
, cgp
;
2742 static char displayed
=0;
2744 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
2745 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
2746 if ( !model
) return 0.0;
2748 /* si les parametres CDxx ou CSxx sont manquants => erreur 1005 */
2749 if(model
->elpTransModel
== elpMOS
)
2751 if((model
->elpCapa
[elpCSS
] == 0.0) &&
2752 (model
->elpCapa
[elpCSP
] == 0.0) &&
2753 (model
->elpCapa
[elpCSW
] == 0.0))
2756 avt_errmsg(ELP_ERRMSG
, "002", AVT_ERROR
, elpTechnoFile
);
2757 // elpError(1005,"diffusion") ;
2763 if((lotrs
->PS
== 0) && (lotrs
->XS
== 0) && (lotrs
->WIDTH
== 0))
2766 if(ELP_CAPA_DIFF
== 1)
2768 if((lotrs
->XS
<0) || (lotrs
->PS
<0))
2770 lotrs
->XS
= model
->elpShrink
[elpWMLT
]*SCALE_X
;
2771 lotrs
->PS
= elpGetShrinkedWidth(lotrs
,model
);
2775 if(lotrs
->WIDTH
== 0)
2776 wcj
= w
= ((double)lotrs
->PS
/ (double)4.0) ;
2778 w
= (double)elpGetShrinkedWidth(lotrs
,model
);
2779 wcj
= elpShrinkSize(lotrs
->WIDTH
,model
->elpShrink
[elpDWCJ
],1.0) ;
2782 switch ( capatype
) {
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
];
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
];
2797 default : css
= model
->elpCapa
[elpCSS
];
2798 csp
= model
->elpCapa
[elpCSP
];
2799 csw
= model
->elpCapa
[elpCSW
];
2800 cgp
= model
->elpCapa
[elpCGP
];
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
)
2810 elpLotrsGetShrinkDim(lotrs
,NULL
,NULL
,&xs_s
,NULL
,&ps_s
,NULL
,NULL
,NULL
, transcase
);
2812 if( model
->elpTransTechno
== elpPSP
) {
2814 as
= (double)xs_s
*w
/ (double)(SCALE_X
*SCALE_X
) ;
2815 ps
= ps_s
/ (double)SCALE_X
;
2816 wj
= wcj
/ (double)SCALE_X
;
2818 switch( model
->elpSWJUNCAP
) {
2825 ab
= getlotrsparam( lotrs
, MBK_ABSOURCE
, NULL
, NULL
);
2826 ls
= getlotrsparam( lotrs
, MBK_LSSOURCE
, NULL
, NULL
);
2827 lg
= getlotrsparam( lotrs
, MBK_LGSOURCE
, NULL
, NULL
);
2842 cswval
= lg
*csw
+ cgp
*w
;
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
] ;
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
;
2857 return cssval
+ cspval
+ cswval
;
2866 /****************************************************************************/
2867 /* fonction LotrsCapaGrid() */
2868 /* calcule la capacite de grille d'un transistor MBK passe en parametre. */
2870 /* Parametres en entree: */
2871 /* -------------------- */
2872 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
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
;
2885 elpmodel_list
*model
;
2889 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
2890 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
2891 if ( !model
) return 0.0;
2893 same_SD
= elpSameSD_sig (lotrs
);
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) ;
2900 cgs
= (same_SD
== 0) ? model
->elpCapa
[elpCGS
] : model
->elpCapa
[elpCGS0
];
2902 /* les parametres CGxx sont obligatoires et ne sont donc pas manquant */
2904 if(model
->elpTransModel
== elpMOS
)
2907 /* contribution en surface */
2908 ((double)w
*(double)l
/ (double)(SCALE_X
*SCALE_X
))
2910 /* contribution en perimetre */
2911 (2.0*(double)w
/ (double)SCALE_X
)*model
->elpCapa
[elpCGP
]) ;
2920 /****************************************************************************/
2921 /* fonction LotrsInCapa () */
2922 /* calcule la capacite d'entree d'un transistor MBK passe en parametre. */
2924 /* Parametres en entree: */
2925 /* -------------------- */
2926 /* 1) lotrs: transistor logique MBK dont on veut calculer la capacite de */
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
,
2941 double cgs
=0.0, cgp
=0.0,vdd
;
2943 elpmodel_list
*model
;
2946 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
2947 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
2948 if ( !model
|| model
->elpTransModel
!= elpMOS
) return 0.0;
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) ;
2955 same_SD
= elpSameSD_sig ( lotrs
);
2957 switch ( capatype
) {
2958 case ELP_CAPA_UP
: if (!same_SD
)
2959 cgs
= model
->elpCapa
[elpCGSU
];
2961 cgs
= model
->elpCapa
[elpCGSU0
];
2962 cgp
= model
->elpCapa
[elpCGPUMIN
];
2964 case ELP_CAPA_UPF
: if (!same_SD
)
2965 cgs
= model
->elpCapa
[elpCGSUF
];
2967 cgs
= model
->elpCapa
[elpCGSU0
];
2968 cgp
= model
->elpCapa
[elpCGPUMIN
];
2970 case ELP_CAPA_UP_MIN
: cgs
= model
->elpCapa
[elpCGSUMIN
];
2971 cgp
= model
->elpCapa
[elpCGPUMIN
];
2973 case ELP_CAPA_UP_MAX
: cgs
= model
->elpCapa
[elpCGSUMAX
];
2974 cgp
= model
->elpCapa
[elpCGPUMAX
];
2976 case ELP_CAPA_DN
: if (!same_SD
)
2977 cgs
= model
->elpCapa
[elpCGSD
];
2979 cgs
= model
->elpCapa
[elpCGSD0
];
2980 cgp
= model
->elpCapa
[elpCGPDMIN
];
2982 case ELP_CAPA_DNF
: if (!same_SD
)
2983 cgs
= model
->elpCapa
[elpCGSDF
];
2985 cgs
= model
->elpCapa
[elpCGSD0
];
2986 cgp
= model
->elpCapa
[elpCGPDMIN
];
2988 case ELP_CAPA_DN_MIN
: cgs
= model
->elpCapa
[elpCGSDMIN
];
2989 cgp
= model
->elpCapa
[elpCGPDMIN
];
2991 case ELP_CAPA_DN_MAX
: cgs
= model
->elpCapa
[elpCGSDMAX
];
2992 cgp
= model
->elpCapa
[elpCGPDMAX
];
2994 case ELP_CAPA_TYPICAL
: if (!same_SD
)
2995 cgs
= model
->elpCapa
[elpCGS
];
2997 cgs
= model
->elpCapa
[elpCGS0
];
2998 cgp
= model
->elpCapa
[elpCGP
];
3002 c
= ((double)w
*(double)l
/ (double)(SCALE_X
*SCALE_X
)) * cgs
;
3004 cc
= ((double)w
) / ((double)SCALE_X
) * cgp
;
3008 && !mbk_LosigIsVSS(lotrs
->SOURCE
->SIG
)
3009 && !mbk_LosigIsVDD(lotrs
->SOURCE
->SIG
) )
3010 cm
= elpGetCapaSig( lofig
, lotrs
->SOURCE
->SIG
, ELP_CAPA_TYPICAL
) - cc
;
3015 c
= c
+ cc
*cm
/(cc
+cm
);
3021 && !mbk_LosigIsVSS(lotrs
->DRAIN
->SIG
)
3022 && !mbk_LosigIsVSS(lotrs
->DRAIN
->SIG
) )
3023 cm
= elpGetCapaSig( lofig
, lotrs
->DRAIN
->SIG
, ELP_CAPA_TYPICAL
) - cc
;
3028 c
= c
+ cc
*cm
/(cc
+cm
);
3035 /****************************************************************************/
3036 /* fonction LofigCapaDiff() */
3037 /* calcule les capas de diffusion des transistors de la figure lofig */
3039 /* Parametres en entree: */
3040 /* -------------------- */
3041 /* 1) lofig: figure logique MBK dont dans laquelle il faut ajouter les */
3042 /* capas de diffusion. */
3044 /* Parametre en sortie: */
3045 /* ------------------- */
3047 /****************************************************************************/
3048 elpFCT
void elpLofigCapaDiff(lofig
,transcase
)
3049 struct lofig
*lofig
;
3057 for(lotrs
= lofig
->LOTRS
; lotrs
!= NULL
; lotrs
= lotrs
->NEXT
)
3059 /* if (mbk_isdioden(getlotrsmodel(lotrs)) || mbk_isdiodep(getlotrsmodel(lotrs)))
3061 if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL0
)
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
) ;
3068 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL1
)
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
) ;
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
) ;
3084 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
)
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
) ;
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
) ;
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
) ;
3114 /****************************************************************************\
3116 * FUNC : elpLofigAddCapas
3118 * Annotate the lofig with the grid and diffusion capacitance
3120 \****************************************************************************/
3121 void elpLofigAddCapas ( lofig_list
*lofig
, int transcase
)
3124 char *techno
= namealloc ( elpTechnoFile
);
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
);
3132 ptype
->DATA
= techno
;
3134 lofig
->USER
= addptype ( lofig
->USER
, ELP_LOFIG_CAPAS_ID
, techno
);
3138 /****************************************************************************/
3139 /* fonction LofigCapaGrid() */
3140 /* calcule les capas de grille. */
3142 /* Parametres en entree: */
3143 /* -------------------- */
3144 /* 1) lofig: figure logique MBK dont dans laquelle il faut ajouter les */
3145 /* capas de grille. */
3147 /* Parametre en sortie: */
3148 /* ------------------- */
3150 /****************************************************************************/
3151 elpFCT
void elpLofigCapaGrid(lofig
,transcase
)
3152 struct lofig
*lofig
;
3159 for(lotrs
= lofig
->LOTRS
; lotrs
!= NULL
; lotrs
= lotrs
->NEXT
)
3161 trsmodel
= getlotrsmodel(lotrs
);
3162 /* if (mbk_isdioden(trsmodel) || mbk_isdiodep(trsmodel))
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
)
3169 elpAddCapaSig( lofig
, lotrs
->GRID
->SIG
, elpLotrsInCapa(lofig
,lotrs
,ELP_CAPA_TYPICAL
,transcase
,0), ELP_CAPA_TYPICAL
);
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
);
3174 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
)
3176 elpAddCapaSig( lofig
, lotrs
->GRID
->SIG
, elpLotrsInCapa(lofig
,lotrs
,ELP_CAPA_TYPICAL
,transcase
,0), ELP_CAPA_TYPICAL
);
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
);
3187 elpAddCapaSig( lofig
, lotrs
->GRID
->SIG
, elpLotrsInCapa(lofig
,lotrs
,ELP_CAPA_TYPICAL
,transcase
,0), ELP_CAPA_TYPICAL
);
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. */
3198 /* Parametres en entree: */
3199 /* -------------------- */
3200 /* 1) lotrs: Transistor dont on veut obtenir la résistance. */
3202 /* Parametre en sortie: */
3203 /* ------------------- */
3204 /* La résistance en ohms. */
3205 /****************************************************************************/
3207 elpFCT
double elpLotrsResiCanal(lotrs
,transcase
)
3208 struct lotrs
*lotrs
;
3214 elpmodel_list
*model
;
3216 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
3217 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
3218 if ( !model
) return 0.0;
3220 a
= model
->elpRss
[elpRSSL
] ;
3221 b
= model
->elpRss
[elpRSSC
] ;
3222 c
= model
->elpRss
[elpRSSW
] ;
3224 w
= ((float)elpGetShrinkedWidth(lotrs
,model
))/((float)SCALE_X
)*1e-6 ;
3225 l
= ((float)elpGetShrinkedLength(lotrs
,model
))/((float)SCALE_X
)*1e-6 ;
3227 if( a
== 0.0 || b
== 0.0 || c
== 0.0 )
3228 r
= model
->elpModel
[elpRT
]*l
/w
; /* Modèle approché utilisant MCC */
3230 r
= ( a
*l
+ b
) / ( c
*w
+ 1.0 ) ; /* Modèle fin */
3236 /****************************************************************************/
3238 double elpScm2Thr (double f
, double smin
, double smax
, double Vt
, double Vfinal
, double Vdd
, int type
)
3244 if (smin
< 0 && smax
< 0) {
3248 if (type
== elpRISE
) {
3252 x0
= (atanh ((v0
- Vt
) / (Vfinal
- Vt
)));
3253 x1
= (atanh ((v1
- Vt
) / (Vfinal
- Vt
)));
3255 x0
= (v0
- Vt
) / (Vfinal
- Vt
);
3256 x1
= (atanh ((v1
- Vt
) / (Vfinal
- Vt
)));
3258 x0
= (v0
- Vt
) / (Vfinal
- Vt
);
3259 x1
= (v1
- Vt
) / (Vfinal
- Vt
);
3264 if (type
== elpFALL
) {
3265 v1
= smax
* (Vdd
- Vfinal
) + Vfinal
;
3266 v0
= smin
* (Vdd
- Vfinal
) + Vfinal
;
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
))));
3274 x1
= (v1
- (Vdd
- Vt
)) / (Vfinal
- (Vdd
- Vt
));
3275 x0
= (v0
- (Vdd
- Vt
)) / (Vfinal
- (Vdd
- Vt
));
3280 fprintf (stderr
, "elp error : wrong transistion type\n");
3287 /****************************************************************************/
3289 double elpThr2Scm (double f
, double smin
, double smax
, double Vt
, double Vfinal
, double Vdd
, int type
)
3295 if (smin
< 0 && smax
< 0) {
3299 if (type
== elpRISE
) {
3303 x0
= (atanh ((v0
- Vt
) / (Vfinal
- Vt
)));
3304 x1
= (atanh ((v1
- Vt
) / (Vfinal
- Vt
)));
3306 x0
= (v0
- Vt
) / (Vfinal
- Vt
);
3307 x1
= (atanh ((v1
- Vt
) / (Vfinal
- Vt
)));
3309 x0
= (v0
- Vt
) / (Vfinal
- Vt
);
3310 x1
= (v1
- Vt
) / (Vfinal
- Vt
);
3315 if (type
== elpFALL
) {
3316 v1
= smax
* (Vdd
- Vfinal
) + Vfinal
;
3317 v0
= smin
* (Vdd
- Vfinal
) + Vfinal
;
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
))));
3325 x1
= (v1
- (Vdd
- Vt
)) / (Vfinal
- (Vdd
- Vt
));
3326 x0
= (v0
- (Vdd
- Vt
)) / (Vfinal
- (Vdd
- Vt
));
3331 fprintf (stderr
, "elp error : wrong transistion type\n");
3338 /****************************************************************************/
3339 void (*elpSetDefaultParam
) ( void ) ;
3341 /****************************************************************************/
3342 void elpdefaultfct2 ( void )
3347 /****************************************************************************/
3348 void elpSetFct2 (void (*f
)( void ))
3351 elpSetDefaultParam
= f
;
3353 elpSetDefaultParam
= elpdefaultfct2
;
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
) ;
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
)
3365 #ifndef __ALL__WARNING__
3372 transcase
= elpTYPICAL
;
3373 ptlotrs_param
= NULL
;
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
))
3386 elpGenParam
= elpdefault
;
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
) ;
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
)
3405 #ifndef __ALL__WARNING__
3421 transcase
= elpTYPICAL
;
3422 ptlotrs_param
= NULL
;
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
))
3438 elpCalcIleak
= elpLeakDfltFct
;
3440 /****************************************************************************/
3441 extern void elpSetCalcPAFct( void(*f
)(lotrs_list
*,char*,int,int,double,elp_lotrs_param
*,double*,double*,double*,double*) )
3446 /****************************************************************************/
3447 elpFCT
int elpLoadOnceElp ()
3450 if (!elpoldtechnofilename
||
3451 (strcasecmp(elpoldtechnofilename
,elpTechnoFile
))) {
3452 elpres_load
= elpLoadElp();
3453 if (elpoldtechnofilename
) mbkfree(elpoldtechnofilename
);
3454 elpoldtechnofilename
= mbkstrdup(elpTechnoFile
);
3459 /****************************************************************************/
3460 elpFCT
float elpGetCapaFromLocon (locon
,capatype
,transcase
)
3468 if ((!locon
) || (locon
->TYPE
!= 'T'))
3471 ELP_CALC_ONLY_CAPA
= 1;
3472 lotrs
= (lotrs_list
*)locon
->ROOT
;
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);
3482 ELP_CALC_ONLY_CAPA
= 0;
3487 /******************************************************************************\
3488 elpGetCapaSig : Renvoie la capacité mémorisée sur un signal, ou 0.0 si rien n'a
3490 \******************************************************************************/
3492 elpFCT
float elpGetCapaSig ( lofig
, losig
, type
)
3499 struct elpcapa
*capas
;
3503 ptl
= getptype( lofig
->USER
, ELP_LOFIG_TABCAPA
);
3507 capas
= (struct elpcapa
*)(ptl
->DATA
);
3508 pos
= losig
->INDEX
- 1;
3510 if( pos
< 0 || pos
>= capas
->NBSIG
) {
3512 fprintf( stderr
, "\nelp error : bad index for signal %s\n",
3519 case ELP_CAPA_TYPICAL
: capa
= capas
->TAB
[pos
];
3521 case ELP_CAPA_UP
: capa
= capas
->TAB_UP
[pos
];
3523 case ELP_CAPA_UP_MIN
: capa
= capas
->TAB_UP_MIN
[pos
];
3525 case ELP_CAPA_UP_MAX
: capa
= capas
->TAB_UP_MAX
[pos
];
3527 case ELP_CAPA_DN
: capa
= capas
->TAB_DN
[pos
];
3529 case ELP_CAPA_DN_MIN
: capa
= capas
->TAB_DN_MIN
[pos
];
3531 case ELP_CAPA_DN_MAX
: capa
= capas
->TAB_DN_MAX
[pos
];
3537 if( capa
== ELP_NOCAPA
)
3544 /******************************************************************************\
3545 elpGetTotalCapaSig : Renvoie toutes les capacités sur un signal.
3546 \******************************************************************************/
3548 elpFCT
float elpGetTotalCapaSig( lofig
, losig
, type
)
3555 c
= rcn_getcapa( lofig
, losig
);
3557 c
= elpGetCapaSig( lofig
, losig
, type
);
3563 /******************************************************************************\
3564 elpSetCapaSig : Mémorise une capacité sur un signal.
3565 \******************************************************************************/
3567 elpFCT
void elpSetCapaSig ( lofig
, losig
, capa
, type
)
3574 struct elpcapa
*capas
;
3578 ptl
= getptype( lofig
->USER
, ELP_LOFIG_TABCAPA
);
3582 lofig
->USER
= addptype( lofig
->USER
, ELP_LOFIG_TABCAPA
, NULL
);
3585 capas
= (struct elpcapa
*)mbkalloc( sizeof( struct elpcapa
) );
3586 capas
->NBSIG
= getnumberoflosig( lofig
);
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
;
3595 if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL0
)
3597 capas
->TAB
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
3599 for( n
=0 ; n
<capas
->NBSIG
; n
++ )
3600 capas
->TAB
[n
] = ELP_NOCAPA
;
3602 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL1
)
3604 capas
->TAB
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
3606 capas
->TAB_UP
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
3607 capas
->TAB_DN
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
3609 for( n
=0 ; n
<capas
->NBSIG
; n
++ )
3611 capas
->TAB
[n
] = ELP_NOCAPA
;
3613 capas
->TAB_UP
[n
] = ELP_NOCAPA
;
3614 capas
->TAB_DN
[n
] = ELP_NOCAPA
;
3617 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
)
3619 capas
->TAB
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
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
);
3628 for( n
=0 ; n
<capas
->NBSIG
; n
++ )
3630 capas
->TAB
[n
] = ELP_NOCAPA
;
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
;
3642 capas
->TAB
= mbkalloc( sizeof( float ) * capas
->NBSIG
);
3644 for( n
=0 ; n
<capas
->NBSIG
; n
++ )
3645 capas
->TAB
[n
] = ELP_NOCAPA
;
3651 capas
= (struct elpcapa
*)ptl
->DATA
;
3653 pos
= losig
->INDEX
- 1;
3654 if( pos
< 0 || pos
>= capas
->NBSIG
) {
3656 fprintf( stderr
, "\nelp error : bad index for signal %s\n",
3662 case ELP_CAPA_TYPICAL
: capas
->TAB
[pos
] = capa
;
3664 case ELP_CAPA_UP
: capas
->TAB_UP
[pos
] = capa
;
3666 case ELP_CAPA_UP_MIN
: capas
->TAB_UP_MIN
[pos
] = capa
;
3668 case ELP_CAPA_UP_MAX
: capas
->TAB_UP_MAX
[pos
] = capa
;
3670 case ELP_CAPA_DN
: capas
->TAB_DN
[pos
] = capa
;
3672 case ELP_CAPA_DN_MIN
: capas
->TAB_DN_MIN
[pos
] = capa
;
3674 case ELP_CAPA_DN_MAX
: capas
->TAB_DN_MAX
[pos
] = capa
;
3680 /******************************************************************************\
3681 elpIsCapaSig : Renvoie 1 si on a déjà mémorisé une capacité sur le signal.
3682 \******************************************************************************/
3684 elpFCT
char elpIsCapaSig( lofig
, losig
, type
)
3690 struct elpcapa
*capas
;
3693 ptl
= getptype( lofig
->USER
, ELP_LOFIG_TABCAPA
);
3697 capas
= (struct elpcapa
*)(ptl
->DATA
);
3698 pos
= losig
->INDEX
- 1;
3700 if( pos
< 0 || pos
>= capas
->NBSIG
) {
3702 fprintf( stderr
, "\nelp error : bad index for signal %s\n",
3710 case ELP_CAPA_TYPICAL
: if( !capas
->TAB
|| capas
->TAB
[pos
] == ELP_NOCAPA
)
3713 case ELP_CAPA_UP
: if( !capas
->TAB_UP
|| capas
->TAB_UP
[pos
] == ELP_NOCAPA
)
3716 case ELP_CAPA_UP_MIN
: if (!capas
->TAB_UP_MIN
|| capas
->TAB_UP_MIN
[pos
] == ELP_NOCAPA
)
3719 case ELP_CAPA_UP_MAX
: if (!capas
->TAB_UP_MAX
|| capas
->TAB_UP_MAX
[pos
] == ELP_NOCAPA
)
3722 case ELP_CAPA_DN
: if(!capas
->TAB_DN
|| capas
->TAB_DN
[pos
] == ELP_NOCAPA
)
3725 case ELP_CAPA_DN_MIN
: if (!capas
->TAB_DN_MIN
|| capas
->TAB_DN_MIN
[pos
] == ELP_NOCAPA
)
3728 case ELP_CAPA_DN_MAX
: if (!capas
->TAB_DN_MAX
|| capas
->TAB_DN_MAX
[pos
] == ELP_NOCAPA
)
3735 /******************************************************************************\
3736 elpAddCapaSig : Ajoute une capacité sur un signal dans la capacité mémorisée.
3737 \******************************************************************************/
3739 elpFCT
float elpAddCapaSig( lofig
, losig
, capa
, type
)
3747 newcapa
= capa
+ elpGetCapaSig( lofig
, losig
, type
);
3748 elpSetCapaSig( lofig
, losig
, newcapa
, type
);
3753 /******************************************************************************\
3754 elpFreeCapaLofig : Efface toutes les capacités de la lofig
3755 \******************************************************************************/
3756 elpFCT
void elpFreeCapaLofig( lofig
)
3760 struct elpcapa
*capas
;
3762 ptl
= getptype( lofig
->USER
, ELP_LOFIG_TABCAPA
);
3764 capas
= (struct elpcapa
*)(ptl
->DATA
);
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
)
3770 mbkfree( capas
->TAB
);
3772 mbkfree( capas
->TAB_UP
);
3773 mbkfree( capas
->TAB_DN
);
3775 else if ( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL2
)
3777 mbkfree( capas
->TAB
);
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
);
3787 mbkfree( capas
->TAB
);
3791 lofig
->USER
= delptype( lofig
->USER
, ELP_LOFIG_TABCAPA
);
3794 /****************************************************************************/
3795 /* fonction LofigUnShrink() */
3797 /* Repositionne les vrais tailles des transistors */
3799 /* Parametres en entree: */
3800 /* -------------------- */
3801 /* 1) lofig: figure logique MBK dont dans laquelle il faut modifier les */
3802 /* dimensions des transistors. */
3804 /* Parametre en sortie: */
3805 /* ------------------- */
3807 /****************************************************************************/
3808 elpFCT
void elpLofigUnShrink(lofig
,transcase
)
3809 struct lofig
*lofig
;
3815 for(lotrs
= lofig
->LOTRS
; lotrs
!= NULL
; lotrs
= lotrs
->NEXT
)
3816 elpLotrsUnShrink(lotrs
,transcase
) ;
3821 /****************************************************************************/
3822 /* fonction LotrsUnShrink() */
3823 /* modifie les dimensions du transistor en fonction des parametres de */
3824 /* shrink et du parametre ACM. */
3826 /* Parametres en entree: */
3827 /* -------------------- */
3828 /* 1) lotrs: transistor logique MBK dont on veut modifier les dimensions */
3830 /* Parametre en sortie: */
3831 /* ------------------- */
3833 /****************************************************************************/
3834 elpFCT
void elpLotrsUnShrink(lotrs
,transcase
)
3835 struct lotrs
*lotrs
;
3839 double deltal
, vdd
,
3841 elpmodel_list
*model
;
3843 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
3844 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
3845 if ( !model
) return;
3847 if((lotrs
->WIDTH
== 0) || (lotrs
->LENGTH
== 0))
3850 if(model
->elpTransModel
== elpMOS
)
3852 deltal
= model
->elpShrink
[elpDL
] * (double)SCALE_X
;
3853 deltaw
= model
->elpShrink
[elpDW
] * (double)SCALE_X
;
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
))) ;
3860 if(elpGeneral
[elpACM
] == 1.0)
3862 lotrs
->XS
= lotrs
->XD
= elpDouble2Long((model
->elpShrink
[elpWMLT
] * (double)SCALE_X
)) ;
3863 lotrs
->PS
= lotrs
->PD
= lotrs
->WIDTH
;
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
;
3877 elpmodel_list
*model
;
3879 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
3880 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
3881 if ( !model
) return;
3883 if((lotrs
->WIDTH
== 0) || (lotrs
->LENGTH
== 0))
3886 if(model
->elpTransModel
== elpMOS
)
3888 deltal
= model
->elpShrink
[elpDL
] * (double)SCALE_X
;
3889 deltaw
= model
->elpShrink
[elpDW
] * (double)SCALE_X
;
3893 *length_s
= elpDouble2Long((((double)length
- deltal
) / model
->elpShrink
[elpLMLT
])) ;
3895 *width_s
= elpDouble2Long((((double)width
- deltaw
) / model
->elpShrink
[elpWMLT
]));
3901 /****************************************************************************/
3902 /* fonction LotrsGetShrinkDim() */
3903 /* modifie les dimensions du transistor en fonction des parametres de */
3904 /* shrink et du parametre ACM. */
3906 /* Parametres en entree: */
3907 /* -------------------- */
3908 /* 1) lotrs: transistor logique MBK dont on veut modifier les dimensions */
3910 /* Parametre en sortie: */
3911 /* ------------------- */
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
;
3928 long lactive
,wactive
;
3929 double deltal
, deltaw
, dla
, dwa
,vdd
;
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
;
3936 elpmodel_list
*model
;
3938 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
3939 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
3940 if ( !model
) return;
3942 if((lotrs
->WIDTH
== 0) || (lotrs
->LENGTH
== 0)){
3944 *xs_s
= elpDouble2Long( (double)lotrs
->XS
) ;
3946 *xd_s
= elpDouble2Long( (double)lotrs
->XD
) ;
3948 *ps_s
= elpDouble2Long( (double)lotrs
->PS
) ;
3950 *pd_s
= elpDouble2Long( (double)lotrs
->PD
) ;
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
;
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
)
3964 if (width_s
!= NULL
)
3966 if (ptlactive
!= NULL
)
3967 *ptlactive
= lactive
;
3968 if (ptwactive
!= NULL
)
3969 *ptwactive
= wactive
;
3971 ptlotrs_param_filled
= 0 ;
3973 /******************************************************************************************************/
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 ;
3981 elpCalcPAFct( lotrs
,
3982 getlotrsmodel( lotrs
),
3983 MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
,
3992 xs
= as
* SCALE_X
* SCALE_X
* 1.0e12
/ lotrs
->WIDTH
;
3996 *xs_s
= elpDouble2Long(((model
->elpShrink
[elpWMLT
] - deltaw
/(double)w_s
) * xs
)) ;
3999 /******************************************************************************************************/
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 ;
4007 elpCalcPAFct( lotrs
,
4008 getlotrsmodel( lotrs
),
4009 MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
,
4018 xd
= ad
* SCALE_X
* SCALE_X
* 1.0e12
/ lotrs
->WIDTH
;
4022 *xd_s
= elpDouble2Long(((model
->elpShrink
[elpWMLT
] - deltaw
/(double)w_s
) * xd
)) ;
4025 /******************************************************************************************************/
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 ;
4034 elpCalcPAFct( lotrs
,
4035 getlotrsmodel( lotrs
),
4036 MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
,
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
4049 Le passage de l'un à l'autre s'effectue à l'aide le la relation
4050 de la doc bsim4v30.pdf p 115.
4053 ps
= ps
* SCALE_X
* 1.0e6
+ lotrs
->WIDTH
;
4056 ps
= lotrs
->PS
<0?0:lotrs
->PS
;
4060 /******************************************************************************************************/
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 ;
4069 elpCalcPAFct( lotrs
,
4070 getlotrsmodel( lotrs
),
4071 MLO_IS_TRANSN(lotrs
->TYPE
) ? elpNMOS
: elpPMOS
,
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
4084 Le passage de l'un à l'autre s'effectue à l'aide le la relation
4085 de la doc bsim4v30.pdf p 115.
4088 pd
= pd
* SCALE_X
* 1.0e6
+ lotrs
->WIDTH
;
4091 pd
= lotrs
->PD
<0?0:lotrs
->PD
;
4095 if(elpGeneral
[elpACM
] == 1.0) {
4097 *xs_s
= elpDouble2Long((model
->elpShrink
[elpWMLT
] * (double)SCALE_X
)) ;
4099 *xd_s
= elpDouble2Long((model
->elpShrink
[elpWMLT
] * (double)SCALE_X
)) ;
4110 /****************************************************************************/
4111 /* fonction elpGetDeltaShrinkWidth */
4112 /****************************************************************************/
4113 elpFCT
void elpGetDeltaShrinkWidth (lotrs
,ptdeff
,ptdactive
,ptwmlt
,transcase
)
4114 struct lotrs
*lotrs
;
4120 long deltaw
=0, dwa
=0;
4122 elpmodel_list
*model
;
4124 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
4125 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
4126 if ( !model
) return;
4128 if((lotrs
->WIDTH
== 0) || (lotrs
->LENGTH
== 0)){
4131 if (ptdactive
!= NULL
)
4136 if(model
->elpTransModel
== elpMOS
) {
4137 deltaw
= elpDouble2Long(model
->elpShrink
[elpDW
] * (double)SCALE_X
) ;
4138 dwa
= elpDouble2Long(model
->elpShrink
[elpDWC
] * (double)SCALE_X
) ;
4142 if (ptdactive
!= NULL
)
4145 *ptwmlt
= elpDouble2Long(model
->elpShrink
[elpWMLT
]);
4151 // Func : elpGetShrinkedLength
4152 // Obtient la longueur shrinkee d'un transistor
4154 long elpGetShrinkedLength (lotrs_list
*lotrs
, elpmodel_list
*model
)
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
)) ;
4168 // Func : elpGetShrinkedWidth
4169 // Obtient la largueur shrinkee d'un transistor
4171 long elpGetShrinkedWidth (lotrs_list
*lotrs
, elpmodel_list
*model
)
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
)) ;
4184 /****************************************************************************\
4185 FUNCTION : elp_lotrs_param_alloc
4186 \****************************************************************************/
4187 elp_lotrs_param
*elp_lotrs_param_alloc ( void )
4189 elp_lotrs_param
*ptlotrs_param
;
4192 ptlotrs_param
= (elp_lotrs_param
*) mbkalloc (sizeof (elp_lotrs_param
));
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
;
4199 ptlotrs_param
->VBULK
= ELPINITVBULK
;
4200 ptlotrs_param
->ISVBSSET
= 0;
4201 ptlotrs_param
->longkey
= NULL
;
4202 return ptlotrs_param
;
4205 /******************************************************************************\
4206 FUNCTION : elp_lotrs_param_free
4207 \******************************************************************************/
4208 void elp_lotrs_param_free (elp_lotrs_param
*ptlotrs_param
)
4212 freechain(ptlotrs_param
->longkey
);
4213 mbkfree (ptlotrs_param
);
4217 /******************************************************************************\
4218 FUNCTION : elp_lotrs_param_create
4220 Cree une structure d'instance avec des parametres specifiques si le transistor
4222 \******************************************************************************/
4223 elp_lotrs_param
*elp_lotrs_param_create (lotrs_list
*lotrs
)
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
;
4231 ptlotrs_param
= elp_lotrs_param_alloc ();
4233 mulu0
= getlotrsparam (lotrs
,MBK_MULU0
,NULL
,&status
);
4235 ptlotrs_param
->PARAM
[elpMULU0
] = mulu0
;
4237 ptlotrs_param
->PARAM
[elpMULU0
] = 1.0;
4239 delvt0
= getlotrsparam (lotrs
,MBK_DELVT0
,NULL
,&status
);
4240 if ( status
== 1 ) {
4241 ptlotrs_param
->PARAM
[elpDELVT0
] = delvt0
;
4244 ptlotrs_param
->PARAM
[elpDELVT0
] = 0.0;
4246 sa
= getlotrsparam (lotrs
,MBK_SA
,NULL
,&status
);
4248 ptlotrs_param
->PARAM
[elpSA
] = sa
;
4250 sb
= getlotrsparam (lotrs
,MBK_SB
,NULL
,&status
);
4252 ptlotrs_param
->PARAM
[elpSB
] = sb
;
4254 sd
= getlotrsparam (lotrs
,MBK_SD
,NULL
,&status
);
4256 ptlotrs_param
->PARAM
[elpSD
] = sd
;
4258 sc
= getlotrsparam (lotrs
,MBK_SC
,NULL
,&status
);
4260 ptlotrs_param
->PARAM
[elpSC
] = sc
;
4262 sca
= getlotrsparam (lotrs
,MBK_SCA
,NULL
,&status
);
4264 ptlotrs_param
->PARAM
[elpSCA
] = sca
;
4266 scb
= getlotrsparam (lotrs
,MBK_SCB
,NULL
,&status
);
4268 ptlotrs_param
->PARAM
[elpSCB
] = scb
;
4270 scc
= getlotrsparam (lotrs
,MBK_SCC
,NULL
,&status
);
4272 ptlotrs_param
->PARAM
[elpSCC
] = scc
;
4274 nf
= getlotrsparam (lotrs
,MBK_NF
,NULL
,&status
);
4276 ptlotrs_param
->PARAM
[elpNF
] = nf
;
4278 nf
= getlotrsparam (lotrs
,MBK_NFING
,NULL
,&status
);
4280 ptlotrs_param
->PARAM
[elpNF
] = nf
;
4283 val
= getlotrsparam (lotrs
,MBK_M
,NULL
,&status
);
4285 ptlotrs_param
->PARAM
[elpM
] = val
;
4287 val
= getlotrsparam (lotrs
,MBK_MULT
,NULL
,&status
);
4289 ptlotrs_param
->PARAM
[elpM
] = val
;
4291 ptlotrs_param
->PARAM
[elpM
] = 1.0;
4293 val
= getlotrsparam (lotrs
,MBK_NRS
,NULL
,&status
);
4295 ptlotrs_param
->PARAM
[elpNRS
] = val
;
4297 val
= getlotrsparam (lotrs
,MBK_NRD
,NULL
,&status
);
4299 ptlotrs_param
->PARAM
[elpNRD
] = val
;
4301 if ( lotrs
->BULK
&& lotrs
->BULK
->SIG
&& getlosigalim(lotrs
->BULK
->SIG
, &vbulk
) )
4302 ptlotrs_param
->VBULK
= vbulk
;
4304 ptlotrs_param
->ISVBSSET
=0;
4305 ptlotrs_param
->longkey
=NULL
;
4306 return ptlotrs_param
;
4309 /****************************************************************************\
4310 FUNCTION : elp_lotrs_param_dup
4311 \****************************************************************************/
4312 elp_lotrs_param
*elp_lotrs_param_dup ( elp_lotrs_param
*src
)
4314 elp_lotrs_param
*dest
= NULL
;
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
) ;
4341 /******************************************************************************\
4342 FUNCTION : elp_lotrs_param_get
4344 \******************************************************************************/
4345 void elp_lotrs_param_get (lotrs_list
*lotrs
,
4362 double delvt0
, mulu0
;
4363 double sa
, sb
, sd
,nf
;
4364 double sca
, scb
, scc
, sc
;
4370 delvt0
= getlotrsparam (lotrs
,MBK_DELVT0
,NULL
,&status
);
4377 mulu0
= getlotrsparam (lotrs
,MBK_MULU0
,NULL
,&status
);
4384 sa
= getlotrsparam (lotrs
,MBK_SA
,NULL
,&status
);
4388 *ptsa
= ELPINITVALUE
;
4391 sb
= getlotrsparam (lotrs
,MBK_SB
,NULL
,&status
);
4395 *ptsb
= ELPINITVALUE
;
4398 sd
= getlotrsparam (lotrs
,MBK_SD
,NULL
,&status
);
4402 *ptsd
= ELPINITVALUE
;
4405 nf
= getlotrsparam (lotrs
,MBK_NF
,NULL
,&status
);
4409 nf
= getlotrsparam (lotrs
,MBK_NFING
,NULL
,&status
);
4417 val
= getlotrsparam (lotrs
,MBK_M
,NULL
,&status
);
4421 val
= getlotrsparam (lotrs
,MBK_MULT
,NULL
,&status
);
4429 val
= getlotrsparam (lotrs
,MBK_NRS
,NULL
,&status
);
4436 val
= getlotrsparam (lotrs
,MBK_NRD
,NULL
,&status
);
4443 if ( lotrs
->BULK
&& lotrs
->BULK
->SIG
&& getlosigalim(lotrs
->BULK
->SIG
, &vbulk
) )
4446 if ( MLO_IS_TRANSN(lotrs
->TYPE
) )
4449 *ptvbulk
= elpGeneral
[elpGVDDMAX
];
4453 sc
= getlotrsparam (lotrs
,MBK_SC
,NULL
,&status
);
4457 *ptsc
= ELPINITVALUE
;
4460 sca
= getlotrsparam (lotrs
,MBK_SCA
,NULL
,&status
);
4464 *ptsca
= ELPINITVALUE
;
4467 scb
= getlotrsparam (lotrs
,MBK_SCB
,NULL
,&status
);
4471 *ptscb
= ELPINITVALUE
;
4474 scc
= getlotrsparam (lotrs
,MBK_SCC
,NULL
,&status
);
4478 *ptscc
= ELPINITVALUE
;
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
)
4495 if ( precision
< 0.0 ) {
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
)
4510 /****************************************************************************\
4511 FUNCTION : elp_scale_vth
4512 \****************************************************************************/
4513 double elp_scale_vth ( lotrs_list
*lotrs
, elpmodel_list
*model
)
4516 double vt
,res
,delta
;
4518 if ( lotrs
&& model
) {
4519 vt
= model
->elpModel
[elpVT
];
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
;
4531 /****************************************************************************\
4532 FUNCTION : elp_scale_a
4533 \****************************************************************************/
4534 double elp_scale_a ( lotrs_list
*lotrs
, elpmodel_list
*model
)
4539 if ( lotrs
&& model
) {
4540 a
= model
->elpModel
[elpA
];
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
] ;
4553 /****************************************************************************\
4554 FUNCTION : elpDriveModel
4555 \****************************************************************************/
4556 void elpDriveModel (char *filename
, elpmodel_list
*model
)
4560 sprintf(filename
, "%s%s",filename
,".elp") ;
4561 file
= fopen(filename
,"a") ;
4563 fprintf(stderr
, "elp error: can't open file %s to drive!!!\n",filename
) ;
4567 elpVerifModel(model
) ;
4568 elpDriveOneModel (file
, model
);
4570 if (fclose(file
) != 0)
4571 avt_errmsg(ELP_ERRMSG
, "003", AVT_ERROR
, filename
);
4572 // elpError(1003,filename) ;
4575 /****************************************************************************\
4576 FUNCTION : elpDriveModel
4577 \****************************************************************************/
4578 void elpDriveOneModel (FILE *file
, elpmodel_list
*model
)
4580 if ( !model
) return;
4581 if(model
->elpTransIndex
== elpNOINDEX
)
4582 fprintf(file
, "BEGIN %s\n\n",model
->elpModelName
) ;
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") ;
4592 fprintf(file
, "TYPE = NMOS\n\n") ;
4594 if (model
->elpTransCase
== elpTYPICAL
) {
4595 fprintf(file
, "#model for best, typical or worst case\n") ;
4596 fprintf(file
, "CASE = TYPICAL\n\n") ;
4598 if(model
->elpTransCase
!= elpTYPICAL
)
4600 fprintf(file
, "#model for best, typical or worst case\n") ;
4601 fprintf(file
, "CASE = %s\n\n",(model
->elpTransCase
== elpWORST
) ? "WORST" : "BEST") ;
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
) ;
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") ;
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
) ;
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
]) ;
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
]) ;
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
]) ;
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
]) ;
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
]) ;
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
]) ;
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
]) ;
4729 if(model
->elpTransIndex
== elpNOINDEX
)
4730 fprintf(file
, "END %s\n\n",model
->elpModelName
) ;
4732 fprintf(file
, "END %s [%d]\n\n",model
->elpModelName
, model
->elpTransIndex
) ;
4735 /*******************************************************************************
4736 * function elp_getlotrsalim *
4737 *******************************************************************************/
4738 double elpCalcIleakage( lotrs_list
*lotrs
,
4741 double vgs
, double vds
, double vbs
,
4742 double *BLeak
, double *DLeak
, double *SLeak
4746 long xs_s
,ps_s
,xd_s
,pd_s
;
4749 elpmodel_list
*model
;
4750 elp_lotrs_param
*ptlotrs_param
;
4752 vdd
= elpGetVddFromCorner ( lotrs
, transcase
);
4753 model
= elpGetModel(lotrs
,vdd
,transcase
) ;
4754 if (!model
) return 0.0;
4756 elpLotrsGetShrinkDim(lotrs
,NULL
,NULL
,
4757 &xs_s
,&xd_s
,&ps_s
,&pd_s
,
4758 NULL
,NULL
, transcase
);
4760 ptlotrs_param
= elp_lotrs_param_create (lotrs
);
4762 if(lotrs
->WIDTH
== 0)
4763 w
= ((double)lotrs
->PS
/ (double)4.0) ;
4765 w
= (double)elpGetShrinkedWidth(lotrs
,model
);
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
;
4772 Ileak
= elpCalcIleak(getlotrsmodel(lotrs
), lotrstype
,
4773 (double)lotrs
->LENGTH
/(double)(SCALE_X
),
4774 (double)lotrs
->WIDTH
/(double)(SCALE_X
),
4781 elp_lotrs_param_free (ptlotrs_param
);
4786 int elpHack_GetNodeLocon( locon_list
*locon
)
4790 if( !locon
->SIG
->PRCN
)
4791 addlorcnet( locon
->SIG
);
4795 node
= locon
->PNODE
->DATA
;
4798 if( locon
->SIG
->PRCN
->PWIRE
)
4799 node
= locon
->SIG
->PRCN
->PWIRE
->NODE1
;
4803 if( locon
->SIG
->PRCN
->PCTC
)
4804 node
= rcn_ctcnode( (loctc_list
*)(locon
->SIG
->PRCN
->PCTC
->DATA
), locon
->SIG
);
4809 setloconnode( locon
, node
);
4815 void elpHack_AddCapa( lotrs_list
*lotrs
, losig_list
*vss
, char where
, float capa
)
4822 locon
= lotrs
->GRID
;
4825 locon
= lotrs
->SOURCE
;
4828 locon
= lotrs
->DRAIN
;
4832 if( locon
->SIG
== vss
)
4835 node
= elpHack_GetNodeLocon( locon
);
4837 addloctc( locon
->SIG
, node
, vss
, 1, capa
*V_FLOAT_TAB
[__AVT_HACK_COEF_CGND
].VALUE
);
4840 void elpHack_AddCtcCapa( locon_list
*locon1
, locon_list
*locon2
, float capa
)
4845 if( !locon1
->SIG
->PRCN
)
4846 addlorcnet( locon1
->SIG
);
4848 node1
= elpHack_GetNodeLocon( locon1
);
4849 node2
= elpHack_GetNodeLocon( locon2
);
4851 addloctc( locon1
->SIG
, node1
, locon2
->SIG
, node2
, capa
*V_FLOAT_TAB
[__AVT_HACK_COEF_CCTK
].VALUE
);
4854 void elpHackNetlistResi( lofig_list
*lofig
)
4862 for( losig
= lofig
->LOSIG
; losig
; losig
= losig
->NEXT
) {
4868 /* remove all resistance */
4869 while( losig
->PRCN
->PWIRE
)
4870 dellowire( losig
, losig
->PRCN
->PWIRE
->NODE1
, losig
->PRCN
->PWIRE
->NODE2
);
4872 /* set all locon to node 1 */
4873 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
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 );
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 );
4893 void elpHackNetlistCapa( lofig_list
*hackedlofig
, int whatjob
)
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
;
4903 elpmodel_list
*elpmodel
;
4917 sig_vss_backup
= NULL
;
4918 sig_vdd_backup
= NULL
;
4920 for( losig
= hackedlofig
->LOSIG
; losig
; losig
= losig
->NEXT
) {
4921 if( mbk_LosigIsVSS( losig
) ) {
4922 if( losig
->PRCN
&& losig
->PRCN
->PCTC
)
4925 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
4926 if( ptl
&& ptl
->DATA
)
4927 sig_vss_backup
= losig
;
4930 if( mbk_LosigIsVDD( losig
) ) {
4931 if( losig
->PRCN
&& losig
->PRCN
->PCTC
)
4934 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
4935 if( ptl
&& ptl
->DATA
)
4936 sig_vdd_backup
= losig
;
4942 sig_vss
= sig_vss_backup
;
4944 sig_vdd
= sig_vdd_backup
;
4946 if( !sig_vss
|| !sig_vdd
) {
4947 printf( "can't find supply signal !\n" );
4951 for( lotrs
= hackedlofig
->LOTRS
; lotrs
; lotrs
= lotrs
->NEXT
) {
4953 if( MLO_IS_TRANSN( lotrs
->TYPE
) )
4954 sig_supply
= sig_vss
;
4956 sig_supply
= sig_vdd
;
4958 vdd
= elpGetVddFromCorner( lotrs
, elpTYPICAL
) ;
4959 elpmodel
= elpGetModel( lotrs
, vdd
, elpTYPICAL
) ;
4961 cs
= elpLotrsCapaSource( lotrs
, ELP_CAPA_TYPICAL
, elpTYPICAL
);
4962 cd
= elpLotrsCapaDrain( lotrs
, ELP_CAPA_TYPICAL
, elpTYPICAL
);
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 ) ;
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
) ;
4975 elpHack_AddCapa( lotrs
, sig_supply
, 's', cs
-cgs
);
4976 elpHack_AddCapa( lotrs
, sig_supply
, 'd', cd
-cgd
);
4978 elpHack_AddCapa( lotrs
, sig_supply
, 'g', cgi
);
4980 if( whatjob
== ELP_HACK_FIX_CAPA_TO_GND
) {
4982 elpHack_AddCapa( lotrs
, sig_supply
, 's', cgs
+csi
);
4983 elpHack_AddCapa( lotrs
, sig_supply
, 'g', cgs
+csi
);
4985 elpHack_AddCapa( lotrs
, sig_supply
, 'd', cgd
+cdi
);
4986 elpHack_AddCapa( lotrs
, sig_supply
, 'g', cgd
+cdi
);
4990 if( lotrs
->GRID
!= lotrs
->DRAIN
)
4991 elpHack_AddCtcCapa( lotrs
->GRID
, lotrs
->DRAIN
, cgd
+cdi
);
4993 if( lotrs
->GRID
!= lotrs
->SOURCE
)
4994 elpHack_AddCtcCapa( lotrs
->GRID
, lotrs
->SOURCE
, cgs
+csi
);