Leçon 4 : Afficheur 16 bits

Dans ce TP, vous allez utiliser ISE pour construire des circuits séquentiels, les simuler et les exécuter sur la carte. Vous verrez comment assembler des bascules D afin de réaliser des compteurs cadencés par une horloge. Vous verrez comment ralentir l’horloge du système en utilisant de tels compteurs. La mise en œuvre vous permettra de réaliser un circuit séquentiel complet, qui vous servira tel que dans la construction de votre processeur S3.

Les circuits séquentiels sont indispensables pour tous les processeurs. Ils permettent d’introduire la notion de temps et de durée dans un circuit numérique. Cette notion de temps existe de par la nature même du support technologique : traverser une porte AND ou un INVerseur demande un certain temps. Les signaux sont donc liés à des événements temporisés et leur valeur dépend de l’instant concerné. Les circuits programmables sont efficaces lorsque leur programmation est synchrone, c’est-à-dire lorsque le temps de réponse d’un circuit combinatoire peut être borné pour une technologie donnée. On peut alors garantir qu’après un temps égal ou supérieur à cette borne le résultat de toutes les sorties du circuit sont correctes et utilisables par un autre circuit combinatoire. Un signal périodique, appelé Horloge, nous permet de cadencer un ensemble complexe de circuits logiques en garantissant que les entrées à l’instant t correspondront aux sorties produites depuis l’instant t-1. Là encore le choix de la période de l’horloge dépend de la technologie cible et du maximum des bornes de tous les circuits.

Connaissances requises

Logique séquentielle, bascule, multiplexeur, compteur.

Objectifs

Dans ce TP, vous allez utiliser ISE pour construire des circuits séquentiels, les simuler et les exécuter sur la carte. Vous verrez comment assembler des bascules D afin de réaliser des compteurs cadencés par une horloge. Vous verrez comment ralentir l’horloge du système en utilisant de tels compteurs. La mise en œuvre vous permettra de réaliser un circuit séquentiel complet, qui vous servira tel que dans la construction de votre processeur S3.

Le projet

Vous allez dans une première étape construire un compteur modulo 4 à partir de deux bascules D. Vous verrez comment utiliser l’horloge de la carte pour incrémenter automatique ce compteur dans le temps. Ensuite vous construirez un afficheur de mots de 16 bits sur les 4 afficheurs 7 segments. Comme nous l’avons observé lors de la leçon 1, il faudra 4 phases successives qui afficheront chacune 4 bits du mot sur un afficheur différent, la technique consiste à jouer avec la valeur de anodes(3:0) afin de balayer successivement ces 4 afficheurs et assez rapidement pour que l’œil ne puisse percevoir le balayage.

Bascule D et compteur

Comme toujours je vous propose de créer un nouveau projet TP4. Créez ensuite une New Source de type Schematic nommée toplevel. Une fois le fichier créé prenez l’habitude de mettre de suite à jour les Properties : rappelez-vous celle liée au fichier ucf et qui autorise les contraintes non utilisées et celle liée au démarrage avec l’option JTAG. Tout cela devient un automatisme et je vous fais grâce des copies d’écran ISE. S’il le faut relisez les leçons précédentes. Nous reviendrons sur toplevel par la suite…

La bascule D

La bascule D utilisée fonctionne sur le front montant de l’horloge, c’est-à-dire que le changement de la sortie Q est effectif à l’instant où l’horloge passe de 0 à 1 . C’est seulement à cet instant que la sortie prend la valeur de l’entrée. Entre deux fronts successifs la valeur en entrée peut changer sans conséquence sur la sortie. On va utiliser cette période pour changer la valeur de D. Si on inverse la sortie Q pour la reconnecter à l’entré D, on observera un changement cyclique de la sortie Q qui s’inverse à chaque front montant de l’horloge.

Ajoutez une New Source nommée compteur4 de type Schematic. Dans ce schéma vous allez instancier un composant fd, il est classé dans la bibliothèque flip flop. Vous pouvez (devriez) toujours relire le Symbol Info. Vous ajoutez un inverseur inv qu’il faut retourner : lors de la création par un rotate 180 ou par un clic droit Symbol> Mirror ou par le bouton Mirror . Cet inverseur reçoit la sortie de Q et produit l’entrée D de votre bascule. Vous ajoutez ensuite un fil clk sur l’entrée C et un fil Q avec leurs deux I/O Marker. Vous l’avez sans aucun doute remarqué, ISE utilise des noms par défaut pour toutes les instances, fils etc. En double cliquant sur le symbole, on peut changer ce nom, c’est bien utile pour s’y retrouver lors de la simulation. Nommez la bascule BasculeD_0. Vous allez déjà essayer de simuler ce circuit !

Figure 48 Bascule fd

Comme pour la leçon précédente, vous créez une new source de type VHDL Test Bench que vous nommerez compteur4_tb. Vous choisissez compteur4 comme source associée.

Figure 49 Création test_bench pour compteur4

Vous allez modifier le process du fichier compteur4_tb de telle sorte que l’horloge soit fonctionnelle. L’horloge doit être initialisée à 0 et change d’état toutes les 10 ns (soit une fréquence de 50Mhz). Il suffit de changer les deux parties de code suivantes.

Placez-vous en mode simulation et lancez Isim sur compteur4_tb. Vous pouvez observer le signal clk qui est généré par votre test_bench. Le signal q est lui aussi périodique, il change d’état à chaque front montant de l’horloge. Vous remarquerez que la fréquence de q est deux fois moindre que celle de clk ! Cette propriété est particulièrement intéressante pour réaliser notre compteur.

Figure 50 Simulation bascule D

Le compteur 2 bits modulo 4

Pour un compteur de 0 à 3 en binaire il faut deux bascules, une pour chaque bit: b00 b01 B10 b11. Si on observe la séquence des valeurs produites à chaque top on obtient :

En analysant ligne par ligne, on observe que Q0 change de valeur à chaque incrémentation alors que Q1 change de valeur deux fois moins vite et toujours quand Q0 passe de 1 à 0. Pour Q0 vous venez de simuler le circuit avec une bascule D. Pour Q1 il suffit d’utiliser une seconde bascule D mais au lieu de la cadencer par l’horloge, c’est le signal Q inversé de la première bascule (quand Q0 passe de 1 à 0) qui cadence la seconde bascule. C’est parti! Sur le schéma compteur4.sch, vous allez supprimer le fil en sortie de la bascule ainsi que son I/O Marker. Sélectionnez la bascule avec l’inverseur et leur fil de connexion. Par un copier-coller (CTRL C CTRL V) vous obtenez une deuxième instance de bascule D. Nommez cette instance par double-clic basculeD_1.

Placez un bus en bas horizontalement et nommez-le q(1:0). Placez un Bus Tap entre q(1) et la sortie q de la basculeD_1, placez un Bus Tap entre Q(0) et la sortie q de la basculeD_0. Relié les deux fils ainsi produits avec les entrées des inverseurs correspondants. Placez un I/O Marker sur le bus q(1:0). Enfin la sortie de l’inverseur associé à la basculeD_0 doit être connectée à l’entrée d’horloge C de la seconde.

Figure 51 Compteur modulo 4

Avant de pouvoir simuler ce circuit, il faut mettre à jour les fichiers compteur4_tb.vhd. En effet les ports ont été changés. La sortie q devient un bus q(1:0). (Vhdl ne différencie pas majuscule et minuscule !) Voici les modifications à apporter.

Une fois la simulation lancée. Vous devez obtenir le comportement de notre compteur modulo 4.

Figure 52 Simulation compteur modulo 4

Allez-y pour le test sur la carte. Vous allez générer un symbole pour compteur4. Dans toplevel vous allez instancier ce composant. Ajoutez un fil en entrée nommé clk, un bus en sortie nommé led(1:0). Sur la carte, vous observerez les valeurs du compteur sur les deux premières leds. Importez par un Project> Add Copy of Source le fichier S3.ucf de la leçon 3. On y trouvera les deux leds. Il faut ajouter le signal clk par la commande suivante.

Carte Nexys2

Carte Nexys3

Générez et chargez le fichier toplevel.bit par Adept. Pas grand-chose à observer !!! Les deux leds restent toujours allumées. Que se passe-t-il ?

  • Carte Nexys2 : L’horloge de la carte est de 50Mhz, donc le signal q(0) change de valeur avec une fréquence de 25Mhz et q(1) avec 12,5 Mhz.
  • Carte Nexys3 : L’horloge de la carte est de 100Mhz, donc le signal q(0) change de valeur avec une fréquence de 50Mhz et q(1) avec 25 Mhz.

Impossible pour l’œil de voir les changements. On est ici à plusieurs dizaines de million de changements par seconde. Vous devez ralentir l’horloge ! Vous avez compris le principe : une bascule D divise la fréquence par 2. Je vous propose de construire un diviseur d’horloge avec des bascules D. Ça ira assez vite avec des copier-coller ! Vous ajoutez une New Source de type Schematic nommée clkdiv. Placez une instance de bascule D par le symbole fd. Instanciez également un inverseur en affichage mirror. Reliez Q à l’entrée de INV et D à la sortie.

Sélectionnez l’ensemble, avec un premier copier-coller vous avez deux bascules. Reliez la sortie Q de la première à l’entrée C de la seconde. Ici ce n’est pas un compteur et l’ordre importe peu, il faut mieux traverser le moins de porte possible, on évite un inverseur entre chaque bascule. Par une suite de copier-coller, créez ainsi une ligne de 7 bascules. Placez les connections entre les sorties Q et les entrée C. Par des copier-coller créez encore trois lignes de bascules, vous pouvez supprimer les deux dernières pour la Nexys2 et la dernière pour la Nexys3. Ajoutez là encore les connexions manquantes. Sur l’entrée C de la première bascule placez un fil nommé clk avec son I/O Marker. Deux bascules vont nous intéresser particulièrement:

  • Carte Nexys2 : la 18ième et la 26ième,
  • Carte Nexys3 : la 19ième et la 27ième.

Vous tirez deux fils en sortie de ces bascules, vous les nommez clk190 et clksec et ajoutez deux I/O Marker. La fréquence de clk190 est de l’ordre de 190 hz, elle sera utile plus tard. La période de clksec est environ de 1,3 seconde. C’est celle-là que vous utiliserez pour cadencer votre compteur. On obtient le circuit suivant.

Figure 53a Un diviseur de clock pour Nexys2

Figure 53b Un diviseur de clock pour Nexys3

Ensuite créez le symbole et placez-le dans toplevel entre l’I/O Marker et votre compteur. Utilisez la sortie clksec pour cadencer votre compteur afin d’observer le changement de vos leds environ chaque seconde. Cette construction de clkdiv entraîne des décalages d'horloge qui peuvent être gênants pour certains développements. ce n'est pas le cas ici car les signaux produits sont exclusivement utilisés pour les I/Os de la carte. Une autre construction est proposée comme exercice à la fin de cette leçon.

Figure 54 Toplevel pour le compteur 4 ralenti

Votre compteur4 est donc fonctionnel. Vous allez pouvoir l’utiliser pour réaliser les 4 affichages successifs sur votre afficheur. Pour cela vous avez besoin d’un multiplexeur 4 entrées. Il vous permettra de choisir en fonction de la valeur de votre compteur, quelle afficheur utiliser et donc quelle valeur envoyer sur anodes, un autre multiplexeur vous permettra par la même occasion de définir quelle partie du mot de 16 bits (4x4) afficher sur cet afficheur.

Ce multiplexeur doit recevoir 4x4 bits en entrée, 2 bits de sélection (0 à 3) et produire 4 bits en sortie. Un tel multiplexeur n’existe pas dans la bibliothèque ISE. Vous allez le construire vous-même.

Créez une nouvelle source de type Schematic nommée Mux4x4. Placez 4 bus verticaux avec leur I/O Marker nommés I0(3:0), I1(3:0), I2(3:0), I3(3:0) (utilisez copier-coller une fois le premier réalisé, il suffira alors de changer le nom par défaut). Placez 4 instances de M4_1E que vous trouvez dans la bibliothèque mux. Placez une bus à gauche nommé O(3:0) qui sera votre sortie. Placez un bus en haut horizontalement nommé S(1:0) c’est votre sélecteur. Il reste à placer les Bus Tap en entrée puis en sortie en respectant scrupuleusement les indices. Pour le premier bus I0, sélectionnez le bus puis connectez les 4 Bus Tap aux 4 M4_1E sur l’entrée D0, il faut mieux commencer par l’indice 3 car ISE le décrémente pour vous automatiquement. Faites de même pour les autres bus I1 sur D1, I2 sur D2 et I3 sur D3. Placez les entrées E à VCC (bibliothèque General). Enfin avec 2 Bus Tap reliez le fil S(0) aux S0 des 4 M4_1E et le fil s(1) aux S1. Connectez les quatre sorties des M4_1E au bus O(3:0) par 4 Bus Tap en respectant le même ordre dans les indices. Il vous manque encore deux I/O Marker sur s(1:0) et sur O(3:0). Vous obtenez le circuit suivant. Vous pouvez simuler quelques jeux d’essai à la main en utilisant comme auparavant Force Constant de Isim. Enfin créez le symbole correspondant.

Figure 55 Multiplexeur 4x4

Vous avez déjà réalisé un afficheur 7 segments lors du TP1, vous pouvez par Project>Add Copy of Source ajouter le code X7seg.vhd qui doit se trouver dans votre projet TP1. Il s’agit de la version initiale du code, pas celles des questions posées en fin de TP. Ce composant a déjà été testé, vous pouvez de suite en créer un symbole.

Vous allez pouvoir créer un composant afficheur16 qui sera réutilisé ultérieurement pour notre processeur S3. Ajoutez une New Source de type Schematic de nom afficheur16. Vous y placez un compteur4. Le compteur4 est connecté en entrée à un I/O Marker nommé clk. Vous y instanciez aussi deux mux4x4 l’un sous l’autre et à droite du compteur4. Placez une instance x7seg à droite du premier mux4x4 et connectez la sortie de mux4x4 avec l’entrée de x7seg : c’est la valeur du digit que vous afficherez. Vous pouvez ajouter un bus en sortie de x7seg sur sevenseg(6:0) en lui donnant le même nom et en y plaçant un I/O marker (vous n’utiliserez pas la sortie anodes de x7seg qui est figée à b1110 dans le code de X7seg que vous avez récupéré). Sur le second mux4x4 connectez un bus en sortie et nommez le anodes(3:0), avec son I/O Marker. Il vous reste à alimenter vos deux multiplexeurs. Devant le premier placez à gauche un bus vertical appelé data(15:0) avec son I/O Marker. Afin de sélectionner successivement les 4 digits à afficher, avec 4 Bus Tap connectez data(3:0) à I0, data(7:4) à I1, data(11:8) à I2 et data(15:12) à I3. Vous pouvez ensuite connecter la sortie de votre compteur4 à l’entrée s(1:0) de chaque multiplexeur, c’est la même sélection cyclique pour les deux multiplexeurs. Sur le deuxième multiplexeur, vous allez ajouter en entrée les quatre valeurs constantes b1110 b1101 b1011 et b0111 afin de sélectionner le bon digit à chaque incrément du compteur4. Vous avez déjà construit des constantes (Figure 37, Figure 38). Pour la première constante ajoutez un symbole constant (dans general) directement sur le port I0, changez sa valeur par un double clic en b1110 et validez, puis refaire un double clic sur la constant pour cette fois sélectionner Cvalue et par edit traits changer sa taille à 4 et le radix à 2. Avec un copier et 3 coller vous faites la même chose pour les ports I1 I2 et I3. Il suffira de changer la valeur.

Figure 56 Constante de 4 bits

Figure 57 Afficheur 16 bits

Vous pouvez simuler afficheur16. Comme chaque fois, il faut ajouter un test bench afficheur16_tb. Le code vhdl est sensiblement le même, il faut générer le signal clk, et ajouter une valeur initiale au bus data(15:0). Je vous propose d’afficher la valeur x1234.

Vous observez lors de la simulation les valeurs successives de sevenseg et de anodes. Elles doivent correspondre à l’affichage de 4, 3, 2, 1 de la gauche vers la droite.

Il vous reste à valider ce TP sur la carte. En revenant sur toplevel, vous instanciez un afficheur16 et un clkdiv. Il faut utiliser la sortie clk190 en entrée de l’afficheur, ce qui correspond aux caractéristiques techniques de votre matériel. Ajoutez un fil clk en entrée de clkdiv et deux bus sevenseg et anodes en sortie de afficheur16, avec leur I/O Marker. Reste à placer une data en entrée. Placez un bus data(15:0) en entrée de votre afficheur16. La carte ne dispose que de 8 switches, je vous propose d’afficher cet octet sur l’afficheur suivi de x00 : si vous placez x24 sur les switches, vous afficherez x2400. Créez un bus switches(7:0) avec son I/O Marker, placez une instance de Ibuf8 et en sortie placez y un bus. Vous pourrez alors placer un Bus Tap entre ce bus et data(15:8). Un second Bus Tap entre data(7:0) et la constante x00 finalise la conception de votre circuit. Vérifiez avant de lancer la compilation que toplevel est bien la racine de votre projet.

Figure 58 Toplevel pour tester votre afficheur

A vous de jouer

Question 1

Reprenez le TP3 avec votre additionneur 4 bits et affichez le résultat sur votre afficheur16 en utilisant les deux premiers digits pour le résultat sur 5 bits.

Question 2

Je vous propose de reprendre l’analyse de clkdiv. Il est possible d’utiliser directement les compteurs proposés par ISE. En particulier le compteur CB16CE est un compteur sur 16 bits qui peut se connecter en cascade : avec deux composants CB16CE vous pouvez construire un compteur 32 bits. Ensuite il suffira de produire en sortie les deux fils associés aux 18 et 26ième bits pour Nexys2 ou 19 et 27ième pour Nexys3. Je vous guide dans la construction de ce nouveau schématique testclk.

    1. Placez deux instances de CB16CE que l’on trouve dans la bibliothèque counter. N’hésitez pas à lire Symbol Info !
    2. Reliez les deux entrées C au même fil clk avec son I/O Marker.
    3. Reliez le premier CE à Vcc, ce compteur est toujours actif.
    4. Reliez les deux CLR à Gnd, on ne remet jamais à zéro.
    5. Reliez la sortie CEO du premier compteur à l’entrée CE du second. Cela construit la cascade : le second sera actif seulement lorsque les 16 bits en sortie du premier valent ‘1’. A ce moment les 16 bits de poids forts sont incrémentés de 1 !
    6. Placez un bus en sortie Q du second compteur vous pouvez le nommer poids_forts.
    7. Ajoutez deux Bus Tap sur les fils 1 et 9 sur ce bus pour la carte Nexys2 et 2 et 10 pour la carte Nexys3 (fréquences différentes).
    8. Ne pouvant placer directement un I/O Marker sur un fil d’un bus ajoutez un symbole buffer BUF sur chacun des deux fils poids_forts(1) et poids_forts(9) sur Nexys2 et poids_forts(2) et poids_forts(10) sur Nexys3..
    9. Enfin créez les deux fils en sortie des BUF, nommez-les clk190 et clksec.
    10. Placez vos I/O Marker sur ces deux fils.
    11. Remplacez clkdiv par ce nouveau symbole testclk dans toplevel pour un test.

Réponses

Curieux...

Un autre implémentation d'un afficheur 7 segments sans clk190!