Principes de Fonctionnement
des Ordinateurs
- Conception d'un microprocesseur -

Frédéric Boulanger
frederic.boulanger@centralesupelec.fr

CentraleSupélec
3e année mention Science du logiciel

Conception d'un microprocesseur


Architecture de von Neumann


Les ordinateurs actuels ont une architecture
caractérisée en 1945 par John von Neumann :

  • unité arithmétique et logique (UAL)
  • unité de contrôle (séquençage des opérations)
  • mémoire (données et programmes)
  • dispositifs d'entrée-sortie

Unité arithmétique et logique


Op$_3$Op$_2$Op$_1$Op$_0$Opération
0000S = A
0001S = A $\vee$ B
0010S = $\neg$(A $\vee$ B)
0011S = $\neg$(A $\wedge$ B)
0100S = (A $\wedge$ B)
0101S = B
0110S = $\neg$B
0111S = A$\oplus$B
1000S = A - B
1001S = A + B
1010S = A + A
1011S = A - 1
1100S = A + 1
1101S = FFFF
1110S = 0
1111S = $\neg$A

Registres


Un processeur utilise des registres pour stocker les résultats intermédiaires.
L'accès aux registres est plus rapide que l'accès à la mémoire.

Notre processeur utilise un banc de 8 registres :

os1n° du registre pour out1
os2n° du registre pour out2
isn° du registre à charger avec in
on1indique si le registre os1 est négatif
on2indique si le registre os2 est négatif
oz1indique si le registre os1 est nul
oz2indique si le registre os2 est nul
clkhorloge de chargement de in

Une calculette


En assemblant l'UAL et le banc de registres, on obtient une calculette qui est le cœur de notre processeur :

Circuit

Une calculette avec mémoire


Cette version permet de plus de stocker des valeurs en mémoire :

Circuit

Retour à von Neumann


  • unité arithmétique et logique (UAL)
OK
  • mémoire (données et programme)
OK
  • unité de contrôle (séquençage des opérations)
?
  • dispositifs d'entrée-sortie
plus tard

Unité de contrôle (séquenceur)


  • Décompose l'exécution d'une instruction en étapes
  • Calcule à chaque étape les signaux :
    • de sélection des registres du banc
    • de chargement des registres
    • du code opération de l'UAL
    • de connexion de la mémoire ou des registres à l'entrée B
    • de lecture/écriture en mémoire
  • A besoin de savoir quelle instruction on exécute :
    registre d'instruction RI

Codage des instructions


Les instructions sont stockées en mémoire

Notre processeur doit pouvoir exécuter différentes instructions :

  • chargement d'un registre depuis une case mémoire
  • écriture de la valeur d'un registre dans une case mémoire
  • copie d'une valeur d'un registre à un autre
  • addition ou soustraction des valeurs de deux registres
  • test de conditions :
    • exécuter une instruction si un résultat est nul
    • exécuter une instruction si un résultat est négatif

Accès à la mémoire


  • Chargement d'un registre :
    ldr rx, adresse
    charge le registre
    rx
    avec le contenu de la case mémoire d'adresse
    adresse
    Par exemple, si la case mémoire d'adresse
    0x002C
    contient la valeur
    0x004A
    , l'instruction
    ldr r1, 0x002C
    charge la valeur
    0x004A
    dans le registre
    r1

Accès à la mémoire


  • Écriture d'un registre :
    str rz, adresse
    écrit la valeur du registre
    rz
    dans la case mémoire d'adresse
    adresse
    Par exemple, si le registre
    r2
    contient la valeur
    0x0012
    , l'instruction
    str r2, 0x00AB
    écrit la valeur
    0x0012
    dans la mémoire à l'adresse
    0x00AB

Copie d'une valeur d'un registre à un autre


mov rx, ry
copie la valeur du registre
ry
dans le registre
rx
Par exemple, si
r2
contient
0x0008
, l'instruction
mov r0, r2
place la valeur
0x0008
dans le registre
r0

Addition


add rx, ry, rz
place la somme de
ry
et
rz
dans le registre
rx
Par exemple, si
r0
contient
0x0008
et
r1
contient
0x0002
, l'instruction
add r2, r0, r1
place la valeur
0x000A
dans le registre
r2

Soustraction


sub rx, ry, rz
place la différence de
ry
et
rz
dans le registre
rx
Par exemple, si
r0
contient
0x0008
et
r1
contient
0x0002
, l'instruction
add r2, r0, r1
place la valeur
0x0006
dans le registre
r2

Test de condition


  • cmp rx, ry
    compare les valeurs de
    rx
    et
    ry
  • la comparaison se fait par soustraction :
    rx - ry
  • si le résultat est nul, les deux registres sont égaux
  • si le résultat est négatif,
    rx < ry
  • pour utiliser le résultat de la comparaison, il faut mémoriser la valeur des indicateurs N et Z de l'UAL $\Rightarrow$ registre d'état SR

Branchements


Pour modifier le comportement d'un programme selon le résultat d'une comparaison, on utilise des instructions de branchement :
  • beq adresse
    saute à l'instruction qui se trouve à
    adresse
    si la dernière comparaison a donné un résultat nul
  • beq = Branch if EQual
    le saut se fait si les deux valeurs comparées étaient égales…
  • …donc si l'indicateur Z était à 1
  • On trouve la valeur de cet indicateur dans le registre d'état
  • Exemple :
    
    cmp r0, r1
    beq 0x1F2A
    				  

Branchements


  • blt adresse
    saute à l'instruction qui se trouve à
    adresse
    si la dernière comparaison a donné un résultat négatif
  • blt = Branch if Lower Than
    le saut se fait si la première valeur était inférieure à la deuxième…
  • …donc si l'indicateur N était à 1
  • On trouve la valeur de cet indicateur dans le registre d'état
  • Exemple :
    
    cmp r0, r1
    blt 0x1F2A
    				  

Branchements


  • b adresse
    saute à l'instruction qui se trouve à
    adresse
  • b = Branch
  • Exemple :
    
            cmp r0, r1
            beq 0x1F2A
            % code pour le cas où r0 ≠ r1
            b 0x1F30
    0x1F2A  % code pour le cas où r0 = r1
    0x1F30  % suite du code
    				  
  • Équivalent de : if r0 == r1: ... else: ...

Branchements


Par défaut, les instructions s'exécutent en séquence :
  • quand une instruction est exécutée, on passe à celle qui suit en mémoire
  • il faut donc toujours connaître l'adresse de la prochaine intruction
  • cette adresse est mémorisée dans un registre : le compteur ordinal
    (PC = Program Counter)
  • lors de l'exécution d'une instruction, le PC est incrémenté pour contenir l'adresse de l'instruction suivante
  • lors d'un branchement, on charge l'adresse à laquelle il faut sauter dans le PC

Récapitulons


Instructions

ldr rx, adresse rx $\leftarrow$ Mem[adresse]
str rz, adresse Mem[adresse] $\leftarrow$ rz
mov rx, ry rx $\leftarrow$ ry
add rx, ry, rz rx $\leftarrow$ ry + rz
sub rx, ry, rz rx $\leftarrow$ ry - rz
cmp rx, ry SR $\leftarrow$ N et Z selon rx-ry
beq adresse PC $\leftarrow$ adresse si Z vaut 1 dans SR
blt adresse PC $\leftarrow$ adresse si N vaut 1 dans SR
b adresse PC $\leftarrow$ adresse

Registres

  • Registre d'adresse mémoire RADM
  • Registre d'instruction RI = code de l'instruction à exécuter
  • Registre d'état SR = résultat de cmp
  • Compteur ordinal PC = adresse de la prochaine instruction

Modes d'adressage


Un mode d'adressage est une manière d'indiquer la valeur d'un opérande
  • adressage par registre
    l'opérande est contenu dans un registre :
    mov r0, r1
  • adressage direct
    l'opérande se trouve en mémoire à une adresse qui est directement indiquée :
    ldr r0, 0x25FC
  • autre exemple d'adressage direct :
    beq 0xAB2C
  • adressage immédiat
    l'opérande est donnée immédiatement (sans passer par un registre ou une adresse) :
    add r0, r0, #1
  • autre exemple d'adressage immédiat :
    cmp r1, #2
  • adressage direct par registre
    l'opérande se trouve en mémoire à une adresse contenue dans un registre :
    ldr r0, [r2]
    , ou
    beq r6

Format des instructions


Instructioncodeimmrxryrz
4 bits1 bit3 bits3 bits3 bits3 bits
ldr rx, adresse00001rx
adresse
str rz, adresse00011 rz
adresse
mov rx, ry00100rxry
mov rx, #val00101rx
val
add rx, ry, rz00110rxryrz
add rx, ry, #val00111rxry
val
sub rx, ry, rz01000rxryrz
sub rx, ry, #val01001rxry
val

Format des instructions


Instructioncodeimmrxryrz
4 bits1 bit3 bits3 bits3 bits3 bits
cmp ry, rz01010 ryrz
cmp ry, #val01001 ry
val
beq rz01100 rz
beq adresse01101
adresse
blt rz01110 rz
blt adresse01111
adresse
b rz10000 rz
b adresse10001
adresse

Format des instructions


Conception du séquenceur


  • le séquenceur est chargé de piloter les signaux du chemin de données
  • il reçoit en entrée le code de l'instruction (RI) et les indicateurs (SR)
  • il décompose l'exécution d'une instruction en une suite d'étapes
  • il dispose pour cela d'une horloge :
  • Ti configure la combinatoire (codes UAL, connexions)
  • Pi permet de charger les registres et d'écrire en mémoire

Conception du séquenceur


  • première étape : le fetch
  • il s'agit d'aller chercher le code de l'instruction en mémoire
  • l'adresse de cette instruction se trouve dans le PC
  • il faut placer cette adresse dans le RADM
  • le code de l'instruction apparaît en sortie de la mémoire
  • il faut le charger dans le RI
  • il faut incrémenter le PC

Circuit LogiSim

Conception du séquenceur


Tableau des temps

On indique pour chaque temps :
  • la configuration du chemin de données (signaux Ti)
  • les registres à charger (signaux Pi)
  • pendant le fetch, ça ne dépend pas de l'instruction
  • pour les temps suivants, il faut tenir compte du code de l'instruction

On détermine ainsi le nombre de temps nécessaires à l'exécution des instructions

Tableau des temps

Conception du séquenceur


Équations du séquenceur

À partir du tableau des temps :
  • on détermine quand les signaux doivent être actifs
  • on en déduit les équations des signaux

# Registre
HRADM = P1+P2+P4*(LDR+STR)

# UAL
U0 = T4*IMM+T5*(LDR+STR+BEQ+BLT+B+(MOV*IMM)+ADD)

# Connexions
PCA = T1+T2+T3*IMM
				

À faire lors du premier BE

Suite…

Coder pour un microprocesseur