Introduction et utilisation d'un chemin de données : séquencement manuel

Introduction

Le but de ce premier BE est d'introduire un chemin de données qu'on va utiliser tout au long du cours et des BE/TP. On introduit progressivement des éléments de logique combinatoire et de logique séquentielle avec le but utiltime de cette séance d'être capable de piloter à la main le chemin de données pour lui faire réaliser quelques opérations. Nous verrons durant les séances suivantes comment automatiser le pilotage du chemin de données ainsi que quelques extensions de ce chemin de données. On va voir notamment:

Logisim est installé sur les postes de travail. Lisez la page principale pour savoir comment le démarrer plus 2/3 autres indications.

Charger des registres et effectuer des opérations arithmétiques

Lancement de logisim et chargement de l'architecture

On considère dans un premier temps l'architecture ci-dessous. Téléchargez les fichiers csmetz2015.jar et archi_seq_man_regual.circ et placez les dans le même répertoire. Lancez logisim et chargez le fichier archi_seq_man_regual.circ. L'architecture chargée est représentée ci-dessous.

Avant de jouer avec cette architecture, je vous propose de décrire rapidement quelques éléments de l'interface logisim.



Vos outils principaux dans ce TP sont le "poke tool" et l'horloge. Le poke tool, la petite main en haut à gauche de l'interface, permet de modifier la valeur des entrées, cliquer sur les boutons, .... L'horloge est activée en appuyant sur les touches "Ctrl + t", le petit symbole de l'horloge indiquant si elle est à un niveau haut ou bas. Appuyer sur Ctrl + t déclenche une transition de niveau bas vers niveau haut ou niveau haut vers niveau bas.

Présentation de l'architecture

L'architecture proposée est constituée :

La circulation des données sur les bus A, B et S est autorisée par des buffers contrôlés par un signal de contrôle particulier. Par exemple, pour charger le registre A, il faut placer des données sur le bus S, autoriser le chargement du registre (SetA), et déclencher un front montant d'horloge.

En plus des signaux Zero (Z), Retenue (Carry) et de débordement (V), l'UAL fournit 11 opérations décrites dans la table ci-dessous:

U3 U2 U1 U0 Opération
0 0 0 0 S = A
0 0 0 1 S = B
0 0 1 0 S = A ET B
0 0 1 1 S = A OU B
0 1 0 0 S = non(A)
0 1 0 1 S = non(B)
0 1 1 0 S = A + B
0 1 1 1 S = A - B
1 0 0 0 S = A + 1
1 0 0 1 S = A - 1
1 0 1 0 S = A * B
1 0 1 1 S = A >> 1
x x x x S = Erreur

Travail à réaliser

En utilisant les signaux de contrôle et l'entrée Data, réalisez les opérations suivantes les unes après les autres. Je vous conseille de remettre à zéro tous les signaux de contrôle avant de passer à l'instruction suivante.

Connecter le chemin de données avec une mémoire RAM

On introduit maintenant une mémoire dans le chemin de données depuis laquelle on va charger des données et dans laquelle on va également écrire des données: archi_seq_man.circ. Pour ce faire, on modifie un peu le chemin de données en ajoutant une RAM et deux registres : PC (Program counter) et RADM (Registre d'ADresse Mémoire). On ajoute aussi quelques afficheurs.



La RAM ainsi que les afficheurs sont adressables. Cela veut dire qu'on peut lire/écrire dans la RAM et écrire dans les afficheurs. Pour une lecture, on commencera par 1) placer l'adresse du mot à lire dans le registre RADM, 2) déclencher la lecture avec le signal ReadMem. Pour une écriture, on commencera par 1) placer l'adresse du mot à écrire dans le registre RADM, 2) placer les données à écrire sur le bus S et déclencher l'écriture avec le signal SetMem. Les afficheurs sont dits mappés en mémoire (on verra un plus en détails ce que cela signifie plus tard), c'est à dire qu'ils ont des adresses particulières: Ne vous laissez pas dérouter par le plat de spaghettis de connexions autour de la mémoire et des afficheurs, en pratique, si je veux afficher le contenu du registre A sur le premier afficheur, je procéderais ainsi : Si je veux charger, dans le registre A, le contenu de la RAM à l'adresse 0x0010, je procéderais ainsi : Si je veux écrire le contenu du registre A dans la RAM à l'adresse 0x0010, je procéderais ainsi : Dans le travail que je propose de réaliser, nous allons charger des opérandes en mémoire à partir d'un fichier (bouton droit sur la RAM, "charger l'image" et choisir par example seq_man.mem) ou bien en éditant directement la RAM (bouton droit sur la RAM, "éditer le contenu"). Chargez l'image en mémoire seq_man.mem et regardez ensuite le contenu de la RAM :
0010 1000 000c 1001 1002
On va considérer les opérandes les unes après les autres (on va bientôt voir le sens de ces valeurs) et pour ce faire, il nous faut disposer d'un registre qui sauvegarde l'adresse de l'opérande en mémoire actuellement considérée; c'est le rôle du program counter (PC). Pour récupérer une opérande dont l'adresse est dans le PC, il suffit de transférer le PC dans le registre RADM et de lire la mémoire. Chaque fois qu'une opérande est utilisée, on devra incrémenter le program counter.

Travail à réaliser

En utilisant uniquement les signaux de contrôle (donc on ne modifie pas les registres "à la main"), et après avoir chargé l'image seq_man.mem dans la RAM, effectuez les opérations ci-dessous. Je vous conseille de prendre des notes des signaux de contrôle que vous utilisez pour chaque étape. Notez que pour chacune des opérations ci-dessous, les opérandes sont placées dans la RAM. Modifiez le contenu de la mémoire et exécutez le programme avec les signaux de contrôle permettant de faire les divisions par deux successives de 128 jusqu'à un résultat nul en affichant le résultat sur les afficheurs à chaque étape. Quel signal me permettait de détecter qu'il faut s'arrêter ?