4. ALU

Dans cette section, nous continuons notre exploration de comment les portes logiques, selon leur assemblage, fournissent les fonctionnalités de base des ordinateurs. En particulier, nous nous intéressons à comment faire effectuer plusieurs opérations à un ordinateur via ce qui s’appelle une unité arithmétique et logique, ou simplement une ALU.

Dans la section précédente, nous avons vu comment créer, via un assemblage de portes logiques, un circuit qui réalise l’addition de deux nombres de 4 bits. Ce circuit était fixe : avec les deux nombres d’entrées, il réalisait toujours une addition et ne servait ainsi qu’à ça.

Les ordinateurs ont la propriété d’être programmables : ils savent effectuer plusieurs opérations, et c’est la manière dont ils sont programmés qui va déterminer l’opération qu’ils effectuent. C’est aussi vrai pour des machines plus simples ; une calculatrice de poche, par exemple, pourra effectuer au moins les quatre opérations de base : addition, soustraction, multiplication et division.

Le composant qui nous permettra de sélectionner une opération ou une autre s’appelle « unité arithmétique et logique », communément appelé simplement « ALU » (de l’anglais arithmetic logic unit). Avant d’inspecter une ALU, nous avons besoin de comprendre comment on peut sélectionner une opération ou une autre avec des circuits logiques.

4.1. Sélection de l’opération

Comment créer un circuit qui permet de sélectionner une opération à faire, et comment indiquer l’opération à sélectionner ? Essayons d’abord de créer un circuit à deux entrées qui va calculer soit le OU soit le ET de ces deux entrées.

Nous savons faire un circuit simple qui calcule le OU de deux entrées \(X\) et \(Y\), avec une seule porte logique :

Nous pouvons sans autre y ajouter une porte ET pour calculer une autre sortie en parallèle, à partir des mêmes entrées \(X\) et \(Y\) :

L’idée est maintenant de combiner ces sorties intermédiaires pour n’en avoir plus qu’une, qui sera soit le OU, soit le ET. Mais comment faire pour indiquer si l’on désire le OU ou le ET ? Nous pouvons rajouter une entrée pour choisir cette opération. Appelons-la \(Op\), pour « opération ». Choisissons une convention : lorsque \(Op\) vaut 0, nous souhaitons effectuer l’opération OU, et lorsque \(Op\) vaut 1, nous souhaitons effectuer l’opération ET.

Ce que nous cherchons à créer est conceptuellement ce que fait ce composant tout prêt ci-dessous. Il s’appelle multiplexeur et connecte à sa sortie soit le signal du haut, soit le signal du bas, en fonction de la valeur de \(Op\). Essayez de changer \(Op\) :

Mais comment construire ce multiplexeur avec les portes logiques que nous connaissons ? Sans le multiplexeur, voici ce que nous devons compléter :

Pour savoir quelles portes utiliser pour recréer le multiplexeur, nous avons besoin de nous rappeler ceci. Lorsqu’un signal, disons \(A\), passe à travers une porte logique ET dont la seconde entrée vaut 0 (ici affichée sans qu’on puisse la changer en cliquant dessus), la sortie de cette porte-là sera toujours identique à 0. Cela nous permet ainsi d’annuler le signal \(A\) — de le mettre à zéro. De manière similaire, si cette seconde entrée vaut 1, le signal \(A\) passera tel quel. On peut ainsi voir la porte ET comme un annulateur de signal. Vérifiez ceci ici :

Ensuite, lorsqu’un signal, disons \(B\) cette fois, passe à travers une porte logique OU dont la seconde entrée est annulée et vaut 0, la sortie de cette porte sera toujours identique à \(B\). Vérifiez ceci ici :

La porte OU peut ainsi servir à combiner deux signaux, pour autant que l’un soit annulé.

Avec tout ceci, on peut ainsi construire un multiplexeur (un sélecteur de signal). Supposons qu’on ait les deux signaux \(A\) et \(B\) : nous pouvons construire un circuit qui combine soit \(A\) tel quel et \(B\) annulé, soit \(A\) annulé et \(B\) tel quel. Cela nous aidera pour notre projet initial ! Il faut cependant s’assurer que \(A\) soit chaque fois annulé quand \(B\) passe tel quel, et inversement. Ceci peut se faire en réutilisant l’idée d’une entrée de contrôle \(Op\) ainsi. Nous avons ainsi deux cas :

  • Lorsque \(Op = 0\), on va sélectionner \(A\) et annuler \(B\). On va donc faire passer \(A\) à travers une porte ET à laquelle on donne 1 à l’autre entrée, et faire passer \(B\) à travers une porte ET à laquelle on donne 0 à la seconde entrée.

  • Lorsque \(Op = 1\), on va faire exactement l’inverse : sélectionner \(B\) et annuler \(A\). On donnera donc un 0 à la porte ET qui filtre \(A\), et 1 à la porte ET qui filtre \(B\).

En relisant ces lignes, on voit que ce qu’on donne à la seconde entrée de la porte qui filtre \(B\) est toujours la même chose que \(Op\), et que ce qu’on donne à la seconde entrée de la porte qui filtre \(A\) est toujours l’inverse de \(Op\). On peut donc construire ce circuit avec un inverseur en plus :

Essayez ce circuit. Quand \(Op=0\), \(B\) filtré sera toujours 0 mais \(A\) passera, et inversement.

Pour recombiner ces sorties filtrées, il ne nous reste plus qu’à les connecter par une porte OU :

Essayez ce circuit pour confirmer qu’il agit comme un sélecteur : lorsque \(Op=0\), on aura sur la sortie \(Z=A\), et lorsque \(Op=1\), on aura \(Z=B\). Comparez-le avec le multiplexeur tout seul ci-dessous : est-ce que notre circuit fait bien la même chose ?

Ceci nous permet de compléter le circuit lacunaire de début de chapitre pour sélectionner avec le même mécanisme soit le OU soit le ET de nos deux entrées \(X\) et \(Y\). On ajoute les portes de notre sélecteur en connectant à l’entrée \(A\) le signal représentant X OU Y, et à l’entrée \(B\) le signal représentant X ET Y :

Exercice 1 – Test du sélecteur OU/ET

Testez le circuit ci-dessus. Établissez la table de vérité de \(Z\) en fonction de \(X\), \(Y\) et \(Op\). À l’aide de la table de vérité, montrez que, lorsque \(Op=0\), \(Z\) représente bien \(X\) OU \(Y\), et que, lorsque \(Op=1\), \(Z\) représente bien \(X\) ET \(Y\).

Nous avons ici construit un circuit qui, grâce à un bit de contrôle \(Op\), sélectionne une opération ou une autre à appliquer à ses deux bits d’entrées \(X\) et \(Y\).

Exercice 2 – Construction d’un sélecteur

En réutilisant les principes appliqués ci-dessus, construisez un circuit à deux bits d’entrées \(X\) et \(Y\) et un bit de contrôle \(Op\) qui donnera sur sa sortie \(Z\) :

  • Le OU exclusif de \(X\) et \(Y\), lorsque \(Op=0\) ;

  • L’inverse du bit \(Y\), lorsque \(Op=1\).

Exercice 3 – Inverseur conditionnel

En réutilisant les principes appliqués ci-dessus, construisez un circuit à une entrée \(X\) avec un bit de contrôle \(Op\) qui donnera sur sa sortie \(Z\) :

  • \(X\) tel quel, lorsque \(Op=0\) ;

  • \(X\) inversé, lorsque \(Op=1\).

Écrivez la table de vérité de ce circuit. Correspond-elle par hasard à une porte déjà connue? Serait-ce dès lors possible de simplifier votre circuit?

4.2. Une ALU à 4 bits

Une unité arithmétique et logique, ou ALU, est un circuit qui ressemble dans ses principes de base à ce que nous venons de faire. L’ALU réalise plusieurs opérations et permet de sélectionner, via un ou plusieurs bits de contrôle, l’opération qui est réalisée. Les opérations proposées sont, comme le nom de l’ALU indique, des opérations arithmétiques (typiquement, l’addition et la soustraction) et des opérations logiques (par exemple, un ET et un OU logiques).

Nous présentons ici une ALU simple à 4 bits :

Cette ALU sait effectuer l’addition ou la soustraction de deux nombres entiers représentés sur 4 bits. Elle a ainsi 8 bits d’entrée pour les données et 4 bits de sorties, à gauche et à droite. En plus de l’addition et de la soustraction, elle sait aussi faire les opérations logiques ET et OU — en tout donc, quatre opérations. Pour sélectionner l’une des quatre opérations, on ne peut plus se contenter d’un seul bit de contrôle, mais nous allons en utiliser deux pour avoir quatre combinaisons possibles. Ce sont les deux entrées supérieures gauches de l’ALU (on ignore ici l’entrée \(C_{in}\)).

La convention utilisée pour la sélection de l’opération est la suivante :

\(Op\)

Opération effectuée

00

Addition

01

Soustraction

10

OU

11

ET

Exercice 4 – Test de l’ALU

Connectez cette ALU à 8 entrées et à 4 sorties de manière à lui faire effectuer l’opération \(7 + 2 = 9\). Connectez les 4 bits des entrées et de la sortie à des afficheurs de demi-octet pour vérifier leur fonctionnement. Connectez ensuite une entrée pour le bit de contrôle qui permettra d’effectuer la soustraction avec les mêmes données d’entrée, donc \(7 - 2 = 5\).

L’ALU a trois sorties en plus, en bas du composant :

  • la sortie \(C_{out}\) (pour carry out) vaut 1 lors d’un dépassement de capacité (si le résultat de l’opération arithmétique représenté sur la sortie n’est pas valable parce qu’il vaudrait davantage de bits pour le représenter ; par exemple, le résultat de \(8 + 8 = 16\) n’est pas représentable sur 4 bits, qui suffisent à représenter les valeurs entières jusqu’à 15 seulement) ;

  • la sortie \(V\) (pour oVerflow) vaut 1 lors d’un dépassement de capacité si on considère les entrées et les sorties comme des nombres signés. Nous ne faisons pas cela ici et ignorons cette sortie ;

  • finalement, la sortie \(Z\) (pour Zero) vaut 1 lorsque tous les bits de sortie valent 0.

Exercice 5 – Une ALU comme comparateur

En programmation, c’est fréquent de tester, par exemple dans une condition avec un if, si deux valeurs sont égales. Par exemple, ce fragment de code affichera « Ces valeurs sont égales! » uniquement si les deux nombres entiers donnés lors de l’exécution du code sont les mêmes:

Ce qui nous intéresse spécialement, c’est la comparaison à la ligne 3. Cette comparaison peut être réalisée avec une ALU. Pour cet exercice, créez un circuit avec une ALU qui compare deux nombres de quatre bits et indique sur la sortie \(Z\) un 1 si les deux nombres sont égaux et un 0 s’ils sont différents.

Plus difficile : essayez de réaliser un circuit qui calcule la même valeur de sortie, mais sans utiliser d’ALU.

En résumé, nous avons appris ici ce qu’est une unité arithmétique et logique et avons examiné de plus près comment construire un multiplexeur, un circuit qui est à même de « choisir » parmi plusieurs signaux d’entrées lequel il va propager sur sa sortie. L’ALU est spécialement intéressante, car c’est le premier composant que nous rencontrons qui incarne une des propriétés de base d’un ordinateur, à savoir d’être programmable, en faisant en sorte que l’opération qu’elle effectue dépende d’un signal externe.

Pour aller plus loin

Notre petite ALU peut aussi faire des calculs en utilisant une représentation signée des nombres entiers. Sur 4 bits, une représentation en complément à deux peut représenter les nombres de \(-8\) à \(+7\). Il est possible d’utiliser les mêmes afficheurs de demi-octets en mode signé pour effectuer des opérations arithmétiques avec des valeurs négatives, par exemple, ici, \(-2 - (-4) = 2\) :

Notez que grâce à la représentation en complément à deux, la circuiterie interne de l’ALU peut se permettre de complètement ignorer si ses entrées sont signées ou pas et livrera le bon résultat tant que la convention d’entrée et de sortie reste la même.

Attention, lorsqu’on interprète les entrées et la sortie comme des nombres signés, ce n’est plus la sortie \(C_{out}\) de l’ALU qui indique un dépassement de capacité, mais la sortie \(V\), qui est calculée différemment.

Essayez de régler les entrées pour que cette ALU calcule le résultat de \(-8 - 4\). Vérifiez qu’un dépassement de capacité est signalé et expliquez pourquoi.