1 /****************************************************************************/
3 /* Chaine de CAO & VLSI Alliance */
5 /* Produit : TRC Version 1.01 */
6 /* Fichier : trc_rcx.c */
8 /* (c) copyright 1997-1998 Laboratoire LIP6 equipe ASIM */
9 /* Tous droits reserves */
10 /* Support : e-mail alliance-support@asim.lip6.fr */
12 /* Auteur(s) : Gregoire AVOT */
14 /****************************************************************************/
18 Revision : $Revision: 1.182 $
19 Author : $Author: fabrice $
20 Date : $Date: 2008/03/20 16:23:04 $
27 int RCX_CROSSTALK
=RCX_NOCROSSTALK
;
28 char RCX_FREEUNUSEDCTC
='Y';
29 char RCX_USECACHE
='Y';
32 /* Valeur du produit RC sur un signal en dessous duquel on considère qu'il n'y
33 a pas de délais RC à prendre en compte. */
34 RCXFLOAT RCX_MINRCSIGNAL
=1.0;
36 /* Valeur relative entre 0 et 1 de la part de capacité de couplage sur un signal
37 en dessous de laquelle on considère que le signal n'est pas sujet au couplage */
38 RCXFLOAT RCX_MINRELCTKSIGNAL
=0.05;
40 /* Filtrage des capacités de couplage : valeur relative entre 0 et 1 de la part
41 des capacités à négliger */
42 RCXFLOAT RCX_MINRELCTKFILTER
=0.05;
44 /* Paramètres de la fonction rcx_rcnload() lorsque l'argument flag vaut
47 RCX_CAPALOAD_MAXRC : Temps (en pico secondes) en dessous duquel le produit
48 de la somme des résistances x somme des capacités doit être inférieur pour
49 qu'on prenne systématiquement une charge purement capacitive.
51 RCX_MAXDELTALOAD : Ecart maximum autorisé entre la cellule en pi et la
52 capacité pure lorsque le générateur de courant est constant (valeur sans
55 RCXFLOAT RCX_CAPALOAD_MAXRC
= 5.0;
56 RCXFLOAT RCX_MAXDELTALOAD
= 1.0;
58 char RCX_CTK_MODEL
= RCX_MILLER_NOMINAL
;
59 char RCX_CTK_NOISE
= RCX_NOISE_FINE
;
60 char RCX_CTK_SLOPE_NOISE
= RCX_SLOPE_CTK
;
61 char RCX_CTK_SLOPE_MILLER
= RCX_SLOPE_NOMINAL
;
62 char RCX_CTK_SLOPE_DELAY
= RCX_SLOPE_DELAY_CTK
;
64 double RCX_SLOPE_UNSHRINK
= 0.6 ;
66 /* Prend en compte les fronts améliorés pour l'effet miller */
67 #define RCX_CORREC_MILLER
69 /*******************************************************************************
72 * Renvoie un nombre caracterisant l'etat de la vue RCX. L'argument peut etre *
75 * -1 Pas de vue RCX (ptrcx = NULL) *
78 * 2 Vue RCX non extraite (RCXNODELAY seul) *
79 * L'argument where permet de savoir si il s'agit d'une vue interne ou externe. *
82 * autre=pas de verification *
83 *******************************************************************************/
86 #define RCX_STATE_NOCHECK 0
87 #define RCX_STATE_LOINS 1
88 #define RCX_STATE_LOFIG 2
91 #define RCX_STATE_NORCX -1
92 #define RCX_STATE_EMPTY 0
93 #define RCX_STATE_TYPED 1
95 int rcx_state( ptrcx
, where
)
100 return(RCX_STATE_NORCX
);
102 if( !GETFLAG( ptrcx
->FLAG
, MODELRCN
) )
104 if( where
== RCX_STATE_LOINS
) // Dans une instance, on a forcement une
105 rcx_error( 21, NULL
, AVT_ERROR
); // vue RCN.
107 return(RCX_STATE_EMPTY
);
110 if( GETFLAG( ptrcx
->FLAG
, MODELRCN
) )
112 if( where
== RCX_STATE_LOFIG
&& !ptrcx
->VIEW
)
113 rcx_error( 22, NULL
, AVT_ERROR
);
114 if( where
== RCX_STATE_LOINS
&& ( !ptrcx
->VIEW
|| !ptrcx
->RCXEXTERNAL
) )
115 rcx_error( 23, NULL
, AVT_ERROR
);
116 return(RCX_STATE_TYPED
);
119 rcx_error( 24, NULL
, AVT_FATAL
);
125 /*******************************************************************************
128 * Ajoute un connecteur dans la vue RCX d'un losig d'une lofig, en regroupant *
129 * ses connecteurs sans faire de boucles. *
131 *******************************************************************************/
133 void merge_ext( file
, ptsig
, ptcon
, iscache
, keeponenode
)
148 if( chkloop( ptsig
) != 0 )
151 if( ptcon
->PNODE
&& keeponenode
== YES
)
153 /* On ne garde que le premier noeud. */
154 for( sn
= ptcon
->PNODE
->NEXT
; sn
; sn
= sn
->NEXT
)
158 chemin
= getway( ptsig
, ptcon
->PNODE
->DATA
, sn
->DATA
);
160 rcx_drive_wire( file
,
161 rcx_get_new_num_node( ptsig
,
166 rcx_get_new_num_node( ptsig
,
186 while( ptcon
->PNODE
->NEXT
)
187 delloconnode( ptcon
, ptcon
->PNODE
->NEXT
->DATA
);
191 ptrcx
= getrcx( ptsig
);
192 ptrcx
->RCXINTERNAL
= addchain( ptrcx
->RCXINTERNAL
, ptcon
);
194 if( ptcon
->TYPE
== 'I' ) {
197 rcx_getinsname( (loins_list
*)(ptcon
->ROOT
) ), SEPAR
,
198 getloconrcxname( ptcon
)
200 addloconrcxname( ptcon
, buffer
);
204 void set_ext_rcn( ptsig
)
209 ptrcx
= getrcx( ptsig
);
212 if( rcx_state( ptrcx
, RCX_STATE_LOFIG
) != RCX_STATE_EMPTY
|| !ptsig
->PRCN
)
213 rcx_error( 25, ptsig
, AVT_WARNING
);
216 ptrcx
->VIEW
= ptsig
->PRCN
;
217 SETFLAG( ptrcx
->FLAG
, MODELRCN
);
220 void rcx_addbellow( losig_list
*ptsig
, char *sigpointed
)
222 ptsig
->USER
= addptype( ptsig
->USER
, RCX_BELLOW
, sigpointed
);
225 losig_list
* rcx_addsigbellow( lofig_list
*ptfig
, char *sigpointed
)
231 for( losig
= ptfig
->LOSIG
; losig
; losig
= losig
->NEXT
)
232 if( losig
->INDEX
> maxidx
)
233 maxidx
= losig
->INDEX
;
237 sprintf( buffer
, "rcx_bellow_%d", maxidx
);
239 losig
= addlosig( ptfig
,
241 addchain( NULL
, namealloc( buffer
) ),
245 losig
->USER
= addptype( losig
->USER
, RCX_BELLOW
, sigpointed
);
246 losig
->USER
= addptype( losig
->USER
, LOFIGCHAIN
, NULL
);
251 /******************************************************************************\
252 Transfert la vue rcx d'une loins dans la vue externe.
253 \******************************************************************************/
255 void rcx_copyrcx( lofig_list
*lofig
,
263 locon_list
*loconint
;
267 chain_list
*scanchain
;
269 rcxext
= getrcx( sigext
);
270 rcxint
= getrcx( sigint
);
272 /* On deplace les locon de la vue interne vers la vue externe :
273 * il suffit juste de les enlever du lofigchain du signal
277 for( scanchain
= rcxint
->RCXINTERNAL
;
279 scanchain
=scanchain
->NEXT
282 loconint
= (locon_list
*)(scanchain
->DATA
);
286 // On commence par calculer les noeuds du locon avant de toucher
288 rcx_trsfnodelocon( loconint
, RCX_LOINS
);
290 while(loconint
->PNODE
)
292 headnum
= addnum( headnum
, loconint
->PNODE
->DATA
);
293 delloconnode( loconint
, loconint
->PNODE
->DATA
);
296 loconint
->SIG
= sigext
;
297 loconint
->ROOT
= NULL
;
298 rcxext
->RCXINTERNAL
= addchain( rcxext
->RCXINTERNAL
, loconint
);
300 pt
= getptype( sigext
->USER
, LOFIGCHAIN
);
301 pt
->DATA
= addchain( ((chain_list
*)(pt
->DATA
)),
305 pt
= getptype( loconint
->USER
, RCXNAME
);
307 loconint
->USER
= delptype( loconint
->USER
, RCXNAME
);
309 for( scannum
= headnum
; scannum
; scannum
= scannum
->NEXT
)
312 rcx_error( 26, sigint
, AVT_ERROR
);
314 setloconnode( loconint
, scannum
->DATA
);
319 // On transfert la capacité associée au locon ( a cause des allocations
322 rcx_transfert_capa_from_instance_to_figure( loins
, lofig
, loconint
);
325 // On ne touche plus à ces connecteurs.
326 freechain( rcxint
->RCXINTERNAL
);
327 rcxint
->RCXINTERNAL
= NULL
;
331 /******************************************************************************\
334 - Crée les BELLOW dans la lofig.
336 Drive les éléments RC d'un signal d'une instance dans le fichier. Crée des
337 signaux BELLOW dans la lofig pour les agresseurs internes à la loins. Ils sont
338 accessibles par le ptype RCX_COPIED mis dans les losigs typés UNRESOLVED de
340 \******************************************************************************/
341 void rcx_dump_loins( rcxfile
*file
,
348 losig_list
*pseudovssins
;
349 losig_list
*pseudovssinsni
;
350 chain_list
*scanchain
;
356 losig_list
*sigbellow
;
360 losig_list
*sigagrext
;
362 rcxint
= getrcx( losig
);
363 sigext
= rcx_get_out_ins_sig( losig
);
364 rcxext
= getrcx( sigext
);
366 if( !GETFLAG( rcxext
->FLAG
, RCXNOWIRE
) ) {
367 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
368 rcx_drive_wire( file
,
369 rcx_get_new_num_node( losig
, wire
->NODE1
, RCX_LOINS
, YES
),
370 rcx_get_new_num_node( losig
, wire
->NODE2
, RCX_LOINS
, YES
),
376 pseudovssins
= getrcxpseudovss( loins
->USER
);
377 pseudovssinsni
= rcx_loinsgetvssni( loins
);
379 for( scanchain
= losig
->PRCN
->PCTC
;
381 scanchain
= scanchain
->NEXT
)
384 loctc
= (loctc_list
*)scanchain
->DATA
;
385 node
= rcn_ctcnode( loctc
, losig
);
386 sigagr
= rcn_ctcothersig( loctc
, losig
);
387 nodeagr
= rcn_ctcothernode( loctc
, losig
);
389 if( sigagr
== pseudovssins
)
390 rcx_drive_ground_capa( file
,
391 rcx_get_new_num_node( losig
, node
, RCX_LOINS
, YES
),
395 if( sigagr
== pseudovssinsni
)
396 rcx_drive_ctcni_capa( file
,
397 rcx_get_new_num_node( losig
, node
, RCX_LOINS
, YES
),
401 if( sigagr
!= pseudovssins
&& sigagr
!= pseudovssinsni
) {
403 if( getptype( sigagr
->USER
, RCX_UNRESOLVEDSIG
) ) {
404 // L'agresseur n'a pas été lu, il correspond à un signal interne.
405 pt
= getptype( sigagr
->USER
, RCX_COPIED
);
408 sigbellow
= rcx_addsigbellow( lofig
,
409 concatname( rcx_getinsname( loins
),
410 rcx_getsigname( sigagr
)
413 sigagr
->USER
= addptype( sigagr
->USER
, RCX_COPIED
, sigbellow
);
414 addlorcnet( sigbellow
);
417 sigbellow
= (losig_list
*)(pt
->DATA
);
419 rcx_drive_ctc_capa( file
,
420 rcx_get_new_num_node( losig
, node
, RCX_LOINS
, YES
),
422 rcx_getsigname( sigbellow
),
427 // On teste le cas où il n'y a pas de vue RCX sur le signal externe.
429 locon_agr = (locon_list*)getptype( sigagr->USER, RCX_LOCONINS )->DATA;
431 sigagrext
= rcx_get_out_ins_sig( sigagr
);
432 if( getrcx( sigagrext
) ) {
433 if( sigagrext
!= sigext
) {
434 rcx_drive_ctc_capa( file
,
435 rcx_get_new_num_node( losig
,
441 rcx_getsigname( sigagrext
),
442 rcx_get_new_num_node( sigagr
,
451 if( tlc_islosigalim( sigagrext
) )
452 rcx_drive_ctcni_capa( file
,
453 rcx_get_new_num_node( losig
, node
, RCX_LOINS
, YES
),
457 rcx_drive_ground_capa( file
,
458 rcx_get_new_num_node( losig
, node
, RCX_LOINS
, YES
),
469 /******************************************************************************\
470 Crée les réseaux RC à plat en mémoire lorsqu'il n'y a pas de cache
471 \******************************************************************************/
472 void rcn_flatnet( lofig_list
*lofig
)
474 losig_list
*vss
=NULL
;
475 losig_list
*vssni
=NULL
;
488 vss
= rcx_getvss( lofig
);
489 vssni
= rcx_getvssni( lofig
);
491 /* Il faut renuméroter tous les RC de la lofig avant d'y ajouter les éléments
492 RC des instances pour ne pas avoir de problèmes avec les CTC/
495 for( losig
= lofig
->LOSIG
; losig
; losig
= losig
->NEXT
) {
497 if( !losig
->PRCN
) continue;
499 rcx
= getrcx( losig
);
503 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
504 rcn_changewirenodes( losig
,
506 rcx_get_new_num_node( losig
, wire
->NODE1
, RCX_LOFIG
, NO
),
507 rcx_get_new_num_node( losig
, wire
->NODE2
, RCX_LOFIG
, NO
)
510 for( ctc
= losig
->PRCN
->PCTC
; ctc
; ctc
= ctc
->NEXT
) {
512 ptctc
= (loctc_list
*)ctc
->DATA
;
514 if( ptctc
->SIG1
== losig
)
515 n1
= rcx_get_new_num_node( losig
, ptctc
->NODE1
, RCX_LOFIG
, NO
);
519 if( ptctc
->SIG2
== losig
)
520 n2
= rcx_get_new_num_node( losig
, ptctc
->NODE2
, RCX_LOFIG
, NO
);
524 rcn_changectcnodes( ptctc
, n1
, n2
);
528 for( losig
= lofig
->LOSIG
; losig
; losig
= losig
->NEXT
) {
530 if( !losig
->PRCN
) continue;
532 rcx
= getrcx( losig
);
535 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
537 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
538 locon
= (locon_list
*)chain
->DATA
;
539 if( !rcx_isvalidlocon( locon
) )
541 if( locon
->TYPE
== 'I' ) {
542 ptl
= getptype( locon
->USER
, PTYPERCX
);
544 sigint
= (losig_list
*)ptl
->DATA
;
545 loins
= (loins_list
*)locon
->ROOT
;
546 rcx_mergercn( lofig
, losig
, loins
, sigint
, vss
, vssni
);
555 for( losig
= lofig
->LOSIG
; losig
; losig
= losig
->NEXT
) {
558 for( ctc
= losig
->PRCN
->PCTC
; ctc
; ctc
= ctc
->NEXT
) {
559 ptctc
= (loctc_list
*)ctc
->DATA
;
560 if( getptype( ptctc
->USER
, RCX_COPIED
) )
561 ptctc
->USER
= delptype( ptctc
->USER
, RCX_COPIED
);
563 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
565 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
566 locon
= (locon_list
*)chain
->DATA
;
567 if( !rcx_isvalidlocon( locon
) )
569 if( locon
->TYPE
== 'I' ) {
570 ptl
= getptype( locon
->USER
, PTYPERCX
);
572 sigint
= (losig_list
*)ptl
->DATA
;
573 for( ctc
= sigint
->PRCN
->PCTC
; ctc
; ctc
= ctc
->NEXT
) {
574 ptctc
= (loctc_list
*)ctc
->DATA
;
575 if( getptype( ptctc
->USER
, RCX_COPIED
) )
576 ptctc
->USER
= delptype( ptctc
->USER
, RCX_COPIED
);
585 /******************************************************************************\
586 Drive les éléments RC d'un signal d'une lofig.
587 \******************************************************************************/
588 void rcx_dumpnet( rcxfile
*file
, losig_list
*losig
)
591 chain_list
*scanchain
;
599 rcxint
= getrcx( losig
);
600 if( !GETFLAG( rcxint
->FLAG
, RCXNOWIRE
) ) {
601 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
) {
602 rcx_drive_wire( file
,
603 rcx_get_new_num_node( losig
, wire
->NODE1
, RCX_LOFIG
, YES
),
604 rcx_get_new_num_node( losig
, wire
->NODE2
, RCX_LOFIG
, YES
),
611 for( scanchain
= losig
->PRCN
->PCTC
;
613 scanchain
= scanchain
->NEXT
)
616 loctc
= (loctc_list
*)scanchain
->DATA
;
617 node
= rcn_ctcnode( loctc
, losig
);
618 sigagr
= rcn_ctcothersig( loctc
, losig
);
619 nodeagr
= rcn_ctcothernode( loctc
, losig
);
621 rcxagr
= getrcx( sigagr
);
623 if( !rcxagr
&& !rcx_isbellow( sigagr
) ) {
624 if( rcx_isnotinfluentagressor( losig
, sigagr
) )
625 rcx_drive_ctcni_capa( file
,
626 rcx_get_new_num_node( losig
, node
, RCX_LOFIG
, YES
),
630 rcx_drive_ground_capa( file
,
631 rcx_get_new_num_node( losig
, node
, RCX_LOFIG
, YES
),
636 rcx_drive_ctc_capa( file
,
637 rcx_get_new_num_node( losig
, node
, RCX_LOFIG
, YES
),
639 rcx_getsigname( sigagr
),
640 rcx_get_new_num_node( sigagr
, nodeagr
, RCX_LOFIG
, YES
)
645 /******************************************************************************\
647 Réalise le merge d'un losig d'une instance sur un signal externe. Utilise les
648 BELLOW créés par rcx_dump_loins.
649 Les vrais capacités de couplage qui ont été copiées ont un ptype RCX_COPIED, il
650 ne faudra plus les copier.
651 \******************************************************************************/
652 void rcx_mergercn( lofig_list
*lofig
,
654 loins_list
*scanloins
,
660 losig_list
*pseudovssins
;
661 losig_list
*pseudovssinsni
;
663 chain_list
*scanchain
;
668 losig_list
*sigagrext
;
670 losig_list
*sigbellow
;
673 pseudovssins
= getrcxpseudovss( scanloins
->USER
);
674 pseudovssinsni
= rcx_loinsgetvssni( scanloins
);
676 if( !sigint
->PRCN
) return;
678 rcxext
= getrcx( sigext
);
679 for( wire
= sigint
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
684 rcx_get_new_num_node( sigint
, wire
->NODE1
, RCX_LOINS
, NO
),
685 rcx_get_new_num_node( sigint
, wire
->NODE2
, RCX_LOINS
, NO
)
688 for( scanchain
= sigint
->PRCN
->PCTC
;
690 scanchain
= scanchain
->NEXT
)
693 loctc
= (loctc_list
*)scanchain
->DATA
;
694 node
= rcn_ctcnode( loctc
, sigint
);
695 sigagr
= rcn_ctcothersig( loctc
, sigint
);
696 nodeagr
= rcn_ctcothernode( loctc
, sigint
);
698 if( sigagr
== pseudovssins
)
699 addloctc( sigext
, rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
704 if( sigagr
== pseudovssinsni
)
705 addloctc( sigext
, rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
710 if( sigagr
!= pseudovssins
&&
711 sigagr
!= pseudovssinsni
&&
712 !getptype( loctc
->USER
, RCX_COPIED
) )
715 if( getptype( sigagr
->USER
, RCX_UNRESOLVEDSIG
) ) {
716 // L'agresseur n'a pas été lu, il correspond à un signal interne.
717 pt
= getptype( sigagr
->USER
, RCX_COPIED
);
720 // ce cas n'arrive jamais. Il a été traité dans rcx_dump_loins()
721 rcx_error(27,sigagr
, AVT_ERROR
);
724 sigbellow
= (losig_list
*)(pt
->DATA
);
726 addloctc( sigext
, rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
733 pt
= getptype( loctc
->USER
, RCX_COPIED
);
735 loctc
->USER
= addptype( loctc
->USER
, RCX_COPIED
, NULL
);
737 sigagrext = ((locon_list*)
738 (getptype( sigagr->USER, RCX_LOCONINS )->DATA ))->SIG;
740 sigagrext
= rcx_get_out_ins_sig( sigagr
);
741 if( getrcx( sigagrext
) ) {
742 if( sigext
!= sigagrext
) {
745 rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
747 rcx_get_new_num_node( sigagr
, nodeagr
, RCX_LOINS
, NO
),
753 // Cas où l'agresseur est un signal ordinaire qui est connecté en
754 // externe à vdd ou vss.
755 if( tlc_islosigalim( sigagrext
) )
757 rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
764 rcx_get_new_num_node( sigint
, node
, RCX_LOINS
, NO
),
776 lofig
=NULL
; //unused parameter
779 /******************************************************************************\
781 Dans le cas où les résistance ne sont pas prise en compte, transfère la
782 capacité des connecteurs internes vers le connecteur externe.
783 sigint est un losig dans une instance.
784 \******************************************************************************/
785 void rcx_trsfloinscapa( lofig_list
*lofig
,
790 locon_list
*loconext
;
791 locon_list
*loconint
;
794 loconext
= (locon_list
*)( getptype( sigint
->USER
, RCX_LOCONINS
)->DATA
);
795 rcxint
= getrcx( sigint
);
797 for( chain
= rcxint
->RCXINTERNAL
; chain
; chain
= chain
->NEXT
) {
798 loconint
= (locon_list
*)(chain
->DATA
);
799 rcx_add_capa_from_instance_to_figure( loins
, lofig
, loconint
, loconext
);
802 if( rcxint
->RCXEXTERNAL
) {
804 for (cl
=rcxint
->RCXEXTERNAL
; cl
!=NULL
; cl
=cl
->NEXT
)
805 rcx_add_capa_from_instance_to_figure( loins
,
807 (locon_list
*)cl
->DATA
,
813 /******************************************************************************\
814 rcx_buildrcxnowire();
815 Conserve le nombre minimum de locon sur une vue RCX si celle-ci est type nowire.
817 Si le signal est externe, on ne conserve que le connecteur externe.
818 Si le signal est interne, on ne conserve que le connecteur qui a le meme nom que
820 Si aucun connecteur ne correspond, on prend un connecteur et on lui colle le
822 \******************************************************************************/
823 void rcx_buildrcxnowire( lofig_list
*lofig
, losig_list
*losig
)
830 locon_list
*goodlocon
;
832 rcx
= getrcx( losig
);
834 if( !rcx
->RCXEXTERNAL
&& !rcx
->RCXINTERNAL
)
837 // On cherche le locon qui va rester.
840 if( rcx
->RCXEXTERNAL
) {
841 goodlocon
= rcx
->RCXEXTERNAL
->DATA
;
842 name
= getloconrcxname( goodlocon
);
845 name
= rcx_getsigname( losig
);
846 for( chain
= rcx
->RCXINTERNAL
; chain
; chain
= chain
->NEXT
) {
847 locon
= (locon_list
*)(chain
->DATA
);
848 if( getloconrcxname( locon
) == name
) {
855 for( chain
= rcx
->RCXINTERNAL
; chain
; chain
= chain
->NEXT
) {
856 locon
= (locon_list
*)(chain
->DATA
);
864 goodlocon
= (locon_list
*)(rcx
->RCXINTERNAL
->DATA
);
866 // On efface les autres.
869 for( chain
= rcx
->RCXINTERNAL
; chain
; chain
= chain
->NEXT
) {
870 locon
= (locon_list
*)(chain
->DATA
);
871 if( locon
== goodlocon
)
873 rcx_add_capa_locon( lofig
, goodlocon
, locon
);
874 rcx_freeloconcapa( lofig
, NULL
, locon
);
876 // Libère les locons alloués par RCX
877 freenum( locon
->PNODE
); locon
->PNODE
= NULL
;
879 freercxlocon( locon
);
882 freechain( rcx
->RCXINTERNAL
); rcx
->RCXINTERNAL
= NULL
;
883 if( !rcx
->RCXEXTERNAL
)
884 rcx
->RCXINTERNAL
= addchain( NULL
, goodlocon
);
886 if( getloconrcxname( goodlocon
) != name
)
887 addloconrcxname( goodlocon
, name
);
891 /******************************************************************************\
893 Met les vues RCX à plat. Fonctionne avec ou sans cache.
894 Dans la boucle des losigs, les réseaux RC ont leurs index de noeud d'origine.
895 Par contre, les connecteurs sont renumérotés au fur et à mesure qu'on les
897 \******************************************************************************/
899 void buildrcx( currentfig
)
900 lofig_list
*currentfig
;
906 loins_list
*scanloins
;
907 locon_list
*scanlocon
;
911 chain_list
*chainlosig
;
914 MBK_OFFSET_MAX offset
;
915 chain_list
*headlosig
;
918 lowire_list
*lw
, *nlw
;
921 if( (origcache
=(rcn_getlofigcache( currentfig
))!=NULL
) || V_BOOL_TAB
[__TAS_ALWAYS_USE_CACHE
].VALUE
)
926 file
= rcx_init_driver( currentfig
, iscache
);
929 fileacces
= mbk_getfileacces( file
->FD
);
931 headlosig
= rcx_driver_sort_losig( currentfig
);
932 rcx_build_new_num_node( currentfig
);
934 for( chainlosig
= headlosig
; chainlosig
; chainlosig
= chainlosig
->NEXT
)
936 if( chainlosig
->DATA
== NULL
) {
937 rcx_end_external( file
);
941 sigext
= (losig_list
*)chainlosig
->DATA
;
942 rcxext
= getrcx( sigext
);
946 if( rcx_has_rc_timings( sigext
) )
947 SETFLAG( rcxext
->FLAG
, RCXIGNORE
);
949 if( rcx_state( rcxext
, RCX_STATE_LOFIG
) == RCX_STATE_EMPTY
)
950 set_ext_rcn( sigext
);
952 rcn_lock_signal( currentfig
, sigext
);
954 if( !rcx_iscrosstalk( currentfig
, sigext
, RCX_TEST_ONE
))
955 SETFLAG( rcxext
->FLAG
, RCXNOCTC
);
957 if( setrcxmodel( currentfig
, sigext
, RCX_BEST
) == RCX_NORCTC
&&
958 V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL0
)
960 rcn_unlock_signal( currentfig
, sigext
);
964 rcx_repair_pnode( sigext
);
966 rcx_drive_signal_header( file
, sigext
, rcxext
);
968 if( !mbkftell( file
->FD
, &offset
))
969 avt_errmsg( TRC_ERRMSG
, "034", AVT_FATAL
, file
->FILENAME
);
971 mbk_losig_setfilepos( currentfig
,
979 rcx_drive_begin_net( file
);
981 rcx_dumpnet( file
, sigext
);
983 for( chain
= (chain_list
*)getptype( sigext
->USER
, LOFIGCHAIN
)->DATA
;
988 scanlocon
= (locon_list
*)chain
->DATA
;
989 if( !rcx_isvalidlocon( scanlocon
) )
994 if( scanlocon
->TYPE
== 'I' ) {
995 scanloins
= (loins_list
*)scanlocon
->ROOT
;
996 if( (pt
= getptype(scanlocon
->USER
,PTYPERCX
) ) ) {
997 sigint
= (losig_list
*)(pt
->DATA
);
998 rcxint
= getrcx( sigint
);
999 if (countchain(rcxint
->RCXEXTERNAL
)>1)
1000 avt_errmsg( TRC_ERRMSG
, "053", AVT_FATAL
, scanloins
->FIGNAME
);
1007 if( rcx_state( rcxint
, RCX_STATE_LOINS
) == RCX_STATE_NORCX
) {
1008 merge_ext( file
, sigext
, scanlocon
, iscache
, YES
);
1009 rcx_trsfnodelocon( scanlocon
, RCX_LOFIG
);
1012 rcx_dump_loins( file
, currentfig
, scanloins
, sigint
);
1013 rcx_trsfdriver( currentfig
, sigext
, rcxext
, sigint
, rcxint
);
1014 name
= concatname( rcx_getinsname( scanloins
),
1015 rcx_getsigname( sigint
)
1017 rcx_addorigin( currentfig
, sigext
, name
);
1018 if( !GETFLAG( rcxext
->FLAG
, RCXNOWIRE
) &&
1019 !GETFLAG( rcxint
->FLAG
, RCXNOWIRE
) )
1020 rcx_copyrcx( currentfig
, sigext
, scanloins
, sigint
);
1022 rcx_trsfloinscapa( currentfig
, scanloins
, sigint
);
1023 merge_ext( file
, sigext
, scanlocon
, iscache
, NO
);
1024 rcx_trsfnodelocon( scanlocon
, RCX_LOFIG
);
1026 rcn_addcapa( sigext
, rcn_getnetcapa( sigint
) );
1030 if( scanlocon
->TYPE
== 'T' ) {
1031 merge_ext( file
, sigext
, scanlocon
, iscache
, YES
);
1032 rcx_trsfnodelocon( scanlocon
, RCX_LOFIG
);
1035 if( scanlocon
->TYPE
== 'E' ) {
1036 rcx_trsfnodelocon( scanlocon
, RCX_LOFIG
);
1041 if( GETFLAG( rcxext
->FLAG
, RCXNOWIRE
) ) {
1042 rcx_buildrcxnowire( currentfig
, sigext
);
1045 rcx_drive_end_net( file
);
1046 rcxprintlocon( file
, rcxext
);
1047 rcxprintorigin( file
, sigext
);
1048 rcx_drive_signal_end( file
, sigext
);
1050 rcn_unlock_signal( currentfig
, sigext
);
1051 if( rcn_islock_signal( currentfig
, sigext
) == YES
)
1052 avt_errmsg( TRC_ERRMSG
, "041", AVT_WARNING
, rcx_getsigname( sigext
) );
1053 rcn_flush_signal( currentfig
, sigext
);
1056 freechain( headlosig
);
1059 rcn_flatnet( currentfig
);
1061 rcx_clear_new_num_node( currentfig
);
1063 rcx_drive_end( file
, currentfig
);
1065 // Vire le contenu des instances
1066 for( scanloins
= currentfig
->LOINS
; scanloins
; scanloins
= scanloins
->NEXT
)
1067 rcx_cleanloins( scanloins
);
1069 // Création des tables de hash
1070 for( sigext
= currentfig
->LOSIG
; sigext
; sigext
= sigext
->NEXT
)
1073 if( tlc_islosigalim( sigext
) )
1076 /* Modif Grégoire le 19 Mai 2003. Grosse bidouille immonde.
1077 TAS récupère les vecteurs sous la forme toto[23] car c'est comme ca que
1078 Yagle crée les noms. Pb : MBK/RCX n'est pas informé de ce nommage. On le
1079 fait donc maintenant ici.
1081 strcpy( buffer
, rcx_getsigname( sigext
) );
1083 rcx_addhtrcxsigbyname( NULL
, currentfig
, sigext
, namealloc( buffer
) );
1085 rcxext
= getrcx( sigext
);
1086 if( !rcxext
) continue;
1088 for (chain
=rcxext
->RCXEXTERNAL
; chain
!=NULL
; chain
=chain
->NEXT
)
1089 rcx_addhtrcxcon( NULL
, currentfig
, (locon_list
*)chain
->DATA
);
1090 for( chain
= rcxext
->RCXINTERNAL
; chain
; chain
= chain
->NEXT
)
1091 rcx_addhtrcxcon( NULL
, currentfig
, (locon_list
*)chain
->DATA
);
1094 for( scanloins
= currentfig
->LOINS
; scanloins
; scanloins
= scanloins
->NEXT
)
1095 rcx_addhtrcxmod( currentfig
,
1096 rcx_getinsname( scanloins
),
1101 // Elimination de l'ancien cache
1102 rcn_disable_cache( currentfig
);
1105 for( sigext
= currentfig
->LOSIG
; sigext
; sigext
= sigext
->NEXT
)
1109 for (lw
=sigext
->PRCN
->PWIRE
; lw
!=NULL
; lw
=nlw
)
1114 sigext
->PRCN
->PWIRE
=NULL
;
1115 while( sigext
->PRCN
->PCTC
)
1116 delloctc( (loctc_list
*)sigext
->PRCN
->PCTC
->DATA
);
1117 sigext
->PRCN
->PCTC
=NULL
;
1121 // Met en route le nouveau cache
1122 rcx_reload( currentfig
, fileacces
);
1127 void rcx_exit( code
)
1132 "\n\n*** RCX : abnormal terminaison. Exit code %d ***\n\n",
1135 avt_log(LOGTRC
,2, "Exit code %d\n", code
);
1139 /******************************************************************************\
1140 Mémorise et retrouve les agresseurs d'un signal.
1141 insname est le nom d'instance de la lofig.
1142 rcx_getagrlistfast() renvoie EMPTYHY si on a jamais traité ce signal dans
1144 \******************************************************************************/
1145 chain_list
* rcx_getagrlistfast( lofig_list
*lofig
,
1153 chain_list
*headagr
;
1159 // Récupère la table des instances de cette lofig.
1160 // Il s'agit des différents noms sous laquelle est instanciée cette lofig. Il
1161 // ne s'agit pas d'un table pour accéder rapidement à un LOINS de cette lofig.
1162 ptl
= getptype( lofig
->USER
, RCX_HTAGR
);
1163 if( !ptl
) return (chain_list
*)EMPTYHT
;
1164 htins
=(ht
*)ptl
->DATA
;
1166 // Récupère la table des signaux.
1167 htsig
= (ht
*)gethtitem( htins
, insname
);
1168 if( htsig
== (ht
*)EMPTYHT
|| htsig
== (ht
*)DELETEHT
)
1169 return (chain_list
*)EMPTYHT
;
1171 // Récupère la liste des agresseurs.
1172 headagr
= (chain_list
*)gethtitem( htsig
, victime
);
1173 if( headagr
== (chain_list
*)EMPTYHT
|| headagr
== (chain_list
*)DELETEHT
)
1174 return (chain_list
*)EMPTYHT
;
1176 // Il ne reste plus qu'a placer les REALAGRESSOR.
1177 for( scan
= headagr
; scan
; scan
= scan
->NEXT
) {
1178 param
= (rcxparam
*)scan
->DATA
;
1179 for( chain
= param
->SIGLOCAL
; chain
; chain
= chain
->NEXT
) {
1180 losig
= (losig_list
*)chain
->DATA
;
1181 losig
->USER
= addptype( losig
->USER
, RCX_REALAGRESSOR
, param
);
1183 if( !getptype( param
->SIGNAL
->USER
, RCX_REALAGRESSOR
) )
1184 param
->SIGNAL
->USER
= addptype( param
->SIGNAL
->USER
,
1193 void rcx_setagrlistfast( lofig_list
*lofig
,
1195 losig_list
*victime
,
1206 // Récupère la table des instances de cette lofig.
1207 // Il s'agit des différents noms sous laquelle est instanciée cette lofig. Il
1208 // ne s'agit pas d'un table pour accéder rapidement à un LOINS de cette lofig.
1209 ptl
= getptype( lofig
->USER
, RCX_HTAGR
);
1211 lofig
->USER
= addptype( lofig
->USER
, RCX_HTAGR
, addht(1) );
1214 htins
=(ht
*)ptl
->DATA
;
1216 // Récupère la table des signaux.
1217 htsig
=(ht
*)gethtitem( htins
, insname
);
1218 if( htsig
== (ht
*)EMPTYHT
|| htsig
== (ht
*)DELETEHT
) {
1220 addhtitem( htins
, insname
, (long)htsig
);
1224 // Récupère la liste des agresseurs.
1226 oldagr
= (chain_list
*)gethtitem( htsig
, victime
);
1227 if( oldagr
!= (chain_list
*)EMPTYHT
&& oldagr
!= (chain_list
*)DELETEHT
)
1228 rcx_error( 30, NULL
, AVT_ERROR
);
1230 addhtitem( htsig
, victime
, (long)headagr
);
1233 /******************************************************************************\
1236 - Récupère une liste de rcxparam correspondant aux agresseurs possédant une vue
1237 rcx et n'étant pas marqué NI par la fonction rcx_checkcrosstalk().
1238 - Place dans chaque agresseur local un ptype RCX_REALAGRESSOR vers le rcxparam.
1240 \******************************************************************************/
1242 chain_list
* rcx_getagrlist( lofig_list
*lofig
,
1243 losig_list
*victime
,
1245 chain_list
*chainfig
1249 chain_list
*scanctc
;
1251 losig_list
*agresseur
;
1253 chain_list
*headagr
;
1254 chain_list
*scanagr
;
1261 if( RCX_FASTMODE
) {
1262 headagr
= rcx_getagrlistfast( lofig
, insname
, victime
);
1263 if( headagr
!= (chain_list
*)EMPTYHT
)
1267 rcx
= getrcx( victime
);
1269 if( rcx_state( rcx
, RCX_STATE_LOFIG
) != RCX_STATE_TYPED
)
1271 if( !GETFLAG( rcx
->FLAG
, MODELRCN
) )
1272 rcx_error(31,NULL
, AVT_ERROR
);
1278 if( ! GETFLAG( rcx
->FLAG
, RCXCTCDONE
) ) {
1279 if( !rcx_iscrosstalk( lofig
, victime
, RCX_TEST_LIMIT
))
1280 SETFLAG( rcx
->FLAG
, RCXNOCTC
);
1281 SETFLAG( rcx
->FLAG
, RCXCTCDONE
);
1284 if( ! GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1286 rcn_lock_signal( lofig
, victime
);
1287 rcx_checkcrosstalk( victime
);
1289 for( scanctc
= victime
->PRCN
->PCTC
; scanctc
; scanctc
= scanctc
->NEXT
) {
1291 ctc
= (loctc_list
*)scanctc
->DATA
;
1292 agresseur
= rcn_ctcothersig( ctc
, victime
);
1294 if( tlc_islosigalim( agresseur
) )
1297 if( rcx_isnotinfluentagressor( victime
, agresseur
) )
1301 ptl
= getptype( agresseur
->USER
, RCX_REALAGRESSOR
);
1303 param
= (rcxparam
*)ptl
->DATA
;
1305 real
= rcx_gethierlosig( agresseur
,
1312 if( real
!= agresseur
)
1313 ptl
= getptype( real
->USER
, RCX_REALAGRESSOR
);
1316 rcxagr
= getrcx( real
);
1317 if( rcx_state( rcxagr
, RCX_STATE_LOFIG
) == RCX_STATE_TYPED
) {
1319 param
= rcx_allocrcxparam();
1320 param
->LOFIG
= deffig
;
1321 param
->INSNAME
= defins
;
1322 param
->SIGNAL
= real
;
1323 param
->SIGLOCAL
= addchain( NULL
, agresseur
);
1325 agresseur
->USER
= addptype( agresseur
->USER
,
1329 if( real
!= agresseur
)
1330 real
->USER
= addptype( real
->USER
,
1334 headagr
= addchain( headagr
, param
);
1339 param
= (rcxparam
*)ptl
->DATA
;
1340 param
->SIGLOCAL
= addchain( param
->SIGLOCAL
, agresseur
);
1341 agresseur
->USER
= addptype( agresseur
->USER
,
1350 param
->CC
= param
->CC
+ ctc
->CAPA
;
1352 rcn_unlock_signal( lofig
, victime
);
1355 for( scanagr
= headagr
; scanagr
; scanagr
= scanagr
->NEXT
) {
1356 param
= (rcxparam
*)(scanagr
->DATA
);
1361 rcx_setagrlistfast( lofig
, insname
, victime
, headagr
);
1366 rcxparam
* rcx_allocrcxparam( void )
1369 param
= (rcxparam
*)mbkalloc( sizeof( rcxparam
) );
1370 param
->LOFIG
= NULL
;
1371 param
->INSNAME
= NULL
;
1372 param
->SIGNAL
= NULL
;
1373 param
->FMINUP
= 0.0;
1375 param
->FMINDW
= 0.0;
1381 param
->SIGLOCAL
= NULL
;
1385 void rcx_freeagrlist( lofig_list
*lofig
,
1386 losig_list
*victime
,
1387 chain_list
*agresseurs
1391 chain_list
*siglocal
;
1395 for( scan
= agresseurs
; scan
; scan
=scan
->NEXT
) {
1397 param
= ((rcxparam
*)(scan
->DATA
));
1401 rcx_error(20,NULL
, AVT_WARNING
);
1404 for( siglocal
= param
->SIGLOCAL
; siglocal
; siglocal
= siglocal
->NEXT
) {
1405 losig
= (losig_list
*)siglocal
->DATA
;
1407 if( !getptype( losig
->USER
, RCX_REALAGRESSOR
) )
1408 rcx_error(32,NULL
, AVT_WARNING
);
1410 losig
->USER
= delptype( losig
->USER
, RCX_REALAGRESSOR
);
1412 if( getptype( param
->SIGNAL
->USER
, RCX_REALAGRESSOR
) )
1413 param
->SIGNAL
->USER
= delptype( param
->SIGNAL
->USER
, RCX_REALAGRESSOR
);
1415 if( !RCX_FASTMODE
) {
1416 freechain( param
->SIGLOCAL
);
1422 freechain( agresseurs
);
1428 /******************************************************************************\
1429 Renvoie le front réel sans la contribution du signal.
1435 cc : somme des capacité de couplage entre la paire de signaux.
1436 cca : somme des capacité de couplage sur le signal.
1437 fcc : front calculé avec les agresseurs actifs
1438 f0 : front sans agression.
1440 Si cca vaut 0, le fcc est renvoyé.
1441 \******************************************************************************/
1443 RCXFLOAT
rcx_realslope( RCXFLOAT cc
, RCXFLOAT cca
, RCXFLOAT fcc
, RCXFLOAT f0
)
1448 f
= ( f0
- fcc
) * ( cc
- cca
) / cca
+ f0
;
1455 /******************************************************************************\
1456 Calcule l'effet miller entre 2 fronts.
1457 type = RCX_SAME | RCX_OPPOSITE
1458 model = RCX_MILLER2C ( capa entre 0C 2C ) | RCX_MILLER4C ( capa entre -C et 4C )
1459 \******************************************************************************/
1461 RCXFLOAT
rcx_getmiller( RCXFLOAT fvic
, RCXFLOAT fagr
, char type
, char model
)
1465 if( type
== RCX_SAME
) {
1466 if( model
== RCX_MILLER2C
) {
1468 m
= (fagr
-fvic
)/fagr
;
1473 if( fvic
< 2.0 * fagr
)
1474 m
= (fagr
-fvic
)/fagr
;
1480 if( type
== RCX_OPPOSITE
) {
1481 if( model
== RCX_MILLER2C
) {
1483 m
= (fvic
+fagr
)/fagr
;
1488 if( fvic
< 2.0 * fagr
)
1489 m
= (fvic
+fagr
)/fagr
;
1498 /******************************************************************************\
1499 Renvoie la valeur d'une capacité prenant en compte l'effet Miller. Les fronts
1500 sont corrigés pour ne pas être pris de façon trop pessimiste.
1501 type : RCX_MIN | RCX_MAX.
1502 \******************************************************************************/
1504 RCXFLOAT
rcx_capamiller( losig_list
*victime
,
1520 if( rcx_crosstalkactive( RCX_QUERY
) == RCX_NOCROSSTALK
)
1523 sigagr
= (loctc
->SIG1
== victime
? loctc
->SIG2
: loctc
->SIG1
);
1525 ptl
= getptype( sigagr
->USER
, RCX_REALAGRESSOR
);
1529 param
= (rcxparam
*)ptl
->DATA
;
1531 if( type
== RCX_MIN
&& (param
->ACTIF
& RCX_AGRBEST
) == RCX_AGRBEST
) {
1533 switch( RCX_CTK_SLOPE_MILLER
) {
1535 case RCX_SLOPE_NOMINAL
:
1537 fvmax
= slope
->F0MAX
;
1538 if( slope
->SENS
== TRC_SLOPE_UP
)
1539 famin
= param
->F0UP
;
1541 famin
= param
->F0DW
;
1544 case RCX_SLOPE_CTK
:
1546 fvmax
= slope
->FCCMAX
;
1547 if( slope
->SENS
== TRC_SLOPE_UP
)
1548 famin
= param
->FMINUP
;
1550 famin
= param
->FMINDW
;
1554 rcx_error( 33, victime
, AVT_FATAL
);
1557 switch( RCX_CTK_MODEL
) {
1559 case RCX_MILLER_0C2C
:
1563 case RCX_MILLER_NC3C
:
1564 m
= rcx_getmiller( fvmax
, famin
, RCX_SAME
, RCX_MILLER4C
);
1567 case RCX_MILLER_NOMINAL
:
1568 m
= rcx_getmiller( fvmax
, famin
, RCX_SAME
, RCX_MILLER2C
);
1572 rcx_error( 34, victime
, AVT_FATAL
);
1575 cc
= loctc
->CAPA
* m
;
1578 if( type
== RCX_MAX
&& (param
->ACTIF
& RCX_AGRWORST
) == RCX_AGRWORST
) {
1580 switch( RCX_CTK_SLOPE_MILLER
) {
1582 case RCX_SLOPE_NOMINAL
:
1584 fvmax
= slope
->F0MAX
;
1585 if( slope
->SENS
== TRC_SLOPE_UP
)
1586 famin
= param
->F0DW
;
1588 famin
= param
->F0UP
;
1592 case RCX_SLOPE_CTK
:
1594 fvmax
= slope
->FCCMAX
;
1595 if( slope
->SENS
== TRC_SLOPE_UP
)
1596 famin
= param
->FMINDW
;
1598 famin
= param
->FMINUP
;
1603 rcx_error(35,victime
, AVT_FATAL
);
1606 switch( RCX_CTK_MODEL
) {
1608 case RCX_MILLER_0C2C
:
1612 case RCX_MILLER_NC3C
:
1613 m
= rcx_getmiller( fvmax
, famin
, RCX_OPPOSITE
, RCX_MILLER4C
);
1616 case RCX_MILLER_NOMINAL
:
1617 m
= rcx_getmiller( fvmax
, famin
, RCX_OPPOSITE
, RCX_MILLER2C
);
1621 rcx_error( 13, victime
, AVT_FATAL
);
1624 cc
= loctc
->CAPA
* m
;
1631 if( rcx_isnotinfluentagressor( victime
, sigagr
) ) {
1637 cc
= 2.0 * loctc
->CAPA
;
1646 /******************************************************************************\
1647 Flags entre deux signaux couplés.
1648 La fonction rcx_getflagcoupled() renvoie seulement les bits sélectionnés si flag
1649 est différent de 0, et la totalité des bits si flag vaut 0.
1650 \******************************************************************************/
1652 void rcx_setflagcoupled( losig_list
*victime
, losig_list
*agresseur
, long flag
)
1656 f
= rcn_getcoupledinformation( victime
, agresseur
, RCXLOSIGFLAG
);
1657 rcn_setcoupledinformation( victime
, agresseur
, f
|flag
, RCXLOSIGFLAG
);
1660 int rcx_getflagcoupled( losig_list
*victime
, losig_list
*agresseur
, long flag
)
1664 f
= rcn_getcoupledinformation( victime
, agresseur
, RCXLOSIGFLAG
);
1670 void rcx_clearflagcoupled( losig_list
*victime
,
1671 losig_list
*agresseur
,
1676 f
= rcn_getcoupledinformation( victime
, agresseur
, RCXLOSIGFLAG
);
1677 rcn_setcoupledinformation( victime
, agresseur
, f
& ~flag
, RCXLOSIGFLAG
);
1680 void rcx_freeflagcoupled( losig_list
*victime
)
1682 rcn_freecoupledinformation( victime
, RCXLOSIGFLAG
);
1685 /******************************************************************************\
1686 Impose que l'agresseur est à considérer comme non influent, c'est à dire qu'on
1687 le considère toujours actif pour ne pas l'avoir dans le stboverlapdev.
1688 \******************************************************************************/
1690 int rcx_isnotinfluentagressor( losig_list
*victime
, losig_list
*agresseur
)
1692 if( rcx_getflagcoupled( victime
, agresseur
, RCX_NI_LOSIG
)== RCX_NI_LOSIG
)
1694 if( getptype( agresseur
->USER
, RCX_VSSNI
) )
1699 void rcx_setnotinfluentagressor( losig_list
*victime
, losig_list
*agresseur
)
1703 rcx
= getrcx( victime
);
1704 if( !rcx
|| GETFLAG( rcx
->FLAG
, RCXNOCTC
) ) return;
1706 rcx_setflagcoupled( victime
, agresseur
, RCX_NI_LOSIG
);
1709 void rcx_clearnotinfluentagressor( losig_list
*victime
, losig_list
*agresseur
)
1711 rcx_clearflagcoupled( victime
, agresseur
, RCX_NI_LOSIG
);
1714 int rcx_iscrosstalkcapa( loctc_list
*loctc
, losig_list
*losig
)
1719 rcx
= getrcx( losig
);
1723 if( GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1724 // On considère que toutes les CTC sont des capacités à la masse.
1727 sigagr
= rcn_ctcothersig( loctc
, losig
);
1729 if( getrcx( sigagr
) ) {
1733 if( rcx_isnotinfluentagressor( losig
, sigagr
) ) {
1734 // Capa de couplage non significative, mais capa de couplage quand même...
1738 if( rcx_isbellow( sigagr
) ) {
1745 int rcx_crosstalkactive( int model
)
1747 if( model
!= RCX_QUERY
)
1748 RCX_CROSSTALK
= model
;
1749 return RCX_CROSSTALK
;
1752 void rcx_freewire( losig_list
*losig
)
1755 rcx
= getrcx( losig
);
1756 SETFLAG( rcx
->FLAG
, RCXNOWIRE
);
1760 void rcx_freectc( losig_list
*losig
)
1763 rcx
= getrcx( losig
);
1765 SETFLAG( rcx
->FLAG
, RCXNOCTC
);
1768 int setrcxmodel( lofig_list
*lofig
, losig_list
*losig
, int request
)
1780 return( RCX_NORCTC
);
1782 if( rcx_isbellow( losig
) )
1783 return( RCX_NORCTC
);
1785 if( tlc_islosigalim( losig
) ) {
1786 return( RCX_NORCTC
);
1789 rcx
= getrcx( losig
);
1790 if( !rcx
) return( RCX_NORCTC
);
1794 SETFLAG( rcx
->FLAG
, RCXNOCTC
);
1797 if( losig
->TYPE
!='E')
1798 SETFLAG( rcx
->FLAG
, RCXNOWIRE
);
1801 SETFLAG( rcx
->FLAG
, RCXNOWIRE
);
1802 SETFLAG( rcx
->FLAG
, RCXNOCTC
);
1807 rcx_error( 36, losig
, AVT_FATAL
);
1810 hasdelayrc
= rcx_isrcdelay( lofig
, losig
);
1811 if( !hasdelayrc
) rcx_freewire( losig
);
1813 if( GETFLAG( rcx
->FLAG
, RCXNOWIRE
) && GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1814 retval
= RCX_NORCTC
;
1815 if( !GETFLAG( rcx
->FLAG
, RCXNOWIRE
) && GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1817 if( GETFLAG( rcx
->FLAG
, RCXNOWIRE
) && !GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1819 if( !GETFLAG( rcx
->FLAG
, RCXNOWIRE
) && !GETFLAG( rcx
->FLAG
, RCXNOCTC
) )
1822 if( retval
== RCX_NORCTC
&& V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
== ELP_CAPA_LEVEL0
) {
1823 // On met seulement la capa à jour
1824 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
1826 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
1827 locon
= (locon_list
*)chain
->DATA
;
1828 if( !rcx_isvalidlocon( locon
) )
1830 rcx_getloinscapa( locon
, &cm
, &ccl
, &ccg
);
1831 rcn_addcapa( losig
, cm
+ ccl
);
1834 // Force le calcul de la capa de RCN
1835 rcn_getcapa( lofig
, losig
);
1842 char* rcx_isbellow( losig
)
1846 ptl
= getptype( losig
->USER
, RCX_BELLOW
);
1848 return (char*)ptl
->DATA
;
1852 int rcx_isloop( ptrcx
, losig
)
1858 lonode_list
*ptnode
;
1860 chain_list
*headpack
;
1861 chain_list
*scanpack
;
1862 rcx_triangle
*pack
;
1864 if( GETFLAG( ptrcx
->FLAG
, RCXHASNOLOOP
) ) return 0;
1865 if( GETFLAG( ptrcx
->FLAG
, RCXHASLOOP
) ) return 1;
1867 if( RCX_USING_AWEMATRIX
== RCX_USING_AWEMATRIX_FORCE
) {
1868 /* Le 6/04/2005, il y a une boucle infinie chez Sony dans le
1869 parcours des rc : lorsqu'on est en mode force, on considère
1870 que tous les rc ont des boucles et il ne faut surtout pas
1871 passer par rcn_treetrip */
1872 SETFLAG( ptrcx
->FLAG
, RCXHASLOOP
);
1876 avt_logenterfunction(LOGTRC
,2, "rcx_isloop()");
1878 clearallwireflag( losig
, RCN_FLAG_PASS
);
1879 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
1880 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
1882 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
) {
1884 ptnode
= getlonode( losig
, wire
->NODE1
) ;
1885 if( RCN_GETFLAG( ptnode
->FLAG
, RCN_FLAG_PASS
) )
1888 r
= rcn_treetrip( losig
,
1890 (int (*)(losig_list
*,lonode_list
*,lowire_list
*,void*)) rcx_up_forloop
,
1891 (int (*)(losig_list
*,lonode_list
*,chain_list
*,ht
*,void*))
1893 (int (*)(losig_list
*,lonode_list
*,void*,void*)) rcx_up_pack_forloop
,
1898 if( r
== RCNTREETRIPLOOP
) {
1899 SETFLAG( ptrcx
->FLAG
, RCXHASLOOP
);
1905 SETFLAG( ptrcx
->FLAG
, RCXHASNOLOOP
);
1907 if( GETFLAG( ptrcx
->FLAG
, RCXHASNOLOOP
) ) {
1908 if ( avt_islog(2,LOGTRC
) ) {
1909 avt_log(LOGTRC
,2,"no loop found\n" );
1911 avt_logexitfunction(LOGTRC
,2);
1915 if( GETFLAG( ptrcx
->FLAG
, RCXHASLOOP
) ) {
1916 avt_log(LOGTRC
,2,"loop found\n" );
1917 /* il faut effacer les triangles qui ont commencés à être construits */
1918 htpack
= addht( 100 );
1920 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
) {
1921 pack
= rcn_getpack( losig
, wire
);
1923 if( gethtitem( htpack
, pack
) == EMPTYHT
) {
1924 headpack
= addchain( headpack
, pack
);
1925 addhtitem( htpack
, pack
, 1 );
1929 for( scanpack
= headpack
; scanpack
; scanpack
= scanpack
->NEXT
) {
1930 pack
= (rcx_triangle
*)scanpack
->DATA
;
1931 rcx_cleantriangle_node( losig
, NULL
, pack
);
1933 freechain( headpack
);
1937 avt_logexitfunction(LOGTRC
,2);
1941 int rcx_dw_forloop( losig_list
*losig
,
1942 lonode_list
*lonode
,
1948 chain_list
*headht
;
1949 chain_list
*scanht
;
1953 headht
= GetAllHTElems( htpack
);
1955 for( scanht
= headht
; scanht
; scanht
= scanht
->NEXT
) {
1956 wire
= (lowire_list
*)((chain_list
*)scanht
->DATA
)->DATA
;
1957 tr
= (rcx_triangle
*)rcn_getpack( losig
, wire
);
1958 rcx_cleantriangle_node( losig
, lonode
, tr
);
1964 freechain( headht
);
1968 int rcx_up_pack_forloop( losig_list
*losig
,
1969 lonode_list
*lonode
,
1975 lonode_list
*tstnode
;
1977 if( tr
->n0
!= lonode
) rcx_triangle_node( losig
, tr
->n0
, NULL
);
1978 if( tr
->n1
!= lonode
) rcx_triangle_node( losig
, tr
->n1
, NULL
);
1979 if( tr
->n2
!= lonode
) rcx_triangle_node( losig
, tr
->n2
, NULL
);
1980 for( chain
= tr
->REPORTED_IN
; chain
; chain
= chain
->NEXT
) {
1981 tstnode
= (lonode_list
*)chain
->DATA
;
1982 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1984 for( chain
= tr
->REPORTED_N1
; chain
; chain
= chain
->NEXT
) {
1985 tstnode
= (lonode_list
*)chain
->DATA
;
1986 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1988 for( chain
= tr
->REPORTED_N2
; chain
; chain
= chain
->NEXT
) {
1989 tstnode
= (lonode_list
*)chain
->DATA
;
1990 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1997 int rcx_up_forloop( losig_list
*losig
,
1998 lonode_list
*lonode
,
1999 lowire_list
*lowire
,
2003 rcx_triangle_node( losig
, lonode
, lowire
);
2008 void rcx_env_error( char *msg
, char *was
)
2010 avt_errmsg( TRC_ERRMSG
, "016", AVT_FATAL
, msg
, was
);
2013 void rcx_env( void )
2018 unsigned long int size
;
2020 if( STM_DEFAULT_SMAXR
>= 0.0 && STM_DEFAULT_SMINR
>= 0.0 )
2021 RCX_SLOPE_UNSHRINK
= STM_DEFAULT_SMAXR
- STM_DEFAULT_SMINR
;
2023 RCX_SLOPE_UNSHRINK
= 0.6 ;
2025 if( V_FLOAT_TAB
[__RCX_MINRCSIGNAL
].VALUE
< 0.0 )
2026 rcx_env_error( "RCX_MINRCSIGNAL must be a positive RCXFLOATing number.",
2029 RCX_MINRCSIGNAL
= V_FLOAT_TAB
[__RCX_MINRCSIGNAL
].VALUE
;
2031 if( V_FLOAT_TAB
[__RCX_MINRELCTKSIGNAL
].VALUE
< 0.0 || V_FLOAT_TAB
[__RCX_MINRELCTKSIGNAL
].VALUE
> 1.0 )
2033 "RCX_MINRELCTKSIGNAL must be a RCXFLOATing number between 0 and 1.",
2036 RCX_MINRELCTKSIGNAL
= V_FLOAT_TAB
[__RCX_MINRELCTKSIGNAL
].VALUE
;
2038 if( V_FLOAT_TAB
[__RCX_MINRELCTKFILTER
].VALUE
< 0.0 || V_FLOAT_TAB
[__RCX_MINRELCTKFILTER
].VALUE
> 1.0 )
2040 "RCX_MINRELCTKFILTER must be a RCXFLOATing number between 0 and 1.",
2043 RCX_MINRELCTKFILTER
= V_FLOAT_TAB
[__RCX_MINRELCTKFILTER
].VALUE
;
2045 if( V_FLOAT_TAB
[__RCX_CAPALOAD_MAXRC
].VALUE
< 0.0 )
2047 "RCX_CAPALOAD_MAXRC must be a positive RCXFLOATing number.",
2050 RCX_CAPALOAD_MAXRC
= V_FLOAT_TAB
[__RCX_CAPALOAD_MAXRC
].VALUE
;
2052 if( V_FLOAT_TAB
[__RCX_MAXDELTALOAD
].VALUE
< 0.0 )
2053 rcx_env_error( "RCX_MAXDELTALOAD must be a positive RCXFLOATing number.",
2056 RCX_MAXDELTALOAD
= V_FLOAT_TAB
[__RCX_MAXDELTALOAD
].VALUE
;
2058 str
= getenv("RCX_FREEUNUSEDCTC");
2060 if( strcmp( str
, "yes" ) == 0 )
2061 RCX_FREEUNUSEDCTC
= 'Y';
2063 if( strcmp( str
, "no" ) == 0 )
2064 RCX_FREEUNUSEDCTC
= 'N';
2066 rcx_env_error( "Allowed value for RCX_FREEUNUSEDCTC is 'yes' or 'no'.",
2072 str
= getenv("RCX_USECACHE");
2074 if( strcmp( str
, "yes" ) == 0 )
2077 if( strcmp( str
, "no" ) == 0 )
2080 rcx_env_error( "Allowed value for RCX_USECACHE is 'yes' or 'no'.",
2086 RCX_USE_MATRIX_LOAD
= V_BOOL_TAB
[__RCX_USE_MATRIX_LOAD
].VALUE
?'Y':'N';
2088 str
= V_STR_TAB
[__RCX_CTK_MODEL
].VALUE
;
2091 if( !strcmp( str
, "MILLER_0C2C" ) )
2092 RCX_CTK_MODEL
= RCX_MILLER_0C2C
;
2093 if( !strcmp( str
, "MILLER_NC3C" ) )
2094 RCX_CTK_MODEL
= RCX_MILLER_NC3C
;
2095 if( !strcmp( str
, "MILLER_NOMINAL" ) )
2096 RCX_CTK_MODEL
= RCX_MILLER_NOMINAL
;
2097 if( !RCX_CTK_MODEL
)
2099 "Allowed value for RCX_CTK_MODEL : MILLER_0C2C | MILLER_NOMINAL | MILLER_NC3C.",
2104 str
= V_STR_TAB
[__RCX_CTK_NOISE
].VALUE
;
2107 if( !strcmp( str
, "NOISE_NEVER" ) )
2108 RCX_CTK_NOISE
= RCX_NOISE_NEVER
;
2109 if( !strcmp( str
, "NOISE_ALWAYS" ) )
2110 RCX_CTK_NOISE
= RCX_NOISE_ALWAYS
;
2111 if( !strcmp( str
, "NOISE_IFSTRONG" ) )
2112 RCX_CTK_NOISE
= RCX_NOISE_IFSTRONG
;
2113 if( !strcmp( str
, "NOISE_CUSTOM" ) )
2114 RCX_CTK_NOISE
= RCX_NOISE_CUSTOM
;
2115 if( !strcmp( str
, "NOISE_FINE" ) )
2116 RCX_CTK_NOISE
= RCX_NOISE_FINE
;
2117 if( !RCX_CTK_NOISE
)
2118 rcx_env_error( "Allowed value for RCX_CTK_NOISE : NOISE_NEVER | NOISE_ALWAYS | NOISE_IFSTRONG | NOISE_CUSTOM | NOISE_FINE.\n",
2123 RCX_FASTMODE
= V_BOOL_TAB
[__RCX_FASTMODE
].VALUE
;
2125 str
= getenv("RCX_AWESTRAIGHT");
2127 if( strcmp( str
, "yes" ) == 0 )
2128 RCX_AWESTRAIGHT
= 1;
2130 if( strcmp( str
, "no" ) == 0 )
2131 RCX_AWESTRAIGHT
= 0;
2133 rcx_env_error( "Allowed value for RCX_AWESTRAIGHT is 'yes' or 'no'.",
2139 str
= getenv("RCX_STEPTANH");
2141 if( strcmp( str
, "yes" ) == 0 )
2144 if( strcmp( str
, "no" ) == 0 )
2147 rcx_env_error( "Allowed value for STEPTANH is 'yes' or 'no'.", str
);
2151 str
= V_STR_TAB
[__RCX_CTK_SLOPE_NOISE
].VALUE
;
2153 RCX_CTK_SLOPE_NOISE
= RCX_SLOPE_NONE
;
2154 if( strcmp( str
, "SLOPE_CTK" ) == 0 )
2155 RCX_CTK_SLOPE_NOISE
= RCX_SLOPE_CTK
;
2156 if( strcmp( str
, "SLOPE_NOMINAL" ) == 0 )
2157 RCX_CTK_SLOPE_NOISE
= RCX_SLOPE_NOMINAL
;
2158 if( strcmp( str
, "SLOPE_REAL" ) == 0 )
2159 RCX_CTK_SLOPE_NOISE
= RCX_SLOPE_REAL
;
2160 if( RCX_CTK_SLOPE_NOISE
== RCX_SLOPE_NONE
)
2161 rcx_env_error( "Allowed value for RCX_CTK_SLOPE_NOISE is SLOPE_CTK | SLOPE_NOMINAL | SLOPE_REAL\n",
2166 str
= getenv("RCX_CTK_SLOPE_MILLER");
2168 RCX_CTK_SLOPE_MILLER
= RCX_SLOPE_NONE
;
2169 if( strcmp( str
, "SLOPE_CTK" ) == 0 )
2170 RCX_CTK_SLOPE_MILLER
= RCX_SLOPE_CTK
;
2171 if( strcmp( str
, "SLOPE_NOMINAL" ) == 0 )
2172 RCX_CTK_SLOPE_MILLER
= RCX_SLOPE_NOMINAL
;
2173 if( RCX_CTK_SLOPE_MILLER
== RCX_SLOPE_NONE
)
2175 "Allowed value for RCX_CTK_SLOPE_MILLER is SLOPE_CTK | SLOPE_NOMINAL\n",
2180 str
= V_STR_TAB
[__RCX_CTK_SLOPE_DELAY
].VALUE
;
2182 RCX_CTK_SLOPE_DELAY
= RCX_SLOPE_DELAY_NONE
;
2183 if( strcmp( str
, "SLOPE_DELAY_CTK" ) == 0 )
2184 RCX_CTK_SLOPE_DELAY
= RCX_SLOPE_DELAY_CTK
;
2185 if( strcmp( str
, "SLOPE_DELAY_ENHANCED" ) == 0 )
2186 RCX_CTK_SLOPE_DELAY
= RCX_SLOPE_DELAY_ENHANCED
;
2187 if( RCX_CTK_SLOPE_DELAY
== RCX_SLOPE_DELAY_NONE
)
2188 rcx_env_error( "Allowed value for RCX_CTK_SLOPE_DELAY is SLOPE_DELAY_CTK | SLOPE_DELAY_ENHANCED\n",
2193 str
= V_STR_TAB
[__RCX_USING_AWEMATRIX
].VALUE
;
2195 RCX_USING_AWEMATRIX
=0;
2196 if( strcmp( str
, "never" )==0 ) RCX_USING_AWEMATRIX
= RCX_USING_AWEMATRIX_NEVER
;
2197 if( strcmp( str
, "always" )==0 ) RCX_USING_AWEMATRIX
= RCX_USING_AWEMATRIX_ALWAYS
;
2198 if( strcmp( str
, "ifneed" )==0 ) RCX_USING_AWEMATRIX
= RCX_USING_AWEMATRIX_IFNEED
;
2199 if( strcmp( str
, "force" )==0 ) RCX_USING_AWEMATRIX
= RCX_USING_AWEMATRIX_FORCE
;
2200 if( !RCX_USING_AWEMATRIX
) {
2201 rcx_env_error( "Allowed value for RCX_USING_AWEMATRIX is never | always | ifneed | force\n", str
);
2205 str
= getenv("RCX_AWE_FAST_MODE") ;
2207 if( strcmp( str
, "yes" ) == 0 )
2208 AWE_FAST_MODE
= 'Y';
2210 if( strcmp( str
, "no" ) == 0 )
2211 AWE_FAST_MODE
= 'N';
2213 rcx_env_error( "Allowed value for AWE_FAST_MODE is 'yes' or 'no'.", str
);
2217 str
= V_STR_TAB
[__RCX_DELAY_CACHE
].VALUE
;
2219 size
= strtoul( str
, &ptend
, 10 );
2221 if( *ptend
!= '\0' ) {
2222 if( strcasecmp( ptend
, "kb" )==0 )
2225 if( strcasecmp( ptend
, "mb" )==0 )
2226 size
= size
* 1048576;
2228 if( strcasecmp( ptend
, "gb" )==0 )
2229 size
= size
* 1073741824;
2231 avt_errmsg( RCN_ERRMSG
, "002", AVT_FATAL
);
2236 rcx_init_delay_cache( size
);
2239 rcx_init_delay_cache( 10*1024*1024 );
2241 str
= getenv( "RCX_AWE_ONE_PNODE" );
2243 RCX_AWE_ONE_PNODE
= 0;
2244 if( strcmp( str
, "yes" )==0 ) RCX_AWE_ONE_PNODE
='Y' ;
2245 if( strcmp( str
, "no" )==0 ) RCX_AWE_ONE_PNODE
='N' ;
2246 if( !RCX_AWE_ONE_PNODE
)
2247 rcx_env_error( "Allowed value for RCX_AWE_ONE_PNODE is yes or no\n", str
);
2248 switch( RCX_AWE_ONE_PNODE
) {
2249 case 'Y' : printf( "yes\n" ); break ;
2250 case 'N' : printf( "no\n" ); break ;
2254 str
= getenv( "RCX_AWE_MIN_RESI" );
2256 AWE_MIN_RESI_VALUE
= atof( str
);
2257 if( AWE_MIN_RESI_VALUE
<= 1.0e-6 ) {
2258 rcx_env_error( "Argument for RCX_AWE_MIN_RESI must be a floating number greater than 1.0e-6\n", str
);
2262 str
= getenv( "RCX_PLOT_AWE" );
2264 RCX_PLOT_AWE
= namealloc(str
);
2266 if( mcc_use_multicorner() ) {
2268 switch( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
) {
2270 case ELP_CAPA_LEVEL0
:
2271 RCX_CAPA_NOM_MIN
= 0 ;
2272 RCX_CAPA_NOM_MAX
= 1 ;
2273 RCX_CAPA_NOMF_MIN
= 2 ;
2274 RCX_CAPA_NOMF_MAX
= 3 ;
2275 RCX_NB_CAPA_L0
= 4 ;
2278 case ELP_CAPA_LEVEL1
:
2279 RCX_CAPA_UP_NOM_MIN
= 0 ;
2280 RCX_CAPA_UP_NOM_MAX
= 1 ;
2281 RCX_CAPA_DW_NOM_MIN
= 2 ;
2282 RCX_CAPA_DW_NOM_MAX
= 3 ;
2283 RCX_CAPA_UP_NOMF_MIN
= 4 ;
2284 RCX_CAPA_UP_NOMF_MAX
= 5 ;
2285 RCX_CAPA_DW_NOMF_MIN
= 6 ;
2286 RCX_CAPA_DW_NOMF_MAX
= 7 ;
2287 RCX_NB_CAPA_L1
= 8 ;
2290 case ELP_CAPA_LEVEL2
:
2291 RCX_CAPA_UP_MIN
= 0 ;
2292 RCX_CAPA_UP_NOM_MIN
= 1 ;
2293 RCX_CAPA_UP_NOM_MAX
= 2 ;
2294 RCX_CAPA_UP_MAX
= 3 ;
2295 RCX_CAPA_DW_MIN
= 4 ;
2296 RCX_CAPA_DW_NOM_MIN
= 5 ;
2297 RCX_CAPA_DW_NOM_MAX
= 6 ;
2298 RCX_CAPA_DW_MAX
= 7 ;
2299 RCX_CAPA_UP_NOMF_MIN
= 8 ;
2300 RCX_CAPA_UP_NOMF_MAX
= 9 ;
2301 RCX_CAPA_DW_NOMF_MIN
= 10 ;
2302 RCX_CAPA_DW_NOMF_MAX
= 11 ;
2303 RCX_NB_CAPA_L2
= 12 ;
2309 switch( V_INT_TAB
[__ELP_CAPA_LEVEL
].VALUE
) {
2311 case ELP_CAPA_LEVEL0
:
2312 RCX_CAPA_NOM_MIN
= 0 ;
2313 RCX_CAPA_NOM_MAX
= 0 ;
2314 RCX_CAPA_NOMF_MIN
= 1 ;
2315 RCX_CAPA_NOMF_MAX
= 1 ;
2316 RCX_NB_CAPA_L0
= 2 ;
2319 case ELP_CAPA_LEVEL1
:
2320 RCX_CAPA_UP_NOM_MIN
= 0 ;
2321 RCX_CAPA_UP_NOM_MAX
= 0 ;
2322 RCX_CAPA_DW_NOM_MIN
= 1 ;
2323 RCX_CAPA_DW_NOM_MAX
= 1 ;
2324 RCX_CAPA_UP_NOMF_MIN
= 2 ;
2325 RCX_CAPA_UP_NOMF_MAX
= 2 ;
2326 RCX_CAPA_DW_NOMF_MIN
= 3 ;
2327 RCX_CAPA_DW_NOMF_MAX
= 3 ;
2328 RCX_NB_CAPA_L1
= 4 ;
2331 case ELP_CAPA_LEVEL2
:
2332 RCX_CAPA_UP_MIN
= 0 ;
2333 RCX_CAPA_UP_NOM_MIN
= 1 ;
2334 RCX_CAPA_UP_NOM_MAX
= 1 ;
2335 RCX_CAPA_UP_MAX
= 2 ;
2336 RCX_CAPA_DW_MIN
= 3 ;
2337 RCX_CAPA_DW_NOM_MIN
= 4 ;
2338 RCX_CAPA_DW_NOM_MAX
= 4 ;
2339 RCX_CAPA_DW_MAX
= 5 ;
2340 RCX_CAPA_UP_NOMF_MIN
= 6 ;
2341 RCX_CAPA_UP_NOMF_MAX
= 6 ;
2342 RCX_CAPA_DW_NOMF_MIN
= 7 ;
2343 RCX_CAPA_DW_NOMF_MAX
= 7 ;
2344 RCX_NB_CAPA_L2
= 8 ;
2350 void rcx_setlosigbreakloop( losig_list
*losig
)
2354 ptrcx
= getrcx( losig
);
2359 SETFLAG( ptrcx
->FLAG
, RCXBREAKLOOP
);
2362 int rcx_islosigbreakloop( losig_list
*losig
)
2366 ptrcx
= getrcx( losig
);
2372 if( GETFLAG( ptrcx
->FLAG
, RCXBREAKLOOP
) )
2378 /******************************************************************************\
2379 Fonction qui répare les locon de la lofig qui ont leur PNODE à 0.
2383 - Le signal doit être présent en mémoire.
2384 - On a pas le droit de modifier des PNODE existant car ils ont peut être été
2385 référencés par d'autres signaux via la fonction rcx_get_new_num_node().
2387 \******************************************************************************/
2388 void rcx_repair_pnode( losig_list
*losig
)
2399 ptl
= getptype( losig
->USER
, LOFIGCHAIN
);
2403 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
2404 locon
= (locon_list
*)chain
->DATA
;
2405 if( !rcx_isvalidlocon( locon
) )
2407 if( locon
->PNODE
) {
2408 goodnode
= locon
->PNODE
->DATA
;
2413 rcx
= getrcx( losig
);
2415 if( goodnode
== -1 ) // aucun locon n'a de PNODE.
2416 goodnode
= losig
->PRCN
->NBNODE
;
2418 // Idée de bug : ca n'arrivera jamais, mais que ce passe t'il si il y
2419 // a des résistances...
2421 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
2423 locon
= (locon_list
*)chain
->DATA
;
2425 if( !locon
->PNODE
) {
2427 ptl
= getptype( locon
->USER
, PTYPERCX
);
2429 sigint
= (losig_list
*)ptl
->DATA
;
2430 rcxint
= getrcx( sigint
);
2431 for (cl
=rcxint
->RCXEXTERNAL
; cl
!=NULL
; cl
=cl
->NEXT
)
2432 for( scan
= ((locon_list
*)cl
->DATA
)->PNODE
; scan
; scan
= scan
->NEXT
) {
2433 setloconnode( locon
, goodnode
);
2437 setloconnode( locon
, goodnode
);
2443 /******************************************************************************\
2445 Fonctions utilisées dans buildrcx pour déterminer le numéro d'un noeud d'un
2448 - On ne connait pas le NBNODE sur les signaux de la lofig (si on a jamais eu
2449 de refresh sur le signal).
2450 - On connait le NBNODE sur les signaux des instances.
2452 \******************************************************************************/
2454 int rcx_get_new_num_node( losig_list
*losig
,
2463 rcx_list
*ptrcx_ext
;
2464 locon_list
*locon_ext
;
2465 num_list
*num_int
, *num_ext
;
2468 base
= rcx_get_node_base( losig
);
2473 rcxint
= getrcx( losig
);
2474 locon_ext
= (locon_list
*)getptype( losig
->USER
, RCX_LOCONINS
)->DATA
;
2475 ptrcx_ext
= getrcx( locon_ext
->SIG
);
2477 // Cas où le connecteur externe ne contient pas de pnode
2478 if( !locon_ext
->PNODE
) {
2479 if( withnowire
==YES
&& GETFLAG( ptrcx_ext
->FLAG
, RCXNOWIRE
) ) {
2483 base_ext
= rcx_get_node_base( locon_ext
->SIG
) +
2484 locon_ext
->SIG
->PRCN
->NBNODE
;
2487 for (cl
=rcxint
->RCXEXTERNAL
; cl
!=NULL
; cl
=cl
->NEXT
)
2488 for( num_int
= ((locon_list
*)cl
->DATA
)->PNODE
;
2490 num_int
= num_int
->NEXT
)
2491 setloconnode( locon_ext
, base_ext
);
2494 if( withnowire
==YES
&& GETFLAG( ptrcx_ext
->FLAG
, RCXNOWIRE
) )
2497 if( withnowire
==YES
&& GETFLAG( rcxint
->FLAG
, RCXNOWIRE
) ) {
2498 newnode
= rcx_get_new_num_node( locon_ext
->SIG
,
2499 locon_ext
->PNODE
->DATA
,
2505 for (cl
=rcxint
->RCXEXTERNAL
; cl
!=NULL
; cl
=cl
->NEXT
)
2506 for( num_int
= ((locon_list
*)cl
->DATA
)->PNODE
,
2507 num_ext
= locon_ext
->PNODE
;
2509 num_int
= num_int
->NEXT
, num_ext
= num_ext
->NEXT
)
2510 if( num_int
->DATA
== node
)
2514 newnode
= rcx_get_new_num_node( locon_ext
->SIG
,
2520 newnode
= node
+ base
;
2526 ptrcx_ext
= getrcx( losig
);
2527 if( withnowire
==YES
&& GETFLAG( ptrcx_ext
->FLAG
, RCXNOWIRE
) )
2530 newnode
= node
+ base
;
2537 // Créé les infos pour les signaux qui auront des noeuds renumérotés.
2539 void rcx_build_new_num_node( lofig_list
*lofig
)
2541 losig_list
*sigext
, *sigint
;
2547 for( sigext
= lofig
->LOSIG
; sigext
; sigext
= sigext
->NEXT
) {
2551 ptl
= getptype( sigext
->USER
, LOFIGCHAIN
);
2555 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
2557 locon
= (locon_list
*)chain
->DATA
;
2558 if( !rcx_isvalidlocon( locon
) )
2561 if( locon
->TYPE
== 'I' ) {
2563 ptl
= getptype( locon
->USER
, PTYPERCX
) ;
2566 sigint
= (losig_list
*)(ptl
->DATA
) ;
2567 if (rcx_set_node_base( sigint
, n
))
2568 n
= n
+ sigint
->PRCN
->NBNODE
;
2573 rcx_set_node_base( sigext
, n
);
2577 // Libère les infos pour les signaux qui auront des noeuds renumérotés.
2579 void rcx_clear_new_num_node( lofig_list
*lofig
)
2581 losig_list
*sigext
, *sigint
;
2586 for( sigext
= lofig
->LOSIG
; sigext
; sigext
= sigext
->NEXT
) {
2588 ptl
= getptype( sigext
->USER
, LOFIGCHAIN
);
2592 for( chain
= (chain_list
*)ptl
->DATA
; chain
; chain
= chain
->NEXT
) {
2594 locon
= (locon_list
*)chain
->DATA
;
2595 if( !rcx_isvalidlocon( locon
) )
2598 if( locon
->TYPE
== 'I' ) {
2600 ptl
= getptype( locon
->USER
, PTYPERCX
) ;
2603 sigint
= (losig_list
*)(ptl
->DATA
) ;
2604 rcx_clear_node_base( sigint
) ;
2609 rcx_clear_node_base( sigext
) ;
2613 // Le losig est interne à une loins. Récupère le nom du signal à l'extérieur de
2615 losig_list
* rcx_get_out_ins_sig( losig_list
*losig
)
2617 locon_list
*locon_ext
;
2618 losig_list
*sig_ext
;
2620 locon_ext
= (locon_list
*)getptype( losig
->USER
, RCX_LOCONINS
)->DATA
;
2621 sig_ext
= locon_ext
->SIG
;
2626 int rcx_get_node_base( losig_list
*losig
)
2629 ptl
= getptype( losig
->USER
, RCX_NODE_BASE
);
2630 if( !ptl
) return 0;
2631 return (int)(long)ptl
->DATA
;
2634 int rcx_set_node_base( losig_list
*losig
, int index
)
2637 ptl
= getptype( losig
->USER
, RCX_NODE_BASE
);
2639 if (countchain(getrcx(losig
)->RCXEXTERNAL
)>1) return 0;
2640 rcx_error( 12, losig
, AVT_ERROR
);
2641 losig
->USER
= delptype( losig
->USER
, RCX_NODE_BASE
);
2643 losig
->USER
= addptype( losig
->USER
, RCX_NODE_BASE
, (void*)(long)index
);
2647 void rcx_clear_node_base( losig_list
*losig
)
2650 ptl
= getptype( losig
->USER
, RCX_NODE_BASE
);
2652 losig
->USER
= delptype( losig
->USER
, RCX_NODE_BASE
);
2655 /******************************************************************************\
2656 Transfert au niveau supérieur les informations sur les drivers.
2657 Si au niveau supérieur il y a deja des informations de driver (cas multi driver
2658 due à la hiérarchie), alors on en prend aucune en compte. Pour indiquer ce cas,
2659 on utilise le flag MULTIDRIVER dans la vue RCX externe.
2660 \******************************************************************************/
2661 void rcx_trsfdriver( lofig_list
*currentfig
, losig_list
*sigext
, rcx_list
*rcxext
, losig_list
*sigint
, rcx_list
*rcxint
)
2663 num_list
*headnodeup
;
2664 num_list
*headnodedw
;
2667 if( GETFLAG( rcxext
->FLAG
, RCXMLTDRIVER
) )
2670 if( ( rcxext
->DRIVERSUP
|| rcxext
->DRIVERSDW
) &&
2671 ( rcxint
->DRIVERSUP
|| rcxint
->DRIVERSDW
) ) {
2672 rcx_cleardriver( sigext
);
2673 SETFLAG( rcxext
->FLAG
, RCXMLTDRIVER
);
2679 if( rcxint
->DRIVERSUP
) {
2680 for( node
= rcxint
->DRIVERSUP
->PNODE
; node
; node
= node
->NEXT
)
2681 headnodeup
= addnum( headnodeup
, rcx_get_new_num_node( sigint
, node
->DATA
, RCX_LOINS
, YES
) ) ;
2684 if( rcxint
->DRIVERSDW
) {
2685 for( node
= rcxint
->DRIVERSDW
->PNODE
; node
; node
= node
->NEXT
)
2686 headnodedw
= addnum( headnodedw
, rcx_get_new_num_node( sigint
, node
->DATA
, RCX_LOINS
, YES
) ) ;
2689 rcx_setdriver( sigext
, headnodeup
, headnodedw
);
2693 /******************************************************************************\
2694 Calcule les nouveaux PNODE d'un locon.
2695 \******************************************************************************/
2696 void rcx_trsfnodelocon( locon_list
*locon
, char where
)
2701 for( scannum
= locon
->PNODE
; scannum
; scannum
= scannum
->NEXT
) {
2702 scannum
->DATA
= rcx_get_new_num_node( locon
->SIG
,
2709 headup
= rcx_getnodebytransition( locon
, TRC_SLOPE_UP
) ;
2710 if( headup
&& locon
->PNODE
!= headup
) {
2711 for( scannum
= headup
; scannum
; scannum
= scannum
->NEXT
)
2712 scannum
->DATA
= rcx_get_new_num_node( locon
->SIG
,
2718 headdn
= rcx_getnodebytransition( locon
, TRC_SLOPE_DOWN
) ;
2719 if( headdn
&& locon
->PNODE
!= headdn
) {
2720 for( scannum
= headdn
; scannum
; scannum
= scannum
->NEXT
)
2721 scannum
->DATA
= rcx_get_new_num_node( locon
->SIG
,
2729 /******************************************************************************\
2730 Création d'une vue RCX sur une lofig, qui peut contenir des instances ou des
2732 \******************************************************************************/
2734 void rcx_create( currentfig
)
2735 lofig_list
*currentfig
;
2737 loins_list
*scanins
;
2739 // Ajoute une vue RCX sur tous les losigs.
2740 rcx_addsignal( currentfig
);
2742 // Récupère les informations correspondant aux instances.
2743 for( scanins
= currentfig
->LOINS
; scanins
; scanins
=scanins
->NEXT
)
2744 rcxparse( scanins
, NULL
, scanins
->FIGNAME
, NULL
);
2746 // Ajoute des noms de connecteur sur les locons des transistors.
2747 rcx_name_locon_trs( currentfig
);
2749 // Ajoute les connecteurs externes de la lofig dans le champs EXTERNAL des
2751 rcx_addfigcon( currentfig
);
2753 // Sélectionne les signaux à sauvegarder dans le fichier RCX.
2754 rcx_set_lofig_savesig( currentfig
);
2757 void rcx_name_locon_trs( lofig_list
*currentfig
)
2759 losig_list
*scansig
;
2764 for( scansig
= currentfig
->LOSIG
; scansig
; scansig
= scansig
->NEXT
) {
2766 if(tlc_islosigalim(scansig
))
2769 if((ptype
= getptype(scansig
->USER
,LOFIGCHAIN
)) != NULL
) {
2771 for( chain
= (chain_list
*)ptype
->DATA
; chain
; chain
= chain
->NEXT
) {
2772 locon
= (locon_list
*)chain
->DATA
;
2773 if( !rcx_isvalidlocon( locon
) )
2775 if(locon
->TYPE
== 'T')
2776 givetransloconrcxname(locon
) ;
2780 givetransloconrcxname(NULL
) ;
2783 void rcx_addsignal( lofig_list
*fig
)
2785 losig_list
*scansig
;
2787 for( scansig
= fig
->LOSIG
; scansig
; scansig
= scansig
->NEXT
)
2789 if(( scansig
->PRCN
== NULL
) || tlc_islosigalim(scansig
))
2792 rcx_alloc( scansig
);
2796 void rcx_set_lofig_savesig( lofig_list
*fig
)
2798 losig_list
*scanlosig
;
2800 for( scanlosig
= fig
->LOSIG
; scanlosig
; scanlosig
= scanlosig
->NEXT
) {
2801 rcxview
= getrcx( scanlosig
);
2803 SETFLAG( rcxview
->FLAG
, SAVESIG
);
2808 void rcx_addfigcon( lofig_list
*fig
)
2810 locon_list
*scanlocon
;
2814 for(scanlocon
=fig
->LOCON
;scanlocon
;scanlocon
=scanlocon
->NEXT
)
2817 rcxview
= getrcx( sig
);
2819 if( rcxview
== NULL
)
2822 if( rcx_isvalidlocon( scanlocon
) )
2823 rcxview
->RCXEXTERNAL
=addchain(rcxview
->RCXEXTERNAL
, scanlocon
);
2827 char rcx_isvalidlocon( locon_list
*locon
)
2831 switch( locon
->TYPE
) {
2845 int rcx_calc_cca_param( rcxparam
*param
)
2847 if( param
->CCA
< 0.0 ) {
2848 param
->CCA
= rcx_getsigcapa( param
->LOFIG
,
2851 RCX_SIGCAPA_LOCAL
|RCX_SIGCAPA_GLOBAL
,
2862 int rcx_calc_cca( rcx_slope
*slope
, losig_list
*victime
)
2864 if( slope
->CCA
< 0.0 ) {
2865 slope
->CCA
= rcx_getsigcapa( NULL
,
2868 RCX_SIGCAPA_LOCAL
|RCX_SIGCAPA_GLOBAL
,
2879 void rcx_cleardriver( losig_list
*losig
)
2883 rcx
= getrcx( losig
);
2887 if( rcx
->DRIVERSUP
) {
2888 freercxlocon( rcx
->DRIVERSUP
);
2889 rcx
->DRIVERSUP
= NULL
;
2892 if( rcx
->DRIVERSDW
) {
2893 freercxlocon( rcx
->DRIVERSDW
);
2894 rcx
->DRIVERSDW
= NULL
;
2899 void rcx_setdriver( losig_list
*losig
, num_list
*driversup
, num_list
*driversdw
)
2903 rcx
= getrcx( losig
);
2907 if( !rcx
->DRIVERSUP
) {
2908 rcx
->DRIVERSUP
= addrcxlocon();
2909 rcx
->DRIVERSUP
->NAME
= "multi-driver-up" ;
2910 rcx
->DRIVERSUP
->SIG
= losig
;
2912 if( rcx
->DRIVERSUP
->PNODE
)
2913 freenum( rcx
->DRIVERSUP
->PNODE
);
2914 rcx
->DRIVERSUP
->PNODE
= driversup
;
2917 if( !rcx
->DRIVERSDW
) {
2918 rcx
->DRIVERSDW
= addrcxlocon();
2919 rcx
->DRIVERSDW
->NAME
= "multi-driver-down" ;
2920 rcx
->DRIVERSDW
->SIG
= losig
;
2922 if( rcx
->DRIVERSDW
->PNODE
)
2923 freenum( rcx
->DRIVERSDW
->PNODE
);
2924 rcx
->DRIVERSDW
->PNODE
= driversdw
;
2928 freenum( driversup
);
2929 freenum( driversdw
);