1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : STM Version 1.00 */
6 /* Fichier : stm_mod_eval.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Gilles Augustins */
13 /****************************************************************************/
15 /****************************************************************************/
17 /****************************************************************************/
21 /****************************************************************************/
23 /****************************************************************************/
25 float stm_mod_constraint (timing_model
*tmodel
, float inputslew
, float clockslew
)
28 switch (tmodel
->UTYPE
) {
30 return stm_modtbl_constraint (tmodel
->UMODEL
.TABLE
, inputslew
, clockslew
);
33 avt_errmsg (STM_ERRMSG
, "010", AVT_ERROR
);
37 return stm_modpln_constraint (tmodel
->UMODEL
.POLYNOM
, inputslew
, clockslew
);
40 return stm_modfct_constraint (tmodel
->UMODEL
.FUNCTION
, inputslew
, clockslew
);
48 /****************************************************************************/
50 float stm_mod_slew_pi (timing_model
* tmodel
, float c1
, float c2
, float r
, float slew
, stm_pwl
*pwl
, stm_pwl
**ptpwl
, char *signame
)
57 float f
= STM_DEF_SLEW
;
60 switch (tmodel
->UTYPE
) {
63 f
= stm_modtbl_slew (tmodel
->UMODEL
.TABLE
, load
, slew
);
66 if( STM_IMAX_FOR_PILOAD
) {
67 vth
= stm_modscm_vth (tmodel
->UMODEL
.SCM
);
68 imax
= stm_modscm_imax (tmodel
->UMODEL
.SCM
);
69 cconf
= stm_modscm_cconf (tmodel
->UMODEL
.SCM
, slew
);
70 load
= stm_capaeq (imax
, r
, c1
+ cconf
, c2
, vth
, signame
);
75 load
= stm_modscm_capaeq (tmodel
->UMODEL
.SCM
, slew
, r
, c1
, c2
, signame
);
77 f
= stm_modscm_slew (tmodel
->UMODEL
.SCM
, slew
, pwl
, ptpwl
, load
);
81 f
= stm_modpln_slew (tmodel
->UMODEL
.POLYNOM
, slew
, load
);
85 f
= stm_modfct_slew (tmodel
->UMODEL
.FUNCTION
, slew
, load
);
88 vth
= stm_mod_vth(tmodel
);
89 vdd
= stm_mod_vdd(tmodel
);
90 f
= stm_modiv_slew_pi (tmodel
->UMODEL
.IV
, slew
, r
, c1
, c2
, vth
, vdd
);
95 if( f
< 1.0 ) f
= 1.0 ;
99 /****************************************************************************/
101 float stm_mod_delay_pi (timing_model
*tmodel
, float c1
, float c2
, float r
, float slew
, stm_pwl
*pwl
, char *signame
)
110 switch (tmodel
->UTYPE
) {
113 return stm_modtbl_delay (tmodel
->UMODEL
.TABLE
, load
, slew
);
116 if( STM_IMAX_FOR_PILOAD
) {
117 vth
= stm_modscm_vth (tmodel
->UMODEL
.SCM
);
118 imax
= stm_modscm_imax (tmodel
->UMODEL
.SCM
);
119 cconf
= stm_modscm_cconf (tmodel
->UMODEL
.SCM
, slew
);
120 load
= stm_capaeq (imax
, r
, c1
+ cconf
, c2
, vth
, signame
);
124 load
= stm_modscm_capaeq (tmodel
->UMODEL
.SCM
, slew
, r
, c1
, c2
, signame
);
125 return stm_modscm_delay (tmodel
->UMODEL
.SCM
, slew
, pwl
, load
);
129 return stm_modpln_delay (tmodel
->UMODEL
.POLYNOM
, slew
, load
);
133 return stm_modfct_delay (tmodel
->UMODEL
.FUNCTION
, slew
, load
);
136 vth
= stm_mod_vth(tmodel
);
137 vdd
= stm_mod_vdd(tmodel
);
138 return stm_modiv_delay_pi (tmodel
->UMODEL
.IV
, slew
, r
, c1
, c2
, vth
, vdd
);
146 /****************************************************************************/
148 float stm_mod_slew (timing_model
* tmodel
, float load
, float slew
, stm_pwl
*pwl
, stm_pwl
**ptpwl
, char *signame
)
152 float f
= STM_DEF_SLEW
;
155 switch (tmodel
->UTYPE
) {
157 f
= stm_modtbl_slew (tmodel
->UMODEL
.TABLE
, load
, slew
);
160 f
= stm_modscm_slew (tmodel
->UMODEL
.SCM
, slew
, pwl
, ptpwl
, load
);
163 f
= stm_modpln_slew (tmodel
->UMODEL
.POLYNOM
, slew
, load
);
166 f
= stm_modfct_slew (tmodel
->UMODEL
.FUNCTION
, slew
, load
);
169 vth
= stm_mod_vth(tmodel
);
170 vdd
= stm_mod_vdd(tmodel
);
171 f
= stm_modiv_slew_c (tmodel
->UMODEL
.IV
, slew
, load
, vth
, vdd
);
174 if( f
< 1.0 ) f
= 1.0 ;
178 /****************************************************************************/
180 float stm_mod_delay (timing_model
*tmodel
, float load
, float slew
, stm_pwl
*pwl
, char *signame
)
186 switch (tmodel
->UTYPE
) {
188 return stm_modtbl_delay (tmodel
->UMODEL
.TABLE
, load
, slew
);
191 return stm_modscm_delay (tmodel
->UMODEL
.SCM
, slew
, pwl
, load
);
194 return stm_modpln_delay (tmodel
->UMODEL
.POLYNOM
, slew
, load
);
197 return stm_modfct_delay (tmodel
->UMODEL
.FUNCTION
, slew
, load
);
200 vth
= stm_mod_vth(tmodel
);
201 vdd
= stm_mod_vdd(tmodel
);
202 return stm_modiv_delay_c (tmodel
->UMODEL
.IV
, slew
, load
, vth
, vdd
);
209 /****************************************************************************/
211 void stm_mod_timing_pi( timing_model
*dmodel
,
212 timing_model
*fmodel
,
234 if( delay
) *delay
= 0.0 ;
235 if( fout
) *fout
= fin
;
236 if( pwlout
) *pwlout
= NULL
;
238 /* Si les modèles ne sont pas les meme pour le front et le delai, il ne faut pas faire l'hypothèse
239 que la capacité equivalente à la charge en pi sera la meme */
240 if( dmodel
->UTYPE
== STM_MOD_MODSCM
&&
241 fmodel
->UTYPE
== STM_MOD_MODSCM
&&
242 dmodel
->UMODEL
.SCM
== fmodel
->UMODEL
.SCM
) {
246 if( V_BOOL_TAB
[ __AVT_PRECISE_PILOAD
].VALUE
) {
247 stm_modscm_timing (dmodel
->UMODEL
.SCM
, fmodel
->UMODEL
.SCM
, fin
, pwlin
, driver
, r
, c1
, c2
, delay
, fout
, pwlout
, dmodel
->NAME
);
250 if( STM_IMAX_FOR_PILOAD
) {
251 vth
= stm_modscm_vth (dmodel
->UMODEL
.SCM
);
252 imax
= stm_modscm_imax (dmodel
->UMODEL
.SCM
);
253 cconf
= stm_modscm_cconf (dmodel
->UMODEL
.SCM
, fin
);
254 load
= stm_capaeq (imax
, r
, c1
+ cconf
, c2
, vth
, signame
);
258 load
= stm_modscm_capaeq (dmodel
->UMODEL
.SCM
, fin
, r
, c1
, c2
, signame
);
259 stm_modscm_timing (dmodel
->UMODEL
.SCM
, fmodel
->UMODEL
.SCM
, fin
, pwlin
, driver
, -1.0, load
, -1.0, delay
, fout
, pwlout
, dmodel
->NAME
);
264 if( dmodel
== fmodel
&& dmodel
->UTYPE
== STM_MOD_MODIV
) {
265 vth
= stm_mod_vth(dmodel
);
266 vdd
= stm_mod_vdd(dmodel
);
267 stm_modiv_timing_pi( dmodel
->UMODEL
.IV
, fin
, r
, c1
, c2
, vth
, vdd
, delay
, fout
);
271 if( delay
&& dmodel
) {
272 switch (dmodel
->UTYPE
) {
275 *delay
= stm_modtbl_delay (dmodel
->UMODEL
.TABLE
, load
, fin
);
278 if( STM_IMAX_FOR_PILOAD
) {
279 vth
= stm_modscm_vth (dmodel
->UMODEL
.SCM
);
280 imax
= stm_modscm_imax (dmodel
->UMODEL
.SCM
);
281 cconf
= stm_modscm_cconf (dmodel
->UMODEL
.SCM
, fin
);
282 load
= stm_capaeq (imax
, r
, c1
+ cconf
, c2
, vth
, signame
);
286 load
= stm_modscm_capaeq (dmodel
->UMODEL
.SCM
, fin
, r
, c1
, c2
, signame
);
287 *delay
= stm_modscm_delay (dmodel
->UMODEL
.SCM
, fin
, pwlin
, load
);
291 *delay
= stm_modpln_delay (dmodel
->UMODEL
.POLYNOM
, fin
, load
);
295 *delay
= stm_modfct_delay (dmodel
->UMODEL
.FUNCTION
, fin
, load
);
299 vth
= stm_mod_vth(dmodel
);
300 vdd
= stm_mod_vdd(dmodel
);
301 *delay
= stm_modiv_delay_c (dmodel
->UMODEL
.IV
, fin
, load
, vth
, vdd
);
306 if( fout
&& fmodel
) {
307 switch (fmodel
->UTYPE
) {
310 *fout
= stm_modtbl_slew (fmodel
->UMODEL
.TABLE
, load
, fin
);
313 if( STM_IMAX_FOR_PILOAD
) {
314 vth
= stm_modscm_vth (fmodel
->UMODEL
.SCM
);
315 imax
= stm_modscm_imax (fmodel
->UMODEL
.SCM
);
316 cconf
= stm_modscm_cconf (fmodel
->UMODEL
.SCM
, fin
);
317 load
= stm_capaeq (imax
, r
, c1
+ cconf
, c2
, vth
, signame
);
321 load
= stm_modscm_capaeq (fmodel
->UMODEL
.SCM
, fin
, r
, c1
, c2
, signame
);
322 *fout
= stm_modscm_slew (fmodel
->UMODEL
.SCM
, fin
, pwlin
, pwlout
, load
);
326 *fout
= stm_modpln_slew (fmodel
->UMODEL
.POLYNOM
, fin
, load
);
330 *fout
= stm_modfct_slew (fmodel
->UMODEL
.FUNCTION
, fin
, load
);
334 vth
= stm_mod_vth(fmodel
);
335 vdd
= stm_mod_vdd(fmodel
);
336 *fout
= stm_modiv_slew_c (fmodel
->UMODEL
.IV
, fin
, load
, vth
, vdd
);
344 if( *fout
< 1.0 ) *fout
= 1.0 ;
346 if (delay
&& V_BOOL_TAB
[__STM_PRECISION_WARNING
].VALUE
) {
347 if (fin
> V_INT_TAB
[__STM_PRECISION_THRESHOLD
].VALUE
* (*delay
)) {
351 avt_errmsg(STM_ERRMSG
, "052", AVT_WARNING
, inputname
, dirin
, signame
, dirout
, (int)fin
, (int)load
);
356 /****************************************************************************/
358 void stm_mod_timing( timing_model
*dmodel
,
359 timing_model
*fmodel
,
376 if( delay
) *delay
= 0.0 ;
377 if( fout
) *fout
= fin
;
378 if( pwlout
) *pwlout
= NULL
;
380 if( dmodel
->UTYPE
== STM_MOD_MODSCM
&&
381 fmodel
->UTYPE
== STM_MOD_MODSCM
) {
382 stm_modscm_timing (dmodel
->UMODEL
.SCM
, fmodel
->UMODEL
.SCM
, fin
, pwlin
, driver
, -1.0, load
, -1.0, delay
, fout
, pwlout
, dmodel
->NAME
);
385 if( dmodel
== fmodel
&& dmodel
->UTYPE
== STM_MOD_MODIV
) {
386 vth
= stm_mod_vth(dmodel
);
387 vdd
= stm_mod_vdd(dmodel
);
388 stm_modiv_timing_c( dmodel
->UMODEL
.IV
, fin
, load
, vth
, vdd
, delay
, fout
);
392 if( delay
&& dmodel
) {
393 switch (dmodel
->UTYPE
) {
395 *delay
= stm_modtbl_delay (dmodel
->UMODEL
.TABLE
, load
, fin
);
398 stm_modscm_timing (dmodel
->UMODEL
.SCM
, fmodel
->UMODEL
.SCM
, fin
, pwlin
, driver
, -1.0, load
, -1.0, delay
, fout
, pwlout
, dmodel
->NAME
);
401 *delay
= stm_modpln_delay (dmodel
->UMODEL
.POLYNOM
, fin
, load
);
404 *delay
= stm_modfct_delay (dmodel
->UMODEL
.FUNCTION
, fin
, load
);
407 vth
= stm_mod_vth(dmodel
);
408 vdd
= stm_mod_vdd(dmodel
);
409 *delay
= stm_modiv_delay_c (dmodel
->UMODEL
.IV
, fin
, load
, vth
, vdd
);
414 if( fout
&& fmodel
) {
415 switch (fmodel
->UTYPE
) {
417 *fout
= stm_modtbl_slew (fmodel
->UMODEL
.TABLE
, load
, fin
);
420 stm_modscm_timing (dmodel
->UMODEL
.SCM
, fmodel
->UMODEL
.SCM
, fin
, pwlin
, driver
, -1.0, load
, -1.0, delay
, fout
, pwlout
, dmodel
->NAME
);
423 *fout
= stm_modpln_slew (fmodel
->UMODEL
.POLYNOM
, fin
, load
);
426 *fout
= stm_modfct_slew (fmodel
->UMODEL
.FUNCTION
, fin
, load
);
429 vth
= stm_mod_vth(fmodel
);
430 vdd
= stm_mod_vdd(fmodel
);
431 *fout
= stm_modiv_slew_c (fmodel
->UMODEL
.IV
, fin
, load
, vth
, vdd
);
439 if( *fout
< 1.0 ) *fout
= 1.0 ;
441 if (delay
&& V_BOOL_TAB
[__STM_PRECISION_WARNING
].VALUE
) {
442 if (fin
> V_INT_TAB
[__STM_PRECISION_THRESHOLD
].VALUE
* (*delay
)) {
443 avt_errmsg(STM_ERRMSG
, "052", AVT_WARNING
, inputname
, dirin
, signame
, dirout
, (int)fin
, (int)load
);
448 /****************************************************************************/
450 float stm_mod_loadparam (timing_model
*tmodel
, float load
, float slew
)
453 switch (tmodel
->UTYPE
) {
455 return stm_modtbl_loadparam (tmodel
->UMODEL
.TABLE
, load
, slew
);
458 return stm_modscm_loadparam (tmodel
->UMODEL
.SCM
, load
, slew
);
461 avt_errmsg (STM_ERRMSG
, "013", AVT_ERROR
);
464 avt_errmsg (STM_ERRMSG
, "013", AVT_ERROR
);
470 /****************************************************************************/
472 float stm_mod_clockslewparam (timing_model
*tmodel
, float clockslew
, float slew
)
475 switch (tmodel
->UTYPE
) {
477 return stm_modtbl_clockslewparam (tmodel
->UMODEL
.TABLE
, clockslew
, slew
);
480 avt_errmsg (STM_ERRMSG
, "014", AVT_ERROR
);
483 avt_errmsg (STM_ERRMSG
, "015", AVT_ERROR
);
486 avt_errmsg (STM_ERRMSG
, "015", AVT_ERROR
);
492 /****************************************************************************/
494 float stm_mod_dataslewparam (timing_model
*tmodel
, float clockslew
, float slew
)
497 switch (tmodel
->UTYPE
) {
499 return stm_modtbl_dataslewparam (tmodel
->UMODEL
.TABLE
, clockslew
, slew
);
502 avt_errmsg (STM_ERRMSG
, "016", AVT_ERROR
);
505 avt_errmsg (STM_ERRMSG
, "017", AVT_ERROR
);
508 avt_errmsg (STM_ERRMSG
, "017", AVT_ERROR
);
514 /****************************************************************************/
516 float stm_mod_imax (timing_model
*model
)
519 switch (model
->UTYPE
) {
521 avt_errmsg (STM_ERRMSG
, "018", AVT_ERROR
);
524 return stm_modscm_imax (model
->UMODEL
.SCM
);
527 avt_errmsg (STM_ERRMSG
, "019", AVT_ERROR
);
530 avt_errmsg (STM_ERRMSG
, "019", AVT_ERROR
);
536 /****************************************************************************/
538 float stm_mod_slewparam (timing_model
*tmodel
, float load
, float slew
)
541 switch (tmodel
->UTYPE
) {
543 return stm_modtbl_slewparam (tmodel
->UMODEL
.TABLE
, load
, slew
);
546 return stm_modscm_slewparam (tmodel
->UMODEL
.SCM
, load
, slew
);
549 avt_errmsg (STM_ERRMSG
, "020", AVT_ERROR
);
552 avt_errmsg (STM_ERRMSG
, "020", AVT_ERROR
);
558 /****************************************************************************/
560 float stm_mod_vt (timing_model
*model
)
563 return STM_DEFAULT_VT
;
565 if( model
->UTYPE
== STM_MOD_MODSCM
)
566 if( model
->UMODEL
.SCM
->TYPE
== STM_MODSCM_DUAL
)
567 return model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_VT
];
572 /****************************************************************************/
574 float stm_mod_vf (timing_model
*model
)
577 return STM_DEFAULT_VFU
;
582 /****************************************************************************/
584 float stm_mod_vf_input (timing_model
*model
)
588 vf
= STM_DEFAULT_VFU
;
589 else if(model
->UTYPE
== STM_MOD_MODSCM
){
590 if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_HH
))
591 vf
= stm_modscm_vf_input (model
->UMODEL
.SCM
);
592 else if((model
->TTYPE
== STM_LL
) || (model
->TTYPE
== STM_LH
))
596 if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_HH
))
597 vf
= stm_mod_vdd(model
);
598 else if((model
->TTYPE
== STM_LL
) || (model
->TTYPE
== STM_LH
))
603 /****************************************************************************/
605 float stm_mod_default_vt (void)
607 return STM_DEFAULT_VT
;
610 /****************************************************************************/
612 float stm_mod_default_vdd (void)
614 return V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
617 /****************************************************************************/
619 float stm_mod_default_vth (void)
621 return V_FLOAT_TAB
[__SIM_VTH
].VALUE
* V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
624 /****************************************************************************/
626 float stm_mod_default_vfd (void)
628 return STM_DEFAULT_VFD
;
631 /****************************************************************************/
633 float stm_mod_default_vfu (void)
635 return STM_DEFAULT_VFU
;
638 /****************************************************************************/
640 float stm_mod_vth (timing_model
*model
)
643 return V_FLOAT_TAB
[__SIM_VTH
].VALUE
* V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
648 /****************************************************************************/
650 float stm_mod_vdd (timing_model
*model
)
653 return V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
658 /****************************************************************************/
660 float stm_mod_vdd_input (timing_model
*model
)
664 vdd
= V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
;
665 else if(model
->UTYPE
== STM_MOD_MODSCM
)
666 vdd
= stm_modscm_vf_input (model
->UMODEL
.SCM
);
668 vdd
= stm_mod_vdd(model
);
671 /****************************************************************************/
673 void stm_mod_driver( timing_model
*model
, float *r
, float *v
)
680 switch( model
->UTYPE
)
684 if (model
->UMODEL
.SCM
->TYPE
== STM_MODSCM_DUAL
) {
686 *r
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_RLIN
] ;
688 *v
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_KRT
] * model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_VDDMAX
] ;
694 /****************************************************************************/
696 float stm_mod_rlin (timing_model
*model
)
703 switch (model
->UTYPE
) {
705 if (model
->UMODEL
.SCM
->TYPE
== STM_MODSCM_DUAL
)
706 rlin
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_RLIN
] ;
713 /****************************************************************************/
715 float stm_mod_default_rlin (void)
717 return STM_DEFAULT_RLIN
;
720 /****************************************************************************/
722 float stm_mod_vsat (timing_model
*model
)
735 switch (model
->UTYPE
) {
739 if (model
->UMODEL
.SCM
->TYPE
== STM_MODSCM_DUAL
) {
741 rsat
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_RSAT
] ;
742 rlin
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_RLIN
] ;
743 imax
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_IMAX
] ;
744 vddmax
= model
->UMODEL
.SCM
->PARAMS
.DUAL
->DP
[STM_VDDMAX
] ;
746 rsatmin
= vddmax
/imax
;
748 if( rsat
> 0.0 && rsat
> rsatmin
&& rsatmin
> rlin
) {
750 ( imax
- vddmax
/ rsat
) * rlin
* rsat
/ ( rsat
- rlin
) ;
761 /****************************************************************************/
763 float stm_mod_default_vsat(void)
765 return STM_DEFAULT_VSAT
;