3MMCEP Projet IT

De Ensiwiki
Aller à : navigation, rechercher
AttentionCette page est maintenue uniquement par les enseignants. Afin de ne pas perturber le déroulement des cours, elle n'a pas vocation à être modifiée par les élèves. Mais si vous avez des modifications à proposer, merci d'en discuter ou d'envoyer un e-mail aux auteurs de la page (cf. historique)

Laptop.png  Première Année  CDROM.png  Informatique 

Fleche haut.png

On décrit sur cette page un mécanisme d'interruption très simplifié par rapport à ceux existant dans des processeurs réalistes comme le MIPS.

Principe d'une interruption

Une interruption est un signal provenant de l'extérieur du processeur (à la différence d'une exception qui elle vient de l'exécution d'une instruction) et servant à notifier l'arrivée d'un évènement : par exemple, qu'on a appuyé sur une touche du clavier, qu'un certain quantum de temps s'est écoulé, etc.

Lorsqu'il reçoit une interruption, le processeur arrête d'exécuter le programme en cours d'exécution, sauvegarde l'état courant (défini précisément plus bas) et commence à exécuter un programme particulier, appelé « traitant d'interruption », dont le rôle est de réagir à l'évènement (par exemple : récupérer le caractère correspondant à la touche appuyée). Une fois le traitant d'interruption terminé, le processeur restaure l'état dans lequel il était au moment où il a été interrompu, et continue à exécuter le programme initial, comme si l'interruption n'avait jamais eu lieu.

Dans notre implantation simplifiée, on ne traitera qu'une seule source d'interruption (IRQ, pour Interrupt Request Query) non-interruptible : cela signifie que le processeur ne peut pas être interrompu lorsqu'il est déjà en train d'exécuter un traitant d'interruption. Pour cela, on utilisera un registre interne au processeur (SR) qui devra contenir la valeur 1 pour que le processeur puisse être interrompu.

Un autre point important est qu'il n'est pas possible d'interrompre l'exécution d'une instruction, car dans ce cas il serait très compliqué de sauvegarder et restaurer l'état du processeur autour du traitant d'interruption. On testera donc si on doit partir en interruption à la fin de chaque instruction, et nul part ailleurs dans l'automate de la PC.

Implantation dans le processeur du projet

Les sources fournies comprennent déjà une entrée IRQ provenant de l'extérieur du processeur (MMIPS_CPU.vhd). Ce signal entre dans la partie opérative, où vous devez ajouter :

  • un registre SR d'un bit, servant à déterminer si le processeur peut-être interrompu (1) ou non (0) ;
  • un registre EPC servant à sauvegarder le contenu du registre PC avant de commencer à exécuter le traitant d'interruption (il faudra pouvoir revenir au programme initial une fois le traitant terminé) ;
  • un circuit calculant la sortie feedback_it renvoyée à la PC : ce signal indique à l'automate de contrôle qu'il doit traiter une interruption, et se calcule simplement en calculant la conjonction logique entre le signal IRQ et le contenu du registre SR.

Dans la partie contrôle, il faut :

  • vérifier si l'entrée feedback_it est à 1 à la fin de l'exécution de chaque instruction ;
  • sauvegarder le contenu de PC dans EPC ;
  • masquer (i.e. désactiver) les interruptions en mettant à 0 le registre SR (dans un processeur réaliste, il y aurait d'autres registres à sauvegarder) ;
  • sauter à l'adresse 0x00001000 où sera placé le traitant d'interruption (sur le MIPS, l'adresse est normalement 0x80000080 mais les cartes FPGA utilisées ne permettent pas de gérer autant de mémoire).

Ecriture d'un traitant d'interruption

Un traitant d'interruption est un programme un peu particulier. Il doit commencer par sauvegarder tous les registres qu'il va utiliser : en effet, lorsqu'on reviendra au programme initial, il faudra que ce programme retrouve les registres dans le même état qu'il les a laissé (par exemple, si le programme initial était en train d'effectuer un calcul, il ne faut pas que l'exécution du traitant modifie le résultat du calcul !). Ensuite, il peut utiliser toutes les instructions du processeur pour réaliser le traitant nécessaire (dans un processeur réaliste gérant un mode « superviseur » et un mode « utilisateur », un traitant peut même utiliser des instructions interdites aux programmes classiques, mais on ne traitera pas cela ici).

Le traitant se termine toujours par la restauration des registres sauvegardés initialement, puis l'exécution d'une instruction particulière rfi (Return From Interrupt) qui réalise les opérations inverses de celles exécutées pour rentrer dans le traitant, c'est à dire :

  • démasquer les interruptions ;
  • restaurer le registre PC à partir de la valeur sauvegardée dans EPC.

L'instruction RFI est une version simplifiée de l'instruction RFE qui existe réellement dans le MIPS et que vous pourrez implanter si vous réaliser l'extension gérant le coprocesseur 0.

Extension possible

Le système de gestion des interruptions décrit ici est basique et impose notamment de conserver le signal IRQ à 1 suffisamment longtemps pour que la PC ait le temps de le détecter, mais pas trop longtemps pour ne pas qu'une fois le traitant terminé, le même signal soit considéré comme une nouvelle interruption.

Une façon simple de l'améliorer consiste à ne plus détecter le fait que le signal IRQ soit à 1, mais son passage de 0 à 1 (en implantant un détecteur de front montant), et de mémoriser chaque front montant de IRQ dans un registre remis à 0 lorsqu'on entre dans le traitant d'interruption.