Les deux premiers projets ont permis de se familiariser à Vivado en privilégiant deux aspects :
Il s'agit maintenant de marier ces deux mondes en créant un module IP maison décrit en VHDL. Ce module pourra ensuite être intégré à un projet de système complet intégrant un coeur de processeur comme dans l'exercice précédent.
Créer un projet de type RTL (comme dans l'exemple précédent) et le nommer Projet_IP_PWM.
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.
Il s'agit de créer un module IP capable de s'interconnecter au Processing System via un bus AXI. Ce type de module est connu sous l'appellation de périphérique AXI4.
Lancer le processus de création par le menu Tools -> Create and Package New IP.
Passer la première boite de dialogue d'information en cliquant sur Next.
La boite de dialogue suivante apparaît :
Choisir Create a new AXI4 peripheral puis cliquer sur Next.
Compléter le dialogue qui apparaît comme suit (champs Name et Description) :
Noter que le dossier d'accueil de l'IP créé est noté ip_repo et ne se trouve pas par défaut dans le dossier du projet en cours.
On sélectionne ensuite les caractéristiques du module IP en conservant les propositions faites par défauts :
Valider par Next.
Le processus préliminaire de création se termine par la boite ci-dessous dans laquelle on sélectionne Edit IP avant de cliquer sur le bouton Finish.
On se propose de réaliser en VHDL un module PWM 16 bits à l'image de celui disponible dans les microcontrôleurs.
Il s'agit de générer un signal carré de période $T$ fixée et au rapport cyclique commandable sur 16 bits. Le résultat prend la forme suivante où $pwm\_out$ est le signal généré :
L'intérêt : obtenir un signal continu dont la valeur moyenne $‹pwm_{out}›=\alpha.V_{CCio}$ soit réglable.
La figure ci-dessus fait apparaître les éléments nécessaires à la génération d'un tel signal. On met d'abord en place un compteur, intitulé ici $pwm\_counter$, comptant de 0 à 65535 donc sur 16 bits non signés. La période de comptage à retenir est donc de $T_{comptage}=\frac{T}{2^{16}}$, ce qui conduit à une fréquence de comptage de $F_{clk}=\frac{2^{16}}{T}$.
Le bloc hiérarchique du module PWM à réaliser est le suivant :
Y figurent les signaux suivants :
Le calcul du rapport de prédivision $N$ se fait aisément avec la relation suivante : $N=2^{prescaler}$
Aides : la mise en place du prescaler se fait aisément en lui associant un compteur décomptant de $N-1$ à $0$ et en autorisant le comptage sur $pwm\_counter$ au moment des passages à 0 du compteur associé au prescaler.
Conseils supplémentaires :
L'étape Création d'un nouveau périphérique AXI4 a abouti à la création de la structure de base du module IP. A cette occasion, deux fichiers VHDL ont été produits :
Les deux fichiers créés sont hiérarchiquement dépendants.
ip_pwm16bits_v1_0.vhd est le sommet de la hiérarchie de notre IP. C'est à partir de ce fichier que le bloc fonctionnel apparaissant dans le diagramme sera élaboré.
ip_pwm16bits_v1_0_S00_AXI.vhd est instancié par le fichier précédent. Ce fichier met en oeuvre l'interface AXI pour assurer les échanges avec le Processing System (PS). Rappelons que ce fichier VHDL sera implémenté dans le Programmable Logic (PL). Il instancie le composant que nous avons créé dans le fichier pwm16bits_core.vhd, lequel conserve l'avantage d'occulter tout ce qui correspond au bus AXI pour une simulation simplifiée.
La suite propose d'ajouter notre composant pwm16bits_core.vhd au fichier ip_pwm16bits_v1_0_S00_AXI.vhd et de l'instancier. Il faudra également faire remonter le signal pwm créé par notre code VHDL jusqu'au sommet de la hiérarchie de l'IP créé, c'est à dire au niveau du fichier ip_pwm16bits_v1_0.vhd.
En dehors des signaux du bus AXI tous déjà définis par le processus précédent, il nous faut maintenant ajouter les signaux que nous allons créer. Dans un premier temps, on se contente d'ajouter une sortie PWM de type STD_LOGIC.
Cette sortie est d'abord ajoutée au niveau du sommet hiérarchique de notre IP donc dans la liste des ports du fichier ip_pwm16bits_v1_0.vhd comme suit :
A noter que cet ajout s'effectue dans la zone identifiée à cet effet par le générateur d'IP par le commentaire -- Users to add ports here.
Comme ce signal PWM sera également présent dans le fichier de description du coeur de notre IP (ip_pwm16bits_v1_0_S00_AXI.vhd), on met à jour la description du composant qui en est faite dans ip_pwm16bits_v1_0.vhd comme suit :
Finalement on ajoute l'information de routage entre le fichier d'instanciation et le fichier instancié dans ip_pwm16bits_v1_0.vhd, fichier dont les modifications sont maintenant terminées.
On s'attaque maintenant à la description de la fonction réalisée par l'IP à proprement parler dans le fichier ip_pwm16bits_v1_0_S00_AXI.vhd.
Logiquement, on commence par ajouter le port pour la sortie pwm :
On va maintenant déclarer le composant pwm16bits_core dans le fichier ip_pwm16bits_v1_0_S00_AXI.vhd dans la zone réservée pour les signaux "utilisateur" (on peut aussi y déclarer des composants).
Composant qu'il faut instancier pour terminer à la toute fin du fichier ip_pwm16bits_v1_0_S00_AXI.vhd :
Noter qu'on utilise ici deux signaux particuliers de l'interface AXI :
Sauvegarder les fichiers VHDL édités durant cette partie pour finir.
Pour lancer le processus d'encapsulation, cliquer sur Package IP dans la section PROJECT MANAGER du Flow Navigator.
Les informations suivantes apparaissent dans le PROJECT MANAGER :
Mettre à jour l'IP en sélectionnant les paramètres qui ne sont pas à jour et ne sont pas pointés par une coche verte et en cliquant sur le message en haut de l'image précédente intitulé Merge changes from Customization Parameters Wizard.
Tout passe alors au vert :
Noter que ces dernières opérations ont permis de prendre en compte les ajouts effectués dans les fichiers VHDL de l'IP, ce que l'on peut constater en listant la liste des ports intégrant dorénavant le signal pwm16bits :
Terminer en configurant les paramètres d'édition de l'encapsultation en sélectionnant l'étape Review and Package :
et en réencapsulant l'IP par un clic sur le bouton Re-Package IP.
L'IP pwm 16 bits peut maintenant être utilisée dans un projet.
Ouvrir le projet nommé Projet_IP_PWM et créer un diagramme semblable à celui du TP Projet SoC avec Xilinx Vivado en reprenant toutes les étapes vues dans ce précédent TP. La seule nuance consistera à connecter les boutons poussoirs sur l'IP GPIO plutôt que les LEDs comme c'était le cas dans le TP précédent.
Ajouter une instance de l'IP pwm en prenant soin d'utiliser les commandes d'automatisation pour en assurer la connexion au reste de la structure de sorte d'aboutir au schéma suivant :
Ajouter également un port de sortie au diagramme et le relier à la sortie pwm16bits de l'IP pwm.
Le diagramme obtenu devra ressembler à cela :
Si le diagramme est conforme à la figure ci-dessus, passer directement à l'étape d'implémentation. Sinon, il se peut que le signal pwm16bits n'apparaisse pas sur notre ip_pwm16bits. Dans ce cas, procéder comme suit :
De retour dans le projet Projet_IP_PWM, cliquer sur Report IP Status.
Enfin mettre à jour l'IP en cliquant sur le bouton Upgrade Selected :
On termine par un clic sur le bouton Generate dans la boite de dialogue qui apparaît (concernant la fenêtre d'avertissements, la fermer par un clic sur le bouton OK).
Comme l'IP a été mis à jour, on regénère le status des IP par un clic sur Rerun dans l'onglet IP Status :
A l'issue de ces étapes, la sortie doit maintenant apparaître sur l'ip_pwm16bits_0 présent dans le diagramme.
Avant l'implémentation proprement dite, n'oubliez pas d'ajouter un fichier de conraintes au projet à l'image de ce qui a été fait dans le premier projet (Projet VHDL avec Xilinx Vivado). Ici, il suffira d'imposer la broche M14 du Zynq pour led_LD0 (signal en sortie de type LVCMOS33).
Lancer le SDK.
Céer une nouvelle application nommée test_pwm sur la base du fichier source du projet précédent.
En vous inspirant du programme écrit dans le TP précédent, écrire un programme qui relève la valeur des 4 boutons poussoirs et qui fixe les 4 bits de poids fort du rapport cyclique du PWM à la valeur des 4 boutons poussoirs de sorte que le rapport cyclique s'écrivre BP3 BP2 BP1 BP0 0000 0000 0000 sous forme binaire.
Aide : consulter le fichier include créé pour l'IP PWM 16 bits afin de savoir comment envoyer les données nécessaires à la configuration de l'IP pour un rapport cyclique donné. On fixera le prescaler à 1.