1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : STB Version 1.00 */
6 /* Fichier : stb_ctk.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Karim DIOURY */
15 /****************************************************************************/
33 #include "stb_error.h"
34 #include "stb_transfer.h"
35 #include "stb_relaxation.h"
36 #include "stb_overlap.h"
38 #include "stb_ctk_noise.h"
39 #include "stb_ctk_debug.h"
40 #include "stb_ctk_score.h"
41 #include "stb_ctk_mutex.h"
42 #include "stb_ctk_agr.h"
44 #include "stb_relaxation_correction.h"
45 #include "stb_ctk_report.h"
48 #include "api_communication.h"
49 #include "stb_communication.c"
52 // Variation de front minimum pour considérer un changement significatif
53 long STB_CTK_MINSLOPECHANGE
=0;
55 // Nombre maximum d'itération lorsqu'il n'y a plus de nouvelles agressions
57 int STB_CTK_MAXLASTITER
=3;
59 // Autorise plus de consommation mémoire pour aller plus vite
60 char STB_CTK_FASTMODE
=1;
62 // Comportement des agresseurs pour lesquels il n'y a pas d'information temporelle
63 //int STB_CTK_NOINFO_ACTIF=0;
65 // Le fichier de report
66 long CTK_REPORT_DELTA_DELAY_MIN
= 0;
67 long CTK_REPORT_DELTA_SLOPE_MIN
= 0;
68 float CTK_REPORT_CTK_MIN
= 0.0;
69 long CTK_REPORT_NOISE_MIN
= 0;
70 // La marge pour la détection des agressions
71 long STB_CTK_MARGIN
=0l;
76 ------------------------------------------------------------------------------
78 FONCTIONS D'AFFICHAGE ET DE DEBUGGAGE
80 ------------------------------------------------------------------------------
83 /* Largeur de la barre de progression */
84 #define STB_PROGRESS_WIDTH 50
86 /* Fonction à appeller pour la barre de progression */
87 void (*CTK_PROGRESSBAR
)(int, int, int, char*) = stb_progress
;
88 /* Fonction à appeller pour l'affichage d'informations */
89 void (*CTK_PRINTINFO
)(char*) = stb_print
;
91 int STBCTK_NBDELAYCALC
;
93 void stb_ctk_error( int code
, char *fmt
, ... )
96 va_start( index
, fmt
);
99 fprintf( stderr
, "\n\n*** ERROR %d IN STB/CTK ***\n\n", code
);
100 vfprintf( stderr
, fmt
, index
);
101 fprintf( stderr
, "\n" );
105 void stb_print( char *msg
)
107 printf( "%s\n", msg
);
110 void stb_progressbar( int max
, int current
)
112 static char ligne
[1024];
118 if( ! isatty(1) || max
== 0 ) return;
122 for( i
=0 ; i
<1024 ; i
++ ) ligne
[i
]=' ';
124 ligne
[STB_PROGRESS_WIDTH
+1]='\0';
128 pos
= ((long)current
)*STB_PROGRESS_WIDTH
/max
;
129 r
= ((long)current
)*100/max
;
130 if( lastr
!= r
|| last
!= pos
|| current
==0) {
131 for( i
=(last
<0?0:last
) ; i
<=pos
; i
++ ) {
134 avt_fprintf( stdout
, "\r%3ld%% [¤2%s¤.] %7ldKb", r
, ligne
, mbkprocessmemoryusage()/1024 );
141 void stb_progress( int iteration
, int max
, int pos
, char *msg
)
143 char bufchrono
[128] ;
144 static mbk_chrono chrono
;
145 static int lastiter
= -1 ;
148 printf( "\n%s\n", msg
);
149 mbk_StartChrono( &chrono
);
152 if( iteration
&& lastiter
!= iteration
)
153 printf( "Iteration #%d\n", iteration
);
154 stb_progressbar( max
, pos
);
157 mbk_StopChrono( &chrono
);
158 mbk_GetUserChrono( &chrono
, bufchrono
);
159 printf(" User CPU time : %s\n", bufchrono
);
160 mbk_StartChrono( &chrono
);
164 lastiter
= iteration
;
168 ------------------------------------------------------------------------------
170 MEMORISATION DES AGRESSIONS ACTIVES DANS STB
172 ------------------------------------------------------------------------------
176 Dans beaucoups de cas, il y a très peu d'agresseurs actifs. Une ptype_list
177 pour stocker l'agresseur (champs DATA) et le type d'agression (champs TYPE)
178 est donc satisfaisante, même si entre les fonctions stb_fillactifrcxparam(),
179 stb_saveactifrcxparam(), stb_getagressiontype() et stb_setagressiontype() cela
180 conduit à des algos en n².
182 Lorsque le n² devient inacceptable ( STB_CTK_MAXCHAIN²), les ptype_list sont
183 remplacées par des tables de hash. Le gain est double : la consomation mémoire
184 ( la table de hash est un tableau de 2 valeurs, il n'y a pas de champs NEXT)
185 et le temps de calcul sont réduit.
187 Q : Pourquoi ne pas avoir utilisé alors systématiquement une table de hash ?
189 Parceque le malloc() standard utilisé par défaut dans addht() consomme en
190 réalité 24 octets au lieu de 12, et si on prend un petit nombre initial (par
191 exemple 2), le malloc des htitem consomme 24 octets au lieu de 16. Pour les
192 petits nombres d'agresseurs actifs (jusqu'à 6), la table de hash est donc plus
193 coûteuse en mémoire, pour un gain CPU très faible.
196 On ne peut pas utiliser les flags de rcx/rcn car les vues rcx sont factorisées :
197 Deux ttvsig peuvent correspondre à un losig.
200 /*****************************************************************************
201 * fonction stb_getagressiontype() *
202 ******************************************************************************
203 * Récupère l'agression entre deux signaux. *
204 *****************************************************************************/
205 char stb_getagressiontype( victime
, agresseur
)
206 ttvsig_list
*victime
;
207 ttvsig_list
*agresseur
;
212 ptl
= getptype( victime
->USER
, STB_CTK_RCXAGRPT
);
216 for( ptl
= ((ptype_list
*)(ptl
->DATA
)) ;
217 ptl
&& ((ttvsig_list
*)(ptl
->DATA
)) != agresseur
;
221 return ((char)(ptl
->TYPE
)) ;
226 ptl
= getptype( victime
->USER
, STB_CTK_RCXAGRHT
);
230 v
= gethtitem( ((ht
*)(ptl
->DATA
)), agresseur
);
240 /*****************************************************************************
241 * fonction stb_setagressiontype() *
242 ******************************************************************************
243 * Mémorise l'agression entre deux signaux. *
244 *****************************************************************************/
245 void stb_setagressiontype( victime
, agresseur
, type
)
246 ttvsig_list
*victime
;
247 ttvsig_list
*agresseur
;
255 ptl
= getptype( victime
->USER
, STB_CTK_RCXAGRHT
);
258 sethtitem( ((ht
*)(ptl
->DATA
)), agresseur
, (long)((unsigned char)type
) );
262 ptl
= getptype( victime
->USER
, STB_CTK_RCXAGRPT
);
266 victime
->USER
= addptype( victime
->USER
,
273 for( scan
= ((ptype_list
*)(ptl
->DATA
)), n
=0 ;
274 scan
&& ((ttvsig_list
*)(scan
->DATA
)) != agresseur
;
275 scan
= scan
->NEXT
, n
++ );
278 scan
->TYPE
= (char) type
;
282 if( n
> STB_CTK_MAXCHAIN
) {
284 newht
= addht( STB_CTK_MAXCHAIN
+ 1 );
286 for( scan
= ((ptype_list
*)( ptl
->DATA
)) ; scan
; scan
= scan
->NEXT
)
287 addhtitem( newht
, scan
->DATA
, (long)((unsigned char)scan
->TYPE
) );
288 addhtitem( newht
, agresseur
, (long)((unsigned char)type
) );
290 freeptype( ((ptype_list
*)(ptl
->DATA
)) );
291 victime
->USER
= delptype( victime
->USER
, STB_CTK_RCXAGRPT
);
294 victime
->USER
= addptype( victime
->USER
, STB_CTK_RCXAGRHT
, newht
);
299 ptl
->DATA
= addptype( ((ptype_list
*)(ptl
->DATA
)),
309 void stb_cleanagressiontype( ttvsig_list
*signal
)
313 ptl
= getptype( signal
->USER
, STB_CTK_RCXAGRPT
);
315 freeptype( (ptype_list
*)ptl
->DATA
);
316 signal
->USER
= delptype( signal
->USER
, STB_CTK_RCXAGRPT
);
319 ptl
= getptype( signal
->USER
, STB_CTK_RCXAGRHT
);
321 delht( (ht
*)ptl
->DATA
);
322 signal
->USER
= delptype( signal
->USER
, STB_CTK_RCXAGRHT
);
327 Marque les driver de victime. Renvoie la chain_list des ttvsig marqués pour
328 les nettoyer plus tard
330 victime est un ttvsig en sortie de gate
331 Ne fonctionne qu'à plat.
334 chain_list
* stb_mark_input( ttvfig_list
*ttvfig
,
335 ttvsig_list
*victime
,
341 ttvline_list
*linerc
;
342 ttvsig_list
*ttvsig
;
343 ttvsig_list
*ttvsigrc
;
344 chain_list
*toclean
;
346 ttv_expfigsig( ttvfig
, victime
, level
, ttvfig
->INFO
->LEVEL
,
347 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
, TTV_FILE_DTX
352 for( i
=0 ; i
<= 1 ; i
++ ) {
354 for( line
= victime
->NODE
[i
].INLINE
; line
; line
= line
->NEXT
) {
356 if( !ttv_islinelevel( ttvfig
, line
, level
) )
359 ttvsig
= line
->NODE
->ROOT
;
361 if( !getptype( ttvsig
->USER
, STB_CTK_DRIVER
) ) {
362 ttvsig
->USER
= addptype( ttvsig
->USER
, STB_CTK_DRIVER
, 0l );
363 toclean
= addchain( toclean
, ttvsig
);
366 /* on marque également les driver des entrées rc */
368 for( j
=0 ; j
<=1 ; j
++ ) {
369 for( linerc
= ttvsig
->NODE
[j
].INLINE
; linerc
; linerc
= linerc
->NEXT
)
372 if( ((linerc
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
) ||
373 !ttv_islinelevel( ttvfig
, linerc
, level
) )
376 ttvsigrc
= linerc
->NODE
->ROOT
;
377 if( !getptype( ttvsigrc
->USER
, STB_CTK_DRIVER
) ) {
378 ttvsigrc
->USER
= addptype( ttvsigrc
->USER
, STB_CTK_DRIVER
, 0l );
379 toclean
= addchain( toclean
, ttvsigrc
);
389 int stb_is_mark_input( ttvsig_list
*ttvsig
)
391 if( getptype( ttvsig
->USER
, STB_CTK_DRIVER
) )
396 void stb_clean_mark_input( chain_list
*tocleanmark
)
399 ttvsig_list
*ttvsig
;
401 for( chain
= tocleanmark
; chain
; chain
= chain
->NEXT
) {
402 ttvsig
= (ttvsig_list
*)chain
->DATA
;
403 ttvsig
->USER
= delptype( ttvsig
->USER
, STB_CTK_DRIVER
);
405 freechain( tocleanmark
);
408 static void stb_set_min_slope(ttvfig_list
*ttvfig
, ttvevent_list
*tve
, int level
, int mode
)
411 long delayval
, lineval
;
414 if ((pt
=getptype(tve
->ROOT
->USER
, STB_CTK_FAST_SLOPE
))==NULL
)
416 sfs
=(stb_fastslope
*)mbkalloc(sizeof(stb_fastslope
));
417 pt
=tve
->ROOT
->USER
=addptype(tve
->ROOT
->USER
, STB_CTK_FAST_SLOPE
, sfs
);
420 sfs
->ev
[i
].delayval
=sfs
->ev
[i
].lineval
=STM_DEF_SLEW
;
421 sfs
->ev
[i
].pairnode
=NULL
;
425 sfs
=(stb_fastslope
*)pt
->DATA
;
427 if (tve
->TYPE
& TTV_NODE_UP
) i
=1; else i
=0;
430 sfs
->ev
[i
].delayval
= ttv_getslopenode( ttvfig
,
433 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
436 if( sfs
->ev
[i
].delayval
== 0 ) sfs
->ev
[i
].delayval
= STM_DEF_SLEW
;
440 sfs
->ev
[i
].lineval
= ttv_getslopenode( ttvfig
,
443 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
446 if( sfs
->ev
[i
].lineval
== 0 ) sfs
->ev
[i
].lineval
= STM_DEF_SLEW
;
450 void stb_setupall_slopes(stbfig_list
*stbfig
, int level
)
454 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
456 tve
=(ttvevent_list
*)chain
->DATA
;
457 stb_set_min_slope(stbfig
->FIG
, tve
, level
, 3);
460 void stb_cleanup_slopes(stbfig_list
*stbfig
)
467 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
469 tve
=(ttvevent_list
*)chain
->DATA
;
470 if ((pt
=getptype(tve
->ROOT
->USER
, STB_CTK_FAST_SLOPE
))!=NULL
)
472 sfs
=(stb_fastslope
*)pt
->DATA
;
474 stb_freestbpair(sfs
->ev
[i
].pairnode
);
476 tve
->ROOT
->USER
=delptype(tve
->ROOT
->USER
, STB_CTK_FAST_SLOPE
);
480 void stb_release_fast_nodepair(ttvevent_list
*tve
)
485 if (tve
->TYPE
& TTV_NODE_UP
) i
=1; else i
=0;
486 if ((pt
=getptype(tve
->ROOT
->USER
, STB_CTK_FAST_SLOPE
))!=NULL
)
488 sfs
=(stb_fastslope
*)pt
->DATA
;
489 stb_freestbpair(sfs
->ev
[i
].pairnode
);
490 sfs
->ev
[i
].pairnode
=NULL
;
494 void stb_cleanup_fast_nodepair(stbfig_list
*stbfig
)
498 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
500 tve
=(ttvevent_list
*)chain
->DATA
;
501 stb_release_fast_nodepair(tve
);
505 /*****************************************************************************
506 * fonction stb_fillttvsigrcxparam() *
507 ******************************************************************************
508 * Ajoute dans tous les rcxparam d'une liste le ttvsig correspondant. Remplie *
509 * egalement les champs FMINUP et FMINDW. Lorsque plusieurs agresseurs sont *
510 * présents, on prend le pire en terme de fronts. *
511 *****************************************************************************/
512 void stb_fillttvsigrcxparam( ttvfig
, level
, type
, headlist
)
516 chain_list
*headlist
;
524 stb_ctkprint( 1, "Filling agressor parameter :\n" );
527 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
529 param
= (rcxparam
*)(chain
->DATA
);
532 ttvsig
= ttv_getttvsig( ttvfig
,
542 param
->USER
= addptype( param
->USER
, STB_CTK_RCXTTVSIG
, ttvsig
);
543 if ((pt
=getptype(ttvsig
->USER
, STB_CTK_FAST_SLOPE
))!=NULL
)
545 sfs
=(stb_fastslope
*)pt
->DATA
;
546 param
->FMINUP
=sfs
->ev
[1].delayval
;
547 param
->FMINDW
=sfs
->ev
[0].delayval
;
548 param
->F0UP
=sfs
->ev
[1].lineval
;
549 param
->F0DW
=sfs
->ev
[0].lineval
;
553 param
->FMINUP
= ttv_getslopenode( ttvfig
,
556 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
559 if( param
->FMINUP
== 0 ) param
->FMINUP
= STM_DEF_SLEW
;
561 param
->FMINDW
= ttv_getslopenode( ttvfig
,
564 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
567 if( param
->FMINDW
== 0 ) param
->FMINDW
= STM_DEF_SLEW
;
569 param
->F0UP
= ttv_getslopenode( ttvfig
,
572 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
575 if( param
->F0UP
== 0 ) param
->F0UP
= STM_DEF_SLEW
;
577 param
->F0DW
= ttv_getslopenode( ttvfig
,
580 TTV_FIND_LINE
| TTV_FIND_GATE
| TTV_FIND_RC
| TTV_FIND_MIN
,
583 if( param
->F0DW
== 0 ) param
->F0DW
= STM_DEF_SLEW
;
587 " %s (netname=%s) : Fmin Up = %g, F0 Up = %g, Fmin Dw = %g, F0 Dw = %g\n",
597 stb_ctkprint( 1, " No corresponding ttvsig for signal %s\n",
598 getsigname( param
->SIGNAL
)
600 param
->FMINUP
= STM_DEF_SLEW
;
601 param
->FMINDW
= STM_DEF_SLEW
;
602 param
->F0UP
= STM_DEF_SLEW
;
603 param
->F0DW
= STM_DEF_SLEW
;
608 /*****************************************************************************
609 * fonction stb_delttvsigrcxparam() *
610 ******************************************************************************
611 * Libère dans tous les rcxparam d'une liste le ttvsig correspondant. *
612 *****************************************************************************/
613 void stb_delttvsigrcxparam( headlist
)
614 chain_list
*headlist
;
620 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
622 param
= (rcxparam
*)(chain
->DATA
);
624 ptl
= getptype( param
->USER
, STB_CTK_RCXTTVSIG
);
628 param
->USER
= delptype( param
->USER
, STB_CTK_RCXTTVSIG
);
632 /*****************************************************************************
633 * fonction stb_getttvsigrcxparam() *
634 ******************************************************************************
635 * Récupère le ttvsig correspondant à un rcxparam *
636 *****************************************************************************/
637 ttvsig_list
* stb_getttvsigrcxparam( param
)
642 ptl
= getptype( param
->USER
, STB_CTK_RCXTTVSIG
);
648 return ((ttvsig_list
*)(ptl
->DATA
));
651 /*****************************************************************************
652 * fonction stb_getrcxparamfromevent() *
653 ******************************************************************************
654 * Récupère le rcxparam d'un event. *
655 *****************************************************************************/
656 rcxparam
* stb_getrcxparamfromevent( event
)
657 ttvevent_list
*event
;
662 ptl
= getptype( event
->USER
, STB_CTK_RCXPARAM
);
665 fprintf( stderr
, "*** Error in STB/CTK : Can't find rcxparam from event.\n"
669 param
= ((rcxparam
*)(ptl
->DATA
));
674 /*****************************************************************************
675 * fonction stb_addrcxparamfromevent() *
676 ******************************************************************************
677 * Récupère le rcxparam d'un event. *
678 *****************************************************************************/
679 void stb_addrcxparamfromevent( event
, param
)
680 ttvevent_list
*event
;
685 ptl
= getptype( event
->USER
, STB_CTK_RCXPARAM
);
688 fprintf( stderr
, "*** Error in STB/CTK : event contain an rcxparam.\n"
694 event
->USER
= addptype( event
->USER
, STB_CTK_RCXPARAM
, param
);
697 /*****************************************************************************
698 * fonction stb_getrcxparamfromevent() *
699 ******************************************************************************
700 * Récupère le rcxparam d'un event. *
701 *****************************************************************************/
702 void stb_delrcxparamfromevent( event
)
703 ttvevent_list
*event
;
707 ptl
= getptype( event
->USER
, STB_CTK_RCXPARAM
);
710 fprintf( stderr
, "*** Error in STB/CTK : Can't find rcxparam from event.\n"
715 event
->USER
= delptype( event
->USER
, STB_CTK_RCXPARAM
);
719 /*****************************************************************************
720 * fonction stb_fillactifrcxparam() *
721 ******************************************************************************
722 * Remplis le champs ACTIF des structures rcxparam à partir des valeurs *
723 * calculées aux itérations précédentes. *
724 * mutex vaut 'Y' ou 'N'. A 'N', seul les aggressions sont renvoyées. A 'Y', *
725 * les résultats de mutex sont pris en compte. *
726 *****************************************************************************/
727 #define STB_MAX_AGR 10000
733 } agr_sort_proba_info
;
735 static int stb_compare_proba_capa(const void *a
, const void *b
)
737 agr_sort_proba_info
*aspia
=(agr_sort_proba_info
*)a
;
738 agr_sort_proba_info
*aspib
=(agr_sort_proba_info
*)b
;
740 mixa
=aspia
->param
->CC
*aspia
->proba
;
741 mixb
=aspib
->param
->CC
*aspib
->proba
;
742 if (mixa
<mixb
) return 1;
743 if (mixa
>mixb
) return -1;
747 void stb_choose_sub_agressor_list_depending_on_probability(chain_list
*headlist
, float probamin
)
749 agr_sort_proba_info tab
[STB_MAX_AGR
];
751 float curproba
, futureproba
;
762 param
=(rcxparam
*)headlist
->DATA
;
764 ttvsig
= stb_getttvsigrcxparam( param
);
768 node
= stb_getstbnode( &ttvsig
->NODE
[0]);
769 if (node
->CK
!=NULL
) ck
=1;
772 node
= stb_getstbnode( &ttvsig
->NODE
[1]);
773 if (node
->CK
!=NULL
) ck
=1;
777 else if ((pt
=getptype(ttvsig
->USER
, STB_TRANSITION_PROBABILITY
))!=NULL
)
778 tab
[i
].proba
=*(float *)&pt
->DATA
, i
++;
779 else if(V_BOOL_TAB
[__STB_CTK_NOINFO_ACTIF
].VALUE
)
783 if(V_BOOL_TAB
[__STB_CTK_NOINFO_ACTIF
].VALUE
)
785 headlist
=headlist
->NEXT
;
788 qsort(tab
, i
, sizeof(agr_sort_proba_info
), stb_compare_proba_capa
);
793 futureproba
=curproba
*tab
[j
].proba
;
794 if (futureproba
<=probamin
)
795 tab
[j
].param
->ACTIF
=0;
797 curproba
=futureproba
;
802 void stb_fillactifrcxparam( ttvfig
, victime
, headlist
, mutex
)
804 ttvevent_list
*victime
;
805 chain_list
*headlist
;
813 stb_ctkprint( 0, " Previous agressors :\n" );
814 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
816 param
= (rcxparam
*)(chain
->DATA
);
819 ttvsig
= stb_getttvsigrcxparam( param
);
823 type
= stb_getagressiontype( victime
->ROOT
, ttvsig
);
825 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
826 ( type
& STB_CTK_UP_WRST
) == STB_CTK_UP_WRST
) ||
827 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
828 ( type
& STB_CTK_DW_WRST
) == STB_CTK_DW_WRST
) )
829 param
->ACTIF
= param
->ACTIF
| RCX_AGRWORST
;
832 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
833 ( type
& STB_CTK_UP_MTX_WORST
) == STB_CTK_UP_MTX_WORST
) ||
834 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
835 ( type
& STB_CTK_DW_MTX_WORST
) == STB_CTK_DW_MTX_WORST
) )
836 param
->ACTIF
= ( param
->ACTIF
| RCX_MTX_WORST
) & ~RCX_AGRWORST
;
838 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
839 ( type
& STB_CTK_UP_BEST
) == STB_CTK_UP_BEST
) ||
840 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
841 ( type
& STB_CTK_DW_BEST
) == STB_CTK_DW_BEST
) )
842 param
->ACTIF
= param
->ACTIF
| RCX_AGRBEST
;
845 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
846 ( type
& STB_CTK_UP_MTX_BEST
) == STB_CTK_UP_MTX_BEST
) ||
847 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
848 ( type
& STB_CTK_DW_MTX_BEST
) == STB_CTK_DW_MTX_BEST
) )
849 param
->ACTIF
= ( param
->ACTIF
| RCX_MTX_BEST
) & ~RCX_AGRBEST
;
853 // On a pas d'infos sur l'agresseur
854 if( V_BOOL_TAB
[__STB_CTK_NOINFO_ACTIF
].VALUE
)
855 param
->ACTIF
= param
->ACTIF
| RCX_AGRWORST
| RCX_AGRBEST
;
858 stb_ctkprint( 0, " - %s.%s : %s %s\n",
860 ttvsig
? ttvsig
->NAME
: getsigname( param
->SIGNAL
),
861 ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
?
863 ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
?
869 stb_choose_sub_agressor_list_depending_on_probability(headlist
, V_FLOAT_TAB
[__STB_MIN_PROBABILITY
].VALUE
);
871 ttvfig
= NULL
; // unused parameter : avoid a warning at compilation
874 /*****************************************************************************
875 * fonction stb_fillinactifrcxparam() *
876 ******************************************************************************
877 * Remplis le champs ACTIF des structures rcxparam à partir des valeurs *
878 * calculées aux itérations précédentes. *
879 *****************************************************************************/
880 void stb_fillinactifrcxparam( ttvfig
, victime
, headlist
, mutex
)
882 ttvevent_list
*victime
;
883 chain_list
*headlist
;
891 stb_ctkprint( 0, " Previous agressors :\n" );
892 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
894 param
= (rcxparam
*)(chain
->DATA
);
896 ttvsig
= stb_getttvsigrcxparam( param
);
898 if( V_BOOL_TAB
[__STB_CTK_NOINFO_ACTIF
].VALUE
)
899 param
->ACTIF
= RCX_AGRWORST
| RCX_AGRBEST
;
903 param
->ACTIF
= RCX_AGRWORST
| RCX_AGRBEST
;
905 type
= stb_getagressiontype( victime
->ROOT
, ttvsig
);
907 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
908 ( type
& STB_CTK_UP_NOWRST
) == STB_CTK_UP_NOWRST
) ||
909 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
910 ( type
& STB_CTK_DW_NOWRST
) == STB_CTK_DW_NOWRST
) )
911 param
->ACTIF
= param
->ACTIF
& ~RCX_AGRWORST
;
914 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
915 ( type
& STB_CTK_UP_MTX_WORST
) == STB_CTK_UP_MTX_WORST
) ||
916 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
917 ( type
& STB_CTK_DW_MTX_WORST
) == STB_CTK_DW_MTX_WORST
) )
918 param
->ACTIF
= ( param
->ACTIF
| RCX_MTX_WORST
) & ~RCX_AGRWORST
;
920 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
921 ( type
& STB_CTK_UP_NOBEST
) == STB_CTK_UP_NOBEST
) ||
922 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
923 ( type
& STB_CTK_DW_NOBEST
) == STB_CTK_DW_NOBEST
) )
924 param
->ACTIF
= param
->ACTIF
& ~RCX_AGRBEST
;
927 if( ( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
928 ( type
& STB_CTK_UP_MTX_BEST
) == STB_CTK_UP_MTX_BEST
) ||
929 ( ( victime
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
930 ( type
& STB_CTK_DW_MTX_BEST
) == STB_CTK_DW_MTX_BEST
) )
931 param
->ACTIF
= ( param
->ACTIF
| RCX_MTX_BEST
) & ~RCX_AGRBEST
;
933 stb_ctkprint( 0, " - %s.%s : %s %s\n",
936 ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
?
938 ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
?
944 stb_choose_sub_agressor_list_depending_on_probability(headlist
, V_FLOAT_TAB
[__STB_MIN_PROBABILITY
].VALUE
);
946 ttvfig
= NULL
; // unused parameter : avoid a warning at compilation
949 /*****************************************************************************
950 * fonction stb_saveactifrcxparam() *
951 ******************************************************************************
952 Mémorise dans STB les nouvelles agressions détectées. Renvoie 1 si il y en
953 a eu au moins une nouvelle, et 0 sinon.
954 Les nouvelles agressions sont stockées de manière définitive, qu'elles soient
955 MUTEX ou non. L'information MUTEX est mémorisée, mais de manière non définitive.
956 *****************************************************************************/
957 int stb_saveactifcoupling( ttvevent_list
*victime
, ttvsig_list
*aggressor
, int rcxaggression
)
963 oldtype
= stb_getagressiontype( victime
->ROOT
, aggressor
);
967 if( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) {
969 if( ( rcxaggression
& RCX_AGRBEST
) == RCX_AGRBEST
)
970 newtype
= newtype
| STB_CTK_UP_BEST
;
972 if( ( rcxaggression
& RCX_MTX_BEST
) == RCX_MTX_BEST
)
973 newtype
= newtype
| STB_CTK_UP_BEST
| STB_CTK_UP_MTX_BEST
;
975 newtype
= newtype
& ~STB_CTK_UP_MTX_BEST
;
977 if( ( rcxaggression
& RCX_AGRWORST
) == RCX_AGRWORST
)
978 newtype
= newtype
| STB_CTK_UP_WRST
;
980 if( ( rcxaggression
& RCX_MTX_WORST
) == RCX_MTX_WORST
)
981 newtype
= newtype
| STB_CTK_UP_WRST
| STB_CTK_UP_MTX_WORST
;
983 newtype
= newtype
& ~STB_CTK_UP_MTX_WORST
;
988 if( ( rcxaggression
& RCX_AGRBEST
) == RCX_AGRBEST
)
989 newtype
= newtype
| STB_CTK_DW_BEST
;
991 if( ( rcxaggression
& RCX_MTX_BEST
) == RCX_MTX_BEST
)
992 newtype
= newtype
| STB_CTK_DW_BEST
| STB_CTK_DW_MTX_BEST
;
994 newtype
= newtype
& ~STB_CTK_DW_MTX_BEST
;
996 if( ( rcxaggression
& RCX_AGRWORST
) == RCX_AGRWORST
)
997 newtype
= newtype
| STB_CTK_DW_WRST
;
999 if( ( rcxaggression
& RCX_MTX_WORST
) == RCX_MTX_WORST
)
1000 newtype
= newtype
| STB_CTK_DW_WRST
| STB_CTK_DW_MTX_WORST
;
1002 newtype
= newtype
& ~STB_CTK_DW_MTX_WORST
;
1005 if( newtype
!= oldtype
) {
1006 stb_setagressiontype( victime
->ROOT
, aggressor
, newtype
);
1013 int stb_saveactifrcxparam( ttvfig
, victime
, headlist
)
1014 ttvfig_list
*ttvfig
;
1015 ttvevent_list
*victime
;
1016 chain_list
*headlist
;
1021 ttvsig_list
*ttvsig
;
1023 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
1025 param
= (rcxparam
*)(chain
->DATA
);
1027 if( param
->ACTIF
& RCX_QUIET
)
1030 ttvsig
= stb_getttvsigrcxparam( param
);
1034 if( stb_saveactifcoupling( victime
, ttvsig
, param
->ACTIF
) )
1038 ttvfig
= NULL
; // unused parameter : avoid a warning at compilation
1042 /*****************************************************************************
1043 * fonction stb_saveinactifrcxparam() *
1044 ******************************************************************************
1045 * Mémorise dans STB les nouvelles agressions détectées. Renvoie 1 si il y en *
1046 * a eu au moins une nouvelle, et 0 sinon. *
1047 *****************************************************************************/
1049 int stb_saveinactifcoupling( ttvevent_list
*victime
, ttvsig_list
*aggressor
, int rcxaggression
)
1055 oldtype
= stb_getagressiontype( victime
->ROOT
, aggressor
);
1059 if( ( victime
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) {
1061 if( ( rcxaggression
& RCX_AGRBEST
) != RCX_AGRBEST
)
1062 newtype
= newtype
| STB_CTK_UP_NOBEST
;
1064 if( ( rcxaggression
& RCX_MTX_BEST
) == RCX_MTX_BEST
)
1065 newtype
= ( newtype
& ~STB_CTK_UP_NOBEST
) | STB_CTK_UP_MTX_BEST
;
1067 newtype
= newtype
& ~STB_CTK_UP_MTX_BEST
;
1069 if( ( rcxaggression
& RCX_AGRWORST
) != RCX_AGRWORST
)
1070 newtype
= newtype
| STB_CTK_UP_NOWRST
;
1072 if( ( rcxaggression
& RCX_MTX_WORST
) == RCX_MTX_WORST
)
1073 newtype
= ( newtype
& ~STB_CTK_UP_NOWRST
) | STB_CTK_UP_MTX_WORST
;
1075 newtype
= newtype
& ~STB_CTK_UP_MTX_WORST
;
1079 if( ( rcxaggression
& RCX_AGRBEST
) != RCX_AGRBEST
)
1080 newtype
= newtype
| STB_CTK_DW_NOBEST
;
1082 if( ( rcxaggression
& RCX_MTX_BEST
) == RCX_MTX_BEST
)
1083 newtype
= ( newtype
& ~STB_CTK_DW_NOBEST
) | STB_CTK_DW_MTX_BEST
;
1085 newtype
= newtype
& ~STB_CTK_DW_MTX_BEST
;
1087 if( ( rcxaggression
& RCX_AGRWORST
) != RCX_AGRWORST
)
1088 newtype
= newtype
| STB_CTK_DW_NOWRST
;
1090 if( ( rcxaggression
& RCX_MTX_WORST
) == RCX_MTX_WORST
)
1091 newtype
= ( newtype
& ~STB_CTK_DW_NOWRST
) | STB_CTK_DW_MTX_WORST
;
1093 newtype
= newtype
& ~STB_CTK_DW_MTX_WORST
;
1096 if( newtype
!= oldtype
) {
1097 stb_setagressiontype( victime
->ROOT
, aggressor
, newtype
);
1104 int stb_saveinactifrcxparam( ttvfig
, victime
, headlist
)
1105 ttvfig_list
*ttvfig
;
1106 ttvevent_list
*victime
;
1107 chain_list
*headlist
;
1112 ttvsig_list
*ttvsig
;
1114 for( chain
= headlist
; chain
; chain
= chain
->NEXT
) {
1116 param
= (rcxparam
*)(chain
->DATA
);
1118 if( param
->ACTIF
& RCX_QUIET
)
1121 ttvsig
= stb_getttvsigrcxparam( param
);
1125 if( stb_saveinactifcoupling( victime
, ttvsig
, param
->ACTIF
) )
1129 ttvfig
= NULL
; // unused parameter : avoid a warning at compilation
1134 ------------------------------------------------------------------------------
1136 FONCTIONS PRINCIPALES
1138 ------------------------------------------------------------------------------
1141 /*****************************************************************************
1142 * fonction stb_marqsigfromgap() *
1143 ******************************************************************************
1144 * Marque tous les signaux d'un gap comme étant des agresseurs actifs. *
1145 *****************************************************************************/
1146 void stb_marqactiffromgap( evtvic
, gap
)
1147 ttvevent_list
*evtvic
;
1151 ttvevent_list
*event
;
1154 stb_ctkprint( 0, " - New aggressors :\n" );
1155 for( scan
= gap
->SIGNALS
; scan
; scan
= scan
->NEXT
) {
1157 event
= ((ttvevent_list
*)(scan
->DATA
));
1158 param
= stb_getrcxparamfromevent( event
);
1160 if( ( ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
&&
1161 ( evtvic
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) ||
1162 ( ( event
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
&&
1163 ( evtvic
->TYPE
& TTV_NODE_DOWN
) == TTV_NODE_DOWN
) ) {
1164 if( (param
->ACTIF
& RCX_AGRBEST
) != RCX_AGRBEST
)
1165 stb_ctkprint( 0, " %s %s : Best case agressor.\n",
1166 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1170 param
->ACTIF
= param
->ACTIF
| RCX_AGRBEST
;
1173 if( (param
->ACTIF
& RCX_AGRWORST
) != RCX_AGRWORST
)
1174 stb_ctkprint( 0, " %s %s : Worst case agressor.\n",
1175 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1179 param
->ACTIF
= param
->ACTIF
| RCX_AGRWORST
;
1184 /*****************************************************************************
1185 * fonction stb_createchainevent() *
1186 ******************************************************************************
1187 * Crée une liste d'event à partir d'une liste de rcxparam. *
1188 *****************************************************************************/
1189 chain_list
* stb_createchainevent( headagr
, type
)
1190 chain_list
*headagr
;
1193 chain_list
*eventlist
= NULL
;
1194 chain_list
*scanagr
;
1196 ttvevent_list
*event
;
1197 ttvsig_list
*ttvsig
;
1199 for( scanagr
= headagr
; scanagr
; scanagr
= scanagr
->NEXT
) {
1201 param
= (rcxparam
*)scanagr
->DATA
;
1202 ttvsig
= stb_getttvsigrcxparam( param
);
1206 if( type
== TTV_NODE_DOWN
)
1207 event
= ttvsig
->NODE
+0;
1209 event
= ttvsig
->NODE
+1;
1211 eventlist
= addchain( eventlist
, event
);
1213 stb_addrcxparamfromevent( event
, param
);
1216 return( eventlist
);
1219 /*****************************************************************************
1220 * fonction stb_getchainevent() *
1221 ******************************************************************************
1222 * Cette fonction a deux fonctionnalités : *
1223 * - Renvoie une liste chainée des event correspondant aux agresseurs ; *
1224 * - Ajoute un ptype STB_CTK_RCXPARAM dans les event ( utilisé par la *
1225 * fonction stb_marqsigfromgap() ). *
1226 * La liste et les ptypes doivent être effacés par un appel à la fonction *
1227 * stb_freechainevent(). *
1228 *****************************************************************************/
1229 chain_list
*stb_getchainevent( evtvic
, type
, headagr
)
1230 ttvevent_list
*evtvic
;
1232 chain_list
*headagr
;
1234 chain_list
*eventlist
;
1236 if( ( evtvic
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
) {
1237 if( type
== STB_CTK_WORST_AGR
)
1238 eventlist
= stb_createchainevent( headagr
, TTV_NODE_DOWN
);
1240 eventlist
= stb_createchainevent( headagr
, TTV_NODE_UP
);
1243 if( type
== STB_CTK_WORST_AGR
)
1244 eventlist
= stb_createchainevent( headagr
, TTV_NODE_UP
);
1246 eventlist
= stb_createchainevent( headagr
, TTV_NODE_DOWN
);
1249 return( eventlist
);
1252 /*****************************************************************************
1253 * fonction stb_freechainevent() *
1254 ******************************************************************************
1255 * Libère la chaine et les ptypes alloués par la fonction stb_getchainevent().*
1256 *****************************************************************************/
1257 void stb_freechainevent( eventlist
)
1258 chain_list
*eventlist
;
1261 ttvevent_list
*event
;
1263 for( chain
= eventlist
; chain
; chain
= chain
->NEXT
) {
1265 event
= ((ttvevent_list
*)(chain
->DATA
));
1266 stb_delrcxparamfromevent( event
);
1269 freechain( eventlist
);
1272 /*****************************************************************************
1273 * fonction stb_detectavtiveagressorworst() *
1274 ******************************************************************************
1275 * Positionne dans les structures rcxparam de la chain_list headagr les bits *
1276 * indiquant les agressions observables. Cette fonction renvoie 1 si au moins *
1277 * une nouvelle agression a été détectée, et 0 sinon. *
1278 * L'approche est pire cas : toutes les agressions sont initialement prises *
1279 * en compte et éliminées progressivement. *
1280 *****************************************************************************/
1281 void stb_detectactiveagressorworst( stbfig
, level
, type
, evtvic
, headagr
)
1282 stbfig_list
*stbfig
;
1285 ttvevent_list
*evtvic
;
1286 chain_list
*headagr
;
1288 chain_list
*eventlist
;
1289 chain_list
*realagrlist
;
1290 chain_list
*alwaysagrlist
;
1291 chain_list
*testagrlist
;
1295 ttvevent_list
*event
;
1298 if( ! headagr
) return;
1300 stbvic
= stb_getstbnode( evtvic
);
1303 fprintf( stderr
, "\n*** Error in STB/CTK : no stability on event.\n" );
1309 stb_ctkprint( 0, " Checking worst case agression.\n" );
1311 // Récupère la liste des agresseurs.
1312 eventlist
= stb_getchainevent( evtvic
, STB_CTK_WORST_AGR
, headagr
);
1313 stb_debug_stab( stbfig
, evtvic
, eventlist
);
1315 // Récupère la liste des agresseurs qui ne sont pas sur la même phase que
1317 alwaysagrlist
= stb_diftdomain( stbfig
, evtvic
, eventlist
);
1318 testagrlist
= subchain( eventlist
, alwaysagrlist
);
1320 stb_log_chain( stbfig
, alwaysagrlist
,
1321 " agressors located on another clock domain"
1323 // Récupère la liste des intervales qui recouvrent la victime.
1325 realagrlist
= stb_overlap( stbfig
,
1332 // Marque les event qu'il faut considérer comme agresseur
1333 for( chain
= realagrlist
; chain
; chain
= chain
->NEXT
) {
1334 event
= ((ttvevent_list
*)chain
->DATA
);
1335 event
->USER
= addptype( event
->USER
, STB_CTK_MARKREALACTIF
, NULL
);
1337 for( chain
= alwaysagrlist
; chain
; chain
= chain
->NEXT
) {
1338 event
= ((ttvevent_list
*)chain
->DATA
);
1339 event
->USER
= addptype( event
->USER
, STB_CTK_MARKREALACTIF
, NULL
);
1342 // Reporte l'information.
1343 for( chain
= eventlist
; chain
; chain
= chain
->NEXT
) {
1344 event
= ((ttvevent_list
*)chain
->DATA
);
1345 if( getptype( event
->USER
, STB_CTK_MARKREALACTIF
) ) {
1346 event
->USER
= delptype( event
->USER
, STB_CTK_MARKREALACTIF
);
1349 param
= stb_getrcxparamfromevent( event
);
1350 oldactif
= param
->ACTIF
;
1351 param
->ACTIF
= param
->ACTIF
& ~RCX_AGRWORST
;
1352 if( param
->ACTIF
!= oldactif
) {
1353 stb_ctkprint( 0, " Removing agressor %s %s\n",
1354 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1362 freechain( realagrlist
);
1363 freechain( alwaysagrlist
);
1364 freechain( testagrlist
);
1365 stb_ctk_handle_mutex( stbfig
->FIG
, evtvic
, eventlist
, RCX_AGRWORST
);
1366 stb_freechainevent( eventlist
);
1370 stb_ctkprint( 0, " Checking best case agression.\n" );
1372 eventlist
= stb_getchainevent( evtvic
, STB_CTK_BEST_AGR
, headagr
);
1373 stb_debug_stab( stbfig
, evtvic
, eventlist
);
1375 alwaysagrlist
= stb_diftdomain( stbfig
, evtvic
, eventlist
);
1376 testagrlist
= subchain( eventlist
, alwaysagrlist
);
1378 stb_log_chain( stbfig
, alwaysagrlist
,
1379 "agressors located on another clock domain"
1381 realagrlist
= stb_overlap( stbfig
,
1388 for( chain
= realagrlist
; chain
; chain
= chain
->NEXT
) {
1389 event
= ((ttvevent_list
*)chain
->DATA
);
1390 event
->USER
= addptype( event
->USER
, STB_CTK_MARKREALACTIF
, NULL
);
1392 for( chain
= testagrlist
; chain
; chain
= chain
->NEXT
) {
1393 event
= ((ttvevent_list
*)chain
->DATA
);
1394 event
->USER
= addptype( event
->USER
, STB_CTK_MARKREALACTIF
, NULL
);
1397 for( chain
= eventlist
; chain
; chain
= chain
->NEXT
) {
1398 event
= ((ttvevent_list
*)chain
->DATA
);
1399 if( getptype( event
->USER
, STB_CTK_MARKREALACTIF
) ) {
1400 event
->USER
= delptype( event
->USER
, STB_CTK_MARKREALACTIF
);
1403 param
= stb_getrcxparamfromevent( event
);
1404 oldactif
= param
->ACTIF
;
1405 param
->ACTIF
= param
->ACTIF
& ~RCX_AGRBEST
;
1406 if( param
->ACTIF
!= oldactif
) {
1407 stb_ctkprint( 0, " Removing agressor %s %s\n",
1408 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1416 freechain( realagrlist
);
1417 freechain( alwaysagrlist
);
1418 freechain( testagrlist
);
1420 stb_ctk_handle_mutex( stbfig
->FIG
, evtvic
, eventlist
, RCX_AGRBEST
);
1421 stb_freechainevent( eventlist
);
1423 level
= 0l; // unused parameter : avoid a warning at compilation
1424 type
= 0l; // unused parameter : avoid a warning at compilation
1427 /*****************************************************************************
1428 * fonction stb_detectavtiveagressorbest() *
1429 ******************************************************************************
1430 * Positionne dans les structures rcxparam de la chain_list headagr les bits *
1431 * indiquant les agressions observables. *
1432 * L'approche est meilleurs cas : Aucune agression n'est initialement prise *
1433 * en compte et détectées progressivement. *
1434 *****************************************************************************/
1435 void stb_detectactiveagressorbest( stbfig
, level
, type
, evtvic
, headagr
)
1436 stbfig_list
*stbfig
;
1439 ttvevent_list
*evtvic
;
1440 chain_list
*headagr
;
1442 chain_list
*eventlist
;
1444 chain_list
*realagrlist
;
1445 chain_list
*testagrlist
;
1446 chain_list
*alwaysagrlist
;
1447 ttvevent_list
*event
;
1453 "Detecting best case agressor for event %s.\n",
1457 if( ! headagr
) return;
1459 stbvic
= stb_getstbnode( evtvic
);
1462 fprintf( stderr
, "\n*** Error in STB/CTK : no stability on event.\n" );
1468 stb_ctkprint( 0, " Checking worst case agression.\n" );
1470 // Récupère la liste des event correspondant aux agresseurs.
1471 eventlist
= stb_getchainevent( evtvic
, STB_CTK_WORST_AGR
, headagr
);
1472 stb_debug_stab( stbfig
, evtvic
, eventlist
);
1474 alwaysagrlist
= stb_diftdomain( stbfig
, evtvic
, eventlist
);
1475 testagrlist
= subchain( eventlist
, alwaysagrlist
);
1477 stb_log_chain( stbfig
, alwaysagrlist
,
1478 "agressors located on another clock domain"
1480 if( ( stbfig
->CTKMODE
& STB_CTK_OBSERVABLE
) == STB_CTK_OBSERVABLE
)
1481 realagrlist
= stb_overlap( stbfig
,
1488 realagrlist
= stb_overlap( stbfig
,
1495 for( chain
= alwaysagrlist
; chain
; chain
= chain
->NEXT
) {
1496 event
= ((ttvevent_list
*)chain
->DATA
);
1497 param
= stb_getrcxparamfromevent( event
);
1498 oldactif
= param
->ACTIF
;
1499 param
->ACTIF
= param
->ACTIF
| RCX_AGRWORST
;
1500 if( param
->ACTIF
!= oldactif
) {
1501 stb_ctkprint( 0, " Setting agressor %s %s\n",
1502 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1508 for( chain
= realagrlist
; chain
; chain
= chain
->NEXT
) {
1509 event
= ((ttvevent_list
*)chain
->DATA
);
1510 param
= stb_getrcxparamfromevent( event
);
1511 oldactif
= param
->ACTIF
;
1512 param
->ACTIF
= param
->ACTIF
| RCX_AGRWORST
;
1513 if( param
->ACTIF
!= oldactif
) {
1514 stb_ctkprint( 0, " Setting agressor %s %s\n",
1515 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1522 freechain( realagrlist
);
1523 freechain( testagrlist
);
1524 freechain( alwaysagrlist
);
1526 /* remove aggression if they are in the same mutex. removed aggression are
1527 marked RCX_MTX_WORST */
1528 stb_ctk_handle_mutex( stbfig
->FIG
, evtvic
, eventlist
, RCX_AGRWORST
);
1529 stb_freechainevent( eventlist
);
1533 stb_ctkprint( 0, " Checking best case agression.\n" );
1535 eventlist
= stb_getchainevent( evtvic
, STB_CTK_BEST_AGR
, headagr
);
1536 stb_debug_stab( stbfig
, evtvic
, eventlist
);
1538 alwaysagrlist
= stb_diftdomain( stbfig
, evtvic
, eventlist
);
1539 testagrlist
= subchain( eventlist
, alwaysagrlist
);
1541 stb_log_chain( stbfig
, alwaysagrlist
,
1542 "agressors located on another clock domain"
1544 if( ( stbfig
->CTKMODE
& STB_CTK_OBSERVABLE
) == STB_CTK_OBSERVABLE
)
1545 realagrlist
= stb_overlap( stbfig
,
1552 realagrlist
= stb_overlap( stbfig
,
1559 for( chain
= alwaysagrlist
; chain
; chain
= chain
->NEXT
) {
1560 event
= ((ttvevent_list
*)chain
->DATA
);
1561 param
= stb_getrcxparamfromevent( event
);
1562 oldactif
= param
->ACTIF
;
1563 param
->ACTIF
= param
->ACTIF
| RCX_AGRBEST
;
1564 if( param
->ACTIF
!= oldactif
) {
1565 stb_ctkprint( 0, " Setting agressor %s %s\n",
1566 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1572 for( chain
= realagrlist
; chain
; chain
= chain
->NEXT
) {
1573 event
= ((ttvevent_list
*)chain
->DATA
);
1574 param
= stb_getrcxparamfromevent( event
);
1575 oldactif
= param
->ACTIF
;
1576 param
->ACTIF
= param
->ACTIF
| RCX_AGRBEST
;
1577 if( param
->ACTIF
!= oldactif
) {
1578 stb_ctkprint( 0, " Setting agressor %s %s\n",
1579 ( event
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" :
1586 freechain( realagrlist
);
1587 freechain( testagrlist
);
1588 freechain( alwaysagrlist
);
1590 /* remove aggression if they are in the same mutex. removed aggression are
1591 marked RCX_MTX_BEST */
1592 stb_ctk_handle_mutex( stbfig
->FIG
, evtvic
, eventlist
, RCX_AGRBEST
);
1593 stb_freechainevent( eventlist
);
1595 level
= 0l; // unused parameter : avoid a warning at compilation
1596 type
= 0l; // unused parameter : avoid a warning at compilation
1599 /*****************************************************************************
1600 * fonction stb_getminoldslope() *
1601 * fonction stb_getmaxoldslope() *
1602 * fonction stb_setminoldslope() *
1603 * fonction stb_setmaxoldslope() *
1604 ******************************************************************************
1605 * Récupère l'ancien le front mémorisé à l'itération précédante. *
1606 *****************************************************************************/
1607 long stb_getminoldslope( node
)
1608 ttvevent_list
*node
;
1611 ptl
= getptype( node
->USER
, STB_CTK_OLDMINSLOPE
);
1613 return (long) ptl
->DATA
;
1614 return TTV_NOSLOPE
;
1617 long stb_getmaxoldslope( node
)
1618 ttvevent_list
*node
;
1621 ptl
= getptype( node
->USER
, STB_CTK_OLDMAXSLOPE
);
1623 return (long) ptl
->DATA
;
1624 return TTV_NOSLOPE
;
1627 void stb_setminoldslope( node
, slope
)
1628 ttvevent_list
*node
;
1633 ptl
= getptype( node
->USER
, STB_CTK_OLDMINSLOPE
);
1635 node
->USER
= addptype( node
->USER
, STB_CTK_OLDMINSLOPE
, NULL
);
1639 ptl
->DATA
= (void*) slope
;
1642 void stb_setmaxoldslope( node
, slope
)
1643 ttvevent_list
*node
;
1648 ptl
= getptype( node
->USER
, STB_CTK_OLDMAXSLOPE
);
1650 node
->USER
= addptype( node
->USER
, STB_CTK_OLDMAXSLOPE
, NULL
);
1654 ptl
->DATA
= (void*) slope
;
1657 void stb_cleanoldslope( node
)
1658 ttvevent_list
*node
;
1661 ptl
= getptype( node
->USER
, STB_CTK_OLDMAXSLOPE
);
1663 node
->USER
= delptype( node
->USER
, STB_CTK_OLDMAXSLOPE
);
1664 ptl
= getptype( node
->USER
, STB_CTK_OLDMINSLOPE
);
1666 node
->USER
= delptype( node
->USER
, STB_CTK_OLDMINSLOPE
);
1669 /*****************************************************************************
1670 * fonction stb_hasslopechanged() *
1671 ******************************************************************************
1672 * Indique si le front sur le noeud a changé depuis la dernière itération. *
1673 * Renvoie STB_NO, STB_YES ou STB_UNK. *
1674 *****************************************************************************/
1676 int stb_hasslopechanged( node
, ttvfig
, level
, type
)
1677 ttvevent_list
*node
;
1678 ttvfig_list
*ttvfig
;
1682 ttvdelay_list
*delay
;
1687 delay
= ttv_getnodedelay( node
);
1689 foldmin
= stb_getminoldslope( node
);
1690 foldmax
= stb_getmaxoldslope( node
);
1692 if( foldmax
== TTV_NOSLOPE
|| foldmin
== TTV_NOSLOPE
)
1695 delta
= foldmin
- delay
->FMIN
;
1696 if( delta
< 0 ) delta
= -delta
;
1697 if( delta
>= STB_CTK_MINSLOPECHANGE
)
1700 delta
= foldmax
- delay
->FMAX
;
1701 if( delta
< 0 ) delta
= -delta
;
1702 if( delta
>= STB_CTK_MINSLOPECHANGE
)
1708 ttvfig
=NULL
; // unused parameter : avoid a warning at compilation
1709 level
=0l; // unused parameter : avoid a warning at compilation
1710 type
=0l; // unused parameter : avoid a warning at compilation
1714 /*****************************************************************************
1715 * fonction stb_saveslope() *
1716 ******************************************************************************
1717 * Sauvegarde tous les fronts de la figure. *
1718 *****************************************************************************/
1720 void stb_saveslope( node
, ttvfig
, level
, type
)
1721 ttvevent_list
*node
;
1722 ttvfig_list
*ttvfig
;
1727 ttvdelay_list
*delay
;
1731 if((type
& TTV_FIND_LINE
) == TTV_FIND_LINE
)
1733 ttv_expfigsig (ttvfig
,node
->ROOT
, level
, ttvfig
->INFO
->LEVEL
,
1734 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
, TTV_FILE_DTX
);
1735 if((ptype
= getptype(node
->USER
,TTV_NODE_DUALLINE
)) != NULL
)
1736 scan
= (chain_list
*)ptype
->DATA
;
1742 ttv_expfigsig (ttvfig
,node
->ROOT
, level
, ttvfig
->INFO
->LEVEL
,
1743 TTV_STS_CL_PJT
|TTV_STS_DUAL_PJT
, TTV_FILE_TTX
);
1744 if((ptype
= getptype(node
->USER
,TTV_NODE_DUALPATH
)) != NULL
)
1745 scan
= (chain_list
*)ptype
->DATA
;
1750 delay
= ttv_getnodedelay( node
);
1752 stb_setminoldslope( node
, delay
->FMIN
);
1753 stb_setmaxoldslope( node
, delay
->FMAX
);
1756 for( ; scan
; scan
= scan
->NEXT
) {
1757 line
= (ttvline_list
*)scan
->DATA
;
1758 if( ( ( line
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
) ||
1759 !ttv_islinelevel( ttvfig
, line
, level
) )
1763 delay
= ttv_getnodedelay( node
);
1765 stb_setminoldslope( node
, delay
->FMIN
);
1766 stb_setmaxoldslope( node
, delay
->FMAX
);
1771 /*****************************************************************************
1772 * fonction stb_needeval() *
1773 ******************************************************************************
1774 * Indique si le node doit être réévalué. Renvoie STB_YES, STB_NO ou STB_UNK. *
1775 *****************************************************************************/
1777 int stb_needeval( ttvfig
, level
, node
, type
, mode
, headagr
)
1778 ttvfig_list
*ttvfig
;
1780 ttvevent_list
*node
;
1783 chain_list
*headagr
;
1785 ttvline_list
*line
;
1786 ttvevent_list
*nodefrom
;
1792 ttvsig_list
*signal
;
1795 if((type
& TTV_FIND_LINE
) == TTV_FIND_LINE
)
1797 ttv_expfigsig (ttvfig
,node
->ROOT
, level
, ttvfig
->INFO
->LEVEL
,
1798 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
, TTV_FILE_DTX
);
1799 line
= node
->INLINE
;
1803 ttv_expfigsig (ttvfig
,node
->ROOT
, level
, ttvfig
->INFO
->LEVEL
,
1804 TTV_STS_CL_PJT
|TTV_STS_DUAL_PJT
, TTV_FILE_TTX
);
1805 line
= node
->INPATH
;
1808 for(; line
!= NULL
; line
= line
->NEXT
)
1810 if( ((line
->TYPE
& TTV_LINE_RC
) == TTV_LINE_RC
) ||
1811 !ttv_islinelevel( ttvfig
, line
, level
) )
1814 nodefrom
= line
->NODE
;
1816 switch ( stb_hasslopechanged( nodefrom
, ttvfig
, level
, type
) ) {
1828 for( scan
= headagr
; scan
; scan
= scan
->NEXT
) {
1830 param
= (rcxparam
*)scan
->DATA
;
1831 signal
= stb_getttvsigrcxparam( param
);
1835 if((type
& TTV_FIND_LINE
) == TTV_FIND_LINE
)
1837 ttv_expfigsig (ttvfig
,signal
,level
,ttvfig
->INFO
->LEVEL
,
1838 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
, TTV_FILE_DTX
);
1842 ttv_expfigsig (ttvfig
,signal
,level
,ttvfig
->INFO
->LEVEL
,
1843 TTV_STS_CL_PJT
|TTV_STS_DUAL_PJT
, TTV_FILE_TTX
);
1846 for( i
=0; i
<=1 ; i
++ ) {
1848 nodefrom
= &(signal
->NODE
[i
]);
1850 switch ( stb_hasslopechanged( nodefrom
, ttvfig
, level
, type
) ) {
1861 if((type
& TTV_FIND_LINE
) == TTV_FIND_LINE
)
1863 if((ptype
= getptype(node
->USER
,TTV_NODE_DUALLINE
)) != NULL
)
1864 chain
= (chain_list
*)ptype
->DATA
;
1870 if((ptype
= getptype(node
->USER
,TTV_NODE_DUALPATH
)) != NULL
)
1871 chain
= (chain_list
*)ptype
->DATA
;
1876 for( ; chain
; chain
= chain
->NEXT
) {
1878 line
= (ttvline_list
*)chain
->DATA
;
1880 if( ((line
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
) ||
1881 !ttv_islinelevel( ttvfig
, line
, level
) )
1884 nodefrom
= line
->ROOT
;
1885 switch ( stb_hasslopechanged( nodefrom
, ttvfig
, level
, type
) ) {
1899 mode
=0; // unused parameter : avoid a warning at compilation
1901 if( thereisunk
== 1 )
1906 void stb_remove_input( ttvfig_list
*ttvfig
, ttvsig_list
*ttvsig
, long level
, chain_list
*headagr
)
1908 chain_list
*toclean
;
1912 toclean
= stb_mark_input( ttvfig
, ttvsig
, level
);
1914 for( chain
= headagr
; chain
; chain
= chain
->NEXT
) {
1916 param
= (rcxparam
*)(chain
->DATA
);
1918 ttvsig
= stb_getttvsigrcxparam( param
);
1921 if( stb_is_mark_input( ttvsig
) ) {
1922 param
->ACTIF
= RCX_QUIET
;
1927 stb_clean_mark_input(toclean
);
1930 /*****************************************************************************
1931 * fonction stb_calcctkdelaynode() *
1932 *****************************************************************************/
1933 int stb_calcctkdelaynode(stbfig
,node
,level
,type
,mode
,deltamax
, iteration
, debugmode
)
1934 stbfig_list
*stbfig
;
1935 ttvevent_list
*node
;
1946 chain_list
*chainfig
;
1947 chain_list
*headagr
;
1952 ttvsig_list
*ttvsig
;
1955 stb_ctkprint( 0, "Computing delays for node %s %s (netname=%s)\n",
1956 (node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" : "DOWN",
1963 if( getptype( node
->ROOT
->USER
, STB_MARK_DEBUG
) )
1970 sigvic
= ttv_getlosigfromevent( stbfig
->FIG
,
1986 headagr
= rcx_getagrlist( figvic
, sigvic
, insname
, chainfig
);
1987 freechain( chainfig
);
1991 stb_fillttvsigrcxparam( stbfig
->FIG
, level
, type
, headagr
);
1993 if( ( stbfig
->CTKMODE
& STB_CTK_WORST
) == STB_CTK_WORST
) {
1994 stb_fillinactifrcxparam( stbfig
->FIG
, node
, headagr
, 'N' );
1996 stb_detectactiveagressorworst( stbfig
, level
, type
, node
, headagr
);
1997 stb_remove_input( stbfig
->FIG
, node
->ROOT
, level
, headagr
);
1998 res
= stb_saveinactifrcxparam( stbfig
->FIG
, node
, headagr
);
2001 stb_fillactifrcxparam( stbfig
->FIG
, node
, headagr
, 'N' );
2003 stb_detectactiveagressorbest( stbfig
, level
, type
, node
, headagr
);
2004 stb_remove_input( stbfig
->FIG
, node
->ROOT
, level
, headagr
);
2005 res
= stb_saveactifrcxparam( stbfig
->FIG
, node
, headagr
);
2009 stb_ctkprint( 0, "-> No agressor.\n" );
2010 stb_debug_stab( stbfig
, node
, NULL
);
2015 stb_debug_stab( stbfig
, node
, NULL
);
2018 stb_saveslope( node
, stbfig
->FIG
, level
, type
);
2019 if( enablenode
== 1 && (
2021 stb_needeval( stbfig
->FIG
, level
, node
, type
, mode
, headagr
) != STB_NO
||
2022 iteration
<= 1 // pour avoir au moins une fois la propagation des fronts
2029 "*** Aggressor for computing %s %s\n",
2030 (node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP" : "DW",
2034 for( chain
= headagr
; chain
; chain
= chain
->NEXT
) {
2035 param
= (rcxparam
*)chain
->DATA
;
2036 ttvsig
= stb_getttvsigrcxparam( param
);
2037 if( ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
)
2038 stb_ctkprint( 0, "B" );
2040 stb_ctkprint( 0, " " );
2041 if( ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
)
2042 stb_ctkprint( 0, "W " );
2044 stb_ctkprint( 0, " " );
2047 ttvsig
? ttvsig
->NAME
: "-no ttvsig-",
2048 rcx_getsigname( param
->SIGNAL
)
2053 *deltamax
= ttv_calcnodedelayslope(stbfig
->FIG
,level
,node
,type
,mode
) ;
2054 STBCTK_NBDELAYCALC
++;
2057 ttv_updatenodedelayslope( stbfig
->FIG
,level
,node
,type
,mode
);
2061 stb_delttvsigrcxparam( headagr
);
2062 rcx_freeagrlist( figvic
, sigvic
, headagr
);
2066 stb_set_min_slope(stbfig
->FIG
, node
, level
, 2);
2067 stb_release_fast_nodepair(node
);
2070 if( rcn_islock_signal( figvic, sigvic ) == YES )
2076 /*****************************************************************************
2077 * fonction stb_calcctkdelay() *
2078 *****************************************************************************/
2079 int stb_calcctkdelay(stbfig
,deltamax
, iteration
)
2080 stbfig_list
*stbfig
;
2084 ttvevent_list
*ptevent
;
2092 static int debugmode
=0;
2094 STBCTK_NBDELAYCALC
=0;
2096 if( deltamax
) *deltamax
= 0;
2098 if (stbfig
->GRAPH
== STB_RED_GRAPH
)
2100 type
= TTV_FIND_PATH
;
2102 fprintf( stderr
, "\n*** Error in STB/CTK: Crosstalk analysis requires detailed graph analysis.\n" );
2105 else if (stbfig
->GRAPH
== STB_DET_GRAPH
)
2107 type
= TTV_FIND_LINE
;
2110 type
|= TTV_FIND_MIN
| TTV_FIND_MAX
;
2112 mode
= TTV_MODE_DELAY
;
2114 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
2115 level
= stbfig
->FIG
->INFO
->LEVEL
;
2119 if( iteration
== 0 ) {
2120 debugmode
= stb_init_debug_node( stbfig
, level
, type
);
2123 for(chain
= stbfig
->NODE
, pb_max
=0; chain
; chain
= chain
->NEXT
, pb_max
++ );
2125 CTK_PROGRESSBAR( iteration
, pb_max
, 0, NULL
);
2126 for(chain
= stbfig
->NODE
, pb_cur
=1; chain
; chain
= chain
->NEXT
, pb_cur
++ ) {
2127 CTK_PROGRESSBAR( iteration
, pb_max
, pb_cur
, NULL
);
2129 ptevent
= (ttvevent_list
*)chain
->DATA
;
2131 if( !ptevent
->INLINE
||
2132 ( ptevent
->INLINE
&&
2133 (ptevent
->INLINE
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
)
2136 if(stb_calcctkdelaynode(stbfig
,ptevent
,level
,type
,mode
, &delta
, iteration
, debugmode
)
2140 if( delta
> *deltamax
)
2145 printf( "ptevent=%p NBPTYPE %ld\n", ptevent
, NBPTYPE
);
2151 void stb_ctk_env(void)
2159 STB_CTK_MINSLOPECHANGE
= 2 * TTV_UNIT
;
2162 env
= getenv("CTK_LOGFILE");
2164 CTK_LOGFILE
= mbkfopen( env
, NULL
, WRITE_TEXT
);
2166 env
= getenv("CTK_LOGLEVEL");
2168 CTK_LOGLEVEL
= atoi(env
);
2171 CTK_REPORT_DELTA_DELAY_MIN
=V_INT_TAB
[__CTK_REPORT_DELTA_DELAY_MIN
].VALUE
;
2173 CTK_REPORT_DELTA_SLOPE_MIN
=V_INT_TAB
[__CTK_REPORT_DELTA_SLOPE_MIN
].VALUE
;
2175 CTK_REPORT_NOISE_MIN
=V_INT_TAB
[__CTK_REPORT_NOISE_MIN
].VALUE
;
2177 if(V_FLOAT_TAB
[__CTK_REPORT_CTK_MIN
].VALUE
<0.0 || V_FLOAT_TAB
[__CTK_REPORT_CTK_MIN
].VALUE
>100.0 )
2179 "Bad value for CTK_REPORT_CTK_MIN. Must be a floating number.\n"
2181 CTK_REPORT_CTK_MIN
=V_FLOAT_TAB
[__CTK_REPORT_CTK_MIN
].VALUE
;
2183 if(V_FLOAT_TAB
[__STB_NOISE_DEFAULT_RESI
].VALUE
<0.0 )
2185 "Bad value for STB_NOISE_DEFAULT_RESI. Must be a floating number.\n"
2187 STB_NOISE_DEFAULT_RESI
=V_FLOAT_TAB
[__STB_NOISE_DEFAULT_RESI
].VALUE
;
2189 if( V_BOOL_TAB
[__STB_CTK_FASTMODE
].VALUE
) {
2197 STB_CTK_MARGIN
=V_INT_TAB
[__STB_CTK_MARGIN
].VALUE
*TTV_UNIT
;
2199 STB_CTK_MINSLOPECHANGE
=V_INT_TAB
[__STB_CTK_MINSLOPECHANGE
].VALUE
*TTV_UNIT
;
2201 STB_CTK_MAXLASTITER
=V_INT_TAB
[__STB_CTK_MAXLASTITER
].VALUE
;
2203 stb_ctk_set_min_score( V_INT_TAB
[__STB_CTK_MIN_NOISE
].VALUE
, -1, -1, -1 );
2205 stb_ctk_set_min_score( -1, V_INT_TAB
[__STB_CTK_MIN_CTK
].VALUE
, -1, -1 );
2207 stb_ctk_set_min_score( -1, -1, V_INT_TAB
[__STB_CTK_MIN_INTERVAL
].VALUE
, -1 );
2209 stb_ctk_set_min_score( -1, -1, -1, V_INT_TAB
[__STB_CTK_MIN_ACTIVITY
].VALUE
);
2211 stb_ctk_set_coef_score( V_INT_TAB
[__STB_CTK_COEF_NOISE
].VALUE
, -1, -1, -1 );
2213 stb_ctk_set_coef_score( -1, V_INT_TAB
[__STB_CTK_COEF_CTK
].VALUE
, -1, -1 );
2215 stb_ctk_set_coef_score( -1, -1, V_INT_TAB
[__STB_CTK_COEF_INTERVAL
].VALUE
, -1 );
2217 stb_ctk_set_coef_score( -1, -1, -1, V_INT_TAB
[__STB_CTK_COEF_ACTIVITY
].VALUE
);
2221 /*****************************************************************************
2222 * fonction stb_ctk_clean() *
2223 *****************************************************************************/
2225 void stb_ctk_clean( stbfig
)
2226 stbfig_list
*stbfig
;
2229 ttvevent_list
*ptevent
;
2231 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
2233 ptevent
= (ttvevent_list
*)chain
->DATA
;
2234 stb_cleanagressiontype( ptevent
->ROOT
);
2237 CtkMutexFree(stbfig
->FIG
);
2240 /*****************************************************************************
2241 * fonction stb_ctk_clean_oldslope() *
2242 *****************************************************************************/
2244 void stb_ctk_clean_oldslope( stbfig
)
2245 stbfig_list
*stbfig
;
2248 ttvevent_list
*ptevent
;
2250 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
2252 ptevent
= (ttvevent_list
*)chain
->DATA
;
2253 stb_cleanoldslope( ptevent
);
2257 /******************************************************************************\
2258 Construit les tables de hash dans la hiérarchie TTV.
2259 \******************************************************************************/
2260 void stb_built_ttv_htab( ttvfig_list
*rootfig
)
2262 ttv_builthtabfig( rootfig
, TTV_STS_L
| TTV_STS_S
);
2265 /******************************************************************************\
2266 Remet à jour les infos de stb, notament les holorloges avec les nouveaux délais.
2267 \******************************************************************************/
2268 void stb_resync( stbfig_list
*stbfig
)
2271 ttvevent_list
*ttvnode
;
2275 for( chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
) {
2276 ttvnode
= (ttvevent_list
*)chain
->DATA
;
2277 stbnode
= stb_getstbnode( ttvnode
);
2278 for( ptstbck
= stbnode
->CK
; ptstbck
; ptstbck
= ptstbck
->NEXT
) {
2279 if( ptstbck
&& ptstbck
->TYPE
!= STB_TYPE_CLOCK
) {
2280 ptstbck
->SUPMAX
= STB_NO_TIME
;
2281 ptstbck
->SUPMIN
= STB_NO_TIME
;
2282 ptstbck
->SDNMAX
= STB_NO_TIME
;
2283 ptstbck
->SDNMIN
= STB_NO_TIME
;
2286 ttvnode
->USER
=testanddelptype (ttvnode
->USER
, STB_NODE_CLOCK
);
2288 stb_initclock( stbfig
,1);
2289 /* for( chain = stbfig->NODE ; chain ; chain = chain->NEXT ) {
2290 ttvnode = (ttvevent_list*)chain->DATA;
2291 stb_initckpath( stbfig, ttvnode );
2294 if(stbfig
->GRAPH
== STB_DET_GRAPH
)
2295 stb_propagate_signal(stbfig
, stbfig
->CLOCK
);
2299 /******************************************************************************\
2301 Détermine les agressions et calcule les délais élémentaires en présence de
2303 Après avoir appellé cette fonction, les agressions calculées sont accessibles
2304 par la fonction stb_getagressiontype().
2305 On libère cette information avec la fonction stb_ctk_clean().
2306 \******************************************************************************/
2310 stbfig_list
*stbfig
;
2315 long deltafrontmax
=0;
2317 int iterwithoutagr
=0, level
;
2322 oldsilent
= STB_SILENT
;
2325 #ifdef AVERTEC_LICENSE
2326 if(avt_givetoken("HITAS_LICENSE_SERVER","ctk")!=AVT_VALID_TOKEN
)
2330 rcx_crosstalkactive( RCX_MILLER
);
2331 rcx_crosstalk_analysis( YES
);
2334 STB_COM_STBFIG
=stbfig
;
2335 STB_COM
=stb_communication
;
2337 stb_built_ttv_htab( stbfig
->FIG
);
2339 stb_ctk_clean(stbfig
) ;
2341 CtkMutexInit( stbfig
->FIG
);
2343 if( stbfig
->CTKMODE
& STB_CTK_REPORT
)
2344 report
= stb_info_open( stbfig
);
2348 CTK_PROGRESSBAR( 0, 1, 0, "Computing initial state." );
2350 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
2351 level
= stbfig
->FIG
->INFO
->LEVEL
;
2354 stb_setupall_slopes(stbfig
, level
);
2356 stb_calcctkdelay( stbfig
, NULL
, 0 ) ;
2357 stb_resync( stbfig
);
2358 stb_cleanup_fast_nodepair(stbfig
);
2360 stb_ctk_drive_iteration_report(stbfig
, 0);
2362 CTK_PROGRESSBAR( 0, 1, 0, "Crosstalk analysis." );
2364 trcflushdelaycache();
2369 stb_ctkprint( 0, "\nItération %d\n\n", i
);
2371 stb_ctk_drive_iteration_report_save_last_iteration_info(stbfig
);
2373 // stb_clean_relax_correction_info(stbfig);
2375 stb_relaxation(stbfig
) ;
2377 changedelay
= stb_calcctkdelay(stbfig
, &deltafrontmax
, i
) ;
2378 stb_resync( stbfig
);
2379 stb_cleanup_fast_nodepair(stbfig
);
2381 sprintf( buf
, " -> %d signals evaluated", STBCTK_NBDELAYCALC
);
2382 CTK_PRINTINFO( buf
);
2384 if( ( stbfig
->CTKMODE
& STB_CTK_WORST
) == STB_CTK_WORST
)
2385 sprintf( buf
, " -> %d signals with one or more agression removed",
2389 sprintf( buf
, " -> %d signals with one or more new agression",
2392 CTK_PRINTINFO( buf
);
2394 sprintf( buf
, " -> Maximum slope variation : %.1fps",
2395 deltafrontmax
/TTV_UNIT
2397 CTK_PRINTINFO( buf
);
2399 stb_ctk_drive_iteration_report(stbfig
, i
);
2401 // Condition de sortie de la boucle
2408 if( deltafrontmax
<= STB_CTK_MINSLOPECHANGE
||
2409 iterwithoutagr
>= STB_CTK_MAXLASTITER
)
2415 #ifdef AVERTEC_LICENSE
2416 if(avt_givetoken("HITAS_LICENSE_SERVER","ctk")!=AVT_VALID_TOKEN
)
2420 trcflushdelaycache();
2422 while( doitagain
&& i
< V_INT_TAB
[__STB_CTK_MAX_ITER
].VALUE
);
2424 stb_ctk_drive_agression( stbfig
);
2426 stb_cleanup_slopes(stbfig
);
2429 stat
= stb_ctk_fill_stat( stbfig
, 1 );
2430 stb_ctk_drive_stat( report
, stbfig
, stat
);
2431 stb_info_close( report
);
2434 //stb_display_mem( stbfig );
2435 CTK_PROGRESSBAR( 0, 1, 0, "Driving crosstalk file." );
2437 if( (stbfig
->CTKMODE
& STB_CTX_REPORT
) == STB_CTX_REPORT
)
2438 ttv_ctxdrive( stbfig
->FIG
);
2440 STB_SILENT
= oldsilent
;
2442 stb_ctk_clean_oldslope( stbfig
);
2444 ttv_freehtabfig( stbfig
->FIG
, TTV_STS_L
| TTV_STS_S
);
2446 STB_COM_STBFIG
=NULL
;
2449 rcx_crosstalkactive( RCX_NOCROSSTALK
);
2450 rcx_crosstalk_analysis( NO
);
2452 ctk_calc_constraint( stbfig
);
2454 stb_clean_ttvfig( stbfig
);
2459 stbfile
* stb_info_open( stbfig_list
*stbfig
)
2461 static stbfile file
;
2463 file
.FD
= mbkfopen( stbfig
->FIG
->INFO
->FIGNAME
, "ctk", "w" );
2464 if( file
.FD
== NULL
) {
2465 stb_ctk_error( 5, "Can't open file %s.ctk for writting.\n",
2466 stbfig
->FIG
->INFO
->FIGNAME
);
2470 "# Crosstalk information for circuit %s.\n\n",
2471 stbfig
->FIG
->INFO
->FIGNAME
2474 file
.STBFIG
= stbfig
;
2476 stb_info( &file
, "Score configuration : Coefficient Miniumum\n" );
2477 stb_info( &file
, " Noise %2d/10 %2d/10\n",
2478 stb_ctk_get_coef_noise(), stb_ctk_get_min_noise() );
2479 stb_info( &file
, " Interval %2d/10 %2d/10\n",
2480 stb_ctk_get_coef_interval(), stb_ctk_get_min_interval() );
2481 stb_info( &file
, " Crosstalk %2d/10 %2d/10\n",
2482 stb_ctk_get_coef_ctk(), stb_ctk_get_min_ctk() );
2483 stb_info( &file
, " Activity %2d/10 %2d/10\n",
2484 stb_ctk_get_coef_activity(), stb_ctk_get_min_activity() );
2488 void stb_info( stbfile
*file
, ... )
2495 va_start( index
, file
);
2496 fmt
= va_arg( index
, char* );
2498 vfprintf( file
->FD
, fmt
, index
);
2501 void stb_info_close( stbfile
*file
)
2508 void stb_drive_line( stbfile
*report
,
2509 ttvfig_list
*ttvfig
,
2523 dmin
= line
->VALMIN
/TTV_UNIT
;
2524 dmax
= line
->VALMAX
/TTV_UNIT
;
2525 fmin
= line
->FMIN
/TTV_UNIT
;
2526 fmax
= line
->FMAX
/TTV_UNIT
;
2527 dmincc
= ttv_getdelaymin( line
)/TTV_UNIT
;
2528 fmincc
= ttv_getslopemin( line
)/TTV_UNIT
;
2529 dmaxcc
= ttv_getdelaymax( line
)/TTV_UNIT
;
2530 fmaxcc
= ttv_getslopemax( line
)/TTV_UNIT
;
2532 if( abs(dmin
-dmincc
) >= CTK_REPORT_DELTA_DELAY_MIN
&&
2533 ttv_getdelaymin( line
) != TTV_NOTIME
) {
2537 stb_display_ttvevent( ttvfig
, line
->NODE
),
2538 stb_display_ttvevent( ttvfig
, line
->ROOT
)
2542 stb_info( report
, " delay min : %.1f -> %.1f\n", dmin
, dmincc
);
2544 if( abs(dmax
-dmaxcc
) >= CTK_REPORT_DELTA_DELAY_MIN
&&
2545 ttv_getdelaymax( line
) != TTV_NOTIME
) {
2549 stb_display_ttvevent( ttvfig
, line
->NODE
),
2550 stb_display_ttvevent( ttvfig
, line
->ROOT
)
2554 stb_info( report
, " delay max : %.1f -> %.1f\n", dmax
, dmaxcc
);
2556 if( abs(fmin
-fmincc
) >= CTK_REPORT_DELTA_SLOPE_MIN
&&
2557 ttv_getslopemin( line
) != TTV_NOSLOPE
){
2561 stb_display_ttvevent( ttvfig
, line
->NODE
),
2562 stb_display_ttvevent( ttvfig
, line
->ROOT
)
2566 stb_info( report
, " slope min : %.1f -> %.1f\n", fmin
, fmincc
);
2568 if( abs(fmax
-fmaxcc
) >= CTK_REPORT_DELTA_SLOPE_MIN
&&
2569 ttv_getslopemax( line
) != TTV_NOSLOPE
){
2573 stb_display_ttvevent( ttvfig
, line
->NODE
),
2574 stb_display_ttvevent( ttvfig
, line
->ROOT
)
2578 stb_info( report
, " slope max : %.1f -> %.1f\n", fmax
, fmaxcc
);
2581 ttvfig
= NULL
; //unused parameter
2584 char* stb_display_ttvevent( ttvfig_list
*ttvfig
, ttvevent_list
*node
)
2587 static char tab
[2][1024];
2592 ttv_getsigname( ttvfig
, ttvname
, node
->ROOT
);
2593 ttv_getnetname( ttvfig
, netname
, node
->ROOT
);
2594 if( strcmp( netname
, ttvname
) == 0 ) {
2595 sprintf( tab
[i
], "%s %s",
2596 ( node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP": "DW",
2601 sprintf( tab
[i
], "%s %s (%s)",
2602 ( node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "UP": "DW",
2611 char* stb_display_ttvevent_noise( ttvfig_list
*ttvfig
, ttvevent_list
*node
)
2614 static char tab
[2][1024];
2619 ttv_getsigname( ttvfig
, ttvname
, node
->ROOT
);
2620 ttv_getnetname( ttvfig
, netname
, node
->ROOT
);
2621 if( strcmp( netname
, ttvname
) == 0 ) {
2622 sprintf( tab
[i
], "%s %s",
2623 ( node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "LOW ": "HIGH",
2628 sprintf( tab
[i
], "%s %s (%s)",
2629 ( node
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
? "LOW ": "HIGH",
2638 char* stb_display_ttvsig( ttvfig_list
*fig
, ttvsig_list
*ttvsig
)
2641 static char tab
[2][1024];
2646 ttv_getsigname( fig
, ttvname
, ttvsig
);
2647 ttv_getnetname( fig
, netname
, ttvsig
);
2648 if( strcmp( netname
, ttvname
) == 0 ) {
2649 sprintf( tab
[i
], "%s", ttvname
);
2652 sprintf( tab
[i
], "%s (%s)", ttvname
, netname
);
2658 stb_ctk_detail
* stb_ctk_get_detail( stbfig_list
*stbfig
,
2659 ttvevent_list
*ptevent
2664 chain_list
*chainfig
;
2667 stb_ctk_detail
*detail
;
2668 stb_ctk_detail_agr_list
*detail_list
;
2671 chain_list
*scanagr
;
2672 chain_list
*headagr
;
2679 ttvsig_list
*ttvagr
;
2683 if (stbfig
->GRAPH
== STB_RED_GRAPH
) {
2685 type
= TTV_FIND_PATH
;
2687 fprintf( stderr
, "\n*** Error in STB/CTK: Crosstalk analysis requires detailed graph analysis.\n" );
2690 else if (stbfig
->GRAPH
== STB_DET_GRAPH
) {
2692 type
= TTV_FIND_LINE
;
2695 type
|= TTV_FIND_MIN
| TTV_FIND_MAX
;
2697 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
2698 level
= stbfig
->FIG
->INFO
->LEVEL
;
2702 if( ptevent
->INLINE
&&
2703 (ptevent
->INLINE
->TYPE
& TTV_LINE_RC
) == TTV_LINE_RC
2707 sigvic
= ttv_getlosigfromevent( stbfig
->FIG
,
2713 if( !sigvic
) return NULL
;
2715 detail
= (stb_ctk_detail
*)mbkalloc( sizeof( stb_ctk_detail
) );
2716 detail
->NODE
= ptevent
;
2717 detail
->LOSIG
= sigvic
;
2720 detail
->NOISE_OVR
= 0.0;
2721 detail
->NOISE_UND
= 0.0;
2722 detail
->NOISE_MAX_OVR
= 0.0;
2723 detail
->NOISE_MAX_UND
= 0.0;
2724 detail
->AGRLIST
= NULL
;
2725 detail
->GAP_UP
.FILLED
= 0 ;
2726 detail
->GAP_DW
.FILLED
= 0 ;
2728 headagr
= rcx_getagrlist( figvic
, sigvic
, insname
, chainfig
);
2729 stb_fillttvsigrcxparam( stbfig
->FIG
, level
, type
, headagr
);
2730 if( ( stbfig
->CTKMODE
& STB_CTK_WORST
) == STB_CTK_WORST
)
2731 stb_fillinactifrcxparam( stbfig
->FIG
, ptevent
, headagr
, 'Y' );
2733 stb_fillactifrcxparam( stbfig
->FIG
, ptevent
, headagr
, 'Y' );
2735 tabagr
= rcx_buildtabagr( figvic
,
2737 sizeof( rcxmodagr
),
2744 for( n
= 0 ; n
< nbagr
; n
++ ) {
2745 cc
= cc
+tabagr
[n
].CLOCALE
+ tabagr
[n
].CGLOBALE
;
2746 dcm
= dcm
+ tabagr
[n
].CGLOBALE
;
2749 detail
->CM
= cm
- dcm
;
2752 for( scanagr
= headagr
; scanagr
; scanagr
= scanagr
->NEXT
) {
2753 param
= (rcxparam
*)scanagr
->DATA
;
2755 detail_list
= ( stb_ctk_detail_agr_list
* )
2756 mbkalloc( sizeof( stb_ctk_detail_agr_list
) );
2758 detail_list
->NEXT
= detail
->AGRLIST
;
2759 detail
->AGRLIST
= detail_list
;
2761 detail_list
->NOISE_RISE_PEAK
= 0;
2762 detail_list
->NOISE_FALL_PEAK
= 0;
2763 detail_list
->NOISE_RISE_EXCLUDED
= 0;
2764 detail_list
->NOISE_FALL_EXCLUDED
= 0;
2766 ttvagr
= stb_getttvsigrcxparam(param
);
2767 detail_list
->TTVAGR
= ttvagr
;
2769 ttvagr
->USER
= addptype( ttvagr
->USER
, STB_CTK_DETAIL
, detail_list
);
2771 detail_list
->NOISE_RISE_PEAK
= 1;
2772 detail_list
->NOISE_FALL_PEAK
= 1;
2775 detail_list
->NETNAME
= (char*)mbkalloc( sizeof( char ) * 1024 );
2776 sprintf( detail_list
->NETNAME
,
2779 rcx_getsigname( param
->SIGNAL
)
2782 if( ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
)
2783 detail_list
->ACT_BEST
= 1;
2785 detail_list
->ACT_BEST
= 0;
2787 if( ( param
->ACTIF
& RCX_MTX_BEST
) == RCX_MTX_BEST
)
2788 detail_list
->ACT_MUTEX_BEST
= 1 ;
2790 detail_list
->ACT_MUTEX_BEST
= 0 ;
2792 if( ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
)
2793 detail_list
->ACT_WORST
= 1;
2795 detail_list
->ACT_WORST
= 0;
2797 if( ( param
->ACTIF
& RCX_MTX_WORST
) == RCX_MTX_WORST
)
2798 detail_list
->ACT_MUTEX_WORST
= 1 ;
2800 detail_list
->ACT_MUTEX_WORST
= 0 ;
2802 agridx
= rcx_gettabagrindex( param
->SIGNAL
);
2803 detail_list
->CC
= tabagr
[agridx
].CLOCALE
+ tabagr
[agridx
].CGLOBALE
;
2806 rcx_freetabagr( tabagr
, sizeof( rcxmodagr
), nbagr
);
2808 detail
->AGRLIST
= (stb_ctk_detail_agr_list
*)
2809 reverse( (chain_list
*)detail
->AGRLIST
);
2811 stb_ctk_noise_node( stbfig
,
2818 &detail
->NOISE_MAX_OVR
,
2821 &detail
->NOISE_MAX_UND
,
2825 vth
= stb_ctk_signal_threshold( stbfig
, detail
->NODE
);
2827 vth
= stb_ctk_signal_threshold_from_input( stbfig
, detail
->NODE
) ;
2828 detail
->NOISE_VTH
= vth
;
2830 stb_delttvsigrcxparam( headagr
);
2831 rcx_freeagrlist( figvic
, sigvic
, headagr
);
2832 freechain( chainfig
); chainfig
= NULL
;
2837 stb_ctk_gap
* stb_fill_gap( stbfig_list
*stbfig
, stb_ctk_detail
*detail
, char transition
)
2840 stb_ctk_detail_agr_list
*agr
;
2841 chain_list
*eventlist
;
2844 if( transition
== TTV_NODE_UP
) {
2846 gap
= & detail
->GAP_UP
;
2850 gap
= & detail
->GAP_DW
;
2857 gap
->OTHERDOMAIN
= NULL
;
2858 gap
->CONDACTIF
= NULL
;
2859 gap
->GAPACTIF
= NULL
;
2860 gap
->NOINFO
= NULL
;
2862 for( agr
= detail
->AGRLIST
; agr
; agr
= agr
->NEXT
) {
2865 eventlist
= addchain( eventlist
, &( agr
->TTVAGR
->NODE
[node
] ) );
2868 gap
->NOINFO
= addchain( gap
->NOINFO
, agr
);
2872 gap
->OTHERDOMAIN
= stb_diftdomain( stbfig
, detail
->NODE
, eventlist
);
2873 gap
->CONDACTIF
= subchain( eventlist
, gap
->OTHERDOMAIN
);
2875 gap
->GAPACTIF
= stb_overlapdev( stbfig
, detail
->NODE
, gap
->CONDACTIF
, 0l );
2876 freechain( eventlist
);
2883 void stb_ctk_free_detail( stbfig_list
*stbfig
, stb_ctk_detail
*detail
)
2885 stb_ctk_detail_agr_list
*list
;
2886 stb_ctk_detail_agr_list
*next
;
2887 ttvsig_list
*ttvsig
;
2890 for( list
= detail
->AGRLIST
; list
; list
= next
) {
2892 ttvsig
= list
->TTVAGR
;
2894 ptl
= getptype( ttvsig
->USER
, STB_CTK_DETAIL
);
2896 fprintf( stderr
, "fatal error in stb_ctk_free_detail().\n" );
2899 ttvsig
->USER
= delptype( ttvsig
->USER
, STB_CTK_DETAIL
);
2903 mbkfree( list
->NETNAME
) ;
2907 if( detail
->GAP_UP
.FILLED
) {
2908 freechain( detail
->GAP_UP
.OTHERDOMAIN
);
2909 freechain( detail
->GAP_UP
.CONDACTIF
);
2910 freechain( detail
->GAP_UP
.NOINFO
);
2911 stb_freegaplist( detail
->GAP_UP
.GAPACTIF
);
2913 if( detail
->GAP_DW
.FILLED
) {
2914 freechain( detail
->GAP_DW
.OTHERDOMAIN
);
2915 freechain( detail
->GAP_DW
.CONDACTIF
);
2916 freechain( detail
->GAP_DW
.NOINFO
);
2917 stb_freegaplist( detail
->GAP_DW
.GAPACTIF
);
2924 stb_ctk_detail_agr_list
* stb_ctk_get_node_detail( ttvsig_list
*ttvsig
)
2927 ptl
= getptype( ttvsig
->USER
, STB_CTK_DETAIL
);
2929 return (stb_ctk_detail_agr_list
*)ptl
->DATA
;
2933 void stb_ctk_drive_stat( stbfile
*report
, stbfig_list
*stbfig
, stb_ctk_stat
*stat
)
2936 ttvevent_list
*event
;
2937 stb_ctk_detail
*ctkdetail
;
2939 CTK_PROGRESSBAR( 0, 1, 0, "Driving crosstalk report file" );
2941 stb_info( report
, "BeginDelay\n" );
2942 for( i
=0 ; i
<stat
->NBDDISPLAY
; i
++ ) {
2943 CTK_PROGRESSBAR( 0, stat
->NBDDISPLAY
, i
, NULL
);
2944 stb_drive_line( report
, stbfig
->FIG
, stat
->TABD
[i
].LINE
);
2946 stb_info( report
, "EndDelay\n\n" );
2947 CTK_PROGRESSBAR( 0, stat
->NBDDISPLAY
, stat
->NBDDISPLAY
, NULL
);
2949 CTK_PROGRESSBAR( 0, 1, 0, "Driving detailled aggression in report file" );
2951 stb_drive_crosstalk_start( report
);
2952 for( i
=0 ; i
<stat
->NBDISPLAY
; i
++ ) {
2953 CTK_PROGRESSBAR( 0, stat
->NBDISPLAY
, i
, NULL
);
2954 event
= stat
->TAB
[i
].NODE
;
2955 ctkdetail
= stb_ctk_get_detail( stbfig
, event
);
2956 stb_drive_crosstalk_detail( report
, ctkdetail
, &(stat
->TAB
[i
]) );
2957 stb_ctk_free_detail( stbfig
, ctkdetail
);
2959 stb_drive_crosstalk_end( report
);
2960 CTK_PROGRESSBAR( 0, stat
->NBDISPLAY
, stat
->NBDISPLAY
, NULL
);
2962 stb_ctk_noise_report( report
, stat
);
2965 int stb_drive_crosstalk_start( stbfile
*report
)
2967 stb_info( report
, "# Crosstalk information :\n" );
2968 stb_info( report
, "# -----------------------\n\n" );
2969 stb_info( report
, "BeginCrosstalk\n" );
2973 int sort_drive_detail( stb_ctk_detail_agr_list
**ag1
, stb_ctk_detail_agr_list
**ag2
)
2975 if( (*ag1
)->CC
> (*ag2
)->CC
) return 1 ;
2976 if( (*ag1
)->CC
< (*ag2
)->CC
) return -1 ;
2977 return strcmp( (*ag1
)->NETNAME
, (*ag2
)->NETNAME
);
2980 int stb_drive_crosstalk_detail( stbfile
*report
,
2981 stb_ctk_detail
*detail
,
2982 stb_ctk_tab_stat
*stat
2986 stb_ctk_detail_agr_list
*list
;
2988 stb_ctk_detail_agr_list
**sort_tab
;
2990 x
= 10 * ( stb_ctk_get_coef_noise() +
2991 stb_ctk_get_coef_activity() +
2992 stb_ctk_get_coef_ctk() +
2993 stb_ctk_get_coef_interval() );
2995 pct
= detail
->CM
+detail
->CC
> 0.0 ? detail
->CC
/(detail
->CM
+detail
->CC
):0.0;
2998 if( pct
> CTK_REPORT_CTK_MIN
) {
3000 stb_info( report
, " Node : %s\n",
3001 stb_display_ttvevent( report
->STBFIG
->FIG
, detail
->NODE
)
3003 stb_info( report
, " Ground capacitance : %fpF\n", detail
->CM
);
3005 stb_info( report
, " Score : Total %3d/%d\n",
3006 stb_ctk_get_score_total( stat
), x
);
3007 stb_info( report
, " Noise %3d/10\n",
3008 stb_ctk_get_score_noise( stat
) );
3009 stb_info( report
, " Interval %3d/10\n",
3010 stb_ctk_get_score_interval( stat
) );
3011 stb_info( report
, " Ctk %3d/10\n",
3012 stb_ctk_get_score_ctk( stat
) );
3013 stb_info( report
, " Activity %3d/10\n",
3014 stb_ctk_get_score_activity( stat
) );
3016 for( list
= detail
->AGRLIST
, x
=0 ; list
; list
= list
->NEXT
, x
++ ) ;
3017 sort_tab
= (stb_ctk_detail_agr_list
**)mbkalloc( sizeof( stb_ctk_detail_agr_list
* ) * x
);
3019 for( list
= detail
->AGRLIST
, x
=0 ; list
; list
= list
->NEXT
, x
++ )
3020 sort_tab
[x
] = list
;
3022 qsort( sort_tab
, x
, sizeof( stb_ctk_detail_agr_list
* ), (int(*)(const void*,const void*))sort_drive_detail
);
3024 stb_info( report
, " Agressor :\n" );
3026 for( y
=0 ; y
<x
; y
++) {
3031 stb_info( report
, " %-65s ",
3032 stb_display_ttvsig(report
->STBFIG
->FIG
, list
->TTVAGR
) );
3034 stb_info( report
, " * %-65s ", list
->NETNAME
);
3036 if( list
->ACT_BEST
)
3037 stb_info( report
, "B " );
3039 if( list
->ACT_MUTEX_BEST
)
3040 stb_info( report
, "b " );
3042 stb_info( report
, " " );
3045 if( list
->ACT_WORST
)
3046 stb_info( report
, "W " );
3048 if( list
->ACT_MUTEX_WORST
)
3049 stb_info( report
, "w " );
3051 stb_info( report
, " " );
3054 if( list
->NOISE_RISE_PEAK
)
3055 stb_info( report
, "R " );
3057 if( list
->NOISE_RISE_EXCLUDED
)
3058 stb_info( report
, "r " );
3060 stb_info( report
, " " );
3063 if( list
->NOISE_FALL_PEAK
)
3064 stb_info( report
, "F " );
3066 if( list
->NOISE_FALL_EXCLUDED
)
3067 stb_info( report
, "f " );
3069 stb_info( report
, " " );
3072 stb_info( report
, " Cc=%fpF\n", list
->CC
);
3075 mbkfree( sort_tab
);
3076 stb_info( report
, " %-65s ----------\n", "" );
3077 stb_info( report
, " %-65s %f (%05.1f%%)\n",
3086 int stb_drive_crosstalk_end( stbfile
*report
)
3088 stb_info( report
, "EndCrosstalk\n\n" );
3092 void ctk_setprint( void (*print
)( char* ) )
3094 CTK_PRINTINFO
= print
;
3097 void ctk_setprogressbar( void (*callfn
)( int, int, int, char* ) )
3099 CTK_PROGRESSBAR
= callfn
;
3102 void ctk_display_event( stbfig_list
*stbfig
, ttvevent_list
*refevent
)
3104 stbpair_list
*refpair
;
3107 refpair
= stb_getpairnode( stbfig
, refevent
, STB_CTK_MARGIN
);
3108 for( pair
= refpair
; pair
; pair
= pair
->NEXT
)
3109 stb_ctkprint( 1, "[%.1f;%.1f] ", pair
->D
/TTV_UNIT
, pair
->U
/TTV_UNIT
);
3110 stb_freestbpair (refpair
);
3111 stb_ctkprint( 1, "\n" );
3114 void ctk_calc_constraint( stbfig_list
*stbfig
)
3120 ttvevent_list
*event
;
3122 mode
= TTV_MODE_DELAY
;
3124 level
= stbfig
->FIG
->INFO
->LEVEL
;
3125 type
= TTV_FIND_LINE
;
3127 for( chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
) {
3128 event
= (ttvevent_list
*)chain
->DATA
;
3129 ttv_calcnodeconstraint( stbfig
->FIG
, level
, event
, type
, mode
);
3133 void stb_ctk_set_stat( stbfig_list
*stbfig
, stb_ctk_stat
*stat
)
3138 ptl
= getptype( stbfig
->USER
, STB_CTK_STAT
);
3140 old
= (stb_ctk_stat
*)ptl
->DATA
;
3141 stb_ctk_free_stat( old
);
3144 stbfig
->USER
= addptype( stbfig
->USER
, STB_CTK_STAT
, NULL
);
3145 ptl
= stbfig
->USER
;
3151 stb_ctk_stat
* stb_ctk_get_stat( stbfig_list
*stbfig
)
3154 stb_ctk_stat
*stat
;
3156 ptl
= getptype( stbfig
->USER
, STB_CTK_STAT
);
3158 stat
= (stb_ctk_stat
*)ptl
->DATA
;
3167 void stb_ctk_clean_stat( stbfig_list
*stbfig
)
3170 stb_ctk_stat
*stat
;
3172 ptl
= getptype( stbfig
->USER
, STB_CTK_STAT
);
3174 stat
= (stb_ctk_stat
*)ptl
->DATA
;
3175 stb_ctk_free_stat( stat
);
3176 stbfig
->USER
= delptype( stbfig
->USER
, STB_CTK_STAT
);
3180 /******************************************************************************\
3182 Fill a stb_ctk_stat structure.
3183 Possibly, call user's fonction fn_xxxx for each detail corresponding to an event.
3184 \******************************************************************************/
3186 stb_ctk_stat
* stb_ctk_fill_stat( stbfig_list
*stbfig
, int fast
)
3188 stb_ctk_stat
*stat
;
3191 stb_ctk_clean_stat( stbfig
);
3193 stat
= mbkalloc( sizeof( stb_ctk_stat
) );
3196 stat
->NBDISPLAY
= 0 ;
3199 stat
->NBDDISPLAY
= 0 ;
3201 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
3202 level
= stbfig
->FIG
->INFO
->LEVEL
;
3206 if (fast
) stb_setupall_slopes(stbfig
, level
);
3209 stb_ctk_fill_stat_tab( stat
, stbfig
);
3210 stb_ctk_fill_stat_line( stat
, stbfig
);
3212 //CTK_PROGRESSBAR( 0, 1, 0, "Sorting results" );
3214 stb_ctk_sort_stat( stat
, STB_CTK_SORT_SCORE_TOTAL
);
3215 stb_ctk_sort_delay( stat
, STB_CTK_SORT_ABS_DELAY
, 0.0 );
3217 stb_ctk_set_stat( stbfig
, stat
);
3219 if (fast
) stb_cleanup_slopes(stbfig
);
3224 int stb_ctk_sort_delay_cmp( sortdelaycmp
*delay1
, sortdelaycmp
*delay2
)
3227 int trs1n
, trs1r
, trs2n
, trs2r
, val1
, val2
;
3229 if( delay1
->VALUE
> delay2
->VALUE
) return -1 ;
3230 if( delay1
->VALUE
< delay2
->VALUE
) return 1 ;
3232 r
= strcmp( delay1
->LINE
->NODE
->ROOT
->NAME
, delay2
->LINE
->NODE
->ROOT
->NAME
);
3236 r
= strcmp( delay1
->LINE
->ROOT
->ROOT
->NAME
, delay2
->LINE
->ROOT
->ROOT
->NAME
);
3240 if( ( delay1
->LINE
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
3245 if( ( delay1
->LINE
->ROOT
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
3250 if( ( delay2
->LINE
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
3255 if( ( delay2
->LINE
->ROOT
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
3260 val1
= trs1n
*2+trs1r
;
3261 val2
= trs2n
*2+trs2r
;
3270 inline void filltabdelayvalue( sortdelaycmp
*elem
, char criterion
)
3283 switch( criterion
) {
3285 case STB_CTK_SORT_ABS_DELAY
:
3287 vnommax
= elem
->LINE
->VALMAX
;
3288 vctkmax
= ttv_getdelaymax( elem
->LINE
) ;
3289 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
)
3290 deltamax
= vctkmax
- vnommax
;
3292 vnommin
= elem
->LINE
->VALMIN
;
3293 vctkmin
= ttv_getdelaymin( elem
->LINE
) ;
3294 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
)
3295 deltamin
= vnommin
- vctkmin
;
3297 if( deltamax
> deltamin
)
3298 elem
->VALUE
= deltamax
;
3300 elem
->VALUE
= deltamin
;
3304 case STB_CTK_SORT_ABS_MAX_DELAY
:
3306 vnommax
= elem
->LINE
->VALMAX
;
3307 vctkmax
= ttv_getdelaymax( elem
->LINE
) ;
3308 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
)
3309 deltamax
= vctkmax
- vnommax
;
3311 elem
->VALUE
= deltamax
;
3315 case STB_CTK_SORT_ABS_MIN_DELAY
:
3317 vnommin
= elem
->LINE
->VALMIN
;
3318 vctkmin
= ttv_getdelaymin( elem
->LINE
) ;
3319 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
)
3320 deltamin
= vnommin
- vctkmin
;
3322 elem
->VALUE
= deltamin
;
3326 case STB_CTK_SORT_ABS_SLOPE
:
3328 vnommax
= elem
->LINE
->FMAX
;
3329 vctkmax
= ttv_getslopemax( elem
->LINE
) ;
3330 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
)
3331 deltamax
= vctkmax
- vnommax
;
3333 vnommin
= elem
->LINE
->FMIN
;
3334 vctkmin
= ttv_getslopemin( elem
->LINE
) ;
3335 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
)
3336 deltamin
= vnommin
- vctkmin
;
3338 if( deltamax
> deltamin
)
3339 elem
->VALUE
= deltamax
;
3341 elem
->VALUE
= deltamin
;
3345 case STB_CTK_SORT_ABS_MAX_SLOPE
:
3347 vnommax
= elem
->LINE
->FMAX
;
3348 vctkmax
= ttv_getslopemax( elem
->LINE
) ;
3349 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
)
3350 deltamax
= vctkmax
- vnommax
;
3352 elem
->VALUE
= deltamax
;
3356 case STB_CTK_SORT_ABS_MIN_SLOPE
:
3358 vnommin
= elem
->LINE
->FMIN
;
3359 vctkmin
= ttv_getslopemin( elem
->LINE
) ;
3360 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
)
3361 deltamin
= vnommin
- vctkmin
;
3363 elem
->VALUE
= deltamin
;
3367 case STB_CTK_SORT_REL_DELAY
:
3369 vnommax
= elem
->LINE
->VALMAX
;
3370 vctkmax
= ttv_getdelaymax( elem
->LINE
) ;
3371 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
&& vnommax
>= 1.0 )
3372 deltamax
= (vctkmax
- vnommax
)/vnommax
;
3374 vnommin
= elem
->LINE
->VALMIN
;
3375 vctkmin
= ttv_getdelaymin( elem
->LINE
) ;
3376 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
&& vnommin
>= 1.0 )
3377 deltamin
= (vnommin
- vctkmin
)/vnommin
;
3379 if( deltamax
> deltamin
)
3380 elem
->VALUE
= deltamax
;
3382 elem
->VALUE
= deltamin
;
3386 case STB_CTK_SORT_REL_MAX_DELAY
:
3388 vnommax
= elem
->LINE
->VALMAX
;
3389 vctkmax
= ttv_getdelaymax( elem
->LINE
) ;
3390 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
&& vnommax
>= 1.0 )
3391 deltamax
= (vctkmax
- vnommax
)/vnommax
;
3393 elem
->VALUE
= deltamax
;
3397 case STB_CTK_SORT_REL_MIN_DELAY
:
3399 vnommin
= elem
->LINE
->VALMIN
;
3400 vctkmin
= ttv_getdelaymin( elem
->LINE
) ;
3401 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
&& vnommin
>= 1.0 )
3402 deltamin
= (vnommin
- vctkmin
)/vnommin
;
3404 elem
->VALUE
= deltamin
;
3408 case STB_CTK_SORT_REL_SLOPE
:
3410 vnommax
= elem
->LINE
->FMAX
;
3411 vctkmax
= ttv_getslopemax( elem
->LINE
) ;
3412 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
&& vnommax
>= 1.0 )
3413 deltamax
= (vctkmax
- vnommax
)/vnommax
;
3415 vnommin
= elem
->LINE
->FMIN
;
3416 vctkmin
= ttv_getslopemin( elem
->LINE
) ;
3417 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
&& vnommin
>= 1.0 )
3418 deltamin
= (vnommin
- vctkmin
)/vnommin
;
3420 if( deltamax
> deltamin
)
3421 elem
->VALUE
= deltamax
;
3423 elem
->VALUE
= deltamin
;
3427 case STB_CTK_SORT_REL_MAX_SLOPE
:
3429 vnommax
= elem
->LINE
->FMAX
;
3430 vctkmax
= ttv_getslopemax( elem
->LINE
) ;
3431 if( vnommax
!= TTV_NOTIME
&& vctkmax
!= TTV_NOTIME
&& vnommax
>= 1.0 )
3432 deltamax
= (vctkmax
- vnommax
)/vnommax
;
3434 elem
->VALUE
= deltamax
;
3438 case STB_CTK_SORT_REL_MIN_SLOPE
:
3440 vnommin
= elem
->LINE
->FMIN
;
3441 vctkmin
= ttv_getslopemin( elem
->LINE
) ;
3442 if( vnommin
!= TTV_NOTIME
&& vctkmin
!= TTV_NOTIME
&& vnommin
>= 1.0 )
3443 deltamin
= (vnommin
- vctkmin
)/vnommin
;
3445 elem
->VALUE
= deltamin
;
3452 void stb_ctk_sort_delay( stb_ctk_stat
*stat
, char criterion
, float delay
)
3454 sortdelaycmp
*tabdelay
;
3457 tabdelay
= (sortdelaycmp
*)mbkalloc( sizeof(sortdelaycmp
) * stat
->NBDELEM
);
3459 for( i
=0 ; i
<stat
->NBDELEM
; i
++ ) {
3460 tabdelay
[i
].LINE
= stat
->TABD
[i
].LINE
;
3461 filltabdelayvalue( &(tabdelay
[i
]), criterion
);
3464 qsort( tabdelay
, stat
->NBDELEM
, sizeof( sortdelaycmp
), ( int(*)(const void*, const void*) )stb_ctk_sort_delay_cmp
);
3466 for( i
=0 ; i
<stat
->NBDELEM
; i
++ ) {
3467 stat
->TABD
[i
].LINE
= tabdelay
[i
].LINE
;
3470 mbkfree( tabdelay
);
3473 void stb_ctk_fill_stat_line( stb_ctk_stat
*stat
,
3479 ttvevent_list
*ptevent
;
3480 ttvline_list
*line
;
3483 chain_list
*scline
;
3485 //CTK_PROGRESSBAR( 0, 1, 0, "Reporting delay variations" );
3487 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
3488 level
= stbfig
->FIG
->INFO
->LEVEL
;
3494 /* comptage du nombre de line */
3495 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
3497 ptevent
= (ttvevent_list
*)chain
->DATA
;
3499 ttv_expfigsig( stbfig
->FIG
,
3502 stbfig
->FIG
->INFO
->LEVEL
,
3503 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
,
3507 line
= ptevent
->INLINE
;
3508 ptype
= getptype( ptevent
->USER
, TTV_NODE_DUALLINE
);
3510 scline
= (chain_list
*)ptype
->DATA
;
3514 for(; line
!= NULL
; line
= line
->NEXT
) {
3515 if( ( ( line
->TYPE
& TTV_LINE_RC
) == TTV_LINE_RC
) ||
3516 ( ( line
->TYPE
& TTV_LINE_CONT
) == TTV_LINE_CONT
) ||
3517 !ttv_islinelevel( stbfig
->FIG
, line
, level
) )
3522 for(; scline
!= NULL
; scline
= scline
->NEXT
) {
3523 line
= (ttvline_list
*)scline
->DATA
;
3525 if( ((line
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
) ||
3526 !ttv_islinelevel( stbfig
->FIG
, line
, level
) )
3532 stat
->TABD
= (stb_ctk_tab_delay
*)mbkalloc( nbline
* sizeof( stb_ctk_tab_delay
) );
3533 stat
->NBDELEM
= nbline
;
3534 stat
->NBDDISPLAY
= nbline
;
3536 /* remplissage des infos */
3538 for(chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
)
3540 ptevent
= (ttvevent_list
*)chain
->DATA
;
3542 ttv_expfigsig( stbfig
->FIG
,
3545 stbfig
->FIG
->INFO
->LEVEL
,
3546 TTV_STS_CLS_FED
|TTV_STS_DUAL_FED
,
3550 line
= ptevent
->INLINE
;
3551 ptype
= getptype( ptevent
->USER
, TTV_NODE_DUALLINE
);
3553 scline
= (chain_list
*)ptype
->DATA
;
3557 for(; line
!= NULL
; line
= line
->NEXT
) {
3558 if( ( ( line
->TYPE
& TTV_LINE_RC
) == TTV_LINE_RC
) ||
3559 ( ( line
->TYPE
& TTV_LINE_CONT
) == TTV_LINE_CONT
) ||
3560 !ttv_islinelevel( stbfig
->FIG
, line
, level
) )
3562 stb_ctk_fill_stat_line_one( &stat
->TABD
[nbline
], line
);
3566 for(; scline
!= NULL
; scline
= scline
->NEXT
) {
3567 line
= (ttvline_list
*)scline
->DATA
;
3569 if( ((line
->TYPE
& TTV_LINE_RC
) != TTV_LINE_RC
) ||
3570 !ttv_islinelevel( stbfig
->FIG
, line
, level
) )
3572 stb_ctk_fill_stat_line_one( &stat
->TABD
[nbline
], line
);
3578 char calc_pct( long vi
, long vf
)
3580 float fvi
, fvf
, pct
;
3585 if( vf
> 0 ) ret
= 100 ;
3586 if( vf
< 0 ) ret
= -100 ;
3591 pct
= ( fvf
- fvi
) / fvi
* 100.0 ;
3592 if( pct
> 100.0 ) pct
= 100.0 ;
3593 if( pct
< -100.0 ) pct
= -100.0 ;
3600 void stb_ctk_fill_stat_line_one( stb_ctk_tab_delay
*delay
, ttvline_list
*line
)
3602 delay
->LINE
= line
;
3605 void stb_ctk_fill_stat_tab( stb_ctk_stat
*stat
,
3609 stb_ctk_detail
*ctkdetail
;
3611 ttvevent_list
*event
;
3616 CTK_PROGRESSBAR( 0, 1, 0, "Computing noises and scores" );
3619 /* build and initialize data strucure */
3620 for( chain
= stbfig
->NODE
, nbevent
= 0 ; chain
; chain
= chain
->NEXT
, nbevent
++ ) ;
3625 CTK_PROGRESSBAR( 0, nbevent
, 0, NULL
);
3627 stat
->TAB
= mbkalloc( sizeof( stb_ctk_tab_stat
) * nbevent
);
3628 for( n
= 0 ; n
< nbevent
; n
++ ) {
3629 stat
->TAB
[n
].NODE
= NULL
;
3630 stat
->TAB
[n
].SCORE_NOISE
= 0 ;
3631 stat
->TAB
[n
].SCORE_INTERVAL
= 0 ;
3632 stat
->TAB
[n
].SCORE_CTK
= 0 ;
3633 stat
->TAB
[n
].SCORE_ACTIVITY
= 0 ;
3634 stat
->TAB
[n
].RISE_PEAK_REAL
= 0 ;
3635 stat
->TAB
[n
].FALL_PEAK_REAL
= 0 ;
3636 stat
->TAB
[n
].RISE_PEAK_MAX
= 0 ;
3637 stat
->TAB
[n
].FALL_PEAK_MAX
= 0 ;
3638 stat
->TAB
[n
].VTH
= 0.0 ;
3639 stat
->TAB
[n
].NOISE_MODEL
= "" ;
3640 stat
->TAB
[n
].CNET_GND
= 0.0 ;
3641 stat
->TAB
[n
].CNET_CC
= 0.0 ;
3642 stat
->TAB
[n
].CGATE
= 0.0 ;
3645 /* filling report crosstalk information */
3649 for( chain
= stbfig
->NODE
; chain
; chain
= chain
->NEXT
) {
3651 event
= (ttvevent_list
*)chain
->DATA
;
3653 CTK_PROGRESSBAR( 0, nbevent
, nm
, NULL
);
3656 ctkdetail
= stb_ctk_get_detail( stbfig
, event
);
3659 stb_ctk_stat_event( stbfig
, ctkdetail
, &(stat
->TAB
[n
]) );
3660 stb_ctk_calc_score( stbfig
, ctkdetail
, &(stat
->TAB
[n
]) );
3661 stb_ctk_free_detail( stbfig
, ctkdetail
);
3667 stat
->NBDISPLAY
= n
;
3671 void stb_ctk_free_stat( stb_ctk_stat
*stat
)
3673 mbkfree( stat
->TABD
);
3674 mbkfree( stat
->TAB
);
3678 void stb_ctk_stat_event( stbfig_list
*stbfig
,
3679 stb_ctk_detail
*ctkdetail
,
3680 stb_ctk_tab_stat
*stat
3685 /* Remplis les infos dont on dispose immédiatement */
3687 stat
->NODE
= ctkdetail
->NODE
;
3689 stat
->RISE_PEAK_REAL
= ctkdetail
->NOISE_OVR
;
3690 stat
->FALL_PEAK_REAL
= ctkdetail
->NOISE_UND
;
3691 stat
->RISE_PEAK_MAX
= ctkdetail
->NOISE_MAX_OVR
;
3692 stat
->FALL_PEAK_MAX
= ctkdetail
->NOISE_MAX_UND
;
3693 stat
->VTH
= ctkdetail
->NOISE_VTH
;
3695 /* Dans ctk_detail, on différencie les modèles de bruit rise et fall.
3696 Dans la pratique, c'est le même. On conserve celui qui va vers vdd/2 */
3698 if( ( ctkdetail
->NODE
->TYPE
& TTV_NODE_UP
) == TTV_NODE_UP
)
3699 stat
->NOISE_MODEL
= ctkdetail
->MODEL_OVR
;
3701 stat
->NOISE_MODEL
= ctkdetail
->MODEL_UND
;
3703 /* Remplis les infos de capa */
3705 capa
= rcx_get_all_locon_capa( ctkdetail
->LOSIG
, TRC_SLOPE_UNK
, TRC_CAPA_NOM
, TRC_HALF
);
3707 stat
->CNET_CC
= ctkdetail
->CC
;
3708 stat
->CGATE
= capa
;
3709 stat
->CNET_GND
= ctkdetail
->CM
- capa
;
3710 if( stat
->CNET_GND
< 0.0 )
3711 stat
->CNET_GND
= 0.0 ;
3715 /******************************************************************************\
3716 Si on est en mode STB_CTK_LINE :
3718 Met à jour les champs delai et front des line avec crosstalk et nettoie les
3719 structures delay de la ttvfig si on est en mode line.
3720 \******************************************************************************/
3722 void stb_clean_ttvfig( stbfig_list
*stbfig
)
3724 if( ( stbfig
->CTKMODE
& STB_CTK_LINE
) == STB_CTK_LINE
)
3725 ttv_movedelayline( stbfig
->FIG
, TTV_LINE_D
| TTV_LINE_E
| TTV_LINE_F
);
3728 /******************************************************************************\
3729 stb_ctk_handle_mutex()
3731 Enleve le flag RCX_AGRBEST ou RCX_AGRWORST des structures rcxparam des
3732 event qui ne peuvent pas se produire (mutex). Lorsqu'un de ces flags est
3733 enlevé, on le remplace par RCX_MTX_BEST ou RCX_MTX_WORST pour le report.
3735 \******************************************************************************/
3736 void stb_ctk_handle_mutex( ttvfig_list
*ttvfig
,
3737 ttvevent_list
*event
,
3738 chain_list
* headagr
,
3743 sortedmutex
*mutex
;
3744 sortedmutexlist
*ml
;
3746 ttvevent_list
*node
;
3748 rcxparam
*parammax
;
3750 mutex
= stb_ctk_sort_by_mutex( ttvfig
, event
, headagr
);
3751 if( !mutex
) return ;
3753 for( ml
= mutex
->LIST
; ml
; ml
= ml
->NEXT
) {
3755 if( ml
->MUTEX
== mutex
->MUTEX
) {
3757 for( chain
= ml
->LIST
; chain
; chain
= chain
->NEXT
) {
3759 node
= (ttvevent_list
*)chain
->DATA
;
3760 param
= stb_getrcxparamfromevent( node
);
3762 if( actif
== RCX_AGRBEST
) {
3763 if( ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
)
3764 param
->ACTIF
= (param
->ACTIF
& ~RCX_AGRBEST
) | RCX_MTX_BEST
;
3767 if( ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
)
3768 param
->ACTIF
= (param
->ACTIF
& ~RCX_AGRWORST
) | RCX_MTX_WORST
;
3777 for( chain
= ml
->LIST
; chain
; chain
= chain
->NEXT
) {
3779 node
= (ttvevent_list
*)chain
->DATA
;
3780 param
= stb_getrcxparamfromevent( node
);
3782 if( ( actif
== RCX_AGRBEST
&&
3783 ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
) ||
3784 ( actif
== RCX_AGRWORST
&&
3785 ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
) ) {
3787 if( param
->CC
> ccmax
) {
3796 for( chain
= ml
->LIST
; chain
; chain
= chain
->NEXT
) {
3798 node
= (ttvevent_list
*)chain
->DATA
;
3799 param
= stb_getrcxparamfromevent( node
);
3801 if( actif
== RCX_AGRBEST
&&
3802 ( param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
) {
3804 if( param
!= parammax
)
3805 param
->ACTIF
= (param
->ACTIF
& ~RCX_AGRBEST
) | RCX_MTX_BEST
;
3808 if( actif
== RCX_AGRWORST
&&
3809 ( param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
) {
3811 if( param
!= parammax
)
3812 param
->ACTIF
= (param
->ACTIF
& ~RCX_AGRWORST
) | RCX_MTX_WORST
;
3818 stb_ctk_free_sortedmutex( ttvfig
, mutex
);
3821 void stb_set_ctk_information(stbfig_list
*stbfig
, ttvevent_list
*node
, long type
, ctk_exchange
*res
)
3824 chain_list
*chainfig
;
3827 if((stbfig
->STABILITYMODE
& STB_STABILITY_LAST
) == STB_STABILITY_LAST
)
3828 level
= stbfig
->FIG
->INFO
->LEVEL
;
3832 res
->sigvic
= ttv_getlosigfromevent( stbfig
->FIG
, node
->ROOT
, &insname
, &chainfig
, &res
->figvic
);
3835 res
->headagr
= rcx_getagrlist( res
->figvic
, res
->sigvic
, insname
, chainfig
);
3836 freechain( chainfig
);
3841 stb_fillttvsigrcxparam( stbfig
->FIG
, level
, type
, res
->headagr
);
3843 if( ( stbfig
->CTKMODE
& STB_CTK_WORST
) == STB_CTK_WORST
)
3845 stb_fillinactifrcxparam( stbfig
->FIG
, node
, res
->headagr
, 'N' );
3849 stb_fillactifrcxparam( stbfig
->FIG
, node
, res
->headagr
, 'N' );
3851 stb_remove_input( stbfig
->FIG
, node
->ROOT
, level
, res
->headagr
);
3858 void stb_release_ctk_information(ctk_exchange
*res
)
3862 stb_delttvsigrcxparam( res
->headagr
);
3863 rcx_freeagrlist( res
->figvic
, res
->sigvic
, res
->headagr
);