1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : STB Version 1.00 */
6 /* Fichier : stb_ctk_score.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Grégoire AVOT */
14 /****************************************************************************/
34 #include "stb_error.h"
35 #include "stb_transfer.h"
36 #include "stb_relaxation.h"
37 #include "stb_overlap.h"
39 #include "stb_ctk_noise.h"
40 #include "stb_ctk_debug.h"
41 #include "stb_ctk_score.h"
43 int STB_CTK_COEF_NOISE
= 4 ;
44 int STB_CTK_COEF_CTK
= 2 ;
45 int STB_CTK_COEF_INTERVAL
= 3 ;
46 int STB_CTK_COEF_ACTIVITY
= 1 ;
48 int STB_CTK_MIN_NOISE
= 3 ;
49 int STB_CTK_MIN_CTK
= 0 ;
50 int STB_CTK_MIN_INTERVAL
= 0 ;
51 int STB_CTK_MIN_ACTIVITY
= 0 ;
53 char STB_CTK_STAT_COMPARE
= STB_CTK_SORT_SCORE_TOTAL
;
55 int stb_ctk_good_score( int score
)
57 if( score
< 0 ) score
= 0 ;
58 if( score
> 10 ) score
= 10 ;
63 int stb_ctk_get_min_noise()
65 return STB_CTK_MIN_NOISE
;
68 int stb_ctk_get_min_interval()
70 return STB_CTK_MIN_INTERVAL
;
73 int stb_ctk_get_min_ctk()
75 return STB_CTK_MIN_CTK
;
78 int stb_ctk_get_min_activity()
80 return STB_CTK_MIN_ACTIVITY
;
83 void stb_ctk_set_min_score( int noise
, int ctk
, int interval
, int activity
)
86 STB_CTK_MIN_NOISE
= noise
;
88 STB_CTK_MIN_CTK
= ctk
;
90 STB_CTK_MIN_INTERVAL
= interval
;
92 STB_CTK_MIN_ACTIVITY
= activity
;
95 int stb_ctk_get_coef_noise()
97 return STB_CTK_COEF_NOISE
;
100 int stb_ctk_get_coef_ctk()
102 return STB_CTK_COEF_CTK
;
105 int stb_ctk_get_coef_interval()
107 return STB_CTK_COEF_INTERVAL
;
110 int stb_ctk_get_coef_activity()
112 return STB_CTK_COEF_ACTIVITY
;
115 /******************************************************************************\
116 stb_ctk_set_coef_score()
117 Initialise les 4 coefficients de pondérations.
118 Les valeurs négatives ne modifient pas le coefficients.
119 Les valeurs sont bornées à 10.
120 \******************************************************************************/
121 void stb_ctk_set_coef_score( int noise
, int ctk
, int interval
, int activity
)
124 STB_CTK_COEF_NOISE
= stb_ctk_good_score( noise
);
126 STB_CTK_COEF_CTK
= stb_ctk_good_score( ctk
);
128 STB_CTK_COEF_INTERVAL
= stb_ctk_good_score( interval
);
130 STB_CTK_COEF_ACTIVITY
= stb_ctk_good_score( activity
);
133 int stb_ctk_get_score_total( stb_ctk_tab_stat
*stat
)
137 n
= stb_ctk_get_score_noise( stat
) * STB_CTK_COEF_NOISE
+
138 stb_ctk_get_score_ctk( stat
) * STB_CTK_COEF_CTK
+
139 stb_ctk_get_score_interval( stat
) * STB_CTK_COEF_INTERVAL
+
140 stb_ctk_get_score_activity( stat
) * STB_CTK_COEF_ACTIVITY
;
146 int stb_ctk_get_score_noise( stb_ctk_tab_stat
*stat
)
148 return stat
->SCORE_NOISE
;
151 int stb_ctk_get_score_ctk( stb_ctk_tab_stat
*stat
)
153 return stat
->SCORE_CTK
;
156 int stb_ctk_get_score_interval( stb_ctk_tab_stat
*stat
)
158 return stat
->SCORE_INTERVAL
;
161 int stb_ctk_get_score_activity( stb_ctk_tab_stat
*stat
)
163 return stat
->SCORE_ACTIVITY
;
166 int stb_ctk_get_score_probability( stb_ctk_tab_stat
*stat
)
168 return stat
->SCORE_PROBABILITY
;
171 /******************************************************************************\
172 stb_ctk_score_noise()
174 Note l'effet du bruit.
175 \******************************************************************************/
176 int stb_ctk_score_noise( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
184 vth
= detail
->NOISE_VTH
;
186 if( ( detail
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
187 noise
= detail
->NOISE_OVR
;
189 noise
= detail
->NOISE_UND
;
191 if( ( detail
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) {
195 score
= ceil( noise
/vth
*10.0 );
198 vdd
= stb_ctk_signal_get_vdd( stbfig
, detail
->NODE
);
199 if( (vdd
-noise
) < vth
)
202 score
= ceil( noise
/(vdd
-vth
)*10.0 );
204 score
= stb_ctk_good_score( score
);
208 /******************************************************************************\
209 stb_ctk_score_interval()
211 Note l'impact de la simultanéité des agresseurs. C'est la part maximum de
212 crosstalk qui peut etre activée à un instant donné.
213 \******************************************************************************/
214 int stb_ctk_score_interval( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
220 stb_ctk_detail_agr_list
*agr
;
227 char calcul
[] = { TTV_NODE_DOWN
, TTV_NODE_UP
};
228 stb_ctk_gap
*ctkgap
;
230 for( i
= 0 ; i
<= 1 ; i
++) {
235 ctkgap
= stb_fill_gap( stbfig
, detail
, calcul
[i
] );
237 for( chain
= ctkgap
->NOINFO
; chain
; chain
= chain
->NEXT
) {
238 agr
= (stb_ctk_detail_agr_list
*)chain
->DATA
;
240 ccalways
[i
] = ccalways
[i
] + agr
->CC
;
243 /* Prend en compte les agresseurs considérés comme toujours actifs */
244 for( chain
= ctkgap
->OTHERDOMAIN
; chain
; chain
= chain
->NEXT
) {
245 agr
= stb_ctk_get_node_detail( ((ttvevent_list
*)chain
->DATA
)->ROOT
);
247 ccalways
[i
] = ccalways
[i
] + agr
->CC
;
250 /* Récupère le crosstalk maximum sur les différents gap */
251 for( gap
= ctkgap
->GAPACTIF
; gap
; gap
= gap
->NEXT
) {
253 for( chain
= gap
->SIGNALS
; chain
; chain
= chain
->NEXT
) {
254 agr
= stb_ctk_get_node_detail( ((ttvevent_list
*)chain
->DATA
)->ROOT
);
256 cgap
= cgap
+ agr
->CC
;
258 if( cgap
> cgapmax
[i
] )
263 sdw
= ccalways
[0] + cgapmax
[0] ;
264 sup
= ccalways
[1] + cgapmax
[1] ;
266 if( detail
->CC
> 0.0 ) {
268 s
= 10.0 * sup
/ detail
->CC
;
270 s
= 10.0 * sdw
/ detail
->CC
;
276 score
= stb_ctk_good_score( score
);
280 /******************************************************************************\
283 Repère les signaux dont le crosstalk est majoritairement due à un nombre
285 \******************************************************************************/
286 int stb_ctk_score_ctk( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
289 stb_ctk_detail_agr_list
*agr
;
296 for( agr
= detail
->AGRLIST
, maxagr
=0 ; agr
; agr
= agr
->NEXT
, maxagr
++ ) ;
302 tabcapa
= (float*)mbkalloc( sizeof( float ) * maxagr
);
304 for( agr
= detail
->AGRLIST
, i
=0 ; agr
; agr
= agr
->NEXT
, i
++ )
305 tabcapa
[i
] = agr
->CC
;
310 (int (*)(const void*, const void*))stb_ctk_qsort_float
314 climit
= detail
->CC
/ 2.0 ;
316 for( i
=0 ; i
< maxagr
; i
++ ) {
317 sum
= sum
+ tabcapa
[i
] ;
322 score
= ceil(( 10.0 * (2*i
- (maxagr
-1)) ) / (maxagr
-1)) ;
323 score
= stb_ctk_good_score( score
);
326 stbfig
= NULL
; // unused parameter
330 /******************************************************************************\
331 stb_ctk_score_activity()
333 Evalue l'impact de l'activité d'un agresseur.
334 Pour l'instant, seules les clock ont une activité à peu près connue.
335 La note renvoyée sur 10 correspond à la part de crosstalk due aux agresseurs
336 considérés comme systématiquement actifs.
340 Voir si il ne faut pas affecter une note intermédiaire aux agresseurs pour
341 lesquels l'activité n'est pas connue, une note maximum si l'activité est
342 certaine et une note minimum si il n'est pas actif.
343 \******************************************************************************/
344 int stb_ctk_score_activity( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
347 stb_ctk_detail_agr_list
*agr
;
356 for( i
= 0 ; i
<= 1 ; i
++ ) {
359 for( agr
= detail
->AGRLIST
; agr
; agr
= agr
->NEXT
) {
362 node
= stb_getstbnode( &(agr
->TTVAGR
->NODE
[i
]) );
367 s
[i
] = s
[i
] + agr
->CC
;
372 if( detail
->CC
> 0.0 ) {
374 r
= 10.0 * s
[0] / detail
->CC
;
376 r
= 10.0 * s
[1] / detail
->CC
;
382 score
= stb_ctk_good_score( score
);
384 stbfig
= NULL
; // unused parameter
388 // probabilite d'occurence de l'agression
389 int stb_ctk_score_propability( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
392 stb_ctk_detail_agr_list
*agr
;
400 for( agr
= detail
->AGRLIST
; agr
; agr
= agr
->NEXT
)
404 if ((pt
=getptype(agr
->TTVAGR
->USER
, STB_TRANSITION_PROBABILITY
))!=NULL
)
405 proba
*=*(float *)&pt
->DATA
;
409 score
= (int)mbk_long_round(10-log(1/proba
));
410 if (score
<0) score
=0;
411 stbfig
= NULL
; // unused parameter
415 /******************************************************************************\
417 \******************************************************************************/
418 void stb_ctk_calc_score( stbfig_list
*stbfig
,
419 stb_ctk_detail
*ctkdetail
,
420 stb_ctk_tab_stat
*stat
423 stat
->SCORE_NOISE
= stb_ctk_score_noise( stbfig
, ctkdetail
);
424 stat
->SCORE_INTERVAL
= stb_ctk_score_interval( stbfig
, ctkdetail
);
425 stat
->SCORE_CTK
= stb_ctk_score_ctk( stbfig
, ctkdetail
);
426 stat
->SCORE_ACTIVITY
= stb_ctk_score_activity( stbfig
, ctkdetail
);
427 stat
->SCORE_PROBABILITY
= stb_ctk_score_propability( stbfig
, ctkdetail
);
430 int stb_ctk_qsort_float( float *f1
, float *f2
)
432 if( *f1
< *f2
) return -1 ;
433 if( *f1
> *f2
) return 1 ;
437 /******************************************************************************\
438 stb_ctk_signal_threshold()
439 Calcule la tension admissible au maximum sur un signal.
440 si <0, c'est qu'on a pas pu la déterminer (cas d'une sortie).
441 \******************************************************************************/
443 float stb_ctk_signal_threshold( stbfig_list
*stbfig
, ttvevent_list
*event
)
447 chain_list
*headline
;
450 float vthmax
= -1.0 ;
451 ttvline_list
*ptline
;
452 ttvevent_list
*nodet
;
453 timing_model
*model
;
456 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
457 level
= stbfig
->FIG
->INFO
->LEVEL
;
461 ttv_expfigsig( stbfig
->FIG
,
464 stbfig
->FIG
->INFO
->LEVEL
,
465 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
,
469 if((ptype
= getptype(event
->USER
,TTV_NODE_DUALLINE
)) != NULL
)
470 headline
= (chain_list
*)ptype
->DATA
;
476 for( chline
= headline
; chline
; chline
= chline
->NEXT
) {
478 ptline
= (ttvline_list
*)chline
->DATA
;
481 if( !ttv_islinelevel( stbfig
->FIG
, ptline
, level
) )
484 nodet
= ptline
->ROOT
;
486 if( (ptline
->TYPE
& TTV_LINE_RC
) == TTV_LINE_RC
) {
487 vth
= stb_ctk_signal_threshold( stbfig
, nodet
);
490 model
= stm_getmodel( ptline
->FIG
->INFO
->FIGNAME
, ptline
->MDMAX
);
492 if( stm_noise_getmodeltype( model
) == STM_NOISE_SCR
) {
493 vth
= stm_noise_scr_invth( stm_noise_getmodel_scr(model
) ) ;
498 if( ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) {
499 if( found
== 0 || vth
< vthmax
) {
505 if( found
== 0 || vth
> vthmax
) {
515 float stb_ctk_signal_get_vdd( stbfig_list
*stbfig
, ttvevent_list
*event
)
518 float vddmin
= FLT_MAX
;
520 ttvline_list
*ptline
;
521 timing_model
*model
;
524 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
525 level
= stbfig
->FIG
->INFO
->LEVEL
;
529 ttv_expfigsig( stbfig
->FIG
,
532 stbfig
->FIG
->INFO
->LEVEL
,
533 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
,
538 for( ptline
= event
->INLINE
; ptline
; ptline
= ptline
->NEXT
) {
540 if( !ttv_islinelevel( stbfig
->FIG
, ptline
, level
) )
543 model
= stm_getmodel( ptline
->FIG
->INFO
->FIGNAME
, ptline
->MDMAX
);
545 vdd
= stm_mod_vdd( model
) ;
547 if( found
== 0 || vdd
< vddmin
) {
555 vddmin
= stm_mod_default_vdd() ;
561 float stb_ctk_signal_threshold_from_input( stbfig_list
*stbfig
,
567 float vddmin
= FLT_MAX
;
569 ttvline_list
*ptline
;
570 timing_model
*model
;
572 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
573 level
= stbfig
->FIG
->INFO
->LEVEL
;
577 ttv_expfigsig( stbfig
->FIG
,
580 stbfig
->FIG
->INFO
->LEVEL
,
581 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
,
585 for( ptline
= event
->INLINE
; ptline
; ptline
= ptline
->NEXT
) {
587 if( !ttv_islinelevel( stbfig
->FIG
, ptline
, level
) )
590 model
= stm_getmodel( ptline
->FIG
->INFO
->FIGNAME
, ptline
->MDMAX
);
592 vdd
= stm_mod_vdd( model
) ;
599 if( vddmin
< FLT_MAX
)
602 vth
= stm_mod_default_vdd() / 2.0 ;
607 /******************************************************************************\
608 Fonction de comparaison pour trier les tableaux de statistiques. Le critère
609 de trie doit être mis dans la variable globale STB_CTK_STAT_COMPARE.
610 \******************************************************************************/
611 int stb_ctk_score_compare( stb_ctk_tab_stat
*n1
, stb_ctk_tab_stat
*n2
)
616 switch( STB_CTK_STAT_COMPARE
) {
617 case STB_CTK_SORT_SCORE_TOTAL
:
618 s1
= stb_ctk_get_score_total( n1
);
619 s2
= stb_ctk_get_score_total( n2
);
621 case STB_CTK_SORT_SCORE_NOISE
:
622 s1
= stb_ctk_get_score_noise( n1
);
623 s2
= stb_ctk_get_score_noise( n2
);
625 case STB_CTK_SORT_SCORE_CTK
:
626 s1
= stb_ctk_get_score_ctk( n1
);
627 s2
= stb_ctk_get_score_ctk( n2
);
629 case STB_CTK_SORT_SCORE_INTERVAL
:
630 s1
= stb_ctk_get_score_interval( n1
);
631 s2
= stb_ctk_get_score_interval( n2
);
633 case STB_CTK_SORT_SCORE_ACTIVITY
:
634 s1
= stb_ctk_get_score_activity( n1
);
635 s2
= stb_ctk_get_score_activity( n2
);
642 if( s1
< s2
) return 1 ;
643 if( s1
> s2
) return -1 ;
644 r
=strcmp( n1
->NODE
->ROOT
->NAME
, n2
->NODE
->ROOT
->NAME
);
648 if( ( n1
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
653 if( ( n2
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
658 if( trs1
>trs2
) return 1;
659 if( trs2
>trs1
) return -1;
663 int stb_ctk_stat_to_keep( stb_ctk_tab_stat
*stat
)
665 if( stb_ctk_get_score_noise( stat
) < stb_ctk_get_min_noise() ||
666 stb_ctk_get_score_interval( stat
) < stb_ctk_get_min_interval() ||
667 stb_ctk_get_score_ctk( stat
) < stb_ctk_get_min_ctk() ||
668 stb_ctk_get_score_activity( stat
) < stb_ctk_get_min_activity() )
673 void stb_ctk_fix_min( stb_ctk_stat
*stat
)
677 stb_ctk_tab_stat tmp
;
679 tabend
= stat
->NBELEM
;
681 while( curpos
< tabend
) {
682 if( ! stb_ctk_stat_to_keep( &stat
->TAB
[curpos
] ) ) {
683 if( curpos
!= tabend
-1 ) {
684 memcpy( &tmp
, &stat
->TAB
[curpos
], sizeof( stb_ctk_tab_stat
) ) ;
685 memcpy( &stat
->TAB
[curpos
], &stat
->TAB
[tabend
-1], sizeof( stb_ctk_tab_stat
) ) ;
686 memcpy( &stat
->TAB
[tabend
-1], &tmp
, sizeof( stb_ctk_tab_stat
) ) ;
694 stat
->NBDISPLAY
= tabend
;