Un contrôleur Vidéo

Introduction

L'objectif de ce microprojet est de bâtir une architecture de  contrôleur  graphique, pour affichage de vidéo sur la maquette FPGA DE10-Nano. Le travail consistera, partant d'une "page blanche"  à construire pas à pas un environnement complet de simulation et de synthèse permettant de vérifier chaque étape du travail:

  • Les contraintes liées à l'implantation sur du matériel "Réel" seront traitées tout au long du projet.
  • Les étudiants disposeront de briques de base (contrôleur de mémoire, générateur vidéo (logiciel),...)
  • Les étudiants disposeront des documentations techniques (carte DE10-Nano, paramètres vidéo,...)
  • Les échanges entre blocs internes seront basées sur le protocole WishBone

La maquette DE10-Nano est basée sur un circuit Cyclone V SoC FPGA. Ce circuit a pour caractéristique de regrouper dans un même boitier une architecture classique de FPGA et un bloc microprocesseur nommé HPS (pour Hard Processor System) composé d'un double processeur ARM Cortex A9.  

Après réalisation des différentes étapes, le système final aura les caractéristiques suivantes :

  • Le contrôleur  graphique  accèdera à une mémoire d'images via une interface Wishbone (nommée wshb_if_sdram dans le projet) .

  • Le contrôleur  graphique  prendra en charge  l'affichage sur un écran LCD via une interface video (nommée video_ifm dans le projet).

  • Un système Linux (déjà opérationnel sur le HPS) transmettra au FPGA, via une interface Wishbone (nommée wshb_if_stream dans le projet) , un flux vidéo destiné à la mémoire d'image 
  • Un arbitre permettra de partager l'accès à la mémoire  entre le contrôleur graphique et  le flux vidéo.
  • Seuls les blocs indiqués en vert seront développés par les étudiants.

Étape 1: Un squelette de projet

ATTENTION : TAG GIT pour cette ETAPE : "SQUELETTE" 

0) Objectif

Nous allons mettre en place un squelette de projet, utilisant quelques ressources disponibles sur la carte fpga DE10-Nano. Nous utiliserons quelques interrupteurs, boutons poussoirs, leds et horloges qui serviront tout au long du projet. Partant d'un squelette de projet "prêt à servir" nous vous laisserons amender ce projet de façon à vous familiariser avec l'ensemble des données et informations à fournir pour mettre en œuvre un design réel sur la carte.

1) Mise en place de l'environnement de travail

  • Placez-vous dans votre dépot  git personnel (cd )
  • Importez les codes de testbench de votre futur bloc:  ​​
  • git checkout master
  • git remote add controleur_video git@gitlab.enst.fr:se204/controleur_video.git
  • git remote update
  • git merge --allow-unrelated-histories controleur_video/master

Le support des blocs matériels déjà codés nécessite une précompilation spécifique . Lancez cette précompilation:

  • Ouvrez une fenêtre de terminal, et placez vous dans le répertoire controleur_video/ips/Qsys
  • Executez la commande "make qsys_compile"
  • Revenez à la lecture du sujet...

2) Arborescence de travail, règles d'écriture

Nous avons préparé une arborescence de travail contenant déjà beaucoup de code, de documents, de scripts... 

Vous n'aurez à intervenir que dans le répertoire SoCFPGA

  • Les sous-répertoires de ce répertoire  sont:
    • Le répertoire src qui ne devra contenir que du code synthétisables de vos blocs.
    • Le répertoire tb_src qui peut contenir tout code pouvant servir à la simulation (testbenchs...)
    • Le répertoire sim, répertoire dans lequel se trouvent les scripts de simulation et dans lequel se déroule la simulation.
    • Le répertoire syn,  répertoire dans le quel se trouvent les scripts de synthèse et dans lequel se déroule la synthèse.
  • Le nom des fichiers créés devra être identique au nom  des modules concernés (un fichier par module)
  • Veuillez respecter les noms proposés  pour les signaux et fichiers de façon à faciliter un déboguage ultérieur, et la création de scripts automatiques pour la vérification.

3) Le module Top

Dans le répertoire "SoCFPGA/src" se trouve  un premier fichier SystemVerilog  Top.sv destiné à contenir le code global du fpga (module Top) . 

  • Examinez le contenu du code du module et lisez les explications suivantes pour en comprendre le contenu

Les entrées/sorties du module sont les suivantes:

Nom Type Nombre de bits Utilisation
FPGA_CLK1_50 entrée 1 Horloge (à 50 Mhz)
KEY entrée 2 Boutons poussoir
LED sortie 8 Affichage LED
SW entrée 4 Interrupteurs 0/1
  • Les entrées/sorties indiquées correspondront à de réelles entrées/sorties du FPGA.
  • Le module fait appel à une  PLL pour générer deux horloges auxiliaires pixel_clk (32 Mhz)  et sys_clk (100MHz) à partir de l'horloge entrante à 50MHz. Ces horloges seront les seules utilisées par vos propres codes.
  • Le module contient 2 interfaces   Wishbone de 32bits:
    • L'interface wshb_if_sdram permettra d'accéder à la mémoidre dynamique de carte DE10_Nano
    • L'interface wshb_if_stream permettra de recevoir un flux vidéo depuis la partie processeur.
    • Les interfaces fonctionnent avec l'horloge sys_clk et sont réinitialisées par le signal sys_rst actif à l'état haut.
  • Le module instancie un sous-module hw_support, chargé
    • de gérer les interfaces
    • de gérer la connection au processeurs
    • de générer le signal sys_rst à partir du bouton KEY[0] 
    • de modifier le comportement des processeurs en fonction de l'état de SW[0].
  • Enfin, comme les interfaces Wishbone ne sont connectées à rien, (pas de maître pour l'interface SDRAM, pas d'esclave pour l'interface stream), nous les neutralisons en plaçant des constantes judicieuses.

4) Première modification du code de Top.

 Écrivez un code dans le module  (après le commentaire Code Eleves) permettant:

  • de recopier la valeur  du signal KEY[0]  vers la led LED[0]
  • de faire clignoter le signal LED[1] à  1Hz en utilisant l'horloge sys_clk. Utilisez un simple compteur binaire dont le reset est sys_rst.

5) Premier environnement de simulation

Il s'agit de créer un environnement minimaliste reproduisant les conditions de fonctionnement réelles du FPGA.

Dans le répertoire SoCFPGA/tb_src,  vous disposez d'un squelette de fichier SystemVerilog tb_Top.sv destiné à contenir le testbench. Il contient la définition des différents signaux externes au bloc Top, et l'instance du bloc Top proprement dit.

Complétez ce code (Code elèves) en ajoutant:

  • Un processus générateur d'horloge à 50Mhz pour générer le signal FPGA_CLK1_50
  • Un processus simulant une action d'initialisation utilisant le bouton KEY[0] 
    • Le bouton KEY[0] doit valoir "1" au démarrage de la simulation
    • Puis passer à "0" au bout de 128ns (valeur arbitraire)
    • Puis passer à "1" au bout de 128ns (valeur arbitraire)
  • Un processus qui ne fait rien, mais stoppe la simulation au bout de 4ms (par exemple) à l'aide de la tâche $stop()

Pour les générateurs d'horloge, vous pouvez vous inspirer du testbench du filtre médian "median-tb.sv"  dans le répertoire simulation de votre projet median. Vous remarquerez que l'on fait simplement une boucle qui fait avancer le temps d'une demi période d'horloge entre chaque changement du signal d'horloge.  La valeur des unités de temps peut être indiquée, et cela peut être un nombre réel.  Attention la précision de ce nombre dépend de la précision avec laquelle le simulateur calcule le temps. Nous avons réglé pour vous cette précision à 1ps dans le Makefile de simulation.

6) Première simulation

Dans le répertoire SoCFPGA/sim, vous disposez un fichier Makefile initial que vous adapterez au fur et à mesure des différentes étapes.  

Avant de lancer la simulation, prenez le temps d'une petite réflexion: Pour compter une seconde avec une horloge à 100Mhz, il faut simuler quelques millions de cycles de l'horloge, vous risquez d'attendre longtemps devant votre écran avant de voir bouger le signal LED[1].

Vous pouvez obtenir un comportement différent en simulation et en synthèse en paramétrant vos compteurs de façon conditionnelle : 

  • Nous avons défini, dans le Makefile, au moment de la compilation des sources, une variable du préprocesseur nommée "SIMULATION" qui peut servir à accélérer la simulation. Par exemple si vous avez un compteur qui compte 50000000 cycles, la simulation peut se faire avec une valeur plus petite comme 50.
  • Vous pouvez utiliser les commandes du préprocesseur `ifdef, `else, `endif  pour définir des paramètres de comptage différents en fonction de la situation

Voici un exemple  (les valeurs proposées sont ici totalement arbitraires) à insérer dans votre code verilog Top.sv .

`ifdef SIMULATION
  localparam hcmpt=50 ;
`else
  localparam hcmpt=50000000 ;
`endif
  • Adaptez votre code pour tenir compte du contexte (simulation/synthèse)
  • Compilez le code de simulation : make compile
  • Executez la simulation : make simu_gui

Vérifiez "visuellement" (chronogrammes) le bon fonctionnement de votre "fpga" et de son environnement associé.

7) Mise en place du mécanisme de rééinitialisation dans le domaine d'horloge pixel_clk:  Le problème du RESET et de la métastabilité.

Le bloc matériel chargé d'envoyer des données vers l'écran LCD utilisera l'horloge pixel_clk. Comme tout bloc de logique synchrone il devra disposer d'un signal de réinitialisation. Nous disposons du  signal sys_rst  mais il est lié à l'horloge sys_clk. Il ne peut pas être utilisé tel quel pour réinitialiser un bloc  matériel utilisant l'horloge pixel_clk.  Au moment du passage en reset, il n'y a pas de problème, que le signal soit utilisé comme reset synchrone ou asynchrone : le système finit toujours par être réinitialisé. Par contre, lorsque le bloc matériel "démarre" , il peut y avoir des phénomènes de métastabilité : dans un système complexe, certaines bascules changent d'état avant d'autres ce qui peut être très dangereux pour des machines à état (passage dans un état non prévu...)

Le schéma suivant se propose de résoudre ce problème d'une façon similaire à celle étudiée pour les changements de domaine d'horloge.

 

 

  • Initialisation : Le passage à "1" du signal sys_rst  provoque la mise à "1" immédiate des deux bascules. 
  • Sortie de l'initialisation : Après le passage à "0" de sys_rst la constante "0" en entrée des bascules est échantillonnée 2 fois pour fournir un signal pixel_rst à "0" en synchronisme avec l'horloge pixel_clk.

A VOUS DE JOUER:

Complétez le module Top :

  • Introduisez un nouveau signal interne pixel_rst
  • Générez le signal pixel_rst en respectant le shéma proposé.
  • Ajoutez un deuxième compteur permettant de faire clignoter le signal LED[2] à  1Hz en utilisant l'horloge pixel_clk. Utilisez un simple compteur binaire dont le reset est pixel_rst.

Vérifiez la resynchronisation ainsi que le bon fonctionnement du deuxième compteur en simulation.

8) Premier environnement de synthèse 

La synthèse en vue d'un téléchargement sur la maquette DE10-Nano nécessite de connaître les ressources disponibles et leurs connexions au FPGA. D'autre part, les entrées/sorties d'un FPGA peuvent être programmées pour s'ajuster aux contraintes éléctriques et temporelles des composants extérieurs. Les outils de synthèse permettent de préciser cela à l'aide de fichiers de contrainte.

Vous disposez, dans le répertoire SoCFPGA/syn des fichiers suivants, prenez le temps de les examiner, car vous devrez adapter certains d'entre eux.

Makefile:

Ce fichier permet de :

  • tester la synthétisabilité de votre code : make test_syn
  • lancer la synthèse   : make syn
  • revoir les messages de l'outil de synthèse sous forme colorée : make log
  • programmation du FPGA : make  program
  • nettoyer le  répertoire de synthèse : make clean

Ce fichier n'est normalement pas à éditer.  Deux variables d'environnement sont définies pour une utilisation dans les scripts de synthèse.

  • PROJECT : c'est le nom du module principal (ici  Top)
  • PROJECT_DIR : le répertoire  principal du projet.

scripts/device_assignment.tcl:

Ce script permet de sélectionner le FPGA cible pour la synthèse. Il s'agit dans notre cas de celui de la carte DE10-Nano. Il faut être précis dans la désignation du circuit pour être d'une part sûr de son brochage et de l'estimation de performances faite par l'outil de synthèse. Si le script ne contient pas les lignes suivantes, alors vous risquez de ne pouvoir programmer votre FPGA...

set_global_assignment -name FAMILY "Cyclone V"
set_global_assignment -name DEVICE 5CSEBA6U23I7

scripts/project_list.tcl:

Ce script permet de définir les fichiers HDL à charger (une ligne par fichier). La syntaxe générale à utiliser est :

set_global_assignment -name langage_source chemin_vers_le_fichier

Où :

  • langage_source est une des trois valeurs SYSTEMVERILOG_FILE, VERILOG_FILE, VHDL_FILE suivant le langage utilisé
  • chemin_vers_le_fichier est le nom du fichier HDL à utiliser. Le chemin peut être absolu, ou relatif. Vous pouvez utiliser l'expression $PROJECT_DIR pour vous référer à la racine du projet.

Pour l'instant, vous n'avez pas à modifier ce fichier.

scripts/timing_constraints.sdc:

 Ce script utilise une syntaxe devenue quasiment une norme de fait en CAO électronique pour définir les contraintes temporelles d'un design. Le suffixe "sdc" signifie "Synopsys Design Constraints" du nom de la société de CAD qui a créé cette syntaxe. Le concepteur doit fournir dans ce fichier toutes les informations "temporelles" susceptibles d'être une contrainte pour le design.

Pour le moment, dans notre cas la première contrainte est d'informer le synthétiseur de l'existence d'un domaine d'horloge liée à l'horloge entrante FPGA_CLK1_50  ayant une fréquence de 50Mhz.  Puis une ligne indique au synthétiseur d'examiner les PLL du design pour en déduire la fréquence des horloges internes générées. Enfin nous demandons au synthétiseur de tenir compte des caractéristiques des PLL pour estimer l'incertitude sur les périodes des horloges.

scripts/pins_assignment.tcl:  

Ce  script permet de définir les entrées/sorties du FPGA.  Prenez le temps de lire les nombreux commentaires de ce fichier qui expliquent  les différents choix faits pour adapter convenablement les signaux entrant et sortant du FPGA aux caractéristiques des circuits externes.

A VOUS DE JOUER

  • Vous trouverez  dans le répertoire "docs" la documentation technique de la carte DE10-Nano
  • Pour chacune des entrées/sorties de votre module (horloge à 50 Mhz, bouton poussoir, interrupteur, leds)  déterminez un élément extérieur au FPGA susceptible d'être utilisé en vous aidant du tableau ci-dessous.
Nom de la pin Ressource pouvant être utilisée
FPGA_CLK1_50 voir chapitre 3.5 Clock Circuitry
KEY voir chapitre 3.6.1 User Push-buttons, Switches and LEDS
SW voir chapitre 3.6.1 User Push-buttons, Switches and LEDS
LED voir chapitre 3.6.1 User Push-buttons, Switches and LEDS
  • Pour chacun de ces éléments, déterminez la patte du fpga qui est connectée.
  • Complétez le fichier "pins_assignments.tcl"  sans oublier de définir le standard "électrique" de la connexion voulue

La syntaxe générale à utiliser est :

set_location_assignment PIN_xxx -to yyy

xxx est le numéro de la patte choisie, et yyy est le nom du signal dans votre module Top.

Enfin pour chacune des entrées/sorties, il convient de définir le standard électrique retenu pour communiquer avec les circuits externes. Dans notre cas nous utilisons une excursion de tension de 3.3V.

  • Pour chacune des entrées sorties que vous avez défini, ajouter la propriété suivante:
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to yyy

Où yyy est le nom du signal dans votre module Top.

9) Première synthèse

Après avoir complété vos fichiers, placez vous dans le répertoire  SocFPGA/syn et lancez un premier test de synthétisabilité (make test_syn ).  Les messages apparaissant à la console sont colorés en vert pour les informations, en bleu pour les warnings, et en rouge pour les erreurs.   

  • Corrigez les éventuelles erreurs et relancer le test jusqu'à leur disparition.
  • Puis lancer la synthèse proprement dite : make syn
  • Cela dure 7 à 8 minutes...
  • Vérifiez les messages de Warning.
  • Ils sont nombreux, et ne concernent pas forcément le code que vous avez écrit. 
  • Ne vérifiez que ceux qui semblent concerner ce que vous avez écrit 

10) Test sur maquette

EN PRESENTIEL

La maquette DE10-Nano étant connectée au PC par le câble USB (port USB-Blaster)

  • tapez la commande make program pour charger le fpga. Une led orange doit s'allumer pour indiquer le bon chargement du FPGA

EN DISTANCIEL

La maquette DE10-Nano étant connectée au PC par le câble USB (port USB-Blaster)

  • Rapatriez sur votre poste personnel  le fichier Top.sof se trouvant dans le répertoire SocFPGA/syn/output_files
  • Suivez les directives de l'annexe "Programmation de la carte DE10-Nano depuis votre PC personnel" pour installer l'outil de programmation quartus_pgm
  • Suivez les mêmes directives pour programmer votre FPGA avec le fichier récupéré.

Vérifiez le fonctionnement du design, et entre autres

Que  LED[0] reproduit l'état de la clef KEY[0]
Que la LED[1] clignote à 1Hz et s'arrète de clignoter si on appuye sur le bouton KEY[0]
Que la LED[2] clignote à 1Hz et s'arrète de clignoter si on appuye sur le bouton KEY[0]

11) CONCLUSION

 Vous disposez d'un squelette permettant de développer votre projet: 

  1. Conservez tout au long du projet les LEDs clignotantes qui permettent de savoir que votre design est actif. 
  2. Conservez de même le dispositif permettant de générer un reset "propre". 
  3. Les messages du synthétiseur sont nombreux. Dans les prochains travaux, vous devrez évidemment éliminer les Erreurs, mais aussi examiner soigneusement les Warnings et déterminer s'ils correspondent à un problème potentiel ou non. Dans la mesure du possible, tentez d'éliminer ces Warnings de façon à détecter plus facilement de nouveau problèmes au fur et a mesure que vous faites évoluer le code.
  4. Vous pouvez à tout moment utiliser la version graphique de l'outil Quartus pour examiner les résultats de synthèse. Pour cela il vous suffit d'ouvrir le projet créé dans l'outil. Faites cependant attention, si vous modifiez votre projet dans l'outil, vous ne retrouverez pas ces modifications dans vos scripts, et ainsi vous ne pourrez plus utiliser le Makefile pour recompiler votre projet.

N'OUBLIEZ PAS !!!  : TAG GIT pour cette ETAPE : "SQUELETTE" 

Étape 2: Un générateur de signaux vidéo

ATTENTION : TAG GIT pour cette ETAPE : "VGA"

0) Objectif

Il s'agit de construire le code d'un dispositif générant des signaux vidéo et les signaux de synchronisation associés permettant de contrôler un écran LCD. De plus, nous voulons plus qu'un simple "code qui marche", mais bel et bien un code paramétrable et réutilisable.

 

 

1) La norme VGA (Video Graphics Array)

La norme d'affichage VGA a été conçue pour afficher des flux vidéo sur un moniteur. Il s'agit d'une suite de pixels correspondant au balayage ligne par ligne, puis colonne par colonne des pixels de l'écran.  Le schéma de transmission reste très fortement influencé par les limitations des anciens moniteurs analogiques.

  • L'horloge pixel n'était pas transmise, mais on indiquait un début d'image ou un début de ligne par une signalisation particulière.
  • Pour permettre au faisceau électronique d'avoir le temps de revenir en début de chaque ligne, ou en début de chaque image, l'image était transmise en ménageant des intervalles de temps neutres (entre lignes et images). Ces intervalles sont appelés intervalles de suppression ou "blanking" en anglais.

Cela aboutit au schéma de transmission suivant pour notre carte DE10-Nano:

  • Le flux vidéo est cadencé par l'horloge pixel_clk.
  • Chaque pixel RGB est un mot de 24 bits, contenant  les 3 composantes colorées Rouge, Vert et Bleu codées chacune sur  8 bits. 
  • Chaque image est transmise de haut en bas ligne par ligne.
  • Chaque ligne est transmise de gauche à droite  pixel par pixel. 
  • Le début d'une image est signalé par un signal de synchronisation spécifique VS pour Vertical Synchro actif à l'état bas.
  • Le début d'une ligne  est signalé par un signal de synchronisation spécifique HS pour Horizontal Synchro actif à l'état bas.
  • Les intervalles de suppression ou "blanking" , c'est à dire sans transmission de pixel,  sont signalés par un signal spécifique BLANK actif à l'état bas.

Les durées des lignes, des images, des signaux de synchronisation et des intervalles de blanking sont normalisées (en nombre de cycles de pixel_clk) et doivent être respectées pour garantir la bonne synchronisation de l'écran.

L'évolution temporelle des signaux peut être représentée sur un diagramme à deux dimensions (la dimension horizontale correspondant aux pixels, la dimension verticale correspondant aux lignes).

 

 

 

Les paramètres temporels choisis pour notre affichage LCD sont les suivant :

Paramètre Commentaire Valeur Unité
Fpix fréquence pixel 32 Mhz
Fdisp fréquence image 66 images/sec
HDISP Largeur de l'image affichée 800 pixels
VDISP Hauteur de l'image affichée 480 lignes
HFP Horizontal Front Porch40 40 pixels
HPULSE Largeur de la synchro ligne 48 pixels
HBP Horizontal Back Porch 40 pixels
VFP Vertical Front Porch 13 lignes
VPULSE Largeur de la sync image 3 lignes
VBP Vertical Back Porch 29 lignes

 

2/ Squelette du contrôleur VGA

  • Dans le répertoire SoCFPGA/src, créez un fichier vga.sv qui contiendra un module nommé vga.  

Pour simplifier la définition des entrées/sorties, nous avons préparé la définition d'une interface video_if dans le fichier  ips/interfaces/video_if.sv

  • Créez le squelette du module (module vga... endmodule) en lui attribuant les entrées/sorties suivantes :
Nom de l'entrée/sortie Type de l'entrée sortie Commentaire
pixel_clk Entrée horloge entrante du module
pixel_rst Entrée initialisation,  actif à l'état haut
video_ifm Modport master de l'interface video_if  Tous les signaux destinés à l'écran passeront par cette interface. Le module vga est un maître.

3/ Génération des signaux de synchro (dans le module vga)

Pour faire simple, il s'agit de ne générer que les signaux de synchronisation associés au flux video.

  • Le cœur du contrôleur est donc constitué de deux compteurs: un compteur de pixels dans une ligne, et un compteur de lignes dans une image. 
  • Tous les signaux sont synchrones de  l'horloge pixel_clk. Le signal de remise à zéro sera pixel_rst
  • Les constantes pour les timings seront fournies via des paramètres locaux (localparam) dont les noms sont indiqués en gras dans le tableau du paragraphe 1.
  • Les constantes  HDISP et VDISP seront des paramètres (parameter) et devront pouvoir être modifiées lors de l'instantiation du module vga.
  • Les valeurs des paramètres par défaut seront celles correspondant à  l'écran LCD de la maquette (image 800x480).
  • Le dimensionnement des différents compteurs (nombre de bits) et les différentes comparaisons de valeurs devront se faire par calcul à partir des paramètres prédéfinis,  à l'exclusion de tout codage en "dur" de constantes. 
  • Les  signaux de synchronisation  (video_ifm.HS, video_ifm.VS, video_ifm.BLANK)  seront calculés à partir de l'état des compteurs pixels et lignes. Ils devront eux même être synchrones.
  • Enfin, le signal video_ifm.CLK sera simplement  pixel_clk.  
  • Ne cherchez pas à simuler pour l'instant, compilez éventuellement avec vlog pour vérifier la syntaxe.

4/ Génération d'une mire (dans le module vga)

Il s'agit de générer une image calculée à la volée pour vérifier le bon fonctionnement de l'ensemble du module. La mire demandée sera très simple:

  • Un fond noir, des colonnes blanches tous les 16 pixels, des lignes blanches toutes les 16 lignes. Attention, les signaux de couleur sont codés sur 8 bits (min=0, max=255)
  • Générez le signal video_ifm.RGB  de manière synchrone de façon à créer la mire en vous appuyant sur les valeurs des compteurs de la synchronisation. Les octets R, G et B sont concaténés dans le mot RGB sous la forme d'un vecteur {R,G,B}.
  • Attention: avant de générer la mire, il peut être utile de calculer des coordonnées relatives des pixels actifs à partir des compteurs, de façon a obtenir une coordonnée (0,0) pour le premier pixel actif de l'image.
  • Ne cherchez pas à simuler pour l'instant, compilez éventuellement pour vérifier la syntaxe.

5/ Mise à jour du module Top pour intégrer le module vga.

Le contrôleur vga est un sous-module de Top . Vous l'intégrerez de la façon suivante:

  1. Créez une instance de vga dans Top.
  2. Connectez le signal pixel_clk au signal de même nom de votre instance (l'horloge à 32 Mhz)
  3. Connectez le signal pixel_rst au signal de même  nom de votre instance.
  4. Enfin, connectez le port d'interface video_ifm à une interface de même nom.

Cette dernière interface doit être directement connectée au monde extérieur :

  1. Modifier la liste des E/S de Top en ajoutant un port nommé video_ifm de type modport master d'une interface de type video_if (la syntaxe est identique à celle utilisée dans vga).
  2. Enfin, rendez le module Top paramétrable:
    1. Ajoutez deux paramètres HDISP et VDISP ayant pour valeurs par défaut 800 et 480.
    2. Modifiez l'instanciation de vga de façon à ce que les paramètres HDISP et VDISP ainsi créés se propagent à vga.
  3. Ne cherchez pas à simuler pour l'instant, compilez éventuellement pour vérifier la syntaxe.

6/ Mise à jour du testbench de fpga pour évaluer votre générateur VGA.

La véritable interface video_if à laquelle est connecté le contrôleur vga via le module Top doit être instanciée dans le tesbench:

  • Dans tb_Top.sv, ajoutez une instance de video_if. Donnez-lui un nom quelconque, par exemple video_if0.
video_if video_if0() ;
  • Modifiez l'instanciation de Top  de façon à ce que les paramètres HDISP et VDISP soient forcés à  160 et 90. Il s'agit, une fois de plus,  de limiter en simulation le nombre de cycles à attendre de manière raisonnable tout en conservant en synthèse les valeurs par défaut.
  • Connectez le module Top à l'interface video video_if0.

7/ Première simulation 

Lancez la simulation en mode graphique, visualisez les signaux "importants" (ceux de l'interface video_if0) et tentez de vérifier "visuellement" le bon comportement de votre contrôleur vga. 

8/ Une vérification plus complète.

Nous avons préparé pour vous un module screen "testeur" de signaux vga. Ce testeur a deux fonctions:

  • Vérifier la validité des signaux de synchronisation en fonction du mode souhaité.
  • Créer un fichier contenant l'image générée par votre code.

Modifiez tb_Top de manière à instancier  le module screen connecté à l'interface video_if0 . Cela devrait ressembler à quelque chose comme ceci 

 screen #(.mode(13),.X(160),.Y(90)) screen0(.video_ifs(video_if0))  ;

Le paramètre mode égal à 13 permet de sélectionner des paramètres de synchro d'images correspondant à votre écran LCD, les paramètres X et Y permettent d'ajuster la taille de l'image à quelque chose de plus raisonnable. Évidemment vous devez choisir les mêmes que ceux choisis pour instancier Top.

Relancez la simulation (le mode batch suffit).

  • Vous devriez voir apparaître des messages d'erreur explicites sur le non respect des valeurs attendues.
  • Si vous êtes chanceux, les seuls messages indiquent les générations successives d'images.

Après la simulation, vous pouvez afficher la dernière image générée :

  • display work/screen_dump.ppm

Enfin, si vous faites évoluer la mire et si vous simulez suffisamment de temps, vous pouvez afficher approximativement la séquence vidéo en lançant l'affichage en parallèle avec la simulation:

  • display -update 1 screen.ppm 

9/  Adaptation de la synthèse à la nouvelle version du code

Définitions des pattes d'entrée/sortie (fichier syn/scripts/pins_assignement.tcl)

  • Nous avons préparé un fichier de contraintes spécifique pour les E/S VGA. Vous devez simplement modifier le fichier pins_assignement.tcl en supprimant le commentaire dans la ligne incluant le source pins_assignement_vga.tcl. Le résultat devrait être:
# Le E/S du contrôleur VGA
source pins_assignment_vga.tcl

Liste des fichiers pour la synthèse (fichier syn/scripts/project_list.tcl)

  • Compléter le fichier project_list.tcl par les définitions des nouveaux fichiers source nécessaires au module vga. 
  • Il s'agit des fichiers suivants:
    • $PROJECT_DIR/ips/interfaces/video_if.sv
    • $PROJECT_DIR/SoCFPGA/src/vga.sv
  • Attention les définitions doivent être placées avant  celle du fichier Top.sv

10 / Synthèse

  • Synthétisez votre design, corrigez les erreurs.
  • En ce qui concerne les Warnings, interrogez vos encadrants pour déterminer s'ils sont importants ou non.

11/ Test sur la maquette

  • Programmez votre maquette (make program)
  • Faites un reset de la maquette (key[0])/
  • Et constatez le bon fonctionnement éventuel.
  • Si cela ne fonctionne pas, revérifiez toutes les étapes.

13/ Conclusion

  • Nous sommes maintenant prêts à stocker les images en mémoire (framebuffer) plutôt que de les générer à la volée. C'est l'objectif de l'étape suivante.

 

N'OUBLIEZ PAS ! : TAG GIT pour cette ETAPE : "VGA"

Étape 3: Utilisation d'une mémoire tampon pour l'image.

ATTENTION : TAG GIT pour cette ETAPE : "SDRAM"

0) Objectif

La carte  DE10-Nano comporte 1GB de mémoire SDRAM (voir DDR3, Figure 2-1 de la documentation de la carte). Cette mémoire est partagée entre le HPS (les processeurs ARM) et la partie FPGA.  Nous allons utiliser une zone de cette mémoire comme mémoire d'image, ou  "frame buffer", pour stocker la mire plutôt que de la générer "à la volée".

  • Le module vga viendra donc lire de façon régulière le contenu de cette zone mémoire, de manière à fournir les pixels pour l'écran.

  • La mire, elle même, sera créée par le système Linux qui tourne sur le HPS.

1) Les "Synchronous Dynamic Ram" et les contrôleurs de DRAM.

Avant d'utiliser cette mémoire, il est bon de connaitre quelques particularités de ce type de composant afin de bien comprendre la nécéssité d'utiliser un "contrôleur de DRAM". L'accès aux données d'une SDRAM n'est pas aussi simple que l'accès aux données d'une mémoire statique. L'opération de transfert, que ce soit en lecture ou en écriture, nécessite une séquence d'opérations mettant en oeuvre plusieurs signaux de contrôle. D'autre part, cette séquence d'opérations dépend d'un état interne de la SDRAM.  Enfin, à la différence de la mémoire statique, la SDRAM finit par perdre ses données même si son alimentation est maintenue. Il faut mettre en oeuvre, de manière régulière, des séquences dites de rafraichissement, pour maintenir les données dans la mémoire. En conséquence, nous retiendrons les points suivants :

  • L'usage d'une SDRAM nécessite l'utilisation d'une unité de contrôle spécialisée, prenant en charge le séquencement des opérations d'accès ainsi que le rafraichissement de la mémoire.
  • Le nombre de cycles nécessaires à  l'accès à une donnée (que ce soit en lecture ou en écriture) n'est pas garanti, car il dépend de l'état interne de la SDRAM.
  • Enfin, la SDRAM étant partagée entre le HPS et le FPGA, le temps d'accès peut dépendre de la charge logicielle.

Nous vous fournissons pour cette étape, un accès au contrôleur de sdram compatible avec le bus Wishbone. Vous n'aurez donc pas à vous soucier du détail de l'accès à la SDRAM, mais simplement à générer des requêtes Wishbone correctes.

2) Première adaptation du module VGA

  • Dans les entrées/sorties du module vga, ajoutez un port correspondant à l' interface wshb_if  de type master et nommée wshb_ifm. Cette interface permettra d'échanger des données de 32 bits avec une fréquence de bus de 100MHz.

Dans une première phase, nous allons modifier le module vga pour créer un maitre Wishbone "bidon" dont le seul rôle est de vérifier une instanciation correcte des différents éléments:

  • Générez sur wshb_ifm des requètes d'écriture permanentes, en assignant les valeurs constantes suivantes:
Nom valeur Commentaire
wshb_ifm.dat_ms 32'hBABECAFE Donnée 32 bits émises
wshb_ifm.adr '0 Adresse d'écriture
wshb_ifm.cyc 1'b1 Le bus est sélectionné
wshb_ifm.sel 4'b1111 Les 4 octets sont à écrire
wshb_ifm.stb 1'b1 Nous demandons une transaction
wshb_ifm.we 1'b1 Transaction en écriture
wshb_ifm.cti '0

Transfert classique

wshb_ifm.bte '0 sans utilité.

4) Adaptation du module Top

  • Dans le module Top, vous disposez  déja d'une instance de l'interface wshb_if_sdram  vers le contrôleur de sdram, le code est le suivant:
  wshb_if #( .DATA_BYTES(4)) wshb_if_sdram  (sys_clk, sys_rst);
  • Cette interface est pour le moment neutralisée. Il faut supprimer cette neutralisation. Pour cela, commentez la zone de code où l'on assigne des valeurs constantes aux signaux de wshb_if_sdram.
  • Enfin, modifiez l'instanciation de vga dans Top de manière à connecter le port wshb_ifm de Top à l'interface wshb_if_sdram.

5) Première simulation

Le testbench Tb_Top.sv contient déjà tous les modules nécessaires pour simuler l'accès à la SDRAM. Il suffit donc de lancer la simulation:

  • Compilez (make compile) et simulez (make simu_batch) la chaine totale tb_Top.
  • Corrigez les différentes erreurs.
  • Relancez la simulation en mode graphique  et visualisez les signaux du module Top ainsi que les signaux internes à l'interface wshb_if_sdram dans Top
  • Vérifiez que le bloc vidéo fonctionne toujours.
  • Vérifiez le bon fonctionnement du bus wshb_if_sdram: des transactions en écriture démarrent, des acquittements sont générés,  les  données "BABECAFE" transitent vers la SDRAM.

Si vous ne voyez pas tout cela, en désespoir de cause, faites appel à un encadrant...

6) Adaptation finale du module VGA pour la lecture de la SDRAM

Modifiez le module vga pour qu'il fonctionne de la façon suivante (lisez toute l'explication avant de commencer le codage):

6.1/ Lecture en SDRAM

  • Les signaux d'horloge et de remise à zéro à utiliser doivent être ceux du bus wshb_ifm.
  • Après la remise à zéro, un contrôleur (codé par vous même) génère des requètes de lectures de pixels sur l'interface Wishbone, en bouclant en permance pour lire une mire supposée être stockée dans la mémoire SDRAM.
    • Les pixels sont stockés par mots de 32bits, la couleur étant codée sur les 3 octets de poids faible
    • Seuls les pixels de la zone affichable de taille VDISPxHDISP sont stockés.
    • Les pixels sont stockés de manière consécutive dans la mémoire, à partir de l'adresse 0.
    • Attention les adresses Wishbone sont des adresses "octet" : un  pixel de coordonnée (x,y) sera accessible en adresse 4*(HDISP*y+x).
    • Les transactions sur le bus Wishbone sont validées par le signal stb. Le signal cyc étant maintenu à 1 en permanence. 
    • Seul le retour du ack en provenance du contrôleur  mémoire fait avancer le processus à la lecture du pixel suivant.
    • Un fois l'image entièrement lue, le processus boucle sur lui-même indéfiniment pour relire en permanence toute l'image.

Après codage, simulez en l'état votre système. Le testbench que nous fournissons contient une mire dont vous devriez voir les pixels défiler. Vérifiez bien que vous lisez exactement HDISPxVDISP pixels et que vous réenchaînez bien des relectures successives de l'image.

6.2/ Ecriture en FIFO

Les pixels lus arrivent à un rythme qui dépend des disponiblilités du contrôleur de SDRAM et qui ne correspond pas à celui de la vidéo. De plus,  l'horloge du bus Wishbone n'est pas corrélée avec celle de l'affichage VGA. Nous allons utiliser une FIFO asynchrone pour faire le tampon entre le processus d'écriture et l'affichage des pixels.

  • Nous utiliserons une fifo de 256 données de 32 bits. Son code se trouve dans le fichier ips/fifos/async_fifo .
  • Attention, le paramètre DEPTH_WIDTH ne représente pas le la profondeur de la FIFO mais le log2 de la profondeur (fournir 8 pour obtenir 256 données) 
  • Instanciez la FIFO dans le code de vga en créant de nouveaux signaux dont vous affecterez les valeurs plus tard.
  • Le signal de remise à zéro de la fifo sera celui du bus Wishbone.
  • Les pixels lus sur le bus Wishbone sont écrits dans la FIFO au rythme de leur arrivée et de l'horloge Wishbone.
  • Si la FIFO est pleine, le contrôleur de lecture doit arrêter de faire des requêtes sur le bus et doit attendre que la FIFO ne soit plus pleine (il faut modifier votre contrôleur précédent pour cela).
  • Simulez votre système: vous devriez voir une série de lectures sur le bus Wishbone suivie d'un arrêt dès que la FIFO est pleine.

6.3/ Lecture de la FIFO.

Le contrôleur vga devra piloter la lecture des pixels dans la FIFO, tout en garantissant que la première donnée lue corresponde au premier pixel affichable de l'écran. Pour cela le dispositif sera le suivant:

  • La lecture dans la FIFO se fait au rythme de l'horloge pixel, uniquement dans la zone d'affichage (BLANK=1).
  • La toute première lecture ne pourra pas avoir lieu tant que la FIFO n'aura pas été pleine au moins une fois avant le début d'une zone d'affichage.
  • Attention, le signal wfull de la FIFO est dans le domaine de l'horloge wshb_ifm.clk et vous devrez l'exploiter dans le domaine de l'horloge pixel_clk. Vous savez ce qu'il faut faire...
  • Supprimez le générateur de mire: La donnée lue dans la FIFO sera directement affectée au pixel à afficher.

7) Simulation et vérification du résultat

Si vous avez respecté ce cahier des charges et utilisé les mếmes résolutions pour la simulation que celles proposées dans les étapes précédentes, vous devriez obtenir ceci:

8) Synthèse 

  • Ajoutez le  module FIFO  dans le fichier  syn/scripts/project_list.tcl
​set_global_assignment -name SYSTEMVERILOG_FILE $PROJECT_DIR/ips/fifos/async_fifo.sv
  • Lancez la synthèse.
  • Corrigez les éventuelles erreurs (si nécessaire, refaites la simulation après correction.)

9) Test sur la maquette 

Attention: Comme indiqué en introduction, la mire affichée est générée par le HPS. Ainsi, pour que tout fonctionne bien, il faut démarrer le système Linux.

  • Programmez le FPGA (make program)
  • Redémarrez le système Linux. Pour cela il faut appuyer sur le bouton WARM_RST que vous pouvez trouver dans la vue suivante.
  • Il faut attendre 10 à 30 secondes et vous devriez voir une mire.
  • Vous pouvez utiliser une autre mire en changeant la position de l'interrupteur SW[0], le plus a droite des 4 interrupteurs entourés en vert.

10) Conclusion

  •  N'OUBLIEZ PAS  : TAG GIT pour cette ETAPE : "SDRAM"

Étape 4: Deux maîtres Wishbone et un arbitre

ATTENTION : TAG GIT pour cette ETAPE : "ARBITRE"

1) Introduction

L'architecture réalisée n'est pas très réaliste. Dans la pratique, l'image affichée n'est pas stockée dans la SDRAM de manière statique mais générée par un dispositif extérieur tel qu'un microprocesseur ou un décodeur vidéo. L'accès au contrôleur SDRAM doit donc être partagé entre le bloc vga et cet autre dispositif. Pour se rapprocher d'une telle structure nous allons mettre en place (dans Top) l'organisation suivante:

  • Le contrôleur vga est inchangé.
  • Un module mire sera créé. Son seul port d'entrée/sortie est une interface Wishbone. Son rôle est d'écrire une mire dans la mémoire SDRAM, et de répéter indéfiniment cette opération.
  • Le module Top contiendra  deux nouvelles interfaces Wishbone :

    • wshb_if_vga  dédiée aux transferts de données du module vga qui ne pourra plus accéder directement au contrôleur de SDRAM.

    • wshb_if_mire  dédiée aux transferts de données de la mire.

  • L'accès au contrôleur de SDRAM étant maintenant partagé par deux modules totalement indépendants, il faut intercepter et arbitrer les requêtes des deux blocs. Un nouveau module wshb_intercon aura pour rôle de:
    • Détecter les requêtes en provenance des deux maitres (en se basant sur les signaux cyc des interfaces Wishbone).
    • Élire un maître.
    • Mettre en correspondance les signaux du maître élu avec les signaux de l'interface maître.
    • Neutraliser les signaux du maître "non élu" pour le forcer à attendre.

La structure codée dans Top sera donc la suivante (les blocs en vert correspondent aux instances des sous-modules, les blocs en rouge correspondent aux instances des interfaces).

2) Travail à réaliser

  • Créer un module mire chargé d'écrire une mire de manière permanente. Attention, le module mire devra être "fair-play" c'est-à-dire ne pas maintenir une demande d'écriture permanente de manière à permettre à l'arbitre de donner la main au module vga. Pour cela vous pouvez, par exemple, insérer un cycle à vide (avec cyc et stb à 0) toutes les 64 requêtes d'écriture.
  • Modifiez (si ce n'est pas déjà le cas) le module vga pour que son signal cyc soit identique à stb. Ainsi, le module vga sera lui-même "fair-play". Quand sa FIFO est pleine, il laisse le module mire prendre éventuellement la main sur le bus Wishbone.
  • Créez le module wshb_intercon pour mettre en place le mécanisme d'arbitrage et de sélection des signaux.  Vous coderez un arbitre équitable basé sur un passage de jeton. Dans la mesure ou le module mire et le module vga rendent la main de manière régulière, il suffira d'observer le signal cyc de chacun des modules:
    • Si le module mire a le jeton et si son signal cyc est à 0, alors l'arbitre donnera le jeton au module vga.
    • Si le module vga a le jeton et si son signal cyc est à 0, alors l'arbitre donnera le jeton au module mire.
  • Modifiez enfin le module Top pour mettre en place les nouvelles interfaces ainsi que les nouveaux modules.
  • Vérifiez par simulation le bon fonctionnement de l'ensemble.
  • Adaptez les fichiers pour la synthèse (project_list.tcl), synthétisez...
  • Testez sur la carte...

N'OUBLIEZ PAS : TAG GIT pour cette ETAPE : "ARBITRE"

Étape 5: Un flux vidéo réaliste

TAG pour cette étape: FLUX

0) Introduction

Cette dernière étape consiste à supprimer le générateur de mire et de récupérer à sa place le flux vidéo en provenance du tampon d'images standard provenant du système Linux tournant sur le HPS. Nous devrions alors disposer d'un gestionnaire de fenêtres classique. L'écran LCD étant tactile nous pourrons de plus interagir avec l'affichage.

1) Adaptation du module Top

  • Supprimez ou commentez l'instanciation du module mire dans le module Top
  • Supprimez ou commentez l'instanciation de l'interface wshb_mire dans le module Top
  • Nous allons utiliser un flux vidéo provenant de l'interface stream. Cette interface est pour le moment neutralisée. Il faut supprimer cette neutralisation. Pour cela, commentez la zone de code où l'on assigne des valeurs constantes aux signaux de wshb_if_stream.
  • Enfin, connectez le port  wsb_ifs_mire  du module wshb_intercon à l'interface wshb_if_stream déjà présente dans Top.

2) Simulation

Le testbench contient tout ce qui est nécessaire, faites simplement la simulation et examinez les images obtenues pour vérifier le bon fonctionnement.

3) Synthèse et test sur la maquette

  • Relancez une synthèse complète.
  • Programmez votre maquette.
  • N'oubliez pas de faire un redémarrage de Linux en utilisant le bouton WARM_RST.
  • Vous devriez avoir l'affichage du  gestionnaire de fenêtre. Avec une souris active...

Vous constaterez probablement que l'image générée est stable, mais pas convenablement synchronisée. Nous allons tenter de résoudre cela 

4) Causes des problèmes de synchronisation

Comme indiqué précédemment, la mémoire SDRAM est partagée entre le HPS et le système que vous avez développé. Ainsi, pendant le démarrage du système, la mémoire est fortement sollicitée, il est possible alors que le module vga ne soit pas capable de récupérer les données à un rythme suffisant.

5) Amélioration du module vga

Pour éviter les décalages de l'image affichée il faut donner plus de temps au module vga pour récupérer des données à afficher.  En effet, la lecture d'un paquet de données en mémoire souffre de la latence de l'accès à la mémoire (plus d'une dizaine de cycles par paquet de données). En conséquence, plus la taille du paquet est élevée, plus le débit moyen est élevé. 

La FIFO asynchrone, de votre module vga possède un signal supplémentaire nommé walmost_full qui indique si la FIFO est "presque" pleine en se basant sur un paramètre ALMOST_FULL_THRESHOLD.

Nous allons mettre en place un dispositif à hysteresis:

  • Forcez le paramètre ALMOST_FULL_THRESHOLD à la valeur 224 (soit 256-32). Ainsi le signal walmost_full sera à 0 lorsque la FIFO disposera d'au moins 32 places vides.
  • Modifiez le signal cyc pour qu'il soit synchrone et suive le comportement suivant:
    • Si la FIFO a suffisemment de places vides alors cyc passe à 1.
    • Si la FIFO est pleine alors cyc passe à 0

Ainsi, nous aurons la garantie que lorsque vga a le jeton, vga fera une requête d'au moins 32 données dans la mémoire. 

  • Faites ces modifications et vérifiez que la nouvelle version de l'architecture est moins sensible aux erreurs de fifo.

6) Test de robustesse

Nous pouvons forcer la mémoire du système à être plus sollicitée, et vérifier ainsi la robustesse de notre contrôleur vidéo.  Pour cela:

  • Sélectionnez le choix Autre dans le menu en bas à gauche de l'écran.
  • Sélectionnez le choix bigbuckbunny

Cela lance une séquence vidéo.  Refaites plusieurs fois cette opération, au bout d'un certain temps votre image devrait de nouveau se désynchroniser...

N'oubliez pas le TAG pour cette étape: FLUX

 

Annexe: Programmation de la carte DE10-Nano depuis votre PC personnel

Chacun des étudiant dispose d'une maquette pour travailler le plus possible en autonomie.  Si l'installation en local de l'ensemble des logiciels nécessaires au projet est lourde, il est néamoins possible d'installer l'outil de programmation du FPGA. 

Pour cela nous supposons le scénario suivant:

  1. Vous disposez d'un PC personnel.
  2. Vous disposez d'une connection permettant d'accéder au réseau de l'école.
  3. Vous vous connectez au réseau de l'école via le VPN de manière à accéder simplement aux machines de nos salles de TP (par exemple tp3a107-xxx).
  4. Vous utilisez les outils de simulation et de synthèse sur les machines de l'école.
  5. Après synthèse vous  recopiez  le fichier controleur_video/SoCFPGA/syn/output_files/Top.sof sur votre PC personnel
  6. Vous programmez la maquette avec l'outil de programmation préalablement installé.

1) Travail sous Windows

Pour les utilisateurs de PC Windows, récupérez l'installeur situé dans le chemin suivant:

/comelec/softs/opt/altera/installers/QuartusProgrammerSetup-20.1.0.711-windows.exe
  • Executez l'installeur
  • En ce qui concerne le mode d'emploi, s'inspirer du paragraphe 2.4 sous Linux...

2) Travail sous Linux

C'est un peu plus compliqué...

2.1) Installation de l'outil de programmation sur PC Linux

Récupérez l'installeur situé dans le chemin suivant (par exemple dans /tmp)

/comelec/softs/opt/altera/installers/QuartusProgrammerSetup-20.1.0.711-linux.run
  • rendez le exécutable:
chmod +x /tmp/QuartusProgrammerSetup-20.1.0.711-linux.run
  • Exécutez le. Vous devriez avoir dans votre home un répertoire intelFpga.
  • Testez l'outil de programmation en mode graphique.
~/intelFPGA/18.1/qprogrammer/bin/quartus_pgmw

2.2) Autorisations d'accès utilisateur au programmateur de FPGA

La programmation du FPGA se fait par un port USB. Pour que l'outil de programmation quartus_pgmw puisse accéder à votre maquette, il faut demander au service udev de détection des `devices` de modifier les droits d'accès. Pour cela:

  • Récupérez le fichier de gestion des règles de propriété udev:
/comelec/softs/opt/altera/installers/z99_quartus_pgm.rules
  • Copiez (en tant que root)  le z99_quartus_pgm.rules dans le répertoire /etc/udev/rules.d
  • relancez le service `udev`, pour cela exécutez : systemctl restart udev en tant qu'utilisateur root
  • Si votre Linux n'utilise pas systemctl, utilisez la bonne méthode ou ... rebootez simplement votre machine

2.3) Test de l'installation

  • branchez la maquette (port USB marqué `USB BLASTER`) à votre PC.
  • Lancez la commande quartus_pgm -l

Vous devriez avoir un message indiquant la détection de la carte:

Info: Command: quartus_pgm -l

1) DE-SoC [1-3]

Les chiffres correspondent au numéro du port USB. Si cela ne marche pas le message est :

Info: Command: quartus_pgm -l

No JTAG hardware available

2.4) Utilisation de l'interface graphique pour la programmation

  • Lancez la commande quartus_pgmw
  • Sélectionnez le menu Hardware Setup.
  • Vous devriez voir, dans Available hardware items, un item DE-SoC.
  • Sélectionnez le en double-cliquant sur DE-SoC
  • Fermez la fenêtre de sélection de hardware
  • Sélectionnez le menu Auto Detect et acceptez la proposition faite (5SEBA6)
  • Double cliquez sur le champ correspondant au device 5SEBA6 (ignorez l'autre ligne), et fournissez le fichier Top.sof que vous avez récupéré.
  • Cliquez le drapeau Program/Configure correspondant au device 5SEBA6
  • Cliquez sur Start
  • La programmation démarre (une led verte s'allume sur la maquette).
  • Une fois le fpga programmé une led orange s'allume sur la maquette.

3) Installation conjointe de questasim/quartus pour Linux

Cette archive est plus volumineuse mais elle contient les différends outils (même le programmeur). Cette installation a été testée sur Debian 10 et Ubuntu 18.4/20.4 mais devrait fonctionner dans d'autres environnements.
  • Récupérez l'archive (ATTENTION elle fait 7.7Go):
/comelec/softs/opt/altera/installers/quartus-medelsim.tar.xz
  • MD5: da58e15beeae0b5ed32fbad90a5f6939
  • Décompressez l'archive dans le répertoire /opt de votre PC
cd /opt && sudo tar xJvf CHEMIN_VERS_L_ARCHIVE/quartus-medelsim.tar.xz
  • Vous devez obtenir un répertoire /opt/comelec avec les différents outils

Utilisation des outils

  • Activez le VPN (nécessaire pour accéder aux licences)
  • Configurez votre PATH
    • export PATH=/opt/comelec/bin:$PATH
  • Testez que ça fonctionne
    • quartus_sh -v
    • vsim -version
  • Pour programmer la carte, vous avez besoin de déployer les règles udev (voir plus haut ou dans /opt/comelec/TODO/LISEZMOI )