1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit: STM Version 1.00 */
6 /* Fichier: stm_mod_meta.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s): Gilles Augustins */
14 /****************************************************************************/
16 /****************************************************************************/
18 /****************************************************************************/
23 /****************************************************************************/
25 /****************************************************************************/
27 float stm_round (float d
, int precision
)
39 cs
= (int)pow ((float)10, (float)precision
);
60 avt_errmsg (STM_ERRMSG
, "050", AVT_ERROR
);
71 /****************************************************************************/
73 float *stm_dyna_slews (int n
, float slew
)
81 slopes
= (float*)mbkalloc ((2 * n
+ 1) * sizeof (float));
82 for (i
= 0 ; i
< 2 * n
+ 1 ; i
++)
83 slopes
[i
] = stm_round (slew
/ pow ((float)((pow (n
- 5, 2) + 12) / 10), (float)(n
- i
)), 2);
87 /****************************************************************************/
89 float *stm_dyna_slewsforpln (int n
, float thmin
, float thmax
)
95 slopes
= (float*)mbkalloc ((2 * n
+ 1) * sizeof (float));
96 step
= (thmax
- thmin
) / (2 * n
);
97 for (i
= 0 ; i
< 2 * n
+ 1 ; i
++)
98 slopes
[i
] = stm_round (thmin
+ (i
* step
), 2);
103 /****************************************************************************/
105 float *stm_dyna_loads (int n
, float avg_r
, float load
)
112 dyna_slews
= stm_dyna_slews (n
, -1.0);
114 loads
= (float*)mbkalloc ((2 * n
+ 1) * sizeof (float)) ;
115 for (i
= 0 ; i
< 2 * n
+ 1 ; i
++){
117 loads
[i
] = stm_round (stm_thr2scm (dyna_slews
[i
], STM_DEFAULT_SMINR
, STM_DEFAULT_SMAXR
, STM_DEFAULT_VTN
, V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
, V_FLOAT_TAB
[__SIM_POWER_SUPPLY
].VALUE
, STM_UP
) / avg_r
, 2) * 1000;
119 loads
[i
] = stm_round (load
/ pow ((float)((pow (n
- 5, 2) + 12) / 10), (float)(n
- i
)), 2);
122 mbkfree (dyna_slews
);
126 /****************************************************************************/
128 float *stm_dyna_loadsforpln (int n
, float thmin
, float thmax
)
135 loads
= (float*)mbkalloc ((2 * n
+ 1) * sizeof (float)) ;
136 step
= (thmax
- thmin
) / (2 * n
);
137 for (i
= 0 ; i
< 2 * n
+ 1 ; i
++)
138 loads
[i
] = stm_round (thmin
+ (i
* step
), 2);
145 /****************************************************************************/
147 float stm_mod_getcaracslewmin (timing_model
*model
)
154 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
157 return ((stm_carac_values
*)ptype
->DATA
)->SLEW_MIN
;
160 /****************************************************************************/
162 float stm_mod_getcaracslewoutmin (timing_model
*model
)
169 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
172 return ((stm_carac_values
*)ptype
->DATA
)->SLEWOUT_MIN
;
175 /****************************************************************************/
177 float stm_mod_getcaracloadmin (timing_model
*model
)
184 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
187 return ((stm_carac_values
*)ptype
->DATA
)->LOAD_MIN
;
190 /****************************************************************************/
192 float stm_mod_getcaracslewmax (timing_model
*model
)
199 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
202 return ((stm_carac_values
*)ptype
->DATA
)->SLEW_MAX
;
205 /****************************************************************************/
207 float stm_mod_getcaracslewoutmax (timing_model
*model
)
214 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
217 return ((stm_carac_values
*)ptype
->DATA
)->SLEWOUT_MAX
;
220 /****************************************************************************/
222 float stm_mod_getcaracloadmax (timing_model
*model
)
229 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
232 return ((stm_carac_values
*)ptype
->DATA
)->LOAD_MAX
;
235 /****************************************************************************/
237 void stm_mod_setcaracslew (timing_model
*model
, float slew
)
240 stm_carac_values
*cvalues
;
245 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
))) {
246 cvalues
= (stm_carac_values
*)mbkalloc (sizeof (struct stm_carac_values
));
247 cvalues
->LOAD_MIN
= FLT_MAX
;
248 cvalues
->LOAD_MAX
= FLT_MIN
;
249 cvalues
->SLEW_MIN
= FLT_MAX
;
250 cvalues
->SLEW_MAX
= FLT_MIN
;
251 cvalues
->SLEWOUT_MIN
= FLT_MAX
;
252 cvalues
->SLEWOUT_MAX
= FLT_MIN
;
253 model
->USER
= addptype (model
->USER
, STM_CARAC_VALUES
, cvalues
);
255 cvalues
= (stm_carac_values
*)ptype
->DATA
;
257 cvalues
->SLEW_MIN
= cvalues
->SLEW_MIN
< slew
? cvalues
->SLEW_MIN
: slew
;
258 cvalues
->SLEW_MAX
= cvalues
->SLEW_MAX
> slew
? cvalues
->SLEW_MAX
: slew
;
261 /****************************************************************************/
263 void stm_mod_setcaracslewout (timing_model
*model
, float slew
)
266 stm_carac_values
*cvalues
;
271 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
))) {
272 cvalues
= (stm_carac_values
*)mbkalloc (sizeof (struct stm_carac_values
));
273 cvalues
->LOAD_MIN
= FLT_MAX
;
274 cvalues
->LOAD_MAX
= FLT_MIN
;
275 cvalues
->SLEW_MIN
= FLT_MAX
;
276 cvalues
->SLEW_MAX
= FLT_MIN
;
277 cvalues
->SLEWOUT_MIN
= FLT_MAX
;
278 cvalues
->SLEWOUT_MAX
= FLT_MIN
;
279 model
->USER
= addptype (model
->USER
, STM_CARAC_VALUES
, cvalues
);
281 cvalues
= (stm_carac_values
*)ptype
->DATA
;
283 cvalues
->SLEWOUT_MIN
= cvalues
->SLEWOUT_MIN
< slew
? cvalues
->SLEWOUT_MIN
: slew
;
284 cvalues
->SLEWOUT_MAX
= cvalues
->SLEWOUT_MAX
> slew
? cvalues
->SLEWOUT_MAX
: slew
;
287 /****************************************************************************/
289 void stm_mod_setcaracload (timing_model
*model
, float load
)
292 stm_carac_values
*cvalues
;
297 if (!(ptype
= getptype (model
->USER
, STM_CARAC_VALUES
))) {
298 cvalues
= (stm_carac_values
*)mbkalloc (sizeof (struct stm_carac_values
));
299 cvalues
->LOAD_MIN
= FLT_MAX
;
300 cvalues
->LOAD_MAX
= FLT_MIN
;
301 cvalues
->SLEW_MIN
= FLT_MAX
;
302 cvalues
->SLEW_MAX
= FLT_MIN
;
303 cvalues
->SLEWOUT_MIN
= FLT_MAX
;
304 cvalues
->SLEWOUT_MAX
= FLT_MIN
;
305 model
->USER
= addptype (model
->USER
, STM_CARAC_VALUES
, cvalues
);
307 cvalues
= (stm_carac_values
*)ptype
->DATA
;
309 cvalues
->LOAD_MIN
= cvalues
->LOAD_MIN
< load
? cvalues
->LOAD_MIN
: load
;
310 cvalues
->LOAD_MAX
= cvalues
->LOAD_MAX
> load
? cvalues
->LOAD_MAX
: load
;
313 /****************************************************************************/
315 long stm_genloadaxis (double *loads
, float load_min
, float load_max
)
318 float step
= (load_max
- load_min
) / (pow(2, n
) - 1);
321 for (i
= 0; i
< n
; i
++)
322 loads
[i
+ 1] = loads
[i
] + step
* pow(2, i
);
327 /****************************************************************************/
329 long stm_genslewaxis (double *slews
, float slew_min
, float slew_max
)
332 float step
= (slew_max
- slew_min
) / (pow(2, n
) - 1);
335 for (i
= 0; i
< n
; i
++)
336 slews
[i
+ 1] = slews
[i
] + step
* pow(2, i
);
341 /****************************************************************************/
343 /****************************************************************************/
344 /*{{{ stm_mod_stm2tbl_delay() */
347 /****************************************************************************/
348 timing_model
*stm_mod_stm2tbl_delay(timing_model
*model
, float *slews
,
349 long ns
, float *loads
, long nl
,
352 switch (model
->UTYPE
)
355 return stm_mod_scm2tbl_delay(model
,slews
,ns
,loads
,nl
,ci0
,STM_DEF_SLEW
,STM_DEF_LOAD
);
357 return stm_mod_pln2tbl_delay(model
,slews
,ns
,loads
,nl
,ci0
);
359 return stm_mod_fct2tbl_delay(model
,slews
,ns
,loads
,nl
,ci0
);
363 model
->UMODEL
.TABLE
= NULL
;
368 /*}}}************************************************************************/
369 /*{{{ stm_mod_stm2tbl_slew() */
372 /****************************************************************************/
373 timing_model
*stm_mod_stm2tbl_slew(timing_model
*model
, float *slews
,
374 long ns
, float *loads
, long nl
, float ci0
)
376 switch (model
->UTYPE
)
379 return stm_mod_scm2tbl_slew(model
,slews
,ns
,loads
,nl
,ci0
,STM_DEF_SLEW
,STM_DEF_LOAD
);
381 return stm_mod_pln2tbl_slew(model
,slews
,ns
,loads
,nl
,ci0
);
383 return stm_mod_fct2tbl_slew(model
,slews
,ns
,loads
,nl
,ci0
);
387 model
->UMODEL
.TABLE
= NULL
;
392 /*}}}************************************************************************/
393 /*{{{ stm_mod_defaultstm2tbl_delay() */
396 /****************************************************************************/
397 void stm_mod_defaultstm2tbl_delay(timing_model
*model
, char xtype
, char ytype
, float slew
, float load
)
399 switch (model
->UTYPE
)
401 case STM_MOD_MODSCM
:
402 stm_mod_defaultscm2tbl_delay(model
, slew
, load
);
404 case STM_MOD_MODPLN
:
405 stm_mod_defaultpln2tbl_delay(model
);
407 case STM_MOD_MODFCT
:
408 stm_mod_defaultfct2tbl_delay(model
,xtype
,ytype
);
410 case STM_MOD_MODTBL
:
413 model
->UMODEL
.TABLE
= NULL
;
418 /*}}}************************************************************************/
419 /*{{{ stm_mod_defaultstm2tbl_slew() */
422 /****************************************************************************/
423 void stm_mod_defaultstm2tbl_slew(timing_model
*model
, char xtype
, char ytype
, float slew
, float load
)
425 switch (model
->UTYPE
)
428 stm_mod_defaultscm2tbl_slew(model
, slew
, load
);
431 stm_mod_defaultpln2tbl_slew(model
);
434 stm_mod_defaultfct2tbl_slew(model
,xtype
,ytype
);
436 case STM_MOD_MODTBL
:
439 model
->UMODEL
.TABLE
= NULL
;
444 /*}}}************************************************************************/
445 /*}}}************************************************************************/
447 /****************************************************************************/
449 /****************************************************************************/
451 timing_model
*stm_mod_scm2tbl_delay (timing_model
*model
, float *slews
, long ns
, float *loads
, long nl
, float ci0
, float slew
, float load
)
454 stm_carac_values
*cvalues
= NULL
;
455 double loc_slews
[1024];
456 double loc_slews_scaled
[1024];
457 double loc_loads
[1024];
467 if (model
->UTYPE
!= STM_MOD_MODSCM
)
470 if ((ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
471 cvalues
= (stm_carac_values
*)ptype
->DATA
;
475 loc_ns
= stm_genslewaxis (loc_slews
, cvalues
->SLEW_MIN
, cvalues
->SLEW_MAX
);
478 for (i
= 0; i
< loc_ns
; i
++)
479 loc_slews
[i
] = slews
[i
];
484 loc_nl
= stm_genloadaxis (loc_loads
, cvalues
->LOAD_MIN
, cvalues
->LOAD_MAX
);
487 for (i
= 0; i
< loc_nl
; i
++)
488 loc_loads
[i
] = loads
[i
];
490 if(slew
< 0.0 && load
>= 0.0) loc_nl
= 0;
491 if(load
< 0.0 && slew
>= 0.0) loc_ns
= 0;
493 if (!loc_ns
&& !loc_nl
)
497 model
->NAME
= stm_dlymname_extract(model
->NAME
);
498 if(stm_if_thresholds()){
499 slew_scaled
= stm_mod_shrinkslew_thr2scm(model
, slew
);
500 stm_mod_shrinkslewaxis_thr2scm(model
, loc_slews_scaled
, loc_slews
, loc_ns
);
502 for (i
= 0; i
< loc_ns
; i
++)
503 loc_slews_scaled
[i
] = loc_slews
[i
];
506 if (loc_ns
&& loc_nl
)
507 tbl
= stm_modtbl_create_delay2D_fstm(model
,loc_slews_scaled
,loc_ns
,loc_loads
,loc_nl
,ci0
);
508 else if (!loc_ns
&& loc_nl
)
509 tbl
= stm_modtbl_create_delay1Dslewfix_fstm(model
,loc_loads
,loc_nl
,slew_scaled
,ci0
);
510 else if (loc_ns
&& !loc_nl
)
511 tbl
= stm_modtbl_create_delay1Dloadfix_fstm(model
,loc_slews_scaled
,loc_ns
,load
);
512 stm_mod_destroy_model (model
);
513 model
->UTYPE
= STM_MOD_MODTBL
;
514 model
->UMODEL
.TABLE
= tbl
;
517 if(stm_if_thresholds()){
518 stm_mod_shrinkslewaxis_scm2thr (model
, loc_slews
);
525 /****************************************************************************/
527 timing_model
*stm_mod_scm2tbl_slew (timing_model
*model
, float *slews
, long ns
, float *loads
, long nl
, float ci0
, float slew
, float load
)
530 stm_carac_values
*cvalues
= NULL
;
531 double loc_slews
[1024];
532 double loc_slews_scaled
[1024];
533 double loc_loads
[1024];
543 if (model
->UTYPE
!= STM_MOD_MODSCM
)
546 if ((ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
547 cvalues
= (stm_carac_values
*)ptype
->DATA
;
551 loc_ns
= stm_genslewaxis (loc_slews
, cvalues
->SLEW_MIN
, cvalues
->SLEW_MAX
);
554 for (i
= 0; i
< loc_ns
; i
++)
555 loc_slews
[i
] = slews
[i
];
560 loc_nl
= stm_genloadaxis (loc_loads
, cvalues
->LOAD_MIN
, cvalues
->LOAD_MAX
);
563 for (i
= 0; i
< loc_nl
; i
++)
564 loc_loads
[i
] = loads
[i
];
566 if(slew
< 0.0 && load
>= 0.0) loc_nl
= 0;
567 if(load
< 0.0 && slew
>= 0.0) loc_ns
= 0;
569 if (!loc_ns
&& !loc_nl
)
573 model
->NAME
= stm_slwmname_extract(model
->NAME
);
574 if(stm_if_thresholds()){
575 slew_scaled
= stm_mod_shrinkslew_thr2scm(model
, slew
);
576 stm_mod_shrinkslewaxis_thr2scm(model
, loc_slews_scaled
, loc_slews
, loc_ns
);
578 for (i
= 0; i
< loc_ns
; i
++)
579 loc_slews_scaled
[i
] = loc_slews
[i
];
581 if (loc_ns
&& loc_nl
)
582 tbl
= stm_modtbl_create_slew2D_fstm(model
,loc_slews_scaled
,loc_ns
,loc_loads
,loc_nl
,ci0
);
583 else if (!loc_ns
&& loc_nl
)
584 tbl
= stm_modtbl_create_slew1Dslewfix_fstm(model
,loc_loads
,loc_nl
,slew_scaled
,ci0
);
585 else if (loc_ns
&& !loc_nl
)
586 tbl
= stm_modtbl_create_slew1Dloadfix_fstm(model
,loc_slews_scaled
,loc_ns
,load
);
587 stm_mod_destroy_model (model
);
588 model
->UTYPE
= STM_MOD_MODTBL
;
589 model
->UMODEL
.TABLE
= tbl
;
590 if(stm_if_thresholds()){
591 stm_mod_shrinkslewaxis_scm2thr (model
, loc_slews
);
592 stm_mod_shrinkslewdata_scm2thr (model
);
599 /****************************************************************************/
601 void stm_mod_defaultscm2tbl_slew (timing_model
*model
, float slew
, float load
)
606 int ns
, nl
, frees
=0, freel
=0;
609 if(slew
< 0.0 && STM_AXIS_NSLOPE
){
610 s_axis
= STM_AXIS_SLOPEIN
;
611 ns
= STM_AXIS_NSLOPE
;
612 }else if(getptype (model
->USER
, STM_CARAC_VALUES
)){
616 s_axis
= stm_dyna_slews (STM_DEF_AXIS_BASE
, slew
);
617 ns
= STM_DEF_AXIS_BASE
* 2 + 1;
620 if(load
< 0.0 && STM_AXIS_NCAPA
){
621 l_axis
= STM_AXIS_CAPAOUT
;
623 }else if(getptype (model
->USER
, STM_CARAC_VALUES
)){
627 vf
= stm_mod_vf (model
);
628 vt
= stm_mod_vt (model
);
630 vf
= stm_mod_vdd(model
) - vt
;
631 imax
= stm_mod_imax (model
);
632 l_axis
= stm_dyna_loads (STM_DEF_AXIS_BASE
, vf
/ imax
, load
);
633 nl
= STM_DEF_AXIS_BASE
* 2 + 1;
637 stm_mod_scm2tbl_slew (model
, s_axis
, ns
, l_axis
, nl
, 0.0, slew
, load
);
645 /****************************************************************************/
647 void stm_mod_defaultscm2tbl_delay (timing_model
*model
, float slew
, float load
)
652 int ns
, nl
, frees
=0, freel
=0;
655 if(slew
< 0.0 && STM_AXIS_NSLOPE
){
656 s_axis
= STM_AXIS_SLOPEIN
;
657 ns
= STM_AXIS_NSLOPE
;
658 }else if(getptype (model
->USER
, STM_CARAC_VALUES
)){
662 s_axis
= stm_dyna_slews (STM_DEF_AXIS_BASE
, slew
);
663 ns
= STM_DEF_AXIS_BASE
* 2 + 1;
666 if(load
< 0.0 && STM_AXIS_NCAPA
){
667 l_axis
= STM_AXIS_CAPAOUT
;
669 }else if(getptype (model
->USER
, STM_CARAC_VALUES
)){
673 vf
= stm_mod_vf (model
);
674 vt
= stm_mod_vt (model
);
676 vf
= stm_mod_vdd(model
) - vt
;
677 imax
= stm_mod_imax (model
);
678 l_axis
= stm_dyna_loads (STM_DEF_AXIS_BASE
, vf
/ imax
, load
);
679 nl
= STM_DEF_AXIS_BASE
* 2 + 1;
683 stm_mod_scm2tbl_delay (model
, s_axis
, ns
, l_axis
, nl
, 0.0, slew
, load
);
691 /*}}}************************************************************************/
693 /****************************************************************************/
694 timing_model
*stm_mod_pln2tbl_delay (timing_model
*model
, float *slews
, long ns
, float *loads
, long nl
, float ci0
)
697 stm_carac_values
*cvalues
= NULL
;
698 double loc_slews
[1024];
699 double loc_loads
[1024];
708 if (model
->UTYPE
!= STM_MOD_MODPLN
)
711 if ((ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
712 cvalues
= (stm_carac_values
*)ptype
->DATA
;
716 loc_ns
= stm_genslewaxis (loc_slews
, cvalues
->SLEW_MIN
, cvalues
->SLEW_MAX
);
719 for (i
= 0; i
< loc_ns
; i
++)
720 loc_slews
[i
] = slews
[i
];
725 loc_nl
= stm_genloadaxis (loc_loads
, cvalues
->LOAD_MIN
, cvalues
->LOAD_MAX
);
728 for (i
= 0; i
< loc_nl
; i
++)
729 loc_loads
[i
] = loads
[i
];
732 if (!loc_ns
&& !loc_nl
)
736 model
->NAME
= stm_dlymname_extract(model
->NAME
);
737 if (loc_ns
&& loc_nl
)
738 tbl
= stm_modtbl_create_delay2D_fstm(model
,loc_slews
,loc_ns
,loc_loads
,loc_nl
,ci0
);
739 else if (!loc_ns
&& loc_nl
)
740 tbl
= stm_modtbl_create_delay1Dslewfix_fstm(model
,loc_loads
,loc_nl
,STM_DEF_SLEW
,ci0
);
741 else if (loc_ns
&& !loc_nl
)
742 tbl
= stm_modtbl_create_delay1Dloadfix_fstm(model
,loc_slews
,loc_ns
,STM_DEF_LOAD
);
743 stm_mod_destroy_model (model
);
744 model
->UTYPE
= STM_MOD_MODTBL
;
745 model
->UMODEL
.TABLE
= tbl
;
751 /****************************************************************************/
753 timing_model
*stm_mod_pln2tbl_slew (timing_model
*model
, float *slews
, long ns
, float *loads
, long nl
, float ci0
)
756 stm_carac_values
*cvalues
= NULL
;
757 double loc_slews
[1024];
758 double loc_loads
[1024];
767 if (model
->UTYPE
!= STM_MOD_MODPLN
)
770 if ((ptype
= getptype (model
->USER
, STM_CARAC_VALUES
)))
771 cvalues
= (stm_carac_values
*)ptype
->DATA
;
775 loc_ns
= stm_genslewaxis (loc_slews
, cvalues
->SLEW_MIN
, cvalues
->SLEW_MAX
);
778 for (i
= 0; i
< loc_ns
; i
++)
779 loc_slews
[i
] = slews
[i
];
784 loc_nl
= stm_genloadaxis (loc_loads
, cvalues
->LOAD_MIN
, cvalues
->LOAD_MAX
);
787 for (i
= 0; i
< loc_nl
; i
++)
788 loc_loads
[i
] = loads
[i
];
791 if (!loc_ns
&& !loc_nl
)
795 model
->NAME
= stm_slwmname_extract(model
->NAME
);
796 if (loc_ns
&& loc_nl
)
797 tbl
= stm_modtbl_create_slew2D_fstm(model
,loc_slews
,loc_ns
,loc_loads
,loc_nl
,ci0
);
798 else if (!loc_ns
&& loc_nl
)
799 tbl
= stm_modtbl_create_slew1Dslewfix_fstm(model
,loc_loads
,loc_nl
,STM_DEF_SLEW
,ci0
);
800 else if (loc_ns
&& !loc_nl
)
801 tbl
= stm_modtbl_create_slew1Dloadfix_fstm(model
,loc_slews
,loc_ns
,STM_DEF_LOAD
);
802 stm_mod_destroy_model (model
);
803 model
->UTYPE
= STM_MOD_MODTBL
;
804 model
->UMODEL
.TABLE
= tbl
;
810 /****************************************************************************/
812 void stm_mod_defaultpln2tbl_slew (timing_model
*model
)
814 float *s_axis
= NULL
;
815 float *l_axis
= NULL
;
816 float thcapamin
= -1.0, thcapamax
= -1.0;
817 float thslewmin
= -1.0, thslewmax
= -1.0;
819 long nbvarmask
, ns
= 0, nl
= 0;
820 long nbvar_degree
= model
->UMODEL
.POLYNOM
->DEG_NBVAR
;
822 nbvarmask
= ULONG_MAX
>> (sizeof(long) * 4);
823 nbvar
= nbvar_degree
& nbvarmask
;
825 for(i
= 0; i
< nbvar
; i
++){
826 if(model
->UMODEL
.POLYNOM
->VAR
[i
]->TYPE
== STM_INPUT_SLEW
){
827 thslewmin
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMIN
;
828 thslewmax
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMAX
;
832 for(i
= 0; i
< nbvar
; i
++){
833 if(model
->UMODEL
.POLYNOM
->VAR
[i
]->TYPE
== STM_LOAD
){
834 thcapamin
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMIN
;
835 thcapamax
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMAX
;
840 if((thslewmin
>= 0.0) && (thslewmax
>= 0.0)){
841 s_axis
= stm_dyna_slewsforpln (STM_DEF_AXIS_BASE
, thslewmin
, thslewmax
);
842 ns
= STM_DEF_AXIS_BASE
* 2 + 1;
844 if((thcapamin
>= 0.0) && (thcapamax
>= 0.0)){
845 l_axis
= stm_dyna_loadsforpln (STM_DEF_AXIS_BASE
, thcapamin
, thcapamax
);
846 nl
= STM_DEF_AXIS_BASE
* 2 + 1;
849 stm_mod_pln2tbl_slew (model
, s_axis
, ns
, l_axis
, nl
, 0.0);
855 /****************************************************************************/
857 void stm_mod_defaultpln2tbl_delay (timing_model
*model
)
859 float *s_axis
= NULL
;
860 float *l_axis
= NULL
;
861 float thcapamin
= -1.0, thcapamax
= -1.0;
862 float thslewmin
= -1.0, thslewmax
= -1.0;
864 long nbvarmask
, ns
= 0, nl
= 0;
865 long nbvar_degree
= model
->UMODEL
.POLYNOM
->DEG_NBVAR
;
867 nbvarmask
= ULONG_MAX
>> (sizeof(long) * 4);
868 nbvar
= nbvar_degree
& nbvarmask
;
870 for(i
= 0; i
< nbvar
; i
++){
871 if(model
->UMODEL
.POLYNOM
->VAR
[i
]->TYPE
== STM_INPUT_SLEW
){
872 thslewmin
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMIN
;
873 thslewmax
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMAX
;
877 for(i
= 0; i
< nbvar
; i
++){
878 if(model
->UMODEL
.POLYNOM
->VAR
[i
]->TYPE
== STM_LOAD
){
879 thcapamin
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMIN
;
880 thcapamax
= model
->UMODEL
.POLYNOM
->VAR
[i
]->THMAX
;
885 if((thslewmin
>= 0.0) && (thslewmax
>= 0.0)){
886 s_axis
= stm_dyna_slewsforpln (STM_DEF_AXIS_BASE
, thslewmin
, thslewmax
);
887 ns
= STM_DEF_AXIS_BASE
* 2 + 1;
889 if((thcapamin
>= 0.0) && (thcapamax
>= 0.0)){
890 l_axis
= stm_dyna_loadsforpln (STM_DEF_AXIS_BASE
, thcapamin
, thcapamax
);
891 nl
= STM_DEF_AXIS_BASE
* 2 + 1;
894 stm_mod_pln2tbl_delay (model
, s_axis
, ns
, l_axis
, nl
, 0.0);
900 /*}}}************************************************************************/
902 /****************************************************************************/
903 /*{{{ stm_mod_fct2tbl_delay() */
906 /****************************************************************************/
907 timing_model
*stm_mod_fct2tbl_delay(timing_model
*model
, float *slews
,
908 long ns
, float *loads
, long nl
, float ci0
)
910 stm_carac_values
*cvalues
= NULL
;
912 double loc_slews
[1024], loc_loads
[1024];
913 long loc_ns
= 0, loc_nl
= 0;
917 if (!model
|| model
->UTYPE
!= STM_MOD_MODFCT
)
921 if ((ptype
= getptype(model
->USER
, STM_CARAC_VALUES
)))
922 cvalues
=(stm_carac_values
*)ptype
->DATA
;
927 for (i
= 0; i
< loc_ns
; i
++)
928 loc_slews
[i
] = slews
[i
];
931 loc_ns
= stm_genslewaxis(loc_slews
, cvalues
->SLEW_MIN
,
936 for (i
= 0; i
< loc_nl
; i
++)
937 loc_loads
[i
] = loads
[i
];
940 loc_nl
= stm_genloadaxis(loc_loads
, cvalues
->LOAD_MIN
,
943 if (!loc_ns
&& !loc_nl
)
947 model
->NAME
= stm_dlymname_extract(model
->NAME
);
948 if (loc_ns
&& loc_nl
)
949 tbl
= stm_modtbl_create_delay2D_fstm(model
,loc_slews
,loc_ns
,loc_loads
,loc_nl
,ci0
);
950 else if (!loc_ns
&& loc_nl
)
951 tbl
= stm_modtbl_create_delay1Dslewfix_fstm(model
,loc_loads
,loc_nl
,STM_DEF_SLEW
,ci0
);
952 else if (loc_ns
&& !loc_nl
)
953 tbl
= stm_modtbl_create_delay1Dloadfix_fstm(model
,loc_slews
,loc_ns
,STM_DEF_LOAD
);
954 stm_mod_destroy_model (model
);
955 model
->UTYPE
= STM_MOD_MODTBL
;
956 model
->UMODEL
.TABLE
= tbl
;
962 /*}}}************************************************************************/
963 /*{{{ stm_mod_fct2tbl_slew() */
966 /****************************************************************************/
967 timing_model
*stm_mod_fct2tbl_slew(timing_model
*model
, float *slews
, long ns
, float *loads
, long nl
, float ci0
)
969 stm_carac_values
*cvalues
= NULL
;
972 double loc_slews
[1024], loc_loads
[1024];
973 long loc_ns
= 0, loc_nl
= 0;
976 if (!model
|| model
->UTYPE
!= STM_MOD_MODPLN
)
980 if ((ptype
= getptype(model
->USER
, STM_CARAC_VALUES
)))
981 cvalues
=(stm_carac_values
*)ptype
->DATA
;
985 loc_ns
= stm_genslewaxis(loc_slews
, cvalues
->SLEW_MIN
,
991 for (i
= 0; i
< loc_ns
; i
++)
992 loc_slews
[i
] = slews
[i
];
997 loc_nl
= stm_genloadaxis(loc_loads
, cvalues
->LOAD_MIN
,
1003 for (i
= 0; i
< loc_nl
; i
++)
1004 loc_loads
[i
] = loads
[i
];
1006 if (!loc_ns
&& !loc_nl
)
1010 model
->NAME
= stm_slwmname_extract(model
->NAME
);
1011 if (loc_ns
&& loc_nl
)
1012 tbl
= stm_modtbl_create_slew2D_fstm(model
,loc_slews
,loc_ns
,loc_loads
,loc_nl
,ci0
);
1013 else if (!loc_ns
&& loc_nl
)
1014 tbl
= stm_modtbl_create_slew1Dslewfix_fstm(model
,loc_loads
,loc_nl
,STM_DEF_SLEW
,ci0
);
1015 else if (loc_ns
&& !loc_nl
)
1016 tbl
= stm_modtbl_create_slew1Dloadfix_fstm(model
,loc_slews
,loc_ns
,STM_DEF_LOAD
);
1017 stm_mod_destroy_model (model
);
1018 model
->UTYPE
= STM_MOD_MODTBL
;
1019 model
->UMODEL
.TABLE
= tbl
;
1026 /*}}}************************************************************************/
1027 /*{{{ stm_getAxis() */
1030 /****************************************************************************/
1031 void stm_getAxis(timing_model
*model
,
1036 stm_carac_values
*cvalues
= NULL
;
1037 float vf
, imax
, vt
, *loc_axis
;
1038 double slews
[1024], loads
[1024];
1041 if(STM_AXIS_NSLOPE
){
1042 *nx
= STM_AXIS_NSLOPE
;
1043 for (i
= 0; i
< *nx
; i
++)
1044 x
[i
] = STM_AXIS_SLOPEIN
[i
];
1046 loc_axis
= stm_dyna_slews (STM_DEF_AXIS_BASE
, -1.0);
1047 *nx
= STM_DEF_AXIS_BASE
* 2 + 1;
1048 for (i
= 0; i
< *nx
; i
++)
1053 *ny
= STM_AXIS_NCAPA
;
1054 for (i
= 0; i
< *ny
; i
++)
1055 y
[i
] = STM_AXIS_CAPAOUT
[i
];
1057 avt_errmsg (STM_ERRMSG
,"039", AVT_ERROR
);
1059 for (i
= 0; i
< *ny
; i
++)
1060 y
[i
] = 10.0 + i
*10.0 ;
1064 /*}}}************************************************************************/
1065 /*{{{ stm_mod_defaultfct2tbl_slew() */
1068 /****************************************************************************/
1069 void stm_mod_defaultfct2tbl_slew(timing_model
*model
, char xtype
, char ytype
)
1071 float s_axis
[2048], l_axis
[2048];
1072 long ns
= 0, nl
= 0;
1075 stm_getAxis(model
, s_axis
, &ns
, l_axis
, &nl
);
1077 ptype
= getptype(model
->USER
,STM_CARAC_VALUES
);
1079 model
->USER
= delptype(model
->USER
,STM_CARAC_VALUES
);
1081 if (xtype
== STM_NOTYPE
)
1083 stm_mod_fct2tbl_slew(model
, NULL
, 0, l_axis
, nl
, 0.0);
1085 else if (ytype
== STM_NOTYPE
)
1087 stm_mod_fct2tbl_slew(model
, s_axis
, ns
, NULL
, 0, 0.0);
1091 stm_mod_fct2tbl_slew(model
, s_axis
, ns
, l_axis
, nl
, 0.0);
1096 ptype
->NEXT
= model
->USER
;
1097 model
->USER
= ptype
;
1101 /*}}}************************************************************************/
1102 /*{{{ stm_mod_defaultfct2tbl_delay() */
1105 /****************************************************************************/
1106 void stm_mod_defaultfct2tbl_delay(timing_model
*model
, char xtype
, char ytype
)
1108 float s_axis
[2048], l_axis
[2048];
1109 long ns
= 0, nl
= 0;
1114 stm_getAxis(model
, s_axis
, &ns
, l_axis
, &nl
);
1116 ptype
= getptype(model
->USER
,STM_CARAC_VALUES
);
1121 model
->USER
= delptype(model
->USER
,STM_CARAC_VALUES
);
1123 if (xtype
== STM_NOTYPE
)
1124 stm_mod_fct2tbl_delay (model
, NULL
, 0, l_axis
, nl
, 0.0);
1125 else if (ytype
== STM_NOTYPE
)
1126 stm_mod_fct2tbl_delay (model
, s_axis
, ns
, NULL
, 0, 0.0);
1128 stm_mod_fct2tbl_delay (model
, s_axis
, ns
, l_axis
, nl
, 0.0);
1132 model
->USER
= addptype(model
->USER
,type
,data
);
1136 /*}}}************************************************************************/
1137 /*}}}************************************************************************/
1139 double stm_thr2scm(double fin
, double thmin
, double thmax
, double vt
, double vf
, double vdd
, char type
)
1144 else if(type
== STM_DN
)
1146 return elpThr2Scm (fin
, thmin
, thmax
, vt
, vf
, vdd
, elptype
);
1149 double stm_scm2thr(double fout
, double thmin
, double thmax
, double vt
, double vf
, double vdd
, char type
)
1154 else if(type
== STM_DN
)
1156 return elpScm2Thr (fout
, thmin
, thmax
, vt
, vf
, vdd
, elptype
);
1159 void stm_mod_shrinkslewaxis_thr2scm(timing_model
*model
, double *slews_scaled
, double *slews
, long ns
)
1162 double vt
, vdd
, vf
, thmin
, thmax
;
1165 vt
= stm_mod_vt(model
);
1166 vdd
= stm_mod_vdd_input(model
);
1167 vf
= stm_mod_vf_input(model
);
1168 if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_HH
)){
1169 thmin
= STM_DEFAULT_SMINR
;
1170 thmax
= STM_DEFAULT_SMAXR
;
1172 }else if((model
->TTYPE
== STM_LH
) || (model
->TTYPE
== STM_LL
)){
1173 thmin
= STM_DEFAULT_SMINF
;
1174 thmax
= STM_DEFAULT_SMAXF
;
1177 for (i
= 0; i
< ns
; i
++)
1178 slews_scaled
[i
] = stm_thr2scm (slews
[i
], thmin
, thmax
, vt
, vf
, vdd
, type
);
1181 double stm_mod_shrinkslew_thr2scm(timing_model
*model
, double fin
)
1183 double vt
, vdd
, vf
, thmin
, thmax
;
1186 if(model
->UTYPE
!= STM_MOD_MODSCM
)
1188 vt
= stm_mod_vt(model
);
1189 vdd
= stm_mod_vdd_input(model
);
1190 vf
= stm_mod_vf_input(model
);
1191 if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_HH
)){
1192 thmin
= STM_DEFAULT_SMINR
;
1193 thmax
= STM_DEFAULT_SMAXR
;
1195 }else if((model
->TTYPE
== STM_LH
) || (model
->TTYPE
== STM_LL
)){
1196 thmin
= STM_DEFAULT_SMINF
;
1197 thmax
= STM_DEFAULT_SMAXF
;
1200 return stm_thr2scm (fin
, thmin
, thmax
, vt
, vf
, vdd
, type
);
1203 double stm_mod_shrinkslew_scm2thr(timing_model
*model
, double fout
)
1205 double vt
, vdd
, vf
, thmin
, thmax
;
1208 if(model
->UTYPE
!= STM_MOD_MODSCM
)
1210 vt
= stm_mod_vt(model
);
1211 vdd
= stm_mod_vdd(model
);
1212 vf
= stm_mod_vf(model
);
1213 if((model
->TTYPE
== STM_LH
) || (model
->TTYPE
== STM_HH
)){
1214 thmin
= STM_DEFAULT_SMINR
;
1215 thmax
= STM_DEFAULT_SMAXR
;
1217 }else if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_LL
)){
1218 thmin
= STM_DEFAULT_SMINF
;
1219 thmax
= STM_DEFAULT_SMAXF
;
1222 return stm_scm2thr (fout
, thmin
, thmax
, vt
, vf
, vdd
, type
);
1225 void stm_mod_shrinkslewaxis_scm2thr (timing_model
*model
, double *slews
)
1228 /* double vt, vdd, vf, thmin, thmax;
1230 timing_table
*table
= model
->UMODEL
.TABLE
;
1232 /* vt = stm_mod_vt(model);
1233 vdd = stm_mod_vdd_input(model);
1234 vf = stm_mod_vf_input(model);
1235 if((model->TTYPE == STM_HL) || (model->TTYPE == STM_HH)){
1236 thmin = STM_DEFAULT_SMINR;
1237 thmax = STM_DEFAULT_SMAXR;
1239 }else if((model->TTYPE == STM_LH) || (model->TTYPE == STM_LL)){
1240 thmin = STM_DEFAULT_SMINF;
1241 thmax = STM_DEFAULT_SMAXF;
1244 if (table
->XTYPE
== STM_INPUT_SLEW
|| table
->XTYPE
== STM_CLOCK_SLEW
) {
1245 for (i
= 0; i
< table
->NX
; i
++) {
1246 table
->XRANGE
[i
] = /*stm_scm2thr (table->XRANGE[i], thmin, thmax, vt, vf, vdd, type)*/slews
[i
];
1250 if (table
->YTYPE
== STM_INPUT_SLEW
|| table
->YTYPE
== STM_CLOCK_SLEW
) {
1251 for (i
= 0; i
< table
->NY
; i
++) {
1252 table
->YRANGE
[i
] = /*stm_scm2thr (table->YRANGE[i], thmin, thmax, vt, vf, vdd, type)*/slews
[i
];
1257 void stm_mod_shrinkslewdata_scm2thr (timing_model
*model
)
1260 double vt
, vdd
, vth
, vf
, thmin
, thmax
;
1262 timing_table
*table
= model
->UMODEL
.TABLE
;
1264 vt
= stm_mod_vt(model
);
1265 vdd
= stm_mod_vdd(model
);
1266 vf
= stm_mod_vf(model
);
1267 vth
= stm_mod_vth(model
);
1268 if((model
->TTYPE
== STM_LH
) || (model
->TTYPE
== STM_HH
)){
1269 thmin
= STM_DEFAULT_SMINR
;
1270 thmax
= STM_DEFAULT_SMAXR
;
1272 }else if((model
->TTYPE
== STM_HL
) || (model
->TTYPE
== STM_LL
)){
1273 thmin
= STM_DEFAULT_SMINF
;
1274 thmax
= STM_DEFAULT_SMAXF
;
1278 if (!stm_modtbl_isnull (table
->CST
)) {
1279 stm_modtbl_setconst (table
, stm_scm2thr (table
->CST
, thmin
, thmax
, vt
, vf
, vdd
, type
));
1283 for (i
= 0; i
< table
->NX
; i
++) {
1284 table
->SET1D
[i
] = stm_scm2thr (table
->SET1D
[i
], thmin
, thmax
, vt
, vf
, vdd
, type
);
1289 for (i
= 0; i
< table
->NX
; i
++) {
1290 for (j
= 0; j
< table
->NY
; j
++) {
1291 table
->SET2D
[i
][j
] = stm_scm2thr (table
->SET2D
[i
][j
], thmin
, thmax
, vt
, vf
, vdd
, type
);
1298 int stm_if_thresholds(void)
1300 if((STM_DEFAULT_SMINR
> 0.0) &&
1301 (STM_DEFAULT_SMAXR
> 0.0) &&
1302 (STM_DEFAULT_SMINF
> 0.0) &&
1303 (STM_DEFAULT_SMAXF
> 0.0))