Académique Documents
Professionnel Documents
Culture Documents
Organisation
o
o
o
o
Mementos et Manuels
o
o
o
o
o
o
Archives tar
o
o
Supports
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
o
Du transistor au processeur
Ce Cours/TP a pour objectif de vous faire comprendre comment est conçu un
processeur à partir de transistors.Il est probable que de terminer ce TP vous
demande environ 2 à 3h de travail en hors-présentiel (exercices 8 et 9). Finir ces
exercices n'est pas nécessaire pour la suite du cours, mais réussir à finir est
relativement satisfaisant puisque vous aurez réussi à concevoir un processeur 8 bits
complet relativement avancé.
Dans ce cours, on suppose que nous sommes sur une île déserte et que nous
devons reconstruire des ordinateurs à partir de zéro. Heureusement, nous avons un
ami physicien sur l'île. Cet ami est capable d'assembler des circuits complexes
construits à partir de transistors, l'élément de base de la plupart des circuits
électroniques. Pour reconstruire un ordinateur, on considère des transistors de type
MOS (Metal-Oxide-Semiconductor) car ce sont ceux aujourd'hui les plus
couramment utilisés pour construire les micro-processeurs. Il existe deux types de
transistors MOS : les transistors nMOS et les transistors pMOS. Dans les
processeurs actuels, on trouve les deux types de transistors, on parle donc de
technologie CMOS (Complementary Metal-Oxide-Semiconductor).
la source, nommée S,
la grille, nommé G.
le drain, nommé D,
Porte NAND
A B Out
0 0 1
0 1 1
1 0 1
1 1 0
.bTable de vérité de la porte logique
.aLa porte logique NAND (credit wikipedia).
NAND.
La construction de la porte logique NAND à partir de portes nMOS et pMOS est
donnée en figure .a, alors que la table de vérité de cette porte est donnée en
figure .b. Dans la figure .a, Vdd est le courant haut qui correspond, par convention, à
la valeur vrai. Vss est le courant bas qui correspond, par convention, à la valeur faux.
Les deux transistors du haut (avec un petit rond sur la grille) sont des pMOS qui
empêchent le courant de passer entre la source et le drain lorsque la grille est
alimentée, alors que les deux transistors du bas (sans petit rond sur la grille) sont
des nMOS qui laissent donc le courant passer entre la source et le drain lorsque la
grille est alimentée.
Vérifiez que le circuit présenté en figure .a met bien en œuvre une porte NAND.Prise
en main du simulateur de circuit
Connexion
Maintenant que vous avons notre première porte logique, nous pouvons l'utiliser
pour construire les autres portes logiques. Avant de nous lancer dans cette mise en
œuvre, nous prenons en main l'environnement de développement que nous
utiliserons pour créer des circuits.
Dans un navigateur Web, connectez-vous au site https://circuitverse.org/simulator.
Ce site permet de construire des circuits logiques de façon conviviale. De façon à
pouvoir enregistrer vos travaux, il faut créer un compte. Pour créer un compte,
cliquez sur
Sign In
. Ensuite, cliquez sur
New user? Sign up
. À partir de ce point, vous pouvez soit créer un nouveau compte, soit, si vous en
avez un, utiliser votre compte
google
ou votre compte
facebook
pour vous authentifier.
Maintenant que vous avez un compte, vous pouvez entrer dans le simulator. Cliquez
sur le menu
Simulator
qui se trouve en haut de la fenêtre. Vous pouvez commencer à configurer votre
projet. Donnez lui un nom, par exemple
CSC4536
, en modifiant la partie
Project Properties
se trouvant en bas à gauche de la fenêtre.
Les entrées
Avant d'aller plus loin, nous allons placer un premier élément dans notre circuit.
Allez dans l'onglet
Input
se trouvant à gauche de la fenêtre et sélectionnez la première icône (lorsque vous
passez dessus avec la souris, vous devriez voir
Input
). Déplacez votre souris sur l'espace de travail (la grille se trouvant à droite de la
fenêtre), et cliquez quelque part. Félicitations, vous avez construit une
entrée binaire
! Vous devriez constatez que, lorsque vous cliquez sur votre entrée binaire, vous
pouvez la faire passer de 0 à 1 et inversement.
Enregistrement
Avant d'aller plus loin, nous allons vérifier que nous pouvons bien sauver notre
travail. Dans le menu
Project
, cliquez sur
Save Online
, ce qui va créer une sauvegarde de votre projet hébergée sur le serveur (vous
pouvez aussi enregistrer votre travail hors-ligne avec
Save Offline
). Pour vérifier que tout s'est bien passé, allez dans la configuration de votre compte
représenté par votre nom d'utilisateur en haut à droite de la fenêtre, et cliquez sur
My circuits
. Vérifiez que vous retrouver bien votre projet et cliquez sur
Launch
pour relancer le simulateur.
Déplacer un élément
Avant de se lancer dans des conceptions plus intéressantes, nous allons juste
apprendre à créer un circuit simple constitué d'une unique porte logique NAND. Vous
trouverez cet élément dans l'onglet
Gates
à gauche de la fenêtre. Dans un premier temps, ajoutez une seconde entrée et une
porte logique NAND. Vous devriez remarquer que, lorsque vous passez sur un
élément dans l'onglet Gates, son nom s'affiche. Vous devriez aussi remarquer que,
lorsque vous cliquez sur un élément placé dans l'espace de travail, vous pouvez le
déplacer.Pour déplacer un élément, il faut cliquer à l'intérieur de l'élément et non sur
les petits points verts se trouvant sur le bord et représentant les points de
connexions.
Nous allons maintenant apprendre à connecter les deux entrées à la porte logique.
Pour connecter deux éléments, il faut créer un fil électrique entre ces éléments. Les
points de connexions sont représentés par les points verts se trouvant sur le bord
d'un élément. Lorsque vous cliquez sur un point de connexion et que vous déplacez
votre souris, vous commencez à créer un fil. Connectez les entrées à la porte NAND.
Sorties
Pour finir, nous allons créer une sortie permettant de visualiser le résultat du calcul
effectué par notre porte NAND. Dans l'onglet
Output
à gauche de l'écran, sélectionnez le premier élément (nommé
Output
). Cet élément, que nous appellerons une sortie binaire, permet d'afficher l'état d'un
fil électrique (0 ou 1). Ajoutez une sortie binaire et connectez la sortie de la porte
NAND à cette sortie. Vous devriez obtenir le circuit présenté en figure . Vérifiez, en
modifiant les entrées, que votre circuit respecte bien la table de vérité de la porte
NAND. Vous devriez remarquer qu'un fil alimenté (valeur 1) apparaît en vert clair
alors qu'un fil non alimenté (valeur 0) apparaît en vert foncé.
Un circuit NAND.
Pour continuer cette prise en main de l'outil, nous allons apprendre à mettre un
circuit en court circuit, c'est-à-dire que nous allons à la fois mettre les valeurs 0 et 1
sur un fil. Il ne faut bien sûr jamais mettre un circuit en court-circuit, cette question n'a
que pour but de vous montrer ce qui se passe, ce qui va vous permettre d'identifier
les erreurs dans vos circuits.
Pour réaliser ce court circuit, cliquer quelque part sur le fil reliant une des entrées à
la porte NAND, ce qui permet de démarrer un second fil à partir de ce point.
Construisiez un fil qui contourne entièrement la porte (par le bas si vous partez du
bas ou par le haut sinon). Pour cela, il faut construire plusieurs fils. Vous devriez
obtenir le résultat présenté en figure . Vous devriez voir des messages s'afficher en
bas de la fenêtre vous indiquant qu'il y a un problème. Vous devriez aussi voir que le
fil reliant la porte à la sortie est à moitié vert foncé et à moitié vert clair, et que le
simulator vous a ajouté de petits rond aux points de connexions qui permettent de
remonter à l'origine du problème (sur le haut de la figure dans le cas de la figure ).
Suppression d'éléments
Nous allons réparer notre circuit en détruisant le court-circuit. Pour cela, cliquez sur
un fil et appuyez sur la touche
backspace
(retour arrière se trouvant en haut à droite de votre clavier), ce qui détruit un
élément. Supprimez tous les fils réalisant le court-circuit.
Pour finir notre prise en main, nous apprenons à déplacer plusieurs éléments. Pour
cela, il suffit d'effectuer une sélection en appuyant sur la touche
Shift
(remarquez que si vous n'appuyez pas sur la touche
Shift
alors que vous cliquez sur une zone sans éléments avant de déplacer la souris,
vous déplacez simplement la grille). Ensuite, vous pouvez, en cliquant sur l'un des
éléments sélectionnés , déplacer l'ensemble de ces éléments.De la porte NAND aux
autres portes logiques
Le but de cet exercice est de construire les portes logiques manquantes à partir de
la porte logique NAND. Les tables de vérités et les icônes associées aux portes que
vous devez construire sont présentées en figure .
Porte OR
Porte Porte Porte Porte
NOT AND NOR XOR
Porte
XNOR
O O O O O
a b a b a b a b a b
ut ut ut ut ut
Ou 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1
a
t 0 1 0 0 1 1 0 1 0 0 1 1 0 1 0
0 1 1 0 0 1 0 1 1 0 0 1 0 1 1 0 0
1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1
L'additionneur (∼ 80mn)
Le demi-additionneur 1 bit
Comme première étape, nous allons réaliser un circuit permettant d'additionner deux
bits (un bit est une valeur binaire, pouvant donc prendre les valeurs 0 ou 1).
Exactement comme on le fait en décimal, il peut il y avoir une retenue (carry en
anglais), donc votre circuit doit produire un résultats sur deux bits :
0 + 0 donne 0 et je retiens 0,
0 + 1 donne 1 et je retiens 0,
1 + 0 donne 1 et je retiens 0,
1 + 1 donne 0 et je retiens 1 (comme 5 + 5 donne 0 et je retiens 1 en décimal),
a b s cout
0 0 0 0
0 1 1 0
1 0 1 0
1 1 0 1
Table de vérité d'un demi-additionneur.
La figure vous donne la table de vérité de l'additionneur. Les entrées
a
et
b
sont les nombres à additionner alors que
s
est la somme et
cout
la retenue.
Commencer par supprimez tous vos anciens circuits. À partir de cette étape, ne
détruisez plus jamais aucun des circuits que nous aurons réalisés : il vont tous nous
resservir à un moment où un autre.
Ensuite, réalisez le circuit permettant d'effectuer une addition binaire.
Réutilisation d'un circuit
De façon à additionner plusieurs bits, nous aurons besoin de réaliser plusieurs fois
le circuit d'addition d'un unique bit. Notre logiciel de simulation permet de réutiliser
des circuits qui ont déjà été mise en œuvre.
Pour rendre votre circuit réutilisable, commencez par donner un nom à vos entrées
et à vos sorties. Pour cela, sélectionnez une des entrées. Dans la partie gauche de
la fenêtre, vous devriez voir apparaître une zone
Properties
. À la ligne
Label
, donnez un nom à vos deux entrées (
a
et
b
). De la même façon, donnez des noms à vos deux sorties (
s
pour la somme et
cout
pour la retenue).
Ensuite, vous pouvez donner un nom à votre circuit. Pour cela, cliquez n'importe où
sur la grille en dehors de tout élément. Ensuite, dans
Project Properties
, remplacez le nom actuel du circuit (ligne
Circuit
indiquant
Main
) en
half-add
. Le nom que vous voyez au dessus de la grille devrait changer de façon adéquate.
Enfin, cliquez sur
Edit layout
en bas à gauche de la fenêtre, ce qui vous permet de modifier l'apparence de votre
circuit quand vous le réutilisez. Nous vous conseillons de laisser les entrées à
gauche et les sorties à droite. Nous vous conseillons aussi de mettre
a
en haut et
b
en dessous, et
s
en haut et
cout
en haut bas. Enfin, nous vous conseillons de laisser deux carreaux entre les entrées
ou entre les sorties. Après avoir donné l'apparence qui vous plaît à votre circuit,
appuyez sur
Save
pour revenir sur le schéma du circuit. Pensez à sauver votre travail (menu
Project->Save Online
).
L'additionneur 1 bit
Comme on le fait en décimal, quand on effectue un calcul sur plusieurs digits, il faut
non seulement additionner les deux digits courants, mais il faut aussi additionner ce
résultat avec la retenue de l'étape précédente. Nous réalisons donc ce circuit à cette
étape. Créez un nouveau circuit (menu
Circuit->New circuit
) que vous nommerez
1-add
(pour additionneur 1 bit).
Ajoutez 3 entrées nommées
a
,
b
et
cin
(retenue d'entrée provenant de l'étape précédente). Ajoutez aussi 2 sorties
nommées
s
pour la somme et
cout
pour la retenue de sortie.
Enfin, utilisez des circuits
half-add
(menu
Circuit->Insert SubCircuit
) pour que
s
soit égal à la somme de
a
,
b
et
cin
, et que
cout
soit égal à la retenue de cette somme. Du bit à l'entier
L'entrée 8 bits
De façon à pouvoir créer un additionneur capable d'effectuer des additions sur des
nombres encodés sur 8 bits, nous commençons par créer une entréee 8 bits. Créez
un nouveau circuit nommé
8-add
. Dans ce circuit, ajoutez une entrée. Si vous sélectionnez cette entrée, vous devriez
voir apparaître ses propriétés. Donnez la valeur 8 à la propriété
BitWidth
de façon à ce que l'entrée soit une entrée avec 8 bits. Donnez le nom
a
à votre entrée.Si vous n'êtes pas à l'aise avec la représentation des nombres en
binaire et en hexadécimal, cliquez sur l'aide.
Le simulateur
circuitverse
permet d'afficher un nombre 4 bits facilement. Pour utiliser cette fonctionnalité, nous
avons donc besoin de séparer notre nombre 8 bits en deux nombres sur 4 bits, l'un
avec les 4 bits de poids fort, et l'autre avec les 4 bits de poids faibles. Dans l'onglet
Misc
, sélectionnez un
Splitter
(deuxième icône). Quand
circuitverse
vous demande la taille du nombre, mettez 8 puisque votre nombre fait 8 bits.
Ensuite, il faut donnez la décomposition de notre nombre. Nous voulons deux
groupes de 4 bits, donc saisissez 4 4, ce qui construit 2 sorties de 4 bits. Connectez
le
Splitter
à
a
. Ensuite, dans l'onglet
Output
, sélectionnez
HexDisplay
(5ième icône) et placez deux
HexDisplay
à côté de votre
Splitter
. Connectez les 4 premiers bits du
Splitter
au second
HexDisplay
et les 4 derniers bits au premier
HexDisplay
. Vous devriez obtenir le circuit présenté en figure .
HexDisplay
et un
Splitter
cin
sur 1 bit que vous devez ajouter. Cette entrée donne la retenue initiale, qui
est bien sûr égale à 0 pour une addition, mais vous verrez dans les questions
suivantes comment exploiter cette entrée pour faire des soustractions.
Le multiplexeur (∼ 30mn)
Dans un circuit, il arrive souvent d'avoir besoin de sélectionner une entrée parmi N
en fonction d'une valeur. Ce mécanisme peut par exemple être utilisé pour
sélectionner les registres qui participent à une instruction. Dans cet exercice, nous
mettons un œuvre des multiplexeurs dont le rôle est justement de sélectionner une
entrée parmi N.
2x1-mux
2x8-mux
2x3-mux
Sur le modèle de
2x8-mux
, construisez un nouveau circuit nommé
2x3-mux
prenant en entrée 2 valeurs sur 3 bits nommées x0 et x1, et un sélecteur sur un bit.
Le circuit doit renvoyer x0 si sel vaut 0 et x1 sinon.Travailler sur des entiers encodés
sur 3 bits peut vous sembler inattendu. Il faut comprendre qu'avec 3 bits, on peut
encoder 23 = 8 valeurs. Comme à terme, notre processeur possédera 8 registres,
nous aurons donc besoin de manipuler des numéros de registre encodés sur 3 bits.
Le
2x3-mux
permettra donc de sélectionner des numéros de registres.
8x8-mux
À partir de
2x8-mux
, construisez un circuit
8x8-mux
permettant de sélectionner une entrée parmi 8, chacune des entrées faisant 8 bits.
Un entier
Un entier
Un entier
func
encodé sur 16 bits qui indiquera l'opération à effectuer avec
et
En sortie,
ALU
doit renvoyer uniquement le résultat de l'opération, c'est-à-dire un entier
out
encodé sur 8 bits.
Une ALU complète renverrai aussi un drapeau indiquant comment s'est déroulée
l'opération, par exemple, est-ce qu'il y a eu un dépassement de capacité ou une
division par zéro.
L'entrée
func
doit être analysée de la façon suivante :
ALU
dans le futur.
,
et
out
Bit 9 : indique si il faut injecter artificiellement une retenue pour l'addition,
Bits 10 et 11 : indique l'opération de comparaison de base à effectuer (égal
pour le bit 10, ou inférieur strictement pour le bit 11).
Bit 12 : indique si il faut inverser le résultat de l'opération de comparaison
effectuée.
Bits 13 à 15 : réservés pour un usage futur.
De façon à décomposer
func
, ajoutez un
Splitter
16 vers 3 3 suivi de dix 1. Les 6 premiers bits vont être utilisés pour sélectionner
l'opération effectuée en se servant de circuits
8x8-mux
. Il faut donc décomposer ces 6 bits en 2 fois 3 bits puisque le sélecteur d'un
8x8-mux
est encodé sur 3 bits. Comme nous n'avons que 3 opérations, nous nous servirons
des 3 premiers bits, mais nous allons ignorer les 3 bits suivants réservés pour de
futurs usages. Les 10 bits qui suivent (6 à 16) vont permettre de gérer les autres
comportements du circuit
ALU
.
Ajoutez un
8-add
et connectez y directement les entrées
a
et
b
et la sortie
out
. Ajoutez des
HexDisplay
avec des
Splitter
8 vers 4 4 pour afficher les valeurs de
a
,
b
et
out
. Connectez aussi le bit 9 de
func
au
cin
de
8-add
. Vérifiez que, quand ce bit 9 est à 0, votre circuit effectue bien une addition.La suite
de l'exercice qui permet de compléter le circuit
ALU
est optionnel et prend environ 90mn (en plus des 2/3h de travail personnel annoncé
en début d'exercice). Appuyez sur détails si vous voulez voir les questions.
Le registre (∼ 60mn)
Maintenant que nous sommes capables d'effectuer des calculs, il faut pouvoir
stocker dans le processeur des variables internes. Pour cela, nous construisons des
registres. Un registre est un circuit possédant principalement une entrée nommée
in
et une sortie nommée
out
. Selon son état, le registre est capable de copier l'entrée
in
sur la sortie
out
ou de mémoriser la sortie
out
indépendamment de l'état de l'entrée. Ce phénomène de mémorisation permet au
registre de conserver un état dans le temps, et donc d'agir comme une mémoire.Le
verrou SR NAND
Dans un nouveau circuit nommé
SR-nand
, reproduisez le circuit constitué de deux portes NAND présenté en figure . Ce circuit
s'appelle un verrou SR (pour Set et Reset) NAND (SR NAND latch en anglais).
Le verrou SR NAND.
Dans quels états sont Q et Q' quand S vaut 0 et R vaut 1 ? Et quand S vaut 1 et R
vaut 0 ?
On suppose que, initialement, S = 0 et R = 1. Dans quel état est le circuit si S passe
à 1 ? Donnez exhaustivement l'ensemble des valeurs Q et Q' possibles en étudiant
les différentes propagations possibles de l'électricité. Pour cela, étudiez le cas où la
porte
NAND
du haut est la première à s'activer et le cas où la porte
NAND
du bas est la première à s'activer.
On suppose que, initialement, S = 1 et R = 0. Dans quel état est le circuit si R passe
à 1 ? De la même façon étudiez les différentes possibilités de propagation de
l'électricité.Le bascule JK
Comme vous avez du le constater, quand S = 1 et R = 1, on peut avoir Q = 1 et Q' =
0 si on vient de l'état S = 0 et R = 1, ou Q = 0 et Q' = 1 si on vient de l'état S = 1 et R
= 0. Cette propriété est très forte car elle signifie qu'on peut "bloquer" la sortie du
circuit à 1/0 ou 0/1 quand on passe S et R à 1. Pour exploiter cette propriété, on va
un petit peu améliorer notre circuit. Dans un nouveau circuit nommé
JK-flip-flop
, reproduisez le circuit présenté en figure . Ce circuit s'appelle une bascule JK (JK
flip-flop en anglais). Le nom JK semble venir du nom du concepteur de ce circuit
(Jack Kirby). La bascule JK (Circuit
JK-flip-flop)
Mettez l'entrée E (Enable) à 1. Dans quels états sont Q et Q' si J = 1 et K = 0 ? Dans
quels états sont Q et Q' si J = 0 et K = 1 ?
Mettez E = 1, J = 0 et K = 1. Passez E à 0. Que se passe-t-il si vous changez les
valeurs de
J
ou de
K
? Expliquez. De la même façon mettez E = 1, J = 1, K = 0. Passez E à 0. Que se
passe-t-il si vous changez les valeurs de
J
ou de
K
? Expliquez.Le registre 1 bit
Comme vous l'avez sûrement déjà compris, si K est l'opposé de J, alors, quand E
vaut 1, l'entrée J est recopiée dans Q. E permet aussi de bloquer le circuit : quand E
passe à 0, l'état de Q ne change plus, même quand J ou K change. En d'autres
termes, l'état du
JK-flip-flop
"mémorise" l'ancienne valeur de J. On va exploiter cette propriété pour construire
une première version du registre 1 bit. Créez un nouveau circuit que vous
nommerez
1-reg
. Ajoutez deux entrées à ce circuit :
in
clock
clock
reinit
clock
in
vers
out
Mettez
clock
à 0 et
WE
à 1,
Passez
reinit
à 1 et vérifiez que
out
vaut
Passez
reinit
à 0 et vérifiez que
out
vaut toujours
Passez
clock
à 1 et vérifiez que
out
in
Passez
WE
in
. Vérifiez que
out
clock
Félicitations, même si nous serons amenés à modifier légèrement le registre 1 bit par
la suite, vous avez construit un superbe registre 8 bits ! Vous avez maintenant la
possibilité d'ajouter des variables internes à votre processeur !
Nous avons maintenant créé pratiquement tous les circuits de base permettant de
construire un processeur complet. Avant de se lancer dans cette mise en œuvre
complète, il faut comprendre comment notre processeur va fonctionner.
Pour commencer, notre processeur a une mémoire de 16 cellules numérotées de 0 à
15. Une cellule mémoire contient un octet (une valeur sur 8 bits), et nous
réutiliserons les registres 8 bits pour mettre en œuvre les cellules.
Ensuite, notre processeur possède 8 registres internes numérotés de 0 à 7. Chaque
registre fait 8 bits, notre processeur est donc un processeur 8 bits. Pour bien
comprendre la différence entre les registres internes et la mémoire, il faut savoir que
la mémoire est un composant séparé du processeur et que notre processeur ne peut
que :
LD
),
écrire la valeur d'un registre interne dans une cellule mémoire (instruction
ST
).
Trois des registres du processeur ont un rôle particulier qui sera expliqué dans la
suite. Les cinq autres sont libres et permettent d'effectuer des calculs.
Le premier registre particulier est le 7ième registre qui se nomme
pc
(Program Counter). Ce registre indique le numéro de cellule mémoire qui contient la
prochaine instruction à exécuter. Notre processeur offre deux types d'instructions.
Où :
op
out
i0
i1
Quand l'instruction est sous la forme triplet, elle effectue un calcul avec les registres
i0
et
i1
, puis stocke le résultat dans le registre
out
. Par exemple, l'instruction
2 3 1 2
sous la forme triplet est une addition (puisque
op
vaut 2) qui ajoute la valeur du registre numéro 1 avec la valeur du registre numéro 2
puis stocke le résultat dans le registre numéro 3.
Quand l'instruction est sous forme accumulateur, elle effectue un calcul avec un
registre accumulateur (le registre
out
) et la valeur directe encodée sur 8 bits. Par exemple, l'instruction
2 3 1
sous la forme accumulateur est une addition (puisque
op
vaut 2) qui ajoute 1 au registre numéro 3.
Pour encoder une instruction, nous avons besoin de 16 bits :
Premier octet
o op
est encodé sur 4 bits (bits 0 à 3), ce qui permet de définir jusqu'à 32
instructions. Dans notre processeur, nous ne définirons que 3
instructions de base, n'hésitez pas à en ajouter en fonction de vos
envies après avoir terminé l'exercice,
o Le bit 4, appelé
accu?
val
,
o Sinon, cet octet se décompose de la façon suivante :
Les bits 0 à 2 donnent
i0
i1
pc
dans le registre
insnl
ajoute 1 à
pc
pc
dans le registre
insnh
ajoute 1 à
pc
insnl
et
insnh
.
Il n'y a pas de question dans cet exercice.
Dans cet exercice, nous concevons les circuits qui permettent de gérer les registres
et la mémoire de notre processeur. D'un point de vu technique, nous mettons en
œuvre les registres du processeur et la mémoire avec des registres. Bien que le
circuit de base utilisé pour construire les registres et la mémoire soit le même, il
existe trois différences fondamentales entre ces objets :
Une instruction peut lire jusqu'à 2 registres pendant un cycle. C'est le cas des
instructions sous la forme triplet,
Une instruction peut écrire au plus un registre pendant un cycle. C'est le cas
d'une instruction de calcul qui utilise l'ALU, comme l'instruction
ADD
LD
qui permet de lire une cellule mémoire et de stocker sa valeur dans un
registre.
ST
qui ne fait que écrire la valeur d'un registre dans une cellule mémoire. Il faut
donc être capable de désactiver les écritures sur le
8x8-regs
au besoin.
Le démultiplexeur
Pour sélectionner jusqu'à deux registres d'entrées d'une instruction dans le
8x8-regs
, nous disposons déjà du circuit
8x8-mux
. En revanche, pour sélectionner le registre écrit par une instruction, il nous manque
un circuit. En effet, il faut être capable d'activer l'entrée WE de l'un des huit registres
du
8x8-regs
en fonction d'un numéro de registre encodé sur 3 bits (3 bits suffisent pour énumérer
8 = 23 valeurs).
À cette question, on vous demande donc de mettre en place un démultiplexeur. Un
démultpléxeur possède une entrée nommée
sel
sur N bits et 2N sorties numérotés de
x0
à
xn-1
. Si l'entrée vaut K, alors le démultiplexeur passe la sortie
xK
à vrai et laisse les autres à faux. Un démultiplexeur a aussi une seconde entrée
nommée
enable
qui, lorsqu'elle vaut 0, désactive le multiplexeur. Dans ce cas, le démultiplexeur
n'active aucune sortie.
Mettez en œuvre le circuit
8-demux
dans lequel
N=3
(c'est-à-dire 2N = 8).
Un banc de 8 registres
à
v7
si0
et
si1
sont les numéros des deux registre lus par l'instruction courante (3 bits),
sout
vout
WE
reinit
v0
à
v7
) (1 bit),
clock
à
r7
vi0
et
vi1
si0
et
si1
bits pour
address
data
sur 8 bits : la valeur écrite dans l'adresse si l'instruction en cours est une
écriture mémoire (instruction
ST
),
WE
reinit
clock
En sortie,
MEM
renvoie la valeur se trouvant à l'adresse
address
.
Initialement, nous vous proposons de placer un programme directement dans la
mémoire. Ce programme assez simple incrémente la 15ième cellule mémoire. Si on
suppose que la cellule 15 contient la valeur d'une variable
x
initialisée à 128 (0x80 en hexadécimal), le code exécuté par notre programme serait
à peu près celui là en Java :
do {
x = x + 1;
} while(true);
À bas niveau, voici les valeurs initiales que doit contenir la mémoire pour exécuter ce
programme :
Octet 0 : 000 1 0010
Octet 1 : 00001111 => ajoute 15 à r0 (r0 valant initialement
0, r0 vaut 15 en sortie, c'est-à-dire
le numéro de la cellule contenant la
variable
x
)
Octet 2 : 001 0 0000
Octet 3 : 00 000 000 => charge la cellule se trouvant en r0
dans r1
(charge la 15ième cellule car r0 = 15)
Octet 4 : 001 1 0010
Octet 5 : 00000001 => ajoute 1 à r1
Octet 6 : 000 0 0001
Octet 7 : 00 001 000 => écrit r1 dans la cellule r0 (adresse
de
x
)
Octet 8 : 111 1 0010
Octet 9 : 11111000 => ajoute 248 à pc
(comme pc = 10 avant d'exécuter
l'instruction, pc + 248 = 258 modulo 256 = 2
=> saute à l'octet 2, ce qui permet de
boucler)
Octets 10 à 14 : 00000000
Octet 15 : valeur initiale de x, mettez 01110000 (0x80 en
hexadécimal)
Le processeur (∼ 120mn)
Le microcode
et
insnh
insnl
et
insnh
. Après avoir exécuté le chargement de ces registres, le circuit va simplement
renvoyer ces valeurs,
reinit
et
clock
mini-pc
Le décodeur d'instruction
insnh
ALU
wm?
ST
(valeur 1). Pour identifier ce cas, il faut isoler les bits qui donnent l'instruction,
c'est-à-dire les 4 premiers de
insnl
8-demux
ST
). Un seul
8-demux
piloté par les 3 premiers bits du numéro d'instruction est nécessaire puisque
nous n'utilisons pas le 4ième bit du numéro d'instruction.
wr?
est vrai lorsque l'instruction écrit dans un registre, c'est-à-dire si l'instruction
n'est pas
ST
alu?
indique quelle valeur doit être utilisée pour écrire dans un registre quand
wr?
MEM
quand
alu?
ALU
quand
alu?
LD
MEM
alu?
x0
du
8-demux
cst?
accu?
(4ième bit de
insnl
op rout, val
rout
sout
insnl
).
si0
LD
et
ST
ALU
. Dans le cas d'une instruction au format triplet (c'est-à-dire quand le bit 4 de
insnl
insnh
sout
si1
ST
ADD
insnh
vi1
si1
cst?
insnh
Le processeur
Vous pouvez enfin mettre en œuvre votre processeur. Vous avez besoin de deux
entrées :
reinit
et
clock
. Tout le reste sera généré par les autres circuits. Vous avez besoin des circuits
suivants :
Un circuit
MICROCODE
Un circuit
DECODER
connecté à
MICROCODE
Un circuit
REGS
si0
,
si1
,
sout
et
wr?
généré par
DECODER
(l'entrée
vout
2x8-mux
cst?
vi1
de
REGS
vi1
de
DECODER
Un circuit
ALU
vi0
de
REGS
2x8-mux
func
générée par
DECODER
.
Un circuit
MEM
vi0
2x8-mux
précédent comme
data
et le
wm?
de
DECODER
comme entrée
WE
Un circuit
2x8-mux
MEM
en
x0
, la sortie de
ALU
pour
x1
, et la sortie
alu?
de
DECODER
vout
de
REGS
puisque, si
wr?
est vrai, c'est la sortie de ce circuit qu'on veut enregistrer dans le registre de
sortie.
Ce circuit étant légèrement complexe, surtout parce que des bugs de mise en œuvre
provenant d'autres circuits vont apparaître, nous vous conseillons vivement d'utiliser
des
HexDisplay
pour afficher l'état des registres, la valeur
v0/adresse
utilisée en entrée de
ALU
/
MEM
, la valeur
v1/data
utilisée en entrée de
ALU
/
MEM
et la valeur
vout
envoyée dans
REGS
. Vous pouvez aussi afficher la case mémoire 15 pour voir l'état de cette case
mémoire évoluée au cours du temps (il faut alors ajouter une sortie à
MEM
pour pouvoir connaître cette valeur). Au démarrage, cette valeur devrait prendre la
valeur 0x80 et être incrémentée régulièrement pas le programme. N'hésitez pas
aussi à afficher l'état du
minipc
de
MICROCODE
en ajoutant une sortie à ce circuit. Bon courage !Si vous êtes arrivé au bout de cet
exercice, bravo ! Vous savez construire un processeur de bout en bout !Depuis la fin
des années 70, on n'écrit plus de processeur directement avec des portes logiques,
sauf pour comprendre sa mise en œuvre comme dans cet exercice. En effet, dans
notre exercice, nous avons fait l'hypothèse que
MEM
avait la même fréquence que le reste du processeur, et que
ALU
était capable d'effectuer un calcul en moins d'un demi-cycle. Dans des machines
réelles, ce n'est pas le cas. Il faut donc synchroniser des circuits qui effectuent des
opérations à différentes vitesses avec la même horloge, voir des circuits qui ont des
horloges différentes quand on communique entre la mémoire et le processeur (on
parle de circuit multi-clock domains). Comme gérer ces synchronisations à la main
devient rapidement très difficile, on utilise aujourd'hui des langages plus expressifs
comme VHDL ou Verilog.
Telecom SudParis
Institut Polytechnique de Paris
9, rue Charles Fourier
F-91011 Evry Cedex France