TutoRISC : un RISC dans mon FPGA Jérémie Detrey LIP ENS Lyon 46, allée d'italie 69 364 Lyon cedex 07 Jeremie.Detrey@ens lyon.fr Résumé Le travail présenté ici s'inscrit dans le cadre d'un cours d'architecture des ordinateurs, donné en 3 ème année de la Licence d'informatique Fondamentale à l'ens de Lyon. Il consiste en un projet s'étalant sur quelques séances de TD (ici deux), durant lesquelles les étudiants sont invités à décrire un processeur RISC 16 bits complet en VHDL. Le processeur est ensuite synthétisé et programmé sur une carte de développement (XUP-V2P) avec des contrôleurs fournis pour la mémoire, l'entrée clavier et la sortie VGA. Remarque : TutoRISC ne se targue en aucun cas d'être un processeur RISC utilisable pour une vraie application, mais uniquement un processeur «jouet» pour que les étudiants puissent l'implémenter de bout en bout en seulement quelques séances de TD. 1 Introduction 1.1 Contexte Le cours d'architecture des ordinateurs donné sur un semestre en 3 ème année de Licence d'informatique Fondamentale à l'ens de Lyon consiste en une présentation des divers concepts sur lesquels reposent la plupart des processeurs passés et actuels, sans pour autant rentrer dans des détails trop technologiques. Le spectre des sujets couverts est assez vaste, des principes de la logique booléenne aux décodage des instructions, en passant entre autres par des bases de l'arithmétique des ordinateurs et les mémoires cache. Jusqu'à l'année précédente, les séances de TD de la fin du semestre avaient pour vocation de montrer aux étudiants qu'ils étaient désormais eux-mêmes en mesure de concevoir «sur le papier» un processeur dans sa quasi-totalité. Ainsi, en deux ou trois séances de deux heures, les étudiants pouvaient explorer divers choix architecturaux. L'exercice s'achevait lorsqu'ils étaient parvenus à un jeu d'instructions complet et précisément décrit, un dessin de l'architecture de leur processeur, avec les diverses unités (ALU, bancs de registres, décodage de l'instruction, etc...) et les nappes de fils qui les relient, ainsi qu'une description précise de l'automate de contrôle. 1.2 Motivation Cependant, à l'issue de ces TD, certains étudiants restaient sceptiques quant à la viabilité de leur processeur. L'idée de TutoRISC est donc apparue comme un prolongement naturel de ces TD théoriques, proposant d'implémenter effectivement le processeur sur une carte de développement munie d'un FPGA. La carte retenue fut la XUP-V2P, développée par Digilent et embarquant un FPGA Virtex-II Pro ainsi que de nombreux ports d'entrée/sortie. 2 TutoRISC 2.1 Processeur RISC TutoRISC ayant été mis en œuvre pour la première fois l'an dernier, pour des raisons de temps et pour simplifier un peu la tâche des étudiants, l'auteur avait choisi de restreindre le processeur réalisé à un RISC 16 bits très simple, mais comprenant tout de même des détails architecturaux
intéressants. À partir de cette année, cependant, plus de temps sera consacré au projet, de telle sorte que les étudiants ne soient plus du tout contraints dans les choix architecturaux du processeur. Voici donc à titre de référence la description du processeur réalisé l'année dernière. 2.1.1 Processeur RISC 16 bits Le processeur présenté ici est une machine à une adresse : seulement un registre est spécifié dans chaque instruction. Un autre registre, explicitement désigné comme tel dans les spécifications du processeur, joue le rôle d'accumulateur. Le banc de registre compte 64 registres de 16 bits, notés de r0 à r63, l'accumulateur Acc correspondant au registre r0 et le compteur ordinal PC (Program Counter) au registre r63. On a aussi un compteur ordinal de retour, dans lequel est stocké l'adresse de retour après un appel de fonction ; il est noté RPC et fixé à r62. Ce processeur n'est de plus pas pipeliné (pour simplifier l'écriture de l'automate de contrôle), et ne dispose pas de MMU ni de gestion d'interruptions. Cela est cependant proposé comme extentions possibles. 2.1.2 Mot d'instruction Les instructions sont toutes prédiquées par une condition qui peut empêcher l'exécution d'une instruction selon la valeur des 4 bits de statut du processeur. Le mot d'instruction est ainsi découpé en cinq champs : bits 15 à 12, cond : prédicat conditionnant l'exécution de l'instruction ; bits 11 à 8, op : opcode de l'instruction ; bit 7, updt : drapeau déterminant si l'instruction doit mettre les bits de statut à jour ; bit 6, imm : drapeau déterminant si le champ val suivant correspond à un numéro de registre ou bien à une valeur immédiate ; et bits 5 à 0, val : numéro de registre rx si imm est à 0, ou valeur immédiate X sinon. 2.1.3 Jeu d'instruction Figure 1. Découpage du mot d'instruction. Le processeur ne dispose donc que de seize instructions : quatre instructions logiques (ET, OU, XOR et NON), deux instructions arithmétiques (addition et soustraction), deux instructions de décalage (gauche et droite), deux instructions mémoire (lecture et écriture), deux instructions de transfert registre à registre (depuis l'accumulateur et vers l'accumulateur), et quatre instructions de saut (sauts relatifs positif et négatif, saut absolu et appel de procédure). Ces seize instructions sont répertoriées dans le tableau 1 page suivante. 2.1.4 Statut et conditions Le registre de statut du processeur est formé de quatre drapeaux : Z (Zero) : 1 si le résultat d'une opération est nul, et 0 sinon ; N (Negative) : 1 si le résultat d'une opération est négatif, et 0 sinon ; C (Carry) : 1 s'il y a dépassement de capacité sur 16 bits, et 0 sinon ; V (overflow) : 1 s'il y a dépassement de capacité sur 15 bits (dépassement signé), et 0 sinon. Les douze prédicats associés à ces drapeaux de statut sont donnés dans le tableau 2.
Opcode Codage Action Opcode Codage Action AND 0000 Acc Acc AND rx/x LDA 1000 Acc [rx/x] OR 0001 Acc Acc OR rx/x STA 1001 [rx/x] Acc XOR 0010 Acc Acc XOR rx/x MTA 1010 Acc rx/x NOT 0011 Acc NOT rx/x MTR 1011 rx Acc ADD 0100 Acc Acc + rx/x JRP 1100 PC PC + rx/x SUB 0101 Acc Acc rx/x JRN 1101 PC PC rx/x LSL 0110 Acc Acc << rx/x JPR 1110 PC rx/x LSR 0111 Acc Acc >> rx/x CAL 1111 RPC PC + 1 PC rx/x Tableau 1. Liste des instructions. Condition Codage Expression Condition Codage Expression F 0000 0 C 1000 C T 0001 1 NC 1001!C Z 0010 Z V 1010 V NZ 0011!Z NC 1011!V P 0100 (!Z) && (!N) 1100 NP 0101 Z N 1101 N 0110 N 1110 NN 0111!N 1111 Tableau 2. Liste des prédicats. 2.1.5 Architecture globale Une vue d'ensemble de l'architecture du processeur est donnée figure 2. Pour plus de détails sur le fonctionnement et l'architecture de ce processeur, le lecteur est invité à lire le sujet du TD qui fut donné aux étudiants, disponible à l'adresse http://perso.enslyon.fr/jeremie.detrey/tutorisc/. 2.2 Contrôleurs Le processeur est prévu pour s'intégrer facilement dans un harnais développé à cet effet, comprenant un contrôleur pour gérer la mémoire, le clavier, connecté à la carte par un port PS/2, et enfin la sortie VGA permettant d'avoir une exécution graphique du processeur. Tous ces contrôleurs ont été développés en VHDL et sont fournis aux étudiants à titre de curiosité uniquement. Le contrôleur mémoire n'utilise pas la barette de mémoire DDR pourtant embarquée sur la carte XUP-V2P. En effet, celle-ci est bien trop complexe à gérer, alors que le Virtex-II Pro embarqué comporte suffisamment de RAMBlocks pour pouvoir stocker les 2 16 mots de 16 bits adressables. Il suffit donc de rajouter quelques muliplexeurs et démultiplexeurs pour fusionner tous ces RAMBlocks en une seule mémoire de 2 16 16 bits. Sur les 64K mots adressables (de l'adresse 0x0000 à 0xffff), une importante partie est réservée pour la mémoire vidéo. En effet, le contrôleur vidéo permet d'afficher sur un moniteur externe l'image formée par 320 256 pixels de 8 bits chacun. Cela correspond donc à un total de 80Ko, soit 40K mots, correspondants aux adresses mémoire de 0x0000 à 0x9fff. Chaque mot stocke ainsi deux pixels.
Figure 2. Architecture globale du processeur. De même, puisque le processeur ne dispose pas de mécanisme d'interruption, la gestion du clavier se fait de manière beaucoup plus directe : une zone de mémoire de 256 mots est réservée à cet effet, aux adresses de 0xff00 à 0xffff. Cette zone mémoire est utilisée comme une FIFO permettant de stocker les événements du clavier en attente. On y trouve ainsi un pointeur de tête FP (Front Pointer, à l'adresse 0xffff) qui indique où sont insérés les nouveaux événements par le contrôleur clavier, ainsi qu'un pointeur de queue BP (Back Pointer, 0xfffe) qui indique où le processeur doit aller dépiler des événements en attente. La zone réservée à la file proprement dite est ainsi restreinte aux adresses de 0xff00 à 0xfffd. Enfin, les adresses de 0xa000 à 0xfeff sont totalement libres et réservées pour le programme, comme présenté figure 3. Figure 3. Organisation de la mémoire. 2.3 Fonctionnement en TD On suppose comme prérequis pour les étudiants que ceux-ci connaissent déjà un peu VHDL et sont capables d'utiliser un simulateur pour vérifier et corriger leur circuit. Le simulateur utilisé pour
ce TD était la version d'évaluation de VHDL Simili 1. Le TP était prévu originellement pour s'étaler sur deux séances de deux heures, mais cela a semblé un peu trop court. Cette année, ce TD prendra trois voire quatre séances pour laisser plus de temps aux étudiants, et surtout leur laisser une totale liberté dans le choix du processeur à implémenter. Le principe est que les étudiants se répartissent naturellement en quatre groupes de 5-6 étudiants chacun dès le début du TD. Chaque groupe se voit alors assigner une tâche particulière : un groupe sera chargé de réaliser les différents registres (registre d'instruction, registre de statut et banc de registres), un autre fera l'alu, un troisième l'automate de contrôle et enfin un dernier groupe se chargera de connecter registres, ALU et contrôle à l'intérieur du processeur. Les quatres groupes peuvent travailler de manière parfaitement indépendante, car chacun dispose d'un testbench en VHDL comportemental fourni avec le sujet et permettant de tester exhaustivement la correction des différents circuits grâce à un simulateur logiciel. Le développement du processeur se fait en VHDL structurel, pour que les étudiants restent proches des aspects matériels du processeur. Une fois le travail des quatre groupes achevé, ils envoient leurs fichiers VHDL au chargé de TD qui les intègre au projet global, contenant déjà les contrôleurs. La synthèse et le placement/routage sont effectués devant les étudiants, grâce aux outils de la suite Xilinx ISE. Durant les quelques minutes que cela prend, le chargé de TD peut en plus expliquer plus précisément le rôle de ces différents outils. Enfin, le circuit final est programmé sur le FPGA de la carte de développement. Un écran et un clavier permettent alors de vérifier le bon fonctionnement du processeur. La vérification est effectuée grâce à un programme écrit dans l'assembleur du processeur RISC, et chargé directement dans sa mémoire. Le programme en question est actuellement un petit jeu graphique qui utilise extensivement toutes les instructions et la plupart des prédicats. Cette vérification est certes moins exhaustive que les vérifications des composants par simulation logicielle, mais présente l'intérêt d'être visuelle et ludique pour les étudiants, qui ont la satisfaction de voir leur processeur exécuter une application concrète. 3 Extensions possibles De nombreuses extensions sont envisageables à partir d'un tel système. On peut ainsi proposer aux étudiants les plus intéressés plusieurs pistes pour aller plus loin. Certaines extensions peuvent même être intégrées sous forme de projet dans d'autres cours. Pipeline : pour l'instant, le processeur n'est pas pipeliné, mais cela peut très bien être réalisé sans trop de difficultés. 32 bits : on peut aussi choisir d'améliorer le processeur pour en faire un processeur 32 bits, disposant ainsi de bien plus de flexibilité pour explorer de nombreux compromis architecturaux. Interruptions : une gestion des interruptions permettrait de simplifier le contrôle du clavier, et d'avoir un processeur plus réaliste. MMU, cache : on peut très bien envisager aussi de développer une gestion avancée de la mémoire ainsi que d'un cache pour ce processeur. Compilation : le jeu d'instruction étant complet, il suffit de développer un petit OS en assembleur muni uniquement des appels systèmes de base ainsi qu'un mécanisme pour charger des exécutables en mémoire pour permettre à un groupe d'étudiants de développer un compilateur d'un langage quelconque vers l'assembleur de ce processeur, dans le cadre d'un 1 http://www.symphonyeda.com/
cours de compilation. Ce projet fut d'ailleurs réalisé aussi l'an dernier par certains des étudiants ayant suivi le cours d'architecture des ordinateurs au semestre précédent. Système d'exploitation : une fois le processeur muni d'interruptions et d'une MMU, on peut envisager porter un système d'exploitation «jouet» comme Nachos 2 sur ce processeur. Cela demandera cependant d'avoir un compilateur complet C ou C++ pour l'assembleur du processeur. Pour cela, un simple back-end pour GCC devrait être suffisant. Interface réseau : la carte XUP-V2P disposant d'un port Ethernet, il est possible aussi dans le cadre d'un cours de réseaux, de réaliser la couche MAC en matériel, puis les couches supérieures en logiciel sur le processeur RISC, pour permettre aux étudiants de manipuler directement les concepts de bas-niveau qui sont à la base des réseaux qu'ils utilisent tous les jours. 4 Conclusion Le projet TutoRISC n'en est actuellement qu'à ses débuts, mais a déjà fait ses preuves. Les étudiants ayant participé au projet l'année dernière ont montré à ce projet un enthousiasme et un intérêt très encourageants. Les aspects un peu trop bas-niveau en ont parfois rebuté quelques uns, mais ceux-ci ont toutefois trouvé du grain à moudre en se chargeant du calcul des conditions de dépassement de capacité de l'alu ou bien de la conception de l'automate de contrôle. Enfin, le sentiment de profonde satisfaction et de fierté dont ont fait preuve tous les étudiants lorsqu'ils ont enfin vu le fruit de leurs efforts exécuter un jeu sur un écran constitue un signe indéniable qu'il faut continuer sur cette voie, et développer encore ce projet dans diverses directions pour en faire un outil d'enseignement transversal pour toutes les matières de l'informatique appliquée, de l'architecture des ordinateurs à la compilation en passant par les systèmes et les réseaux. Remarque : tous les fichiers nécessaires à ce projet sont disponibles sous license GPL à partir de la page web de l'auteur http://perso.ens lyon.fr/jeremie.detrey/tutorisc/. Leur diffusion est bien entendu encouragée. 2 http://www.cs.washington.edu/homes/tom/nachos/