Chapitre 5 |
Arithmétique binaire
L |
es codes sont manipulés au quotidien sans qu’on s’en rende compte, et leur compréhension est quasi instinctive. Le seul fait de lire fait appel au codage alphabétique, auquel la civilisation moderne doit son développement rapide. Les nombres aussi sont représentés par des codes, et ces codes sont formés par des chiffres. Il existe à ce titre de multiples codes pour représenter les nombres; ainsi les symboles graphiques ‘XX’ et ‘20’ représentent tous deux la même quantité : vingt. Dans cet ouvrage, nous entendons le mot code dans sa définition représentative, associant un symbole à un objet, un signifiant à un signifié : ‘123’ n’est pas la quantité cent vingt trois, de la même façon que ‘oie’ n’est pas l’animal.
Ce chapitre traite plus particulièrement des codes analytiques auxquels les ingénieurs ont recours pour effectuer des opérations arithmétiques. Le chapitre 7 couvrira quant à lui les codes dits représentatifs. Ces notions sont importante car les systèmes numériques que l’on rencontre dans la pratique recourent à ces codes et en respectent les standards.
Dans le cadre de notre étude, nous considérons les codes sous une représentation binaire. C’est à dire que nous représenterons tout code avec un ensemble de ‘0’ et de ‘1’. Ces deux symboles représentent les formes possibles d’un bit.
Bit : Le mot fut utilisé pour la première fois par Claude Shannon dans un article publié en 1948. On attribue cependant son origine à John Wilder Tukey, mathématicien américain, qui inventa également le mot software. Bit est une contraction des mots binary digit, ou également binary unit. Un bit peut prendre deux valeurs possibles, ‘0’ ou ‘1’. Il est à la base des codes que nous allons présenter.
Un mot est un ensemble de bits agencés de sorte à représenter un objet dans un code. Le mot ‘0110000’ représente le caractère ‘0’ (zéro) en code Ascii (voir le chapitre 7), ou le nombre 48 dans la représentation dite décimale des entiers.
Les codes analytiques sont utilisés pour représenter les nombres (une quantité numérale). La matière théorique s’y rattachant sera traitée en plusieurs sous-sections. Nous verrons d’abord la théorie des systèmes de numération à base entière b, avant de traiter plus particulièrement la base 2. Une fois cette partie de la matière traitée, nous considérerons les représentations des nombres binaires signés, et finalement considérerons les opérations arithmétiques pouvant être utilisées sur ces représentations.
On peut écrire les nombres réels sous différentes bases. La base dix est la plus utilisée. La forme générale s’écrit :
Les indices des ai sont associés aux puissances de b et vérifient tous l’inégalité suivante : 0 ≤ ai < b. Ainsi, la valeur de N est :
N = an-1 x bn-1 + an-2 x bn-2 + … + a1 x b1 + a0 x b0 + a-1 x b-1 + a-2 x b-2 + … +a-m x b-m
123,561(10) = 1 x 102 + 2 x 101 + 3 x 100 + 5 x 10-1 + 6 x 10-2 + 1 x 10-3
= 1 x 100 + 2 x 10 + 3 x 1 + 5 x 1/10 + 6 x 1/100 + 1 x 1/1000
= 100 + 20 + 3 + 0.5 +0.06 +0.001
3623,71(10) = 3 x 103 + 6 x 102 + 2 x 101 + 3 x 100 + 7 x 10-1 + 1 x 10-2
= 3 x 1000 + 6 x 100 + 2 x 10 + 3 x 1 + 7 x 1/10 + 1 x 1/100
= 3000 + 600 + 20 + 3 + 0.7 +0.01
Utiliser des bases autre que la décimale n’est pas plus compliqué. Regardons à ce titre les exemples suivants :
123,561(8) = 1 x 82 + 2 x 81 + 3 x 80 + 5 x 8-1 + 6 x 8-2 + 1 x 8-3
= 1 x 64 + 2 x 8 + 3 x 1 + 5 x 1/8 + 6 x 1/64 + 1 x 1/512
= 64 + 16 + 3 + 0,625 +0,09375 +0,001953125 = 83,720703125
3623,71(16) = 3 x 163 + 6 x 162 + 2 x 161 + 3 x 160 + 7 x 16-1 + 1 x 16-2
= 3 x 4096 + 6 x 256 + 2 x 16 + 3 x 1 + 7 x 1/16 + 1 x 1/256
= 12288 + 1536 + 32+ 3 + 0,4375 +0,00390625 = 13859,44140625
Les bases 2, 8 et 16 sont souvent utilisées dans le monde informatique et celui de l’électronique. Leur utilité réside dans le fait que ces bases sont des puissances de 2 et permettent de ce fait de manipuler des bits.
Pour les bases 2 et 8, l’ensemble
des chiffres ai utilisés sont respectivement {0, 1} et
{0, 1, 2, 3, 4, 5, 6, 7}
(ce qui respecte l’inégalité énoncée précédemment : 0 ≤ ai
< b ). Cependant, la base 16 a recours à des chiffres représentant les
quantités 10 à 15. L’usage veut que ces quantités soient représentées par les six
premières lettres de l’alphabet. On utilise donc l’ensemble {0, 1, 2, 3, 4, 5,
6, 7, 8, 9, A, B, C, D, E, F}. Ainsi, le nombre CAF représentera la quantité
3 247 (en base 10) :
CAF(16) = C x 162 + A x 161 + F x 160
= C x 256 + A x 16 + F x 1
= 12 x 256 + 10 x 16 + 15 x 1
= 3072 + 160 + 15 = 3247
Le tableau qui suit illustre l’écriture des nombres 0 à 16 dans les quatre bases usuelles de l’informatique :
Décimal (10) |
Binaire (2) |
Octal (8) |
Hexadécimal (16) |
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
00000 00001 00010 00011 00100 00101 00110 00111 01000 01001 01010 01011 01100 01101 01110 01111 10000 |
00 01 02 03 04 05 06 07 10 11 12 13 14 15 16 17 20 |
0 1 2 3 4 5 6 7 8 9 A B C D E F 10 |
Il est important de noter certains points :
1. Les zéros à gauche de la partie entière n’ajoute et n’enlève rien au nombre : 00010(2) et 10(2) valent tous deux 2(10). Il en est de même pour les zéros à la droite de la partie fractionnaire : 0,1(2) et 0,1000(2) valent tous deux 0,5(10).
2. Quelle que soit la base b utilisée, les chiffres 10 donnent un nombre qui vaut b :10(b) = b
3.
k zéros
Quelle que soit la base b
utilisée, le nombre auquel on associe le symbole constitué du chiffre 1 suivi
d’un nombre k de 0, vaut b à la puissance k : 10000…000 (b) =
bk
Il est utile de pouvoir passer de la représentation d’un nombre dans une base à une autre. Nous étudierons trois méthodes de conversion dans ce manuel.
1. La méthode polynomiale
Pour retrouver la valeur d’un nombre, cette méthode utilise l’expression :
N = an-1 x bn-1 + an-2 x bn-2 + … + a1 x b1 + a0 x b0 + a-1 x b-1 + a-2 x b-2 + … +a-m x b-m
Dans la pratique, elle nous sera utile pour exprimer la valeur numérale du nombre N lorsqu’on l’exprime dans tout autre base b autre que la décimale. Nous l’avons illustré par de nombreux exemples précédemment et ferons l’économie d’autre exemples (voir la section 5.2.1).
2. La méthode itérative
Cette méthode consiste à convertir un nombre vers une base b. Pour ce faire, considérons le nombre N:
Notons la partie entière E et la partie fractionnaire F.
E = [an-1 an-2 … a1 a0](b)
F = [0 , a-1 a-2 … a-m](b)
Partant du constat que
E/b = [an-1 an-2 … a1 a0](b)/b = { an-1 x bn-1 + an-2 x bn-2 + … + a1 x b1 + a0 x b0}/b
E/b = an-1 x bn-2 + an-2 x bn-3 + … + a1 x b0 + a0 / b = Q1 et reste a0
Q1/b = an-1 x bn-3 + an-2 x bn-4 + … + a2 x b0 + a1 / b = Q2 et reste a1
Q2/b = an-1 x bn-4 + an-2 x bn-5 + … + a3 x b0 + a2 / b = Q3 et reste a2
Et que le processus peut se poursuivre jusqu’à obtenir an-1, nous verrons dans cette opération algorithmique une méthode permettant d’exprimer un nombre entier dans une base b.
Les exemples suivants illustrent le concept :
· 57(10) = ?(2)
57 ¸ 2 = 28 reste 1
28 ¸ 2 = 14 reste 0
14 ¸ 2 = 7 reste 0
7 ¸ 2 = 3 reste 1
3 ¸ 2 = 1 reste 1
1 ¸ 2 = 0 reste 1
d’où 57(10) = 111001(2)
· 637(10) = ?(16)
637 ¸ 16 = 39 reste 13 (représenté par D en hexadécimal)
39 ¸ 16 = 2 reste 7
2 ¸ 16 = 0 reste 2
d’où 637(10) = 27D(16)
La partie fractionnaire, elle, est traitée inversement :
F x b = [a-1 x b-1 + a-2 x b-2 + … +a-m x b-m] x b
= a-1 + a-2 x b-1 + … +a-m x b-m+1 = a-1 + F1
F1 x b = a-2 + a-3 x b-1 + … +a-m x b-m+2 = a-2 + F2
F2 x b = a-2 + a-3 x b-1 + … +a-m x b-m+2 = a-2 + F3
Le processus peut se poursuivre jusqu’à obtenir a-m.
Les exemples suivants illustrent le concept :
· 0,6875(10) = ?(2)
0,6875 ´ 2 = 1,375 partie entière = 1
0,375 ´ 2 = 0,75 partie entière = 0
0,75 ´ 2 = 1,5 partie entière = 1
0,5 ´ 2 = 1,0 partie entière = 1
d’où 0,6875(10) = 0,1011(2)
· 0,8125(10) = ?(8)
0,8125 ´ 8 = 6,5 partie entière = 6
0,5 ´ 8 = 4,0 partie entière = 4
d’où 0,8125(10) = 0,64(8)
3. Cas des bases b et bk
Cette méthode est utilisée pour passer d’une base b à une base bk, et vice versa. Le cas le plus courant est celui ou il s’agit de passer d’une représentation binaire à une représentation octale ou hexadécimale, ou de procéder à l’opération inverse.
Afin de mieux illustrer le concept, considérons les exemples suivants :
1101001(2) = 1 101 001(2) = 001 101 001(2) = 151(8)
100100111(2) = 1 0010 0111(2) = 0001 0010 0111(2) = 127(16)
110111101111(2) = 1101 1110 1111(2) = DEF(16)
Le principe utilisé ici est de regrouper k chiffres pour passer de b à bk. L’inverse est également applicable, comme l’illustrent les exemples suivants :
1EC5(16) = 0001 1110 1100 0101(2) = 0001111011000101(2) = 1111011000101(2)
1672(8) = 001 110 111 010(2) = 001110111010(2) = 1110111010(2)
Dans ce cas, on traduit chaque chiffre en k chiffres binaires. Notons finalement que l’opération est tout aussi faisable pour les nombres à partie fractionnaires, comme l’illustrent les exemples suivants, où la virgule est considérée comme un délimiteur pour rassembler les k chiffres.
1101001,1001(2) = 1 101 001 , 100 1 (2) = 001 101 001 , 100 100(2) = 151,44(8)
100100111,011001(2) = 1 0010 0111 , 0110 01 (2) = 0001 0010 0111 , 0110 0100(2) = 127,64(16)
11011110,11101(2) = 1101 1110 , 1110 1000(2) = DE,E8(16)
Le problème de la représentation des nombres négatifs se pose assez rapidement lorsque l’on veut manipuler des mots formés par des bits à cause de l’absence des symboles +/--. Il existe plusieurs approches pour résoudre le problème. La représentation des nombres entiers négatifs en complément à deux est la plus pratique et la plus utilisée de toutes. La représentation des nombres négatifs en complément à deux consiste à utiliser un bit supplémentaire (noté s) pour le signe pour un total de n+1 bits à gauche de la virgule et m bits à droite :
= s an-1 an-2 … a1 a0 , a-1 a-2… a-m
désigne ici la représentation d’un nombre négatif N. On dira de qu’il est l’opérateur de complément à deux de la valeur de |N|représentée sur n +1 bits à gauche de la virgule et m bit à droite de la virgule. La valeur numérale associée au mot ainsi obtenu est donnée par la relation :
est le complément à 2 du nombre |N|. On relèvera alors que :
Définissons l’opérateur dit de complément à un qui consiste à inverser les bits de |N|, l’opérateur de complément est donné par la relation :
Il en résulte l’écriture suivante de l’opérateur de complément à deux :
Ce qui revient à dire que le complément à deux peut être effectué par un complément à un (inversion de tous les bits) suivi d’une addition d’une unité égale à la valeur du bit le moins significatif.
Le procédé sera clarifié à l’aide des quelques exemples qui suivent :
· Comment écrit-on N = -15 (5 bits + 1 bit de signe) ?
|N| = 15 = 001111(2) => = 110000(2) => -15 º = 110000(2)+000001(2) = 110001(2)
· Comment écrit-on -35 (6 bits + 1 bit de signe) ?
|N| = 35 = 0100011 (2) => = 1011100(2) => -35 º = 1011100(2)+ 0000001(2) = 1011101(2)
Le bit de signe des nombres négatifs dans la représentation binaire signée prend la valeur 1. Les nombres positifs sont représentés en binaire signé en posant le bit de signe à 0 et en gardant la représentation non signée :
· Comment écrit-on +15 en binaire signé (5 bits + 1 bit de signe) ?
15 = 001111(2)
· Comment écrit-on +35 en binaire signé (6 bits + 1 bit de signe) ?
35 = 0100011(2)
De ce fait, pour un nombre de bits donné, certaines valeurs sont impossible à représenter en binaire signé. Par exemple :
· Il est impossible de représenter +15 en binaire signé avec 3 bits + 1 bit de signe.
· Il est impossible de représenter –15 en binaire signé avec 3 bits + 1 bit de signe.
· Il est impossible de représenter +35 en binaire signé avec 4 bits + 1 bit de signe.
· Il est impossible de représenter –35 en binaire signé avec 4 bits + 1 bit de signe.
En admettant une acception plus large de l’opérateur de complément à deux :
On trouve que le complément à deux est involué :
Le tableau qui suit
montre, à titre d’illustration, l’ensemble des nombres représentables avec 4
bits (3 bits +
1 bit de signe) en binaire signé.
-8 |
1000 |
-4 |
1100 |
0 |
0000 |
+4 |
0100 |
-7 |
1001 |
-3 |
1101 |
+1 |
0001 |
+5 |
0101 |
-6 |
1010 |
-2 |
1110 |
+2 |
0010 |
+6 |
0110 |
-5 |
1011 |
-1 |
1111 |
+3 |
0011 |
+7 |
0111 |
Comme nous l’avions précisé précédemment, les codes analytiques sont utilisés pour leur signification numérale. Ainsi, ils sont utilisés dans des opérations arithmétiques, suivant des algorithmes que nous voudrons connaître.
1. Formulation naïve de l’addition
Considérons d’abord le principe d’addition dans une formulation un peu naïve. Supposons que nous voulions additionner deux mots binaires d’une même longueur (par exemple 16). Pour ce faire, on commencera par poser la table d’addition binaire :
a |
b |
s=a+b |
r |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
Grâce à cette table, il devient possible d’effectuer certaines opérations d’addition de la même façon que cela se fait couramment en base dix:
Retenues |
|
|
|
|
|
|
|
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
A |
|
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
B |
+ |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
Somme |
|
1 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
En passant d’un colonne à la suivante, il peut arriver que l’on ait à additionner trois 1. Dans ce cas, la table d’addition binaire doit être légèrement modifiée. À la colonne i, nous aurons :
ri |
ai |
bi |
si |
ri+1 |
ri |
ai |
bi |
si |
ri+1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
1 |
Grâce à cette nouvelle table, il devient possible d’effectuer toutes opérations d’addition binaire :
Retenues |
|
|
|
|
|
1 |
|
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
A |
|
1 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
B |
+ |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
Somme |
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Comme les mots ont une limite de longueur, on dira que le résultat a provoqué une retenue si il nous faut un bit supplémentaire pour le conserver. Par exemple :
Retenues |
|
|
|
|
|
1 |
|
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
A |
|
1 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
B |
+ |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
Somme |
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Le résultat de cette addition a nécessité 17 bits. Or si nous limitons la longueur des mots à 16 bits, cette addition ne serait pas possible.
2. Addition avec retranchement de la retenue
Posons une addition qui provoque un dépassement de retenue (retenue supplémentaire sur une longueur de bits prédéfinie :
Retenues |
|
|
1 |
|
|
|
1 |
|
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
A |
|
|
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
B |
+ |
|
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
Somme |
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
Le résultat de l’addition nécessite 17 bits. En admettant un retranchement de la retenue supplémentaire, on obtient l’algorithme de l’addition avec retranchement de retenue :
Retenues |
|
|
1 |
|
|
|
1 |
|
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
|
A |
|
|
1 |
1 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
B |
+ |
|
0 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
1 |
Somme |
|
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
La cyclicité du complément à deux dans la représentation des nombres signés permet d’utiliser correctement l’addition avec retranchement de retenue pour effectuer toutes les opérations d’addition. Par exemple :
Retenues |
|
|
1 |
|
|
|
A |
|
|
1 |
1 |
1 |
0 |
B |
+ |
|
0 |
1 |
0 |
0 |
Somme |
|
1 |
0 |
0 |
1 |
0 |
Ce qui s’illustre bien graphiquement :
Considérons un exemple un peu plus élaboré que le lecteur est invité à détailler :
Termes |
Écriture binaire |
Complément à 2 |
A |
1110101010010011 |
-5485 |
B |
0100010001101101 |
17517 |
Résultat |
0010111100000000 |
12032 |
Résultat réel |
--- |
12032 |
Aussi étonnant que cela puisse sembler, le simple retranchement du 17e bit a pour effet de rendre le résultat correct dans le cas du complément à 2.
3. Addition et soustraction dans le cas du complément à 2
La soustraction N1 – N2 peut être regardée comme une addition en inversant l’opérande de droite. Posons complément à 2 (inverse) de N2. Selon la définition du complément à 2, nous avons :
Si N1 ‑ N2 est positif, en retirant la retenue supplémentaire, on élimine la valeur () et on obtient la bonne réponse :
Si N1 ‑ N2 est négatif, est positif et il n’y a pas de retenue supplémentaire. Sachant que :
et le résultat obtenu est correct.
Encore une fois, nous allons nous appuyer sur des exemples pour illustrer la chose :
‑ 01101010 ‑ 01100001 =------------ |
‑ 01101010 + 10011111 =100001001 |
10101010 + 10011111 = 00001001 |
Soustraction à effectuer |
Addition N1+ |
Retranche la retenue donne le résultat |
L’équivalent décimal est 106 – 97 = 9
Inversons maintenant les termes de l’addition :
‑ 01100001 ‑ 01101010 =------------ |
‑ 01100001 + 10010110 = 11110111 |
Soustraction à effectuer |
Addition N1+ : pas de retenue? On laisse cela tel quel |
Et à nouveau, le résultat ici (11110111) est ‑9.
Une limitation intrinsèque des systèmes logiques est, comme nous avons pu le mentionner, la longueur des mots dans un code. Dans le cas des codes analytiques, cette limitation n’est pas à écarter et doit être considérée avec prudence Un problème important survient dans le cas de l’addition et la soustraction lorsque le résultat ne peut être représenté selon la longueur des mots binaires.
Supposons que nous disposions d’un code de 4 bits pour représenter les nombres en binaire signé. Cela signifie que nous disposons des nombres allant de -8 à +7. Si le résultat de l’opération dépasse ces limites, nous faisons face à un cas de débordement. Par exemple, si nous additionnons +4 et +4, le résultat est +8 et n’est pas représentable en complément à 2 sur 4 bits. Il en est de même lorsque nous additionnons -4 et -5.
0100 + 0100 = 1000 (résultat invalide) |
1100 + 1011 = 0111 (résultat invalide) |
Les dépassements surviennent uniquement lorsque l’on additionne deux valeurs positives ou deux valeurs négatives. On peut les reconnaître par l’incohérence du résultat final qui se trouve être négatif dans le cas de l’addition de deux nombres positifs, et négatif dans le cas de l’addition de deux nombres positifs.
5.3.1 L’additionneur
L’additionneur est un circuit arithmétique permettant, comme l’indique son nom, d’additionner deux nombres binaires A et B. Les signaux A et B doivent avoir la même longueur (nombre de bits) et donnent un résultat de même longueur plus un bit de retenue supplémentaire.
L’additionneur est un circuit complexe qui a mérité une attention particulière dans le domaine des circuits numérique. Cette complexité est certes due aux normes régissant l’addition (représentation des nombres, format choisi pour représenter les nombres négatifs), et nous tâcherons d’aborder la conception du circuit par étapes de sorte à éclairer au mieux les connaissances théoriques connues jusqu’à présent.
L’additionneur comprend deux entrées (A et B) de longueur n. Il comporte également une sortie correspondant au résultat de l’addition (S) de longueur n, ainsi que deux signaux de sortie, le signal (R) pour la retenue supplémentaire et le signal (D) pour le débordement. On va également vouloir utiliser le même circuit pour effectuer la soustraction. On ajoute donc en entrée un signal de contrôle (C) permettant d’effectuer l’opération A ‑ B plutôt que A + B.
Nous présentons ici le schéma global d’un additionneur :
Nous allons faire appel à la conception itérative pour réaliser ce circuit. Mais nous commencerons par simplifier le problème en retirant les signaux (C) et (D), et les ajouterons au fur à mesure que nous pourrons enrichir notre implémentation.
Nous connaissons déjà un algorithme simple pour effectuer l’addition, celui de ce que nous avions appelé la formulation naïve de l’addition :
Additionneur simple |
Algorithme itératif pour l’additionneur simple |
Comme on peut s’en rendre compte, l’addition est réalisée au niveau de chaque bit et le résultat intermédiaire est propagé itérativement d’un niveau à l’autre jusqu’à obtenir le résultat total. À l’exception du premier bit, pour chaque niveau i nous considérons trois termes : Ai, Bi et ri qui donnent le résultat Si et une retenue pour le niveau suivant ri+1. Le résultat R est récupéré du signal rn mais n’est pas considéré pour appliquer l’algorithme d’addition avec retranchement de la retenue supplémentaire.
On peut concevoir une cellule à trois entrées et deux sorties pour réaliser l’ensemble du circuit :
Cellule i |
Circuit itératif réalisé sur la base d’une cellule pour l’additionneur |
La table de vérité associée à cette cellule est la suivante :
|
On trouve alors que les signaux de sorties sont donnés par les équations : · Si = AiBiri · ri+1 = AiBi+Airi+Biri
|
Ce qui nous donne le circuit :
Cellule i de l’additionneur itératif
Mais cette implémentation n’est pas optimisée. La littérature en propose une autre qui la divise en deux demi-cellules (appelées demi-additionneurs binaires) au prix d’une réalisation multi-niveaux.
Le demi-additionneur prend deux entrées au lieu de trois, et le circuit complet est le suivant :
Additionneur binaire complet (cellule i) avec demi additionneurs |
Demi Additionneur, implémentation |
On se rappellera la table d’addition utilisée à la section 5.2.4 qui est aussi la table de vérité du circuit du demi-additionneur.
Un inconvénient du circuit itératif, c’est le délai de propagation qu’il entraîne sur le chemin menant des termes A et B jusqu’à la retenue. L’image suivante présente un additionneur itératifs 4 bits réalisé avec des demi-additionneurs où nous avons mis l’accent sur le chemin critique menant du bit le moins significatif du signal (A) jusqu’au signal de retenue supplémentaire (R). Comme on peut le voir, le signal traverse un total de 8 portes logiques avant que le résultat sur le signal (R) ne soit disponible.
Accélérer la propagation du signal de retenu est possible en reprenant nos équations :
Si on revoit l’expression de r i+1, on a : r i+1 = AiBi+( AiBi )ri = gi+pi ri où gi=AiBi et pi=AiBi On il est possible de faire apparaître le terme r0 dans l’expression de tout ri. Reprenons l’exemple de l’additionneur 4 bits :
|
Comme on peut le constater, toutes ces expressions utilisent les signaux pi et gi ainsi que le signal r0. Cette écriture peut à l’évidence être généralisée pour tout ri+1 jusqu’au signal rn. Pour tout ri+1, on écrit :
r i+1 = gi+pi gi-1+ pipi-1gi-2+ pipi-1pi-2gi-3+…+( pipi-1…p4p3)g2+( pipi-1…p3p2)g1+ ( pipi-1…p2p1)g0+( pipi-1…p1p0)r0
Notons aussi que tout signal Si s’écrit Si=piri. Nous pouvons donc réaliser un circuit qui prend 2n+1 entrées (les n pi et les n gi et le signal r0) et donnera en sortie 2n+1 signaux (les n+1 ri et les n pi nécessaires pour générer les si). On appellera ce circuit un anticipateur de retenue car il va permettre d’accélérer le calcul) du signal de retenue (R). Cet anticipateur de retenue va nous permettre de réaliser un additionneur rapide :
Si nous reprenons le circuit classique de l’additionneur :
et celui de l’additionneur rapide utilisant un anticipateur de retenue :
Le coût du circuit rapide est plus élevé mais le chemin critique traverse quatre portes au plus. De plus, le chemin de r0 à R est très court.
Il reste encore à discuter de l’option d’effectuer la soustraction. Afin de représenter les nombres négatifs, nous choisissons la représentation en complément à 2. On se rappelle que pour inverser un nombre en complément à 2 il suffit d’inverser tous les bits et d’ajouter 1 au bit le moins significatif. Aussi, pour obtenir un soustracteur, il suffit d’inverser les bits de B et de mettre 1 dans r 0. Que l’on choisisse l’additionneur itératif ou l’additionneur rapide avec anticipateur de retenue, la solution demeure identique :
Cependant, nous voulons commander l’opération de soustraction par le signa (C). Or se rappellera que :
· X1=
· X0=X
On aura donc une addition si C = 0 et une soustraction pour C=1 avec le circuit suivant:
Finalement, le signal (D) s’obtient en effectuer un XOR entre les signaux r n et r n-1.
5.3.2 Le comparateur
Le comparateur est un circuit arithmétique permettant de comparer deux nombres binaires A et B. A et B doivent avoir la même longueur (nombre de bits). On cherche à savoir si A > B, A<B ou A=B. On comprend donc que le circuit répond à une question à trois choix.
Notre circuit final doit produire trois signaux Sg (actif si A>B), Sp (actif si A<B) et Se (actif si A=B) en prenant en entrée les signaux A et B :
Ce circuit compare les deux entrées A et B et donne :
· Sg Sp Se = 100 si A>B
· Sg Sp Se = 010 si A<B
· Sg Sp Se = 001 si A=B
La conception d’un tel circuit n’est pas évidente, d’autant plus que la longueur des mots A et B n’est pas connue à priori. On veut donc utiliser une conception modulable, permettant de générer le circuit selon les contraintes imposées. Une méthode de conception flexible et souvent utilisée dans la conception de circuits arithmétiques est l’utilisation de circuits itératifs.
Les circuits itératifs sont l’application en circuits logiques d’algorithmes itératifs. Le principe général est de trouver une méthode ou un algorithme agissant sur un seul bit et de le répéter de façon itérative pour obtenir au final le résultat voulu pour une longueur de mot (en bits) donnée.
Si nous considérons le problème de la comparaison de deux nombres binaires, on constate que cette comparaison peut se réaliser en effectuant la comparaison depuis le bit le plus significatif et decrescendo jusqu’au bit le moins significatif.
Considérons pour cela la cellule du circuit itératif suivante :
Cellule i |
Circuit itératif réalisé sur la base d’une cellule pour le comparateur |
Ai et Bi correspondent aux bits unitaires des mots A et B. Les signaux intermédiaires Gi, Pi et Ei permettant aux cellules de communiquer entre elles. On associe les signaux Gi, Pi et Ei aux réponses intermédiaires du système, respectivement « Plus Grand que… », « Plus Petit que… » et « Égal… ». Dans la réalisation du circuit complet, on pose Gn=Pn=0, et En=1. Les signaux terminaux G0, P0 et E0 correspondent aux sorties du comparateur, respectivement Sg, Sp et Se. Au niveau de chaque cellule, on compare les signaux Ai et Bi et décide de la sortie en fonction de la réponse intermédiaire à donner (Gi, Pi et Ei) en fonction de la réponse intermédiaire de la cellule précédent (Gi+1, Pi+1 et Ei+1).
· Si la réponse précédente est Gi+1Pi+1Ei+1 = 100, la sortie sera GiPiEi = 100 (car la valeur des bits moins significatifs n’a pas d’importance dans ce cas).
· Si la réponse précédente est Gi+1Pi+1Ei+1 = 010, la sortie sera GiPiEi = 010 (car la valeur des bits moins significatifs n’a pas d’importance dans ce cas).
· Si la réponse précédente est Gi+1Pi+1Ei+1 = 001, la sortie sera GiPiEi dépend de Ai et Bi. :
o Si Ai=Bi ð GiPiEi = 001
o Si AiBi=10 ð GiPiEi = 100
o Si AiBi=01 ð GiPiEi = 010
Cela se traduit par la table de vérité que voici :
Gi+1 |
Pi+1 |
Ei+1 |
Ai |
Bi |
Gi |
Pi |
Ei |
1 |
0 |
0 |
- |
- |
1 |
0 |
0 |
0 |
1 |
0 |
- |
- |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
Tous les autres cas sont facultatifs. On peut associer à cette table de vérité les trois tables de Karnaugh à variables inscrites suivantes :
Karnaugh associé à Gi |
Karnaugh associé à Pi |
Karnaugh associé à Ei |
On trouve donc :
Gi = Ai + Gi+1 ; Pi = Bi + Pi+1 ; Ei =Ei+1= Ei+1
Ce qui nous donne le circuit suivant :
Notons que le circuit itératif aurait pu être pensé de façon inverse, en effectuant la comparaison depuis le bit le plus moins significatif et crescendo jusqu’au bit le plus significatif.