3MMCEP VGA : Différence entre versions

De Ensiwiki
Aller à : navigation, rechercher
 
(14 révisions intermédiaires par 3 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 +
{{Maintenance uniquement par enseignants}}
 
{{1A}} {{Matériel}}
 
{{1A}} {{Matériel}}
 
[[Catégorie:Première Année]]
 
[[Catégorie:Première Année]]
Ligne 10 : Ligne 11 :
  
 
Pour bien aborder le TP et comprendre ce que vous allez faire, il faut que vous arriviez en séance en ayant lu la [[Media:DocVGAXilinx.pdf|documentation]] décrivant le fonctionnement d'une carte VGA.
 
Pour bien aborder le TP et comprendre ce que vous allez faire, il faut que vous arriviez en séance en ayant lu la [[Media:DocVGAXilinx.pdf|documentation]] décrivant le fonctionnement d'une carte VGA.
 +
 +
Les fichiers <tt>GeneSync.vhd</tt> et <tt>RAM_VIDEO.vhd</tt> qui vous sont fournis ne doivent pas être modifiés : tout le travail demandé doit être implanté dans <tt>GeneRGB.vhd</tt> et <tt>VGA.vhd</tt> (vous pouvez créer de nouveaux fichiers pour implanter les registres de la dernière question si vous le souhaitez).
  
 
Une fois que vous avez lu la documentation, lisez l'exercice "Affichage basique" ci-dessous et essayer de prévoir ce qui sera affiché une fois le circuit implanté.
 
Une fois que vous avez lu la documentation, lisez l'exercice "Affichage basique" ci-dessous et essayer de prévoir ce qui sera affiché une fois le circuit implanté.
Ligne 39 : Ligne 42 :
  
 
Simuler le comportement du circuit. (le fichier de test TestBench_VGA.vhd vous est déjà fourni). Pour ce faire taper en ligne de commande <tt>make clean TestBench_VGA.view_vcd DUREESIMU=20ms</tt>
 
Simuler le comportement du circuit. (le fichier de test TestBench_VGA.vhd vous est déjà fourni). Pour ce faire taper en ligne de commande <tt>make clean TestBench_VGA.view_vcd DUREESIMU=20ms</tt>
 +
 +
'''Vous prendrez soin d'afficher les valeurs des signaux de synchronisation <tt>HSYNC</tt> et <tt>VSYNC</tt>, ainsi que du signal <tt>IMG</tt>.'''
 +
 +
En regardant l'évolution de leurs valeurs, et en vous aidant de la [[Media:DocVGAXilinx.pdf|documentation VGA]], essayez de comprendre leur utilité.
  
 
=== Question 4 ===
 
=== Question 4 ===
  
Vérifier que le fichier de contraintes utilisé pour associer les entrées et sorties du circuit aux pattes du FPGA (les numéros de pattes sont indiqués entre parenthèses sur le schéma) correspond bien à ce qui est souhaité.  
+
Vérifier que le fichier de contraintes utilisé (<tt>VGA.ucf</tt>) pour associer les entrées et sorties du circuit aux pattes du FPGA (les numéros de pattes sont indiqués entre parenthèses sur le schéma) correspond bien à ce qui est souhaité.
  
 
=== Question 5 ===
 
=== Question 5 ===
Ligne 50 : Ligne 57 :
 
== Générateur de mire VGA ==
 
== Générateur de mire VGA ==
  
On souhaite maintenant construire un circuit capable d'afficher la mire ci-dessous (noter bien les différences avec la version précédente).
+
On souhaite maintenant construire un circuit capable d'afficher la mire ci-dessous (noter bien les différences avec la version précédente : les couleurs a afficher sont rouge, bleu, vert et noir).
  
 
[[Image:3MMCEP_VGA_Mire.png|center]]
 
[[Image:3MMCEP_VGA_Mire.png|center]]
Ligne 78 : Ligne 85 :
 
[[Image:3MMCEP_VGA_Bitmap.png|center]]
 
[[Image:3MMCEP_VGA_Bitmap.png|center]]
  
L'image que l'on va utiliser est une image en noir et blanc de résolution 320x240px (pour limiter l'espace mémoire nécessaire au stockage de l'image). Comme <tt>GeneSync</tt> calcule X et Y pour un affichage de résolution 640x480px, il suffit d'utiliser X(9..1) et Y(8..1) pour afficher l'image à la bonne résolution.
+
L'image que l'on va utiliser est une image en noir et blanc de résolution 320x240px (pour limiter l'espace mémoire nécessaire au stockage de l'image). Comme <tt>GeneSync</tt> calcule X et Y pour un affichage de résolution 640x480px, il suffit d'utiliser <tt>X(9 downto 1)</tt> et <tt>Y(8 downto 1)</tt> pour afficher l'image à la bonne résolution.
  
La mémoire utilisée travaille avec des mots de 32 bits : cela signifie qu'on trouve les 32 premiers pixels de l'image à l'adresse 0, les 32 suivants à l'adresse 1, etc. On calcule donc l'adresse de la case mémoire contenant le pixel voulu en utilisant la formule <tt>ad = Y(8..1) & X(9..6)</tt> (où <tt>&</tt> est l'opérateur de concaténation). Par exemple, le pixel de coordonnées (X, Y) = (129, 2) se trouve à l'adresse 0x0024 (c'est à dire 000000100100 en binaire).
+
La mémoire utilisée travaille avec des mots de 32 bits : cela signifie qu'on trouve les 32 premiers pixels de l'image à l'adresse 0, les 32 suivants à l'adresse 1, etc. On calcule donc l'adresse de la case mémoire contenant le pixel voulu en utilisant la formule <tt>addrb <= Y(8 downto 1) & X(9 downto 6)</tt> (où <tt>&</tt> est l'opérateur de concaténation). Par exemple, le pixel de coordonnées (X, Y) = (129, 2) se trouve à l'adresse 0x0024 (c'est à dire 000000100100 en binaire).
  
Comme chaque mot contient 32 pixels, on va utiliser un simple multiplexeur 32 entrées vers 1 sortie pour extraire le bit voulu. L'entrée de données du multiplexeur sera donc le mot lu en mémoire et l'entrée de sélection X(5..1). Les signaux R, G et B seront alors égaux à la sortie du multiplexeur si IMG vaut 1, et 0 sinon.
+
Comme chaque mot contient 32 pixels, on va utiliser un simple multiplexeur 32 entrées vers 1 sortie pour extraire le bit voulu. L'entrée de données du multiplexeur sera donc le mot lu en mémoire et l'entrée de sélection X(5 downto 1). Les signaux R, G et B seront alors égaux à la sortie du multiplexeur si IMG vaut 1, et 0 sinon.
  
 
Vous pouvez implanter le multiplexeur comme vu en cours ou utiliser la fonction <tt>conv_integer</tt> prédéfinie dans la bibliothèque standard : cette fonction prend en paramètre un <tt>std_logic_vector</tt> et renvoie l'entier correspondant.
 
Vous pouvez implanter le multiplexeur comme vu en cours ou utiliser la fonction <tt>conv_integer</tt> prédéfinie dans la bibliothèque standard : cette fonction prend en paramètre un <tt>std_logic_vector</tt> et renvoie l'entier correspondant.
Ligne 91 : Ligne 98 :
  
 
La partie "A" de la mémoire vidéo n'est pas utilisée dans ce TP, dans le fichier <tt>VGA.vhd</tt> vous pouvez donc :
 
La partie "A" de la mémoire vidéo n'est pas utilisée dans ce TP, dans le fichier <tt>VGA.vhd</tt> vous pouvez donc :
* brancher l'horloge <tt>clka</tt> sur l'horloge globale ;
+
* forcer à zéro toutes les entrées inutiles (<tt>'0'</tt>, <tt>"000"</tt>, <tt>(others => '0')</tt> selon le nombre de bits) ;
* forcer à 0 (sur le bon nombre de bits) toutes les entrées inutiles ;
+
* ne rien associer aux sorties inutiles (mot-clé <tt>open</tt>) ;
* ne rien associer aux sorties inutiles.
+
* pensez à brancher l'horloge <tt>CLKB</tt> sur l'horloge globale.
  
 
Tester en simulation pour vérifier que vos composants sont corrects (même si l'analyse visuelle de la simulation ne vous apportera pas grand-chose !).
 
Tester en simulation pour vérifier que vos composants sont corrects (même si l'analyse visuelle de la simulation ne vous apportera pas grand-chose !).
Ligne 101 : Ligne 108 :
 
Tester le circuit sur la carte FPGA. En regardant l'affichage, à votre avis, comment sont stockés les pixels dans la mémoire ?
 
Tester le circuit sur la carte FPGA. En regardant l'affichage, à votre avis, comment sont stockés les pixels dans la mémoire ?
  
Corriger ce défaut et reprogrammer la carte. Que remarquez-vous maintenant ?  Corriger ce nouveau défaut d'affichage (induit par l'utilisation d'une mémoire synchrone), par exemple en ajoutant un registre 5 bits pour introduire un retard d'un cycle dans la sélection du pixel. Vous avez besoin ici de rajouter l'entrée <tt>CLK</tt> au composant <tt>GeneRGB</tt> comme décrit dans le schéma ci-dessus.
+
Corriger ce défaut et reprogrammer la carte. Que remarquez-vous maintenant ?  Corriger ce nouveau défaut d'affichage (induit par l'utilisation d'une mémoire synchrone), par exemple en ajoutant un registre 5 bits pour introduire un retard d'un cycle dans la sélection du pixel, et un registre 1 bit pour les signaux de synchronisation. Vous avez besoin ici de rajouter l'entrée <tt>CLK</tt> au composant <tt>GeneRGB</tt> comme décrit dans le schéma ci-dessus.

Version actuelle en date du 11 avril 2017 à 07:37

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  Puce.png  Matériel 
Fleche haut.png

Le but de ce TP d'introduction est de maîtriser le petit sous-ensemble du langage VHDL qu'on va utiliser pendant le projet, et de se familiariser avec la programmation de la carte FPGA.

Préparation

Pour bien aborder le TP et comprendre ce que vous allez faire, il faut que vous arriviez en séance en ayant lu la documentation décrivant le fonctionnement d'une carte VGA.

Les fichiers GeneSync.vhd et RAM_VIDEO.vhd qui vous sont fournis ne doivent pas être modifiés : tout le travail demandé doit être implanté dans GeneRGB.vhd et VGA.vhd (vous pouvez créer de nouveaux fichiers pour implanter les registres de la dernière question si vous le souhaitez).

Une fois que vous avez lu la documentation, lisez l'exercice "Affichage basique" ci-dessous et essayer de prévoir ce qui sera affiché une fois le circuit implanté.

Avant de commencer le TP, vous devez récupérer les sources de départ.

A chaque fois que vous compilez du code VHDL ou programmez la carte FPGA, on vous recommande d'exécuter d'abord la commande make clean dans le répertoire contenant vos sources, afin de réinitialiser les répertoires de travail proprement.

N'oubliez pas d'appuyer sur le bouton "SELECT / AUTO" sous l'écran VGA pour ajuster l'affichage après chaque programmation.

Note : vous pouvez ignorer les messages du type : rm: impossible de supprimer «_xmsgs»: Le dossier n'est pas vide qui sont dus à des latences du système de fichiers NFS.

Affichage basique

Soit le schéma ci-dessous, décrivant la structure du circuit que l'on va implanter.

3MMCEP VGA 8couleurs.png

Le composant GeneSync est un bloc qui génère les signaux HSYNC et VSYNC conformément à la norme VGA (pour une résolution de 640x480 pixels). Le signal IMG est à 1 uniquement lorsque le canon à électrons est dans une zone visible de l'image. Si IMG est à 0, alors les signaux R, G et B doivent obligatoirement être à 0 aussi. Les signaux X et Y désignent les coordonnées du pixel de couleurs R, G et B à l'instant considéré.

Question 1

Créer le composant GeneRGB (dans le fichier GeneRGB.vhd) correspondant au schéma ci-dessus (avec un simple éditeur de fichier). Vous devez donc construire le circuit qui calcule les valeurs des signaux R, G et B en fonction de la position (X, Y) du pixel ainsi que du signal de contrôle IMG.

Question 2

Modifier le composant VGA (dans le fichier VGA.vhd) qui interconnecte les composants GeneSync et GeneRGB comme dans le schéma précédent.

Question 3

Simuler le comportement du circuit. (le fichier de test TestBench_VGA.vhd vous est déjà fourni). Pour ce faire taper en ligne de commande make clean TestBench_VGA.view_vcd DUREESIMU=20ms

Vous prendrez soin d'afficher les valeurs des signaux de synchronisation HSYNC et VSYNC, ainsi que du signal IMG.

En regardant l'évolution de leurs valeurs, et en vous aidant de la documentation VGA, essayez de comprendre leur utilité.

Question 4

Vérifier que le fichier de contraintes utilisé (VGA.ucf) pour associer les entrées et sorties du circuit aux pattes du FPGA (les numéros de pattes sont indiqués entre parenthèses sur le schéma) correspond bien à ce qui est souhaité.

Question 5

Programmer la carte (avec la commande make clean VGA.program) , connecter le câble VGA à l'écran et vérifier que l'affichage correspond bien à ce que vous aviez prévu.

Générateur de mire VGA

On souhaite maintenant construire un circuit capable d'afficher la mire ci-dessous (noter bien les différences avec la version précédente : les couleurs a afficher sont rouge, bleu, vert et noir).

3MMCEP VGA Mire.png

Cette mire affiche une bande rouge de 32 pixels de large, puis une bande bleue de 32px, puis une bande verte de 32px, puis une bande noire de 32px, etc.

Question 1

Modifier (après l'avoir sauvegardé) le schéma GeneRGB pour obtenir cette mire.

Question 2

Vérifier en simulation que le circuit se comporte comme prévu.

Question 3

Implanter le circuit sur la carte FPGA.

Affichage d'une image bitmap

Dans cet exercice, on va afficher à l'écran une image bitmap, c'est à dire une image décrite sous la forme d'un tableau dont chaque case correspond à la couleur du point de coordonnées correspondantes. L'image finale que vous devez obtenir est la suivante (cliquer dessus pour la voir en grand) :

3MMCEP VGA Image.jpg

Le circuit que l'on veut réaliser est décrit dans le schéma ci-dessous.

3MMCEP VGA Bitmap.png

L'image que l'on va utiliser est une image en noir et blanc de résolution 320x240px (pour limiter l'espace mémoire nécessaire au stockage de l'image). Comme GeneSync calcule X et Y pour un affichage de résolution 640x480px, il suffit d'utiliser X(9 downto 1) et Y(8 downto 1) pour afficher l'image à la bonne résolution.

La mémoire utilisée travaille avec des mots de 32 bits : cela signifie qu'on trouve les 32 premiers pixels de l'image à l'adresse 0, les 32 suivants à l'adresse 1, etc. On calcule donc l'adresse de la case mémoire contenant le pixel voulu en utilisant la formule addrb <= Y(8 downto 1) & X(9 downto 6) (où & est l'opérateur de concaténation). Par exemple, le pixel de coordonnées (X, Y) = (129, 2) se trouve à l'adresse 0x0024 (c'est à dire 000000100100 en binaire).

Comme chaque mot contient 32 pixels, on va utiliser un simple multiplexeur 32 entrées vers 1 sortie pour extraire le bit voulu. L'entrée de données du multiplexeur sera donc le mot lu en mémoire et l'entrée de sélection X(5 downto 1). Les signaux R, G et B seront alors égaux à la sortie du multiplexeur si IMG vaut 1, et 0 sinon.

Vous pouvez implanter le multiplexeur comme vu en cours ou utiliser la fonction conv_integer prédéfinie dans la bibliothèque standard : cette fonction prend en paramètre un std_logic_vector et renvoie l'entier correspondant.

Question 1

Modifier (après les avoir sauvegardés) les fichiers GeneRGB.vhd et VGA.vhd. Dans cette question, vous n'avez pas besoin d'une entrée CLK pour le composant GeneRGB.

La partie "A" de la mémoire vidéo n'est pas utilisée dans ce TP, dans le fichier VGA.vhd vous pouvez donc :

  • forcer à zéro toutes les entrées inutiles ('0', "000", (others => '0') selon le nombre de bits) ;
  • ne rien associer aux sorties inutiles (mot-clé open) ;
  • pensez à brancher l'horloge CLKB sur l'horloge globale.

Tester en simulation pour vérifier que vos composants sont corrects (même si l'analyse visuelle de la simulation ne vous apportera pas grand-chose !).

Question 2

Tester le circuit sur la carte FPGA. En regardant l'affichage, à votre avis, comment sont stockés les pixels dans la mémoire ?

Corriger ce défaut et reprogrammer la carte. Que remarquez-vous maintenant ? Corriger ce nouveau défaut d'affichage (induit par l'utilisation d'une mémoire synchrone), par exemple en ajoutant un registre 5 bits pour introduire un retard d'un cycle dans la sélection du pixel, et un registre 1 bit pour les signaux de synchronisation. Vous avez besoin ici de rajouter l'entrée CLK au composant GeneRGB comme décrit dans le schéma ci-dessus.