Projet SoC avec Vivado

Introduction

Dans ce projet, on exploite à la fois la partie processeur du Zynq (PS pour Processing System) et le réseau de portes configurable (PL pour Programmable Logic).

La communication entre la partie processeur et le réseau de portes configurable s'effectue grâce au bus AXI, ressource interne à la partie PS.

Pour ce premier exemple, on met en oeuvre un coeur de processeur dont la programmation s'effectuera en langage C capable de communiquer avec un périphérique d'entrées/sorties permettant d'accéder aux LEDs de la carte Zybo.

Le processeur comme le périphérique d'entrées/sorties sont des modules IP prééxistants dans Vivado.

Projet SoC version 1

Réalisation d'un projet avec IPs

Première étape : créer le projet

Créer un projet de type RTL (comme dans l'exemple précédent) et le nommer ProjetSoC1.

Note : le projet créé est totalement vierge et doit être configuré pour cibler une carte Zybo comme dans le projet VHDL vu précédemment.

Seconde étape : créer la structure du système à partir des IP du catalogue d'IP Xilinx

Ce projet repose sur un schéma hiérarchique intégrant des IPs. Pour le créer, cliquer sur Create Block Design dans le Flow Navigator.

Saisir ProjetSoC1 pour le nom du design et valider par OK.

Design du projet SoC version 1

Cette étape aboutit à la création d'un diagramme vierge.

Design vierge du projet SoC version 1

On commence par ajouter l'IP du processeur à notre projet en cliquant sur le bouton + (soit dans la palette d'outils de la section Diagram; soit en cliquant sur le + présent au centre du diagram).

Choix d'une IP

Dans la liste qui apparaît, sélectionner l'IP ZYNQ7 Processing System qui englobe donc les coeurs ARM Cortex A9 ainsi que toute la logique d'interconnexion AXI vers le réseau de portes configurables puis valider par Entrer ou par un double clic sur le nom de l'IP à intégrer.

Résultat :

IP Zynq7 en place

Lancement du magicien de configuration des IP

Vivado facilite largement l'usage des IP grâce à des assistants qui automatisent les tâches de configuration des IPs. Cliquer sur le texte Run Block Automation qui apparaît sous la barre d'outils de la fenêtre Diagram (un clic droit sur l'espace de travail du diagramme permet aussi d'accéder à cet outil).

Valider par OK pour utiliser la configuration par défaut.

L'automate fournit toute la connectivité nécessaire entre la mémoire DDR de la carte Zybo et les coeurs ARM du Zynq mais aussi entre les coeurs ARM et différents périphériques de la carte Zybo (interface Ethernet, mémoire Flash ...) par l'intermédiaire du bus FIXED_IO.

Connectivité entre PS et DDR

Pour que le Processing System puisse accéder aux LEDs, ajouter un IP AXI_GPIO au projet (bouton + comme précédemment) puis lancer le processus d'automatisation pour connecter l'IP AXI GPIO au PS.

Connectivité entre PS et AXI GPIO

Configurer la boite de dialogue comme ci-dessus (mode All Automation et sélectionner leds_4bits dans les options GPIO Select Board Part Interface. Valider par OK.

Effectuer un clic droit dans la zone de travail du diagramme pour Regénerer le Layout et obtenir un diagramme semblable à ceci :

Système complet avec un GPIO

Sauvegarder le diagramme et valider sa structure en exécutant l'outil du menu Tools->Validate Design.

Dernière étape : finalisation du projet et export de la configuration matérielle

Pour pouvoir générer le bitstream du projet, Vivado a besoin que le diagramme réalisé soit maintenant exploitable par une approche VHDL. La commande Create HDL Wrapper permet cette exploitation du projet à un niveau VHDL en générant une netliste du diagramme en VHDL. Pour la lancer, sélectionner le ProjetSoC1 dans l'onglet Sources et choisir Create HDL Wrapper dans le menu contextuel.

Création du wrapper VHDL

Création du wrapper VHDL

Valider par OK après avoir sélectionner l'option Let Vivado manage wrapper and auto-update.

Pour clore toute cette partie, commencer par générer le bitstream destiné à la configuration du Zynq en cliquant sur Generate Bitstream dans la catégorie PROGRAM AND DEBUG de la section Flow Navigator.

Note : il faut valider le lancement de l'implémentation qui elle-même exécutera l'opération de Synthèse (2 boites de dialogue de confirmation).

La suite propose de programmer le processeur ARM du Zynq en langage C. Pour rendre cette étape possible, on termine par l'export des fichiers matériels : menu File->Export->Export Hardware...

Export de la configuration matérielle

Penser à cocher la case à cocher Include bitstream et valider par OK.

Export de la configuration matérielle

La création du système est maintenant achevée.

Programmer avec le SDK

Création d'une application

Lancer le SDK à partir de Vivado HLx : menu File->Lauch SDK...

Lancement du SDK

Valider par OK.

La configuration matérielle créé dans Vivado est le premier élément chargé dans le SDK.

Caractéristique de la platforme matérielle

Note : la première partie de ce fichier contient un tableau qui renseigne sur les plages d'adresses attribuées à chacun des composants de la structure matérielle.

Créer l'application à partir du menu File->New->Application Project.

Menu pour créer l'application

Compléter la boite de dialogue comme suit :

Création de l'application

Cliquer Next pour choisir un application de base et sélectionner Empty Application comme ci-dessous :

Création d'une application vide

Cette action a créé deux dossiers. Un dossier pour le codage de notre projet et dans lequel on placera les fichiers sources. Le second dossier possède le suffixe _bsp, pour Board support package. Ce dossier fournit un ensemble de bibliothèques et pilotes constituant la couche de plus bas niveau de l'application.

Les bibliothèques et pilotes sont parfaitement documentés dans le dossier d'information BSP Documentation. Un clic sur l'intitulé gpio_vx_y permet d'accéder à l'ensemble de la documentation générée par doxygen pour l'IP GPIO sur internet.

Dossier BSP

Pour ce premier projet, on part d'un code source existant proposé par Xilinx pour le test d'un GPIO.

Effectuer un clic droit avec la souris sur le code source ci-dessous pour l'enregistrer dans le dossier ProjetSoC1\ProjetSoC1.sdk\testLEDs\src de votre projet.

Note : pour en savoir plus sur l'usage de l'IP GPIO dans un programme en C sous le SDK, penser à consulter la documentation dont le lien est présent dans le dossier BSP du projet.

Cliquer sur le lien ci-dessous pour voir le code source du fichier :

/*
 * @file : gpio.c
 * 
 * @brief : Utilisation de l'IP AXI GPIO
 * 
 */

#include <stdio.h>
#include "platform.h"       /* Mise en place de la liaison série. */
#include "xil_printf.h"
#include "xparameters.h"    /* Contient la définition des adresses et offsets des IP du projet. */
#include "xgpio.h"          /* Contient les prototypes des fonctions utiles pour accéder au module IP AXI GPIO. */
#include "stdlib.h"

/** @def Redéfinition de l'ID du GPIO_0 par GPIO_ID */  
#define GPIO_ID XPAR_AXI_GPIO_0_DEVICE_ID
/** @def LEDs positionné sur le canal 1 */
#define CHANNEL_LEDS 1

XGpio monGPIO;  /** @var Objet utilisé pour accéder au GPIO_0 */

int main()
{
	u32 bps;

    init_platform();

    /* La fonction print écrit sur le port série. Ouvrir un terminal dans le SDK pour visualiser ce qu'elle envoie. */
    print("Hello World\n\r");

    /* Initialisation du GPIO. */
    if (XGpio_Initialize(&monGPIO, GPIO_ID) != XST_SUCCESS) {
    	print("Erreur d'initialisation du GPIO\n\r");
    	exit(0);
    }

    // Configuration en sortie du canal des leds
    XGpio_SetDataDirection(&monGPIO, CHANNEL_LEDS, 0xFFFFFFF0);

    while(1) {
        // Exemple : allumage des LEDs 1 et 3
        bps = (1 << 3) | (1 << 1);
    	XGpio_DiscreteWrite(&monGPIO, CHANNEL_LEDS, bps);
    }

    cleanup_platform();
    return 0;
}

Etude du code source

Parcourir le code source et identifier les différentes fonctions permettant d'utiliser l'IP GPIO.

Comment pourrait-on utiliser le GPIO en entrée ?

Exécution

La première exécution requiert de programmer la configuration dans le FPGA : menu Xilinx->Program FPGA

Programmation de configuration matérielle dans le FPGA

Penser à vérifier que le nom du bitstream, ProjetSoC1_wrapper.bit, est bien présent dans la boite de dialogue puis cliquer sur Program.

A noter que cette configuration sera perdue à l'extinction de la carte Zybo.

Avant d'exécuter le programme proposé ci-dessus, on construit l'exécutable en sélectionnant le dossier testLEDs dans le Project Explorer :

Sélection du projet actif

puis en cliquant sur Build All dans le menu Project.

Noter qu'un clic droit de la souris dont le curseur est positionné sur le dossier du projet permet d'accéder à la commande Build ou, qu'en fonction de la configuration du SDK, la sauvegarde des fichiers sources du programme lance le processus de construction de l'application.

L'exécution peut ensuite être lancée :

  • soit par un Run As -> Launch on Hardware (System Debugger),
  • soit par un Debug As -> Launch on Hardware (System Debugger) pour bénéficier des fonctionnalités de mise au point.

Exercice

Créer un projet en repartant de 0 pour lequel vous activerez le port canal 2 de l'IP GPIO. Le premier port restera lié aux LEDs de la carte Zybo. Le second port sera mappé sur les boutons poussoirs.

La partie logicielle reprendra le fichier source précédent, modifié pour que les LEDs reflètent l'états des boutons poussoirs.

Noter que l'intitulé LED_CHANNEL est défini pour permettre l'accès au port 1 de l'IP GPIO et qu'il sera judicieux de créer une définition PB_CHANNEL valant 2 pour accéder au second port de l'IP GPIO.