Le chemin de données sait déplacer des valeurs et calculer, mais il ne décide rien seul. À chaque cycle d’horloge, il faut lui dire quel registre va sur le bus, quelle opération fait l’ALU, quel registre reçoit le résultat, et si la mémoire est lue ou écrite. C’est le rôle de l’unité de contrôle.
À chaque cycle, l’unité de contrôle produit deux choses :
- la valeur de chaque signal de contrôle pour ce cycle ;
- l’étape qui vient ensuite.
Il existe deux façons classiques de la construire : en logique fixe (contrôle câblé), ou comme un petit programme stocké dans le CPU (contrôle microprogrammé, ou microcode).
Les signaux de contrôle
Un signal de contrôle est un fil qui active ou désactive une chose. Pour le chemin de données du chapitre précédent, les signaux comprennent :
- les sources du bus : quel registre alimente le bus interne —
eax?rbp? le MDR ? - la fonction de l’ALU : addition, soustraction, ET, recopie…
- les destinations : quel registre charge le résultat en fin de cycle ;
- la mémoire : charger le MAR, charger le MDR, activer MEMR ou MEMW ;
- le séquencement : mettre à jour
rip, charger l’IR.
Certaines combinaisons sont interdites. Deux registres ne doivent jamais alimenter le même bus en même temps — sur du vrai matériel, cela peut même endommager le circuit. Les concepteurs encodent donc la source du bus en un petit nombre, qu’un décodeur transforme en une seule ligne d’activation. Avec 16 sources possibles, 4 bits suffisent au lieu de 16 fils.
La machine d’exemple de Tanenbaum, la Mic-1, a besoin de 29 signaux de contrôle, que l’encodage ramène à 24 bits.
Micro-instructions et mémoire de contrôle
Une micro-instruction, ce sont les signaux de contrôle d’un cycle, écrits sous forme d’une ligne de bits, plus un champ qui indique quelle micro-instruction vient ensuite. Un microprogramme est une liste de ces lignes, rangée dans une petite mémoire rapide à l’intérieur du CPU : la mémoire de contrôle (control store), en général une ROM.
La mémoire de contrôle a ses propres registres d’adresse et de données :
- le MPC (compteur de microprogramme) contient l’adresse de la micro-instruction courante ;
- le MIR (registre de micro-instruction) contient la micro-instruction elle-même. Ses bits pilotent les signaux de contrôle : la plupart vont directement au chemin de données, et les champs encodés, comme la source du bus, passent d’abord par un décodeur.
Les micro-instructions de la Mic-1 font 36 bits : 24 bits de contrôle, 9 bits d’adresse suivante, et 3 bits qui choisissent comment l’adresse suivante est formée. Sa mémoire de contrôle en contient 512. C’est toute la machine : une horloge, un chemin de données, une mémoire de contrôle, et une minuscule boucle qui lit une micro-instruction par cycle.
Le microprogramme d’une instruction
Voici add eax, DWORD PTR [rbp-4] — l’instruction du chapitre sur le cycle fetch–decode–execute — écrite comme un microprogramme pour le chemin de données du simulateur. Chaque ligne est une étape, et les colonnes sont des groupes de signaux de contrôle :
| Étape | Source du bus | ALU / AGU | Charge | Mémoire | Suivante |
|---|---|---|---|---|---|
| fetch | rip | — | MAR, puis IR | MEMR | decode |
| decode | IR | — | — | — | saut à la routine add r, [m] |
| 1 | eax | — | entrée de l’ALU | — | 2 |
| 2 | rbp | AGU : rbp − 4 | MAR | — | 3 |
| 3 | — | — | MDR | MEMR | 4 |
| 4 | MDR | ALU : addition | drapeaux | — | 5 |
| 5 | sortie de l’ALU | — | eax | — | 6 |
| 6 | — | — | rip ← suivante | — | fetch |
Avancez pas à pas dans le simulateur et comparez. Chaque micro-opération affichée sur le schéma correspond à une ligne :
- mov DWORD PTR [rbp-4], 10
- mov eax, 5
- add eax, DWORD PTR [rbp-4]
Les lignes fetch et decode sont communes à toutes les instructions. Seules les lignes après decode sont propres à add. Une autre instruction, comme mov ou push, a sa propre courte routine ailleurs dans la mémoire de contrôle, et toutes se terminent en revenant au fetch.
Choisir l’étape suivante
Un programme normal exécute ses instructions dans l’ordre des adresses, sauf en cas de saut. Pas un microprogramme : chaque micro-instruction indique explicitement laquelle vient ensuite. Cela permet trois sortes de « suivante » :
- Inconditionnelle : aller à l’adresse n. La plupart des lignes font cela.
- Conditionnelle : aller à l’une de deux adresses, selon un bit d’état de l’ALU — par exemple, si le dernier résultat était nul. La Mic-1 le fait en combinant par un OU le bit Z ou N mémorisé avec le bit de poids fort de l’adresse suivante : les deux successeurs possibles sont alors n et n + 256.
- Multiple (aiguillage) : aller à une adresse calculée à partir de l’opcode. C’est exactement ce qu’est le decode. La Mic-1 combine par un OU l’octet d’opcode avec l’adresse suivante, ce qui saute en une seule étape à la routine de cette instruction, parmi jusqu’à 256 destinations possibles.
Les micro-branchements conditionnels permettent à une même instruction de faire des choses différentes. Dans le simulateur, jl montre l’idée un niveau plus haut — l’unité de contrôle teste les drapeaux et choisit entre deux valeurs possibles pour le prochain rip :
- mov eax, 3
- cmp eax, 5
- jl smaller
- mov ecx, 0
- smaller:
- mov ecx, 1
La troisième micro-opération indique SF=1 OF=0 → TAKEN. Remplacez 3 par 7 et elle devient not taken.
Une instruction, de nombreuses étapes
Avec un micro-branchement conditionnel, un microprogramme peut boucler, si bien qu’une seule instruction machine peut effectuer une quantité de travail qui dépend des données. Le x86 a des instructions de ce genre. rep stosb remplit rcx octets en [rdi] avec al :
- .bss
- buf: .zero 8
- .text
- _start:
- lea rdi, [rip+buf]
- mov ecx, 4
- mov al, 0x41
- rep stosb
Cette seule instruction prend 15 micro-opérations : fetch et decode, puis quatre tours de écrire un octet, avancer rdi, décrémenter rcx, puis la mise à jour de rip. Le compteur de bus affiche 1 R · 4 W : une lecture d’instruction et quatre écritures de données. Mettez ecx à 100 et la même instruction fera 100 tours.
Sur les vrais processeurs Intel et AMD, les instructions de chaîne rep font partie de celles qui s’exécutent en microcode : le décodeur les confie à un séquenceur de microcode, qui débite les opérations internes de la boucle.
Câblé ou microprogrammé ?
Une unité de contrôle câblée calcule directement les signaux de contrôle avec des portes logiques, à partir de l’opcode et d’un petit compteur d’état. Une unité microprogrammée les lit dans la mémoire de contrôle.
| Câblée | Microprogrammée | |
|---|---|---|
| Vitesse | rapide : pas de lecture de la mémoire de contrôle sur le chemin critique | une lecture de la mémoire de contrôle à chaque cycle |
| Instructions complexes | difficile : chaque cas ajoute de la logique | facile : il suffit d’ajouter du microcode |
| Conception et corrections | tout changement impose de refaire la logique | tout changement revient à réécrire le microprogramme |
| Même jeu d’instructions sur des matériels différents | difficile | naturel |
L’histoire a oscillé entre les deux :
- 1951 : Maurice Wilkes propose la microprogrammation. Une machine simple interprète un jeu d’instructions plus riche, et demande bien moins des tubes à vide peu fiables de l’époque.
- Années 1960–70 : le microcode domine. L’IBM System/360 (1964) s’en sert pour exécuter un même jeu d’instructions sur toute une famille de machines, la plupart microprogrammées, au matériel très différent du modèle le moins cher au plus rapide. Les jeux d’instructions s’enrichissent, et les microprogrammes grossissent et ralentissent.
- Années 1980 : les processeurs RISC abandonnent le microcode. Ils utilisent des instructions simples, exécutées directement par un contrôle câblé, une par cycle.
- Aujourd’hui : le x86 est un hybride.
Le microcode dans un CPU x86 moderne
Un cœur Intel ou AMD actuel n’interprète pas la plupart des instructions par microcode :
- Les décodeurs traduisent chaque instruction x86 en micro-ops (µops) internes, surtout par de la logique câblée. Une instruction simple comme
add eax, ebxdevient une µop.add eax, [rbp-4]devient une µop de chargement plus une µop d’addition. - Les µops décodées sont conservées dans un cache de µops : une boucle très exécutée n’a pas besoin d’être décodée à nouveau.
- Seules les instructions complexes — opérations de chaîne
rep,cpuid, beaucoup d’instructions système — passent par le séquenceur de microcode, qui débite de plus longues séquences de µops depuis une ROM interne.
Notez que les micro-opérations du simulateur sont plus petites que les µops d’Intel. Elles sont plus proches des lignes d’un microprogramme : un transfert de bus ou une opération d’ALU chacune.
Le microcode peut aussi être corrigé. Les fabricants publient des mises à jour de microcode que le firmware ou le système d’exploitation charge à chaque démarrage — la mise à jour n’est pas permanente et doit donc être réappliquée à chaque fois. Sous Linux, la révision courante apparaît sur la ligne microcode de /proc/cpuinfo. Ces mises à jour corrigent des bugs du processeur (errata) et ajoutent des protections de sécurité. Plusieurs défenses contre Spectre, en 2018, ont été livrées ainsi, sous forme de nouveaux registres de contrôle. En 2019, une mise à jour de microcode contre les vulnérabilités MDS a fait qu’une vieille instruction, verw, efface aussi des tampons internes du CPU. Un processeur déjà installé dans votre machine a gagné un nouveau comportement — ce qui n’a de sens que si une partie du CPU est du logiciel.
À retenir
- À chaque cycle, l’unité de contrôle positionne les signaux de contrôle du chemin de données et choisit l’étape suivante.
- Une micro-instruction, ce sont les signaux de contrôle d’un cycle plus une adresse suivante. Le microprogramme réside dans la mémoire de contrôle, adressée par le MPC et lue dans le MIR.
- L’adresse suivante peut être inconditionnelle, conditionnée par l’état de l’ALU, ou un aiguillage sur l’opcode — c’est ainsi que fonctionne le decode.
- Les micro-branchements permettent à une seule instruction de boucler, comme
rep stosb. - Le contrôle câblé est plus rapide ; le microcode facilite les instructions complexes et les corrections. Le x86 moderne décode la plupart des instructions en matériel, utilise le microcode pour les plus complexes, et accepte des mises à jour de microcode au démarrage.