# Very High Speed Integrated Circuit Hardware Description Language/Travail pratique/Utiliser des shields Arduino avec les FPGA

Comme son titre l'indique, ce chapitre est destiné à étudier les liaisons dangereuses (ou pas) entre les shields destinés aux Arduinos (5 V) et les FPGA (3,3 V). Ici, le mot shield sera pris dans un sens très large : tout ce qui se connecte à l'Arduino rapidement, y compris avec des fils et des plaques à essais.
La très grande majorité des shields Arduino sont prévus pour être alimenté en 5 V. L'utilisation de ces shields avec des FPGA qui fonctionnent en 3,3 V nécessite donc un certain nombre de précautions. Celui qui craint le plus dans l'histoire est naturellement le FPGA.
Il existe des cartes FPGA avec un connecteur de type Arduino, donc capable de recevoir un shield :
* la DE0 nano Soc de chez Terasic en est un premier exemple. Elle est équipée d'un cyclone V de chez Altera(Euh... pardon, de chez Intel) . Le connecteur Arduino de cette carte fournit du 5 V à l'endroit normal du 5 V des cartes Arduino. Cela veut dire que si vous mettez un shield sur cette carte, vous risquez d'endommager le FPGA. Il suffit d'avoir 3 boutons en pull-up et vous avez automatiquement du 5 V sur quelques entrées du FPGA !
* la DE10-lite du même constructeur possède aussi un connecteur Arduino.
* La carte Arty en est un autre exemple de chez Digilent. Nous ne l'avons pas encore exploré (car nous n'en possédons pas) et ne savons donc pas comment est géré le 5 V. Une phrase dans la documentation nous laisse penser qu'on a le même type de problème qu'avec la carte précédente : The Arty is not compatible with shields that output 5 V digital or analog signals. Driving pins on the Arty shield connector above 5 V may cause damage to the FPGA.
Pour cela nous avons décidé de faire nos propres shields en gardant quelques bonnes idées des shields commercialisés. Il est difficile cependant de se mettre un bandeau sur les yeux et de ne pas regarder vers l'orient. Même si construire est une idée raisonnable pour un établissement qui enseigne l'électronique et donc la fabrication de cartes, les bas prix des shields venant de Chine la met à mal pour les hobbyistes et même les enseignants qui ont des budgets de plus en plus serrés. Nous avons en effet trouvé un shield avec quelques boutons et un afficheur LCD de deux lignes de 16 caractères pour un peu moins de 4 € et un shield multifonction pour un peu plus de 5 €. Tous les deux ont été testés et fonctionnent parfaitement avec des Arduino. Nous allons donc explorer leur utilisation dans ce chapitre en remplaçant l'Arduino par un FPGA. Et nous en profiterons pour nous intéresser à bien d'autres shields et capteurs...
Pour les cartes Xilinx de Digilent, pensez à relire les connecteurs PMod pour comprendre cette connectique.

## Étude du shield multi fonction

Le shield multifonction est décrit par exemple ici.
Cette carte est prévue pour un fonctionnement en 5 V. Les 4 digits d'affichage sept segments sont pilotés par deux registres à décalage qu'il nous faudra étudier pour bien comprendre ce que l'on cherche à réaliser. Le point important à ce stade est qu'ils ont été choisis en CMOS (74HC595) et que par conséquent le 3,3 V ne leur fait pas peur. L'autre problème éventuel est de savoir si les afficheurs fonctionnent en 3,3 V. La réponse est OUI.

### Présentation

Prenez le code d'exemple présenté ici. Nous vous conseillons fortement son utilisation avec une carte Arduino pour une prise de contact rapide. On reproduit ce code ici
Ce programme est sensé afficher 0123 sur les 4 digits. Il montre aussi quelques détails importants sur le câblage :
* le transfert des données se fait à l'aide de trois fils (seulement) et c'est ce qui en fait tout son intérêt. Ces trois fils sont décrit maintenant
* le fil de donnée DATA_DIO est câblé en broche 8 Arduino
* le fil d'horloge de transfert CLK_DIO est câblé en broche 7 Arduino
* le fil de mémorisation est câblé en broche 4
Ces informations sont vitales pour nous.
Revenons un peu sur cette histoire des trois fils. Un afficheur sept segments 4 digits comporte au moins 12 fils :
* 7 fils pour chacun des segments
* 1 fil pour le point
* 4 fils pour la sélection de chacun des digits.
Réussir à n'utiliser que trois sorties pour l'utiliser est donc une idée intéressante. Elle est réalisable en remplaçant l'écriture parallèle par une écriture série. Ce qui rend la mise en œuvre délicate est le multiplexage des afficheurs : il faut mettre à jour sans arrêt l'affichage pour faire croire au lecteur qu'il est simultané sur les quatre afficheurs alors qu'il n'en n'est rien. En programmation, ceci peut être réalisé à l'aide d'une interruption qui s'occupe des transferts dans les deux 74HC595. En VHDL, le matériel doit s'occuper de tout cela.

### Notre montage d'essai

Nous n'avons pas beaucoup de fils à brancher à cause de l'utilisation des registres à décalage. 5 fils en tout (alimentation comprise). Le connecteur PMod des cartes Digilent est déjà décrit dans un autre chapitre et permet de brancher 6 fils (y compris alimentation). Un simple connecteur PMod est donc suffisant et donc facile à trouver sur les cartes Digilent.
* le Vcc 3,3 V de PMod est amené au 5 V du shield
* La masse de PMod est amenée à la masse du shield
* le suivant, fil de donnée, est amené à la broche 8 du shield
* le suivant, fil d'horloge, est amené à la broche 7 du shield
* le suivant, horloge de mémorisation, est amené à la broche 4 du shield.
Tous les numéros apparaissant dans cette description correspondent à la sériegraphie du shield.
Évidemment, une connexion aussi simple ne permet pas d'avoir accès à toutes les fonctionnalités du shield. Pour cet exemple seuls les 4 digits des afficheurs sept segments sont gérés par le FPGA. Si vous voulez utiliser l'information des boutons poussoirs il vous faut savoir qu'ils sont montés avec une résistance de tirage vers le haut (pull-up) et sont connectés aux broches serigraphiées A1, A2 et A3 du shield. Donc trois fils en plus. Les 4 leds sont reliées à 13, 12, 11 et 10 encore 4 fils. Le buzzer est relié à 3 avec donc un seul fil.

### Du VHDL pour afficher une donnée sur 4 digits

Résoudre ce problème est pédagogiquement très intéressant pour l'étude des registres à décalages et aussi pour la gestion d'un séquencement à l'aide d'un compteur.
Dans la suite nous serons amenés à réaliser deux types de signaux :
* un tick : signal à "un" pendant une seule période d'horloge globale du FPGA (nous utiliserons cette dénomination anglo-saxonne dans la suite de ce chapitre)
* une horloge : signal qui reste à 1 sur plusieurs fronts et à 0 sur plusieurs fronts de l'horloge globale du FPGA
Le tick ne servira qu'à l'intérieur du FPGA pour réaliser des montages synchrones tandis que l'horloge pilotera des circuits externes incapables de fonctionner à la fréquence du FPGA. Tout ceci va très vite devenir plus clair avec les mises en pratiques dans les exercices qui suivent.
* Quand on vous dit qu'un tick ne dure qu'une période d'horloge globale, cela veut dire qu'il ne dure absolument pas longtemps (20ns pour 50MHz).

#### Introduction : Exercice 1

Nous allons commencer par réaliser un compteur 16 bits. Nous allons afficher son comptage sur les Leds disponibles : 8 sur la Nexys 3 (Digilent) et 16 sur la DE2-115 (Terasic). Il est donc impossible d'utiliser l'horloge 100MHz de la carte Nexys 3 et espérer voir quelque chose à l’œil. Il faut donc utiliser un autre compteur pour diminuer cette fréquence. Ceci a été présenté plusieurs fois dans ce livre et ailleurs :
* TP4 introduction au séquentiel
* Décodeur 8 bits vers deux afficheurs
* Compteur de passages
Mais à chaque fois il s'agissait de prendre le bit de poids fort du compteur et de l'utiliser comme horloge de l'étage suivant. Cette façon de faire est assez facile à comprendre mais déconseillée pour une utilisation dans un FPGA. On doit lui préférer la méthode synchrone : toutes les horloges de tous les composants sont reliées à une horloge commune : l'horloge globale.
Nous allons donc réaliser l'ensemble demandé dans les règles de l'art : les deux compteurs utiliseront la même horloge. On vous demande de réaliser l'ensemble présenté par le schéma ci-dessus, en commençant par trouver l'équation combinatoire demandée. Il s'agit de réaliser un tick sur ENO, c'est-à-dire un signal qui ne vaut un que pendant une seule période d'horloge : l'horloge globale.
ENO est un diminutif de "enable output" en anglais que l'on peut traduire par sortie d'autorisation
* Lorsque, comme ici sur le schéma ci-dessus, la sortie ENO n'a pas d'entrée correspondante appelée EN dans le composant à réaliser, une simple comparaison sur la valeur du compteur suffit pour fabriquer ENO
* Lorsque la sortie ENO a une entrée correspondante appelée EN dans le composant à réaliser, une double comparaison sur la valeur du compteur et sur la valeur à un de EN fabrique ENO

#### Le multiplexeur et le transcodeur : Exercice 2

On vous donne le schéma complet de ce que l'on cherche à faire dans la figure ci-contre. On vous demande de réaliser le multiplexeur et le transcodeur (à droite du schéma).
Le multiplexeur ne présente aucune difficulté de réalisation.
Le transcodeur non plus. Il vous faut seulement savoir qu'il faut un '0' pour allumer un segment et que le segment g est poids faible.
En fin de l'exercice 2 vous aurez donc le compteur 25 bits, le compteur 16 bits, le multiplexeur commandé par 4 interrupteurs et le transcodeur.
Cet ensemble peut être testé sur les afficheurs de votre carte FPGA. Vous prendrez quatre interrupteurs pour la sélection même si le séquenceur de l'exercice 3 n'en délivrera que deux. Cela vous permettra de savoir comment on sélectionne une seul afficheur à la fois et surtout ce qui se passe lorsque vous en sélectionnez deux.

#### Le séquenceur : Exercice 3

Comme d'habitude, l'affichage consiste à réaliser des choses visibles et d'autres non visibles. Par exemple, faire défiler des nombres est intéressant si cela est visible. Mais la commutation des afficheurs, elle, reste invisible. Ceci nécessite la réalisation de plusieurs fréquences :
* une d'environ 2,98 Hz (= 100MHz / 2**25) nécessite donc un compteur de 25 bits sera utilisée pour faire défiler un compteur de 16 bits qui sera affiché
* une d'environ 1,56 MHz (= 100MHz / 2**6) servira à envoyer les données au shield (servira d'horloge de données)
* une d'environ 1525 Hz (= 100MHz / 2**16) servira à commuter les afficheurs
Nous allons essayer de respecter les règles matérielles des FPGA pour les horloges en question. Cela veut dire qu'en fait ce ne seront pas des horloges mais des signaux de validation. Nous n'avons pas assez utilisé cette règle dans ce livre et essayerons de résoudre ce problème plus tard.
Réaliser le séquenceur. La difficulté, bien sûr est de réaliser une partie matérielle qui est en fait du combinatoire. Nous allons vous aider en vous présentant un extrait de la table de vérité (figure ci-contre). Une bonne compréhension de celle-ci est nécessaire pour résoudre ce problème.
Une bonne exploration de la table de séquencement vous montre que :
* les bits Q17 et Q16 serviront à la sélection du digit en cours d'affichage : il y en a 4 donc deux bits suffisent (cela n'apparaît pas sur la table de séquencement)
* les bits Q24 à Q18 ne sont pas utiles au séquencement : les équations logiques ne les feront donc pas apparaître
* il y a deux types de sortie :
** tick ne sont définis que pour une période d'horloge : Eno et Load. Ils seront utiles au fonctionnement interne, c'est-à-dire au FPGA mais pas au shield directement.
** horloges utiles à l'extérieure : Done. On ne peut pas prendre un tick pour cela car cela serait bien trop rapide pour les circuits 74HC595D du shield.
* le 0->1->0 qui apparaît en dernière colonne a pour signification que l'on doit réaliser une période d'horloge sur une ligne. Le seul moyen de faire cela est d'utiliser le bit de poids immédiatement plus petit, à savoir Q5.
1°) Exprimer Eno et Load en fonction de Q(15 downto 0)
2°) Exprimer Done en fonction de Q(15 downto 6)
3°) On vous donne la réalisation de clk1MHz
N'aviez-vous pas remarqué que cette "horloge" ne fonctionne pas tout le temps, seulement après un Load ?
4°) Complétez ce qui est nécessaire pour réaliser le séquenceur complet
5°) A l'aide d'un code un peu similaire à celui ci-dessous, on vous demande d'essayer encore une fois votre code sur votre carte FPGA (sans shield)

#### Le composant "Load_And_Send" : Exercice 4

On redonne ci-contre, la figure que l'on cherche à réaliser. Il ne reste plus qu'à réaliser le composant du bas (à droite) que l'on a appelé load_and_send.
* Une des entrées de ce composant est "sel" mais sur deux bits. Un code comme celui donné dans l'exercice 3 (5° question) sera nécessaire pour le transformer en sélection de 1 parmi 3.
* L'autre est naturellement la donnée qui sort du transcodeur.
Ce que l'on doit faire avec ce composant est de former un signal de 16 bits avec les deux données qui n'en font que 11, et ceci lors d'un LOad synchrone. On vous rappelle que ceci peut se faire avec le code VHDL :
où l'opérateur '&' en VHDL est l'opérateur de concaténation. Le '1' complètement à droite est là pour éteindre le point.
* sa troisième fonctionnalité est de réaliser un décalage vers la droite quand son entrée 'en' est à un.
Quand tout cela sera réalisé, il sera grand temps de réaliser l'ensemble complet.

#### Le code complet corrigé

Voici le code complet correspondant à la résolution de notre problème.
Avec ce code source, seule la gestion du point n'est pas correcte : pas de point pour le digit des unités comme nous le désirons , mais un point sur les trois autres digits !
Comme la photo l'a montré, nous utilisons le connecteur JD d'une carte Nexyx 3. Nous donnons donc le fichier ucf pour cette carte :

#### Comptage décimal : Exercice 5

Le compatge précédent affiche en hexadécimal. Les informaticiens savent le lire mais pas le commun des mortels. On vous demande donc de remplacer le compteur sur 16 bits par quatre compteur BCD cascadés.
Le schéma de principe est présenté dans la figure ci-contre. L'idée générale est de remplacer le compteur 16 bits de la section précédente par quatre compteurs cascadés : un par digit.
Nous n'avons pas nommé les fils internes dans la figure. C'est la première étape de ce que vous ferez si vous ne voulez pas vous perdre dans le câblage des composants.
Indication : Vous disposez d'un compteur décimal BCD cascadable complet:
Voici la solution correspondante.

#### Réalisation d'un réveil : Exercice 6

Transformer l'ensemble des quatre compteurs décimaux en un ensemble capable de compter des heures et minutes.
La résolution de ce problème nécessitera d'utiliser
* le reset pour les compteurs dizaine et unité des heures : détection de 23 et du en sur les unités passe à 00 à l'aide du reset (bouclage synchrone par du combinatoire, synchrone car le reset est synchrone)
* pour les minutes, le comptage des dizaine nécessitera la réalisation d'un compteur modulo 6. Il s'agit de partir du compteur BCD de la section précédente et d'exécuter une simple modification.
L'ensemble du travail à réaliser vous est présenté dans la figure ci-contre. Cet ensemble remplacera le compteur 16 bits qui attaquait le multiplexeur. Nous gardons donc la fréquence de 3 Hz pour ne pas attendre trop longtemps le passage de 23:59 à 00:00 qui est la difficulté de cet exercice.

### Et si l'on mettait un processeur pour piloter tout cela

Maintenant que nous avons réalisé un périphérique fonctionnel, il est grand temps de le piloter par un processeur. Ce travail va consister donc à remplacer le compteur 16 bits de l'exercice 4 par deux ports d'un processeur. Nous allons utiliser pour cela l'ATMega16 déjà décrit dans ce livre.

#### Exercice 7 : Réalisation simple avec deux PORTs

L'objectif de cet exercice est d'arriver au même point que l'exercice 6 mais avec un processeur. Il s'agit donc de faire défiler des chiffres en format hh:mm, deux digits pour les heures et deux pour les minutes. Le transcodage matériel est gardé, cela implique que les données seront sur 16 bits. Pour simplifier le dessin de la figure, un certain nombre de détails n'ont pas été présentés :
* le fichier io.vhd n'est pas dessiné mais une partie de son contenu seulement (le process iowr qui est le seul qui nous intéresse)
* le fichier complet du processeur qui est le fichier complet contenu dans le FPGA n'est que très partiellement présenté
Malgré cette représentation partielle par le dessin, nous espérons que le travail à réaliser vous paraîtra clair :
* retirer le compteur 16 bits de l'exercice 6 et de le remplacer par une entrée sur 16 bits
* réaliser l'entrée 16 bits avec deux PORTs du processeur. On prendra PORTB pour les 8 bits de poids faible, donc les minutes et PORTC pour les 8 bits de poids fort, donc les heures
* le composant top de l'exercice 6 amputé de son compteur 16 bits, sera ensuite changé en composant de "io.vhd" et câblé correctement. Ses trois sorties seront amenées jusqu'aux sorties du processeur
* Ainsi 0x0635 doit afficher 06:35 sur les quatre digits (les deux points ont été rajoutés pour les explications mais ne sont pas gérés et d'ailleurs pas présents sur le shield).
* 0x1129 qui représente 11:29 doit donner 11:30 pour l'ajout de 1 alors que 0x1129 + 1 = 0x112A ! Que se passe-t-il si vous ajoutez 0x0006 à 0x112A ? Est-ce général ?
* 0x1459 qui représente 14:59 à qui on ajoute 1 doit donner 15:00 soit 0x1500. Or si vous ajoutez 1 à 0x1459 cela donne 0x145A ! Que se passe-t-il si vous ajoutez 0x0006 à 0x112A puis 0x00A0 ?
* 0x2359 qui représente 23:59 doit donner 00:00 si on ajoute 1 (soit 0x0000) mais 0x2359+1 = 0x295A !
Réaliser ensuite le programme qui compte comme un réveil. 0n vous conseille cependant d'utiliser l'incrémentation ++, habituelle en C, et de la faire suivre d'une série de tests.
La série de "if" qui suit l'incrémentation n'est pas facile à trouver intuitivement. Elle est liée au fait que l'on veut garder les données par paquets de 4 bits et en décimal. Et que ces données doivent respecter l'arithmétique des des minutes et heures (qui n'est pas habituelle). L'ordre de ces "if" est absolument impératif.

#### Exercice 8 : Réalisation d'un réveil complet

Nous allons utiliser les ressources complètes du shield multifonction pour réaliser un réveil complet. Il s'agit d'utiliser en plus des afficheurs, les trois boutons et le buzzer. Il doit être possible de régler l'heure de réveil et l'armement de ce dernier. L'heure courante sera gardée assez rapide pour les tests.
Le cahier des charges est le suivant :
* le bouton de gauche est utilisé pour l'armement du réveil et allume une LED.
* le bouton du milieu est utilisé pour passer en mode réglage (incrémentation) de l'heure de réveil. Un nouvel appui passe en mode décrémentation. Enfin un nouvel appui quitte le mode réglage
* le bouton de droite incrémente l'heure de réveil. Un bon fonctionnement serait d'augmenter la vitesse de défilement de ces heures en fonction du temps d'appui
La sérigraphie du shield vous donne :
* bouton gauche en A1, bouton milieu en A2 et bouton droite en A3
* LED D1 en 13. En fait les 4 LEDs font face à leur connecteurs
* Le buzzer est en (-3)
Ces informations sont importantes pour câbler votre shield au FPGA.