ENI: Électronique Numérique Intégrée


---

Chapitre 19
TP - Nanoprocesseur


 19.1 Introduction
 19.2 Architecture du système à microprocesseur
 19.3 Fonctionnement et jeu d’instructions du microprocesseur
 19.4 Architecture du coeur du nanoprocesseur
 19.5 Séquencement des opérations
  19.5.1 Premier cycle "IF"
  19.5.2 Deuxième cycle "AF"
  19.5.3 Troisième cycle "EX"
 19.6 Travail demandé
 19.7 Verilog ou schéma ?
 19.8 Conception du bloc PC
 19.9 Conception du bloc CTR
  19.9.1 Validation
  19.9.2 Simulation
  19.9.3 Test réel
  19.9.4 Test musical
 19.10 Questions subsidiaires

19.1 Introduction

Au cours de ce TP vous allez :

 
Conseils :

19.2 Architecture du système à microprocesseur

Bien que le sujet du TP concerne plus le coeur d’exécution du microprocesseur que son environnement d’utilisation, nous présentons ici le système complet implanté sur la maquette de test. Le système proposé se compose :

Quelques autres périphériques ne sont pas représentés sur le schéma 19.1

PIC

Fig. 19.1: Schéma global du processeur et de ses périphériques




Nom

Entrées et sortie du processeur

Type (vu du processeur)



sclk

Horloge générale du processeur

Entrée



reset_n

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

Entrée



BZ

Port pouvant être positionné à ’1’ ou ’0’

Sortie



ram_addr[7..0]

Adresse de l’accès à la RAM

Sortie



accu[7..0]

Sortie de l’ACCUmulateur. Ce mot est mémorisé dans la RAM à l’adresse ram_addr si ram_write vaut 1 (accès à la RAM en écriture)

Sorties



ram_data[7..0]

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

Entrées



ram_write

Signal indiquant le sens de l’échange avec la mémoire (’1’ pour une écriture)

Sortie




Tab. 19.1: Entrées-sorties du processeur

Remarque : il y a quelques différences par rapport à la leçon sur le microprocesseur portant sur les noms des signaux :

19.3 Fonctionnement et jeu d’instructions du microprocesseur

Les caractéristiques principales de notre microprocesseur sont les suivantes :

Le tableau 19.2 résume le jeu d’instruction du microprocesseur.







Mnémonique

Instruction

Effet sur l’accumulateur

Effet sur le PC

code (binaire 8 bits)

code (décimal)







NOP

No OPeration

A <= A

PC <= PC + 2

00000000

0







XOR

XOR function

A <= A xor (AD)

PC <= PC + 2

00000001

1







AND

AND function

A <= A and (AD)

PC <= PC + 2

00000010

2







OR

OR function

A <= A or (AD)

PC <= PC + 2

00000011

3







ADD

ADDition without carry

A <= A + (AD)

PC <= PC + 2

00000100

4







ADC

ADDition with Carry

A <= A + (AD) + C

PC <= PC + 2

00000101

5







SUB

SUBstraction without carry

A <= A - (AD)

PC <= PC + 2

00000110

6







SBC

SuBstraction with Carry

A <= A - (AD) - C

PC <= PC + 2

00000111

7







ROL

ROtate Left

A <= A[6..0]A[7]

PC <= PC + 2

00001000

8







ROR

ROtate Right

A <= A[0]A[7..1]

PC <= PC + 2

00001001

9







LDA

LoaD Accumulator from memory

A <= (AD)

PC <= PC + 2

00001010

10







STA

STore Accumulator to memory

(AD) = A

PC <= PC + 2

00001011

11







OUT

OUTput

BZ <= (AD)(0)

PC <= PC + 2

00001100

12







JMP

JuMP

A <= A

PC <= AD

00001101

13







JNC

Jump if No Carry

A <= A

PC <= AD si C=0, PC+2 sinon

00001110

14







JNZ

Jump if No Zero

A <= A

PC <= AD si Z=0, PC+2 sinon

00001111

15








Tab. 19.2: Jeu d’instructions du processeur

Nous vous conseillons de vous familiariser avec le jeu d’instructions et les codes associés du microprocesseur en étudiant le programme verif_globale qui servira de jeu de test de simulation pour le microprocesseur.

19.4 Architecture du coeur du nanoprocesseur

Le coeur, comme illustré à la figure 19.2 est composé de quelques registres, d’une unité de calcul, d’un compteur de programme et d’une unité de contrôle. Tous les registres du microprocesseur sont pilotés par l’horloge sclk (comme horloge système, system clock en anglais) et remis à zéro par l’état bas du signal reset_n.

PIC

Fig. 19.2: Intérieur du processeur

Le compteur de programme (PC)

Le compteur de programme (8 bits) sert à stocker l’adresse de l’instruction courante.

Le signal load_PC est prioritaire par rapport au signal inc_PC.

La machine à état de contrôle (CTR)

Cette unité contient la machine à état permettant de gérer les unités du processeur. Elle est donc en charge de séquencer les différents cycles d’une instruction (chargement d’une instruction, chargement de l’opérande, puis exécution) et de générer les signaux de contrôle des différents blocs, sans oublier, bien sûr, le signal ram_write de validation d’écriture en mémoire.

Registres de mémorisation

Ce bloc regroupe en fait les quatre registres suivants :

Tous ces registres fonctionnent de la même façon : l’entrée xxx est mémorisée sur le front montant de l’horloge si l’enable correspondant (load_xxx) est à 1.

Le multiplexeur d’adresses (MUX_ADDR, en sortie du PC)

Ce multiplexeur permet de choisir qui, de l’adresse "pointeur programme" PC ou de l’adresse de données AD, doit être envoyé sur le bus d’adresse ram_addr de la mémoire. Le choix de l’un ou de l’autre dépend de l’état courant de fonctionnement du microprocesseur. De manière générale, lorsque le microprocesseur va chercher une instruction en mémoire, PC est sélectionné, et lorsque le microprocesseur va traiter une donnée en mémoire, AD est sélectionné. Le choix est contrôlé par le signal sel_adr.

Nous représenterons ce choix par l’équation suivante 
ram_addr[7:0] = sel_adr * AD[7:0] + !sel_adr * PC[7:0]

L’ALU, unité atithmétique et logique

Ce bloc prend comme opérandes le contenu de l’accumulateur et le bus de donnée de la RAM, et effectue dessus l’opération indiquée par I. Selon le type d’opération,

19.5 Séquencement des opérations

Le signal reset_n permet de réinitialiser le fonctionnement du microprocesseur. Au premier cycle d’horloge suivant le passage à 1 du signal reset_n, le microprocesseur va chercher la première instruction du programme à exécuter qui se trouve implicitement à l’adresse "0" de la mémoire.

L’exécution d’une instruction s’effectue systématiquement en trois cycles d’horloge.

Le graphe de la machine à état est rappelé dans la figure 19.3 (toutes les sorties ne sont pas indiquées).

PIC

Fig. 19.3: Graphe d’état du contrôleur CTR

19.5.1 Premier cycle "IF"

Pendant le premier cycle (IF pour "instruction fetch") deux opérations sont réalisées simultanément.

19.5.2 Deuxième cycle "AF"

Pendant le deuxième cycle (AF pour "address fetch") deux opérations sont réalisées simultanément.

Remarque : pour simplifier, inc_PC est systématiquement mis à 1. En cas de saut, le bloc PC considerera le signal load_PC comme étant prioritaire.

19.5.3 Troisième cycle "EX"

Le troisième cycle correspond à l’exécution proprement dite de l’instruction. L’opération réalisée dépend de l’instruction stockée dans le registre d’instruction I. Dans tous les cas, le contenu de la mémoire à l’adresse déterminée par le pointeur stocké dans AD au cycle précédent, est lu de la mémoire et placé sur le bus d’entrée ram_data (sel_adr = 1).

Le chronograme 19.4 permet de résumer les différents cas.

PIC

Fig. 19.4: Chronogrammes du processeur

19.6 Travail demandé

Vous venez de lire les spécifications d’un petit micro-processeur, appelé nanoprocesseur, destiné à synthétiser de douces mélodies. Comme tout projet bien spécifié, différentes équipes ont pu travailler de façon indépendante à la conception des différents modules. Ainsi, la carte contenant les différents composants électroniques et acoustiques est prête, un programme assembleur de test et un autre générant de doux sons sont déja écrits, le schéma global est terminé ainsi que les sous-blocs ALU, REG, MEMOIRE.

 
Hélas, lors de la phase final d’intégration, le chef de projet réalise, tardivement, il est vrai, que les équipes chargées des blocs PC et CTR ont fait un travail de tellement piètre qualité, qu’il juge préférable de les reconcevoir complètement.

A vous de jouer...

19.7 Verilog ou schéma ?

Vous avez jusqu’à présent travaillé avec des schémas. Sans renier l’utilité des schémas pour des circuits simples ou pour donner une vue d’ensemble d’un système, il faut quand même avouer qu’ils ne se prêtent pas tellement à la réalisation de circuits complexes : vous vous imaginez placer et relier entre eux les quelques 80.000 bascules D d’un Pentium, ainsi que les centaines de milliers de portes autour d’eux ? Nous non...

 
C’est pour faciliter la description de circuits complexes que les langages de description de matériel ont été inventés. Ces langages représentent les circuits sous forme textuelle.

 
Ils peuvent représenter :

 
Vous allez réaliser ce circuit à l’aide de l’un de ces langages : Verilog. Il en existe d’autres (VHDL, SystemC, Confluence, ...), mais Verilog a quelques gros avantages :

 
Le but n’est pas de faire de vous des gourous de Verilog (ça viendra plus tard), mais plutôt de vous en donner suffisament de bases pour que vous puissiez vous débrouiller.

 
Allez tout d’abord faire un tour sur la page Verilog en 12 minutes, pour en avoir un petit aperçu !

19.8 Conception du bloc PC

La première étape consiste bien évidemment à déterminer le fonctionnement exact de ce bloc à partir des spécifications globales.

Remarque : vous pouvez vous reporter à la leçon sur le processeur (8) pour vous aider...

 
Puis, à partir de ces spécifications, il faut en écrire le code Verilog. Vous trouverez dans le répertoire des sources (src) :

 
Lancez votre éditeur de texte favori, par exemple : xemacs src/pc.v & , puis complétez le code du PC.

 
Lorsque vous pensez avoir quelque chose qui tient la route, simulez-le en lançant, depuis le répertoire nanoproc : make simu_pc . Après un certain temps, le simulateur doit vous afficher : "le bloc PC fonctionne", et la fenêtre de chronogrammes doit avoir la même tête que la figure 19.5.

PIC

Fig. 19.5: Chronogrammes du PC

Si le simulateur vous donne une erreur, c’est que votre code Verilog comporte une erreur de syntaxe. Fermez le simulateur, corrigez-la, et relancez la simulation. Si les chronogrammes ne sont pas assez grands, vous pouvez zoomer à l’aide des icônes PIC. Vous pouvez aussi zoomer sur une partie précise avec l’icône PIC.

19.9 Conception du bloc CTR

PIC

Fig. 19.6: Bloc CTR

De nouveau, il faut commencer par extraire des specifications le comportement exact de la machine à états, en déduire une architecture, et la coder en Verilog.

Registre d’état courant

Cette machine à états ne comportant que 3 états qui s’enchaîne dans un ordre fixe, elle sera codée en one-hot. L’état courant sera donc stocké dans trois registres, qu’on appelera cycle[2:0], dont l’en-tête a déjà été écrite.

Vous aurez à compléter le code de ces trois registres, c’est-à-dire à déterminer ce qui leur sera affecté au front montant de l’horloge, selon l’état des entrées, et de reset_n...

Calcul des sorties

Le calcul des sorties est un bloc purement combinatoire. Vous aurez donc à déterminer ce qui est affecté aux différentes sorties en fonction des entrées et de l’état courant (cycle[2:0]). Si l’équation est simple, vous donnerez à la sortie en question un type wire (à déclarer au bon endroit), et vous l’affecterez avec un assign sortie_xxx = .... ; Si l’équation est moins simple, vous utiliserez les instructions évoluées de Verilog, en :

 
La simulation du bloc CTR sera une simulation globale du microprocesseur et de sa RAM !

19.9.1 Validation

Vous pouvez vérifier le bon fonctionnement de CTR en simulant directement le système complet (nanoprocesseur + mémoire) avec un programme de test. Ce programme, nommé verif_globale permet d’exécuter toutes les instructions du nanoprocesseur.

Pour cela, vous avez deux options : la simulation (virtuelle) et l’exécution pas-à-pas sur la maquette.

19.9.2 Simulation

Placez vous dans le répertoire nanoproc, et lancez la simulation de l’ensemble avec le programme verif_globale : make simu Au bout d’un certain temps, le simulateur ouvre une fenêtre de chornogrammes qui doivent avoir la même tête que ceux en figure 19.7.

PIC

Fig. 19.7: Chronogrammes de la simulation du programme de test verif_globale

Ces chronogrammes sont disponibles en version plus grande en cliquant ici.

 
Nous avons inclus dans ces chronogrammes les signaux nécessaires à la compréhension de ce qui se passe dans le processeur :

 
Pour suivre les chronogrammes, il est conseillé de se rapporter à la page du programme de test verif_globale, et de suivre le déroulement du programme cycle par cycle.

 
Il est également possible de comparer vos chronogrammes à des chronogrammes de référence. Pour cela :

 
Par exemple, ces chronogrammes (visibles seulement depuis la version HTML) mettent en évidence le dysfonctionnement provoqué par le bug suivant :  
assign load_PC = cycle[2] && ( I==13 || ( I== 14 && !C ) || ( I== 15 && !Z ) ); (la logique correcte étant assign load_PC = cycle[1] ...).

19.9.3 Test réel

Lors la simulation est correcte, vous pouvez aussi suivre le déroulement du programme "en vrai", sur la maquette de test.

Pour cela, il faut tranformer le code Verilog en une liste de portes (netlist) compréhensible par le FPGA. Ceci est fait au moyen des même programmes que ceux que vous avez utilisés au dernier TP.

 
Placez-vous dans le répertoire nanoproc , et lancez la compilation des sources Verilog en une liste de portes pour le FPGA : make Si la compilation s’est terminée sans erreurs, lancez la programmation du FPGA (après avoir mis la maquette sous tension...) : make program Le FPGA doit commencer à exécuter le programme de vérification.

Il y a deux modes d’exécution de ce programme de test :

 
Vous pouvez suivre l’état de certain signaux du processeur :

Ici aussi, il est recommandé de suivre l’exécution du programme pas à pas, en vérifiant chaque étape à l’aide de la page du programme de test verif_globale.

19.9.4 Test musical

Pour finir le test de votre processeur, nous vous proposons de lui faire jouer un petit morceau de "musique". Pour cela, appelez un enseignant qui branchera un haut-parleur sur votre maquette. Puis lancez la compilation du processeur en lui passant en argument le programme musical : make chicken.  
Programmez le FPGA : make program

19.10 Questions subsidiaires

Pour les plus rapides, voici quelques sujets d’investigation...

  1. Montrer que les instructions JNC, JNZ, JMP, ROL, ROR et OUT peuvent être exécutées en deux cycles. Modifier le contrôle en conséquence.
  2. Comment augmenter de 256 à 1024 la taille de la mémoire ?



Pour revenir au sommaire des supports du cours ENI.
---

Page maintenue par Jean Provost
Dernière modification:23 août 2006