Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / tas / stb / stb_ctk_score.c
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : STB Version 1.00 */
6 /* Fichier : stb_ctk_score.c */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Grégoire AVOT */
12 /* */
13 /* */
14 /****************************************************************************/
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdarg.h>
20 #include <limits.h>
21 #include <float.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 #include STM_H
31
32 #include "stb_util.h"
33 #include "stb_init.h"
34 #include "stb_error.h"
35 #include "stb_transfer.h"
36 #include "stb_relaxation.h"
37 #include "stb_overlap.h"
38 #include "stb_ctk.h"
39 #include "stb_ctk_noise.h"
40 #include "stb_ctk_debug.h"
41 #include "stb_ctk_score.h"
42
43 int STB_CTK_COEF_NOISE = 4 ;
44 int STB_CTK_COEF_CTK = 2 ;
45 int STB_CTK_COEF_INTERVAL = 3 ;
46 int STB_CTK_COEF_ACTIVITY = 1 ;
47
48 int STB_CTK_MIN_NOISE = 3 ;
49 int STB_CTK_MIN_CTK = 0 ;
50 int STB_CTK_MIN_INTERVAL = 0 ;
51 int STB_CTK_MIN_ACTIVITY = 0 ;
52
53 char STB_CTK_STAT_COMPARE = STB_CTK_SORT_SCORE_TOTAL ;
54
55 int stb_ctk_good_score( int score )
56 {
57 if( score < 0 ) score = 0 ;
58 if( score > 10 ) score = 10 ;
59
60 return score ;
61 }
62
63 int stb_ctk_get_min_noise()
64 {
65 return STB_CTK_MIN_NOISE ;
66 }
67
68 int stb_ctk_get_min_interval()
69 {
70 return STB_CTK_MIN_INTERVAL ;
71 }
72
73 int stb_ctk_get_min_ctk()
74 {
75 return STB_CTK_MIN_CTK ;
76 }
77
78 int stb_ctk_get_min_activity()
79 {
80 return STB_CTK_MIN_ACTIVITY ;
81 }
82
83 void stb_ctk_set_min_score( int noise, int ctk, int interval, int activity )
84 {
85 if( noise >= 0 )
86 STB_CTK_MIN_NOISE = noise ;
87 if( ctk >= 0 )
88 STB_CTK_MIN_CTK = ctk ;
89 if( interval >= 0 )
90 STB_CTK_MIN_INTERVAL = interval;
91 if( activity >= 0 )
92 STB_CTK_MIN_ACTIVITY = activity ;
93 }
94
95 int stb_ctk_get_coef_noise()
96 {
97 return STB_CTK_COEF_NOISE ;
98 }
99
100 int stb_ctk_get_coef_ctk()
101 {
102 return STB_CTK_COEF_CTK ;
103 }
104
105 int stb_ctk_get_coef_interval()
106 {
107 return STB_CTK_COEF_INTERVAL ;
108 }
109
110 int stb_ctk_get_coef_activity()
111 {
112 return STB_CTK_COEF_ACTIVITY ;
113 }
114
115 /******************************************************************************\
116 stb_ctk_set_coef_score()
117 Initialise les 4 coefficients de pondérations.
118 Les valeurs négatives ne modifient pas le coefficients.
119 Les valeurs sont bornées à 10.
120 \******************************************************************************/
121 void stb_ctk_set_coef_score( int noise, int ctk, int interval, int activity )
122 {
123 if( noise >= 0 )
124 STB_CTK_COEF_NOISE = stb_ctk_good_score( noise );
125 if( ctk >= 0 )
126 STB_CTK_COEF_CTK = stb_ctk_good_score( ctk );
127 if( interval >= 0 )
128 STB_CTK_COEF_INTERVAL = stb_ctk_good_score( interval );
129 if( activity >= 0 )
130 STB_CTK_COEF_ACTIVITY = stb_ctk_good_score( activity );
131 }
132
133 int stb_ctk_get_score_total( stb_ctk_tab_stat *stat )
134 {
135 int n ;
136
137 n = stb_ctk_get_score_noise( stat ) * STB_CTK_COEF_NOISE +
138 stb_ctk_get_score_ctk( stat ) * STB_CTK_COEF_CTK +
139 stb_ctk_get_score_interval( stat ) * STB_CTK_COEF_INTERVAL +
140 stb_ctk_get_score_activity( stat ) * STB_CTK_COEF_ACTIVITY ;
141
142 return n ;
143
144 }
145
146 int stb_ctk_get_score_noise( stb_ctk_tab_stat *stat )
147 {
148 return stat->SCORE_NOISE ;
149 }
150
151 int stb_ctk_get_score_ctk( stb_ctk_tab_stat *stat )
152 {
153 return stat->SCORE_CTK ;
154 }
155
156 int stb_ctk_get_score_interval( stb_ctk_tab_stat *stat )
157 {
158 return stat->SCORE_INTERVAL ;
159 }
160
161 int stb_ctk_get_score_activity( stb_ctk_tab_stat *stat )
162 {
163 return stat->SCORE_ACTIVITY ;
164 }
165
166 int stb_ctk_get_score_probability( stb_ctk_tab_stat *stat )
167 {
168 return stat->SCORE_PROBABILITY ;
169 }
170
171 /******************************************************************************\
172 stb_ctk_score_noise()
173
174 Note l'effet du bruit.
175 \******************************************************************************/
176 int stb_ctk_score_noise( stbfig_list *stbfig, stb_ctk_detail *detail )
177 {
178 int score = 0 ;
179 float vth ;
180 float noise ;
181 float vdd ;
182
183
184 vth = detail->NOISE_VTH ;
185
186 if( ( detail->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
187 noise = detail->NOISE_OVR ;
188 else
189 noise = detail->NOISE_UND ;
190
191 if( ( detail->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ) {
192 if( noise > vth )
193 score = 10 ;
194 else
195 score = ceil( noise/vth*10.0 );
196 }
197 else {
198 vdd = stb_ctk_signal_get_vdd( stbfig, detail->NODE );
199 if( (vdd-noise) < vth )
200 score = 10 ;
201 else
202 score = ceil( noise/(vdd-vth)*10.0 );
203 }
204 score = stb_ctk_good_score( score );
205 return score ;
206 }
207
208 /******************************************************************************\
209 stb_ctk_score_interval()
210
211 Note l'impact de la simultanéité des agresseurs. C'est la part maximum de
212 crosstalk qui peut etre activée à un instant donné.
213 \******************************************************************************/
214 int stb_ctk_score_interval( stbfig_list *stbfig, stb_ctk_detail *detail )
215 {
216 int score = 0 ;
217 float s;
218 float sdw;
219 float sup;
220 stb_ctk_detail_agr_list *agr;
221 chain_list *chain ;
222 float ccalways[2] ;
223 float cgap ;
224 float cgapmax[2] ;
225 stbgap_list *gap ;
226 int i ;
227 char calcul[] = { TTV_NODE_DOWN, TTV_NODE_UP };
228 stb_ctk_gap *ctkgap ;
229
230 for( i = 0 ; i <= 1 ; i++) {
231
232 ccalways[i] = 0.0 ;
233 cgapmax[i] = 0.0 ;
234
235 ctkgap = stb_fill_gap( stbfig, detail, calcul[i] );
236
237 for( chain = ctkgap->NOINFO ; chain ; chain = chain->NEXT ) {
238 agr = (stb_ctk_detail_agr_list*)chain->DATA ;
239 if( agr )
240 ccalways[i] = ccalways[i] + agr->CC ;
241 }
242
243 /* Prend en compte les agresseurs considérés comme toujours actifs */
244 for( chain = ctkgap->OTHERDOMAIN ; chain ; chain = chain->NEXT ) {
245 agr = stb_ctk_get_node_detail( ((ttvevent_list*)chain->DATA)->ROOT );
246 if( agr )
247 ccalways[i] = ccalways[i] + agr->CC ;
248 }
249
250 /* Récupère le crosstalk maximum sur les différents gap */
251 for( gap = ctkgap->GAPACTIF ; gap ; gap = gap->NEXT ) {
252 cgap = 0.0 ;
253 for( chain = gap->SIGNALS ; chain ; chain = chain->NEXT ) {
254 agr = stb_ctk_get_node_detail( ((ttvevent_list*)chain->DATA)->ROOT );
255 if( agr )
256 cgap = cgap + agr->CC ;
257 }
258 if( cgap > cgapmax[i] )
259 cgapmax[i] = cgap ;
260 }
261 }
262
263 sdw = ccalways[0] + cgapmax[0] ;
264 sup = ccalways[1] + cgapmax[1] ;
265
266 if( detail->CC > 0.0 ) {
267 if( sup > sdw )
268 s = 10.0 * sup / detail->CC ;
269 else
270 s = 10.0 * sdw / detail->CC ;
271 }
272 else
273 s = 0.0 ;
274
275 score = ceil( s );
276 score = stb_ctk_good_score( score );
277 return score ;
278 }
279
280 /******************************************************************************\
281 stb_ctk_score_ctk()
282
283 Repère les signaux dont le crosstalk est majoritairement due à un nombre
284 reduit d'agresseurs.
285 \******************************************************************************/
286 int stb_ctk_score_ctk( stbfig_list *stbfig, stb_ctk_detail *detail )
287 {
288 int score = 0 ;
289 stb_ctk_detail_agr_list *agr ;
290 int maxagr ;
291 int i ;
292 float *tabcapa ;
293 float sum ;
294 float climit ;
295
296 for( agr = detail->AGRLIST, maxagr=0 ; agr ; agr = agr->NEXT, maxagr++ ) ;
297 if( maxagr == 0 )
298 return 0 ;
299 if( maxagr == 1 )
300 return 10 ;
301
302 tabcapa = (float*)mbkalloc( sizeof( float ) * maxagr );
303
304 for( agr = detail->AGRLIST, i=0 ; agr ; agr = agr->NEXT, i++ )
305 tabcapa[i] = agr->CC ;
306
307 qsort( tabcapa,
308 maxagr,
309 sizeof( float ),
310 (int (*)(const void*, const void*))stb_ctk_qsort_float
311 );
312
313 sum = 0.0 ;
314 climit = detail->CC / 2.0 ;
315
316 for( i=0 ; i < maxagr ; i++ ) {
317 sum = sum + tabcapa[i] ;
318 if( sum > climit )
319 break;
320 }
321
322 score = ceil(( 10.0 * (2*i - (maxagr-1)) ) / (maxagr-1)) ;
323 score = stb_ctk_good_score( score );
324
325 mbkfree( tabcapa );
326 stbfig = NULL ; // unused parameter
327 return score ;
328 }
329
330 /******************************************************************************\
331 stb_ctk_score_activity()
332
333 Evalue l'impact de l'activité d'un agresseur.
334 Pour l'instant, seules les clock ont une activité à peu près connue.
335 La note renvoyée sur 10 correspond à la part de crosstalk due aux agresseurs
336 considérés comme systématiquement actifs.
337
338 Idée :
339
340 Voir si il ne faut pas affecter une note intermédiaire aux agresseurs pour
341 lesquels l'activité n'est pas connue, une note maximum si l'activité est
342 certaine et une note minimum si il n'est pas actif.
343 \******************************************************************************/
344 int stb_ctk_score_activity( stbfig_list *stbfig, stb_ctk_detail *detail )
345 {
346 int score = 0 ;
347 stb_ctk_detail_agr_list *agr ;
348 float s[2] ;
349 stbnode *node ;
350 int i ;
351 float r ;
352
353 s[0] = 0.0 ;
354 s[1] = 0.0 ;
355
356 for( i = 0 ; i <= 1 ; i++ ) {
357 s[i] = 0.0 ;
358
359 for( agr = detail->AGRLIST ; agr ; agr = agr->NEXT ) {
360
361 if( agr->TTVAGR ) {
362 node = stb_getstbnode( &(agr->TTVAGR->NODE[i]) );
363 if( !node )
364 continue ;
365
366 if( node->CK )
367 s[i] = s[i] + agr->CC ;
368 }
369 }
370 }
371
372 if( detail->CC > 0.0 ) {
373 if( s[0] > s[1] )
374 r = 10.0 * s[0] / detail->CC ;
375 else
376 r = 10.0 * s[1] / detail->CC ;
377 }
378 else
379 r = 0.0 ;
380
381 score = ceil( r );
382 score = stb_ctk_good_score( score );
383
384 stbfig = NULL ; // unused parameter
385 return score ;
386 }
387
388 // probabilite d'occurence de l'agression
389 int stb_ctk_score_propability( stbfig_list *stbfig, stb_ctk_detail *detail )
390 {
391 int score = 0 ;
392 stb_ctk_detail_agr_list *agr ;
393 int maxagr ;
394 int i ;
395 float *tabcapa ;
396 float sum ;
397 float proba=1 ;
398 ptype_list *pt;
399
400 for( agr = detail->AGRLIST ; agr ; agr = agr->NEXT)
401 {
402 if( agr->TTVAGR )
403 {
404 if ((pt=getptype(agr->TTVAGR->USER, STB_TRANSITION_PROBABILITY))!=NULL)
405 proba*=*(float *)&pt->DATA;
406 }
407 }
408
409 score = (int)mbk_long_round(10-log(1/proba));
410 if (score<0) score=0;
411 stbfig = NULL ; // unused parameter
412 return score ;
413 }
414
415 /******************************************************************************\
416 stb_ctk_calc_score()
417 \******************************************************************************/
418 void stb_ctk_calc_score( stbfig_list *stbfig,
419 stb_ctk_detail *ctkdetail,
420 stb_ctk_tab_stat *stat
421 )
422 {
423 stat->SCORE_NOISE = stb_ctk_score_noise( stbfig, ctkdetail );
424 stat->SCORE_INTERVAL = stb_ctk_score_interval( stbfig, ctkdetail );
425 stat->SCORE_CTK = stb_ctk_score_ctk( stbfig, ctkdetail );
426 stat->SCORE_ACTIVITY = stb_ctk_score_activity( stbfig, ctkdetail );
427 stat->SCORE_PROBABILITY = stb_ctk_score_propability( stbfig, ctkdetail );
428 }
429
430 int stb_ctk_qsort_float( float *f1, float *f2 )
431 {
432 if( *f1 < *f2 ) return -1 ;
433 if( *f1 > *f2 ) return 1 ;
434 return 0;
435 }
436
437 /******************************************************************************\
438 stb_ctk_signal_threshold()
439 Calcule la tension admissible au maximum sur un signal.
440 si <0, c'est qu'on a pas pu la déterminer (cas d'une sortie).
441 \******************************************************************************/
442
443 float stb_ctk_signal_threshold( stbfig_list *stbfig, ttvevent_list *event )
444 {
445 ptype_list *ptype ;
446 chain_list *chline ;
447 chain_list *headline ;
448 long level ;
449 float vth ;
450 float vthmax = -1.0 ;
451 ttvline_list *ptline ;
452 ttvevent_list *nodet ;
453 timing_model *model ;
454 int found ;
455
456 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
457 level = stbfig->FIG->INFO->LEVEL ;
458 else
459 level = 0 ;
460
461 ttv_expfigsig( stbfig->FIG,
462 event->ROOT,
463 level,
464 stbfig->FIG->INFO->LEVEL,
465 TTV_STS_CLS_FED|TTV_STS_DUAL_FED,
466 TTV_FILE_DTX
467 );
468
469 if((ptype = getptype(event->USER,TTV_NODE_DUALLINE)) != NULL)
470 headline = (chain_list *)ptype->DATA ;
471 else
472 headline = NULL ;
473
474 found = 0 ;
475
476 for( chline = headline ; chline ; chline = chline->NEXT ) {
477
478 ptline = (ttvline_list*)chline->DATA ;
479
480 vth = -1.0 ;
481 if( !ttv_islinelevel( stbfig->FIG, ptline, level ) )
482 continue ;
483
484 nodet = ptline->ROOT ;
485
486 if( (ptline->TYPE & TTV_LINE_RC ) == TTV_LINE_RC ) {
487 vth = stb_ctk_signal_threshold( stbfig, nodet );
488 }
489 else {
490 model = stm_getmodel( ptline->FIG->INFO->FIGNAME, ptline->MDMAX );
491 if( model ) {
492 if( stm_noise_getmodeltype( model ) == STM_NOISE_SCR ) {
493 vth = stm_noise_scr_invth( stm_noise_getmodel_scr(model) ) ;
494 }
495 }
496 }
497
498 if( ( event->TYPE & TTV_NODE_UP ) == TTV_NODE_UP ) {
499 if( found == 0 || vth < vthmax ) {
500 vthmax = vth ;
501 found = 1 ;
502 }
503 }
504 else {
505 if( found == 0 || vth > vthmax ) {
506 vthmax = vth ;
507 found = 1 ;
508 }
509 }
510 }
511
512 return vthmax ;
513 }
514
515 float stb_ctk_signal_get_vdd( stbfig_list *stbfig, ttvevent_list *event )
516 {
517 long level ;
518 float vddmin = FLT_MAX ;
519 float vdd ;
520 ttvline_list *ptline ;
521 timing_model *model ;
522 int found ;
523
524 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
525 level = stbfig->FIG->INFO->LEVEL ;
526 else
527 level = 0 ;
528
529 ttv_expfigsig( stbfig->FIG,
530 event->ROOT,
531 level,
532 stbfig->FIG->INFO->LEVEL,
533 TTV_STS_CLS_FED|TTV_STS_DUAL_FED,
534 TTV_FILE_DTX
535 );
536
537 found = 0 ;
538 for( ptline = event->INLINE ; ptline ; ptline = ptline->NEXT ) {
539
540 if( !ttv_islinelevel( stbfig->FIG, ptline, level ) )
541 continue ;
542
543 model = stm_getmodel( ptline->FIG->INFO->FIGNAME, ptline->MDMAX );
544 if( model ) {
545 vdd = stm_mod_vdd( model ) ;
546
547 if( found == 0 || vdd < vddmin ) {
548 vddmin = vdd ;
549 found = 1 ;
550 }
551 }
552 }
553
554 if( found == 0 )
555 vddmin = stm_mod_default_vdd() ;
556
557 return vddmin ;
558
559 }
560
561 float stb_ctk_signal_threshold_from_input( stbfig_list *stbfig,
562 ttvevent_list *event
563 )
564 {
565 long level ;
566 float vth ;
567 float vddmin = FLT_MAX ;
568 float vdd ;
569 ttvline_list *ptline ;
570 timing_model *model ;
571
572 if((stbfig->STABILITYMODE & STB_STABILITY_LAST) == STB_STABILITY_LAST)
573 level = stbfig->FIG->INFO->LEVEL ;
574 else
575 level = 0 ;
576
577 ttv_expfigsig( stbfig->FIG,
578 event->ROOT,
579 level,
580 stbfig->FIG->INFO->LEVEL,
581 TTV_STS_CLS_FED|TTV_STS_DUAL_FED,
582 TTV_FILE_DTX
583 );
584
585 for( ptline = event->INLINE ; ptline ; ptline = ptline->NEXT ) {
586
587 if( !ttv_islinelevel( stbfig->FIG, ptline, level ) )
588 continue ;
589
590 model = stm_getmodel( ptline->FIG->INFO->FIGNAME, ptline->MDMAX );
591 if( model ) {
592 vdd = stm_mod_vdd( model ) ;
593
594 if( vdd < vddmin )
595 vddmin = vdd ;
596 }
597 }
598
599 if( vddmin < FLT_MAX )
600 vth = vddmin / 2.0 ;
601 else
602 vth = stm_mod_default_vdd() / 2.0 ;
603
604 return vth ;
605 }
606
607 /******************************************************************************\
608 Fonction de comparaison pour trier les tableaux de statistiques. Le critère
609 de trie doit être mis dans la variable globale STB_CTK_STAT_COMPARE.
610 \******************************************************************************/
611 int stb_ctk_score_compare( stb_ctk_tab_stat *n1, stb_ctk_tab_stat *n2 )
612 {
613 int s1, s2 ;
614 int r, trs1, trs2 ;
615
616 switch( STB_CTK_STAT_COMPARE ) {
617 case STB_CTK_SORT_SCORE_TOTAL :
618 s1 = stb_ctk_get_score_total( n1 );
619 s2 = stb_ctk_get_score_total( n2 );
620 break;
621 case STB_CTK_SORT_SCORE_NOISE :
622 s1 = stb_ctk_get_score_noise( n1 );
623 s2 = stb_ctk_get_score_noise( n2 );
624 break;
625 case STB_CTK_SORT_SCORE_CTK :
626 s1 = stb_ctk_get_score_ctk( n1 );
627 s2 = stb_ctk_get_score_ctk( n2 );
628 break;
629 case STB_CTK_SORT_SCORE_INTERVAL :
630 s1 = stb_ctk_get_score_interval( n1 );
631 s2 = stb_ctk_get_score_interval( n2 );
632 break;
633 case STB_CTK_SORT_SCORE_ACTIVITY :
634 s1 = stb_ctk_get_score_activity( n1 );
635 s2 = stb_ctk_get_score_activity( n2 );
636 break;
637 default :
638 s1 = 0;
639 s2 = 0;
640 }
641
642 if( s1 < s2 ) return 1 ;
643 if( s1 > s2 ) return -1 ;
644 r =strcmp( n1->NODE->ROOT->NAME, n2->NODE->ROOT->NAME );
645 if( r )
646 return r ;
647
648 if( ( n1->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
649 trs1=1;
650 else
651 trs1=0;
652
653 if( ( n2->NODE->TYPE & TTV_NODE_UP ) == TTV_NODE_UP )
654 trs2=1;
655 else
656 trs2=0;
657
658 if( trs1>trs2 ) return 1;
659 if( trs2>trs1 ) return -1;
660 return 0;
661 }
662
663 int stb_ctk_stat_to_keep( stb_ctk_tab_stat *stat )
664 {
665 if( stb_ctk_get_score_noise( stat ) < stb_ctk_get_min_noise() ||
666 stb_ctk_get_score_interval( stat ) < stb_ctk_get_min_interval() ||
667 stb_ctk_get_score_ctk( stat ) < stb_ctk_get_min_ctk() ||
668 stb_ctk_get_score_activity( stat ) < stb_ctk_get_min_activity() )
669 return 0 ;
670 return 1 ;
671 }
672
673 void stb_ctk_fix_min( stb_ctk_stat *stat )
674 {
675 int tabend ;
676 int curpos ;
677 stb_ctk_tab_stat tmp;
678
679 tabend = stat->NBELEM ;
680 curpos = 0 ;
681 while( curpos < tabend ) {
682 if( ! stb_ctk_stat_to_keep( &stat->TAB[curpos] ) ) {
683 if( curpos != tabend-1 ) {
684 memcpy( &tmp, &stat->TAB[curpos], sizeof( stb_ctk_tab_stat ) ) ;
685 memcpy( &stat->TAB[curpos], &stat->TAB[tabend-1], sizeof( stb_ctk_tab_stat ) ) ;
686 memcpy( &stat->TAB[tabend-1], &tmp, sizeof( stb_ctk_tab_stat ) ) ;
687 }
688 tabend-- ;
689 }
690 else {
691 curpos++ ;
692 }
693 }
694 stat->NBDISPLAY = tabend ;
695 }