Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stb / stb_ctk.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : STB Version 1.00 */
6 /* Fichier : stb_ctk.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Karim DIOURY */
12 /* Anthony LESTER */
13 /* Grégoire AVOT */
14 /* */
15 /****************************************************************************/
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdarg.h>
21 #include <limits.h>
22 #include <unistd.h>
23
24
25 #include MUT_H
26 #include STB_H
27 #include RCN_H
28 #include TRC_H
29 #include TTV_H
30
31 #include "stb_util.h"
32 #include "stb_init.h"
33 #include "stb_error.h"
34 #include "stb_transfer.h"
35 #include "stb_relaxation.h"
36 #include "stb_overlap.h"
37 #include "stb_ctk.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"
43
44 #include "stb_relaxation_correction.h"
45 #include "stb_ctk_report.h"
46
47 // pour les apis
48 #include "api_communication.h"
49 #include "stb_communication.c"
50 // -------------
51
52 // Variation de front minimum pour considérer un changement significatif
53 long STB_CTK_MINSLOPECHANGE=0;
54
55 // Nombre maximum d'itération lorsqu'il n'y a plus de nouvelles agressions
56 // détectées.
57 int STB_CTK_MAXLASTITER=3;
58
59 // Autorise plus de consommation mémoire pour aller plus vite
60 char STB_CTK_FASTMODE=1;
61
62 // Comportement des agresseurs pour lesquels il n'y a pas d'information temporelle
63 //int STB_CTK_NOINFO_ACTIF=0;
64
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;
72
73 long NBPTYPE=0l;
74
75 /*
76 ------------------------------------------------------------------------------
77
78 FONCTIONS D'AFFICHAGE ET DE DEBUGGAGE
79
80 ------------------------------------------------------------------------------
81 */
82
83 /* Largeur de la barre de progression */
84 #define STB_PROGRESS_WIDTH 50
85
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 ;
90
91 int STBCTK_NBDELAYCALC;
92
93 void stb_ctk_error( int code, char *fmt, ... )
94 {
95 va_list index;
96 va_start( index, fmt );
97
98 fflush( stdout );
99 fprintf( stderr, "\n\n*** ERROR %d IN STB/CTK ***\n\n", code );
100 vfprintf( stderr, fmt, index );
101 fprintf( stderr, "\n" );
102 EXIT(1);
103 }
104
105 void stb_print( char *msg )
106 {
107 printf( "%s\n", msg );
108 }
109
110 void stb_progressbar( int max, int current )
111 {
112 static char ligne [1024];
113 long pos;
114 long r;
115 int i;
116 static int last;
117 static int lastr;
118 if( ! isatty(1) || max == 0 ) return;
119
120 if( current == 0 ) {
121
122 for( i=0 ; i<1024 ; i++ ) ligne[i]=' ';
123
124 ligne[STB_PROGRESS_WIDTH+1]='\0';
125
126 }
127
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++ ) {
132 ligne[i]='#';
133 }
134 avt_fprintf( stdout, "\r%3ld%% [¤2%s¤.] %7ldKb", r, ligne, mbkprocessmemoryusage()/1024 );
135 fflush( stdout );
136 last = pos;
137 lastr = r;
138 }
139 }
140
141 void stb_progress( int iteration, int max, int pos, char *msg )
142 {
143 char bufchrono[128] ;
144 static mbk_chrono chrono;
145 static int lastiter = -1 ;
146
147 if( msg ) {
148 printf( "\n%s\n", msg );
149 mbk_StartChrono( &chrono );
150 }
151 else {
152 if( iteration && lastiter != iteration )
153 printf( "Iteration #%d\n", iteration );
154 stb_progressbar( max, pos );
155 if( pos == max ) {
156 printf( "\n" );
157 mbk_StopChrono( &chrono );
158 mbk_GetUserChrono( &chrono, bufchrono );
159 printf(" User CPU time : %s\n", bufchrono );
160 mbk_StartChrono( &chrono );
161 }
162 }
163
164 lastiter = iteration ;
165 }
166
167 /*
168 ------------------------------------------------------------------------------
169
170 MEMORISATION DES AGRESSIONS ACTIVES DANS STB
171
172 ------------------------------------------------------------------------------
173
174 Principe :
175
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².
181
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.
186
187 Q : Pourquoi ne pas avoir utilisé alors systématiquement une table de hash ?
188
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.
194
195
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.
198 */
199
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;
208 {
209 ptype_list *ptl;
210 long v;
211
212 ptl = getptype( victime->USER, STB_CTK_RCXAGRPT );
213
214 if( ptl ) {
215
216 for( ptl = ((ptype_list*)(ptl->DATA)) ;
217 ptl && ((ttvsig_list*)(ptl->DATA)) != agresseur ;
218 ptl = ptl->NEXT );
219
220 if( ptl )
221 return ((char)(ptl->TYPE)) ;
222
223 return 0;
224 }
225
226 ptl = getptype( victime->USER, STB_CTK_RCXAGRHT );
227
228 if( ptl ) {
229
230 v = gethtitem( ((ht*)(ptl->DATA)), agresseur );
231 if( v != EMPTYHT )
232 return ((char)v) ;
233
234 return 0;
235 }
236
237 return 0;
238 }
239
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;
248 char type;
249 {
250 ptype_list *ptl;
251 ptype_list *scan;
252 int n;
253 ht *newht;
254
255 ptl = getptype( victime->USER, STB_CTK_RCXAGRHT );
256
257 if( ptl ) {
258 sethtitem( ((ht*)(ptl->DATA)), agresseur, (long)((unsigned char)type) );
259 return ;
260 }
261
262 ptl = getptype( victime->USER, STB_CTK_RCXAGRPT );
263
264 if( !ptl ) {
265
266 victime->USER = addptype( victime->USER,
267 STB_CTK_RCXAGRPT,
268 NULL
269 );
270 ptl = victime->USER;
271 }
272
273 for( scan = ((ptype_list*)(ptl->DATA)), n=0 ;
274 scan && ((ttvsig_list*)(scan->DATA)) != agresseur ;
275 scan = scan->NEXT, n++ );
276
277 if( scan ) {
278 scan->TYPE = (char) type;
279 return ;
280 }
281
282 if( n > STB_CTK_MAXCHAIN ) {
283
284 newht = addht( STB_CTK_MAXCHAIN + 1 );
285
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) );
289
290 freeptype( ((ptype_list*)(ptl->DATA)) );
291 victime->USER = delptype( victime->USER, STB_CTK_RCXAGRPT );
292 ptl = NULL;
293
294 victime->USER = addptype( victime->USER, STB_CTK_RCXAGRHT, newht );
295
296 }
297 else {
298
299 ptl->DATA = addptype( ((ptype_list*)(ptl->DATA)),
300 (char)type,
301 agresseur
302 );
303 }
304
305 return;
306
307 }
308
309 void stb_cleanagressiontype( ttvsig_list *signal )
310 {
311 ptype_list *ptl;
312
313 ptl = getptype( signal->USER, STB_CTK_RCXAGRPT );
314 if( ptl ) {
315 freeptype( (ptype_list*)ptl->DATA );
316 signal->USER = delptype( signal->USER, STB_CTK_RCXAGRPT );
317 }
318
319 ptl = getptype( signal->USER, STB_CTK_RCXAGRHT );
320 if( ptl ) {
321 delht( (ht*)ptl->DATA );
322 signal->USER = delptype( signal->USER, STB_CTK_RCXAGRHT );
323 }
324 }
325
326 /*
327 Marque les driver de victime. Renvoie la chain_list des ttvsig marqués pour
328 les nettoyer plus tard
329
330 victime est un ttvsig en sortie de gate
331 Ne fonctionne qu'à plat.
332 */
333
334 chain_list* stb_mark_input( ttvfig_list *ttvfig,
335 ttvsig_list *victime,
336 long level
337 )
338 {
339 int i, j;
340 ttvline_list *line ;
341 ttvline_list *linerc ;
342 ttvsig_list *ttvsig ;
343 ttvsig_list *ttvsigrc ;
344 chain_list *toclean ;
345
346 ttv_expfigsig( ttvfig, victime, level, ttvfig->INFO->LEVEL,
347 TTV_STS_CLS_FED|TTV_STS_DUAL_FED, TTV_FILE_DTX
348 );
349
350 toclean = NULL ;
351
352 for( i=0 ; i<= 1 ; i++ ) {
353
354 for( line = victime->NODE[i].INLINE ; line ; line = line->NEXT ) {
355
356 if( !ttv_islinelevel( ttvfig, line, level ) )
357 continue ;
358
359 ttvsig = line->NODE->ROOT ;
360
361 if( !getptype( ttvsig->USER, STB_CTK_DRIVER ) ) {
362 ttvsig->USER = addptype( ttvsig->USER, STB_CTK_DRIVER, 0l );
363 toclean = addchain( toclean, ttvsig );
364 }
365
366 /* on marque également les driver des entrées rc */
367
368 for( j=0 ; j<=1 ; j++ ) {
369 for( linerc = ttvsig->NODE[j].INLINE ; linerc ; linerc = linerc->NEXT )
370 {
371
372 if( ((linerc->TYPE & TTV_LINE_RC) != TTV_LINE_RC) ||
373 !ttv_islinelevel( ttvfig, linerc, level ) )
374 continue ;
375
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 );
380 }
381 }
382 }
383 }
384 }
385
386 return toclean ;
387 }
388
389 int stb_is_mark_input( ttvsig_list *ttvsig )
390 {
391 if( getptype( ttvsig->USER, STB_CTK_DRIVER ) )
392 return 1 ;
393 return 0;
394 }
395
396 void stb_clean_mark_input( chain_list *tocleanmark )
397 {
398 chain_list *chain ;
399 ttvsig_list *ttvsig ;
400
401 for( chain = tocleanmark ; chain ; chain = chain->NEXT ) {
402 ttvsig = (ttvsig_list*)chain->DATA ;
403 ttvsig->USER = delptype( ttvsig->USER, STB_CTK_DRIVER );
404 }
405 freechain( tocleanmark );
406 }
407
408 static void stb_set_min_slope(ttvfig_list *ttvfig, ttvevent_list *tve, int level, int mode)
409 {
410 ptype_list *pt;
411 long delayval, lineval;
412 stb_fastslope *sfs;
413 int i;
414 if ((pt=getptype(tve->ROOT->USER, STB_CTK_FAST_SLOPE))==NULL)
415 {
416 sfs=(stb_fastslope *)mbkalloc(sizeof(stb_fastslope));
417 pt=tve->ROOT->USER=addptype(tve->ROOT->USER, STB_CTK_FAST_SLOPE, sfs);
418 for (i=0; i<2; i++)
419 {
420 sfs->ev[i].delayval=sfs->ev[i].lineval=STM_DEF_SLEW;
421 sfs->ev[i].pairnode=NULL;
422 }
423 }
424
425 sfs=(stb_fastslope *)pt->DATA;
426
427 if (tve->TYPE & TTV_NODE_UP) i=1; else i=0;
428 if (mode & 2)
429 {
430 sfs->ev[i].delayval = ttv_getslopenode( ttvfig,
431 level,
432 tve,
433 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
434 TTV_MODE_DELAY
435 )/TTV_UNIT;
436 if( sfs->ev[i].delayval == 0 ) sfs->ev[i].delayval = STM_DEF_SLEW ;
437 }
438 if (mode & 1)
439 {
440 sfs->ev[i].lineval = ttv_getslopenode( ttvfig,
441 level,
442 tve,
443 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
444 TTV_MODE_LINE
445 )/TTV_UNIT;
446 if( sfs->ev[i].lineval == 0 ) sfs->ev[i].lineval = STM_DEF_SLEW ;
447 }
448 }
449
450 void stb_setupall_slopes(stbfig_list *stbfig, int level)
451 {
452 ttvevent_list *tve;
453 chain_list *chain;
454 for(chain = stbfig->NODE; chain ; chain = chain->NEXT)
455 {
456 tve=(ttvevent_list *)chain->DATA;
457 stb_set_min_slope(stbfig->FIG, tve, level, 3);
458 }
459 }
460 void stb_cleanup_slopes(stbfig_list *stbfig)
461 {
462 ttvevent_list *tve;
463 chain_list *chain;
464 ptype_list *pt;
465 int i;
466 stb_fastslope *sfs;
467 for(chain = stbfig->NODE; chain ; chain = chain->NEXT)
468 {
469 tve=(ttvevent_list *)chain->DATA;
470 if ((pt=getptype(tve->ROOT->USER, STB_CTK_FAST_SLOPE))!=NULL)
471 {
472 sfs=(stb_fastslope *)pt->DATA;
473 for (i=0; i<2; i++)
474 stb_freestbpair(sfs->ev[i].pairnode);
475 mbkfree(sfs);
476 tve->ROOT->USER=delptype(tve->ROOT->USER, STB_CTK_FAST_SLOPE);
477 }
478 }
479 }
480 void stb_release_fast_nodepair(ttvevent_list *tve)
481 {
482 ptype_list *pt;
483 stb_fastslope *sfs;
484 int i;
485 if (tve->TYPE & TTV_NODE_UP) i=1; else i=0;
486 if ((pt=getptype(tve->ROOT->USER, STB_CTK_FAST_SLOPE))!=NULL)
487 {
488 sfs=(stb_fastslope *)pt->DATA;
489 stb_freestbpair(sfs->ev[i].pairnode);
490 sfs->ev[i].pairnode=NULL;
491 }
492 }
493
494 void stb_cleanup_fast_nodepair(stbfig_list *stbfig)
495 {
496 ttvevent_list *tve;
497 chain_list *chain;
498 for(chain = stbfig->NODE; chain ; chain = chain->NEXT)
499 {
500 tve=(ttvevent_list *)chain->DATA;
501 stb_release_fast_nodepair(tve);
502 }
503 }
504
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 )
513 ttvfig_list *ttvfig;
514 long level;
515 long type;
516 chain_list *headlist;
517 {
518 chain_list *chain;
519 rcxparam *param;
520 ttvsig_list *ttvsig;
521 ptype_list *pt;
522 stb_fastslope *sfs;
523
524 stb_ctkprint( 1, "Filling agressor parameter :\n" );
525
526
527 for( chain = headlist ; chain ; chain = chain->NEXT ) {
528
529 param = (rcxparam*)(chain->DATA);
530
531
532 ttvsig = ttv_getttvsig( ttvfig,
533 level,
534 type,
535 param->INSNAME,
536 param->SIGNAL,
537 STB_CTK_FASTMODE
538 );
539
540 if( ttvsig ) {
541
542 param->USER = addptype( param->USER, STB_CTK_RCXTTVSIG, ttvsig );
543 if ((pt=getptype(ttvsig->USER, STB_CTK_FAST_SLOPE))!=NULL)
544 {
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;
550 }
551 else
552 {
553 param->FMINUP = ttv_getslopenode( ttvfig,
554 level,
555 ttvsig->NODE+1,
556 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
557 TTV_MODE_DELAY
558 )/TTV_UNIT;
559 if( param->FMINUP == 0 ) param->FMINUP = STM_DEF_SLEW ;
560
561 param->FMINDW = ttv_getslopenode( ttvfig,
562 level,
563 ttvsig->NODE,
564 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
565 TTV_MODE_DELAY
566 )/TTV_UNIT;
567 if( param->FMINDW == 0 ) param->FMINDW = STM_DEF_SLEW ;
568
569 param->F0UP = ttv_getslopenode( ttvfig,
570 level,
571 ttvsig->NODE+1,
572 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
573 TTV_MODE_LINE
574 )/TTV_UNIT;
575 if( param->F0UP == 0 ) param->F0UP = STM_DEF_SLEW ;
576
577 param->F0DW = ttv_getslopenode( ttvfig,
578 level,
579 ttvsig->NODE,
580 TTV_FIND_LINE | TTV_FIND_GATE | TTV_FIND_RC | TTV_FIND_MIN,
581 TTV_MODE_LINE
582 )/TTV_UNIT;
583 if( param->F0DW == 0 ) param->F0DW = STM_DEF_SLEW ;
584 }
585
586 stb_ctkprint( 1,
587 " %s (netname=%s) : Fmin Up = %g, F0 Up = %g, Fmin Dw = %g, F0 Dw = %g\n",
588 ttvsig->NAME,
589 ttvsig->NETNAME,
590 param->FMINUP,
591 param->F0UP,
592 param->FMINDW,
593 param->F0DW
594 );
595 }
596 else {
597 stb_ctkprint( 1, " No corresponding ttvsig for signal %s\n",
598 getsigname( param->SIGNAL )
599 );
600 param->FMINUP = STM_DEF_SLEW;
601 param->FMINDW = STM_DEF_SLEW;
602 param->F0UP = STM_DEF_SLEW;
603 param->F0DW = STM_DEF_SLEW;
604 }
605 }
606 }
607
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;
615 {
616 chain_list *chain;
617 rcxparam *param;
618 ptype_list *ptl;
619
620 for( chain = headlist ; chain ; chain = chain->NEXT ) {
621
622 param = (rcxparam*)(chain->DATA);
623
624 ptl = getptype( param->USER, STB_CTK_RCXTTVSIG );
625 if( !ptl )
626 continue;
627
628 param->USER = delptype( param->USER, STB_CTK_RCXTTVSIG );
629 }
630 }
631
632 /*****************************************************************************
633 * fonction stb_getttvsigrcxparam() *
634 ******************************************************************************
635 * Récupère le ttvsig correspondant à un rcxparam *
636 *****************************************************************************/
637 ttvsig_list* stb_getttvsigrcxparam( param )
638 rcxparam *param;
639 {
640 ptype_list *ptl;
641
642 ptl = getptype( param->USER, STB_CTK_RCXTTVSIG );
643
644 if( !ptl ) {
645 return( NULL );
646 }
647
648 return ((ttvsig_list*)(ptl->DATA));
649 }
650
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;
658 {
659 rcxparam *param;
660 ptype_list *ptl;
661
662 ptl = getptype( event->USER, STB_CTK_RCXPARAM );
663 if( !ptl ) {
664 fflush( stdout );
665 fprintf( stderr, "*** Error in STB/CTK : Can't find rcxparam from event.\n"
666 );
667 EXIT(1);
668 }
669 param = ((rcxparam*)(ptl->DATA));
670
671 return param ;
672 }
673
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;
681 rcxparam *param;
682 {
683 ptype_list *ptl;
684
685 ptl = getptype( event->USER, STB_CTK_RCXPARAM );
686 if( ptl ) {
687 fflush( stdout );
688 fprintf( stderr, "*** Error in STB/CTK : event contain an rcxparam.\n"
689 );
690 EXIT(1);
691 }
692
693 NBPTYPE++;
694 event->USER = addptype( event->USER, STB_CTK_RCXPARAM, param );
695 }
696
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;
704 {
705 ptype_list *ptl;
706
707 ptl = getptype( event->USER, STB_CTK_RCXPARAM );
708 if( !ptl ) {
709 fflush( stdout );
710 fprintf( stderr, "*** Error in STB/CTK : Can't find rcxparam from event.\n"
711 );
712 EXIT(1);
713 }
714
715 event->USER = delptype( event->USER, STB_CTK_RCXPARAM );
716 NBPTYPE--;
717 }
718
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
728
729 typedef struct
730 {
731 rcxparam *param;
732 float proba;
733 } agr_sort_proba_info;
734
735 static int stb_compare_proba_capa(const void *a, const void *b)
736 {
737 agr_sort_proba_info *aspia=(agr_sort_proba_info *)a;
738 agr_sort_proba_info *aspib=(agr_sort_proba_info *)b;
739 float mixa, mixb;
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;
744 return 0;
745 }
746
747 void stb_choose_sub_agressor_list_depending_on_probability(chain_list *headlist, float probamin)
748 {
749 agr_sort_proba_info tab[STB_MAX_AGR];
750 int i, j, ck;
751 float curproba, futureproba;
752 rcxparam *param;
753 ttvsig_list *ttvsig;
754 ptype_list *pt;
755 stbnode *node;
756
757 if (probamin!=0)
758 {
759 i=0;
760 while (headlist)
761 {
762 param=(rcxparam *)headlist->DATA;
763 tab[i].param=param;
764 ttvsig = stb_getttvsigrcxparam( param );
765 if (ttvsig!=NULL)
766 {
767 ck=0;
768 node = stb_getstbnode( &ttvsig->NODE[0]);
769 if (node->CK!=NULL) ck=1;
770 else
771 {
772 node = stb_getstbnode( &ttvsig->NODE[1]);
773 if (node->CK!=NULL) ck=1;
774 }
775 if (ck)
776 tab[i].proba=1, i++;
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)
780 tab[i].proba=1, i++;
781 }
782 else
783 if(V_BOOL_TAB[__STB_CTK_NOINFO_ACTIF].VALUE)
784 tab[i].proba=1, i++;
785 headlist=headlist->NEXT;
786 }
787
788 qsort(tab, i, sizeof(agr_sort_proba_info), stb_compare_proba_capa);
789
790 curproba=1;
791 for (j=0; j<i; j++)
792 {
793 futureproba=curproba*tab[j].proba;
794 if (futureproba<=probamin)
795 tab[j].param->ACTIF=0;
796 else
797 curproba=futureproba;
798 }
799 }
800 }
801
802 void stb_fillactifrcxparam( ttvfig, victime, headlist, mutex )
803 ttvfig_list *ttvfig;
804 ttvevent_list *victime;
805 chain_list *headlist;
806 char mutex;
807 {
808 chain_list *chain;
809 rcxparam *param;
810 char type;
811 ttvsig_list *ttvsig;
812
813 stb_ctkprint( 0, " Previous agressors :\n" );
814 for( chain = headlist ; chain ; chain = chain->NEXT ) {
815
816 param = (rcxparam*)(chain->DATA);
817 param->ACTIF = 0;
818
819 ttvsig = stb_getttvsigrcxparam( param );
820
821 if( ttvsig ) {
822
823 type = stb_getagressiontype( victime->ROOT, ttvsig );
824
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 ;
830
831 if( mutex == 'Y' )
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 ;
837
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 ;
843
844 if( mutex == 'Y' )
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 ;
850
851 }
852 else {
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 ;
856 }
857
858 stb_ctkprint( 0, " - %s.%s : %s %s\n",
859 param->INSNAME,
860 ttvsig ? ttvsig->NAME : getsigname( param->SIGNAL ),
861 ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST ?
862 "BEST":"",
863 ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST ?
864 "WORST":""
865 );
866
867 }
868
869 stb_choose_sub_agressor_list_depending_on_probability(headlist, V_FLOAT_TAB[__STB_MIN_PROBABILITY].VALUE);
870
871 ttvfig = NULL; // unused parameter : avoid a warning at compilation
872 }
873
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 )
881 ttvfig_list *ttvfig;
882 ttvevent_list *victime;
883 chain_list *headlist;
884 char mutex;
885 {
886 chain_list *chain;
887 rcxparam *param;
888 char type;
889 ttvsig_list *ttvsig;
890
891 stb_ctkprint( 0, " Previous agressors :\n" );
892 for( chain = headlist ; chain ; chain = chain->NEXT ) {
893
894 param = (rcxparam*)(chain->DATA);
895
896 ttvsig = stb_getttvsigrcxparam( param );
897 if( !ttvsig ) {
898 if( V_BOOL_TAB[__STB_CTK_NOINFO_ACTIF].VALUE )
899 param->ACTIF = RCX_AGRWORST | RCX_AGRBEST ;
900 continue;
901 }
902
903 param->ACTIF = RCX_AGRWORST | RCX_AGRBEST ;
904
905 type = stb_getagressiontype( victime->ROOT, ttvsig );
906
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 ;
912
913 if( mutex == 'Y' )
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 ;
919
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 ;
925
926 if( mutex == 'Y' )
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 ;
932
933 stb_ctkprint( 0, " - %s.%s : %s %s\n",
934 param->INSNAME,
935 ttvsig->NAME,
936 ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST ?
937 "BEST":"",
938 ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST ?
939 "WORST":""
940 );
941
942 }
943
944 stb_choose_sub_agressor_list_depending_on_probability(headlist, V_FLOAT_TAB[__STB_MIN_PROBABILITY].VALUE);
945
946 ttvfig = NULL; // unused parameter : avoid a warning at compilation
947 }
948
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 )
958 {
959 char oldtype;
960 char newtype;
961 char newagr=0;
962
963 oldtype = stb_getagressiontype( victime->ROOT, aggressor );
964 newtype = oldtype;
965
966
967 if( ( victime->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ) {
968
969 if( ( rcxaggression & RCX_AGRBEST ) == RCX_AGRBEST )
970 newtype = newtype | STB_CTK_UP_BEST;
971
972 if( ( rcxaggression & RCX_MTX_BEST ) == RCX_MTX_BEST )
973 newtype = newtype | STB_CTK_UP_BEST | STB_CTK_UP_MTX_BEST;
974 else
975 newtype = newtype & ~STB_CTK_UP_MTX_BEST ;
976
977 if( ( rcxaggression & RCX_AGRWORST ) == RCX_AGRWORST )
978 newtype = newtype | STB_CTK_UP_WRST;
979
980 if( ( rcxaggression & RCX_MTX_WORST ) == RCX_MTX_WORST )
981 newtype = newtype | STB_CTK_UP_WRST | STB_CTK_UP_MTX_WORST;
982 else
983 newtype = newtype & ~STB_CTK_UP_MTX_WORST ;
984
985 }
986 else {
987
988 if( ( rcxaggression & RCX_AGRBEST ) == RCX_AGRBEST )
989 newtype = newtype | STB_CTK_DW_BEST;
990
991 if( ( rcxaggression & RCX_MTX_BEST ) == RCX_MTX_BEST )
992 newtype = newtype | STB_CTK_DW_BEST | STB_CTK_DW_MTX_BEST;
993 else
994 newtype = newtype & ~STB_CTK_DW_MTX_BEST ;
995
996 if( ( rcxaggression & RCX_AGRWORST ) == RCX_AGRWORST )
997 newtype = newtype | STB_CTK_DW_WRST;
998
999 if( ( rcxaggression & RCX_MTX_WORST ) == RCX_MTX_WORST )
1000 newtype = newtype | STB_CTK_DW_WRST | STB_CTK_DW_MTX_WORST;
1001 else
1002 newtype = newtype & ~STB_CTK_DW_MTX_WORST ;
1003 }
1004
1005 if( newtype != oldtype ) {
1006 stb_setagressiontype( victime->ROOT, aggressor, newtype );
1007 newagr = 1;
1008 }
1009
1010 return newagr ;
1011 }
1012
1013 int stb_saveactifrcxparam( ttvfig, victime, headlist )
1014 ttvfig_list *ttvfig;
1015 ttvevent_list *victime;
1016 chain_list *headlist;
1017 {
1018 chain_list *chain;
1019 rcxparam *param;
1020 char newagr=0;
1021 ttvsig_list *ttvsig ;
1022
1023 for( chain = headlist ; chain ; chain = chain->NEXT ) {
1024
1025 param = (rcxparam*)(chain->DATA);
1026
1027 if( param->ACTIF & RCX_QUIET )
1028 continue ;
1029
1030 ttvsig = stb_getttvsigrcxparam( param );
1031 if( !ttvsig )
1032 continue ;
1033
1034 if( stb_saveactifcoupling( victime, ttvsig, param->ACTIF ) )
1035 newagr = 1 ;
1036 }
1037
1038 ttvfig = NULL; // unused parameter : avoid a warning at compilation
1039 return( newagr );
1040 }
1041
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 *****************************************************************************/
1048
1049 int stb_saveinactifcoupling( ttvevent_list *victime, ttvsig_list *aggressor, int rcxaggression )
1050 {
1051 char oldtype;
1052 char newtype;
1053 char newagr=0;
1054
1055 oldtype = stb_getagressiontype( victime->ROOT, aggressor );
1056 newtype = oldtype;
1057
1058
1059 if( ( victime->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ) {
1060
1061 if( ( rcxaggression & RCX_AGRBEST ) != RCX_AGRBEST )
1062 newtype = newtype | STB_CTK_UP_NOBEST;
1063
1064 if( ( rcxaggression & RCX_MTX_BEST ) == RCX_MTX_BEST )
1065 newtype = ( newtype & ~STB_CTK_UP_NOBEST ) | STB_CTK_UP_MTX_BEST;
1066 else
1067 newtype = newtype & ~STB_CTK_UP_MTX_BEST ;
1068
1069 if( ( rcxaggression & RCX_AGRWORST ) != RCX_AGRWORST )
1070 newtype = newtype | STB_CTK_UP_NOWRST;
1071
1072 if( ( rcxaggression & RCX_MTX_WORST ) == RCX_MTX_WORST )
1073 newtype = ( newtype & ~STB_CTK_UP_NOWRST ) | STB_CTK_UP_MTX_WORST;
1074 else
1075 newtype = newtype & ~STB_CTK_UP_MTX_WORST ;
1076 }
1077 else {
1078
1079 if( ( rcxaggression & RCX_AGRBEST ) != RCX_AGRBEST )
1080 newtype = newtype | STB_CTK_DW_NOBEST;
1081
1082 if( ( rcxaggression & RCX_MTX_BEST ) == RCX_MTX_BEST )
1083 newtype = ( newtype & ~STB_CTK_DW_NOBEST ) | STB_CTK_DW_MTX_BEST;
1084 else
1085 newtype = newtype & ~STB_CTK_DW_MTX_BEST ;
1086
1087 if( ( rcxaggression & RCX_AGRWORST ) != RCX_AGRWORST )
1088 newtype = newtype | STB_CTK_DW_NOWRST;
1089
1090 if( ( rcxaggression & RCX_MTX_WORST ) == RCX_MTX_WORST )
1091 newtype = ( newtype & ~STB_CTK_DW_NOWRST ) | STB_CTK_DW_MTX_WORST;
1092 else
1093 newtype = newtype & ~STB_CTK_DW_MTX_WORST ;
1094 }
1095
1096 if( newtype != oldtype ) {
1097 stb_setagressiontype( victime->ROOT, aggressor, newtype );
1098 newagr = 1;
1099 }
1100
1101 return newagr ;
1102 }
1103
1104 int stb_saveinactifrcxparam( ttvfig, victime, headlist )
1105 ttvfig_list *ttvfig;
1106 ttvevent_list *victime;
1107 chain_list *headlist;
1108 {
1109 chain_list *chain;
1110 rcxparam *param;
1111 char newagr=0;
1112 ttvsig_list *ttvsig;
1113
1114 for( chain = headlist ; chain ; chain = chain->NEXT ) {
1115
1116 param = (rcxparam*)(chain->DATA);
1117
1118 if( param->ACTIF & RCX_QUIET )
1119 continue ;
1120
1121 ttvsig = stb_getttvsigrcxparam( param );
1122 if( !ttvsig )
1123 continue ;
1124
1125 if( stb_saveinactifcoupling( victime, ttvsig, param->ACTIF ) )
1126 newagr = 1 ;
1127 }
1128
1129 ttvfig = NULL; // unused parameter : avoid a warning at compilation
1130 return( newagr );
1131 }
1132
1133 /*
1134 ------------------------------------------------------------------------------
1135
1136 FONCTIONS PRINCIPALES
1137
1138 ------------------------------------------------------------------------------
1139 */
1140
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;
1148 stbgap_list *gap;
1149 {
1150 chain_list *scan;
1151 ttvevent_list *event;
1152 rcxparam *param;
1153
1154 stb_ctkprint( 0, " - New aggressors :\n" );
1155 for( scan = gap->SIGNALS ; scan ; scan = scan->NEXT ) {
1156
1157 event = ((ttvevent_list*)(scan->DATA));
1158 param = stb_getrcxparamfromevent( event );
1159
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" :
1167 "DOWN",
1168 event->ROOT->NAME
1169 );
1170 param->ACTIF = param->ACTIF | RCX_AGRBEST ;
1171 }
1172 else {
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" :
1176 "DOWN",
1177 event->ROOT->NAME
1178 );
1179 param->ACTIF = param->ACTIF | RCX_AGRWORST ;
1180 }
1181 }
1182 }
1183
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;
1191 long type;
1192 {
1193 chain_list *eventlist = NULL ;
1194 chain_list *scanagr;
1195 rcxparam *param;
1196 ttvevent_list *event;
1197 ttvsig_list *ttvsig;
1198
1199 for( scanagr = headagr ; scanagr ; scanagr = scanagr->NEXT ) {
1200
1201 param = (rcxparam*)scanagr->DATA;
1202 ttvsig = stb_getttvsigrcxparam( param );
1203 if( !ttvsig )
1204 continue;
1205
1206 if( type == TTV_NODE_DOWN )
1207 event = ttvsig->NODE+0;
1208 else
1209 event = ttvsig->NODE+1;
1210
1211 eventlist = addchain( eventlist, event );
1212
1213 stb_addrcxparamfromevent( event, param );
1214 }
1215
1216 return( eventlist );
1217 }
1218
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;
1231 char type;
1232 chain_list *headagr;
1233 {
1234 chain_list *eventlist;
1235
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 );
1239 else
1240 eventlist = stb_createchainevent( headagr, TTV_NODE_UP );
1241 }
1242 else {
1243 if( type == STB_CTK_WORST_AGR )
1244 eventlist = stb_createchainevent( headagr, TTV_NODE_UP );
1245 else
1246 eventlist = stb_createchainevent( headagr, TTV_NODE_DOWN );
1247 }
1248
1249 return( eventlist );
1250 }
1251
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;
1259 {
1260 chain_list *chain;
1261 ttvevent_list *event;
1262
1263 for( chain = eventlist ; chain ; chain = chain->NEXT ) {
1264
1265 event = ((ttvevent_list*)(chain->DATA));
1266 stb_delrcxparamfromevent( event );
1267 }
1268
1269 freechain( eventlist );
1270 }
1271
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;
1283 long level;
1284 long type;
1285 ttvevent_list *evtvic;
1286 chain_list *headagr;
1287 {
1288 chain_list *eventlist;
1289 chain_list *realagrlist;
1290 chain_list *alwaysagrlist;
1291 chain_list *testagrlist;
1292 chain_list *chain;
1293 stbnode *stbvic;
1294 rcxparam *param;
1295 ttvevent_list *event;
1296 char oldactif;
1297
1298 if( ! headagr ) return;
1299
1300 stbvic = stb_getstbnode( evtvic );
1301 if( !stbvic ) {
1302 fflush( stdout );
1303 fprintf( stderr, "\n*** Error in STB/CTK : no stability on event.\n" );
1304 EXIT(1);
1305 }
1306
1307 /* WORST CASE */
1308
1309 stb_ctkprint( 0, " Checking worst case agression.\n" );
1310
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 );
1314
1315 // Récupère la liste des agresseurs qui ne sont pas sur la même phase que
1316 // evtvic.
1317 alwaysagrlist = stb_diftdomain( stbfig, evtvic, eventlist );
1318 testagrlist = subchain( eventlist, alwaysagrlist );
1319
1320 stb_log_chain( stbfig, alwaysagrlist,
1321 " agressors located on another clock domain"
1322 );
1323 // Récupère la liste des intervales qui recouvrent la victime.
1324
1325 realagrlist = stb_overlap( stbfig,
1326 evtvic,
1327 testagrlist,
1328 STB_CTK_MARGIN,
1329 STB_STD
1330 );
1331
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 );
1336 }
1337 for( chain = alwaysagrlist ; chain ; chain = chain->NEXT ) {
1338 event = ((ttvevent_list*)chain->DATA);
1339 event->USER = addptype( event->USER, STB_CTK_MARKREALACTIF, NULL );
1340 }
1341
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 );
1347 }
1348 else {
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" :
1355 "DOWN",
1356 event->ROOT->NAME
1357 );
1358 }
1359 }
1360 }
1361
1362 freechain( realagrlist );
1363 freechain( alwaysagrlist );
1364 freechain( testagrlist );
1365 stb_ctk_handle_mutex( stbfig->FIG, evtvic, eventlist, RCX_AGRWORST );
1366 stb_freechainevent( eventlist );
1367
1368 /* BEST CASE */
1369
1370 stb_ctkprint( 0, " Checking best case agression.\n" );
1371
1372 eventlist = stb_getchainevent( evtvic, STB_CTK_BEST_AGR, headagr );
1373 stb_debug_stab( stbfig, evtvic, eventlist );
1374
1375 alwaysagrlist = stb_diftdomain( stbfig, evtvic, eventlist );
1376 testagrlist = subchain( eventlist, alwaysagrlist );
1377
1378 stb_log_chain( stbfig, alwaysagrlist,
1379 "agressors located on another clock domain"
1380 );
1381 realagrlist = stb_overlap( stbfig,
1382 evtvic,
1383 testagrlist,
1384 STB_CTK_MARGIN,
1385 STB_STD
1386 );
1387
1388 for( chain = realagrlist ; chain ; chain = chain->NEXT ) {
1389 event = ((ttvevent_list*)chain->DATA);
1390 event->USER = addptype( event->USER, STB_CTK_MARKREALACTIF, NULL );
1391 }
1392 for( chain = testagrlist ; chain ; chain = chain->NEXT ) {
1393 event = ((ttvevent_list*)chain->DATA);
1394 event->USER = addptype( event->USER, STB_CTK_MARKREALACTIF, NULL );
1395 }
1396
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 );
1401 }
1402 else {
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" :
1409 "DOWN",
1410 event->ROOT->NAME
1411 );
1412 }
1413 }
1414 }
1415
1416 freechain( realagrlist );
1417 freechain( alwaysagrlist );
1418 freechain( testagrlist );
1419
1420 stb_ctk_handle_mutex( stbfig->FIG, evtvic, eventlist, RCX_AGRBEST );
1421 stb_freechainevent( eventlist );
1422
1423 level = 0l; // unused parameter : avoid a warning at compilation
1424 type = 0l; // unused parameter : avoid a warning at compilation
1425 }
1426
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;
1437 long level;
1438 long type;
1439 ttvevent_list *evtvic;
1440 chain_list *headagr;
1441 {
1442 chain_list *eventlist;
1443 stbnode *stbvic;
1444 chain_list *realagrlist;
1445 chain_list *testagrlist;
1446 chain_list *alwaysagrlist;
1447 ttvevent_list *event;
1448 chain_list *chain;
1449 rcxparam *param;
1450 char oldactif;
1451
1452 stb_ctkprint( 1,
1453 "Detecting best case agressor for event %s.\n",
1454 evtvic->ROOT->NAME
1455 );
1456
1457 if( ! headagr ) return;
1458
1459 stbvic = stb_getstbnode( evtvic );
1460 if( !stbvic ) {
1461 fflush( stdout );
1462 fprintf( stderr, "\n*** Error in STB/CTK : no stability on event.\n" );
1463 EXIT(1);
1464 }
1465
1466 /* WORST CASE */
1467
1468 stb_ctkprint( 0, " Checking worst case agression.\n" );
1469
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 );
1473
1474 alwaysagrlist = stb_diftdomain( stbfig, evtvic, eventlist );
1475 testagrlist = subchain( eventlist, alwaysagrlist );
1476
1477 stb_log_chain( stbfig, alwaysagrlist,
1478 "agressors located on another clock domain"
1479 );
1480 if( ( stbfig->CTKMODE & STB_CTK_OBSERVABLE ) == STB_CTK_OBSERVABLE )
1481 realagrlist = stb_overlap( stbfig,
1482 evtvic,
1483 testagrlist,
1484 STB_CTK_MARGIN,
1485 STB_OBS
1486 );
1487 else
1488 realagrlist = stb_overlap( stbfig,
1489 evtvic,
1490 testagrlist,
1491 STB_CTK_MARGIN,
1492 STB_STD
1493 );
1494
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" :
1503 "DOWN",
1504 event->ROOT->NAME
1505 );
1506 }
1507 }
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" :
1516 "DOWN",
1517 event->ROOT->NAME
1518 );
1519 }
1520 }
1521
1522 freechain( realagrlist );
1523 freechain( testagrlist );
1524 freechain( alwaysagrlist );
1525
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 );
1530
1531 /* BEST CASE */
1532
1533 stb_ctkprint( 0, " Checking best case agression.\n" );
1534
1535 eventlist = stb_getchainevent( evtvic, STB_CTK_BEST_AGR, headagr );
1536 stb_debug_stab( stbfig, evtvic, eventlist );
1537
1538 alwaysagrlist = stb_diftdomain( stbfig, evtvic, eventlist );
1539 testagrlist = subchain( eventlist, alwaysagrlist );
1540
1541 stb_log_chain( stbfig, alwaysagrlist,
1542 "agressors located on another clock domain"
1543 );
1544 if( ( stbfig->CTKMODE & STB_CTK_OBSERVABLE ) == STB_CTK_OBSERVABLE )
1545 realagrlist = stb_overlap( stbfig,
1546 evtvic,
1547 testagrlist,
1548 STB_CTK_MARGIN,
1549 STB_OBS
1550 );
1551 else
1552 realagrlist = stb_overlap( stbfig,
1553 evtvic,
1554 testagrlist,
1555 STB_CTK_MARGIN,
1556 STB_STD
1557 );
1558
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" :
1567 "DOWN",
1568 event->ROOT->NAME
1569 );
1570 }
1571 }
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" :
1580 "DOWN",
1581 event->ROOT->NAME
1582 );
1583 }
1584 }
1585
1586 freechain( realagrlist );
1587 freechain( testagrlist );
1588 freechain( alwaysagrlist );
1589
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 );
1594
1595 level = 0l; // unused parameter : avoid a warning at compilation
1596 type = 0l; // unused parameter : avoid a warning at compilation
1597 }
1598
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;
1609 {
1610 ptype_list *ptl;
1611 ptl = getptype( node->USER, STB_CTK_OLDMINSLOPE );
1612 if( ptl )
1613 return (long) ptl->DATA ;
1614 return TTV_NOSLOPE ;
1615 }
1616
1617 long stb_getmaxoldslope( node )
1618 ttvevent_list *node;
1619 {
1620 ptype_list *ptl;
1621 ptl = getptype( node->USER, STB_CTK_OLDMAXSLOPE );
1622 if( ptl )
1623 return (long) ptl->DATA ;
1624 return TTV_NOSLOPE ;
1625 }
1626
1627 void stb_setminoldslope( node, slope )
1628 ttvevent_list *node;
1629 long slope;
1630 {
1631 ptype_list *ptl;
1632
1633 ptl = getptype( node->USER, STB_CTK_OLDMINSLOPE );
1634 if( !ptl ) {
1635 node->USER = addptype( node->USER, STB_CTK_OLDMINSLOPE, NULL );
1636 ptl = node->USER;
1637 }
1638
1639 ptl->DATA = (void*) slope;
1640 }
1641
1642 void stb_setmaxoldslope( node, slope )
1643 ttvevent_list *node;
1644 long slope;
1645 {
1646 ptype_list *ptl;
1647
1648 ptl = getptype( node->USER, STB_CTK_OLDMAXSLOPE );
1649 if( !ptl ) {
1650 node->USER = addptype( node->USER, STB_CTK_OLDMAXSLOPE, NULL );
1651 ptl = node->USER;
1652 }
1653
1654 ptl->DATA = (void*) slope;
1655 }
1656
1657 void stb_cleanoldslope( node )
1658 ttvevent_list *node;
1659 {
1660 ptype_list *ptl;
1661 ptl = getptype( node->USER, STB_CTK_OLDMAXSLOPE );
1662 if( ptl )
1663 node->USER = delptype( node->USER, STB_CTK_OLDMAXSLOPE );
1664 ptl = getptype( node->USER, STB_CTK_OLDMINSLOPE );
1665 if( ptl )
1666 node->USER = delptype( node->USER, STB_CTK_OLDMINSLOPE );
1667 }
1668
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 *****************************************************************************/
1675
1676 int stb_hasslopechanged( node, ttvfig, level, type )
1677 ttvevent_list *node;
1678 ttvfig_list *ttvfig;
1679 long level;
1680 long type;
1681 {
1682 ttvdelay_list *delay;
1683 long foldmin;
1684 long foldmax;
1685 long delta;
1686
1687 delay = ttv_getnodedelay( node );
1688 if( delay ) {
1689 foldmin = stb_getminoldslope( node );
1690 foldmax = stb_getmaxoldslope( node );
1691
1692 if( foldmax == TTV_NOSLOPE || foldmin == TTV_NOSLOPE )
1693 return STB_UNK;
1694
1695 delta = foldmin - delay->FMIN ;
1696 if( delta < 0 ) delta = -delta;
1697 if( delta >= STB_CTK_MINSLOPECHANGE )
1698 return STB_YES;
1699
1700 delta = foldmax - delay->FMAX ;
1701 if( delta < 0 ) delta = -delta;
1702 if( delta >= STB_CTK_MINSLOPECHANGE )
1703 return STB_YES;
1704
1705 return STB_NO;
1706 }
1707
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
1711 return STB_UNK;
1712 }
1713
1714 /*****************************************************************************
1715 * fonction stb_saveslope() *
1716 ******************************************************************************
1717 * Sauvegarde tous les fronts de la figure. *
1718 *****************************************************************************/
1719
1720 void stb_saveslope( node, ttvfig, level, type )
1721 ttvevent_list *node;
1722 ttvfig_list *ttvfig;
1723 long level;
1724 long type;
1725 {
1726 chain_list *scan;
1727 ttvdelay_list *delay;
1728 ptype_list *ptype;
1729 ttvline_list *line;
1730
1731 if((type & TTV_FIND_LINE) == TTV_FIND_LINE)
1732 {
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 ;
1737 else
1738 scan = NULL ;
1739 }
1740 else
1741 {
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 ;
1746 else
1747 scan = NULL ;
1748 }
1749
1750 delay = ttv_getnodedelay( node );
1751 if( delay ) {
1752 stb_setminoldslope( node, delay->FMIN );
1753 stb_setmaxoldslope( node, delay->FMAX );
1754 }
1755
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 ) )
1760 continue ;
1761
1762 node = line->ROOT;
1763 delay = ttv_getnodedelay( node );
1764 if( delay ) {
1765 stb_setminoldslope( node, delay->FMIN );
1766 stb_setmaxoldslope( node, delay->FMAX );
1767 }
1768 }
1769 }
1770
1771 /*****************************************************************************
1772 * fonction stb_needeval() *
1773 ******************************************************************************
1774 * Indique si le node doit être réévalué. Renvoie STB_YES, STB_NO ou STB_UNK. *
1775 *****************************************************************************/
1776
1777 int stb_needeval( ttvfig, level, node, type, mode, headagr )
1778 ttvfig_list *ttvfig ;
1779 long level ;
1780 ttvevent_list *node ;
1781 long type ;
1782 char mode ;
1783 chain_list *headagr ;
1784 {
1785 ttvline_list *line ;
1786 ttvevent_list *nodefrom ;
1787 int thereisunk = 0;
1788 chain_list *scan;
1789 chain_list *chain;
1790 rcxparam *param;
1791 int i;
1792 ttvsig_list *signal;
1793 ptype_list *ptype;
1794
1795 if((type & TTV_FIND_LINE) == TTV_FIND_LINE)
1796 {
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 ;
1800 }
1801 else
1802 {
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 ;
1806 }
1807
1808 for(; line != NULL ; line = line->NEXT)
1809 {
1810 if( ((line->TYPE & TTV_LINE_RC) == TTV_LINE_RC) ||
1811 !ttv_islinelevel( ttvfig, line, level ) )
1812 continue ;
1813
1814 nodefrom = line->NODE;
1815
1816 switch ( stb_hasslopechanged( nodefrom, ttvfig, level, type ) ) {
1817 case STB_YES :
1818 return STB_YES;
1819 break;
1820 case STB_NO :
1821 break;
1822 case STB_UNK :
1823 thereisunk=1;
1824 break;
1825 }
1826 }
1827
1828 for( scan = headagr ; scan ; scan = scan->NEXT ) {
1829
1830 param = (rcxparam*)scan->DATA;
1831 signal = stb_getttvsigrcxparam( param );
1832 if( !signal )
1833 continue;
1834
1835 if((type & TTV_FIND_LINE) == TTV_FIND_LINE)
1836 {
1837 ttv_expfigsig (ttvfig,signal,level,ttvfig->INFO->LEVEL,
1838 TTV_STS_CLS_FED|TTV_STS_DUAL_FED, TTV_FILE_DTX);
1839 }
1840 else
1841 {
1842 ttv_expfigsig (ttvfig,signal,level,ttvfig->INFO->LEVEL,
1843 TTV_STS_CL_PJT|TTV_STS_DUAL_PJT, TTV_FILE_TTX);
1844 }
1845
1846 for( i=0; i <=1 ; i++ ) {
1847
1848 nodefrom = &(signal->NODE[i]);
1849
1850 switch ( stb_hasslopechanged( nodefrom, ttvfig, level, type ) ) {
1851 case STB_YES :
1852 return STB_YES;
1853 break;
1854 case STB_NO :
1855 break;
1856 case STB_UNK :
1857 thereisunk=1;
1858 break;
1859 }
1860
1861 if((type & TTV_FIND_LINE) == TTV_FIND_LINE)
1862 {
1863 if((ptype = getptype(node->USER,TTV_NODE_DUALLINE)) != NULL)
1864 chain = (chain_list *)ptype->DATA ;
1865 else
1866 chain = NULL ;
1867 }
1868 else
1869 {
1870 if((ptype = getptype(node->USER,TTV_NODE_DUALPATH)) != NULL)
1871 chain = (chain_list *)ptype->DATA ;
1872 else
1873 chain = NULL ;
1874 }
1875
1876 for( ; chain ; chain = chain->NEXT ) {
1877
1878 line = (ttvline_list *)chain->DATA ;
1879
1880 if( ((line->TYPE & TTV_LINE_RC) != TTV_LINE_RC) ||
1881 !ttv_islinelevel( ttvfig, line, level ) )
1882 continue ;
1883
1884 nodefrom = line->ROOT;
1885 switch ( stb_hasslopechanged( nodefrom, ttvfig, level, type ) ) {
1886 case STB_YES :
1887 return STB_YES;
1888 break;
1889 case STB_NO :
1890 break;
1891 case STB_UNK :
1892 thereisunk=1;
1893 break;
1894 }
1895 }
1896 }
1897 }
1898
1899 mode=0; // unused parameter : avoid a warning at compilation
1900
1901 if( thereisunk == 1 )
1902 return STB_UNK;
1903 return STB_NO;
1904 }
1905
1906 void stb_remove_input( ttvfig_list *ttvfig, ttvsig_list *ttvsig, long level, chain_list *headagr )
1907 {
1908 chain_list *toclean ;
1909 chain_list *chain ;
1910 rcxparam *param ;
1911
1912 toclean = stb_mark_input( ttvfig, ttvsig, level );
1913
1914 for( chain = headagr ; chain ; chain = chain->NEXT ) {
1915
1916 param = (rcxparam*)(chain->DATA);
1917
1918 ttvsig = stb_getttvsigrcxparam( param );
1919
1920 if( ttvsig ) {
1921 if( stb_is_mark_input( ttvsig ) ) {
1922 param->ACTIF = RCX_QUIET ;
1923 }
1924 }
1925 }
1926
1927 stb_clean_mark_input(toclean);
1928 }
1929
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;
1936 long level ;
1937 long type ;
1938 char mode ;
1939 long *deltamax ;
1940 int iteration ;
1941 int debugmode ;
1942 {
1943 int res = 0 ;
1944 char *insname;
1945 losig_list *sigvic;
1946 chain_list *chainfig;
1947 chain_list *headagr;
1948 lofig_list *figvic;
1949
1950 chain_list *chain;
1951 rcxparam *param;
1952 ttvsig_list *ttvsig;
1953 int enablenode;
1954
1955 stb_ctkprint( 0, "Computing delays for node %s %s (netname=%s)\n",
1956 (node->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ? "UP" : "DOWN",
1957 node->ROOT->NAME,
1958 node->ROOT->NETNAME
1959 );
1960
1961 if( debugmode ) {
1962 enablenode = 0 ;
1963 if( getptype( node->ROOT->USER, STB_MARK_DEBUG ) )
1964 enablenode = 1 ;
1965 }
1966 else
1967 enablenode = 1 ;
1968
1969 if( enablenode ) {
1970 sigvic = ttv_getlosigfromevent( stbfig->FIG,
1971 node->ROOT,
1972 &insname,
1973 &chainfig,
1974 &figvic
1975 );
1976 }
1977 else {
1978 sigvic = NULL ;
1979 insname = NULL ;
1980 figvic = NULL ;
1981 chainfig = NULL ;
1982 }
1983
1984 if( sigvic ) {
1985
1986 headagr = rcx_getagrlist( figvic, sigvic, insname, chainfig );
1987 freechain( chainfig );
1988
1989 if( headagr ) {
1990
1991 stb_fillttvsigrcxparam( stbfig->FIG, level, type, headagr );
1992
1993 if( ( stbfig->CTKMODE & STB_CTK_WORST ) == STB_CTK_WORST ) {
1994 stb_fillinactifrcxparam( stbfig->FIG, node, headagr, 'N' );
1995 if( iteration > 0 )
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 );
1999 }
2000 else {
2001 stb_fillactifrcxparam( stbfig->FIG, node, headagr, 'N' );
2002 if( iteration > 0 )
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 );
2006 }
2007 }
2008 else {
2009 stb_ctkprint( 0, "-> No agressor.\n" );
2010 stb_debug_stab( stbfig, node, NULL );
2011 }
2012 }
2013 else {
2014 headagr = NULL;
2015 stb_debug_stab( stbfig, node, NULL );
2016 }
2017
2018 stb_saveslope( node, stbfig->FIG, level, type );
2019 if( enablenode == 1 && (
2020 res ||
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
2023 )
2024 ) {
2025
2026 if( CTK_LOGFILE ) {
2027
2028 stb_ctkprint( 0,
2029 "*** Aggressor for computing %s %s\n",
2030 (node->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ? "UP" : "DW",
2031 node->ROOT->NAME
2032 );
2033
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" );
2039 else
2040 stb_ctkprint( 0, " " );
2041 if( ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST )
2042 stb_ctkprint( 0, "W " );
2043 else
2044 stb_ctkprint( 0, " " );
2045 stb_ctkprint( 0,
2046 "%s (%s)\n",
2047 ttvsig ? ttvsig->NAME : "-no ttvsig-",
2048 rcx_getsigname( param->SIGNAL )
2049 );
2050
2051 }
2052 }
2053 *deltamax = ttv_calcnodedelayslope(stbfig->FIG,level,node,type,mode) ;
2054 STBCTK_NBDELAYCALC++;
2055 }
2056 else
2057 ttv_updatenodedelayslope( stbfig->FIG,level,node,type,mode );
2058
2059 if( headagr ) {
2060
2061 stb_delttvsigrcxparam( headagr );
2062 rcx_freeagrlist( figvic, sigvic, headagr );
2063
2064 }
2065
2066 stb_set_min_slope(stbfig->FIG, node, level, 2);
2067 stb_release_fast_nodepair(node);
2068
2069 /*
2070 if( rcn_islock_signal( figvic, sigvic ) == YES )
2071 printf( "lock\n" );
2072 */
2073 return(res) ;
2074 }
2075
2076 /*****************************************************************************
2077 * fonction stb_calcctkdelay() *
2078 *****************************************************************************/
2079 int stb_calcctkdelay(stbfig ,deltamax, iteration )
2080 stbfig_list *stbfig;
2081 long *deltamax;
2082 int iteration;
2083 {
2084 ttvevent_list *ptevent;
2085 chain_list *chain;
2086 long level ;
2087 long type = 0 ;
2088 char mode ;
2089 int res = 0 ;
2090 long delta = 0;
2091 int pb_max, pb_cur;
2092 static int debugmode=0;
2093
2094 STBCTK_NBDELAYCALC=0;
2095
2096 if( deltamax ) *deltamax = 0;
2097
2098 if (stbfig->GRAPH == STB_RED_GRAPH)
2099 {
2100 type = TTV_FIND_PATH ;
2101 fflush( stdout );
2102 fprintf( stderr, "\n*** Error in STB/CTK: Crosstalk analysis requires detailed graph analysis.\n" );
2103 EXIT(1);
2104 }
2105 else if (stbfig->GRAPH == STB_DET_GRAPH)
2106 {
2107 type = TTV_FIND_LINE ;
2108 }
2109
2110 type |= TTV_FIND_MIN | TTV_FIND_MAX ;
2111
2112 mode = TTV_MODE_DELAY ;
2113
2114 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
2115 level = stbfig->FIG->INFO->LEVEL ;
2116 else
2117 level = 0 ;
2118
2119 if( iteration == 0 ) {
2120 debugmode = stb_init_debug_node( stbfig, level, type );
2121 }
2122
2123 for(chain = stbfig->NODE, pb_max=0; chain ; chain = chain->NEXT, pb_max++ );
2124
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 );
2128
2129 ptevent = (ttvevent_list *)chain->DATA;
2130
2131 if( !ptevent->INLINE ||
2132 ( ptevent->INLINE &&
2133 (ptevent->INLINE->TYPE & TTV_LINE_RC) != TTV_LINE_RC )
2134 )
2135 {
2136 if(stb_calcctkdelaynode(stbfig,ptevent,level,type,mode, &delta, iteration, debugmode)
2137 != 0)
2138 res++ ;
2139 if( deltamax ) {
2140 if( delta > *deltamax )
2141 *deltamax = delta;
2142 }
2143 }
2144 if( NBPTYPE > 0l )
2145 printf( "ptevent=%p NBPTYPE %ld\n", ptevent, NBPTYPE );
2146 }
2147
2148 return(res) ;
2149 }
2150
2151 void stb_ctk_env(void)
2152 {
2153 char *env;
2154 long t;
2155 char *ptend;
2156 double d;
2157 char valid;
2158
2159 STB_CTK_MINSLOPECHANGE = 2 * TTV_UNIT ;
2160 CTK_LOGFILE = NULL;
2161
2162 env = getenv("CTK_LOGFILE");
2163 if( env ) {
2164 CTK_LOGFILE = mbkfopen( env, NULL, WRITE_TEXT );
2165 }
2166 env = getenv("CTK_LOGLEVEL");
2167 if( env ) {
2168 CTK_LOGLEVEL = atoi(env);
2169 }
2170
2171 CTK_REPORT_DELTA_DELAY_MIN=V_INT_TAB[__CTK_REPORT_DELTA_DELAY_MIN].VALUE;
2172
2173 CTK_REPORT_DELTA_SLOPE_MIN=V_INT_TAB[__CTK_REPORT_DELTA_SLOPE_MIN].VALUE;
2174
2175 CTK_REPORT_NOISE_MIN=V_INT_TAB[__CTK_REPORT_NOISE_MIN].VALUE;
2176
2177 if(V_FLOAT_TAB[__CTK_REPORT_CTK_MIN].VALUE<0.0 || V_FLOAT_TAB[__CTK_REPORT_CTK_MIN].VALUE>100.0 )
2178 stb_ctk_error( 4,
2179 "Bad value for CTK_REPORT_CTK_MIN. Must be a floating number.\n"
2180 );
2181 CTK_REPORT_CTK_MIN=V_FLOAT_TAB[__CTK_REPORT_CTK_MIN].VALUE;
2182
2183 if(V_FLOAT_TAB[__STB_NOISE_DEFAULT_RESI].VALUE<0.0 )
2184 stb_ctk_error( 4,
2185 "Bad value for STB_NOISE_DEFAULT_RESI. Must be a floating number.\n"
2186 );
2187 STB_NOISE_DEFAULT_RESI=V_FLOAT_TAB[__STB_NOISE_DEFAULT_RESI].VALUE;
2188
2189 if( V_BOOL_TAB[__STB_CTK_FASTMODE].VALUE ) {
2190 valid = 'y';
2191 STB_CTK_FASTMODE=1;
2192 } else {
2193 valid = 'y';
2194 STB_CTK_FASTMODE=0;
2195 }
2196
2197 STB_CTK_MARGIN=V_INT_TAB[__STB_CTK_MARGIN].VALUE*TTV_UNIT;
2198
2199 STB_CTK_MINSLOPECHANGE=V_INT_TAB[__STB_CTK_MINSLOPECHANGE].VALUE*TTV_UNIT;
2200
2201 STB_CTK_MAXLASTITER=V_INT_TAB[__STB_CTK_MAXLASTITER].VALUE;
2202
2203 stb_ctk_set_min_score( V_INT_TAB[__STB_CTK_MIN_NOISE].VALUE, -1, -1, -1 );
2204
2205 stb_ctk_set_min_score( -1, V_INT_TAB[__STB_CTK_MIN_CTK].VALUE, -1, -1 );
2206
2207 stb_ctk_set_min_score( -1, -1, V_INT_TAB[__STB_CTK_MIN_INTERVAL].VALUE, -1 );
2208
2209 stb_ctk_set_min_score( -1, -1, -1, V_INT_TAB[__STB_CTK_MIN_ACTIVITY].VALUE );
2210
2211 stb_ctk_set_coef_score( V_INT_TAB[__STB_CTK_COEF_NOISE].VALUE, -1, -1, -1 );
2212
2213 stb_ctk_set_coef_score( -1, V_INT_TAB[__STB_CTK_COEF_CTK].VALUE, -1, -1 );
2214
2215 stb_ctk_set_coef_score( -1, -1, V_INT_TAB[__STB_CTK_COEF_INTERVAL].VALUE, -1 );
2216
2217 stb_ctk_set_coef_score( -1, -1, -1, V_INT_TAB[__STB_CTK_COEF_ACTIVITY].VALUE );
2218
2219 }
2220
2221 /*****************************************************************************
2222 * fonction stb_ctk_clean() *
2223 *****************************************************************************/
2224
2225 void stb_ctk_clean( stbfig )
2226 stbfig_list *stbfig;
2227 {
2228 chain_list *chain;
2229 ttvevent_list *ptevent;
2230
2231 for(chain = stbfig->NODE ; chain ; chain = chain->NEXT )
2232 {
2233 ptevent = (ttvevent_list *)chain->DATA;
2234 stb_cleanagressiontype( ptevent->ROOT );
2235 }
2236
2237 CtkMutexFree(stbfig->FIG);
2238 }
2239
2240 /*****************************************************************************
2241 * fonction stb_ctk_clean_oldslope() *
2242 *****************************************************************************/
2243
2244 void stb_ctk_clean_oldslope( stbfig )
2245 stbfig_list *stbfig;
2246 {
2247 chain_list *chain;
2248 ttvevent_list *ptevent;
2249
2250 for(chain = stbfig->NODE ; chain ; chain = chain->NEXT )
2251 {
2252 ptevent = (ttvevent_list *)chain->DATA;
2253 stb_cleanoldslope( ptevent );
2254 }
2255 }
2256
2257 /******************************************************************************\
2258 Construit les tables de hash dans la hiérarchie TTV.
2259 \******************************************************************************/
2260 void stb_built_ttv_htab( ttvfig_list *rootfig )
2261 {
2262 ttv_builthtabfig( rootfig, TTV_STS_L | TTV_STS_S );
2263 }
2264
2265 /******************************************************************************\
2266 Remet à jour les infos de stb, notament les holorloges avec les nouveaux délais.
2267 \******************************************************************************/
2268 void stb_resync( stbfig_list *stbfig )
2269 {
2270 chain_list *chain;
2271 ttvevent_list *ttvnode;
2272 stbnode *stbnode;
2273 stbck *ptstbck;
2274
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 ;
2284 }
2285 }
2286 ttvnode->USER=testanddelptype (ttvnode->USER, STB_NODE_CLOCK);
2287 }
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 );
2292 }*/
2293
2294 if(stbfig->GRAPH == STB_DET_GRAPH)
2295 stb_propagate_signal(stbfig, stbfig->CLOCK);
2296
2297 }
2298
2299 /******************************************************************************\
2300 fonction stb_ctk()
2301 Détermine les agressions et calcule les délais élémentaires en présence de
2302 crosstalk.
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 \******************************************************************************/
2307
2308
2309 int stb_ctk(stbfig)
2310 stbfig_list *stbfig;
2311 {
2312 int i ;
2313 int changedelay=1 ;
2314 char oldsilent ;
2315 long deltafrontmax=0;
2316 char doitagain;
2317 int iterwithoutagr=0, level;
2318 stbfile *report;
2319 stb_ctk_stat *stat;
2320 char buf[80];
2321
2322 oldsilent = STB_SILENT ;
2323 STB_SILENT = 'Y' ;
2324
2325 #ifdef AVERTEC_LICENSE
2326 if(avt_givetoken("HITAS_LICENSE_SERVER","ctk")!=AVT_VALID_TOKEN)
2327 EXIT(1) ;
2328 #endif
2329
2330 rcx_crosstalkactive( RCX_MILLER );
2331 rcx_crosstalk_analysis( YES );
2332
2333 // pour les apis
2334 STB_COM_STBFIG=stbfig;
2335 STB_COM=stb_communication;
2336
2337 stb_built_ttv_htab( stbfig->FIG );
2338
2339 stb_ctk_clean(stbfig) ;
2340
2341 CtkMutexInit( stbfig->FIG );
2342
2343 if( stbfig->CTKMODE & STB_CTK_REPORT )
2344 report = stb_info_open( stbfig );
2345 else
2346 report = NULL ;
2347
2348 CTK_PROGRESSBAR( 0, 1, 0, "Computing initial state." );
2349
2350 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
2351 level = stbfig->FIG->INFO->LEVEL ;
2352 else
2353 level = 0 ;
2354 stb_setupall_slopes(stbfig, level);
2355
2356 stb_calcctkdelay( stbfig, NULL, 0 ) ;
2357 stb_resync( stbfig );
2358 stb_cleanup_fast_nodepair(stbfig);
2359
2360 stb_ctk_drive_iteration_report(stbfig, 0);
2361
2362 CTK_PROGRESSBAR( 0, 1, 0, "Crosstalk analysis." );
2363
2364 trcflushdelaycache();
2365 i=0;
2366 do
2367 {
2368 i++ ;
2369 stb_ctkprint( 0, "\nItération %d\n\n", i );
2370
2371 stb_ctk_drive_iteration_report_save_last_iteration_info(stbfig);
2372
2373 // stb_clean_relax_correction_info(stbfig);
2374
2375 stb_relaxation(stbfig) ;
2376
2377 changedelay = stb_calcctkdelay(stbfig, &deltafrontmax, i) ;
2378 stb_resync( stbfig );
2379 stb_cleanup_fast_nodepair(stbfig);
2380
2381 sprintf( buf, " -> %d signals evaluated", STBCTK_NBDELAYCALC );
2382 CTK_PRINTINFO( buf );
2383
2384 if( ( stbfig->CTKMODE & STB_CTK_WORST ) == STB_CTK_WORST )
2385 sprintf( buf, " -> %d signals with one or more agression removed",
2386 changedelay
2387 );
2388 else
2389 sprintf( buf, " -> %d signals with one or more new agression",
2390 changedelay
2391 );
2392 CTK_PRINTINFO( buf );
2393
2394 sprintf( buf, " -> Maximum slope variation : %.1fps",
2395 deltafrontmax/TTV_UNIT
2396 );
2397 CTK_PRINTINFO( buf );
2398
2399 stb_ctk_drive_iteration_report(stbfig, i);
2400
2401 // Condition de sortie de la boucle
2402 if( changedelay ) {
2403 doitagain=1;
2404 iterwithoutagr=0;
2405 }
2406 else {
2407 iterwithoutagr++;
2408 if( deltafrontmax <= STB_CTK_MINSLOPECHANGE ||
2409 iterwithoutagr >= STB_CTK_MAXLASTITER )
2410 doitagain=0;
2411 else
2412 doitagain=1;
2413 }
2414
2415 #ifdef AVERTEC_LICENSE
2416 if(avt_givetoken("HITAS_LICENSE_SERVER","ctk")!=AVT_VALID_TOKEN)
2417 EXIT(1) ;
2418 #endif
2419
2420 trcflushdelaycache();
2421 }
2422 while( doitagain && i < V_INT_TAB[__STB_CTK_MAX_ITER].VALUE );
2423
2424 stb_ctk_drive_agression( stbfig );
2425
2426 stb_cleanup_slopes(stbfig);
2427
2428 if( report ) {
2429 stat = stb_ctk_fill_stat( stbfig, 1 );
2430 stb_ctk_drive_stat( report, stbfig, stat );
2431 stb_info_close( report );
2432 }
2433
2434 //stb_display_mem( stbfig );
2435 CTK_PROGRESSBAR( 0, 1, 0, "Driving crosstalk file." );
2436
2437 if( (stbfig->CTKMODE & STB_CTX_REPORT) == STB_CTX_REPORT )
2438 ttv_ctxdrive( stbfig->FIG );
2439
2440 STB_SILENT = oldsilent ;
2441
2442 stb_ctk_clean_oldslope( stbfig );
2443
2444 ttv_freehtabfig( stbfig->FIG, TTV_STS_L | TTV_STS_S );
2445
2446 STB_COM_STBFIG=NULL;
2447 STB_COM=NULL;
2448
2449 rcx_crosstalkactive( RCX_NOCROSSTALK );
2450 rcx_crosstalk_analysis( NO );
2451
2452 ctk_calc_constraint( stbfig );
2453
2454 stb_clean_ttvfig( stbfig );
2455
2456 return(i) ;
2457 }
2458
2459 stbfile* stb_info_open( stbfig_list *stbfig )
2460 {
2461 static stbfile file;
2462
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 );
2467 }
2468
2469 stb_info( &file,
2470 "# Crosstalk information for circuit %s.\n\n",
2471 stbfig->FIG->INFO->FIGNAME
2472 );
2473
2474 file.STBFIG = stbfig ;
2475
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() );
2485 return &file;
2486 }
2487
2488 void stb_info( stbfile *file, ... )
2489 {
2490 va_list index;
2491 char *fmt;
2492
2493 if( !file ) return;
2494
2495 va_start( index, file );
2496 fmt = va_arg( index, char* );
2497
2498 vfprintf( file->FD, fmt, index );
2499 }
2500
2501 void stb_info_close( stbfile *file )
2502 {
2503 if( !file ) return;
2504
2505 fclose( file->FD );
2506 }
2507
2508 void stb_drive_line( stbfile *report,
2509 ttvfig_list *ttvfig,
2510 ttvline_list *line
2511 )
2512 {
2513 float dmin;
2514 float dmax;
2515 float fmin;
2516 float fmax;
2517 float dmincc;
2518 float dmaxcc;
2519 float fmincc;
2520 float fmaxcc;
2521 char title=0;
2522
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;
2531
2532 if( abs(dmin-dmincc) >= CTK_REPORT_DELTA_DELAY_MIN &&
2533 ttv_getdelaymin( line ) != TTV_NOTIME ) {
2534 if( title==0 ) {
2535 stb_info( report,
2536 " %-38s %-38s\n",
2537 stb_display_ttvevent( ttvfig, line->NODE ),
2538 stb_display_ttvevent( ttvfig, line->ROOT )
2539 );
2540 title=1;
2541 }
2542 stb_info( report, " delay min : %.1f -> %.1f\n", dmin, dmincc );
2543 }
2544 if( abs(dmax-dmaxcc) >= CTK_REPORT_DELTA_DELAY_MIN &&
2545 ttv_getdelaymax( line ) != TTV_NOTIME ) {
2546 if( title==0 ) {
2547 stb_info( report,
2548 " %-38s %-38s\n",
2549 stb_display_ttvevent( ttvfig, line->NODE ),
2550 stb_display_ttvevent( ttvfig, line->ROOT )
2551 );
2552 title=1;
2553 }
2554 stb_info( report, " delay max : %.1f -> %.1f\n", dmax, dmaxcc );
2555 }
2556 if( abs(fmin-fmincc) >= CTK_REPORT_DELTA_SLOPE_MIN &&
2557 ttv_getslopemin( line ) != TTV_NOSLOPE ){
2558 if( title==0 ) {
2559 stb_info( report,
2560 " %-38s %-38s\n",
2561 stb_display_ttvevent( ttvfig, line->NODE ),
2562 stb_display_ttvevent( ttvfig, line->ROOT )
2563 );
2564 title=1;
2565 }
2566 stb_info( report, " slope min : %.1f -> %.1f\n", fmin, fmincc );
2567 }
2568 if( abs(fmax-fmaxcc) >= CTK_REPORT_DELTA_SLOPE_MIN &&
2569 ttv_getslopemax( line ) != TTV_NOSLOPE ){
2570 if( title==0 ) {
2571 stb_info( report,
2572 " %-38s %-38s\n",
2573 stb_display_ttvevent( ttvfig, line->NODE ),
2574 stb_display_ttvevent( ttvfig, line->ROOT )
2575 );
2576 title=1;
2577 }
2578 stb_info( report, " slope max : %.1f -> %.1f\n", fmax, fmaxcc );
2579 }
2580
2581 ttvfig = NULL; //unused parameter
2582 }
2583
2584 char* stb_display_ttvevent( ttvfig_list *ttvfig, ttvevent_list *node )
2585 {
2586 static int i=0;
2587 static char tab[2][1024];
2588 char ttvname[1024];
2589 char netname[1024];
2590 i=(i+1)%2;
2591
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",
2597 ttvname
2598 );
2599 }
2600 else {
2601 sprintf( tab[i], "%s %s (%s)",
2602 ( node->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ? "UP": "DW",
2603 ttvname,
2604 netname
2605 );
2606 }
2607
2608 return tab[i];
2609 }
2610
2611 char* stb_display_ttvevent_noise( ttvfig_list *ttvfig, ttvevent_list *node )
2612 {
2613 static int i=0;
2614 static char tab[2][1024];
2615 char ttvname[1024];
2616 char netname[1024];
2617 i=(i+1)%2;
2618
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",
2624 ttvname
2625 );
2626 }
2627 else {
2628 sprintf( tab[i], "%s %s (%s)",
2629 ( node->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ? "LOW ": "HIGH",
2630 ttvname,
2631 netname
2632 );
2633 }
2634
2635 return tab[i];
2636 }
2637
2638 char* stb_display_ttvsig( ttvfig_list *fig, ttvsig_list *ttvsig )
2639 {
2640 static int i=0;
2641 static char tab[2][1024];
2642 char ttvname[1024];
2643 char netname[1024];
2644 i=(i+1)%2;
2645
2646 ttv_getsigname( fig, ttvname, ttvsig );
2647 ttv_getnetname( fig, netname, ttvsig );
2648 if( strcmp( netname, ttvname ) == 0 ) {
2649 sprintf( tab[i], "%s", ttvname );
2650 }
2651 else {
2652 sprintf( tab[i], "%s (%s)", ttvname, netname );
2653 }
2654
2655 return tab[i];
2656 }
2657
2658 stb_ctk_detail* stb_ctk_get_detail( stbfig_list *stbfig,
2659 ttvevent_list *ptevent
2660 )
2661 {
2662 losig_list *sigvic;
2663 char *insname;
2664 chain_list *chainfig;
2665 rcxparam *param;
2666 lofig_list *figvic;
2667 stb_ctk_detail *detail;
2668 stb_ctk_detail_agr_list *detail_list;
2669 long level ;
2670 long type=0 ;
2671 chain_list *scanagr;
2672 chain_list *headagr;
2673 RCXFLOAT cm;
2674 RCXFLOAT dcm;
2675 RCXFLOAT cc;
2676 rcxmodagr *tabagr;
2677 int nbagr;
2678 int n;
2679 ttvsig_list *ttvagr;
2680 int agridx;
2681 float vth ;
2682
2683 if (stbfig->GRAPH == STB_RED_GRAPH) {
2684
2685 type = TTV_FIND_PATH ;
2686 fflush( stdout );
2687 fprintf( stderr, "\n*** Error in STB/CTK: Crosstalk analysis requires detailed graph analysis.\n" );
2688 EXIT(1);
2689 }
2690 else if (stbfig->GRAPH == STB_DET_GRAPH) {
2691
2692 type = TTV_FIND_LINE ;
2693 }
2694
2695 type |= TTV_FIND_MIN | TTV_FIND_MAX ;
2696
2697 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
2698 level = stbfig->FIG->INFO->LEVEL ;
2699 else
2700 level = 0 ;
2701
2702 if( ptevent->INLINE &&
2703 (ptevent->INLINE->TYPE & TTV_LINE_RC) == TTV_LINE_RC
2704 )
2705 return NULL;
2706
2707 sigvic = ttv_getlosigfromevent( stbfig->FIG,
2708 ptevent->ROOT,
2709 &insname,
2710 &chainfig,
2711 &figvic
2712 );
2713 if( !sigvic ) return NULL;
2714
2715 detail = (stb_ctk_detail*)mbkalloc( sizeof( stb_ctk_detail ) );
2716 detail->NODE = ptevent;
2717 detail->LOSIG = sigvic;
2718 detail->CM = 0.0;
2719 detail->CC = 0.0;
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 ;
2727
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' );
2732 else
2733 stb_fillactifrcxparam( stbfig->FIG, ptevent, headagr, 'Y' );
2734
2735 tabagr = rcx_buildtabagr( figvic,
2736 sigvic,
2737 sizeof( rcxmodagr ),
2738 &nbagr,
2739 &cm
2740 );
2741
2742 cc = 0.0;
2743 dcm = 0.0;
2744 for( n = 0 ; n < nbagr ; n++ ) {
2745 cc = cc+tabagr[n].CLOCALE + tabagr[n].CGLOBALE;
2746 dcm = dcm + tabagr[n].CGLOBALE ;
2747 }
2748
2749 detail->CM = cm - dcm ;
2750 detail->CC = cc ;
2751
2752 for( scanagr = headagr ; scanagr ; scanagr = scanagr->NEXT ) {
2753 param = (rcxparam*)scanagr->DATA;
2754
2755 detail_list = ( stb_ctk_detail_agr_list* )
2756 mbkalloc( sizeof( stb_ctk_detail_agr_list ) );
2757
2758 detail_list->NEXT = detail->AGRLIST ;
2759 detail->AGRLIST = detail_list ;
2760
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;
2765
2766 ttvagr = stb_getttvsigrcxparam(param);
2767 detail_list->TTVAGR = ttvagr;
2768 if( ttvagr )
2769 ttvagr->USER = addptype( ttvagr->USER, STB_CTK_DETAIL, detail_list );
2770 else {
2771 detail_list->NOISE_RISE_PEAK = 1;
2772 detail_list->NOISE_FALL_PEAK = 1;
2773 }
2774
2775 detail_list->NETNAME = (char*)mbkalloc( sizeof( char ) * 1024 );
2776 sprintf( detail_list->NETNAME,
2777 "%s.%s",
2778 param->INSNAME,
2779 rcx_getsigname( param->SIGNAL )
2780 );
2781
2782 if( ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST )
2783 detail_list->ACT_BEST = 1;
2784 else
2785 detail_list->ACT_BEST = 0;
2786
2787 if( ( param->ACTIF & RCX_MTX_BEST ) == RCX_MTX_BEST )
2788 detail_list->ACT_MUTEX_BEST = 1 ;
2789 else
2790 detail_list->ACT_MUTEX_BEST = 0 ;
2791
2792 if( ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST )
2793 detail_list->ACT_WORST = 1;
2794 else
2795 detail_list->ACT_WORST = 0;
2796
2797 if( ( param->ACTIF & RCX_MTX_WORST ) == RCX_MTX_WORST )
2798 detail_list->ACT_MUTEX_WORST = 1 ;
2799 else
2800 detail_list->ACT_MUTEX_WORST = 0 ;
2801
2802 agridx = rcx_gettabagrindex( param->SIGNAL );
2803 detail_list->CC = tabagr[agridx].CLOCALE + tabagr[agridx].CGLOBALE ;
2804 }
2805
2806 rcx_freetabagr( tabagr, sizeof( rcxmodagr ), nbagr );
2807
2808 detail->AGRLIST = (stb_ctk_detail_agr_list*)
2809 reverse( (chain_list*)detail->AGRLIST );
2810
2811 stb_ctk_noise_node( stbfig,
2812 figvic,
2813 detail,
2814 headagr,
2815 level,
2816 type,
2817 &detail->MODEL_OVR,
2818 &detail->NOISE_MAX_OVR,
2819 &detail->NOISE_OVR,
2820 &detail->MODEL_UND,
2821 &detail->NOISE_MAX_UND,
2822 &detail->NOISE_UND
2823 );
2824
2825 vth = stb_ctk_signal_threshold( stbfig, detail->NODE );
2826 if( vth < 0.0 )
2827 vth = stb_ctk_signal_threshold_from_input( stbfig, detail->NODE ) ;
2828 detail->NOISE_VTH = vth ;
2829
2830 stb_delttvsigrcxparam( headagr );
2831 rcx_freeagrlist( figvic, sigvic, headagr );
2832 freechain( chainfig ); chainfig = NULL ;
2833
2834 return detail;
2835 }
2836
2837 stb_ctk_gap* stb_fill_gap( stbfig_list *stbfig, stb_ctk_detail *detail, char transition )
2838 {
2839 stb_ctk_gap *gap ;
2840 stb_ctk_detail_agr_list *agr ;
2841 chain_list *eventlist ;
2842 int node ;
2843
2844 if( transition == TTV_NODE_UP ) {
2845 node = 1 ;
2846 gap = & detail->GAP_UP ;
2847 }
2848 else {
2849 node = 0 ;
2850 gap = & detail->GAP_DW ;
2851 }
2852
2853 if( gap->FILLED )
2854 return gap ;
2855
2856 eventlist = NULL ;
2857 gap->OTHERDOMAIN = NULL ;
2858 gap->CONDACTIF = NULL ;
2859 gap->GAPACTIF = NULL ;
2860 gap->NOINFO = NULL ;
2861
2862 for( agr = detail->AGRLIST ; agr ; agr = agr->NEXT ) {
2863
2864 if( agr->TTVAGR ) {
2865 eventlist = addchain( eventlist, &( agr->TTVAGR->NODE[node] ) );
2866 }
2867 else {
2868 gap->NOINFO = addchain( gap->NOINFO, agr );
2869 }
2870 }
2871
2872 gap->OTHERDOMAIN = stb_diftdomain( stbfig, detail->NODE, eventlist );
2873 gap->CONDACTIF = subchain( eventlist, gap->OTHERDOMAIN );
2874
2875 gap->GAPACTIF = stb_overlapdev( stbfig, detail->NODE, gap->CONDACTIF, 0l );
2876 freechain( eventlist );
2877
2878 gap->FILLED = 1 ;
2879
2880 return gap ;
2881 }
2882
2883 void stb_ctk_free_detail( stbfig_list *stbfig, stb_ctk_detail *detail )
2884 {
2885 stb_ctk_detail_agr_list *list;
2886 stb_ctk_detail_agr_list *next;
2887 ttvsig_list *ttvsig;
2888 ptype_list *ptl;
2889
2890 for( list = detail->AGRLIST ; list ; list = next ) {
2891
2892 ttvsig = list->TTVAGR ;
2893 if( ttvsig ) {
2894 ptl = getptype( ttvsig->USER, STB_CTK_DETAIL );
2895 if( !ptl ) {
2896 fprintf( stderr, "fatal error in stb_ctk_free_detail().\n" );
2897 EXIT(1);
2898 }
2899 ttvsig->USER = delptype( ttvsig->USER, STB_CTK_DETAIL );
2900 }
2901
2902 next = list->NEXT ;
2903 mbkfree( list->NETNAME ) ;
2904 mbkfree( list ) ;
2905 }
2906
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 );
2912 }
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 );
2918 }
2919
2920 mbkfree( detail );
2921 stbfig=NULL;
2922 }
2923
2924 stb_ctk_detail_agr_list* stb_ctk_get_node_detail( ttvsig_list *ttvsig )
2925 {
2926 ptype_list *ptl;
2927 ptl = getptype( ttvsig->USER, STB_CTK_DETAIL );
2928 if( ptl )
2929 return (stb_ctk_detail_agr_list*)ptl->DATA;
2930 return NULL;
2931 }
2932
2933 void stb_ctk_drive_stat( stbfile *report, stbfig_list *stbfig, stb_ctk_stat *stat )
2934 {
2935 int i;
2936 ttvevent_list *event ;
2937 stb_ctk_detail *ctkdetail ;
2938
2939 CTK_PROGRESSBAR( 0, 1, 0, "Driving crosstalk report file" );
2940
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 );
2945 }
2946 stb_info( report, "EndDelay\n\n" );
2947 CTK_PROGRESSBAR( 0, stat->NBDDISPLAY, stat->NBDDISPLAY, NULL );
2948
2949 CTK_PROGRESSBAR( 0, 1, 0, "Driving detailled aggression in report file" );
2950
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 );
2958 }
2959 stb_drive_crosstalk_end( report );
2960 CTK_PROGRESSBAR( 0, stat->NBDISPLAY, stat->NBDISPLAY, NULL );
2961
2962 stb_ctk_noise_report( report, stat );
2963 }
2964
2965 int stb_drive_crosstalk_start( stbfile *report )
2966 {
2967 stb_info( report, "# Crosstalk information :\n" );
2968 stb_info( report, "# -----------------------\n\n" );
2969 stb_info( report, "BeginCrosstalk\n" );
2970 return 1;
2971 }
2972
2973 int sort_drive_detail( stb_ctk_detail_agr_list **ag1, stb_ctk_detail_agr_list**ag2 )
2974 {
2975 if( (*ag1)->CC > (*ag2)->CC ) return 1 ;
2976 if( (*ag1)->CC < (*ag2)->CC ) return -1 ;
2977 return strcmp( (*ag1)->NETNAME, (*ag2)->NETNAME );
2978 }
2979
2980 int stb_drive_crosstalk_detail( stbfile *report,
2981 stb_ctk_detail *detail,
2982 stb_ctk_tab_stat *stat
2983 )
2984 {
2985 float pct ;
2986 stb_ctk_detail_agr_list *list ;
2987 int x, y ;
2988 stb_ctk_detail_agr_list **sort_tab;
2989
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() );
2994
2995 pct = detail->CM+detail->CC > 0.0 ? detail->CC/(detail->CM+detail->CC):0.0;
2996 pct = 100.0*pct;
2997
2998 if( pct > CTK_REPORT_CTK_MIN ) {
2999
3000 stb_info( report, " Node : %s\n",
3001 stb_display_ttvevent( report->STBFIG->FIG, detail->NODE )
3002 );
3003 stb_info( report, " Ground capacitance : %fpF\n", detail->CM );
3004
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 ) );
3015
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 );
3018
3019 for( list = detail->AGRLIST, x=0 ; list ; list = list->NEXT, x++ )
3020 sort_tab[x] = list ;
3021
3022 qsort( sort_tab, x, sizeof( stb_ctk_detail_agr_list* ), (int(*)(const void*,const void*))sort_drive_detail );
3023
3024 stb_info( report, " Agressor :\n" );
3025
3026 for( y=0 ; y<x ; y++) {
3027
3028 list = sort_tab[y];
3029
3030 if( list->TTVAGR )
3031 stb_info( report, " %-65s ",
3032 stb_display_ttvsig(report->STBFIG->FIG, list->TTVAGR) );
3033 else
3034 stb_info( report, " * %-65s ", list->NETNAME );
3035
3036 if( list->ACT_BEST )
3037 stb_info( report, "B " );
3038 else {
3039 if( list->ACT_MUTEX_BEST )
3040 stb_info( report, "b " );
3041 else
3042 stb_info( report, " " );
3043 }
3044
3045 if( list->ACT_WORST )
3046 stb_info( report, "W " );
3047 else {
3048 if( list->ACT_MUTEX_WORST )
3049 stb_info( report, "w " );
3050 else
3051 stb_info( report, " " );
3052 }
3053
3054 if( list->NOISE_RISE_PEAK )
3055 stb_info( report, "R " );
3056 else {
3057 if( list->NOISE_RISE_EXCLUDED )
3058 stb_info( report, "r " );
3059 else
3060 stb_info( report, " " );
3061 }
3062
3063 if( list->NOISE_FALL_PEAK )
3064 stb_info( report, "F " );
3065 else {
3066 if( list->NOISE_FALL_EXCLUDED )
3067 stb_info( report, "f " );
3068 else
3069 stb_info( report, " " );
3070 }
3071
3072 stb_info( report, " Cc=%fpF\n", list->CC );
3073 }
3074
3075 mbkfree( sort_tab );
3076 stb_info( report, " %-65s ----------\n", "" );
3077 stb_info( report, " %-65s %f (%05.1f%%)\n",
3078 "",
3079 detail->CC,
3080 pct
3081 );
3082 }
3083 return 1;
3084 }
3085
3086 int stb_drive_crosstalk_end( stbfile *report )
3087 {
3088 stb_info( report, "EndCrosstalk\n\n" );
3089 return 1;
3090 }
3091
3092 void ctk_setprint( void (*print)( char* ) )
3093 {
3094 CTK_PRINTINFO = print ;
3095 }
3096
3097 void ctk_setprogressbar( void (*callfn)( int, int, int, char* ) )
3098 {
3099 CTK_PROGRESSBAR = callfn ;
3100 }
3101
3102 void ctk_display_event( stbfig_list *stbfig, ttvevent_list *refevent )
3103 {
3104 stbpair_list *refpair;
3105 stbpair_list *pair;
3106
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" );
3112 }
3113
3114 void ctk_calc_constraint( stbfig_list *stbfig )
3115 {
3116 long level;
3117 char mode;
3118 long type;
3119 chain_list *chain;
3120 ttvevent_list *event;
3121
3122 mode = TTV_MODE_DELAY ;
3123
3124 level = stbfig->FIG->INFO->LEVEL ;
3125 type = TTV_FIND_LINE ;
3126
3127 for( chain = stbfig->NODE ; chain ; chain = chain->NEXT ) {
3128 event = (ttvevent_list*)chain->DATA ;
3129 ttv_calcnodeconstraint( stbfig->FIG, level, event, type, mode );
3130 }
3131 }
3132
3133 void stb_ctk_set_stat( stbfig_list *stbfig, stb_ctk_stat *stat )
3134 {
3135 ptype_list *ptl ;
3136 stb_ctk_stat *old;
3137
3138 ptl = getptype( stbfig->USER, STB_CTK_STAT );
3139 if( ptl ) {
3140 old = (stb_ctk_stat*)ptl->DATA ;
3141 stb_ctk_free_stat( old );
3142 }
3143 else {
3144 stbfig->USER = addptype( stbfig->USER, STB_CTK_STAT, NULL );
3145 ptl = stbfig->USER ;
3146 }
3147
3148 ptl->DATA = stat ;
3149 }
3150
3151 stb_ctk_stat* stb_ctk_get_stat( stbfig_list *stbfig )
3152 {
3153 ptype_list *ptl ;
3154 stb_ctk_stat *stat ;
3155
3156 ptl = getptype( stbfig->USER, STB_CTK_STAT );
3157 if( ptl ) {
3158 stat = (stb_ctk_stat*)ptl->DATA ;
3159 }
3160 else {
3161 stat = NULL ;
3162 }
3163
3164 return stat ;
3165 }
3166
3167 void stb_ctk_clean_stat( stbfig_list *stbfig )
3168 {
3169 ptype_list *ptl ;
3170 stb_ctk_stat *stat ;
3171
3172 ptl = getptype( stbfig->USER, STB_CTK_STAT );
3173 if( ptl ) {
3174 stat = (stb_ctk_stat*)ptl->DATA ;
3175 stb_ctk_free_stat( stat );
3176 stbfig->USER = delptype( stbfig->USER, STB_CTK_STAT );
3177 }
3178 }
3179
3180 /******************************************************************************\
3181 stb_ctk_infos()
3182 Fill a stb_ctk_stat structure.
3183 Possibly, call user's fonction fn_xxxx for each detail corresponding to an event.
3184 \******************************************************************************/
3185
3186 stb_ctk_stat* stb_ctk_fill_stat( stbfig_list *stbfig, int fast )
3187 {
3188 stb_ctk_stat *stat ;
3189 long level;
3190
3191 stb_ctk_clean_stat( stbfig );
3192
3193 stat = mbkalloc( sizeof( stb_ctk_stat ) );
3194 stat->TAB = NULL ;
3195 stat->NBELEM = 0 ;
3196 stat->NBDISPLAY = 0 ;
3197 stat->TABD = NULL ;
3198 stat->NBDELEM = 0 ;
3199 stat->NBDDISPLAY = 0 ;
3200
3201 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
3202 level = stbfig->FIG->INFO->LEVEL ;
3203 else
3204 level = 0 ;
3205
3206 if (fast) stb_setupall_slopes(stbfig, level);
3207
3208
3209 stb_ctk_fill_stat_tab( stat, stbfig );
3210 stb_ctk_fill_stat_line( stat, stbfig );
3211
3212 //CTK_PROGRESSBAR( 0, 1, 0, "Sorting results" );
3213
3214 stb_ctk_sort_stat( stat, STB_CTK_SORT_SCORE_TOTAL );
3215 stb_ctk_sort_delay( stat, STB_CTK_SORT_ABS_DELAY, 0.0 );
3216
3217 stb_ctk_set_stat( stbfig, stat );
3218
3219 if (fast) stb_cleanup_slopes(stbfig);
3220
3221 return stat ;
3222 }
3223
3224 int stb_ctk_sort_delay_cmp( sortdelaycmp *delay1, sortdelaycmp *delay2 )
3225 {
3226 int r ;
3227 int trs1n, trs1r, trs2n, trs2r, val1, val2 ;
3228
3229 if( delay1->VALUE > delay2->VALUE ) return -1 ;
3230 if( delay1->VALUE < delay2->VALUE ) return 1 ;
3231
3232 r = strcmp( delay1->LINE->NODE->ROOT->NAME, delay2->LINE->NODE->ROOT->NAME );
3233 if( r )
3234 return r ;
3235
3236 r = strcmp( delay1->LINE->ROOT->ROOT->NAME, delay2->LINE->ROOT->ROOT->NAME );
3237 if( r )
3238 return r ;
3239
3240 if( ( delay1->LINE->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
3241 trs1n = 1 ;
3242 else
3243 trs1n = 0 ;
3244
3245 if( ( delay1->LINE->ROOT->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
3246 trs1r = 1 ;
3247 else
3248 trs1r = 0 ;
3249
3250 if( ( delay2->LINE->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
3251 trs2n = 1 ;
3252 else
3253 trs2n = 0 ;
3254
3255 if( ( delay2->LINE->ROOT->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
3256 trs2r = 1 ;
3257 else
3258 trs2r = 0 ;
3259
3260 val1 = trs1n*2+trs1r ;
3261 val2 = trs2n*2+trs2r ;
3262
3263 if( val1 < val2 )
3264 return -1 ;
3265 if( val1 > val2 )
3266 return 1 ;
3267 return 0 ;
3268 }
3269
3270 inline void filltabdelayvalue( sortdelaycmp *elem, char criterion )
3271 {
3272 float deltamax ;
3273 float deltamin ;
3274 float vnommax ;
3275 float vnommin ;
3276 float vctkmax ;
3277 float vctkmin ;
3278
3279 deltamax = 0.0 ;
3280 deltamin = 0.0 ;
3281 elem->VALUE = 0.0 ;
3282
3283 switch( criterion ) {
3284
3285 case STB_CTK_SORT_ABS_DELAY :
3286
3287 vnommax = elem->LINE->VALMAX ;
3288 vctkmax = ttv_getdelaymax( elem->LINE ) ;
3289 if( vnommax != TTV_NOTIME && vctkmax != TTV_NOTIME )
3290 deltamax = vctkmax - vnommax ;
3291
3292 vnommin = elem->LINE->VALMIN ;
3293 vctkmin = ttv_getdelaymin( elem->LINE ) ;
3294 if( vnommin != TTV_NOTIME && vctkmin != TTV_NOTIME )
3295 deltamin = vnommin - vctkmin ;
3296
3297 if( deltamax > deltamin )
3298 elem->VALUE = deltamax ;
3299 else
3300 elem->VALUE = deltamin ;
3301
3302 break ;
3303
3304 case STB_CTK_SORT_ABS_MAX_DELAY :
3305
3306 vnommax = elem->LINE->VALMAX ;
3307 vctkmax = ttv_getdelaymax( elem->LINE ) ;
3308 if( vnommax != TTV_NOTIME && vctkmax != TTV_NOTIME )
3309 deltamax = vctkmax - vnommax ;
3310
3311 elem->VALUE = deltamax ;
3312
3313 break ;
3314
3315 case STB_CTK_SORT_ABS_MIN_DELAY :
3316
3317 vnommin = elem->LINE->VALMIN ;
3318 vctkmin = ttv_getdelaymin( elem->LINE ) ;
3319 if( vnommin != TTV_NOTIME && vctkmin != TTV_NOTIME )
3320 deltamin = vnommin - vctkmin ;
3321
3322 elem->VALUE = deltamin ;
3323
3324 break ;
3325
3326 case STB_CTK_SORT_ABS_SLOPE :
3327
3328 vnommax = elem->LINE->FMAX ;
3329 vctkmax = ttv_getslopemax( elem->LINE ) ;
3330 if( vnommax != TTV_NOTIME && vctkmax != TTV_NOTIME )
3331 deltamax = vctkmax - vnommax ;
3332
3333 vnommin = elem->LINE->FMIN ;
3334 vctkmin = ttv_getslopemin( elem->LINE ) ;
3335 if( vnommin != TTV_NOTIME && vctkmin != TTV_NOTIME )
3336 deltamin = vnommin - vctkmin ;
3337
3338 if( deltamax > deltamin )
3339 elem->VALUE = deltamax ;
3340 else
3341 elem->VALUE = deltamin ;
3342
3343 break ;
3344
3345 case STB_CTK_SORT_ABS_MAX_SLOPE :
3346
3347 vnommax = elem->LINE->FMAX ;
3348 vctkmax = ttv_getslopemax( elem->LINE ) ;
3349 if( vnommax != TTV_NOTIME && vctkmax != TTV_NOTIME )
3350 deltamax = vctkmax - vnommax ;
3351
3352 elem->VALUE = deltamax ;
3353
3354 break ;
3355
3356 case STB_CTK_SORT_ABS_MIN_SLOPE :
3357
3358 vnommin = elem->LINE->FMIN ;
3359 vctkmin = ttv_getslopemin( elem->LINE ) ;
3360 if( vnommin != TTV_NOTIME && vctkmin != TTV_NOTIME )
3361 deltamin = vnommin - vctkmin ;
3362
3363 elem->VALUE = deltamin ;
3364
3365 break ;
3366
3367 case STB_CTK_SORT_REL_DELAY :
3368
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 ;
3373
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 ;
3378
3379 if( deltamax > deltamin )
3380 elem->VALUE = deltamax ;
3381 else
3382 elem->VALUE = deltamin ;
3383
3384 break ;
3385
3386 case STB_CTK_SORT_REL_MAX_DELAY :
3387
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 ;
3392
3393 elem->VALUE = deltamax ;
3394
3395 break ;
3396
3397 case STB_CTK_SORT_REL_MIN_DELAY :
3398
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 ;
3403
3404 elem->VALUE = deltamin ;
3405
3406 break ;
3407
3408 case STB_CTK_SORT_REL_SLOPE :
3409
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 ;
3414
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 ;
3419
3420 if( deltamax > deltamin )
3421 elem->VALUE = deltamax ;
3422 else
3423 elem->VALUE = deltamin ;
3424
3425 break ;
3426
3427 case STB_CTK_SORT_REL_MAX_SLOPE :
3428
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 ;
3433
3434 elem->VALUE = deltamax ;
3435
3436 break ;
3437
3438 case STB_CTK_SORT_REL_MIN_SLOPE :
3439
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 ;
3444
3445 elem->VALUE = deltamin ;
3446
3447 break ;
3448
3449 }
3450 }
3451
3452 void stb_ctk_sort_delay( stb_ctk_stat *stat, char criterion, float delay )
3453 {
3454 sortdelaycmp *tabdelay;
3455 int i ;
3456
3457 tabdelay = (sortdelaycmp*)mbkalloc( sizeof(sortdelaycmp) * stat->NBDELEM );
3458
3459 for( i=0 ; i<stat->NBDELEM ; i++ ) {
3460 tabdelay[i].LINE = stat->TABD[i].LINE ;
3461 filltabdelayvalue( &(tabdelay[i]), criterion );
3462 }
3463
3464 qsort( tabdelay, stat->NBDELEM, sizeof( sortdelaycmp ), ( int(*)(const void*, const void*) )stb_ctk_sort_delay_cmp );
3465
3466 for( i=0 ; i<stat->NBDELEM ; i++ ) {
3467 stat->TABD[i].LINE = tabdelay[i].LINE ;
3468 }
3469
3470 mbkfree( tabdelay );
3471 }
3472
3473 void stb_ctk_fill_stat_line( stb_ctk_stat *stat,
3474 stbfig_list *stbfig
3475 )
3476 {
3477 long level ;
3478 chain_list *chain ;
3479 ttvevent_list *ptevent ;
3480 ttvline_list *line ;
3481 ptype_list *ptype ;
3482 int nbline ;
3483 chain_list *scline ;
3484
3485 //CTK_PROGRESSBAR( 0, 1, 0, "Reporting delay variations" );
3486
3487 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
3488 level = stbfig->FIG->INFO->LEVEL ;
3489 else
3490 level = 0 ;
3491
3492 nbline = 0 ;
3493
3494 /* comptage du nombre de line */
3495 for(chain = stbfig->NODE ; chain ; chain = chain->NEXT )
3496 {
3497 ptevent = (ttvevent_list *)chain->DATA;
3498
3499 ttv_expfigsig( stbfig->FIG,
3500 ptevent->ROOT,
3501 level,
3502 stbfig->FIG->INFO->LEVEL,
3503 TTV_STS_CLS_FED|TTV_STS_DUAL_FED,
3504 TTV_FILE_DTX
3505 );
3506
3507 line = ptevent->INLINE ;
3508 ptype = getptype( ptevent->USER, TTV_NODE_DUALLINE );
3509 if( ptype )
3510 scline = (chain_list *)ptype->DATA ;
3511 else
3512 scline = NULL ;
3513
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 ) )
3518 continue ;
3519 nbline++;
3520 }
3521
3522 for(; scline != NULL ; scline = scline->NEXT) {
3523 line = (ttvline_list *)scline->DATA ;
3524
3525 if( ((line->TYPE & TTV_LINE_RC) != TTV_LINE_RC) ||
3526 !ttv_islinelevel( stbfig->FIG, line, level ) )
3527 continue ;
3528 nbline++;
3529 }
3530 }
3531
3532 stat->TABD = (stb_ctk_tab_delay*)mbkalloc( nbline * sizeof( stb_ctk_tab_delay ) );
3533 stat->NBDELEM = nbline ;
3534 stat->NBDDISPLAY = nbline ;
3535
3536 /* remplissage des infos */
3537 nbline = 0 ;
3538 for(chain = stbfig->NODE ; chain ; chain = chain->NEXT )
3539 {
3540 ptevent = (ttvevent_list *)chain->DATA;
3541
3542 ttv_expfigsig( stbfig->FIG,
3543 ptevent->ROOT,
3544 level,
3545 stbfig->FIG->INFO->LEVEL,
3546 TTV_STS_CLS_FED|TTV_STS_DUAL_FED,
3547 TTV_FILE_DTX
3548 );
3549
3550 line = ptevent->INLINE ;
3551 ptype = getptype( ptevent->USER, TTV_NODE_DUALLINE );
3552 if( ptype )
3553 scline = (chain_list *)ptype->DATA ;
3554 else
3555 scline = NULL ;
3556
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 ) )
3561 continue ;
3562 stb_ctk_fill_stat_line_one( &stat->TABD[nbline], line );
3563 nbline++;
3564 }
3565
3566 for(; scline != NULL ; scline = scline->NEXT) {
3567 line = (ttvline_list *)scline->DATA ;
3568
3569 if( ((line->TYPE & TTV_LINE_RC) != TTV_LINE_RC) ||
3570 !ttv_islinelevel( stbfig->FIG, line, level ) )
3571 continue ;
3572 stb_ctk_fill_stat_line_one( &stat->TABD[nbline], line );
3573 nbline++;
3574 }
3575 }
3576 }
3577
3578 char calc_pct( long vi, long vf )
3579 {
3580 float fvi, fvf, pct ;
3581 char ret=0 ;
3582
3583 if( vi == 0 ) {
3584 ret = 0;
3585 if( vf > 0 ) ret = 100 ;
3586 if( vf < 0 ) ret = -100 ;
3587 }
3588 else {
3589 fvi = (float)vi ;
3590 fvf = (float)vf ;
3591 pct = ( fvf - fvi ) / fvi * 100.0 ;
3592 if( pct > 100.0 ) pct = 100.0 ;
3593 if( pct < -100.0 ) pct = -100.0 ;
3594 ret = (char)pct ;
3595 }
3596
3597 return ret ;
3598 }
3599
3600 void stb_ctk_fill_stat_line_one( stb_ctk_tab_delay *delay, ttvline_list *line )
3601 {
3602 delay->LINE = line ;
3603 }
3604
3605 void stb_ctk_fill_stat_tab( stb_ctk_stat *stat,
3606 stbfig_list *stbfig
3607 )
3608 {
3609 stb_ctk_detail *ctkdetail ;
3610 chain_list *chain ;
3611 ttvevent_list *event ;
3612 int nbevent ;
3613 int n ;
3614 int nm ;
3615
3616 CTK_PROGRESSBAR( 0, 1, 0, "Computing noises and scores" );
3617
3618
3619 /* build and initialize data strucure */
3620 for( chain = stbfig->NODE, nbevent = 0 ; chain ; chain = chain->NEXT, nbevent++ ) ;
3621
3622 if( nbevent == 0 )
3623 return ;
3624
3625 CTK_PROGRESSBAR( 0, nbevent, 0, NULL );
3626
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 ;
3643 }
3644
3645 /* filling report crosstalk information */
3646
3647 n = 0 ;
3648 nm = 1 ;
3649 for( chain = stbfig->NODE ; chain ; chain = chain->NEXT ) {
3650
3651 event = (ttvevent_list*)chain->DATA ;
3652
3653 CTK_PROGRESSBAR( 0, nbevent, nm, NULL );
3654 nm++ ;
3655
3656 ctkdetail = stb_ctk_get_detail( stbfig, event );
3657
3658 if( ctkdetail ) {
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 );
3662 n++;
3663 }
3664 }
3665
3666 stat->NBELEM = n ;
3667 stat->NBDISPLAY = n ;
3668
3669 }
3670
3671 void stb_ctk_free_stat( stb_ctk_stat *stat )
3672 {
3673 mbkfree( stat->TABD );
3674 mbkfree( stat->TAB );
3675 mbkfree( stat );
3676 }
3677
3678 void stb_ctk_stat_event( stbfig_list *stbfig,
3679 stb_ctk_detail *ctkdetail,
3680 stb_ctk_tab_stat *stat
3681 )
3682 {
3683 float capa ;
3684
3685 /* Remplis les infos dont on dispose immédiatement */
3686
3687 stat->NODE = ctkdetail->NODE ;
3688
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 ;
3694
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 */
3697
3698 if( ( ctkdetail->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
3699 stat->NOISE_MODEL = ctkdetail->MODEL_OVR ;
3700 else
3701 stat->NOISE_MODEL = ctkdetail->MODEL_UND ;
3702
3703 /* Remplis les infos de capa */
3704
3705 capa = rcx_get_all_locon_capa( ctkdetail->LOSIG, TRC_SLOPE_UNK, TRC_CAPA_NOM, TRC_HALF );
3706
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 ;
3712 stbfig = NULL;
3713 }
3714
3715 /******************************************************************************\
3716 Si on est en mode STB_CTK_LINE :
3717
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 \******************************************************************************/
3721
3722 void stb_clean_ttvfig( stbfig_list *stbfig )
3723 {
3724 if( ( stbfig->CTKMODE & STB_CTK_LINE ) == STB_CTK_LINE )
3725 ttv_movedelayline( stbfig->FIG, TTV_LINE_D | TTV_LINE_E | TTV_LINE_F );
3726 }
3727
3728 /******************************************************************************\
3729 stb_ctk_handle_mutex()
3730
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.
3734
3735 \******************************************************************************/
3736 void stb_ctk_handle_mutex( ttvfig_list *ttvfig,
3737 ttvevent_list *event,
3738 chain_list* headagr,
3739 char actif
3740 )
3741 {
3742 chain_list *chain ;
3743 sortedmutex *mutex ;
3744 sortedmutexlist *ml ;
3745 rcxparam *param ;
3746 ttvevent_list *node ;
3747 RCXFLOAT ccmax ;
3748 rcxparam *parammax ;
3749
3750 mutex = stb_ctk_sort_by_mutex( ttvfig, event, headagr );
3751 if( !mutex ) return ;
3752
3753 for( ml = mutex->LIST ; ml ; ml = ml->NEXT ) {
3754
3755 if( ml->MUTEX == mutex->MUTEX ) {
3756
3757 for( chain = ml->LIST ; chain ; chain = chain->NEXT ) {
3758
3759 node = (ttvevent_list*)chain->DATA ;
3760 param = stb_getrcxparamfromevent( node );
3761
3762 if( actif == RCX_AGRBEST ) {
3763 if( ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST )
3764 param->ACTIF = (param->ACTIF & ~RCX_AGRBEST) | RCX_MTX_BEST ;
3765 }
3766 else {
3767 if( ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST )
3768 param->ACTIF = (param->ACTIF & ~RCX_AGRWORST) | RCX_MTX_WORST ;
3769 }
3770 }
3771 }
3772 else {
3773
3774 ccmax = 0.0 ;
3775 parammax = NULL ;
3776
3777 for( chain = ml->LIST ; chain ; chain = chain->NEXT ) {
3778
3779 node = (ttvevent_list*)chain->DATA ;
3780 param = stb_getrcxparamfromevent( node );
3781
3782 if( ( actif == RCX_AGRBEST &&
3783 ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST ) ||
3784 ( actif == RCX_AGRWORST &&
3785 ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST ) ) {
3786
3787 if( param->CC > ccmax ) {
3788 ccmax = param->CC ;
3789 parammax = param ;
3790 }
3791 }
3792 }
3793
3794 if( parammax ) {
3795
3796 for( chain = ml->LIST ; chain ; chain = chain->NEXT ) {
3797
3798 node = (ttvevent_list*)chain->DATA ;
3799 param = stb_getrcxparamfromevent( node );
3800
3801 if( actif == RCX_AGRBEST &&
3802 ( param->ACTIF & RCX_AGRBEST ) == RCX_AGRBEST ) {
3803
3804 if( param != parammax )
3805 param->ACTIF = (param->ACTIF & ~RCX_AGRBEST) | RCX_MTX_BEST ;
3806 }
3807
3808 if( actif == RCX_AGRWORST &&
3809 ( param->ACTIF & RCX_AGRWORST ) == RCX_AGRWORST ) {
3810
3811 if( param != parammax )
3812 param->ACTIF = (param->ACTIF & ~RCX_AGRWORST) | RCX_MTX_WORST ;
3813 }
3814 }
3815 }
3816 }
3817 }
3818 stb_ctk_free_sortedmutex( ttvfig, mutex );
3819 }
3820
3821 void stb_set_ctk_information(stbfig_list *stbfig, ttvevent_list *node, long type, ctk_exchange *res)
3822 {
3823 char *insname;
3824 chain_list *chainfig;
3825 long level;
3826
3827 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
3828 level = stbfig->FIG->INFO->LEVEL ;
3829 else
3830 level = 0 ;
3831
3832 res->sigvic = ttv_getlosigfromevent( stbfig->FIG, node->ROOT, &insname, &chainfig, &res->figvic );
3833 if( res->sigvic )
3834 {
3835 res->headagr = rcx_getagrlist( res->figvic, res->sigvic, insname, chainfig );
3836 freechain( chainfig );
3837
3838 if( res->headagr )
3839 {
3840
3841 stb_fillttvsigrcxparam( stbfig->FIG, level, type, res->headagr );
3842
3843 if( ( stbfig->CTKMODE & STB_CTK_WORST ) == STB_CTK_WORST )
3844 {
3845 stb_fillinactifrcxparam( stbfig->FIG, node, res->headagr, 'N' );
3846 }
3847 else
3848 {
3849 stb_fillactifrcxparam( stbfig->FIG, node, res->headagr, 'N' );
3850 }
3851 stb_remove_input( stbfig->FIG, node->ROOT, level, res->headagr );
3852 }
3853 }
3854 else
3855 res->headagr=NULL;
3856 }
3857
3858 void stb_release_ctk_information(ctk_exchange *res)
3859 {
3860 if( res->headagr )
3861 {
3862 stb_delttvsigrcxparam( res->headagr );
3863 rcx_freeagrlist( res->figvic, res->sigvic, res->headagr );
3864 }
3865 }