6 Spécification sommaire pour les extensions 6.1 Décaleur à barillet Le décaleur à barillet fournit dans la PO utilise plusieurs opérateurs de décalage définis dans la bibliothèque std_logic_arith. Pour améliorer ses performances, on peut créer son propre décaleur à barillet. Par exemple, l’architecture de décaleur logarithmique utilisant des portes miroirs comme celui vu dans le TD 4 d’archi 1 est un bon point de départ. Ci-dessous un schéma type de ce décaleur : e31 e0 sens 0 e1 e30 1 0 x31 p 5 0 1 circuit miroir en entrée x0 x1 décaleur à droite logique ou arithmétique arith (5 étages de mux) sens circuit miroir en sortie s31 6.2 1 e0 e31 s1 s0 Additionneur à préfixe, multiplication, division Additionneur De base, l’outil de synthèse logique de Xilinx peut selon les besoins adaptés l’architecture de vos additionneurs selon vos besoins (performance ou ressources). Pour être sûr d’avoir un additionneur performant, vous pouvez essayer d’implanter un additionneur de Sklansky ou un de Brent&Kung. Le cours en ligne d’Alain Guyot 7 fournit des informations sur ces architectures. Multiplieur Pour l’implantation du multiplieur, il faudra rajouter les 2 registres dédiés hi et lo. L’outil de synthèse sera en mesure de vous générer un multiplieur sur les multiplieurs dédiés du FPGA. Pas la peine d’espérer pouvoir faire mieux. Que cela ne vous empêche pas d’essayer de comprendre ce qu’est par exemple un multiplieur de Booth. Division, modulo Vous pouvez soit utiliser le package numeric std soit implanter un diviseur itératif. Il est possible de faire encore mieux mais cela serait déraisonnable. 6.3 Les périphériques L’ajout de périphériques au système est relativement simple. Il suffit d’ associer à ces derniers un ou plusieurs emplacements mémoire, de modifier le décodeur d’adresse en conséquence. Horloge (Timer) L’utilisation d’une horloge permet au processeur d’externaliser la gestion du temps et de dissocier la notion du temps de celle de fréquence d’horloge. Réduit à son strict minimum, un périphérique timer est un compteur s’incrémentant à chaque cycle de l’horloge du circuit (50MHz sur notre carte). En plus de ce référentiel de temps, l’horloge fournit un système d’alarme programmable. Par exemple, le processeur voulant rafraichir une sortie sur les LED toutes les 100ms, programmera l’horloge pour être réveillée à cette fréquence. 7. http://users-tima.imag.fr/cis/guyot/Cours/Oparithm/francais/Additi.htm 6 Pour des raisons d’efficacité, l’alarme utilise une interruption pour se signaler au processeur. Afficheur 7 segments La documentation de la carte explique fort bien comment utiliser ce périphérique. Attention cependant à utiliser une fréquence de rafraichissement assez faible pour scanner vos 4 afficheurs. Mémoire SRAM La carte utilisée dispose de deux mémoires SRAM asynchrones au dos. Pour des raisons de temps de propagation très contraints, l’accès en lecture à ces mémoires est très difficile à garantir à 50MHz. Pour les intégrer malgré tout dans le plan mémoire en lecture/écriture, on peut ajouter un cycle au load dans la PC lorsqu’on les utilise. Sinon, vous pouvez également ne conserver que l’accès en écriture et utiliser ces mémoires comme une mémoire vidéo, le bloc VGA balayant alors à fréquence réduite la mémoire lorsque cette dernière n’est pas accédée en écriture par le processeur. Dans cette hypothèse, une seule mémoire est suffisante pour contenir une image 640x480 avec des pixels codés sur 3 bits. VGA La séance 1 devrait vous offrir toute l’aide nécessaire pour ce périphérique. Organisation de la mémoire Périphérique BRAM Accès RW Plage d’adresse 0x0-0x1FFF LEDs interrupteurs + boutons poussoirs W 0x4000 R 0x4004 afficheurs 7 segments W 0x4008 0x400A timer RW W 0x4010 0x4014 SRAM RW 0x100000-0x1FFFFF 6.4 Action Mémoire contenant au moins un programme et un traitant d’interruption. Affiche l’octet de poids faible du bus de donnée sur les LED Ecrit la valeur récupérée sur les 8 interrupteurs dans l’octet de poids faible du bus de donnée et la valeur des 3 boutons poussoirs aux positions 16...18 de ce même bus et 0 sur les autres bits Mot à afficher Configuration d’affichage (e.g. hexa demi-mot de poids faible, de poids fort, brut sur le mot complet) Valeur de l’horloge (pas à définir) Programme une alarme qui déclenchera une interruption dans un temps défini par la valeur écrite par le temps du pas. (inactif à 0) A vous de voir COP0 : le coprocesseur système du MIPS Cette section décrit un sous-ensemble du coprocesseur 0, utilisé par le MIPS pour gérer les exceptions (6B) et plusieurs lignes d’interruption (6A), car la réalité est un peu plus complexe que ce qui vous a été décrit dans la section 5.2. généralités A ce stade, vous avez normalement compris qu’une exception ou une interruption désigne un événement inattendu qui perturbe le fonctionnement normal du processeur. On distingue une exception, un événement provenant de l’intérieur, d’une interruption qui provient d’une source externe. exceptions Comme en témoigne, le champ exception dans le descriptif des instructions, les causes d’exceptions sont nombreuses : overflow, adresse invalide, appel système ... 7 Pour chacune de ces exceptions 8 , il convient d’ajouter à la partie opérative un état, l’ayant détectée, durant lequel on enregistre la cause de cette exception dans un registre spécifique du coprocesseur 0 : le registre de cause(CR). Ces causes sont codées de la manière suivante : CR6···2 Cause de l’exception 0 interruption externe 4 erreur d’adressage sur une lecture (instruction, mot, demi-mot ou octet) 5 erreur d’adressage sur une écriture 8 exception syscall 9 exception break A instruction non définie C dépassement de capacité arithmétique Le départ en exception est déclenché par le coprocesseur si CR6···2 est non nul et si les interruptions ne sont pas inhibées par le registre SR (le même que celui utilisé pour l’interruption simple). Les départs en exception (sur une nouvelle entrée ERQ pour la PC) et en interruption (sur l’entrée IT) ne diffèrent que par la valeur à stocker dans EPC. On a vu qu’une interruption va y mettre l’adresse de l’instruction suivante, tandis qu’une exception va conserver l’adresse de l’instruction fautive. Ayant déjà réalisé PC+4 dans l’état décode, il faut donc stocker PC-4 dans EPC pour traiter correctement une exception. Noter que dans les deux cas, le traitant d’interruption est situé au même endroit. C’est donc à lui qu’incombe la tâche de trouver la source de l’interruption ou de l’exception et de la traiter correctement. Détail des registres Contrairement à ce qu’on a vu dans le processeur simple, EPC et SR (Status Register) sont comme CR des registres du coprocesseur 0. Pour accéder à ces registres et écrire un traitant d’interruption plus efficace, le programmeur peut utiliser les instructions mtc0 et mfc0. Ces registres y sont désignés par leurs indexes dans le coprocesseur 0 soit $12 pour le registre de status SR, $13 pour le registre de cause CR et $14 pour le registre EPC. Les registres SR et CR sont organisés comme suit : 31 16 15 8 5 4 3 2 1 0 Registre de status : masque KU IE KU IE KU IE ligne vieux précédent courant 31 16 15 8 6 2 Registre de cause : lignes code d’interruption d’exception Pour SR, IE à 1 signifie que les interruptions sont activées et KU indique si on est en mode kernel (0) ou User (1). A priori, vous pouvez ignorer le bit KU. Ces deux bits doivent être sauvegardés lors d’un départ en interruption ou en exception. Pour le faire, on décale SR de 2 vers la gauche sur les 6 premiers bits : SR5···0 ⇐ SR3···0 ||02 . Au retour en interruption, l’instruction rfe se charge de restaurer le registre SR. Si IE=1, le masque d’interruption dans SR15...8 permet de masquer/démasquer les 8 lignes d’interruption (CR15...8 ) individuellement. L’entrée IT de la partie contrôle est alors généré par un OR8 issu des ET bit à bit entre SR et CR. A ce stade, vous devez être en mesure de gérer plusieurs sources d’interruptions matérielles ininterruptible. Pour permettre à une interruption d’en interrompre une autre, il faut fixer des priorités à vos lignes. Généralement la ligne d’interruption la plus à gauche a la plus forte priorité. Ainsi votre traitant d’interruption, après avoir identifié la source de l’interruption, va pouvoir autoriser les interruptions plus prioritaires avant le retour d’interruption. L’architecture décrite ne supporterait pas plus de 2 instructions sans perdre les informations de SR. Pour être capable, de gérer plus, il faut mettre en place une pile pour les exceptions où EPC et CR seraient stockés pour chaque appel. A vous d’imaginer cela. 8. Faire en priorité l’overflow et les instructions non définies. 8