Demo Qsys : Apprentissage à la conception orientée système sur FPGA

Introduction

Le but de cette séance est de présenter une plateforme d'intégration système pour construire un système autour d'un cœur de microprocesseur dans un FPGA.

Dans cette séance, nous utiliserons un FPGA de la famille Cyclone V d'Altera ainsi que l'outil d'intégration Qsys. De plus le cœur de processeur que nous utiliserons sera le Nios ii, un cœur de processeur soft disponible avec les outils d'Altera.

Notez qu'il existe des équivalents de cet outil chez d'autres fabricants de circuit FPGA. Nous pouvons citer par exemple, Vivado de Xilinx ou Libero SoC de Microsemi. Les concepts abordés durant cette séance se retrouveront aussi sur ces différents outils.

De plus, nous montrerons comment s'interfacer avec des outils de développement logiciel pour écrire des programmes simple en C.

Système de base

Le système de base que nous allons construire sera composés des éléments suivants:

  • un processeur niosii dans une configuration de base
  • une uart pour pouvoir communiquer par un lien série avec la plateforme
    • physiquement cette liaison utilisera le lien USB qui sert à programmer le FPGA
    • la même interface servira aussi au débug
  • une mémoire qui utilisera les blocs internes du FPGA
  • des périphériques simples permettant de contrôler les leds et d'accéder aux interrupteurs

Le tout est connecté sur un bus qui utilise le protocole Avalon d'Altera.

Le schéma suivant montre la structure de ce système de base.

Les étapes par lesquelles nous passerons sont:

  1. construire le système dans Qsys
  2. intégrer ce système dans le flot FPGA
  3. écrire un logiciel de test pour tester le fonctionnement des périphériques

Construire le système de base dans Qsys

Pour simplifier l'intégration du système dans le flot FPGA nous partirons d'un projet Quartus existant. Pour cela nous commencerons par lancer quartus.

Dans Quartus, vous pouvez ouvrir le projet de référence pour la carte DE1-SoC qui vous est fourni. Dans le menu File selectionnez l'item Open Project... puis sélectionner le fichier DE1-SoC.qpf.

Ce projet contient un unique fichier SystemVerilog représentant les entrées/sorties du FPGA ainsi que toutes les contraintes nécessaires pour y associer les pins physiques.

À partir du menu Tools lancer Qsys.

Vous devriez obtenir une fenêtre semblable à la figure suivante.

C'est la base du système que nous allons construire.

Tout système possède au minimum une horloge et une entrée de remiser à zéro, ici, clk et reset. Notez que ces deux signaux apparaissent dans la colonne export, ce qui veut dire qu'ils viendront de l'extérieur du système.

Ajouter des éléments

Sur le panneau latéral gauche IP Catalog nous avons la liste des IPs disponible. Certaines ont été fournies avec l'outil, d'autres installées par la suite.

Le premier élément que nous allons ajouter au système sera le processeur, Nios II. Nous le trouverons dans la catégorie Processors and Peripheral ou en utilisant la barre de recherche. Pour l'ajouter au système il suffit de double clique dessus puis éventuellement le configurer.

Ici, vous devez choisir la version du processeur de taille minimale.

À la fin de cette étape, vous devriez voir apparaitre le processeur dans le panneau central System Contents comme le montre l'image suivante.

Notez les différentes connexions qui entrent et sortent du processeur.

Le second élément que vous devez ajouter est un bloc mémoire. Vous le trouverez dans la catégorie Basic Function sous le nom On Chip Memory (RAM or ROM)

Modifiez la configuration de base pour avoir une taille mémoire de 20Ko comme le montre la figure suivante.

En suite nous ajouterons deux périphériques de type Parallel I/O (PIO) pour les leds et les switches. Le premier doit être configuré comme sortie (output) sur une largeur de 10 bits, comme le montre la figure suivante:

Le second doit être configuré comme entrée (inputs) sur une largeur de 10 bits aussi.

En fin, le dernier élément à ajouter est une JTAG UART pour qu'on puisse communiquer avec le système par l'intermédiaire de la liaison USB.

Connecter les éléments

Dans la colonne Connections vous pouvez connecter les différents éléments en cliquant sur les cercle qui apparaissent. L'outil ne vous laissera connecter que des éléments compatibles entre eux (horloge, reset,…).

Voici les connexions qu'il faudra faire:

  • l'entrée clk de tous les modules doit être connectée à la sortie clk du bloc clk_0
  • l'entrée reset de tous les modules doit être connectée à la sortie clk_reset du bloc clk_0
  • l'entrée s1 de la ram connectée aux sorties data_master et instruction master du processeur
  • toutes les autres entrées de type Avalon Memory Mapped Slave à la seule sortie data_master du processeur
  • l'interruption sortant de l'uart connectée à l'entrée prévue du processeur.

Vous devriez à la fin obtenir un système semblable à celui de la figure suivante.

Remarqe 1 Pour changer les noms des différents modules instanciés, il suffit de double cliquer sur leur nom dans la colonne Name.

Remarqe 2 Le nios possède 32 entrées d'interruption, dans la colonne IRQ on peut préciser laquelle utiliser. Ici nous choisirons la N°5 en modifiant la valeur qui y apparait.

Choisir les adresses des différents périphériques:

La colonne BASE contient les adresses des différents périphériques. Pour l'instant elles sont toutes identiques et égales à 0. L'outil peut assigner des adresses différentes et correctes aux périphériques.

Nous voulons aussi que la mémoire reste à l'adresse 0. Pour cela, avant de demander la génération des adresses, on verrouille l'adresse de base de la ram en cliquant sur le petit cadenas à gauche de l'adresse.

En suite, on peut demander l'affectation automatique des adresses en choisissant l'item Assign Base Addresses du menu System.

Vous devriez obtenir quelque chose de similaire à la figure suivante:

Prenez le temps de noter les adresses de base des différents périphériques, nous en aurons besoin quand nous écrirons le logiciel de test.

Il faut maintenant revenir à la configuration du processeur et spécifier les périphériques qui contiendront le code de démarrage (reset) et des exceptions en les sélectionnant dans l'onglet vectors. Pour notre exemple, c'est la ram qu'il faut sélectionner.

Ajouter des entrées/sorties

Les deux périphériques PIO sont supposés être connectés à des éléments de la carte. Il faut donc pouvoir ajouter les entrées/sorties correspondantes. Pour cela, il faut double cliquer, dans la colonne Export, sur la ligne correspondant à l'external_connection de chaque module, puis de choisir des noms explicites (leds et sw par exemple).

La figure suivante montre ce que vous pouvez obtenir.

Sauvegarder et générer

La dernière étape est de générer l'ensemble des fichiers RTL (verilog ou vhdl) correspondants à notre système.

  • Sauvegardez le projet en cliquant sur Save dans le menu File. Nommez le projet cpu_system.
  • Générez les fichiers RTL en cliquant sur l'item Generate HDL du menu Generate. Les fichiers seront générés dans un sous dossier du projet Quartus.

Test sur la maquette

Intégration dans le flot FPGA

En quittant qsys vous reviendrez dans quartus. Un message vous indiquera qu'il faut manuellement ajouter le fichier cpu_system.qip au projet.

On peut aussi simplement ajouter le fichier cpu_system.qsys à la liste des fichiers du projet.

Une fois fait, il faut modifier le fichier DE1_SoC.sv pour instancier le système et connecter les entrées/sorties. Le fichier cpu_system/cpu_system_inst.v vous donne un exemple d'instanciation.

Nous utiliserons clock_50 comme horloge le boutons key[0] comme reset.

//////////////////////////////////////////////////////////////////////
// Processeu niosii
//////////////////////////////////////////////////////////////////////

    cpu_system u0 (
        .clk_clk       ( clock_50 ) ,
        .reset_reset_n ( key[0]   ) ,
        .sw_export     ( sw       ) ,
        .leds_export   ( ledr     )
    );

Attention, comme ledr est connecté au processeur, il faudra supprimer ou commenter la ligne où cette sortie est mise à zéro.

Un fois la modification effectuée, sauvegardez puis compiler le projet pour générer le fichier de programmation du FPGA (bitstream).

Programmer la maquette

Une fois la compilation et la synthèse faite, comme pour un projet standard, utilisez le programmeur pour programmer le FPGA.

Écrire un logiciel de test

Altera fourni une chaine de compilation basée sur les outils GNU (gcc, gnu binutils) pour les cœurs de processeur Niosii et ARM.

Cette chaine de compilation est intégrée à des environnements de développement intégrés (IDE) que nous allons utiliser pour tester le système que nous venons de construire.

Utilisation d'Altera Monitor Program

Altera Monitor Program est un outil d'Altera destiné principalement à l'apprentissage. Il permet de compiler des programmes simples pour les cœurs Niosii et ARM, de les télécharger sur une maquette ainsi et de les exécuter. C'est l'outil que nous utiliserons aujourd'hui.

Pour des développements logiciels plus complexes, nous verrons par la suite qu'il existe aussi un environnement de développement logiciel plus complet basé sur Eclipse.

  1. Le programme

Voici un programme simple, écrit en langage C, qui permet de tester notre système. Plus particulièrement, il permet de tester les PIO connectés aux leds et aux interrupteurs.

#define LEDS  (*(volatile unsigned int*) 0x00009010)
#define SW    (*(volatile unsigned int*) 0x00009000)


int main()
{
   while(1)
      LEDS = SW;

}

Ce programme lit en permanence l'état des interrupteurs (SW) et modifie en conséquence les leds (LEDS).

  1. Le test

Pour lancer l'outil utilisez la commande altera-monitor-program dans un terminal. La figure suivante vous montre la fenêtre principale de l'outil.

On commence par créer un nouveau projet:

On précise sont nom, le répertoire dans lequel il est créé et le type de processeur utilisé:

On le lie ensuite au système qu'on a conçu ainsi qu'au fichier de programmation du FPGA.

On précise ensuite que l'on veut faire un programme en langage C:

Puis on ajoute les fichiers C à compiler et on peut modifier certaines options de compilation:

Les autres étapes permettent de vérifier que le programme se retrouvera bien dans la bonne mémoire. Nous pouvons garder la configuration par défaut.

De retour, dans la fenêtre principale, on peut compiler le programme et le charger sur le système. L'interface permet ensuite d'exécuter le programme, de mettre des points d'arrêt ou d'examiner le contenu de la mémoire.

La figure suivante montre l'outil une fois le programme chargé sur le système.

À partir de là c'est le monde des développeurs logiciels.

Utilisation d'Eclipse

Eclipse est un IDE (Integrated Development Environment) bien connu des développeurs logiciels. Il est distribué sous licence libre et, grâce à une architecture modulaire et un ensemble de plugins, peut être utilisé pour le développement dans plusieurs langages informatiques.

La suite d'outils fournie par Altera, contient une version d'Eclipse avec des plugins additionnels permettant de cibler les cœurs de processeurs fournis par Altera et de tester et déployer le logiciel développer sur les FPGAs de la marque.

Une démonstration de l'utilisation de cet outil sera faite.

Fichier attachéTaille
PDF icon Slides de présentation2.62 Mo