Réponse 1

La première réponse est très détaillée. Les autre réponses seront plus succinctes.

1 Les adresses

Pour effectuer un calcul, l’automate doit disposer de trois informations :

  • l’instruction (l’opération)
  • l’opérande 1
  • l’opérande 2

Plus que ça, il doit en disposer en même temps. Mais elles sont stockées en RAM, et ne peuvent être lues que l’une après l’autre. Il faudra donc prévoir un moyen de stockage de ces trois informations à l’intérieur du processeur pour pouvoir effectuer le calcul.

Vu l’organisation de la mémoire, il semble logique de lire ces trois informations de la façon la plus simple possible, c’est à dire :

  • tout d’abord l’instruction,
  • puis l’opérande 1,
  • puis l’opérande 2,

ce qui correspond à un parcours linéaire de la mémoire.

De plus, le stockage du résultat s’effectue dans la RAM à l’adresse suivant celle de l’opérande 2. On peut donc doter l’automate d’un compteur qu’on appellera compteur d’adresse ou PC (Program Counter), qui donnera l’adresse de la RAM à laquelle on est en train d’accéder (que ce soit en lecture ou en écriture). Ce compteur sera incrémenté à chaque coup d’horloge, et pilotera directement le bus d’adresse de la RAM.

2 Les données

Vu ce qui vient d’être dit, l’automate a un fonctionnement linéaire - l’ordre des actions effectuées est toujours le même :

  1. chercher une instruction
  2. chercher le premier opérande
  3. chercher la deuxième opérande
  4. stocker le résultat du calcul

On peut donc le concevoir comme un automate à quatre états, dont le fonctionnement est circulaire : état 1 → état 2 → état 3 → état 4 → état 1 → état 2 → …

État 1:
  • le compteur est en train de présenter à la RAM une adresse correspondant à une instruction.
    Le processeur récupère sur le bus Q[7:0] la contenu de la RAM à cette adresse, c’est à dire l’instruction à effectuer.
  • il faut stocker cette instruction pour plus tard (quand on effectuera l’opération demandée).
    On ajoute donc à l’automate un registre sur 8 bits disposant d’un enable (8 bascules DFFE en parallèle).
    L’entrée de ce registre est reliée au bus Q[7:0] (sortie de la RAM)
    Le signal d’enable de ce registre est mis à l’état haut seulement pendant l’état 1 –> stockage de l’instruction dans le registre
État 2:
  • le compteur est en train de présenter à la RAM une adresse correspondant aux premier opérande.
    le processeur récupère sur le bus Q[7:0] la contenu de la RAM à cette adresse, c’est à dire l’opérande 1…
  • il faut stocker cet opérande, donc re-belotte, on ajoute un registre 8 bits avec enable, relié à la sortie de la RAM (Q[7:0]).
    l’enable est mis à l’état haut seulement pendant l’état 2.
État 3:
  • le compteur est en train de présenter à la RAM une adresse correspondant aux deuxième opérande.
    le processeur récupère sur le bus Q[7:0] la contenu de la RAM à cette adresse, c’est à dire l’opérande 2…
  • comme d’habitude on stocke cet opérande dans un registre 8 bits, dont l’enable est piloté à l’état haut seulement pendant ce cycle-ci.

Remarque : on peut se dire que ce n’est pas la peine de stocker cet opérande, car on dispose dès à présent de toutes les données pour effectuer le calcul : l’instruction dans un registre, l’opérande dans un autre registre, et le deuxième opérande sur le bus Q[7:0]. Mais il faudrait alors stocker le résultat dans un registre 8 bits, car on ne fait son stockage en RAM qu’au prochain cycle…Alors qu’ici, le calcul et le stockage seront faits en bloc au prochain cycle (donc pas besoin de stocker le résultat dans un registre). Au total, dans les deux approches, le nombre de registres est le même, et ce ne sont que des considérations de chemin critique qui permettront de déterminer la meilleure des deux méthodes…

État 4:
  • le compteur est en train de présenter à la RAM une adresse correspondant au résultat à stocker.
  • l’automate dispose dans ses trois registres de toutes les données pour effectuer le calcul. Il suffit d’ajouter une fonction combinatoire pure, pour produire le résultat.
    La sortie de cette fonction combinatoire sera reliée au bus d’entrée de la RAM.
    L’équation de cette fonction sera du genre : RES[7:0] = (si INSTRUCTION="00000100" : OP_1[7:0] + OP_2[7:0], sinon OP_1[7:0] - OP_2[7:0])
    Une telle fonction combinatoire a été réalisée au TP numéro 2…(ALU)
  • Parallèlement, l’automate doit piloter le signal WRITE de la RAM à l’état haut, pour dire à la RAM de stocker à l’adresse courante la sortie de la fonction de calcul.

On obtient donc l’architecture suivante pour notre processeur :

  • En rouge : le compteur d’adresse courante
  • En bleu : les trois registres 8 bits, les signaux load sont les enable
  • En noir rond : la fonction combinatoire de calcul proprement dite (ALU)
  • En noir carré : la machine à état qui séquence tout ça…

L'automate  (CTRL) est présenté en figure 1.4 et son graphe d’états en figure 1.5.

Figure 1.4: Architecture de la première version du nanoprocesseur

L'automate a quatre états, parcourus de façon linéaire, sans condition sur les transitions.

Il dispose de 4 sorties, chacune d’entre elles à l’état haut dans un seul état de l'automate. Un codage "one-hot", consistant à matérialiser chaque état par un registre est donc très approprié.

L’implémentation en registre a déjà été vue (registres les uns à la suite des autres), et ne sera pas détaillée ici. Les sorties des registres donnent directement les sorties de l'automate…

Figure 1.5: Graphe d'états de l'automate linéaire