TP : Le NanoProcesseur

Vous allez construire un microprocesseur 8 bits simple mais efficace, dont l'architecture est très proche de celle étudiée dans la séance précédente:

 Vous pourrez (devrez..) vous appuyer sur les résultats des travaux effectués dans la séance "Nanoprocesseur" pour concevoir les différents codes demandés.  Cette séance sera, de plus, l'occasion, de découvrir un nouvel outil, le simulateur logique.

 Le système proposé se compose :

  • Du microprocesseur implanté dans un circuit logique programmable Altera Cyclone V -SoC.
  • D'une mémoire RAM contenant le programme et les données (cette mémoire est elle aussi intégrée dans le FPGA) ;
  • D’un haut-parleur piloté par un port de sortie du microprocesseur.

 

 

Quelques autres blocs ne sont pas représentés sur ce schéma : 

  • le générateur d’horloge sclk et la génération de la remise à zéro (reset_n)
  • les afficheurs pour le debug
  • d'éventuels autres périphériques...

Au cours de cette séance vous allez :

  • Étudier l’architecture du microprocesseur abordé dans la leçon sur le processeur,
  • Concevoir le compteur de programme (PC) du microprocesseur,
  • Concevoir l'automate qui contrôle le processeur (CTR)
  • Concevoir l'ALU qui effectue les opérations arithmétiques du processeur
  • Configurer un circuit logique programmable Altera afin qu’il réalise ce microprocesseur,
  • Faire exécuter un programme de test puis un programme musical à votre microprocesseur sur la carte FPGA,
  • Et enfin améliorer votre microprocesseur 

Le rôle de chaque signal du schéma précédent sont indiqués dans le tableau 1.1.

Tableau 1.1: Les signaux du "système" à base de NanoProcesseur
Nom Description Type (vu du processeur)

sclk

Horloge générale du processeur

Entrée

reset_n

Remise à zéro asynchrone et active à ’0’

Entrée

out

Port dont les bits peuvent être positionnés à ’1’ ou ’0’ et branché ainsi :

  • bit 0 : sur codec audio (et sur haut-parleur externe)
  • bits 7 à 1 : leds rouges

Sortie

ram_addr[7:0]

Adresse de l’accès à la RAM

Sortie

ram_data_write[7:0]

Sortie de l’accumulateur. Ce mot est mémorisé dans la RAM à l’adresseram_addr si write vaut 1 (accès à la RAM en écriture)

Sortie

ram_data_read[7:0]

Mot lu dans la RAM à l’adresse ram_addr (accès à la RAM en lecture)

Entrée

ram_write

Signal indiquant le type d'échange effectué avec la mémoire :

  • 1 pour une écriture
  • 0 pour une lecture

Sortie

0. Architecture du Nanoprocesseur

Prenez le temps de vous remémorer l'architecture du coeur. Étudiez le rôle de chacun des blocs et les différents signaux. Attention cette architecture peut être légèrement différente de celle créée en séance de TD.

1. Mise en place de l'environnement de travail

Nous avons préparé un squelette d'architecture dans lequel  les blocs ALU,  PC et CTR sont des boites "vides".

Tous les modules nécessaires sont déjà préparés, dans le sous-répertoire "src" . Vous n'aurez qu'à compléter leur contenu, sans modifier les entrées/sorties déjà déclarées.

2. Codage et test du compteur de programme

Il s'agit du bloc PC de votre NanoProcesseur. Un simple compteur respectant le cahier des charges décrit dans  l'architecture du coeur devrait suffire...

  • Complétez le code SystemVerilog du bloc PC

Le test se fait par simulation :

  1. Ouvrez une fenêtre de terminal
  2. Dans cette fenêtre, placez vous dans le répertoire de plus haut niveau (../../nanoprocesseur)  
  3. Tapez la commande  make compile_pc
  4. Tant que vous obtenez des messages d'erreur c'est que votre code n'est pas syntaxiquement correct.., lisez les messages et corrigez en conséquence
  5. Une fois le code corrigé, lancez une simulation en tapant la commande make simu_pc
  6. Examinez les chronogrammes ainsi que les messages dans la fenêtre "transcript" (au bas de l'écran) et prenez les dispositions nécessaires...

ATTENTION : Pensez à fermer systématiquement le simulateur en cours avant de lancer une commande de type "make simu..." , vous risquez sinon d'avoir plusieurs programmes de simulation en parallèle, puis un bloquage de votre poste...

3. Codage et test de l'unité arithmétique et logique

Il s'agit du bloc ALU dont le détail est décrit ici. Le codage de ce bloc est relativement direct : Il s'agit de choisir une opération à effectuer en fonction du code de l'instruction en entrée...

  1. Complétez le code SystemVerilog du bloc ALU
  2. Vérifiez la syntaxe de votre ALU par la commande make compile_alu
  3. Pour la simulation tapez la commande  make simu_alu
  4. Cette simulation ne génère pas de chronogrammes. Examinez les messages d'erreur et modifiez votre code en conséquence

4. Codage de l'automate de contrôle, et test du nanoprocesseur

Il s'agit du bloc CTR qui génère, en fonction de l'instruction en cours et des flags Z et C, les signaux d'enable des registres et de commande des multiplexeurs. Ce bloc pourra être codé de la façon suivante :

  • Un compteur permettant de définir l'enchaînement des états.
  • Un processus combinatoire pour chaque  signal de contrôle à générer. 

La table précise des instructions à coder se trouve ici.

  1. Complétez le code SystemVerilog du bloc CTR
  2. Vérifiez la syntaxe de votre contrôleur par la commande make compile_ctr
  3. Dans la fenêtre de terminal, tapez la commande  make simu

Il n'y a pas de test du contrôleur en simulation, mais un test global du microprocesseur :

La fenêtre de chronogrammes présente 

  • Dans la partie haute, l'ensemble des signaux de votre nanoprocesseur
  • Dans la partie basse, une comparaison avec les chronogrammes d'un NanoProcessuer de référence.

S'il n'y a pas de zones hachurées en rouge c'est que votre microprocesseur fonctionne correctement. 

Sinon :

  • Examinez la première erreur
  • Déterminez l' instructions fautive en vous aidant éventuellement du source du programme exécuté (test.s)
  • Corrigez votre erreur
  • Itérez jusqu'à épuisement des erreurs...

ATTENTION : pensez à fermer systématiquement le simulateur en cours avant de lancer une commande de type "make simu..." , vous risquez sinon d'avoir plusieurs programmes de simulation en parallèle, puis un bloquage de votre poste... 

5. Synthèse et test sur la maquette DE1-SoC

Si les chronogrammes sont sans erreur, alors nous pouvons passer au test sur la maquette.

  1. Synthèsez  l'architecture (c'est un peu long et il y a plein de messages)  : make chicken
  2. Branchez et allumez la maquette...
  3. Programmez la maquette : make prg_chicken

Attention: la maquette peut être contrôlée de la façon suivante : 

  • Si SW0 est à 0, l'horloge est la bonne (1MHz), et on entend la musique ...
  • Si SW0 est à 1, alors c'est KEY3 qui joue le rôle d'horloge manuelle. On peut alors suivre le déroulement du programme sur les afficheurs (mais on n'entendra rien) :
    • L'afficheur HEX4 et HEX5  présentent le contenu de l'accumulateur
    • Les afficheurs HEX2 et HEX 3  présentent l'instruction traitée
    • L'afficheur HEX0 et HEX1  présentent le l'adresse présentée à la RAM.

6. K2000 en code assembleur

Maintenant que vous disposez d'un microprocesseur opérationnel, vous allez vous exercer à écrire du code en assembleur. Nous allons de nouveau prendre K2000 pour exemple.

L'instruction "OUT" du nanoprocesseur permet non seulement d'envoyer le bit de poids faible de la donnée addressée en lecture  vers le buzzer, mais aussi de de stocker les 7 autres bits dans un registre connecté aux leds rouges de la maquette (ledr[6:0]

 

  1. Nous voulons réaliser un K2000 en modifiant l'affichage des 7 leds de manière régulière à l'aide de l'instruction "OUT".   Pour cela, éditez le fichier "moncode.s" se trouvant dans le répertoire "soft", et tenez compte des commentaires suivants:
    • L'horloge du processeur sera réglée à environ 1KHz.
    • Une instruction de déroule en 3 cycles d'horloge.
    • Le bit de poids faible de l'accumulateur sera maintenu à 0 pour éviter de générer des sons intempestifs...
  2. Une fois votre code écrit, compilez le en executant la commande "make moncode". Corrigez les éventuelles erreurs et recompilez le code jusqu'à ce qu'aucune erreur ne soit signalée.
  3. Positionnez SW1 à 1 pour sélectionner une horloge de 1KHz
  4. Programmez le FPGA par la commande "make prg_moncode". Cela peut prendre un peu de temps car cela nécessite la mise à jour du fichier de programmation a partir de votre code
  5. Et vérifiez le bon fonctionnement, ou non de votre programme.
  6. N'oubliez pas que vous pouvez faire fonctionner le microprocesseur pas à pas en plaçant l'interrupteur SW0 à 1 et en utilisant le bouton KEY3.

 

 

 

 

Tentez de modifier le NanoProcesseur pour en améliorer les performances (nombre de cycles variable selon l'instruction).

 

Fichier attachéTaille
Fichier nanoprocesseur.tgz27.79 Ko