Dans ce TP, vous allez réaliser votre première conception (j’utiliserai aussi le mot design) simple qui va vous permettre de découvrir les entrées et sorties de la carte Nexys3. Par la même occasion, ce TP vise à fournir une initiation à l’utilisation des outils de Xilinx et Digilent. De par sa simplicité, c’est aussi un bon exemple pour comprendre le fonctionnement de la chaîne de transformation : comment à partir d’un code de description ou un schéma de circuit vous allez, par ISE, produire un fichier toplevel.bit. Ce fichier est ensuite chargé sur la carte afin d’implanter sur celle-ci le circuit spécifié dans ISE.
Il faudra utiliser le résultat Add4 pour le TP2,
La Figure suivante identifie les principaux éléments de l’interface du Navigateur de Projet ISE utilisé dans ces TPs. Pour installer ce logiciel sur les machines de l’université de Lille 1 :
Le logiciel ISE est maintenant prêt à être utiliser. Il se lance avec la commande: /opt/Xilinx/12.4/ISE_DS/ISE/bin/lin64/ise
Alias ISE
Si vous utilisez bash, rajoutez dans .bashrc la ligne suivante:
alias ise='/opt/Xilinx/12.4/ISE_DS/ISE/bin/lin64/ise'
enregistrez et fermez .
ensuite la commande source .bashrc pour recharger le nouveau bashrc dans votre terminal
Figure 1 Environnement ISE (cliquez sur l'image)
Le Navigateur de projet ISE sera utilisé comme outil de conception lors de ces TPs. Cet outil de Xilinx permet de créer des projets comportant plusieurs types de fichiers (HDL, schématique, UCF, EDIF, etc.), de compiler, d’effectuer des design rule check (DRC), de créer des contraintes d’implémentation dont des contraintes de timings sur les horloges, de déterminer l’emplacement des broches, de créer des bancs d’essai de simulation (testbench) et de gérer efficacement les projets d’envergure.
Le Navigateur de projet ISE offre un environnement de conception centralisé extrêmement efficace qui regroupe tous les outils nécessaires à la conception, la simulation et à l’implémentation d’un projet d’envergure ainsi qu’à la configuration de la carte, la Nexys3 en ce qui nous concerne.
ISE chez vous!
Vous pouvez installer ISE sur votre machine linux ou Windows. Reportez-vous à cette page pour l’installation.
Si vous avez suivi la leçon 1, vous l'avez déjà lu...
La carte de développement Nexys3 de Digilent utilise le FPGA Spartan (XC6LX16) de Xilinx. Cette carte offre un environnement de conception très adapté pour le prototypage d’applications variées dont celles des systèmes numériques à usage général et des systèmes embarqués. Cette carte est de plus idéale pour les applications de traitement vidéo et de traitement de signal en général.
La carte Nexys3 regroupe entre autre un FPGA XC6LX16 Spartan 6, un accès USB2 pour la configuration et le transfert de données rapide (On pourra utiliser le logiciel Adept).
Caractéristiques principales:
Les ports d'E/S du FPGA sont repris sur 4 connecteurs femelles spécifiques. Ces connecteurs permettent l'utilisation de petits modules d'extensions optionnels (appelés "Pmod"). Une fois enfichées sur les connecteurs femelles de la carte"NEXYS3", ces modules vous permettraient d'adjoindre de multiples possibilités et interfaces supplémentaires. La carte"NEXYS3" dispose également d'un connecteur d'extension spécial dédié aux signaux haut débit. Ce connecteur est destiné à recevoir diverses extensions "Vmod™".
Le FPGA peut être programmé de deux façons: directement à partir d'un PC en utilisant le port USB, et à partir de la Flash ROM (la Flash ROM est également programmable par l'utilisateur via le Port USB). Un cavalier sur la carte Nexys3 détermine la source (PC ou ROM) du FPGA à utiliser pour charger sa configuration. Le FPGA peut automatiquement charger une configuration à partir de la ROM Flash Platform à la mise sous tension si le cavalier de mode de configuration est réglé sur "Master série ". Si le cavalier Mode est réglé sur "JTAG", le FPGA attendra la programmation à partir du PC (via le câble USB). C’est cette configuration qu’on utilisera lors des TPs. Les cavaliers sur les cartes sont normalement dans les bonnes configurations.
Le logiciel Adept peut être utilisé pour configurer le FPGA avec n'importe quel fichier approprié stocké sur l'ordinateur. Adept utilise le câble USB pour transférer un fichier binaire sélectionné à partir du PC vers le FPGA ou la Flash ROM. Alors le FPGA est configuré, il le restera ainsi jusqu'à ce qu'il soit remis à zéro par une rupture d'alimentation ou par une pression sur le bouton de réinitialisation du FPGA (BTNR). La Flash ROM conservera le fichier binaire jusqu'à ce qu'elle soit reprogrammée, indépendamment de la mise sous tension.
Pour une description approfondie de la carte Nexys3, consultez le manuel d’utilisation ainsi que la fiche technique disponible chez DIGILENT. N’hésitez pas à consulter ces documents pour vous aider lors des travaux pratiques. Référez-vous à la Figure 2 pour une vue d’ensemble de la carte Nexys3 et ses principaux modules.
Figure 2 La carte Nexys3
Les différents outils de conception que vous utiliserez lors des travaux pratiques sont tous intégrés et accessibles directement depuis le navigateur de projet ISE. ISE permet une grande efficacité car il regroupe plusieurs aspects de la conception d’un projet dans un seul environnement et un seul jeu de fichiers.
Lors de ces TPs, vous utiliserez l’outil de conception et simulation Isim pour effectuer les simulations de vos projets. Vous utiliserez l’outil XST de Xilinx pour effectuer la synthèse des différents projets. Notez que pour ce qui est de l’étape de synthèse, seule l’utilisation de l’outil XST est vue dans ces séances. Enfin, les outils PlanAhead et ADEPT de Xilinx et DIGILENT peuvent être utilisés respectivement pour implémenter le projet (placement et routage) et configurer les composants de la carte avec le projet implémenté (FPGA, CPLD, mémoire ROM, etc.).
Ces TPs recouvrent les deux approches de conception FGPA : l’approche de conception par schéma et l’approche de conception par langage HDL. Bien qu’assez différentes, les deux approches mènent exactement au même résultat final. Vous constaterez que l’approche par schéma est plus près du schéma bloc et de la réalisation du circuit alors que l’approche par langage HDL est liée davantage aux processus algorithmiques et semble par conséquent plus abstraite.
Par ailleurs, l’approche par schéma est sans doute plus instinctive que l’approche HDL. Elle est d’ailleurs davantage préconisée pour les concepteurs débutants ou novices. Les concepteurs aguerris préfèrent généralement l’approche par langage HDL parce qu’elle est plus flexible et plus efficace. De plus, cette dernière présente une meilleure compatibilité avec les outils EDA et elle est davantage employée dans l’industrie.
La Figure 3 illustre le flow de conception type sous ISE.
Figure 3. Flow de conception adopté dans ce didacticiel.
C’est parti! Connectez la carte via le câble USB et placez l’interrupteur en position ON. Lancez le logiciel ISE 12.4 !
Si une erreur se produit!!!
Pour certaines machines, il faut supprimer la définition de la variable LANG.
Cela dépend du shell utilisé, sous Linux :
Pour cette première expérience, nous aborderons les dispositifs de communication directe avec la carte Nexys3, le vecteur de 8 switches (interrupteurs), les 8 Leds et l’afficheur quatre fois 7 segments. La première partie est assez simple: vous afficherez sur les 8 Leds les résultats des 8 switches : ‘0’ ou ‘1’ pour éteint ou allumé. Ensuite vous utiliserez 8 interrupteurs SW0 à SW7 pour représenter un nombre de 8 bits codé en binaire dont la valeur peut évidemment s’afficher en hexadécimal sur deux afficheurs : x00 à xFF, soit b00000000 à b11111111 en binaire, soit 0 à 15 en décimal (Notation : b pour nombre binaire, x pour nombre hexadécimal, rien pour décimal). Vous placerez cette valeur sur l’afficheur en complétant par deux x0 sur les deux afficheurs de gauche, puis vous afficherez la valeur sur 1 ou deux afficheurs seulement en fonction de la valeur saisie.
Dans ce premier exemple, vous allez mixer la conception par schéma et la conception par code. Les schémas sont propres à ISE, le code lui respecte le standard VHDL. C’est un langage de conception que vous découvrirez au fur et à mesure des séances ainsi qu'en, cours et TD. Cela ne vous empêche pas de regarder d’un peu plus près ce puissant langage de synthèse dont vous ne verrez que quelques éléments. Des milliers de références sur le net, ce lien Syntaxe VHDL vous sera néanmoins suffisant pour vos développements.
Le choix entre code ou VHDL n’est pas exclusif et parfois on préférera avoir une vision structurelle d’une portion du circuit et donc adaptée à la vue schématique, parfois on voudra exprimer un comportement et la vision « algorithme » est alors favorisée. Dans vos séances, nous combinerons la vision schématique qui est très intuitive et le langage VHDL en tant que tel.
Pour commencer la conception, il faut créer un nouveau projet avec File>New Project. Lorsque vous spécifiez le nom du projet et le répertoire, évitez les espaces dans le chemin, j’ai choisi TP1.
Figure 4 Création du projet TP1
La prochaine étape sert à préciser le type de FPGA que vous ciblez. C'est pour nous celui de la carte Nexys3. On utilisera également VHDL comme langage préféré.
Figure 5 Caractéristiques de la carte Nexys3
Enfin, Next puis Finish vont clôturer cette partie.
Pour décrire le système, vous ajoutez un nouveau fichier à votre projet. Ce fichier contiendra le schéma du circuit que vous allez définir. Donc ici vous sélectionnez Project>New Source…, puis remplissez la boîte de dialogue permettant à l’outil de créer un nouveau fichier toplevel.sch en sélectionnant Schematic et donc le nom toplevel.
Figure 6 Création d'un schématique
En cliquant Next et Finish, vous créez le fichier toplevel.sch et ISE ouvre de suite la fenêtre de conception schématique pour ce fichier. Vous comprendrez vite qu’ISE est capable d’ouvrir plusieurs fenêtres et que l’on passe de l’une à l’autre par les onglets associés à chacun des noms. Le logo
apparaît devant toplevel.sch et indique la racine de votre projet (Top Module).
Les principaux boutons de saisies (les mêmes actions sont accessibles par le menu Add) permettent de manipuler des symboles, des fils, des bus2.
La construction du circuit va pourvoir commencer. Cette première étape est simple, vous allez relier les 8 switches aux 8 leds sur la carte. Aucune logique n’est nécessaire, c’est comme si vous réalisiez par ISE la «soudure» de fils entre les switches et les leds. Même simpliste, c’est quand même une architecture qui sera programmée!
Vous allez donc placer dans votre schéma toplevel, un ibuf8 et un obuf8 (ce sont des buffers nécessaires pour les entrées/sorties de la carte). En cliquant sur le bouton ajouter un symbole (Add Symbol), une liste de symboles disponibles apparaît. Choisissez dans la sous-liste IO les deux symboles cités précédemment. Cliquez sur le nom dans la liste et recliquez dans la fenêtre associée au schéma pour créer une instance. (Ctrl Z pour annuler une action)
Si vous avez besoin de savoir ce que fait un symbole, il suffit de le sélectionner et de cliquer sur Symbol Info.
Figure 6 Création d'un symbole
Vous ajoutez 3 fils (Figure 8) en sélectionnant le bouton correspondant Add Wire et en cliquant sur l’emplacement d’une extrémité puis en cliquant sur l’emplacement de l’autre. ATTENTION il faut être attentif à ce que les fils soient bien connectés au composant, n’hésitez pas à zoomer afin de mieux voir les 4 petits carrés sous le curseur qui vous garantissent la bonne connexion une fois le curseur sur le port du composant. Ajoutez deux I/O Marker aux deux extrémités libres de vos fils, là encore en sélectionnant le bon bouton et en cliquant sur les 2 extrémités libres. Il vous reste à renommer les 2 I/O Marker. Pour cela sélectionnez un à un les fils connectés aux deux I/O Marker. Utilisez le bouton nommer un fil. Il vous suffira de nommer switches(7:0) l’entrée et led(7:0) la sortie. Une fois le nom saisi, placez-le dans le schéma par un clic sur le fil concerné.
Figure 7 Nommage des fils et bus
Voici les résultats de votre saisie, vous devriez sauver votre projet. Sans effort vous venez de créer un circuit qui est composé de 8 fils associant chaque switches(i) à la led(i) de votre carte. Cet ensemble de 8 fils est appelé un BUS la représentation sous ISE correspond à la notation name(Upper:Lower).
Figure 8 Votre toplevel.sch
Remarque : Pour vous simplifier la vie, ISE insère les iobuf par défaut. Ici ils sont explicites car ils permettent de spécifier deux noms différents aux deux I/O Marker.
Vous avez utilisé des noms logiques choisis par vous-même (sous mon influence) pour vos fils et I/O Marker. Pour qu’ISE puisse associer ces noms logiques aux noms physiques des broches de votre puce programmable, il faut explicitement donner toutes les correspondances :
un nom logique = un nom physique
Pour ce faire, vous devez créer une nouvelle source de type Implementation Constraints File (.ucf). Cela sera fait par Project > New Source.
Figure 9 Création du fichier Nexys3.ucf
Next et Finish comme toujours créent le fichier et ISE ouvre l’éditeur sur ce fichier pour sa saisie. Il faut ici insérer le code qui correspond à la carte Nexys3.
Voici les noms des broches du Spartan6 et ses connexions sur la carte.
Figure 10 Les broches sur la carte Nexys3 - document Digilent
Voici le code correspondant à insérer et à sauvegarder dans le fichier Nexys3.ucf. Vous faites ici le lien entre les noms de vos ports et les noms des broches sur lesquelles vous voulez vous connecter.
Le fichier Nexys3.ucf apparaît aussi sous la hiérarchie de toplevel.sch. (il s'appelait S3.ucf dans la figure 11 ;-) )
Il n’y a pas grand-chose à simuler sur cet exemple, par contre vous allez pouvoir tester le circuit sur la carte!
ISE vous propose un mode simulation et un mode implementation. Il vous faudra choisir implementation en revenant sous l’onglet design.
Figure 11 Chaîne de compilation
C’est la partie la plus simple ! C’est ISE qui va faire le travail. Il reste néanmoins un ensemble d’informations à lui donner pour qu’il s’en sorte.
Il vous reste à positionner le mode de l’horloge utilisé lors du chargement du FPGA. Sélectionnez toplevel.sch, puis dans la fenêtre processes, cliquez droit sur Generate Programming File et dans le menu déroulant sur Process Properties. Positionnez la FPGA Start-UP Clock à JTAG Clock dans Startup Options. Pour chaque nouveau projet, il faudra lors de la première compilation vérifier ce paramètre. Vous pouvez générer le fichier toplevel.bit avec un double clic sur Generate Programming File.
Figure 12 Option JTAG
Lorsque la compilation est un succès, il vous reste à charger le code produit sur la carte. Celle-ci doit être connectée et allumée. Vous allez pour cela utiliser le logiciel Adept que Digilent vous a fourni.
Chargement sous windows
Le fichier généré se trouve dans votre projet et se nomme ici toplevel.bit. Lancez Adept depuis le menu demarrer de votre PC. Il vous suffit de sélectionner le bon fichier avec Browse et une fois effectué vous pouvez charger le code produit par ISE sur le FPGA de la carte Nexys. Cliquez sur Program.
Figure 13 Chargement sur Nexys3 sous Windows
Chargement sous linux :
Le chargement du design sur le FPGA sous Linux se réalise en mode ligne de commande. Vérifiez que votre carte FPGA soit branchée et allumée. Ouvrez un terminal, seulement 2 commandes sont utiles.
La commande djtgcfg enum : cette commande permet de lister toutes les cartes connectées à l’ordinateur.
La commande djtgcfg -d Nexys3 prog -i 0 -f toplevel.bit permet de charger le fichier sur la carte Nexys3.
A vous de vérifier que la position des switches positionne les leds correspondantes.
Question 1
Vous allez réaliser un additionneur 4 bits en VHDL ( cf Exercice 1). Un mot de 4 bits est saisi sur les 4 switches de droite, le second sur les 4 de gauche, l'affichage du résultat se fera sur les 5 leds de droites (retenue comprise).
Ajoutez une nouvelle source à votre projet. Vous savez déjà le faire. Cette fois choisissez de créer un VHDL Module. Je vous propose comme nom add4. ISE vous aide pour créer le fichier add4.vhd.
Création de add4.vhd
Le second écran vous permet de spécifier les ports de votre composant. Il vous suffit de donner un nom aux ports, un sens input ou output et une taille lorsqu'il s'agit d'un bus de plusieurs fils.
Dans votre design vous observez l’apparition à coté de toplevel d'un nouveau fichier add4.vhd. Ouvrez-le!
En vous aidant de ces informations 4-Bit_Adder, en particulier l'exemple 2, premier code, est parfait, codez votre adder 4 bits.
Avant de poursuivre la conception, vous pouvez pas à pas vérifier par simulation le bon comportement d’un composant. C’est une bonne habitude de travail, chaque brique de base est testée avant assemblage.Il faut vous placer dans le mode simulation. Vous devriez obtenir d’office le niveau de simulation Behevioral, si ce n’est pas le cas à vous de le positionner. Ensuite c’est toujours pareil, sélectionnez le composant et lancez dans la fenêtre processes l’action qui vous intéresse. Ici, vous lancez la simulation Isim par Simulate Behavioral Model.
Fig 18 Lancement d'Isim sur un composant
Isim permet d’observer les valeurs sur chacun des fils du composant à tout moment de la simulation. En particulier Isim représente cette évolution par un chronogramme où les fils (ou signaux) valent normalement ‘0’ ou ‘1’ ou des valeurs sur des bus. Pour l’instant vos fils sont soit ‘u’ pour undefined, soit ‘x’ pour quelconque. C’est normal les entrées n’ont pas été initialisées! Vous allez pouvoir tester différentes valeurs en entrée afin de valider votre composant matériel. La sortie sum doit correspondre à vos spécifications, ici la somme de a et b.
Dans la fenêtre chronogramme sous la colonne Name il suffit de faire un clic droit sur a ou b et de sélectionner dans le menu déroulant Force constant pour les initialiser à des valeurs en hexadécimal, j'avais choisi (2,3) et (2,F).
Figure 19 Forcer un port à une valeur
Isim nous propose 4 boutons qui permettent, de la gauche vers la droite: de replacer le simulateur à l’état initial, de lancer la boucle de simulation, d’avancer la simulation d’un pas de temps, ici 1.00us. Vous lancerez le simulateur pour un pas de temps. Les fils deviennent verts, ils sont tous définis. Recommencez la même manipulation en plaçant d'autres valeurs sur a et b puis un pas de simulation afin de visualiser le résultat sur sum. En utilisant le bouton zoom
vous obtenez une vue globale de la simulation pour les quelques microsecondes de votre simulation.
Si la simulation vous donne de bons résultats, vous pouvez utiliser ce composants dans votre design.
Pour exécuter ce composant directement sur la carte, en mode implémentation il faut que add4.vhd soit définit comme le top module de votre design. il faut pour cela faire un clic droit sur le nom et valider cet état dans le menu déroulant. Le fichier nexys.ucf vient alors se positionner dans la hiérarchie de add4. celui-ci n'est plus adapté!! Vous allez recontruire un fichier ucf en suivant la même procedure que précedement, appelez-le add4. Mettez à jour ce fichier add4.ucf afin de connecter les ports de add4 avec les bonnes broches du FPGA ( switch et led n'existent plus , ici c'est a, b et sum, les lignes commençant par # sont des commentaires). Il ne peut y avoir deux fichiers ucf pour le même design, faites un remove sur nexys3.ucf via un clic droit sur le nom
Cette fois vous êtes en mesure de créer le .bit en reprenant la procédure de synthèse décrite précédemment. Chargez le fichier add4.bit ainsi créé sur la carte et testez votre design. Faites valider par votre enseignant.
Question 2
On voudrait utiliser le même fichier nexys3.ucf pour ce adder 4 bits. Créez un nouveau fichier VHDL my_add.vhd qui utilise alors les ports nommés switches(7:0) et led(7:0) en entrée et sortie. Simulez et testez ce nouveau circuit, il faudra le mettre en top module. Faites valider en fin de séance.
Question 3
Pour les plus rapides, ISE permet de mélanger le design via des schémas et des codes VHDL. Un code VHDL peut ainsi devenir un composant manipulable dans un schéma. Et inversement un schéma peut générer du code VHDL qui sera utiliser dans un design VHDL. En cherchant un peu dans les menus,il faudrait réussir à créer un symbol à partir du nouveau code my_add.vhdl, placer ce symbole dans le schéma toplevel et le connecter aux ports de toplevel puis cette fois synthétiser toplevel pour obtenir le même comportement... Faites valider également.....