cursus.

Cours 2 · Logique et circuitsLeçon 2 sur 2

Circuits logiques

6 h de lecture8 sections Version PDF

À la fin de cette leçon, vous saurez

Portes logiques ; additionneur, multiplexeur, décodeur et comparateur ; bascules, registres et compteurs.

Un processeur récent compte des dizaines de milliards de transistors. Ce nombre décourage, et il ne devrait pas : la variété des briques, elle, tient sur une page. Quelques portes logiques, un additionneur, un multiplexeur, un décodeur, une bascule — et tout le reste est de la répétition et de l'assemblage.

Ce chapitre est la charnière du cours. Le chapitre 3 a donné l'algèbre ; on la câble ici. Le chapitre 5 posera l'architecture du processeur ; ses unités seront faites de ce qu'on construit maintenant. Et le TP prend tout son sens ici : monter un additionneur porte par porte dans Logisim, puis écrire la même addition en assembleur au chapitre 6, est ce qui relie concrètement les deux moitiés du semestre.

Les portes, et la seule qui compte vraiment

Une porte logique est un circuit qui réalise un opérateur booléen. Les trois de base — ET, OU, NON — se complètent de trois formes niées, NAND, NOR et XOR, plus utiles en pratique que leurs cousines directes.

PorteSortie à 1 quand…Notation
ET (AND)toutes les entrées valent 1aba \cdot b
OU (OR)au moins une entrée vaut 1a+ba + b
NON (NOT)l'entrée vaut 0aˉ\bar{a}
NON-ET (NAND)pas toutes les entrées à 1ab\overline{a \cdot b}
NON-OU (NOR)aucune entrée à 1a+b\overline{a + b}
OU exclusif (XOR)les entrées diffèrentaba \oplus b

Le fait remarquable du chapitre est que le NAND est universel : on construit toute fonction booléenne avec des NAND seuls. La démonstration tient en trois lignes, et De Morgan en est la clé.

NON a    = NAND(a, a)a ET b   = NON( NAND(a, b) )        = NAND( NAND(a,b), NAND(a,b) )a OU b   = NAND( NON a, NON b )     par De Morgan

Ce n'est pas une curiosité théorique. En technologie CMOS, la porte naturelle est justement inverseuse : un NAND coûte quatre transistors, un ET en coûte six — un NAND suivi d'un inverseur. Les bibliothèques de cellules sont donc bâties sur NAND et NOR, et une conception qui les ignore paie ses portes plus cher qu'il ne faut.

Combinatoire : la sortie ne dépend que des entrées

Un circuit est combinatoire quand sa sortie est entièrement déterminée par ses entrées courantes. Pas de mémoire, pas d'histoire : mêmes entrées, même sortie, toujours.

Le demi-additionneur, puis l'additionneur complet

Additionner deux bits produit une somme et une retenue. La table est celle du chapitre 1 :

aabbssrr
0000
0110
1010
1101

La colonne somme vaut 1 quand les entrées diffèrent : c'est un XOR. La colonne retenue vaut 1 quand les deux valent 1 : c'est un ET. Deux portes, et voilà le demi-additionneur — ainsi nommé parce qu'il lui manque l'essentiel : il ne sait pas recevoir la retenue de la colonne précédente.

L'additionneur complet prend trois entrées, aa, bb et la retenue entrante rer_e :

s=abrers=ab+are+bres = a \oplus b \oplus r_e \qquad\qquad r_s = ab + a r_e + b r_e

Regardez la seconde expression : c'est exactement la fonction majorité simplifiée au Karnaugh du chapitre 3. Il y a une retenue sortante dès que deux des trois entrées valent 1, ce qui est intuitif — additionner trois bits donne 2 ou 3 dès que deux d'entre eux sont à 1.

De un bit à nn : l'additionneur à propagation

Pour additionner deux mots de 8 bits, on chaîne huit additionneurs complets, la retenue sortante de chacun alimentant la retenue entrante du suivant. C'est l'additionneur à propagation de retenue (ripple-carry), et c'est le circuit du TP.

Il a un défaut, et ce défaut gouverne toute l'architecture qui suit : la retenue doit traverser les huit étages avant que le dernier bit soit correct. Le temps de calcul est proportionnel au nombre de bits. Sur 64 bits, c'est intenable — d'où les additionneurs à anticipation de retenue, qui calculent les retenues en parallèle, plus rapides et plus gourmands en portes. C'est le premier compromis surface/vitesse du cours, et il ne sera pas le dernier.

Et la soustraction ? Le chapitre 2 a déjà répondu : ab=a+(b)a - b = a + (-b), et b-b s'obtient en inversant les bits de bb puis en ajoutant 1. Concrètement, on place un XOR sur chaque bit de bb commandé par un signal MM, et on injecte ce même MM comme retenue entrante du premier étage. M=0M = 0 : le circuit additionne. M=1M = 1 : il soustrait. Le même additionneur fait les deux, pour le prix de huit portes XOR — c'est là que le choix du complément à deux se paie en silicium économisé.

Multiplexeur, décodeur, comparateur

Trois autres briques reviennent partout.

Le multiplexeur est un aiguillage : 2k2^k entrées de données, kk entrées de commande, une sortie qui recopie l'entrée désignée. Le plus simple, à deux entrées, s'écrit s=cˉe0+ce1s = \bar{c}\,e_0 + c\,e_1. C'est le composant qui, au chapitre 5, choisira si l'unité de calcul reçoit un registre ou une valeur immédiate.

Le décodeur fait l'inverse : kk entrées, 2k2^k sorties, et une seule sortie active, celle dont le numéro est écrit en binaire sur les entrées. C'est ainsi qu'une adresse sélectionne une case mémoire, et qu'un code d'opération active la bonne commande.

Le comparateur teste l'égalité de deux mots. Deux bits sont égaux quand leur XOR vaut 0 ; deux mots sont égaux quand tous leurs XOR valent 0, ce qui s'écrit avec un NOR final. La comparaison d'ordre demande davantage de logique, et se ramène souvent à une soustraction dont on lit le signe — encore le même additionneur.

Quiz · vérifiez votre compréhension Sans réponse

Pourquoi une machine n'a-t-elle pas besoin d'un circuit de soustraction distinct de son additionneur ?

Séquentiel : quand le circuit se souvient

Tout ce qui précède oublie instantanément. Or un processeur doit retenir : le contenu d'un registre, la valeur d'un compteur, l'adresse de la prochaine instruction. Il faut un circuit dont la sortie dépende aussi de son état passé. On l'obtient par un moyen simple et troublant : reboucler une sortie sur une entrée.

La bascule RS est le cas fondateur : deux portes NOR croisées, chacune recevant la sortie de l'autre. Trois comportements. Mettre SS (set) à 1 force la sortie à 1. Mettre RR (reset) à 1 la force à 0. Et laisser les deux à 0 conserve l'état — c'est là qu'il y a mémoire, dans le simple fait que la boucle s'auto-entretient. La combinaison R=S=1R = S = 1 est interdite : elle produit un état incohérent, et l'issue dépend de qui retombe à 0 en premier.

Une bascule RS réagit dès que ses entrées bougent, ce qui est ingérable dans un circuit complexe. On la discipline avec une horloge, signal carré qui rythme tout le système, et l'on obtient la bascule D : une entrée de donnée, une entrée d'horloge, et la sortie qui recopie l'entrée au moment décidé par l'horloge.

Ce moment fait toute la différence. Une bascule sur niveau (latch) est transparente tant que l'horloge est haute : la sortie suit l'entrée, ce qui peut faire traverser plusieurs étages en un seul cycle. Une bascule sur front ne prend en compte l'entrée qu'à l'instant précis où l'horloge monte, puis se verrouille. C'est celle qu'on emploie partout, parce qu'elle rend le circuit prévisible : à chaque front, tout l'état bascule d'un coup vers sa valeur suivante, et ce qui se passe entre deux fronts n'a aucune importance.

D'où la contrainte qui fixe la fréquence d'une machine, et que le chapitre 5 reprendra : entre deux fronts, il faut que le plus long chemin combinatoire — le chemin critique, la propagation de la retenue par exemple — ait eu le temps de se stabiliser. La période d'horloge est dictée par le circuit le plus lent, pas par le plus rapide.

Registres et compteurs

À partir de la bascule D, deux assemblages suffisent.

Un registre de nn bits est un paquet de nn bascules D partageant la même horloge et le même signal d'écriture. Tous les bits basculent ensemble, ce qui est indispensable : un registre dont les bits changeraient à des instants différents laisserait lire des valeurs qui n'ont jamais existé. Un registre à décalage relie en plus la sortie de chaque bascule à l'entrée de la suivante, et décale son contenu d'un rang à chaque front — c'est le décalage qui multiplie ou divise par deux du chapitre 1, réalisé en fils plutôt qu'en calcul.

Un compteur est un registre bouclé sur un incrémenteur : à chaque front, il ajoute 1 à son propre contenu. Sur nn bits, il compte modulo 2n2^n et revient à zéro — le tour de compteur du chapitre 2, sous sa forme matérielle. C'est directement le compteur ordinal du chapitre 5, celui qui contient l'adresse de la prochaine instruction et qui s'incrémente à chaque cycle.

Quiz · vérifiez votre compréhension Sans réponse

Qu'est-ce qui distingue fondamentalement un circuit séquentiel d'un circuit combinatoire, et par quel moyen l'obtient-on ?

À vous

L'exercice construit l'additionneur du TP, mais en JavaScript et à partir des portes seules : un additionneur complet, puis huit en cascade, puis l'astuce du XOR commandé qui transforme l'additionneur en soustracteur.

Le jeu de tests reprend volontairement les cas du chapitre 2 — 100+50100 + 50 et 128-128 — pour que le circuit reproduise, à la porte près, les débordements que le codage annonçait.

Exercice · JavaScript · à vous de jouer

Câblez la retenue de l'additionneur complet, puis faites-en un soustracteur.

En attente
// Les portes. On ne s'autorise rien d'autre : pas de +, pas de -.
const NON = (a) => a ^ 1;
const ET  = (a, b) => a & b;
const OU  = (a, b) => a | b;
const XOR = (a, b) => a ^ b;

// Additionneur complet : trois bits en entrée, somme et retenue en sortie.
function additionneurComplet(a, b, re) {
  const s = XOR(XOR(a, b), re);
  const rs = 0;              // ← à écrire : la fonction majorité de a, b, re
  return { s, rs };
}

const N = 8;
const versBits = (n) => Array.from({ length: N }, (_, i) => (n >> i) & 1); // [poids faible…]
const versNombre = (bits) => bits.reduce((n, b, i) => n + b * (1 << i), 0);

// Additionneur n bits à propagation de retenue, avec entrée de commande M.
// M = 0 : calcule a + b.  M = 1 : doit calculer a − b.
function additionner(a, b, M) {
  const A = versBits(a), B = versBits(b);
  const S = [];
  let retenue = 0;           // ← que doit valoir la retenue entrante si M = 1 ?
  for (let i = 0; i < N; i++) {
    const bi = B[i];         // ← et que doit devenir ce bit si M = 1 ?
    const { s, rs } = additionneurComplet(A[i], bi, retenue);
    S.push(s);
    retenue = rs;
  }
  return { motif: versNombre(S), retenueSortante: retenue };
}

// ── À VOUS ────────────────────────────────────────────────────────────────
// 1. Écrivez rs dans additionneurComplet (majorité : ab + a·re + b·re).
// 2. Faites soustraire le circuit : inverser chaque bit de B par un XOR
//    commandé par M, et injecter M comme retenue entrante initiale.

const signe = (m) => (m >= 128 ? m - 256 : m);
const CAS = [
  { a: 11,  b: 7,   M: 0 },
  { a: 100, b: 50,  M: 0 },
  { a: 5,   b: 5,   M: 1 },
  { a: 3,   b: 10,  M: 1 },
  { a: 255, b: 1,   M: 0 },
];

for (const c of CAS) {
  const r = additionner(c.a, c.b, c.M);
  const attendu = c.M === 0 ? c.a + c.b : c.a - c.b;
  const lu = signe(r.motif);
  const ok = lu === attendu || r.motif === (attendu & 255) ? "  ok" : "  X";
  console.log(
    (c.a + (c.M ? " - " : " + ") + c.b).padEnd(12) +
    "motif " + r.motif.toString(2).padStart(8, "0") +
    "  non signé " + String(r.motif).padStart(3) +
    "  signé " + String(lu).padStart(4) + ok
  );
}

Console de sortie
Le résultat s'affiche dans la console

En travaux pratiques

Travaux pratiques 4 · sur machine

Construire une unité arithmétique et logique

Assembler, porte par porte, le circuit qui calcule dans un processeur — puis lui ajouter la mémoire d'un bit, qui fait basculer du combinatoire au séquentiel.

4 h
Avant de commencer
  • Le TP 3 : simplification et vérification exhaustive
  • Un simulateur de circuits logiques : Logisim Evolution, Digital, ou équivalent
  • Le complément à deux du TP 2
  1. 1. Le demi-additionneur

    Construisez le circuit qui additionne deux bits et produit une somme et une retenue. Deux portes suffisent. Vérifiez les quatre cas.

  2. 2. L'additionneur complet

    Ajoutez une retenue entrante. Établissez d'abord la table de vérité à trois entrées, simplifiez comme au TP 3, puis câblez. Vérifiez les huit cas.

  3. 3. Quatre bits

    Chaînez quatre additionneurs complets. Testez 7 + 5, puis 15 + 1. Comptez ensuite le nombre de portes traversées par le signal entre l'entrée et le bit de poids fort.

  4. 4. Soustraire sans circuit de soustraction

    Ajoutez une entrée de commande qui, à 1, fait calculer A − B. Un XOR par bit de B et la retenue initiale suffisent. Testez 7 − 5 puis 5 − 7.

  5. 5. Les drapeaux

    Ajoutez la sortie Z (résultat nul) et la sortie V (débordement signé). Trouvez le cas où V doit valoir 1 alors que la retenue sortante vaut 0.

  6. 6. L'unité complète

    Ajoutez un multiplexeur commandé par deux bits, qui choisit entre ET, OU, addition et soustraction. Vous avez une UAL 4 bits.

  7. 7. Une mémoire d'un bit

    Construisez une bascule D, reliez-en quatre à une horloge, et faites-en un registre. Chargez le résultat de l'UAL dedans, puis réinjectez-le en entrée A.

  8. 8. Le compteur

    Câblez le registre pour qu'il s'incrémente à chaque coup d'horloge. Vous venez de construire un compteur ordinal — celui du chapitre suivant.

C'est réussi quand
  • 15 + 1 donne 0 avec la retenue sortante à 1
  • 7 − 5 donne 2 sans qu'aucun circuit de soustraction n'existe dans votre schéma
  • Votre compteur avance d'exactement un par front d'horloge
  • Vous savez dire quelle sortie s'allume sur 7 + 1 en signé, et pourquoi

Ce que la suite en fait

Les briques de ce chapitre se retrouvent une à une dans le processeur du chapitre 5. Le registre devient le banc de registres et le compteur ordinal ; le décodeur devient la sélection d'une case mémoire et le décodage du code d'opération ; le multiplexeur choisit les entrées de l'unité arithmétique et logique, qui n'est elle-même qu'un additionneur entouré de quelques portes ; et l'horloge devient la fréquence affichée sur la fiche technique.

Le chemin critique, lui, ressortira deux fois : au chapitre 5 pour expliquer pourquoi un cycle dure ce qu'il dure, et au chapitre 8 pour expliquer ce que le pipeline gagne en le découpant.

À retenir

Flashcards · 1 / 4Toucher pour retourner
Fin de la leçon

Vous avez parcouru les 8 sections.

Marquez-la terminée pour faire avancer votre parcours, ou revenez sur un point avant de passer à la suite.