1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : RCX - AWE support. */
6 /* Fichier : trc_awe.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Grégoire Avot */
13 /****************************************************************************/
17 Revision : $Revision: 1.107 $
18 Author : $Author: fabrice $
19 Date : $Date: 2008/03/27 15:16:20 $
28 /******************************************************************************\
30 \******************************************************************************/
33 awetabnode_list
*AWEHEADTABNODE
= NULL
; // Allocation par bloc
34 char RCX_AWESTRAIGHT
=0;
37 int awestatcallinfo
=0;
38 int awestatcallmoment
=0;
39 int awestatcallfilter
=0;
40 int awestatnbheapinfo
=0;
42 char RCX_USING_AWEMATRIX
=RCX_USING_AWEMATRIX_IFNEED
;
43 char RCX_AWE_ONE_PNODE
='N';
45 losig_list
*AWE_DEBUG_NET
;
46 locon_list
*AWE_DEBUG_DRIVER
;
47 locon_list
*AWE_DEBUG_RECEIVER
;
48 char *RCX_PLOT_AWE
=NULL
;
49 char *AWE_DUMP_NETNAME
;
51 char AWE_FAST_MODE
='N';
52 int AWE_MAX_ITER
=1000;
54 awetabnode
* aweallocnodes( void )
59 if( AWEHEADTABNODE
== NULL
) {
60 AWEHEADTABNODE
= (awetabnode_list
*)(mbkalloc( sizeof( awetabnode_list
) * AWESIZETABNODE
) );
62 for( i
=1 ; i
< AWESIZETABNODE
; i
++ ) {
70 AWEHEADTABNODE
= AWEHEADTABNODE
->NEXT
;
72 /* initialisation des moments et de la capacité */
73 for( i
=0 ; i
< AWE_MAX_MOMENT
; i
++ )
74 pt
->TABNODE
.MOMENT
[i
] = 0.0 ;
75 pt
->TABNODE
.SUMMOMENTCAPA
= 0.0;
77 return((awetabnode
*)pt
);
80 void aweunallocnodes( awetabnode
*tofree
)
84 pt
= (awetabnode_list
*)(tofree
);
86 pt
->NEXT
= AWEHEADTABNODE
;
90 int awe_dw_forbuildnodes( losig_list
*losig
,
100 awetabnode
*ltabnode
;
101 lonode_list
*ptnode
;
110 tabnode
= aweallocnodes();
111 if( getptype( lonode
->USER
, AWENODE
) ) {
112 awe_error( 0, AVT_INTERNAL
);
114 lonode
->USER
= addptype( lonode
->USER
, AWENODE
, tabnode
);
117 ptl
= getptype( lonode
->USER
, AWENODE
);
119 awe_error( 1, AVT_INTERNAL
);
121 tabnode
= (awetabnode
*)ptl
->DATA
;
124 c
= rcx_getnodecapa( losig
,
133 tabnode
->SUMMOMENTCAPA
= c
;
135 for( chain
= chwire
; chain
; chain
= chain
->NEXT
) {
136 wire
= (lowire_list
*)chain
->DATA
;
137 inode
= (wire
->NODE1
== lonode
->INDEX
? wire
->NODE2
: wire
->NODE1
);
138 ptnode
= getlonode( losig
, inode
);
139 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
140 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
143 headht
= GetAllHTElems( htpack
);
145 for( chain
= headht
; chain
; chain
= chain
->NEXT
) {
146 wire
= (lowire_list
*)((chain_list
*)chain
->DATA
)->DATA
;
147 tr
= (rcx_triangle
*)rcn_getpack( losig
, wire
) ;
149 ltabnode
= (awetabnode
*)getptype( tr
->n1
->USER
, AWENODE
)->DATA
;
150 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
152 ltabnode
= (awetabnode
*)getptype( tr
->n2
->USER
, AWENODE
)->DATA
;
153 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
155 for( chrep
= tr
->REPORTED_IN
; chrep
; chrep
= chrep
->NEXT
) {
156 ptnode
= (lonode_list
*)chrep
->DATA
;
157 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
158 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
161 for( chrep
= tr
->REPORTED_N1
; chrep
; chrep
= chrep
->NEXT
) {
162 ptnode
= (lonode_list
*)chrep
->DATA
;
163 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
164 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
167 for( chrep
= tr
->REPORTED_N2
; chrep
; chrep
= chrep
->NEXT
) {
168 ptnode
= (lonode_list
*)chrep
->DATA
;
169 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
170 tabnode
->SUMMOMENTCAPA
= tabnode
->SUMMOMENTCAPA
+ ltabnode
->SUMMOMENTCAPA
;
179 void awebuildnodes( losig_list
*losig
,
182 rcx_slope
*slopemiller
,
191 infos
.extcapa
= extcapa
;
192 infos
.slope
= slopemiller
;
194 infos
.coefctc
= coefctc
;
195 infos
.reset
= reset
;
197 avt_logenterfunction(LOGTRC
,2, "awebuildnodes()" );
199 clearallwireflag( losig
, RCN_FLAG_PASS
);
200 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
201 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
206 (int (*)(losig_list
*,lonode_list
*,chain_list
*,ht
*,void*))awe_dw_forbuildnodes
,
211 avt_logexitfunction(LOGTRC
,2);
214 int awe_up_formoment( losig_list
*losig
,
221 awetabnode
*prevmoment
;
223 lonode_list
*prevnode
;
226 inode
= (lowire
->NODE1
== lonode
->INDEX
) ? lowire
->NODE2
: lowire
->NODE1
;
227 prevnode
= getlonode( losig
, inode
);
229 moment
= (awetabnode
*)getptype( lonode
->USER
, AWENODE
)->DATA
;
230 prevmoment
= (awetabnode
*)getptype( prevnode
->USER
, AWENODE
)->DATA
;
232 moment
->MOMENT
[info
->ordre
-1] = prevmoment
->MOMENT
[info
->ordre
-1] -
233 rcn_get_resi_para( lowire
) / info
->k
* moment
->SUMMOMENTCAPA
;
238 int awe_dw_formoment( losig_list
*losig
,
250 awetabnode
*ltabnode
;
253 lonode_list
*ptnode
;
256 moment
= (awetabnode
*)getptype( lonode
->USER
, AWENODE
)->DATA
;
258 for( chain
= chwire
; chain
; chain
= chain
->NEXT
) {
260 wire
= (lowire_list
*)chain
->DATA
;
262 inode
= (wire
->NODE1
== lonode
->INDEX
) ? wire
->NODE2
: wire
->NODE1
;
263 ptnode
= getlonode( losig
, inode
);
265 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
267 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
270 headht
= GetAllHTElems( htpack
);
272 for( chain
= headht
; chain
; chain
= chain
->NEXT
) {
273 wire
= (lowire_list
*)((chain_list
*)chain
->DATA
)->DATA
;
274 tr
= (rcx_triangle
*)rcn_getpack( losig
, wire
) ;
276 ltabnode
= (awetabnode
*)getptype( tr
->n1
->USER
, AWENODE
)->DATA
;
277 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
279 ltabnode
= (awetabnode
*)getptype( tr
->n2
->USER
, AWENODE
)->DATA
;
280 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
282 for( chrep
= tr
->REPORTED_IN
; chrep
; chrep
= chrep
->NEXT
) {
283 ptnode
= (lonode_list
*)chrep
->DATA
;
284 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
285 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
288 for( chrep
= tr
->REPORTED_N1
; chrep
; chrep
= chrep
->NEXT
) {
289 ptnode
= (lonode_list
*)chrep
->DATA
;
290 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
291 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
294 for( chrep
= tr
->REPORTED_N2
; chrep
; chrep
= chrep
->NEXT
) {
295 ptnode
= (lonode_list
*)chrep
->DATA
;
296 ltabnode
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
297 smc
= smc
+ ltabnode
->SUMMOMENTCAPA
;
301 smc
= smc
+ moment
->CAPA
* moment
->MOMENT
[info
->ordre
-1];
303 moment
->SUMMOMENTCAPA
= smc
;
310 int awe_packup_formoment( losig_list
*losig
,
317 awetabnode
*repmoment
;
324 lonode_list
*ptnode
;
326 moment
= (awetabnode
*)getptype( lonode
->USER
, AWENODE
)->DATA
;
328 for( chain
= tr
->REPORTED_IN
; chain
; chain
= chain
->NEXT
) {
330 ptnode
= (lonode_list
*)chain
->DATA
;
332 repmoment
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
333 repmoment
->MOMENT
[info
->ordre
-1] = moment
->MOMENT
[info
->ordre
-1] ;
336 mmtn1
= (awetabnode
*)getptype( tr
->n1
->USER
, AWENODE
)->DATA
;
337 mmtn2
= (awetabnode
*)getptype( tr
->n2
->USER
, AWENODE
)->DATA
;
339 mmc1
= mmtn1
->SUMMOMENTCAPA
;
340 mmc2
= mmtn2
->SUMMOMENTCAPA
;
342 for( chain
= tr
->REPORTED_N1
; chain
; chain
= chain
->NEXT
) {
343 ptnode
= (lonode_list
*)chain
->DATA
;
344 repmoment
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
345 mmc1
= mmc1
+ repmoment
->SUMMOMENTCAPA
;
347 for( chain
= tr
->REPORTED_N2
; chain
; chain
= chain
->NEXT
) {
348 ptnode
= (lonode_list
*)chain
->DATA
;
349 repmoment
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
350 mmc2
= mmc2
+ repmoment
->SUMMOMENTCAPA
;
353 immt
= moment
->MOMENT
[info
->ordre
-1] - tr
->Z0
/ info
->k
* ( mmc1
+ mmc2
) ;
355 mmtn1
->MOMENT
[info
->ordre
-1] = immt
- tr
->Z1
/ info
->k
* mmc1
;
356 mmtn2
->MOMENT
[info
->ordre
-1] = immt
- tr
->Z2
/ info
->k
* mmc2
;
358 for( chain
= tr
->REPORTED_N1
; chain
; chain
= chain
->NEXT
) {
360 ptnode
= (lonode_list
*)chain
->DATA
;
362 repmoment
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
363 repmoment
->MOMENT
[info
->ordre
-1] = mmtn1
->MOMENT
[info
->ordre
-1] ;
366 for( chain
= tr
->REPORTED_N2
; chain
; chain
= chain
->NEXT
) {
368 ptnode
= (lonode_list
*)chain
->DATA
;
370 repmoment
= (awetabnode
*)getptype( ptnode
->USER
, AWENODE
)->DATA
;
371 repmoment
->MOMENT
[info
->ordre
-1] = mmtn2
->MOMENT
[info
->ordre
-1] ;
378 void awemoment( losig_list
*losig
,
388 avt_logenterfunction(LOGTRC
,2, "awemoment()" );
390 infos
.ordre
= ordre
;
391 infos
.extcapa
= extcapa
;
394 clearallwireflag( losig
, RCN_FLAG_PASS
);
395 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
396 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
400 (int (*)(losig_list
*,lonode_list
*,lowire_list
*,void*))awe_up_formoment
,
401 (int (*)(losig_list
*,lonode_list
*,chain_list
*,ht
*,void*))awe_dw_formoment
,
402 (int (*)(losig_list
*,lonode_list
*,void*,void*))awe_packup_formoment
,
406 avt_logexitfunction(LOGTRC
,2);
409 int awe_dw_forcleannodes( losig_list
*losig
,
417 ptl
= getptype( lonode
->USER
, AWENODE
);
419 awe_error( 2, AVT_INTERNAL
);
421 aweunallocnodes( (awetabnode
*) ptl
->DATA
);
422 lonode
->USER
= delptype( lonode
->USER
, AWENODE
);
432 void awecleannodes( losig_list
*losig
,
438 clearallwireflag( losig
, RCN_FLAG_PASS
);
439 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
440 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
442 rcn_treetrip( losig
, node
, NULL
, awe_dw_forcleannodes
, NULL
, NULL
, 0 );
445 RCXFLOAT
awedelay( aweinfo_list
*awe
,
463 mbk_laplace
*laplace
;
464 static int fordebug
=0;
467 avt_logenterfunction(LOGTRC
,2, "awedelay()" );
471 if( awe
->FLAG
== AWE_NODELAY
) {
472 avt_log(LOGTRC
,2, "no delay\n" );
473 avt_logexitfunction(LOGTRC
,2);
479 if( RCX_AWESTRAIGHT
) {
480 avt_log(LOGTRC
,2,"old algorithm : rcx_awestraight\n");
481 awe_tanh_to_straight( inputslope
, vmax
, vt
, &a
, &b
);
482 ts
= aweinstant_straight( awe
, v
, vmax
, a
, b
);
488 avt_log(LOGTRC
,2,"using input pwl\n");
493 avt_log(LOGTRC
,2,"building pwl from hyperbolic tangent\n");
494 tanhpwl
= awe_tanh_to_pwl( inputslope
, vmax
, vt
, vsat
, rl
, r
, c1
, c2
);
499 laplace
= awe_pwl_to_laplace( lines
, awe
);
501 ts
= aweinstant_pwl( awe
, v
, vmax
, laplace
, &status
);
503 avt_log(LOGTRC
,2,"find ts=%g\n", ts
);
504 if( mbk_pwl_get_inv_value( lines
, v
, &te
) ) {
506 if( t
<0.0 ) { /* possible car les solutions trouvées pour
507 ts et te sont approximatives. */
508 if( -t
/ ts
> 0.01 ) {
509 /* on considère que si t représente plus de 1% de ts, c'est
510 qu'il y a un problème d'évaluation de awe */
511 avt_errmsg( TRC_ERRMSG
, "001", AVT_WARNING
,
512 rcx_getsigname( AWE_DEBUG_NET
) );
519 avt_errmsg( TRC_ERRMSG
, "042", AVT_WARNING
,
520 rcx_getsigname( AWE_DEBUG_NET
) );
524 avt_log(LOGTRC
,2,"can't determine output transition time\n");
525 avt_errmsg( TRC_ERRMSG
, "043", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
527 mbk_free_laplace( laplace
);
530 avt_log(LOGTRC
,2,"Laplace transfrom not found\n");
531 avt_errmsg( TRC_ERRMSG
, "044", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
533 mbk_pwl_free_pwl( tanhpwl
);
536 avt_log(LOGTRC
,2, "no pwl\n" );
537 avt_errmsg( TRC_ERRMSG
, "044", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
545 avt_logexitfunction(LOGTRC
,2);
550 RCXFLOAT
aweslope( aweinfo_list
*awe
,
558 RCXFLOAT t1
, t2
, v1
, v2
;
562 mbk_laplace
*laplace
;
563 static int fordebug
=0;
564 awefilter datapwltanh
;
566 double capa
, capaf
, tp2
, t20
, tp
;
567 RCXFLOAT inputslope
;
576 rcx_slope_param
*sparam
;
578 chain_list
*headlocon
;
580 if( type
== RCX_MAX
)
581 sparam
= &(slope
->MAX
) ;
583 sparam
= &(slope
->MIN
) ;
585 inputslope
= sparam
->slope
;
588 vsat
= sparam
->vsat
;
593 pwlin
= sparam
->pwl
;
595 avt_logenterfunction(LOGTRC
,2, "aweslope()" );
602 if( awe
->FLAG
== AWE_NODELAY
) {
603 avt_log(LOGTRC
,2, "call aweslope() with AWE_NODELAY filter.\n" );
604 avt_logexitfunction(LOGTRC
,2);
605 return( inputslope
);
608 // Le calcul s'effectue à partir de la tangente à la tension v, en prenant
609 // deux mesures de la tension séparée de 5%.
611 if( RCX_AWESTRAIGHT
) {
613 avt_log(LOGTRC
,2, "old algorithm used : RCX_AWESTRAIGHT\n" );
614 awe_tanh_to_straight( inputslope
, vmax
, vt
, &a
, &b
);
617 t1
= aweinstant_straight( awe
, v1
, vmax
, a
, b
);
619 avt_log(LOGTRC
,2, "error when computing t1\n" );
620 avt_logexitfunction(LOGTRC
,2);
621 return( inputslope
);
625 v2
= awevoltage_straight( awe
, t2
, vmax
, a
, b
);
627 avt_log(LOGTRC
,2, "error when computing v2\n" );
628 avt_logexitfunction(LOGTRC
,2);
629 return( inputslope
);
635 // Le front calculé à partir de la dérivée. Formule semblabe à celle
636 // décrite dans la thèse d'Amjad Hajjar pIII/9 (3-3-a et 3-3-b), généralisée
637 // Ã n'importe quelle tension de seuil.
639 f
= (vmax
-v
)*(vmax
+v
-2.0*vt
)/(a
*(vmax
-vt
));
643 avt_log(LOGTRC
,2, "using input pwl\n" );
648 avt_log(LOGTRC
,2, "building pwl from hyperbolic tangent\n" );
649 tanhpwl
= awe_tanh_to_pwl( inputslope
, vmax
, vt
, vsat
, rl
, r
, c1
, c2
);
653 avt_log(LOGTRC
,2, "no pwl\n" );
654 avt_logexitfunction(LOGTRC
,2);
658 laplace
= awe_pwl_to_laplace( lines
, awe
);
660 mbk_pwl_free_pwl( tanhpwl
);
661 avt_log(LOGTRC
,2,"can't build Laplace transfom\n" );
662 avt_logexitfunction(LOGTRC
,2);
666 awe_tanh_point_measure( vt
, vmax
, inputslope
, &t1
, &v1
, &t2
, &v2
);
668 t1
= aweinstant_pwl( awe
, v1
, vmax
, laplace
, &status
);
670 avt_errmsg( TRC_ERRMSG
, "043", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
671 mbk_free_laplace( laplace
);
672 mbk_pwl_free_pwl( tanhpwl
);
673 avt_log(LOGTRC
,2,"can't find t1\n");
674 avt_logexitfunction(LOGTRC
,2);
678 t2
= aweinstant_pwl( awe
, v2
, vmax
, laplace
, &status
);
680 avt_errmsg( TRC_ERRMSG
, "043", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
681 mbk_free_laplace( laplace
);
682 mbk_pwl_free_pwl( tanhpwl
);
683 avt_log(LOGTRC
,2,"can't find t2\n");
684 avt_logexitfunction(LOGTRC
,2);
688 if( V_BOOL_TAB
[ __TAS_USE_FINAL_CAPACITANCE
].VALUE
) {
689 node
= getlonode( awe
->LOCON_LOAD
->SIG
, awe
->NODE_LOAD
);
690 /* critère : un seul locon et une seul resistance, r>10k */
691 headlocon
= getloconnode( node
);
692 if( headlocon
&& !headlocon
->NEXT
) {
693 if( node
->WIRELIST
&& !node
->WIRELIST
->NEXT
&& ((lowire_list
*)(node
->WIRELIST
->DATA
))->RESI
> 10000 ) {
694 if (mbk_pwl_get_inv_value( lines
, v2
, &t20
)) {
697 capa
= rcx_getnodecapa( awe
->LOCON_LOAD
->SIG
,
698 getlonode( awe
->LOCON_LOAD
->SIG
, awe
->NODE_LOAD
),
705 capaf
= rcx_getnodecapa( awe
->LOCON_LOAD
->SIG
,
706 getlonode( awe
->LOCON_LOAD
->SIG
, awe
->NODE_LOAD
),
713 tp2
= tp
*capaf
/capa
;
718 avt_log(LOGTRC
,2, "error when computing v2 crossing time\n" );
724 f
= (t2
-t1
)/(atanh((v2
-vt
)/(vmax
-vt
)-atanh((v1
-vt
)/(vmax
-vt
))));
726 avt_log(LOGTRC
,2, "slope computed : %g\n" ,f
);
728 if( AWE_DUMP_NETNAME
) {
730 sprintf( name
, "rc_%s_%s", AWE_DUMP_NETNAME
, AWE_DUMP_SLOPE
==TRC_SLOPE_UP
? "up":"dw" );
731 awevoltage_pwl_plot( awe
, 2.0*t2
, lines
, laplace
, 1.0e-12, 0.0, vmax
, name
);
735 avt_log(LOGTRC
,2,"build pwlout\n");
736 datapwltanh
.LAPLACE
= laplace
;
737 datapwltanh
.AWE
= awe
;
738 datapwltanh
.VMAX
= vmax
;
739 *pwlout
= mbk_create_pwl_according_tanh( (char (*)(void*, float, float*))awe_get_time_for_pwl
,
746 mbk_free_laplace( laplace
);
747 mbk_pwl_free_pwl( tanhpwl
);
749 if( f
< inputslope
) {
750 avt_log(LOGTRC
,2,"an error occured. try the simplest model for driver\n" );
751 lines
= awe_tanh_to_pwl( inputslope
, vmax
, vt
,
752 -1.0, -1.0, -1.0, -1.0, -1.0 );
754 avt_logexitfunction(LOGTRC
,2);
758 laplace
= awe_pwl_to_laplace( lines
, awe
);
760 mbk_pwl_free_pwl( lines
);
761 avt_logexitfunction(LOGTRC
,2);
765 awe_tanh_point_measure( vt
, vmax
, inputslope
, &t1
, &v1
, &t2
, &v2
);
767 t1
= aweinstant_pwl( awe
, v1
, vmax
, laplace
, &status
);
769 avt_errmsg( TRC_ERRMSG
, "043", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
770 mbk_free_laplace( laplace
);
771 mbk_pwl_free_pwl( lines
);
772 avt_log(LOGTRC
,2,"can't find t1\n");
773 avt_logexitfunction(LOGTRC
,2);
777 t2
= aweinstant_pwl( awe
, v2
, vmax
, laplace
, &status
);
778 mbk_free_laplace( laplace
);
779 mbk_pwl_free_pwl( lines
);
781 avt_errmsg( TRC_ERRMSG
, "043", AVT_WARNING
, rcx_getsigname( AWE_DEBUG_NET
) );
782 avt_log(LOGTRC
,2,"can't find t2\n");
783 avt_logexitfunction(LOGTRC
,2);
787 f
= (t2
-t1
)/(atanh((v2
-vt
)/(vmax
-vt
)-atanh((v1
-vt
)/(vmax
-vt
))));
788 avt_log(LOGTRC
,2, "slope computed : %g\n" ,f
);
792 avt_logexitfunction(LOGTRC
,2);
796 char awe_get_time_for_pwl( awefilter
*filter
, float v
, float *t
)
799 *t
= aweinstant_pwl( filter
->AWE
, v
, filter
->VMAX
, filter
->LAPLACE
, &status
);
803 void awe_tanh_point_measure( RCXFLOAT vt
,
815 *v2
=3.0*(vmax
-vt
)/4.0+vt
;
816 *t2
=f
*atanh( (*v2
-vt
)/(vmax
-vt
) );
819 RCXFLOAT
awe_pi_get_v20( RCXFLOAT tsat
, RCXFLOAT inputslope
, RCXFLOAT vmax
, RCXFLOAT vt
, RCXFLOAT r
, RCXFLOAT c2
)
825 mbk_laplace
*laplace
;
830 lines
= awe_tanh_to_pwl( inputslope
, vmax
, vt
, -1.0, -1.0, -1.0, -1.0, -1.0 );
834 laplace
= mbk_pwl_to_laplace( lines
, sizeof( mbk_laplace_data
) );
841 i
< laplace
->N
&& tsat
> ((mbk_laplace_data
*)laplace
->DATA
)[i
].T
;
844 tr
= tsat
- ((mbk_laplace_data
*)laplace
->DATA
)[i
].T
;
845 a
= ((mbk_laplace_data
*)laplace
->DATA
)[i
].A
;
846 v20
=v20
+a
*(tr
-r
*c2
*(1.0-exp(-tr
/(r
*c2
))));
849 mbk_free_laplace( laplace
);
851 mbk_pwl_free_pwl( lines
);
857 /* Convertie une tangente hyperbolique en un ensemble de droites */
858 mbk_pwl
* awe_tanh_to_pwl( RCXFLOAT inputslope
,
870 mbk_pwl_param
*param
;
871 RCXFLOAT t1
, v1
, t2
, v2
;
879 static int fordebug
=0;
883 data
.F
= inputslope
;
886 data
.A
= ( vmax
- vt
) / inputslope
;
888 data
.TSAT
= FLT_MAX
;
892 if( vsat
> 0.0 && rl
>0.0 && r
>0.0 && c1
>0.0 && c2
>0.0 ) {
894 delta
= r
*r
*c2
*c2
+ rl
*rl
*(c1
+c2
)*(c1
+c2
) - 2*r
*rl
*c2
*(c1
-c2
) ;
895 tsat
= inputslope
* atanh( ( vsat
- vt
) / ( vmax
- vt
) ) ;
896 v20
= awe_pi_get_v20( tsat
, inputslope
, vmax
, vt
, r
, c2
);
898 if( delta
> 0.0 && v20
> 0.0 ) {
903 data
.P1
= (-r
*c2
-rl
*(c1
+c2
)-sqrt(delta
))/(2.0*r
*rl
*c1
*c2
) ;
904 data
.P2
= (-r
*c2
-rl
*(c1
+c2
)+sqrt(delta
))/(2.0*r
*rl
*c1
*c2
) ;
914 // Calcule l'instant td<0 de départ de la tanh en supposant qu'entre td et 0
915 // le front est une droite dont la pente vaut la dérivée de la tanh en t=0
919 data
.TR
= - vt
/ data
.A
;
921 tmax
= awe_tanh_tmax( &data
);
923 param
= mbk_pwl_get_default_param( (char (*)(void*, double, double*))awe_tanh
,
929 /* Demande une bonne modélisation de la partie correspondant à la tanh */
931 sdmin
= data
.F
/100.0 ;
932 if( param
->PARAM
.DEFAULT
.DELTAXMIN
> dxmin
)
933 param
->PARAM
.DEFAULT
.DELTAXMIN
= dxmin
;
934 if( param
->PARAM
.DEFAULT
.SDERIVE
> sdmin
)
935 param
->PARAM
.DEFAULT
.SDERIVE
= sdmin
;
938 if( t1
> 2.0*data
.F
)
939 mbk_pwl_add_param_point( param
, t1
);
942 awe_tanh_point_measure( vt
, vmax
, inputslope
, &t1
, &v1
, &t2
, &v2
);
944 mbk_pwl_add_param_point( param
, tsat
);
947 mbk_pwl_add_param_point( param
, t1
);
948 mbk_pwl_add_param_point( param
, t2
);
950 lines
= mbk_pwl_create( (char (*)(void*, double, double*))awe_tanh
,
957 mbk_pwl_free_param( param
);
962 /* Renvoie l'instant à partir duquel le front est considéré comme terminé */
963 double awe_tanh_tmax( awe_tanh_data
*data
)
970 vmax
= 0.99 * data
->VMAX
;
975 if( !awe_tanh( data
, t
, &v
) )
983 /* Fonction locale de tangente hyperbolique */
984 char awe_tanh( awe_tanh_data
*data
, double t
, double *v
)
989 if( t
<= data
->TSAT
)
990 *v
= data
->VT
+ (data
->VMAX
- data
->VT
) * tanh( t
/data
->F
);
994 /* pour eviter une diminution de la tension lorsqu'on passe du
995 générateur modélisé par une tension à une résistance linéaire */
996 r
= data
->R
+ data
->RL
;
997 c
= data
->C1
+ data
->C2
;
998 vmin
= data
->VMAX
*(1.0-exp(-t
/(r
*c
))) +
999 data
->V10
*exp(-t
/(r
*c
)) ;
1001 *v
= ( data
->C1
*data
->V10
+ data
->C2
*data
->V20
+
1002 data
->VMAX
*data
->C2
*data
->R
/data
->RL
)
1003 / ( data
->R
*data
->C1
*data
->C2
)
1004 * ( exp(data
->P1
*t
) - exp(data
->P2
*t
))
1005 / (data
->P1
-data
->P2
) ;
1007 * ( data
->P2
*exp(data
->P2
*t
) - data
->P1
*exp(data
->P1
*t
) )
1008 / ( data
->P2
- data
->P1
) ;
1009 *v
= *v
- data
->VMAX
/ ( data
->R
* data
->RL
* data
->C1
* data
->C2
)
1010 * ( data
->P1
*exp(data
->P2
*t
) - data
->P2
*exp(data
->P1
*t
)
1011 + ( data
->P2
- data
->P1
) )
1012 / ( data
->P1
* data
->P2
* ( data
->P1
- data
->P2
)) ;
1019 *v
= data
->VT
+ t
* data
->A
;
1026 void plot_awe_tanh( awe_tanh_data
*data
, float t_unit
, float tmax
, char *name
)
1030 ptf
= mbkfopen( name
, "dat", "w" );
1031 for( t
=0.0 ; t
<tmax
; t
=t
+0.01 ) {
1032 awe_tanh( data
, t
, &v
);
1033 fprintf( ptf
, "%g %g\n", t
*t_unit
, v
);
1038 /* Converti une tangente hyperbolique en une droite */
1040 void awe_tanh_to_straight( RCXFLOAT inputslope
,
1047 RCXFLOAT v1
, v2
, t1
, t2
;
1051 t1
= INVTH( inputslope
, vt
, vmax
, v1
);
1052 t2
= INVTH( inputslope
, vt
, vmax
, v2
);
1054 *a
= (v1
-v2
)/(t1
-t2
);
1058 void awevoltage_pwl_plot( aweinfo_list
*awe
,
1061 mbk_laplace
*laplace
,
1077 file
= mbkfopen( filename
, "dat", "w" );
1079 printf( "Can't open file.\n" );
1085 t0
= aweinstant_pwl( awe
, vmax
/2.0, vmax
, laplace
, NULL
);
1089 for( t
=-lines
->DATA
[0].B
/lines
->DATA
[0].A
; t
<tmax
; t
=t
+ts
) {
1090 switch( mbk_pwl_get_value( lines
, t
, &ve
) ) {
1091 case MBK_PWL_FOUND
:
1094 case MBK_PWL_ERROR
:
1095 case MBK_PWL_EXTPL
:
1099 vs
= awevoltage_pwl( awe
, t
, laplace
);
1100 if( AWE_DUMP_SLOPE
== TRC_SLOPE_UP
)
1101 fprintf( file
, "%g %g %g\n", t
*t_unit
, ve
, vs
);
1103 fprintf( file
, "%g %g %g\n", t
*t_unit
, vmax
-ve
, vmax
-vs
);
1109 mbk_laplace
* awe_pwl_to_laplace( mbk_pwl
*lines
, aweinfo_list
*awe
)
1114 avt_logenterfunction(LOGTRC
,2,"awe_pwl_to_laplace");
1115 if( awe
->FLAG
== AWE_MOMENT
)
1116 awemomentfiltre( awe
);
1118 if( awe
->FLAG
!= AWE_FILTER
) {
1119 avt_logexitfunction(LOGTRC
,2);
1123 l
= mbk_pwl_to_laplace( lines
, sizeof( mbk_laplace_data
) );
1125 // Normalise les pentes et les délais.
1126 for( i
= 0 ; i
< l
->N
; i
++ ) {
1127 ((mbk_laplace_data
*)l
->DATA
)[i
].A
=
1128 ((mbk_laplace_data
*)l
->DATA
)[i
].A
* awe
->K
;
1129 ((mbk_laplace_data
*)l
->DATA
)[i
].T
=
1130 ((mbk_laplace_data
*)l
->DATA
)[i
].T
/ awe
->K
;
1132 avt_logexitfunction(LOGTRC
,2);
1137 RCXFLOAT
awevoltage_fast( aweinfo_list
*awe
, double f
)
1145 static int fordebug
=0 ;
1147 avt_logenterfunction(LOGTRC
,2, "awevoltage_fast()" );
1151 if( AWE_FAST_MODE
== 'N' ) {
1152 avt_log(LOGTRC
,2, "AWE_FAST_MODE disable\n" );
1153 avt_logexitfunction(LOGTRC
,2);
1157 if( awe
->FLAG
== AWE_NODELAY
) {
1158 avt_log(LOGTRC
,2, "nodelay\n" );
1159 avt_logexitfunction(LOGTRC
,2);
1163 if( awe
->FLAG
== AWE_MOMENT
)
1164 awemomentfiltre( awe
);
1166 if( awe
->FLAG
!= AWE_FILTER
) {
1167 avt_log(LOGTRC
,2,"no filter\n");
1168 avt_logexitfunction(LOGTRC
,2);
1177 for( l
=0 ; l
<awe
->DATA
.FILTER
.ORDER
; l
++ ) {
1179 k
= awe
->DATA
.FILTER
.RESIDU
[l
] ;
1180 p
= -awe
->DATA
.FILTER
.POLE
[l
] ;
1187 avt_logexitfunction(LOGTRC
,2);
1191 /* Une bonne approximation du temps de propagation du réseau RC est
1194 avt_log(LOGTRC
,2, "approx value : %g\n", v
);
1195 avt_logexitfunction(LOGTRC
,2);
1200 RCXFLOAT
awevoltage_pwl( aweinfo_list
*awe
,
1202 mbk_laplace
*laplace
1206 double p
, k
, v
, tr
;
1210 // Calcule la réponse temporelle.
1213 for( i
= 0 ; i
< laplace
->N
&& t
> ((mbk_laplace_data
*)laplace
->DATA
)[i
].T
; i
++ ) {
1215 tr
= t
- ((mbk_laplace_data
*)laplace
->DATA
)[i
].T
;
1217 for( l
=0 ; l
<awe
->DATA
.FILTER
.ORDER
; l
++ ) {
1219 k
= awe
->DATA
.FILTER
.RESIDU
[l
] ;
1220 p
= awe
->DATA
.FILTER
.POLE
[l
] ;
1222 v
= v
+ (((mbk_laplace_data
*)laplace
->DATA
)[i
].A
) * k
/ p
* ( -tr
- 1.0/p
+ exp( tr
*p
)/p
) ;
1225 v
= v
- laplace
->B
* k
/p
*( 1.0 - exp( tr
*p
) ) ;
1232 RCXFLOAT
aweinstant_pwl( aweinfo_list
*awe
,
1235 mbk_laplace
*laplace
,
1239 RCXFLOAT t1
, t2
, lt1
, lt2
, tp
, v
, v1
, v2
;
1241 static int fordebug
=0;
1244 avt_logenterfunction(LOGTRC
,2, "aweinstant_pwl()" );
1245 if( status
) *status
= 0 ;
1247 if( awe
->FLAG
== AWE_NODELAY
)
1249 avt_log(LOGTRC
,2, "aweinstant_pwl() : call with AWE_NODELAY filter.\n" );
1250 avt_logexitfunction(LOGTRC
,2);
1254 /* Calcul du tp par dichotomie */
1259 do { // On vérifie que la solution recherchée est entre t1 et v2.
1261 v
= awevoltage_pwl( awe
, t2
, laplace
);
1270 while( v
< vf
&& n
);
1273 avt_log(LOGTRC
,2, "aweinstant_pwl() : can't solve #1\n" );
1274 avt_logexitfunction(LOGTRC
,2);
1278 v1
= awevoltage_pwl( awe
, t1
, laplace
);
1284 // tp = (t2+t1)/2.0;
1285 tp
= (t2
-t1
)/(v2
-v1
)*(vf
-v1
)+t1
;
1289 v
= awevoltage_pwl( awe
, tp
, laplace
);
1291 if( v
== vf
) { // ça arrive !
1309 while( fabs(v
-vf
)>vmax
/1000.0 && n
);
1312 avt_log(LOGTRC
,2, "aweinstant_pwl() : can't solve #2\n" );
1313 avt_logexitfunction(LOGTRC
,2);
1317 if( status
) *status
= 1 ;
1318 avt_logexitfunction(LOGTRC
,2);
1322 /* Tension à l'instant T lorsque l'entrée est une droite v(t)=a.t+b
1323 jusqu'à vmax et constant après */
1325 RCXFLOAT
awevoltage_straight( aweinfo_list
*awe
,
1333 RCXFLOAT v
, k
, p
, tm
;
1335 if( awe
->FLAG
== AWE_MOMENT
)
1336 awemomentfiltre( awe
);
1338 if( awe
->FLAG
!= AWE_FILTER
)
1346 for( l
=0 ; l
<awe
->DATA
.FILTER
.ORDER
; l
++ ) {
1348 k
= awe
->DATA
.FILTER
.RESIDU
[l
] ;
1349 p
= awe
->DATA
.FILTER
.POLE
[l
] ;
1351 v
= v
+ a
*k
*( -t
/p
- 1.0/p
/p
*(1.0-exp(p
*t
)) ) - b
*k
/p
*(1.0-exp(p
*t
)) ;
1353 v
= v
- (a
*k
*(-(t
-tm
)/p
-1.0/p
/p
*(1.0-exp(p
*(t
-tm
)))));
1359 /* Calcul par dichotomie l'instant de passage de la tension
1360 par vf. L'entrée est une droite */
1362 RCXFLOAT
aweinstant_straight( aweinfo_list
*awe
,
1369 RCXFLOAT t1
, t2
, lt1
, lt2
, tp
, v
, v1
, v2
;
1371 if( awe
->FLAG
== AWE_NODELAY
)
1373 avt_log(LOGTRC
,2, "awe : call aweinstant_straight() with AWE_NODELAY filter.\n"
1378 /* Calcul du tp par dichotomie */
1382 do { // On vérifie que la solution recherchée est entre t1 et v2.
1384 v
= awevoltage_straight( awe
, t2
, vmax
, a
, b
);
1395 v1
= awevoltage_straight( awe
, t1
, vmax
, a
, b
);
1400 // tp = (t2+t1)/2.0;
1401 tp
= (t2
-t1
)/(v2
-v1
)*(vf
-v1
)+t1
;
1405 v
= awevoltage_straight( awe
, tp
, vmax
, a
, b
);
1409 if( v
== vf
) { // ça arrive !
1425 while( fabs(v
-vf
)>vmax
/1000.0 );
1430 /* Fonction utilisée pour normaliser les délais. Renvoie le plus grand moment de 1° ordre
1431 * sur le reseau ( ce nombre est <0 )
1433 int awe_dw_formaxmoment( losig_list
*losig
,
1434 lonode_list
*lonode
,
1441 awetabnode
*tabnode
;
1444 ptl
= getptype( lonode
->USER
, AWENODE
);
1446 awe_error( 3, AVT_INTERNAL
);
1448 tabnode
= (awetabnode
*)ptl
->DATA
;
1449 moment
= tabnode
->MOMENT
[0] ;
1451 if( moment
< *ptmax
)
1461 RCXFLOAT
awemaxmoment( losig_list
*losig
, lonode_list
*node
)
1468 clearallwireflag( losig
, RCN_FLAG_PASS
);
1469 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
1470 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
1472 rcn_treetrip( losig
,
1475 (int (*)(losig_list
*,lonode_list
*,chain_list
*,ht
*,void*))awe_dw_formaxmoment
,
1483 // Renvoie le temps de propagation d'un réseau RC calculé avec AWE à l'ordre
1484 // 3. Comme le calcul des moments est assez long, on ne le fait qu'une fois pour toute
1485 // pour un émetteur donné, et les moments de tous les récepteurs sont mémorisés.
1486 // L'évaluation des poles et résidus étant également couteuse, on ne la fait
1488 // Il faut qu'à tous les appels le réseau et extcapa soient identiques. Sinon, il faut appeler
1489 // avant la fonction awereset().
1490 // Renvoie 1 en cas de succès, 0 sinon.
1492 int getawedelay( lofig_list
*lofig
, // La figure
1493 losig_list
*losig
, // Le signal
1494 locon_list
*locon_emt
, // L'emetteur
1495 locon_list
*locon_rec
, // Le recepteur
1496 rcx_slope
*slopemiller
, // Front d'entrée pour miller
1497 RCXFLOAT vmaxmax
, // Tension max pour delai max
1498 RCXFLOAT vmaxmin
, // Tension max pour delai min
1499 RCXFLOAT extcapa
, // La capacité externe
1500 RCXFLOAT
*dmax
, // Le délai maximum calculé
1501 RCXFLOAT
*dmin
, // minimum
1502 RCXFLOAT
*fmax
, // Le front maximum calculé
1503 RCXFLOAT
*fmin
, // minimum
1504 mbk_pwl
**pwloutmax
,
1511 RCXFLOAT groundcapa
= -1e6
;
1513 char flagmin
=0, flagmax
=0;
1517 chain_list
*headawe
;
1518 chain_list
*scanawe
;
1520 avt_logenterfunction(LOGTRC
,2,"getawedelay()");
1521 avt_log(LOGTRC
,2, "vmaxmax=%g vmaxmin=%g\n", vmaxmax
, vmaxmin
);
1528 if( RCX_PLOT_AWE
) {
1529 if( rcx_getsigname( losig
) == RCX_PLOT_AWE
) {
1530 AWE_DUMP_NETNAME
= RCX_PLOT_AWE
;
1531 AWE_DUMP_SLOPE
= slopemiller
->SENS
;
1535 AWE_DUMP_NETNAME
= NULL
;
1538 AWE_DEBUG_NET
= losig
;
1539 AWE_DEBUG_DRIVER
= locon_emt
;
1540 AWE_DEBUG_RECEIVER
= locon_rec
;
1542 if( slopemiller
->MIN
.slope
< 1.0 )
1543 slopemiller
->MIN
.slope
= 1.0;
1544 if( slopemiller
->MAX
.slope
< 1.0 )
1545 slopemiller
->MAX
.slope
= 1.0;
1547 ctkactive
= rcx_crosstalkactive( RCX_QUERY
);
1549 if( fmin
) *fmin
= -1.0 ;
1550 if( fmax
) *fmax
= -1.0 ;
1551 if( dmin
) *dmin
= -1.0 ;
1552 if( dmax
) *dmax
= -1.0 ;
1555 if( fmin
|| dmin
) {
1556 avt_log(LOGTRC
,2, "computing minimum delays\n" );
1559 rcx_getcoefctc( lofig
, losig
, slopemiller
, RCX_MIN
, extcapa
, &groundcapa
);
1561 headawe
= getaweinfo( losig
,
1570 for( scanawe
= headawe
; scanawe
; scanawe
= scanawe
->NEXT
) {
1571 awe
= (aweinfo_list
*)scanawe
->DATA
;
1572 if( awe
->FLAG
== AWE_NODELAY
)
1577 v
= -1.0 ; // un nombre qui indique qu'on a pas de valeur calculée.
1578 computedfast
= 'n' ;
1582 d
= awevoltage_fast( awe
, slopemiller
->MIN
.slope
);
1583 computedfast
= 'y' ;
1589 slopemiller
->MIN
.slope
,
1591 slopemiller
->MIN
.vt
,
1592 slopemiller
->MIN
.vth
,
1593 slopemiller
->MIN
.vsat
,
1594 slopemiller
->MIN
.rlin
,
1596 slopemiller
->MIN
.c1
,
1597 slopemiller
->MIN
.c2
,
1598 slopemiller
->MIN
.pwl
1602 if( *dmin
< 0.0 || v
< *dmin
)
1611 if( computedfast
== 'n' )
1612 d
= awevoltage_fast( awe
, slopemiller
->MIN
.slope
);
1618 if( slopemiller
->MIN
.pwl
)
1619 pwl
= mbk_pwl_duplicate( slopemiller
->MIN
.pwl
);
1621 v
= slopemiller
->MIN
.slope
;
1626 pwloutmin
? &pwl
: NULL
,
1633 if( *fmin
< 0.0 || v
< *fmin
) {
1636 if( *pwloutmin
) mbk_pwl_free_pwl( *pwloutmin
);
1641 mbk_pwl_free_pwl( pwl
);
1644 mbk_pwl_free_pwl( pwl
);
1649 awefreeinfolist( headawe
);
1650 // Pas de connexion entre les deux locons
1652 avt_log(LOGTRC
,2, "can't compute delays for min\n" );
1653 if( fmin
) *fmin
=slopemiller
->MIN
.slope
;
1654 if( dmin
) *dmin
=0.0;
1658 if( dmax
|| fmax
) {
1660 avt_log(LOGTRC
,2, "computing maximum delays\n" );
1662 /* récupere le delaycache */
1665 rcx_getcoefctc( lofig
, losig
, slopemiller
, RCX_MAX
, extcapa
, &groundcapa
);
1667 headawe
= getaweinfo( losig
,
1675 for( scanawe
= headawe
; scanawe
; scanawe
= scanawe
->NEXT
) {
1676 awe
= (aweinfo_list
*)scanawe
->DATA
;
1677 if( awe
->FLAG
== AWE_NODELAY
)
1682 v
= -1.0 ; // un nombre qui indique qu'on a pas de valeur calculée.
1683 computedfast
= 'n' ;
1687 d
= awevoltage_fast( awe
, slopemiller
->MAX
.slope
);
1688 computedfast
= 'y' ;
1694 slopemiller
->MAX
.slope
,
1696 slopemiller
->MAX
.vt
,
1697 slopemiller
->MAX
.vth
,
1698 slopemiller
->MAX
.vsat
,
1699 slopemiller
->MAX
.rlin
,
1701 slopemiller
->MAX
.c1
,
1702 slopemiller
->MAX
.c2
,
1703 slopemiller
->MAX
.pwl
1707 if( *dmax
< 0.0 || v
> *dmax
)
1716 if( computedfast
== 'n' )
1717 d
= awevoltage_fast( awe
, slopemiller
->MAX
.slope
);
1722 if( slopemiller
->MAX
.pwl
)
1723 pwl
= mbk_pwl_duplicate( slopemiller
->MAX
.pwl
);
1725 v
= slopemiller
->MAX
.slope
;
1730 pwloutmax
? &pwl
: NULL
,
1737 if( *fmax
< 0.0 || v
> *fmax
) {
1740 if( *pwloutmax
) mbk_pwl_free_pwl( *pwloutmax
);
1745 mbk_pwl_free_pwl( pwl
);
1748 mbk_pwl_free_pwl( pwl
);
1753 awefreeinfolist( headawe
);
1755 // Pas de connexion entre les deux locons
1757 avt_log(LOGTRC
,2, "can't compute delays for max\n" );
1758 if( fmax
) *fmax
=slopemiller
->MAX
.slope
;
1759 if( dmax
) *dmax
=0.0;
1763 avt_logexitfunction(LOGTRC
,2);
1768 /******************************************************************************\
1769 Fonctions qui orientent le réseau RC.
1770 Il faut le faire pour chaque émetteur car les triangles supposent qu'on entre
1772 \******************************************************************************/
1774 int awe_up_forcreatetriangle( losig_list
*losig
,
1775 lonode_list
*lonode
,
1776 lowire_list
*lowire
,
1780 rcx_triangle_node( losig
, lonode
, lowire
);
1785 int awe_packup_forcreatetriangle( losig_list
*losig
,
1786 lonode_list
*lonode
,
1792 lonode_list
*tstnode
;
1794 if( tr
->n0
!= lonode
) rcx_triangle_node( losig
, tr
->n0
, NULL
);
1795 if( tr
->n1
!= lonode
) rcx_triangle_node( losig
, tr
->n1
, NULL
);
1796 if( tr
->n2
!= lonode
) rcx_triangle_node( losig
, tr
->n2
, NULL
);
1797 for( chain
= tr
->REPORTED_IN
; chain
; chain
= chain
->NEXT
) {
1798 tstnode
= (lonode_list
*)chain
->DATA
;
1799 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1801 for( chain
= tr
->REPORTED_N1
; chain
; chain
= chain
->NEXT
) {
1802 tstnode
= (lonode_list
*)chain
->DATA
;
1803 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1805 for( chain
= tr
->REPORTED_N2
; chain
; chain
= chain
->NEXT
) {
1806 tstnode
= (lonode_list
*)chain
->DATA
;
1807 if( tstnode
!= lonode
) rcx_triangle_node( losig
, tstnode
, NULL
);
1814 int awe_dw_forcleantriangle( losig_list
*losig
,
1815 lonode_list
*lonode
,
1821 chain_list
*headht
, *chain
;
1825 headht
= GetAllHTElems( htpack
);
1827 for( chain
= headht
; chain
; chain
= chain
->NEXT
) {
1828 wire
= (lowire_list
*)((chain_list
*)chain
->DATA
)->DATA
;
1829 tr
= (rcx_triangle
*)rcn_getpack( losig
, wire
) ;
1830 rcx_cleantriangle_node( losig
, lonode
, tr
);
1833 freechain( headht
);
1840 void awe_create_triangle( losig_list
*losig
, lonode_list
*driver
)
1844 avt_logenterfunction(LOGTRC
,2,"awe_create_triangle()");
1845 clearallwireflag( losig
, RCN_FLAG_PASS
);
1846 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
1847 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
1849 rcn_treetrip( losig
,
1851 awe_up_forcreatetriangle
,
1853 (int (*)(losig_list
*,lonode_list
*,void*,void*))
1854 awe_packup_forcreatetriangle
,
1858 avt_logexitfunction(LOGTRC
,2);
1861 void awe_clean_triangle( losig_list
*losig
, lonode_list
*driver
)
1865 clearallwireflag( losig
, RCN_FLAG_PASS
);
1866 for( wire
= losig
->PRCN
->PWIRE
; wire
; wire
= wire
->NEXT
)
1867 RCN_CLEARFLAG( wire
->FLAG
, RCXNODEINTR
);
1869 rcn_treetrip( losig
,
1872 awe_dw_forcleantriangle
,
1879 /******************************************************************************\
1880 Fonction qui récupère les moments sur le réseau RC.
1881 \******************************************************************************/
1882 chain_list
* getaweinfo( losig_list
*losig
,
1886 rcx_slope
*slopemiller
,
1895 chain_list
*head
= NULL
;
1897 chain_list
*removeextra
= NULL
;
1899 unsigned long int sizeallocated
=0;
1906 avt_logenterfunction(LOGTRC
,2,"getaweinfo()");
1908 cache
= rcx_get_delay_cache();
1910 mbk_cache_refresh( cache
, NULL
, losig
);
1911 mbk_cache_lock( cache
, losig
);
1912 awetop
= rcx_get_cache_awe( losig
,
1915 rcx_crosstalkactive( RCX_QUERY
)
1918 if( awetop
&& awetop
->HEAD
) {
1920 list
= (chain_list
*)gethtitem( awetop
->HT
, load
);
1921 if( list
!= (chain_list
*)EMPTYHT
&& list
!= (chain_list
*)DELETEHT
) {
1923 awe
= (aweinfo_list
*)list
->DATA
;
1924 if( awe
->LOCON_DRIVER
== driver
&&
1925 awe
->EXTCAPA
== extcapa
)
1926 head
= addchain( head
, awe
);
1932 awe
= awetop
->HEAD
;
1934 if( awe
->LOCON_DRIVER
== driver
&&
1935 awe
->LOCON_LOAD
== load
&&
1936 awe
->EXTCAPA
== extcapa
)
1937 head
= addchain( head
, awe
);
1944 avt_logexitfunction(LOGTRC
,2);
1945 mbk_cache_unlock( cache
, losig
);
1950 // Il faut calculer tous les moments sur les récepteurs à partir de l'emetteur driver.
1951 if( !driver
->PNODE
) {
1952 awe_error( 4, AVT_WARNING
);
1953 avt_logexitfunction(LOGTRC
,2);
1954 mbk_cache_unlock( cache
, losig
);
1958 rcx
= getrcx( losig
);
1960 isloop
= rcx_isloop( rcx
, losig
);
1964 if( ( RCX_USING_AWEMATRIX
==RCX_USING_AWEMATRIX_ALWAYS
||
1965 RCX_USING_AWEMATRIX
==RCX_USING_AWEMATRIX_FORCE
) ||
1966 ( RCX_USING_AWEMATRIX
==RCX_USING_AWEMATRIX_IFNEED
&&
1968 rcx_is_multiple_pnode( losig
, driver
) ) ) )
1969 build_awe_moment_with_loop( losig
,
1977 build_awe_moment_without_loop( losig
,
1985 ptl
= getptype( losig
->USER
, AWEINFO
);
1987 if( ptl
) { // Cas des composantes connexes
1989 for( awe
= (aweinfo_list
*)(ptl
->DATA
) ; awe
; awe
= awe
->NEXT
) {
1990 if( awe
->LOCON_DRIVER
== driver
&&
1991 awe
->LOCON_LOAD
== load
&&
1992 awe
->EXTCAPA
== extcapa
)
1993 head
= addchain( head
, awe
);
1996 removeextra
= addchain( removeextra
, awe
);
2001 sizeallocated
= rcx_add_cache_awe( losig
,
2004 rcx_crosstalkactive( RCX_QUERY
)
2006 mbk_cache_update_size( cache
, NULL
, sizeallocated
);
2007 // trccheckcachecoherence();
2010 awefreeinfolist( removeextra
);
2013 losig
->USER
= delptype( losig
->USER
, AWEINFO
);
2017 mbk_cache_unlock( cache
, losig
);
2019 avt_logexitfunction(LOGTRC
,2);
2023 /* return 1 if pnodes for locon 'driver' should be considered as mulptiple
2024 simultaneous driver, or 0 if they can be considers as equivalent. */
2026 int rcx_is_multiple_pnode( losig_list
*losig
, locon_list
*driver
)
2032 lonode_list
*lonode
;
2037 avt_logenterfunction(LOGTRC
,2,"rcx_is_multiple_pnode()");
2041 if( !driver
->PNODE
) {
2042 avt_log(LOGTRC
,2, "no pnode found on locon %s\n", getloconrcxname( driver
) );
2043 avt_logexitfunction(LOGTRC
,2);
2047 /* first test : check the number of pnode */
2049 for( pnode
= driver
->PNODE
; pnode
; pnode
= pnode
->NEXT
)
2053 avt_log(LOGTRC
,2, "more than 3 pnode found on locon %s\n", getloconrcxname( driver
) );
2054 avt_logexitfunction(LOGTRC
,2);
2058 capa
= rcx_getcapa( NULL
, losig
);
2060 for( pnode
= driver
->PNODE
; pnode
; pnode
= pnode
->NEXT
) {
2062 avt_log(LOGTRC
,2,"computing from node %ld\n", pnode
->DATA
);
2064 rcn_treetrip( losig
,
2065 getlonode( losig
, pnode
->DATA
),
2072 for( onode
= pnode
->NEXT
; onode
; onode
= onode
->NEXT
) {
2073 lonode
= getlonode( losig
, onode
->DATA
);
2074 ptl
= getptype( lonode
->USER
, AWESUMRESI
);
2076 resi
= ((long)ptl
->DATA
)/1000.0 ;
2077 if( resi
* capa
> 1.0 )
2081 /* the number of wire between pnode and onode exceed the value of the
2082 last argument of rcn_treetrip */
2089 avt_log(LOGTRC
,2, "cleanning\n" );
2090 rcn_treetrip( losig
,
2091 getlonode( losig
, pnode
->DATA
),
2103 avt_logexitfunction(LOGTRC
,2);
2107 int rcx_imp_clean( losig_list
*losig
,
2108 lonode_list
*lonode
,
2109 lowire_list
*lowire
,
2115 ptl
= getptype( lonode
->USER
, AWESUMRESI
);
2117 lonode
->USER
= delptype( lonode
->USER
, AWESUMRESI
);
2126 int rcx_imp_prop( losig_list
*losig
,
2127 lonode_list
*lonode
,
2128 lowire_list
*lowire
,
2135 lonode_list
*pfrom
;
2137 ptl
= getptype( lonode
->USER
, AWESUMRESI
);
2139 /* big problem : there is a loop not detected by rcn_treetrip */
2140 awe_error( 5, AVT_INTERNAL
);
2143 ifrom
= (lowire
->NODE1
== lonode
->INDEX
? lowire
->NODE2
: lowire
->NODE1
);
2144 pfrom
= getlonode( losig
, ifrom
);
2145 ptl
= getptype( pfrom
->USER
, AWESUMRESI
);
2147 resi
= ((long)ptl
->DATA
);
2150 resi
= resi
+ ((int)(1000.0*lowire
->RESI
));
2151 lonode
->USER
= addptype( lonode
->USER
, AWESUMRESI
, (void*)((long)resi
) );
2158 void build_awe_moment_without_loop( losig_list
*losig
,
2161 rcx_slope
*slopemiller
,
2166 num_list
*scan_driver
;
2167 lonode_list
*node_driver
;
2170 avt_logenterfunction(LOGTRC
,2,"build_awe_moment_without_loop()");
2172 for( scan_driver
= driver
->PNODE
; scan_driver
; scan_driver
= scan_driver
->NEXT
) {
2174 avt_log(LOGTRC
,2, "from driver %d\n", scan_driver
->DATA
);
2177 // On ne compte que les vrais appels. Pas les récursifs.
2178 awestatcallmoment
++;
2181 // Premiere étape, on reserve la mémoire pour les moments sur tous les noeuds du reseau RC.
2183 node_driver
= getlonode( losig
, scan_driver
->DATA
);
2185 awe_create_triangle( losig
, node_driver
);
2187 awebuildnodes( losig
,
2196 // Ensuite, on construit le premier moment : il sert à normaliser les résultats pour ne pas
2197 // avoir trop d'erreur d'arrondi dans les calculs.
2199 #ifdef AWE_NORMALISE
2200 avt_log(LOGTRC
,2,"normalisation\n");
2201 awemoment( losig
, node_driver
, 1, 1.0, extcapa
);
2202 k
= -awemaxmoment( losig
, node_driver
);
2203 awebuildnodes( losig
,
2210 ); // Réinitialise les SUMMOMENTCAPA
2216 avt_log(LOGTRC
,2,"building moment\n");
2217 // Enfin, on construit définitivement les moments.
2218 for( n
=1;n
<=AWE_MAX_MOMENT
;n
++)
2219 awemoment( losig
, node_driver
, n
, k
, extcapa
);
2221 // On les mémorise finalement dans les structures aweinfo.
2222 awebuildinfo( losig
, driver
, node_driver
->INDEX
, k
, extcapa
);
2224 // Puis on efface ceux qui ne servent à rien.
2225 avt_log(LOGTRC
,2,"cleanning\n");
2226 awecleannodes( losig
, node_driver
);
2227 awe_clean_triangle( losig
, node_driver
);
2230 avt_logexitfunction(LOGTRC
,2);
2233 void awebuildinfo( losig_list
*ptsig
,
2240 chain_list
*scanlocon
;
2241 num_list
*scannode
;
2243 awetabnode
*tabnode
;
2244 lonode_list
*ptnode
;
2246 double m
[AWE_MAX_MOMENT
];
2249 for( i
=0 ; i
<AWE_MAX_MOMENT
; i
++ )
2252 for( scanlocon
= (chain_list
*)(getptype( ptsig
->USER
, LOFIGCHAIN
)->DATA
) ;
2254 scanlocon
= scanlocon
->NEXT
) {
2256 load
= (locon_list
*)(scanlocon
->DATA
);
2257 if( !rcx_isvalidlocon( load
) )
2260 if( load
!= driver
) {
2262 for( scannode
= load
->PNODE
; scannode
; scannode
= scannode
->NEXT
) {
2264 if( node_driver
== scannode
->DATA
) {
2265 aweaddnodeinfo( ptsig
,
2277 ptnode
= getlonode( ptsig
, scannode
->DATA
);
2279 // lorsqu'on a plusieurs composantes connexes, il est possible
2280 // de ne pas avoir de ptype construits.
2281 ptl
= getptype( ptnode
->USER
, AWENODE
);
2283 aweaddnodeinfo( ptsig
,
2295 tabnode
= (awetabnode
*)(ptl
->DATA
);
2297 aweaddnodeinfo( ptsig
,
2311 aweinfo_list
* awegetheapinfo( void )
2313 aweinfo_list
*pt
=NULL
;
2315 pt
= (aweinfo_list
*)mbkalloc(sizeof( aweinfo_list
));
2319 void awefreeinfo( aweinfo_list
*awe
)
2324 aweinfo_list
* awegetnewinfo( void )
2328 pt
= awegetheapinfo();
2332 aweinfo_list
* aweaddnodeinfo( losig_list
*signal
,
2346 pt
= awegetnewinfo( );
2348 pt
->LOCON_DRIVER
= driver
;
2349 pt
->NODE_DRIVER
= node_driver
;
2350 pt
->LOCON_LOAD
= load
;
2351 pt
->NODE_LOAD
= node_load
;
2353 pt
->EXTCAPA
= extcapa
;
2355 // Cas où tous les moments sont nuls : l'émetteur et le récepteur sont
2356 // sur le meme noeud.
2358 for( i
=0 ; i
< AWE_MAX_MOMENT
; i
++ ) {
2359 if( moment
[i
] != 0.0 )
2363 if( i
==AWE_MAX_MOMENT
) {
2364 pt
->FLAG
= AWE_NODELAY
;
2366 pt
->FLAG
= AWE_MOMENT
;
2369 for( i
= 0 ; i
< AWE_MAX_MOMENT
; i
++ ) {
2370 pt
->DATA
.MOMENT
[i
] = moment
[i
];
2373 ptl
= getptype( signal
->USER
, AWEINFO
);
2375 signal
->USER
= addptype( signal
->USER
, AWEINFO
, NULL
) ;
2376 ptl
= signal
->USER
;
2379 pt
->NEXT
= (aweinfo_list
*)(ptl
->DATA
);
2385 void awemomentfiltre( aweinfo_list
*info
)
2387 matrice
*a
, *c
, *alpha
;
2389 matrice
*polea
, *polec
, *polex
;
2390 RCXFLOAT poles
[AWE_MAX_ORDER
], poly
[AWE_MAX_ORDER
+1];
2393 avt_logenterfunction(LOGTRC
,2,"awemomentfiltre()");
2395 if( info
->FLAG
== AWE_NODELAY
) {
2396 avt_log(LOGTRC
,2,"nodelay\n");
2397 avt_logexitfunction(LOGTRC
,2);
2402 awestatcallfilter
++;
2405 ordre
= AWE_MAX_ORDER
+1;
2410 avt_log(LOGTRC
,2,"order %d\n", ordre
);
2413 info
->FLAG
= (AWE_FLAGERROR
| AWE_FLAGALLORDERFAILED
);
2415 avt_errmsg( TRC_ERRMSG
, "002", AVT_WARNING
,
2416 rcx_getsigname( AWE_DEBUG_NET
) );
2420 avt_log(LOGTRC
,2, "building matrix\n");
2421 a
= mat_create( ordre
, ordre
);
2422 alpha
= mat_create( ordre
, 1 );
2423 c
= mat_create( ordre
, 1 );
2424 polea
= mat_create( ordre
, ordre
);
2425 polec
= mat_create( ordre
, 1 );
2426 polex
= mat_create( ordre
, 1 );
2428 for( l
= 0 ; l
< ordre
; l
++ )
2430 for( m
= 0, k
=l
; m
< ordre
; m
++, k
++ )
2431 MATELEM( a
, l
, m
) = ( (k
==0) ? 1.0 : info
->DATA
.MOMENT
[k
-1] );
2434 for( l
= 0 ; l
< ordre
; l
++ )
2435 MATELEM( c
, l
, 0 ) = -info
->DATA
.MOMENT
[ordre
+l
-1];
2437 // Détermination du dénominateur de la fonction de transfert
2439 avt_log(LOGTRC
,2,"finding denominator\n" );
2441 if( !mat_solve( a
, c
, alpha
) ) {
2442 avt_log(LOGTRC
,2, "singular matrix at order %d on signal %s.\n",
2444 rcx_getsigname( info
->LOCON_DRIVER
->SIG
)
2456 // Vérifier qu'on a pas de nan :
2459 /* on recupère dans alpha le dénominateur de la fonction de transfert :
2460 * bn.s^n+...+b2.s^2+b1.s+1 -> (bn,...,b2,b1)
2463 for( l
=0 ; l
<ordre
; l
++ )
2464 poly
[l
+1] = MATELEM(alpha
, ordre
-1-l
, 0);
2467 // On récupère les racines de ce polynome. Si on a pas pu les obtenir, on abandonne
2468 avt_log(LOGTRC
,2,"finding root\n");
2470 if( poly_findroot( poly
, ordre
, poles
) == 0 ) {
2471 avt_log(LOGTRC
,2, "awe : can't find roots at order %d on signal %s.\n",
2473 rcx_getsigname( info
->LOCON_DRIVER
->SIG
)
2484 /* En principe, toutes les racines sont censées être négatives. On le vérifie
2486 for( l
= 0 ; l
< ordre
; l
++ )
2487 if( poles
[l
]>=0.0 ) {
2488 avt_log(LOGTRC
,2, "awe : a positive root has been found at order %d on signal %s.\n",
2490 rcx_getsigname( info
->LOCON_DRIVER
->SIG
)
2504 /* on détermine les résidus */
2506 avt_log(LOGTRC
,2,"find residues\n");
2507 for( l
= 0 ; l
< ordre
; l
++ )
2508 for( m
= 0 ; m
< ordre
; m
++ )
2509 MATELEM( polea
, l
, m
) = 1.0/pow(poles
[m
],l
+1.0);
2511 MATELEM( polec
, 0, 0 ) = -1.0;
2512 for( l
= 1 ; l
< ordre
; l
++ )
2513 MATELEM( polec
, l
, 0 ) = -info
->DATA
.MOMENT
[l
-1];
2515 if( !mat_solve( polea
, polec
, polex
) ) {
2516 avt_log(LOGTRC
,2, "awe : risidues matrix is singular at order %d on signal %s.\n",
2518 rcx_getsigname( info
->LOCON_DRIVER
->SIG
)
2529 // C'est fini : on range le tout.
2531 avt_log(LOGTRC
,2,"parameter determined\n");
2532 info
->FLAG
= AWE_FILTER
;
2533 for( l
=0 ; l
<ordre
; l
++ ) {
2534 info
->DATA
.FILTER
.POLE
[l
] = poles
[l
];
2535 info
->DATA
.FILTER
.RESIDU
[l
] = MATELEM( polex
, l
, 0 ) ;
2537 info
->DATA
.FILTER
.ORDER
= ordre
;
2547 while( info
->FLAG
== AWE_MOMENT
);
2548 avt_logexitfunction(LOGTRC
,2);
2551 /******************************************************************************\
2552 Renvoie une liste de délais.
2553 \******************************************************************************/
2555 awelist
* getawedelaylist( lofig_list
*lofig
,
2557 locon_list
*locon_emt
,
2558 rcx_slope
*slopemiller
,
2565 RCXFLOAT dmax
, dmin
, fmax
, fmin
;
2566 awelist
*headlist
=NULL
;
2568 for( chain
= ((chain_list
*)(getptype( losig
->USER
, LOFIGCHAIN
)->DATA
) ) ;
2573 locon
= (locon_list
*)chain
->DATA
;
2574 if( !rcx_isvalidlocon( locon
) )
2577 if( locon
== locon_emt
)
2580 res
= getawedelay( lofig
, losig
, locon_emt
, locon
,
2582 slopemiller
->MAX
.vend
,
2583 slopemiller
->MIN
.vend
,
2594 headlist
= addawelist( headlist
, locon
, dmax
, dmin
, fmax
, fmin
);
2600 void freeawedelaylist( awelist
*headlist
)
2605 next
= headlist
->NEXT
;
2606 mbkfree( headlist
);
2611 awelist
*addawelist( awelist
*head
, locon_list
*locon
,
2612 RCXFLOAT dmax
, RCXFLOAT dmin
, RCXFLOAT fmax
, RCXFLOAT fmin
2617 new = mbkalloc( sizeof( awelist
) );
2628 void awe_error( int subcode
, int type
)
2630 avt_errmsg( TRC_ERRMSG
, "000", type
,
2632 rcx_getsigname( AWE_DEBUG_NET
),
2633 getloconrcxname( AWE_DEBUG_DRIVER
),
2634 getloconrcxname( AWE_DEBUG_RECEIVER
)
2638 void awefreeinfolist( chain_list
*head
)
2643 cache
= rcx_get_delay_cache();
2646 for( scan
= head
; scan
; scan
= scan
->NEXT
) {
2647 awefreeinfo( (aweinfo_list
*)scan
->DATA
);
2654 awecache
* rcx_get_cache_awe( losig_list
*losig
,
2666 ptl
= getptype( losig
->USER
, RCX_DELAYCACHE
);
2668 avt_errmsg( TRC_ERRMSG
, "047", AVT_ERROR
, rcx_getsigname( losig
) );
2673 rcx_cache_build_ptype( transition
, type
, iscrosstalk
, RCX_MODEL_AWE
);
2675 for( ptype
= (ptype_list
*)ptl
->DATA
; ptype
; ptype
= ptype
->NEXT
) {
2677 if( ptype
->TYPE
== ntype
) {
2678 awe
= (awecache
*)ptype
->DATA
;
2686 unsigned long int rcx_add_cache_awe( losig_list
*losig
,
2692 unsigned long int size_allocated
= 0 ;
2696 aweinfo_list
*head
;
2699 ptl
= getptype( losig
->USER
, RCX_DELAYCACHE
);
2701 avt_errmsg( TRC_ERRMSG
, "047", AVT_ERROR
, rcx_getsigname( losig
) );
2706 rcx_cache_build_ptype( transition
, type
, iscrosstalk
, RCX_MODEL_AWE
);
2708 for( ptype
= (ptype_list
*)ptl
->DATA
; ptype
; ptype
= ptype
->NEXT
) {
2710 if( ptype
->TYPE
== ntype
)
2716 awetop
= mbkalloc( sizeof( awecache
) );
2717 awetop
->HEAD
= NULL
;
2720 size_allocated
+= sizeof( awecache
);
2722 ptl
->DATA
= addptype( (ptype_list
*)ptl
->DATA
, ntype
, awetop
);
2723 size_allocated
+= sizeof( ptype_list
);
2727 awetop
= (awecache
*)ptype
->DATA
;
2730 ptl
= getptype( losig
->USER
, AWEINFO
);
2733 head
= (aweinfo_list
*)ptl
->DATA
;
2737 while( head
->NEXT
) {
2738 size_allocated
+= sizeof( aweinfo_list
);
2742 size_allocated
+= sizeof( aweinfo_list
);
2745 size_allocated
+= rcx_awe_cache_update_ht( awetop
,
2746 (aweinfo_list
*)ptl
->DATA
2749 head
->NEXT
= awetop
->HEAD
;
2750 awetop
->HEAD
= (aweinfo_list
*)ptl
->DATA
;
2756 avt_errmsg( TRC_ERRMSG
, "047", AVT_ERROR
, rcx_getsigname( losig
) );
2759 return size_allocated
;
2762 unsigned long int rcx_awe_cache_update_ht( awecache
*awetop
,
2766 aweinfo_list
*scan
;
2767 unsigned long int size
=0;
2769 /* pas de prise en compte de la taille de la table de hash car sa taille
2771 if( awetop
->HT
== NULL
) {
2772 if( awetop
->NB
> 30 ) {
2773 awetop
->HT
= addht(30);
2774 for( scan
= awetop
->HEAD
; scan
; scan
= scan
->NEXT
) {
2775 size
+= sizeof( chain_list
);
2776 rcx_awe_cache_add_ht( awetop
->HT
, scan
);
2781 for( scan
= head
; scan
; scan
= scan
->NEXT
) {
2782 size
+= sizeof( chain_list
);
2783 rcx_awe_cache_add_ht( awetop
->HT
, scan
);
2790 void rcx_awe_cache_add_ht( ht
*ht
, aweinfo_list
*aweinfo
)
2792 controlled_addhtitem( ht
,
2793 aweinfo
->LOCON_LOAD
,
2794 (long(*)(int,long,void*))rcx_awe_cache_fn
,
2799 long rcx_awe_cache_fn( int isnew
, chain_list
*head
, aweinfo_list
*awe
)
2802 return (long) addchain( NULL
, awe
);
2803 return (long) addchain( head
, awe
);
2806 unsigned long int rcx_cache_release_awe( awecache
*awetop
)
2808 unsigned long int torelease
= 0;
2809 aweinfo_list
*next
;
2810 aweinfo_list
*head
;
2811 chain_list
*chainht
;
2812 chain_list
*scanht
;
2815 head
= awetop
->HEAD
;
2817 torelease
+= sizeof( aweinfo_list
);
2819 awefreeinfo( head
);
2823 chainht
= GetAllHTElems( awetop
->HT
);
2824 for( scanht
= chainht
; scanht
; scanht
= scanht
->NEXT
) {
2825 for( count
= (chain_list
*)scanht
->DATA
; count
; count
= count
->NEXT
)
2826 torelease
+= sizeof( chain_list
) ;
2827 freechain( (chain_list
*)scanht
->DATA
);
2829 freechain( chainht
);
2830 delht( awetop
->HT
);
2833 torelease
+= sizeof( awecache
);