• Aucun résultat trouvé

Avantages et inconvénients de la logique asynchrone

6.1 Méthode de conception asynchrone

6.1.3 Avantages et inconvénients de la logique asynchrone

6.1.3.1 Pipeline élastique

Le pipeline, que ce soit en logique synchrone ou asynchrone permet d’effectuer plusieurs tâches en parallèle. L’avantage en logique asynchrone, c’est que celui-ci a une capacité variable grâce aux mécanismes de synchronisation locale. Ainsi les données peuvent se déplacer dans le pipeline aussi loin qu’elles ne rencontrent pas de ressources occupées et ne sont pas forcément séparées par le même nombre d’étage au court du temps.

6.1.3.2 Circuit adapté à des évènements non déterministes

Les évènements non déterministes peuvent faire référence aux interruptions dans un processeur par exemple. En synchrone il est nécessaire d’échantillonner le signal d’inter- ruption et le resynchroniser avec l’horloge. Ici le signal d’interruption est considéré comme un évènement normal et est traité directement par la logique QDI, ce qui est un avan- tage certain pour notre application qui exécute du code uniquement sur interruptions. De plus les temps de réveil sont instantanés en logique asynchrone car aucune horloge n’est à

Figure6.6 – Exemple de propagation d’un signal dans un pipeline de simple buffer QDI WCHB

réveiller et la mise en veille s’effectue de manière intrinsèque par la logique.

6.1.3.3 Calcul en temps minimum et temps moyen

Nous avons pu voir qu’un opérateur pouvait avoir une latence variable (figure 6.4) suivant les données d’entrée et le chemin utilisé. Cette latence est comprise entre une borne minimum et une borne supérieure. En asynchrone le calcul s’effectue au plus tôt suivant la fonction à évaluer, les données et le chemin parcouru, en d’autre terme il fonctionne à la vitesse maximale permise par le dispositif. Contrairement au synchrone, les performances globales ne sont pas contraintes par le pire cas d’un bloc. Il faut alors optimiser les temps de calcul moyen des blocs en moyenne les plus utilisés.

6.1.3.4 Absence d’horloge

L’avantage considérable des circuits asynchrones est de ne pas avoir d’horloge globale. L’arbre d’horloge dans un circuit synchrone représente une grande partie de la consom- mation. En asynchrone les éléments de synchronisation sont distribués dans l’ensemble du circuit et leur conception est nettement plus facile. Il n’y a plus de problèmes de temps de

skew ou temps de hold à respecter, le temps d’arrivée d’un signal d’un bout à l’autre du

circuit n’a pas d’importance, il faut juste respecter le principe de fourche isochrone.

6.1.3.5 Consommation évènementielle et lisse

Le fonctionnement évènementiel des circuits asynchrones impacte sa consommation. En effet, l’absence d’horloge supprime la consommation due aux transitions dans les bas- cules et les chargements de l’arbre d’horloge. Les aléas de la logique combinatoires sont supprimés en asynchrone et représentent une consommation non négligeable en synchrone. La consommation dynamique du circuit asynchrone varie proportionnellement au nombre d’évènements à traiter. De plus les transitions apparaissent uniquement quand des données sont à traiter, pas comme en synchrone ou les blocs commutent tous au signal d’horloge

Méthode de conception asynchrone 93 même si cela est inutile. Ceci engendre un clock gating naturel de la logique asynchrone à tous les niveaux de granularité lorsqu’il n’y a rien à traiter.

Grâce au fonctionnement évènementiel, la consommation des opérateurs est répartie sur le temps au fur et à mesure que les évènements se propagent dans la logique. De plus, il n’y a pas de pic de courant à chaque coup d’horloge comme en synchrone, ce qui implique une consommation en courant nettement plus lisse que pour un circuit synchrone. Ceci implique par la même occasion une réduction des émissions électromagnétiques du circuit et est donc moins sensible à des attaques de type étude des émissions électromagnétiques du circuit dans le domaine de la sécurité.

6.1.3.6 Robustesse des circuits asynchrones et souplesses d’alimentation L’un des grands avantages de la logique asynchrone est sa robustesse aux variations de tension et de température. En effet la logique asynchrone est correcte par construction et ainsi, en réduisant la tension d’alimentation, on augmente les temps de propagation dans la logique mais cela n’impacte pas le fonctionnement du circuit. Ainsi en asynchrone il est aisé de diminuer la tension d’alimentation pour diminuer sa consommation de puissance tout en perdant d’un autre côté des performances.

6.1.3.7 Augmentation de la surface du circuit

L’un des problèmes majeurs de la logique asynchrone est par contre l’augmentation de la surface du circuit. En effet, par rapport à un équivalent synchrone, la surface du circuit asynchrone peut être doublée, ce qui augmente la consommation statique du circuit. Mais heureusement, comme nous l’avons vu, il est très aisé de pouvoir diminuer les tensions d’alimentation du circuit pour réduire la consommation de puissance tout en garantissant son fonctionnement. C’est pourquoi dans notre cas, durant les longues périodes de veille il sera nécessaire de diminuer la tension de la logique asynchrone à sa tension minimale de rétention et de l’élever lorsqu’un évènement est à traiter. Il peut être aussi envisageable de couper l’alimentation d’une partie de la logique asynchrone pour réduire encore plus la consommation statique pendant ces longues phases de veille.

6.1.4 Exemples de description de modules asynchrones en SystemVerilog avec les outils de Tiempo

Cette section a pour but de présenter la manière de décrire des modules en SystemVeri- log grâce aux outils de Tiempo. La description de ces modules sont basées sur des méthodes de lecture et d’écriture sur les canaux asynchrones pour obtenir une synchronisation locale entre les modules. L’annexe B présente des structures asynchrones très utilisées dans le WUC. L’exemple d’un banc de registres avec uniquement quatre registres va être détaillé dans cette section.

Il faut dans un premier temps décrire les ports d’entrées/sorties du module à l’aide de canaux push_channel_bitx comme montré ci-dessous.

1 module reg_file_cha n 2 ( 3 /∗ ∗∗∗∗∗∗∗∗∗∗ Data i n ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/ 4 // R e g i s t e r Number 5 push_channel_bit2 . i n Op1_i , 6 push_channel_bit2 . i n Op2_i , 7 push_channel_bit2 . i n Dest_i ,

8 // Unit Data Write

9 push_channel_bit32 . i n Units_i , 10

11 /∗ ∗∗∗∗∗∗∗∗∗∗ Data out ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗/ 12 //Bus 1 and 2 Read

13 push_channel_bit32 . out Bus1_o , 14 push_channel_bit32 . out Bus2_o , 15

16 (∗ ACC_Reset ∗) input b i t r e s e t n 17 ) ;

Ensuite les différents processus se déclarent toujours entre un always begin et end. Ces processus ouvrent des canaux grâce à la méthode BeginRead(), effectuent un travail sur les données entrantes pour écrire sur d’autres canaux grâce à la méthode Write() et referment les canaux ouverts avec la méthode EndRead(). L’exemple ci-dessous montre le processus de lecture dans le banc de registres pour écrire l’opérande 1 sur le bus 1.

1 always

2 begin: Read_reg_1

3 b i t 2 op1 ; 4 b i t 3 2 data ; 5

6 Op1_i . BeginRead ( op1 ) ; 7 unique c a s e( op1 ) 8 ‘R0 :begin

9 r0 . BeginRead ( data ) ; 10 Bus1_o . Write ( data ) ; 11 r0 . EndRead ( ) ;

12 end

13 ‘R1 :begin

14 r1 . BeginRead ( data ) ; 15 Bus1_o . Write ( data ) ; 16 r1 . EndRead ( ) ;

17 end

18 ‘R2 : begin

19 r2 . BeginRead ( data ) ; 20 Bus1_o . Write ( data ) ; 21 r2 . EndRead ( ) ;

22 end

23 ‘R3 : begin

24 r3 . BeginRead ( data ) ; 25 Bus1_o . Write ( data ) ; 26 r3 . EndRead ( ) ;

27 end

28 endcase

29 Op1_i . EndRead ( ) ; 30 end

Chaque processus est ainsi déclaré de cette manière et les canaux de lecture se ferment uniquement quand les écritures sur les canaux à l’intérieur du processus ont été acquittées. Les registres sont décrits à l’aide de Shared Variable et sont synthétisés avec des cel-

Architecture de la mémoire de programme et données 95 lules de registre. Différents types de conflits peuvent être gérés par la Shared Variable : aucun conflit, lecture-écriture, écriture-écriture, tous les conflits. Voici comment déclarer un registre en asynchrone :

1 s h a r e d _ v a r i a b l e _ bi t 3 2 #(.INITIAL_VALUE( 3 2 ’ h00000000 ) , . ACCESS_CONFLICT(E_READ_WRITE_CONFLICT_C) ) r0 ( ) ;