L'unité de commande#
Nous avons tous les organes d'un processeur, et nous savons ce qu'est un programme : une suite d'instructions que la machine doit chercher, décoder et exécuter, encore et encore. Il manque pourtant le chef d'orchestre : qui dit à chaque composant quoi faire, et surtout quand ? C'est le rôle de l'unité de commande (aussi appelée séquenceur).
Le program counter#
Un compteur est un registre un peu particulier : au lieu d'être chargé de l'extérieur, il réutilise l'additionneur (chapitre « Additionneur ») pour ajouter 1 à sa propre valeur à chaque front montant d'horloge.
Dans notre processeur, ce compteur sert à repérer, une à une, les instructions
du programme à exécuter : c'est pourquoi on l'appelle le program counter (ou
compteur ordinal en français). Il indique à tout moment la position, dans le
programme, de la prochaine instruction. Comme n'importe quel registre, il garde
son entrée de charge LD : elle permet de lui imposer directement une valeur
précise plutôt que de simplement ajouter 1, ce qui servira à « sauter » ailleurs
dans le programme (par exemple pour une boucle).
Dans la démonstration ci-dessous, faites avancer l'horloge : le compteur ajoute
1 à chaque front montant tant que en vaut 1.
Faire agir un composant, c'est lui envoyer un signal#
Reprenons nos composants. Chacun possède, en plus de ses entrées de données, des entrées de commande qui décident de son comportement :
un registre a son entrée de charge
LD: il capture la valeur présente à son entrée au front montant ;un multiplexeur a son entrée de sélection (par exemple
src, qui choisit ce qui entre dans le banc de registres) ;la mémoire a son entrée
écrire;le program counter peut s'incrémenter ou être chargé ;
l'ALU reçoit son code opération.
Faire faire quelque chose au processeur, ce n'est donc rien d'autre que mettre
les bons signaux de commande à 1, au bon moment. Une combinaison précise de
signaux, à un instant donné, réalise une petite action : en général, un registre
capture une valeur, choisie au besoin par un multiplexeur. Tout le travail du processeur
se ramène à une longue suite de ces petits transferts.
Une instruction, plusieurs micro-étapes#
Une instruction ne se fait pas en un seul front montant. On la découpe en une poignée de micro-étapes, chacune réalisée en un front montant. C'est obligatoire : un registre ne capture une valeur qu'au front montant. Une valeur qui doit d'abord être rangée dans un registre n'est donc utilisable qu'à l'étape suivante.
L'étape "Chercher" du cycle est toujours la même, quelle que soit l'instruction. Elle utilise deux registres d'aide : un registre d'adresse qui fournit son adresse à la mémoire, et un registre d'instruction qui retient l'instruction lue (pour que le program counter puisse avancer sans l'effacer).
La mémoire lit à l'adresse contenue dans le registre d'adresse. Il faut donc d'abord charger le registre d'adresse (étape 1) avant que le registre d'instruction puisse capturer l'instruction lue (étape 3). Si l'on chargeait les deux au même front montant, le registre d'instruction capturerait ce que la mémoire présentait avant que le registre d'adresse change : la mauvaise case. En plus, on ne fait qu'une seule action par étape, pour que le déroulement reste facile à suivre.
Dans la colonne « signaux à 1 », LD X signifie « X capture la valeur présente à son entrée au front montant ». src règle le multiplexeur d'écriture, qui choisit ce qui entre dans le banc de registres.
étape |
ce qui se passe |
signaux à |
|---|---|---|
1 |
le registre d'adresse capture la valeur du program counter |
|
2 |
le program counter s'incrémente |
incrémenter |
3 |
le registre d'instruction capture l'instruction lue en mémoire, à l'adresse contenue dans le registre d'adresse |
|
Une fois l'instruction dans le registre d'instruction, son opcode est connu,
et les micro-étapes suivantes dépendent de lui. Prenons LOAD r0, valeur, qui doit
aller chercher sa valeur dans l'octet suivant :
étape |
ce qui se passe |
signaux à |
|---|---|---|
4 |
le registre d'adresse capture la valeur du program counter (l'adresse de la valeur) |
|
5 |
le program counter s'incrémente |
incrémenter |
6 |
le registre |
|
L'instruction est terminée : on repart à l'étape 1 pour la suivante. On voit que exécuter une instruction, c'est dérouler une petite chorégraphie de signaux, fixée d'avance pour chaque opcode.
Le compteur d'étapes#
Pour savoir dans quelle micro-étape on se trouve, le processeur utilise un petit
compteur d'étapes : il compte 1, 2, 3, 4... et il est remis à zéro au
début de chaque nouvelle instruction. Un décodeur transforme sa valeur en une
seule ligne active à la fois : la ligne T1 pendant l'étape 1, T2 pendant
l'étape 2, et ainsi de suite. À chaque front montant, on avance d'une étape.
L'unité de commande : une grande table de décisions#
L'unité de commande est le circuit qui décide, à chaque instant, quels signaux de
commande valent 1. Ses entrées sont l'opcode de l'instruction en cours (lu
dans le registre d'instruction) et l'étape en cours (T1, T2, ...) ; ses
sorties sont tous les signaux de commande du processeur.
L'unité de commande combine l'opcode et l'étape courante pour produire les signaux de commande envoyés à tous les composants.#
Au fond, l'unité de commande n'est qu'une grande table : pour chaque couple
(opcode, étape), elle indique quels signaux mettre à 1. Et une table qui
transforme des entrées en sorties, nous savons la réaliser : avec des décodeurs
(pour reconnaître l'opcode et l'étape) et des portes ET/OU (pour activer
chaque signal dans les bonnes cases). L'unité de commande ne contient donc, elle
aussi, que des circuits déjà connus.
On peut la voir comme un chef d'orchestre qui lit une partition : à chaque temps (l'étape), et selon le morceau joué (l'opcode), il fait signe aux bons instruments (les signaux) d'entrer en jeu. La musique, ce sont les valeurs qui passent d'un registre à l'autre, étape après étape.
Important
Commander le processeur, c'est mettre les bons signaux de commande à
1au bon moment ; chaque front montant réalise une micro-étape.L'unité de commande lit l'opcode et l'étape courante (donnée par un compteur d'étapes + décodeur) et en déduit tous les signaux : c'est une grande table faite de décodeurs et de portes.
Exercices#
Exercice 49#
Le program counter (pc) est un registre spécial : à chaque front montant, s'il n'est
pas chargé (LD = 0), il ajoute 1 à sa valeur. S'il est chargé
(LD = 1), il prend directement la valeur imposée (un saut), au lieu de
s'incrémenter.
Au départ, avant le premier front montant, pc = 0. Voici sept fronts montants successifs, avec la
valeur de LD et, quand elle s'applique, la valeur de saut. Complétez pc
après chaque front montant.
front montant |
|
valeur de saut |
|
|---|---|---|---|
1 |
|
/ |
|
2 |
|
/ |
|
3 |
|
|
|
4 |
|
/ |
|
5 |
|
/ |
|
6 |
|
|
|
7 |
|
/ |
Exercice 50#
Voici l'étape 1 du cycle (commune à toutes les instructions) : le registre d'adresse capture la valeur du compteur ordinal.
Pour chacun des signaux suivants, dites s'il doit valoir 1 ou 0 pendant cette
étape.
charger le registre d'adresse (
LD RA) :incrémenter le
pc:écrire dans la mémoire (
écrire) :charger un registre
r0àr3(LD Rd) :
Exercice 51#
L'instruction ADD r0, r1 s'exécute, après l'étape "Chercher", en une seule
micro-étape (l'étape 4) : l'ALU lit directement r0 et r1 dans le banc de
registres, calcule leur somme, et r0 la charge. Le multiplexeur d'écriture est
réglé sur l'ALU (src = 00). Pour cette étape 4, dites si chaque signal doit
valoir 1 ou 0.
charger le registre
r0(LD Rd) :charger le registre d'instruction (
LD RI) :incrémenter le
pc:charger le registre de sortie (
LD sortie) :
Exercice 52#
Un élève propose de faire toute l'instruction LOAD r0, valeur en un seul front montant
d'horloge, pour aller plus vite : ranger l'adresse de la valeur dans le registre
d'adresse, lire la mémoire et charger r0 en même temps. Expliquez, en vous
appuyant sur le fonctionnement des registres, pourquoi c'est impossible et
pourquoi il faut plusieurs micro-étapes.
Solution
Un registre ne capture une valeur qu'au front montant. Or la mémoire lit à
l'adresse contenue dans le registre d'adresse RA. Il faut donc d'abord ranger
l'adresse de la valeur dans RA, à un front montant. Ce n'est qu'ensuite que la
mémoire présente la bonne valeur à sa sortie, et r0 ne peut la capturer qu'à un
front montant suivant. Si tout se faisait au même front montant, r0
capturerait ce que la mémoire présentait avant que RA change, c'est-à-dire le
contenu de la mauvaise case. Il faut donc au moins deux fronts montants, donc
deux micro-étapes successives.
TP : l'unité de commande et l'assemblage du processeur#
C'est le grand assemblage final : vous allez réunir, dans Logix, tous les blocs construits aux pages précédentes en un processeur complet, puis lui faire exécuter un vrai programme.
Astuce
Nommez vos composants (
pc,RA,RI,ALU...) : un circuit lisible est un circuit réparable.Partez du fichier du TP registres (banc de registres + ALU) et réutilisez votre composant
ALUencapsulé.
L'unité de commande produit, à chaque front montant, les signaux de commande. Les signaux
LD disent quel registre capture au front montant ; src règle le multiplexeur
d'écriture, c'est-à-dire ce qui entre dans Rd (00 : résultat de l'ALU, 01 :
registre Rs, 10 : donnée lue en mémoire) ; op choisit l'opération de l'ALU
(00 : addition, 01 : soustraction, 10 : ET, 11 : OU).
étape |
signaux à |
|---|---|
1 |
|
2 |
incrémenter |
3 |
|
opcode |
étape 4 |
étape 5 |
étape 6 |
|---|---|---|---|
|
|
- |
- |
|
|
- |
- |
|
|
- |
- |
|
|
- |
- |
|
|
- |
- |
|
|
- |
- |
|
|
incrémenter |
|
|
arrêter l'horloge |
- |
- |
Marche à suivre :
Le compteur d'étapes : un compteur suivi d'un décodeur donne les lignes
T1,T2,T3... (une seule active à la fois), avec une remise à zéro en fin d'instruction.L'unité de commande : à partir de l'opcode (décodé) et des lignes d'étapes, produisez chaque signal de commande comme un OU de cas "(cet opcode) ET (cette étape)", en suivant la table ci-dessus. Avancez signal par signal.
L'assemblage : partez du fichier du TP registres (banc de registres +
ALU) et ajoutez :le
program counter(pc) ;le registre d'adresse
RA: son entrée est reliée aupc, sa sortie à l'adresse de laRAM;la
RAM;le registre d'instruction
RI: son entrée est reliée à la sortie de laRAM; ajoutez ses troisSLICE([7:4],[3:2],[1:0]) ;le multiplexeur d'écriture (ALU /
Rs/ mémoire), devant l'entrée de donnée du banc de registres ;un registre de sortie (entrée = lecture
Rd) relié à un afficheur.
Chargez le programme test en mémoire :
adresse contenu binaire signification 0 0001 00 00 LOAD r0, … 1 0000 1101 13 2 0001 01 00 LOAD r1, … 3 0000 0010 2 4 0010 00 01 ADD r0, r1 5 0101 00 00 OUT r0 6 0000 0000 STOP
Remettez
pcet le compteur d'étapes à zéro, lancez l'horloge : le processeur doit charger13dansr0,2dansr1, calculer leur somme dansr0, afficher15, puis s'arrêter.Enregistrez votre processeur. Vous venez de construire un ordinateur.