Fonctionnement d'un ordinateur/Les circuits compteurs et décompteurs
Les compteurs/décompteurs sont des circuits électroniques qui mémorisent un nombre et l'incrémentent à la demande. En clair, ce sont des registres améliorés afin de supporter l'incrémentation et la décrémentation. Pour donner un exemple d'utilisation, imaginez un circuit qui compte le nombre de voitures dans un parking dans la journée. Pour cela, vous allez prendre deux circuits qui détectent respectivement l'entrée ou la sortie d'une voiture, et un compteur. Le compteur est initialisé à 0 quand le parking est vide, puis est incrémenté à chaque entrée de voiture, décrémenté à chaque sortie. Les exemples de ce type sont suffisamment nombreux pour qu'on dédie un chapitre aux compteurs.
Les compteurs/décompteurs : généralités
[modifier | modifier le wikicode]Un compteur mémorise donc un nombre qui est incrémenté ou décrémenté au besoin. Le nombre mémorisé sera appelé le décompte dans ce qui suit. Il faut faire la différence entre les compteurs d'un côté et les décompteurs de l'autre. Les compteurs incrémentent le décompte, les décompteurs le décrémentent, les compteurs-décompteurs peuvent faire les deux, suivant ce qu'on leur demande. Le décompte est incrémenté/décrémenté d'une quantité appelée le pas du compteur. La plupart des compteurs utilisent un pas constant, qui est fixé à la création du compteur, ce qui simplifie la conception du circuit. Le cas le plus fréquent est un pas fixe de 1, à savoir que le contenu de leur registre est incrémenté/décrémenté de 1 à la demande.
Quelques compteurs ont un pas variable, ce qui sert à compter quelque chose qui varie de manière non-régulière. Par exemple, imaginez un circuit qui compte combien de voitures sont rentrées sur une autoroute par un péage bien précis. Plusieurs voitures peuvent rentrer sur le péage durant la même minute, presque en même temps. Pour cela, il suffit de prendre un compteur à pas variable, qui est incrémenté du nombre de voiture rentrées sur l'autoroute lors de la dernière période de temps. Évidemment, de tels compteurs à pas variables ont une entrée supplémentaire sur laquelle on peut envoyer le pas du compteur.

Les compteurs que nous allons voir encodent leur décompte en binaire normal sur bits, mais il faut savoir que d'autres compteurs utilisent le BCD, d'autre le code Gray, etc. Au passage, le nombre de bits du compteur est appelé la taille du compteur, par analogie avec les registres. La plupart des compteurs comptent de 0 à , avec la taille du compteur. D'autres compteurs ne comptent pas jusque-là : leur limite est plus basse que . Par exemple, certains compteurs ne comptent que jusqu'à 10, 150, etc. Ils sont appelés des compteurs modulo. Prenons un compteur modulo 6, par exemple : il compte de 0 à 5, et est remis immédiatement à zéro quand il atteint 6. Il compte donc comme suit : 0, 1, 2, 3, 4, 5, 0, 1, 2, ...
Outre la valeur de la limite du compteur, il est aussi intéressant de se pencher sur ce qui se passe quand le décompte atteint cette limite. Certains restent bloqués sur le décompte maximale tant qu'on ne les remet pas à zéro "manuellement" : ce sont des compteurs à saturation. D'autres recommencent à compter naturellement à partir de zéro : ce sont des compteurs modulaires.
L'interface d'un compteur/décompteur
[modifier | modifier le wikicode]Les compteurs et décompteurs sont des circuits synchrones et ont donc une entrée d'horloge. Les compteurs les plus simples incrémentent leur contenu à chaque cycle d'horloge, et nous verrons un usage de ce genre de compteur dans le chapitre suivant. Mais la majorité des compteurs n'incrémente le décompte que sur demande. Pour cela, ils disposent d'une entrée Enable, similaire à celle des registres. Le décompte est incrémenté/décrémenté seulement si l'entrée Enable est à 1, mais pas si elle est à 0. L'entrée Enable est séparée de l'entrée d'horloge, le compteur/décompteur est incrémenté seulement si il y a un front sur le signal d'horloge et une entrée Enable à 1.
Sur les compteurs/décompteurs, il y a une entrée qui décide s'il faut compter ou décompter. Typiquement, elle est à 1 s'il faut compter et 0 s'il faut décompter.
Les compteurs ont aussi une entrée Reset qui permet de les remettre à zéro. Il y a parfois une entrée qui permet d'initialiser le compteur à une valeur par défaut, non-nulle. Par exemple, on peut initialiser le décompte à la valeur 5, ou une autre. Pour cela, le compteur dispose de deux entrées : une entrée sur laquelle envoyer le décompte initial, une entrée pour autoriser la réinitialisation. Les entrées en question sont appelées Preload Data et Preload Enable. La seconde entrée est parfois distincte de l'entrée de réinitialisation, pour permettre de réinitialiser le compteur soit à zéro, soit à la valeur voulue.

Le circuit d'un compteur : généralités
[modifier | modifier le wikicode]Un compteur/décompteur est registre amélioré pour le rendre capable de compter/décompter. Tous les compteurs/décompteurs combinent un registre pour mémoriser le nombre, avec des circuits combinatoires pour calculer la prochaine valeur du compteur. Ce circuit combinatoire est le plus souvent, mais pas toujours, un circuit capable de réaliser des additions (compteur), des soustractions (décompteurs), voire les deux (compteur-décompteur). Plus rarement, il s'agit de circuits conçus sur mesure, dans le cas où le pas du compteur est fié une bonne fois pour toutes.

Les compteurs modulo ont une valeur maximale qui est plus faible que la valeur maximale du registre. Ils sont construits à partir d'un compteur normal, couplé à un circuit comparateur qui remet à zéro le registre quand il atteint la valeur maximale. Par exemple, on peut imaginer un compteur modulo 6, ce qui veut dire qu'il compte de 0 à 5. Il est construit à partir d'un compteur 4 bits qui compte de 0 à 15 (donc un compteur modulo 16), mais qui est remis à zéro quand il atteint 6. Il compte donc comme suit : 0, 1, 2, 3, 4, 5, 0, 1, 2, ... Le circuit comparateur vérifie si la valeur maximale 6 est atteinte et met à 1 l'entrée Reset si c'est le cas. Le comparateur est juste un comparateur avec une constante, que vous savez déjà fabriquer à cet endroit du cours.

La valeur maximale d'un compteur modulo peut être configurable. Pour cela, le compteur est associé à un registre de configuration qui mémorise la valeur maximale souhaitée. A chaque cycle d'horloge, la valeur dans le compteur est comparée au registre de configuration. Si elles sont identiques, le compteur est remis à zéro. Le compteur est associé au registre de configuration et à un comparateur qui vérifie que les deux sont égaux. Pour le moment, nous ne savons pas faire de circuits comparateurs, ce qui fait qu'on ne peut pas expliquer ce circuit plus en détail.

Les compteurs synchrones et asynchrones
[modifier | modifier le wikicode]Dans cette section, nous allons créer des compteurs qui incrémentent leur décompte à chaque cycle d'horloge, ou du moins quand leur Enable le permet. A ce propos, dans les schémas qui vont suivre, les entrées Enable ne sont pas représentées. Il est sous-entendu qu'il y a une entrée Enable pour tous les compteurs qui vont suivre. Il existe deux méthodes pour créer de tels compteurs : la première donne ce qu'on appelle des compteurs asynchrones, et l'autre des compteurs synchrones.
Les compteurs asynchrones
[modifier | modifier le wikicode]Pour comprendre comment fonctionne un compteur asynchrone, il faut regarder la séquence des premiers entiers :
- 000 ;
- 001 ;
- 010 ;
- 011 ;
- 100 ;
- 101 ;
- 110 ;
- 111.
Il faut remarquer que le bit de poids faible s'inverse à chaque cycle d'horloge. Pour les colonnes suivantes, le bit s'inverse quand le bit de la colonne précédente passe de 1 à 0, lors d'un front descendant sur la colonne précédente. Maintenant que l'on sait cela, on peut créer un compteur avec des bascules T (elles inversent leur contenu à chaque cycle d'horloge). La première colonne inverse son contenu à chaque cycle, elle correspond donc à une bascule T reliée directement à l'horloge. Les autres colonnes utilisent des bascules T activées sur front descendant.
- Attention, la bascule la plus à gauche stocke le bit de poids faible, pas celui de poids fort. Cela sera pareil dans tous les schémas qui suivront.

Il est aussi possible d'utiliser des bascules D pour créer un compteur comme les deux précédents. En effet, une bascule T simplifiée est identique à une bascule D dont on boucle la sortie /Q sur l'entrée de données. Cette implémentation permet d'ailleurs de réinitialiser le compteur à une valeur non-nulle. Pour cela, l'entrée de chaque bascule D est précédée d'un multiplexeur, qui choisit entre le bit calculé par le compteur et celui présenté sur l'entrée de ré-initialisation. Quand l'entrée Reset est activée, les multiplexeurs connectent les bascules aux bits sur l'entrée de ré-initialisation. Dans le cas contraire, le compteur fonctionne normalement, les multiplexeurs connectant l'entrée de chaque bascule à sa sortie.

Les compteurs synchrones
[modifier | modifier le wikicode]Passons maintenant au compteurs synchrones. Et pour comprendre comment créer un tel compteur, reprenons la séquence d'un compteur :
- 000
- 001
- 010
- 011
- 100
- 101
- 110
- 111
Il faut remarquer que lors d'une incrémentation, un bit s'inverse quand tous les bits des colonnes précédentes valent 1. Pour implanter cela en circuit, on a besoin d'un circuit qui détermine si les bits des colonnes précédentes sont à 1. Il n'est autre qu'un simple ET entre les bits en question. Et au lieu d'utiliser une porte ET à plusieurs entrée pour chaque colonne, il y a moyen d'utiliser des portes plus simples, avec une banale porte ET à deux entrées pour chaque bascule. Le résultat est indiqué ci-dessous.
L’implémentation de circuit avec des bascules D nécessite, pour chaque colonne, un inverseur commandable pour inverser le bit de la bascule si besoin. L'inverseur commandable est, pour rappel, une simple XOR. Il prend en entrée la sortie de la bascule D et la sortie de la porte ET, et envoie son résultat à l'entrée de la bascule D. On peut appliquer la même logique pour un décompteur, ce qui donne un circuit presque identique, si ce n'est que les sorties des bascules doivent être inversées avant d'être envoyée à l'inverseur commandable.

La gestion du débordement des compteurs synchrones/asynchrones
[modifier | modifier le wikicode]Les compteurs précédents ne peuvent pas être réinitialisés, ce qui pose des problèmes, notamment pour implémenter des compteurs modulo. Pour cela, il faut que les bascules du compteur aient une entrée de réinitialisation Reset, qui les force à se remettre à zéro. Il suffit alors de connecter ensemble les entrées Reset des bascules à l'entrée Reset du compteur.

Implémenter un compteur modulo demande d'ajouter un comparateur qui détecte quand la valeur maximale est atteinte, afin de commander l'entrée de réinitialisation. Un tel circuit est juste un comparateur avec une constante, que vous savez déjà fabriquer à cet endroit du cours.

Il peut être utile de prévenir quand un compteur a débordé, ce qui est utile pour fabriquer des circuits diviseurs de fréquence et des timers (qu'on verra dans le prochain chapitre). Pour cela, on ajoute une sortie de débordement au compteur, qui est mise à 1 quand le compteur déborde. Pour les compteurs modulo, la sortie n'est autre que la sortie du comparateur. Pour les compteurs non-modulo, un débordement se traduit par un front descendant sur la sortie de la dernière bascule, celle qui contient le bit de poids fort.
Les compteurs en cascade
[modifier | modifier le wikicode]Il est possible de concevoir des compteurs à partir de compteurs plus petits, mis en cascade. Par exemple, en créant un compteur 16 bits à partir de compteurs 4 bits, enchainés l'un à la suite de l'autre. Les compteurs de 4 bits peuvent même être des compteurs asynchrones, ce qui donne un compteur hybride entre synchrone et asynchrone. Les compteurs sont mis en cascade de la manière suivante : leur sortie de débordement est connectée sur l'entrée Enable du compteur suivant, celle qui déclenche l'incrémentation du compteur. La sortie de débordement est notée RCO dans les schéma qui suivent, nous verrons pourquoi dans le prochaine paragraphe.

Les compteurs mis en cascade ont les mêmes entrées et sorties que les compteurs normaux, avec cependant une entrée en plus, indiquant que le compteur a atteint sa valeur maximale, appelée sortie Ripple carry out (RCO). La sortie en question est calculée avec une porte ET entre tous les bits du compteur pour un compteur synchrone. Si tous les bits du compteurs sont à 1, cela signifie que le compteur suivant doit être incrémenté au prochain cycle d'horloge.

Les compteurs basés sur des registres à décalage
[modifier | modifier le wikicode]Il existe des compteurs basés sur un registre à décalage. Pour simplifier les explications, nous allons les classer suivant le type de registre à décalage utilisé. Pour rappel, un registre à décalage dispose d'une entrée et d'une sortie. L'entrée peut être de deux types : soit une entrée série qui prend 1 bit, soit une entrée parallèle qui prend un nombre. Il en est de même pour la sortie, qui peut être série ou parallèle. En combinant les deux, cela donne quatre possibilités qui portent les noms de registres à décalage PIPO, PISO, SIPO et SISO (P pour parallèle, S pour série, I pourInput, O pour Output).
| Entrée parallèle | Entrée série | |
|---|---|---|
| Sortie parallèle | (registre simple) | SIPO |
| Sortie série | PISO | SISO |
Les registres PIPO ne sont pas des registres à décalage, on les omets dans ce qui suit. Les trois types restants de registres à décalage permettent de créer des compteurs. Les compteurs en question ne portent pas de noms proprement dit, à l'exception de certains compteurs basés sur un registre SISO appelés des compteurs en anneau, et encore cette dénomination est légèrement impropre.
À l'exception de certains compteurs one-hot qui seront vu juste après, ces compteurs sont des compteurs à rétroaction. Un terme bien barbare pour dire que l'on boucle leur sortie sur leur entrée, parfois en insérant un circuit combinatoire entre les deux. Ils sont conçus pour dérouler une suite de nombres bien précise, prédéterminée lors de la création du compteur. En conséquence, on peut les réinitialiser, mais pas insérer une valeur dans le compteur. Par exemple, on peut créer un compteur qui sort la suite de nombres 4,7,6,1,0,3,2,5 en boucle, ce qui peut servir pour fabriquer des suites de nombres pseudo-aléatoires, par exemple.
Un exemple d'utilisation est celui de l'Intel 8008, le tout premier microprocesseur 8 bits commercialisé, où ce genre de compteurs étaient utilisés pour le pointeur de pile, pour économiser quelques portes logiques. Ces compteurs implémentaient la séquence suivante : 000, 001, 010, 101, 011, 111, 110, 100. Pour les connaisseurs qui veulent en savoir plus, voici un article de blog sur le sujet : Analyzing the vintage 8008 processor from die photos: its unusual counters.
Les compteurs en anneau et de Johnson (SISO)
[modifier | modifier le wikicode]Les compteurs basés sur des registres à décalage SISO sont aussi appelés des compteurs en anneau. Ils sont appelés ainsi car le bit sortant du registre est renvoyé sur son entrée. Précisément, le bit entrant dans le registre à décalage est calculé à partir du bit sortant. Et il n'y a pas 36 façons de faire ce calcul : soit le bit sortant est laissé tel quel, soit il est inversé. La première possibilité, où le bit entrant est égal au bit sortant, donne un compteur one-hot. La seconde possibilité, où le bit sortant est inversé, donne un compteur de Johnson. Les deux sont très différents, et ne fonctionnent pas du tout pareil.
Les compteurs en anneau : les compteurs one-hot
[modifier | modifier le wikicode]Les compteurs one-hot sont appelés ainsi, car ils permettent de compter dans une représentation des nombres appelée la représentation one-hot. Pour rappel, dans une telle représentation, un seul bit est à 1 pendant que les autres sont à 0. Les entiers sont codés de la manière suivante : le nombre N est encodé en mettant le énième bit à 1, avec la condition que l'on commence à compteur à partir de zéro. Il est important de remarquer que dans cette représentation, le zéro est n'est PAS codé en mettant tous les bits à 0, la valeur 0000...0000 est une valeur interdite. A la place, le zéro est codé en mettant le bit de poids faible à 1. Pour N bits, on peut encoder seulement N valeurs, dont le zéro.
| Décimal | Binaire | One-hot |
|---|---|---|
| 0 | 000 | 00000001 |
| 1 | 001 | 00000010 |
| 2 | 010 | 00000100 |
| 3 | 011 | 00001000 |
| 4 | 100 | 00010000 |
| 5 | 101 | 00100000 |
| 6 | 110 | 01000000 |
| 7 | 111 | 10000000 |
Un compteur en représentation one-hot contient un nombre codé de cette manière, qui est incrémenté ou décrémenté si besoin. Pour donner un exemple, la séquence d'un compteur en anneau de 4 bits est :
- 0001 (0) ;
- 0010 (1) ;
- 0100 (2) ;
- 1000 (3) .
Un compteur one-hot basique est composé d'un registre à décalage SISO dont on boucle la sortie sur son entrée. En faisant cela, on garantit que le registre revient à zéro lors d'un débordement, zéro étant codé avec un 1 dans le bit de poids faible. Au passage, si vous ne mettez que des 0 dans un compteur en anneau, il restera bloqué pour toujours : décaler une suite de 0 donnera la même suite de 0. Initialiser un compteur one-hot demande donc quelques subtilités qu'on détaillera plus bas.

Faire des comparaisons avec ce type de compteur est très simple : le compteur contient la valeur N si le énième bit est à 1. Pas besoin d'utiliser de circuit comparateur, juste de lire un bit. Par contre, ce compteur n'est pas très économe en bascules. Imaginons que l'on veut un compteur qui compte jusqu'à une valeur N arbitraire : un compteur binaire normal utilisera environ bascules, alors qu'un compteur one-hot demande N bascules. Mais si N est assez petit, l'économie de bascules est assez faible, alors que l'économie de circuits comparateurs/incrémenteurs l'est beaucoup plus.
Il y a peu d'applications qui utilisent des compteurs en anneau. Ils étaient autrefois utilisés dans les tous premiers ordinateurs, notamment ceux qui géraient une représentation des nombres spécifique appelée la Bi-quinary coded decimal. Ils étaient aussi utilisés comme diviseurs de fréquence, comme on le verra dans le chapitre suivant. De nos jours, de tels compteurs sont utilisés dans les séquenceurs de processeurs, mais aussi dans les séquenceurs de certains périphériques, ou dans les circuits séquentiels simples qui se résument à des machines à états. Ils sont alors utilisés car très rapides, parfaitement adaptés au stockage de petites valeur, et surtout : ils n'ont pas besoin de circuit comparateur pour connaitre la valeur stockée dedans. Nous n'allons pas rentrer dans le détail de leurs utilisations car nous en reparlerons dans la suite du cours.
Les compteurs de Johnson : les compteurs unaires
[modifier | modifier le wikicode]Sur les compteurs de Johnson, le bit sortant est inversé avant d'être bouclé sur l'entrée.

La séquence d'un compteur de Johnson de 4 bits est :
- 1000 ;
- 1100 ;
- 1110 ;
- 1111 ;
- 0111 ;
- 0011 ;
- 0001 ;
- 0000.
Vous remarquerez peut-être que lorsque l'on passe d'une valeur à la suivante, seul un bit change d'état. Sachant cela, vous ferez peut-être le parallèle avec le code Gray vu dans les tout premiers chapitres, mais cela n'a rien à voir. Les valeurs d'un compteur Johnson ne suivent pas un code Gray classique, ni même une variante de celui-ci. Les compteurs qui comptent en code Gray sont foncièrement différents des compteurs Johnson.
Une application des compteurs de Johnson, assez surprenante, est la fabrication d'un signal sinusoïdal. En combinant un compteur de Johnson, quelques résistances, et des circuits annexes, on peut facilement fabriquer un circuit qui émet un signal presque sinusoïdal (avec un effet d'escalier pas négligeable, mais bref). Les oscillateurs sinusoïdaux numériques les plus simples qui soient sont conçus ainsi. Quant aux compteurs en anneau, ils sont utilisés en lieu et place des compteurs normaux dans des circuits qui portent le nom de séquenceurs ou de machines à états, afin d'économiser quelques circuits. Mais nous en reparlerons dans le chapitre sur l'unité du contrôle du processeur.
Les registres à décalage à rétroaction de type SIPO/PISO
[modifier | modifier le wikicode]D'autres compteurs sont fabriqués en prenant un registre à décalage SIPO ou PISO dont on boucle l'entrée sur la sortie. Pour être plus précis, il y a très souvent un circuit combinatoire qui s'intercale entre la sortie et l'entrée. Son rôle est de calculer ce qu'il faut mettre sur l'entrée, en fonction de la sortie.
Étudions en premier lieu le cas des registres à décalage à rétroaction linéaire. Le terme anglais pour de tels registres est Linear Feedback Shift Register, ce qui s’abrège en LFSR. Nous utiliserons cette abréviation dans ce qui suit pour simplifier grandement l'écriture. Les LFSR sont appelés ainsi pour plusieurs raisons. Déjà, registre à décalage implique qu'ils sont fabriqués avec un registre à décalage, et plus précisément des registres à décalage SIPO. A rétroaction indique que l'on boucle la sortie sur l'entrée. Le terme combinaison linéaire demande quelques explications.
Pour simplifier, cela veut dire qu'on multiplie chaque bit par 0 ou 1, avant d'additionner le tout. Dans ce calcul, on ne garde qu'un seul bit du résultat, vu que l'entrée du registre à décalage ne fait qu'un bit. Par simplicité, on ne garde que le bit de poids faible. Or, il s'avère que cela simplifie grandement les calculs, car cela permet de remplacer les additions par une simple opération XOR.
Le résultat est ce que l'on appelle un LFSR de Fibonacci, ou encore un LFSR classique, qui celui qui colle le mieux avec la définition.

Les registres à décalages à rétroaction affine sont identique aux précédents à une différence près : le bit calculé est inversé avant d'être inséré dans le registre. Un tel circuit est donc composé de portes NXOR, comparé à son comparse linéaire, composé à partir de portes XOR. Petite remarque : si je prends un registre à rétroaction linéaire et un registre à rétroaction affine avec les mêmes coefficients sur les mêmes bits, le résultat du premier sera égal à l'inverse de l'autre.
Les registres à décalage à rétroaction de Gallois sont un peu l'inverse des LFSR vus juste avant. Au lieu d'utiliser un registre à décalage SIPO, ils utilisent un registre à décalage PISO. Pour faire la différence, nous appellerons ces derniers les LFSR PISO, et les premiers LFSR SIPO. Avec les LFSR PISO, on prend le bit sortant et on en déduit plusieurs bits à partir d'un circuit combinatoire, qui sont chacun insérés dans le registre à décalage à un endroit bien précis. Bien sûr, la fonction qui calcule des différents bits à partir du bit d'entrée conserve les mêmes propriétés que celle utilisée pour les LFSR : elle se calcule avec uniquement des portes XOR, ou NXOR pour leur variante affine.
Leur avantage est qu'ils sont plus rapides, car il n'y a qu'une seule porte logique entre la sortie et une entrée du registre à décalage, contre potentiellement plusieurs avec les LFSR SIPO. Notons que tout comme les LFSR qui ne peuvent pas mémoriser un 0, de tels registres à décalage à rétroaction ne peuvent pas avoir la valeur maximale stockable dans le registre. Cette valeur gèle le registre à cette valeur, dans le sens où le résultat au cycle suivant sera identique. Mais cela ne pose pas de problèmes pour l'initialisation du compteur.

Il existe enfin des compteursqui ne sont pas des LFSR, même en incluant les compteurs de Gallois et autres. Ce sont des compteurs basés sur des registres à décalage où le circuit combinatoire inséré entre l'entrée et la sortie n'est pas basé sur des portes XOR ou NXOR. Ils sont cependant plus compliqués à concevoir, mais ils ont beaucoup d'avantages.
La période d'un compteur à rétroaction
[modifier | modifier le wikicode]Un compteur à rétroaction est déterministe : pour le même résultat en entrée, il donnera toujours le même résultat en sortie. De plus, il ne peut contenir qu'un nombre fini de valeurs, ce qui fait qu'il finira par repasser par une valeur qu'il aura déjà parcourue. Une fois qu'il repassera par cette valeur, son fonctionnement se reproduira à l'identique comparé à son passage antérieur, il bouclera. Il parcourt un nombre N de valeurs à chaque cycle, ce nombre étant appelé la période du compteur.
Le cas le plus simple est celui des compteurs en anneau, suivi par les compteurs Johnson. Un compteur en anneau de N bits peut prendre N valeurs différentes, qui ont toutes un seul bit à 1. À l'opposé, un compteur Johnson peut prendre deux fois plus de valeurs. Pour nous en rendre compte, comparons la séquence de nombre déroulé par chaque compteur. Pour 5 bits, les séquences sont illustrées ci-dessous, dans les deux animations.


La période des registres à décalage à rétroaction linéaire dépend fortement de la fonction utilisée pour calculer le bit de sortie. Dans le meilleur des cas, le registre à décalage à rétroaction passera par toutes les valeurs que le registre peut prendre, sauf une : suivant le registre, le zéro ou sa valeur maximale sont interdits. Si un registre à rétroaction linéaire passe par zéro, il y reste bloqué définitivement. La raison à cela est simple : un XOR sur des zéros donnera toujours 0. Le même raisonnement peut être tenu pour les registres à rétroaction affine, sauf que cette fois-ci, c'est la valeur maximale stockable dans le registre qui est fautive. Tout le chalenge consiste donc à trouver quels sont les registres à rétroaction dont la période est maximale : ceux dont la période vaut . Qu'on se rassure, quelle que soit la longueur du registre, il en existe au moins un : cela se prouve mathématiquement.
L'initialisation d'un compteur à rétroaction
[modifier | modifier le wikicode]Les compteurs à rétroaction ne peuvent pas être initialisés à une valeur arbitraire, en raison de la présence d'une valeur interdite qui bloque le compteur, sans compter que les débordements d'entiers y sont impossibles. Pour ce qui est de l'initialisation, tous les compteurs basés sur un registre à décalage ne sont pas égaux : soit le compteur peut être initialisé avec zéro sans que cela pose problème, soit ce n'est pas le cas.
Le premier cas est celui où le compteur peut être initialisé avec zéro sans que cela ne pose problème. C'est le cas sur les compteurs de Johnson, mais aussi sur les registres à décalage à rétroaction non-linéaire. Sur de tels compteurs, la réinitialisation se fait comme pour n'importe quel registre/compteur. A savoir que les entrées de reset des bascules sont toutes connectées ensemble, au même signal de reset.

Le second cas est celuid es compteurs en anneau et des LFSR non-affine. Lors de la réinitialisation, il faut que toutes les bascules soient réinitialisées à 0, sauf une qui est mise à 1. La bascule en question doit disposer d'une entrée S (Set) qui met la bascule à 1 quand elle est activée. Cela garantit que le registre est réinitialisé avec un zéro codé en one-hot.

Une autre solution est de mettre un multiplexeur juste avant l'entrée du registre à décalage. Cette solution marché bien dans le sens où elle permet d'initialiser le registre avec une valeur arbitraire, qui est insérée dans le registre en plusieurs cycles. Pour les LFSR, le multiplexeur est connecté soit au bit calculé par les portes XOR, soit par une entrée servant uniquement de l'initialisation.

Les compteurs en code Gray
[modifier | modifier le wikicode]Il existe des compteurs qui comptent en code Gray. Pour rappel, le code Gray permet de coder des nombres d'une manière un peu différente du binaire normal. Son avantage principal est que lorsqu'on incrémente ou décrémente un nombre, seul un bit change ! Ils ont beaucoup d'avantages, qui sont tous liés à cette propriété.
L'absence d'états transitoires douteux
[modifier | modifier le wikicode]Le premier l'absence d'état transitoires douteux. En binaire normal, lorsqu'on passe d'un nombre au suivant, plusieurs bits changent. La moyenne est d'environ deux bits, avec beaucoup de transitions de 1 bit, mais aussi quelques-unes qui en changent beaucoup plus. Le problème est que tous les bits modifiés ne le sont pas en même temps. Typiquement, les bits de poids faibles sont modifiés avant les autres.
Évidemment, à la fin du calcul, on obtient le résultat final, correct. Mais pendant le temps de calcul, le compteur peut se retrouver dans un état transitoire, où certains bits ont été modifiés mais pas les autres. Et c'est parfois un problème si le contenu de ce compteur est relié à des circuits assez rapides, qui peuvent, mais ne doivent pas voir cet état transitoire sous peine de dysfonctionner. L'usage de compteurs en code Gray permet d'éviter ce problème : vu que seul un bit est modifié lors d'une incrémentation/décrémentation, les états transitoires n'existent tout simplement pas.
Un exemple typique, évoqué dans les chapitres précédents, est l'échange d'informations entre deux domaines d'horloge. Pour rappel, il arrive que deux portions d'un circuit imprimé aillent à des fréquences différences : on dit que le circuit à plusieurs domaines d'horloge. Mais il faut échanger des informations entre ces deux portions, et divers problèmes surviennent alors. Un domaine d'horloge sera plus rapide que l'autre, et il pourra voir les états transitoires invisible pour le circuit. Et par voir, on veut dire qu'il les prendra pour des états valides, et cela fera dysfonctionner le circuit. Pour éviter cela, diverses techniques de croisement de domaines d'horloge existent. Et les compteurs Gray en font partie : si un domaine d'horloge utilise la valeur d'un compteur de l'autre, mieux vaut que ce compteur soit un compteur Gray. Et cette situation est assez fréquente !
La consommation énergétique du compteur Gray
[modifier | modifier le wikicode]Un autre point est que la consommation d'énergie de ces compteurs est bien plus réduite qu'avec un compteur normal. Rappelons que pour fonctionner, les circuits électroniques consomment un peu d'électricité. Un compteur ne fait pas exception. Et la majeure partie de cette consommation sert à changer l'état des portes logiques. Faire passer un bit de 0 à 1 ou de 1 à 0 consomme beaucoup plus d'énergie que de laisser un bit inchangé. Ce qui fait que quand un compteur est incrémenté ou décrémenté, cela consomme un peu d'énergie électrique. Et les conséquences de cela sont nombreuses.
Premièrement, plus on change de bits, plus la consommation est forte. Or, comme on l'a dit plus haut, la moyenne pour un compteur binaire normal est de 2 bits changés par incrémentation/décrémentation, contre un seul pour un compteur Gray. Un compteur Gray consomme donc deux fois moins d'énergie. En soi, cela n'est pas grand-chose, un compteur consomme généralement peu. Mais l'avantage est que cela va avoir des effets en cascade sur les circuits qui suivent ce compteur. Si l'entrée de ces circuits ne change que d'un seul bit, alors leur état changera moins que si c'était deux bits. Les circuits qui suivent vont donc moins consommer.
Un autre avantage en matière de consommation énergétique est lié justement au point précédent, sur les transitions d'état douteux. Les circuits connectés au compteur vont voir ces transitions d'état douteux : ils vont réagir à ces entrées de transition et modifier leur état interne en réaction. Bien sur, l'état final correct fera de même, ce qui effacera ces états transitoires intermédiaires. Mais chaque état intermédiaire transitoire correspondra à un changement d'état, donc à une consommation d'énergie. En supprimant ces états transitoires, on réduit fortement la consommation d'énergie du circuit. Cela vaut pour le compteur Gray lui-même, mais aussi sur tous les circuits qui ont ce compteur comme entrée !