Fonctionnement d'un ordinateur/Les circuits compteurs et décompteurs

Un livre de Wikilivres.
Aller à la navigation Aller à la recherche
Illustration du fonctionnement d'un compteur modulaire binaire de 4 bits, avec un pas de compteur de 1 (le contenu est augmenté de 1 à chaque mise à jour).

Les compteurs/décompteurs sont des circuits électroniques qui mémorisent un nombre qu'ils mettent à jour régulièrement. Cette mise à jour augmente ou diminue le compteur d'une quantité fixe, 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 combinatoire. D'autres permettent un pas variable, et ont donc une entrée supplémentaire sur laquelle on peut envoyer le pas du compteur.

Suivant la valeur du pas, on fait la différence entre les compteurs d'un côté et les décompteurs de l'autre. Comme leur nom l'indique, les compteurs comptent alors que les décompteurs décomptent. Les compteurs augmentent le contenu du compteur à chaque mise à jour, alors que les décompteurs le diminuent. Dit autrement, le pas d'un compteur est positif, alors que le pas d'un décompteur est négatif. Les compteurs-décompteurs peuvent faire les deux, suivant ce qu'on leur demande.

Suivant le compteur, la représentation du nombre mémorisé change : certains utilisent le binaire traditionnel, d'autres le BCD, d'autre le code Gray, etc. Mais tous les compteurs que nous allons voir seront des compteurs/décompteurs binaires, à savoir que les nombres qu'ils utilisent sont codés sur bits. Au passage, le nombre de bits du compteur est appelé la taille du compteur, par analogie avec les registres.

Vu que la taille d'un compteur est limitée, il cesse de compter au-delà d'une valeur maximale. La plupart des compteurs comptent de 0 à , avec la taille du compteur. Ils sont appelés des compteurs modulo. 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.

Outre la valeur de la limite du compteur, il est aussi intéressant de se pencher sur ce qui se passe quand le compteur atteint cette limite. Certains restent bloqués sur cette valeur 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[modifier | modifier le wikicode]

Compteurs et décompteurs sont presque tous des circuits synchrones, à savoir cadencés par une horloge. Du moins, c'est le cas des compteurs/décompteurs que nous allons voir dans ce chapitre, par souci de simplicité. Un compteur/décompteur est donc relié à une entrée d'horloge.

De plus, certains compteurs ont une entrée Enable qui active/désactive le comptage. Le compteur s'incrémente/décrémente seulement si l'entrée Enable est à 1, mais ne fait rien si elle est à 0. Les compteurs les plus simples sont incrémentés/décrémentés à chaque cycle d'horloge et n'ont pas d'entrée Enable, mais les compteurs plus complexes en ont une. Ce faisant, le compteur/décompteur est incrémenté seulement si deux conditions sont réunies : un front montant sur le signal d'horloge, et une entrée Enable à 1. Dans les schémas qui vont suivre, nous ferons mention soit au signal d'horloge, soit à l'entrée Enable. Si on fait référence à l'entrée Enable, il est sous-entendu que les bascules du registre sont cadencées par une horloge, qui leur dit quand s'actualiser.

En outre, les compteurs ont souvent une entrée Reset qui permet de les remettre à zéro.

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.

Compteur 4 Bits.
Compteur 4 Bits avec entrée Reset.
Compteur 4 Bits avec entrée pour décider s'il faut compter ou décompter.

Le circuit d'un compteur : généralités[modifier | modifier le wikicode]

Un compteur/décompteur peut être vu comme une sorte de registre (il peuvent stocker un nombre), mais qu'on aurait amélioré de manière à le rendre capable de compter/décompter. Tous les compteurs/décompteurs utilisent un registre pour mémoriser le nombre, ainsi que 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 toute.

Comme tout registre, un compteur/décompteur peut être initialisé avec la valeur de notre choix. Pour cela, ils possèdent une entrée d'initialisation sur laquelle on peut placer le nombre initial, couplée à une entrée Reset qui indique si le compteur doit être réinitialisé ou non. Certains compteurs/décompteurs spécifiques n'ont pas d'entrée d'initialisation, mais seulement une entrée de reset, mais il s'agit là d'utilisations assez particulières où le compteur ne peut qu'être réinitialisé à une valeur par défaut. Pour les compteurs/décompteurs, il faut aussi rajouter une entrée qui précise s'il faut compter ou décompter.

Fonctionnement d'un compteur (décompteur), schématique

Comme dit plus haut, certains compteurs ont une valeur maximale qui est plus faible que la valeur maximale du registre. Par exemple, on peut imaginer un compteur qui compte de 0 à 9 : celui-ci est construit à partir d'un registre de 4 bits qui peut donc compter de 0 à 15 ! Ces compteurs sont construits à partir d'un compteur modulo, auquel on rajoute un circuit combinatoire. Ce dernier détecte le dépassement de la valeur maximale et remet à zéro le registre quand c'est nécessaire, via l'entrée de Remise à zéro (entrée Reset).

Compteur modulo N.

L'incrémenteur/décrémenteur[modifier | modifier le wikicode]

Certains compteurs, aussi appelés incrémenteurs comptent de un en un. Les décompteurs analogues sont appelés des décrementeurs. Nous allons voir comment créer ceux-ci dans ce qui va suivre. Il faut savoir qu'il existe deux méthodes pour créer des incrémenteurs/décrémenteurs. La première donne ce qu'on appelle des incrémenteurs asynchrones, et l'autre des incrémenteurs synchrones. Nous allons commencer par voir comment fabriquer un incrémenteur synchrone, avant de passer aux incrémenteurs asynchrones.

L'incrémenteur asynchrone[modifier | modifier le wikicode]

Pour fabriquer un incrémenteur synchrone, la première méthode, il suffit de regarder la séquence des premiers entiers, puis de prendre des paires de colonnes adjacentes :

  • 000 ;
  • 001 ;
  • 010 ;
  • 011 ;
  • 100 ;
  • 101 ;
  • 110 ;
  • 111.

On remarque que le bit sur une colonne change quand le bit de la colonne précédente passe de 1 à 0, en clair, lorsqu'on a un front descendant sur la colonne précédente. Pour la colonne la plus à droite (celle des bits de poids faible), on remarque que celle-ci inverse son contenu à chaque cycle d'horloge. Maintenant que l'on sait cela, on peut facilement créer un compteur avec quelques bascules. Et plus précisément, il est utile d'utiliser des bascules T, éventuellement des bascules T simplifiées. Pour rappel, ces bascules inversent leur contenu à chaque cycle d'horloge. Par simplicité, nous allons utiliser des bascules avec une sortie qui fournit l'inverse du bit stocké.

La première colonne inverse son contenu à chaque cycle, elle correspond donc à une bascule T simplifiée reliée directement à l'horloge. Les autres colonnes s'inversent quand survient un front descendant sur la colonne précédente. le circuit qui correspond est donc celui-ci, avec des bascules T activées sur front descendant :

Compteur asynchrone de 3 bits, basé sur des bascules T simplifiées activées sur front descendant.

Il est aussi possible d'utiliser des bascules T actives sur front montant. En effet, notons qu'un front descendant sur la sortie Q correspond à un front montant sur la sortie /Q. En clair, il suffit de relier la sortie /Q d'une colonne sur l'entrée d'horloge de la suivante. Le circuit est donc le suivant :

Compteur asynchrone de 3 bits, basé sur des bascules T simplifiées activées sur front montant.

Il est aussi possible d'utiliser des bascules JK pour créer un compteur comme les deux précédents. En effet, une bascule T simplifiée est identique à une bascule JK dont les deux entrées J et K sont à 1.

Compteur asynchrone de 3 bits, basé sur des bascules JK activées sur front montant.

Le circuit précédent a cependant un problème : il ne peut pas être réinitialisé. Pour que cela soit possible, il faut que les bascules du compteur aient une entrée de réinitialisation Reset, qui les force à se remettre à zéro, alors on peut l'utiliser. Il suffit d'ajouter une entrée Reset au compteur, et de la connecter aux entrées Reset des bascules. Ce faisant, le compteur peut être remis à zéro sur simple demande.

Compteur réinitialisable.

Cette réinitialisation est utile pour créer des compteurs modulo. Il suffit de créer un circuit qui vérifie si la valeur maximale du comparateur est atteinte et qui met à 1 l'entrée Reset si c'est le cas. Un exemple est illustré ci-dessous.

Compteur modulo 10.

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.

Compteur asynchrone, sans initialisation

Cette implémentation peut être modifiée pour facilement réinitialiser le compteur à une valeur non-nulle. Pour cela, il faut ajouter une entrée au compteur, sur laquelle on présente la valeur d’initialisation. Chaque bit de cette entrée est reliée à un multiplexeur, qui choisir quel bit mémoriser dans la bascule : celui fournit par la mise à jour du compteur, ou celui présenté sur l'entrée d'initialisation. On obtient le circuit décrit dans le schéma qui suit. Quand l'entrée Reset est activée, les multiplexeurs connectent les bascules aux bits sur l'entrée d'initialisation. Dans le cas contraire, le compteur fonctionne normalement, les multiplexeurs connectant l'entrée de chaque bascule à sa sortie.

Compteur asynchrone, avec initialisation.

Le décrémenteur asynchrone[modifier | modifier le wikicode]

Un décrémenteur est strictement identique à un incrémenteur auquel on a inversé tous les bits. On peut donc réutiliser le compteur du dessus, à part que les sorties du compteurs sont reliées aux sorties Q des bascules.


Décompteur asynchrone de 3 bits, basé sur des bascules T simplifiées activées sur front descendant.

L'incrémenteur/décrémenteur synchrone[modifier | modifier le wikicode]

Passons maintenant à l'incrémenteur synchrone. Pour le fabriquer, on repart de la séquence des premiers entiers. Dans ce qui va suivre, nous allons créer un circuit qui compte de 1 en 1, sans utiliser d'additionneur. Pour comprendre comment créer un tel compteur, nous allons reprendre la séquence d'un compteur, déjà vue dans le premier extrait :

  • 000
  • 001
  • 010
  • 011
  • 100
  • 101
  • 110
  • 111

On peut remarquer quelque chose dans ce tableau : peu importe la colonne, un bit s'inversera au prochain cycle d’horloge quand tous les bits des colonnes précédentes valent 1. Et c'est vrai quel que soit la taille du compteur ou sa valeur ! Ainsi, prenons le cas où le compteur vaut 110111 :

  • les deux premiers 1 sont respectivement précédés par la séquence 10111 et 0111 : vu qu'il y a un zéro dans ces séquences, ils ne s'inverseront pas au cycle suivant ;
  • le bit qui vaut zéro est précédé de la séquence de bit 111 : il s'inversera au cycle suivant ;
  • le troisième 1 en partant de la gauche est précédé de la séquence de bits 11 : il s'inversera aussi ;
  • même raisonnement pour le quatrième 1 en partant de la gauche ;
  • 1 le plus à droite correspond au bit de poids faible, qui s'inverse tous les cycles.

Pour résumer, un bit s'inverse (à la prochaine mise à jour) quand tous les bits des colonnes précédentes valent 1. Pour implanter cela en circuit, on a besoin de deux circuits par bascules : un qui détermine si les bits des colonnes précédentes sont à 1, et un autre qui inverse le bit de la bascule. Le circuit qui détermine si tous les bits précédents sont à 1 est un simple ET entre les bits en question. L'autre circuit prend en entrée le contenu de la bascule et un bit qui indique s'il faut inverser ou pas. En écrivant sa table de vérité, on s’aperçoit qu'il s'agit d'un simple XOR.

Compteur synchrone à incrémenteur

On peut appliquer la même logique pour un décrémenteur. Avec ce circuit, un bit s'inverse lorsque tous les bits précédents sont à zéro. En utilisant le même raisonnement que celui utilisé pour concevoir un incrémenteur, on obtient un circuit presque identique, si ce n'est que les sorties des bascules doivent être inversées avant d'être envoyée à la porte XOR qui suit.

Les compteurs basés sur des registres à décalage[modifier | modifier le wikicode]

Il existe des compteurs qui sont basés sur un registre à décalage modifiés. Ils regroupent les compteurs en anneau, les compteurs de Johnson et les registres à décalage à rétroaction linéaire. Les plus connus sont basés sur des registres à décalage avec une entrée série, à savoir qu'ils ont une entrée d'un seul bit. Ils peuvent donc insérer un bit dans le registre, à chaque cycle d’horloge. Le bit inséré est calculé soit en fonction du contenu du registre, soit en fonction du bit sortant du registre.

Les compteurs en anneau[modifier | modifier le wikicode]

Les compteurs en anneau sont des registres à décalage dont le bit sortant est renvoyé sur l'entrée. Naturellement, il existe une version qui peut être remise à zéro.

Compteur en anneau de 4 bits
Compteur en anneau de 5 bits.

Avec n bits, ce registre peut prendre N valeurs différentes, qui ont toutes un seul bit à 1. La séquence d'un compteur en anneau de 4 bits est illustrée ci-dessous. Elle donne ceci : 1000, 0100, 0010, 0001.

Évolution du contenu d'un compteur en anneau.

Les compteurs de Johnson[modifier | modifier le wikicode]

Compteur de Johnson de 4 bits.

Sur les compteurs de Johnson, le bit sortant est inversé avant d'être bouclé sur l'entrée. Ce compteur parcours deux fois plus de valeurs différentes, comparé à un compteur en anneau. La séquence d'un tel compteur est :

  • 1000 ;
  • 1100 ;
  • 1110 ;
  • 1111 ;
  • 0111 ;
  • 0011 ;
  • 0001 ;
  • 0000.
Compteur de Johnson de 4 bits

Les registres à décalage à rétroaction linéaire[modifier | modifier le wikicode]

Sur les registres à décalage à rétroaction linéaire de Fibonacci, le bit d'entrée est calculé en fonction du contenu du registre par un circuit combinatoire. La fonction mathématique qui calcule le bit en entrée est assez spéciale. Dans le cas le plus simple, on dit qu'elle est linéaire, ce qui veut dire que le bit de sortie se calcule à partir en multipliant les bits d'entrée par 0 ou 1, et en additionnant le tout. En clair, ce bit de sortie se calcule par une formule du style : :

, où on ne garde que le bit de poids faible du résultat.

Penchons-nous un peu sur cette addition qui ne garde que le bit de poids faible : je ne sais pas si vous avez remarqué, mais il s'agit ni plus ni moins que d'un calcul de parité paire. En effet, si on additionne N bits, le bit de poids faible vaut zéro pour un nombre pair, et 1 pour un nombre impair. Le circuit combinatoire chargé de calculer le bit de résultat est donc un circuit qui calcule la parité de la somme des bits choisis. Pour cela, il suffit d'effectuer une série de XOR entre tous les bits à additionner.

Registre à décalage à rétroaction de Fibonnaci.

Il existe une variante de ce genre de registre, qui modifie légèrement son fonctionnement. Il s'agit des registres à décalages à rétroaction affine. Avec ces registres, la fonction qui calcule le bit de résultat n'est pas linéaire, mais affine. En clair, ce bit de sortie se calcule par une formule du style :

Notez le + 1 à la fin de la formule : c'est la seule différence. Avec ce genre de registre, le bit de résultat est donc calculé en faisant le calcul d'un bit d'imparité de certains (ou de la totalité) des bits du 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.

Exemple avec un registre à rétroaction linéaire de 4 bits.

Les registres à décalage à rétroaction de Gallois sont un peu l'inverse des registres à décalages à rétroaction de Fibonacci vus juste avant. Dans ces derniers, on prenait plusieurs bits du registre à décalage pour en déduire un seul bit. Avec les registres à décalage à rétroaction de Gallois, c'est l'inverse : 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 registres à décalages à rétroaction linéaire : elle est affine ou linéaire, et se calcule avec uniquement des portes XOR pour les fonctions linéaires, ou NXOR pour les fonctions affines.

Registre à décalage à rétroaction de Galois.