Cours:TP AutomneM1102
Nous allons regrouper dans ce chapitre un ensemble de TPs qui sont réalisées en niveau 14 (L1) à l'IUT de Troyes.
Sommaire
- 1 Utilisation Basys2 avec ADEPT sous Linux
- 2 TP1 - Tables de vérité et VHDL aux simplifications (3 heures)
- 3 TP2 - Des tables de vérités aux LUT4 (en VHDL)
- 4 Ne pas perdre votre travail réalisé !
- 5 TP3 Arithmétique, comparateurs et multiplexeurs
- 6 TP4 Introduction au séquentiel (3 heures)
- 7 A quoi peuvent bien servir les compteurs ?
- 8 Un petit peu de lecture pour commencer !
- 9 TP5 M1102 : VHDL et Compteurs
- 10 TP6 : Mémoires
- 11 Principe de fonctionnement du réveil
- 11.1 Les graphes d'évolutions et le style « case when »
- 11.2 Programmation sans initialisation
- 11.3 Exercice 1
- 11.4 Compteur à sortie sept segments avec mémoire
- 11.5 Exercice 3 : Texte défilant
- 11.6 Exercice 4 : Chenillard sur LEDs
- 11.7 Autre métode pour utiliser des RAMs
- 11.8 Exercice 6 : Barregraphe sur LEDs
Utilisation Basys2 avec ADEPT sous Linux
En principe, avec les versions modernes de l'ISE, c'est IMPACT qui se chargera de télécharger dans le FPGA. Si vous rencontrez des problèmes de téléchargement, ADEPT peut être utilisé en ligne de commande.
On utilisera la carte Basys 2 avec un SPARTAN 3E 250 (xc3s250e) dans un boîtier CP132.
- Commandes ADEPT et ISE
Detection djtgcfg enum
donne Basys2 come usernameTéléchargement djtgcfg prog -d Basys2 --index 0 --file toto.bit <<<y
Lancement ISE /opt/Xilinx/14.5/ISE_DS/ISE/bin/lin/ise &
TP1 - Tables de vérité et VHDL aux simplifications (3 heures)
L'objectif de ce TP est de montrer qu'avec un FPGA la connaissance d'une table de vérité suffit pour réaliser un programme VHDL (sans les simplifier). Cependant, pour vous faire travailler les tableaux de Karnaugh, on vous demandera parfois de trouver les équations et de les implanter. A la fin de ce TP, vous serez capable
- d'établir une table de vérité
- d'en déduire immédiatement le programme VHDL correspondant
- ou de la transformer à l'aide d'un tableau de Karnaugh en une équation simplifiée et de l'implanter en VHDL
Tous ces allers et retours entre toutes ces formes (Table de vérité, Tableau de Karnaugh, équations) sont la base de l'apprentissage.
Un exemple simple pour comprendre l'IDE Xilinx
Vous allez réaliser un simple OU en suivant un exemple complet réalisé par votre enseignant. L'objectif est d'apprendre :
- à réaliser un fichier VHDL, le sauver et l'ajouter au projet
- à réaliser un fichier de contrainte pour choisir les entrées et sorties, et l'ajouter au projet
- à compiler
- à charger le fichier dans votre FPGA avec IMPACT ou ADEPT
Voici les fichiers VHDL utilisés :
- à partir d'une table de vérité
library IEEE;
use IEEE.STD_LOGIC_1164.all;
ENTITY ou IS
PORT(e0,e1 : IN std_logic;
s : OUT std_logic);
END ou;
ARCHITECTURE arch_ou OF ou IS
SIGNAL entrees : std_logic_vector(1 downto 0);
BEGIN
entrees <= e1 & e0;
WITH entrees SELECT
s <= '1' WHEN "01" | "10" | "11",
'0' WHEN OTHERS;
END arch_ou;
- à partir d'une équation
library IEEE;
use IEEE.STD_LOGIC_1164.all;
ENTITY ou IS
PORT(e0,e1 : IN std_logic;
s : OUT std_logic);
END ou;
ARCHITECTURE arch_ou OF ou IS
BEGIN
s <= e0 OR e1;
END arch_ou;
Modifier cet exemple pour ajouter une sortie qui réalise un ET.
Fichier ucf utile pour Basys 2
Pour éviter de chercher nous donnons quelques contenus du fichier ucf :
# Pin assignment for SWs NET "sw7" LOC = "N3"; # Bank = 2, Signal name = SW7 NET "sw6" LOC = "E2"; # Bank = 3, Signal name = SW6 NET "sw5" LOC = "F3"; # Bank = 3, Signal name = SW5 NET "sw4" LOC = "G3"; # Bank = 3, Signal name = SW4 NET "sw3" LOC = "B4"; # Bank = 3, Signal name = SW3 NET "sw2" LOC = "K3"; # Bank = 3, Signal name = SW2 NET "sw1" LOC = "L3"; # Bank = 3, Signal name = SW1 NET "sw0" LOC = "P11"; # Bank = 2, Signal name = SW0 # Pin assignment for LEDs NET "Led7" LOC = "G1" ; # Bank = 3, Signal name = LD7 NET "Led6" LOC = "P4" ; # Bank = 2, Signal name = LD6 NET "Led5" LOC = "N4" ; # Bank = 2, Signal name = LD5 NET "Led4" LOC = "N5" ; # Bank = 2, Signal name = LD4 NET "Led3" LOC = "P6" ; # Bank = 2, Signal name = LD3 NET "Led2" LOC = "P7" ; # Bank = 3, Signal name = LD2 NET "Led1" LOC = "M11" ; # Bank = 2, Signal name = LD1 NET "Led0" LOC = "M5" ; # Bank = 2, Signal name = LD0
Analyse d'un schéma simple puis synthèse équivalente
On donne le schéma ci-dessus.
1°) Plot the corresponding function in the truth table below and in the Karnaugh map. Find the simplified sum of product expression of s=f(e0,e1,e2).
- Table de vérité
Entrées Sorties e2 e1 e0 a b s 0 0 0 ? ? ? 0 0 1 ? ? ? 0 1 0 ? ? ? 0 1 1 ? ? ? 1 0 0 ? ? ? 1 0 1 ? ? ? 1 1 0 ? ? ? 1 1 1 ? ? ?
Remarque : a et b ne sont pas à proprement parler des sorties. Il s'agit de fils intermédiaires, mais il faut les calculer pour avoir s.
2°) Realize the corresponding simplified expression as a VHDL program with an equation.
3°) Realize the corresponding simplified expression as a VHDL program with a "with select when" statement.
Exercice 2 (Vote au directoire)
Le comité directeur d’une entreprise est constitué de quatre membres :
- le directeur D,
- ses trois adjoints A, B, C.
Lors des réunions, les décisions sont prises à la majorité.
Chaque personne dispose d’un interrupteur pour voter sur lequel elle appuie en cas d’accord avec le projet soumis au vote. En cas d'égalité du nombre de voix, celle du directeur compte double.
On vous demande de réaliser un dispositif logique permettant l’affichage du résultat du vote sur lampe V (pour nous ce sera une LED).
1°) Écrire une table de vérité pour la sortie V puis un tableau de Karnaugh
2°) Réaliser le programme VHDL pour la sortie V avec une équation.
3°) Réaliser le programme VHDL pour la sortie V avec un with select when.
Exercice 3 (Vote au directoire amélioré)
Une société est composée de 4 actionnaires ayant les nombres suivants d'actions A=60, B=100, C=160 et D=180.
Nous désirons construire une machine à voter automatiquement, tenant compte dans le résultat du poids en actions de chaque personne. La machine dispose de 4 boutons poussoirs A, B, C, D et le résultat sera un voyant V qui s'allumera si la majorité pondérée appuie sur les boutons.
1°) Écrire une table de vérité pour la sortie V. Réaliser le programme VHDL correspondant et vérifier que vous avez la bonne table de vérité.
2°) Réaliser le programme VHDL avec un with select when. Remarquez l'apparition d'un WARNING.
3°) Pour comprendre le WARNING de la question précédente, on vous demande de trouver l'équation simplifiée. E l'examinant vous comprendrez quel est le problème. Puis réaliser le programme VHDL avec une équation logique pour la sortie V en supprimant le WARNING.
TP2 - Des tables de vérités aux LUT4 (en VHDL)
Les LUT4 sont aux FPGA ce que les portes logiques sont aux schémas : des briques de base à assembler. Les portes logiques sont figées mais vous pouvez choisir celles qui vous intéressent. Pour les LUT4, ce sont des composants à 4 entrées qui sont universels : ils peuvent réaliser n'importe quelle fonction logique.
Des tables de vérité à l'hexadécimal (cours sur LUTs)
Une table de vérité de trois entrées peut être représentée par un nombre 8 bits que l'on convertit en hexadécimal. Soit donc la table de vérité suivante (trois entrées notées e0, e1 et e2, une sortie notée s) :
- Table de vérité
Entrées Sorties bits e2 e1 e0 s 0 0 0 0 b0 0 0 1 1 b1 0 1 0 1 b2 0 1 1 0 b3 1 0 0 1 b4 1 0 1 0 b5 1 1 0 1 b6 1 1 1 0 b7
Vous pouvez synthétiser la table de vérité à l'aide d'un seul nombre sur 8 bit (poids faible en haut) :
- en binaire ce nombre vaut : 0b01010110
- en hexadécimal ce nombre vaut : 0x56 (X"56" en VHDL)
La valeur hexadécimale 56 est la valeur qu'il vous faudra utiliser dans la partie INIT d'une (catégorie) LUT qu'il faudra câbler.
Combien de bits nécessite l'initialisation d'une lut4 à 4 entrées ? Combien de chiffres hexadécimaux ?
Utiliser des LUTs en VHDL
Un exemple est donné maintenant :
library IEEE; -- transodeur binaire -> 7 segments
use IEEE.STD_LOGIC_1164.ALL;
library unisim;
use unisim.vcomponents.all;
ENTITY transcodeur IS PORT(
e : in STD_LOGIC_VECTOR(3 DOWNTO 0); -- 4 entrées
s : out STD_LOGIC_VECTOR(6 DOWNTO 0)); -- 7 sorties
END transcodeur;
ARCHITECTURE atranscodeur OF transcodeur IS BEGIN
i1 : LUT4
generic map (INIT => X"EAAA")
port map( I0 => e(0),
I1 => e(1),
I2 => e(2),
I3 => e(3),
O => s(0) );
.....
Cet exemple vous montre comment on câble une LUT4 en VHDL (port map) et comment on l'initialise (generic map). Le câblage de ce composant est correct mais pas son initialisation puisqu'on vous demande de la calculer plus loin.
Les deux lignes library ... et use ... sont à ajouter avant toute entité qui utilise une LUT en plus bien sûr de "library ieee;".
Multiplieur de deux nombres de 2 bits
Exercise 1 (English)
Design and build a combinational logic circuit with four inputs and four outputs that multiplies two 2-bits numbers, labeled X, and Y. The output is labeled Z. Use a truth table and find out the corresponding with select when.
library IEEE;
use IEEE.std_logic_1164.all;
entity multiplier is
port ( X,Y: in STD_LOGIC_VECTOR (1 downto 0); -- binary inputs
Z : out STD_LOGIC_VECTOR (3 downto 0)); -- binary output
end multiplier;
1°) Réaliser ce circuit avec un WITH SELECT WHEN
2°) Réaliser ensuite ce circuit avec 4 LUT4
Transcodeur binaire 7 segments
Lire 7 segments.
On va réaliser un transcodeur binaire décimal vers un afficheur 7 segments. L'objectif de ce TP est d'utiliser toutes les techniques classiques de synthèse combinatoire.
Présentation du sujet
Un schéma présente de manière symbolique ce que l'on cherche à faire.
sel est choisi à 0 pour sélectionner l'afficheur de gauche. La valeur binaire (de 0 à F) choisie sur les interrupteurs est convertie pour être affichée comme ci-contre.
Exercice 2 : Transcodeur hexadécimal vers sept segments et « with select when »
1°) First complete the truth table below. Read the first line carefully before starting.
- Table de vérité
Entrées Sorties sw3 sw2 sw1 sw0 a b c d e f g 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1
2°) Realize this truth table as circuit in VHDL (style "with select when").
3°) Faire la même réalisation en utilisant des LUT4.
Il serait bon de mettre de côté un programme solution de la question 2° et / ou celui de la question 3°. Vous en aurez besoin plus tard. |
Exercice 3 : Transcodeur pour dé
1°) Réaliser le transcodeur ci-dessus avec les LEDs présentes sur la carte FPGA en utilisant un with select when. Ce que vous avez à réaliser est donc un circuit qui comporte 3 interrupteurs en entrée et 7 leds en sortie (voir schéma ci-contre).
2°) Faire le même travail avec 7 LUT4.
3°) En gardant ce que vous avez fait en question 2°, on vous demande d'y ajouter un affichage sur les sept segments en utilisant le programme de la question 2° ou 3° de l'exercice précédent (que l'on vous avez demandé de mettre de côté).
Indication : Malheureusement les tests ne seront pas facilités puisque les leds utilisées sont alignées... mais l'esprit humain peut contourner ce genre de détail.
TP3 Arithmétique, comparateurs et multiplexeurs
L'arithmétique consiste à implanter des fonctions de base de l'arithmétique, c'est à dire addition, soustraction et multiplication. L'utilisation de l'arithmétique dans un FPGA doit suivre ses propres règles. Nous allons commencer par examiner l'addition, d'abord sans se préoccuper du fait que l'on utilise un FPGA, puis on cherchera à utiliser les composants Xilinx.
Du demi-additionneur à l'additionneur 1 bit
Lire Additionneur dans Wikipédia.
Exercice 1
1) Implanter un additionneur 1 bit avec deux LUTs. Pour les tests, les entrées seront reliées à des interrupteurs et les sorties à des LEDs.
2) Réaliser 4 fois le schéma précédent et montrer que l'on peut réaliser ainsi un additionneur 4 bits. N'oubliez pas que la somme de deux nombres de 4 bits peut donner un nombre de 5 bits. (Lire additionneur parallèle à propagation de retenue)
Additionneur 4 bits
Après avoir réalisé un additionneur 4 bits, on vous propose l'exercice ci-dessous. L'additionneur 4 bits est nommé 7483 dans le schéma. Vous pouvez utiliser l'additionneur 4 bits des Tds en utilisant des std_logic_vector
Exercice 2 (transcodeur BCD vers EXCESS- 3)
Code converter is a combinational circuit that translates the input code word into a new corresponding word. The excess-3 code digit is obtained by adding three to the corresponding BCD digit. To Construct a BCD-to-excess-3-code converter with a 4-bit adder feed BCD-code to the 4-bit adder as the first operand and then feed constant 3 as the second operand. The output is the corresponding excess-3 code.
Realize this circuit diagram in VHDL.
Indications :
- Un transcodeur comme celui demandé peut être réalisé avec 4 LUT4. Mais remarquez que celui qui est proposé dans le schéma est bidirectionnel.
- On pourra utiliser le code ci-dessous pour l'additionneur 4 bits en lieu et place de celui qu'on a réalisé dans l'exercice 1 :
-- addition sur 4 bits
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
ENTITY add4 IS
PORT (a,b : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
Cin : IN STD_LOGIC; --retenue précédente
s : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)); --retenue en s(4)
END add4;
ARCHITECTURE arch_add4 OF add4 IS
BEGIN
-- ne pas confondre + avec OR
s <= conv_std_logic_vector((conv_integer(a) + conv_integer(b) + conv_integer(Cin)),5);
END arch_add4;
- La table de vérité du code excess-3 est :
- Table de vérité du code EXCESS-3
Entrées Sorties B3 B2 B1 B0 E3 E2 E1 E0 0 0 0 0 0 0 1 1 0 0 0 1 0 1 0 0 0 0 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 1 0 1 0 1 1 0 0 0 0 1 1 0 1 0 0 1 0 1 1 1 1 0 1 0 1 0 0 0 1 0 1 1 1 0 0 1 1 1 0 0 1 0 1 0 Φ Φ Φ Φ 1 0 1 1 Φ Φ Φ Φ 1 1 0 0 Φ Φ Φ Φ 1 1 0 1 Φ Φ Φ Φ 1 1 1 0 Φ Φ Φ Φ 1 1 1 1 Φ Φ Φ Φ
Exercice 3
Première partie
Réaliser une comparaison seule (figure ci-contre en remplaçant le "neuf" par des interrupteurs). Réaliser le fichier ucf pour utiliser sw7 ... sw0 en entrée et led0 en sortie (pour GT seulement). Tester.
Indication : Le comparateur COMPM4 présent dans cet exercice peut être réalisé par le code VHDL :
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.std_logic_unsigned.all;
entity COMPM4_exo3 is
port(
GT : out std_logic;
LT : out std_logic;
A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic;
B0 : in std_logic;
B1 : in std_logic;
B2 : in std_logic;
B3 : in std_logic
);
end COMPM4_exo3;
architecture COMPM4_exo3_V of COMPM4_exo3 is
signal a_tmp: std_logic_vector(3 downto 0);
signal b_tmp: std_logic_vector(3 downto 0);
begin
a_tmp <= A3&A2&A1&A0;
b_tmp <= B3&B2&B1&B0;
GT <= '1' when (a_tmp > b_tmp ) else '0';
LT <= '1' when (a_tmp < b_tmp ) else '0';
end COMPM4_exo3_V;
----- CELL CB4CE_HXILINX_chenillard -----
Deuxième partie
Puis fixer les entrées Bi à 9 pour en faire une fonction de 4 entrées A3,A2,A1,A0 comme dans la figure. Remplir une table de vérité puis un tableau de Karnaugh.
- Table de vérité du comparateur à 9
Entrées Sorties A3 A2 A1 A0 GT 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1
S | A1 A0 | 00 | 01 | 11 | 10 |
---|---|---|---|---|---|
A3 A2 | |||||
00 | |||||
01 | |||||
11 | |||||
10 |
1°) Déduire de la table de vérité une LUT4 réalisant l'ensemble. La câbler puis l'essayer dans le FPGA. Faire constater à l'enseignant.
2°) Déduire du tableau de Karnaugh une équation simplifiée que l'on implantera en VHDL.
Exercice 4 : additionneur complet (1 bit) et multiplexeur
Implement a full 1-bit adder
(a) using two 8-to-1 MUXes. Connect X,Y, and Cin in to the control inputs of the MUXes and connect 1 or 0 to each data input.
(b) using two 4-to-1 MUXes and one inverter. Connect X and Y to the control inputs of the MUXes, and connect 1’s, 0’s, Cin in , or Cin′ in to each data input.
(c) again using two 4-to-1 MUXes, but this time connect Cin in and Y to the control inputs of the MUXes, and connect 1’s, 0’s, X, or X′ to each data input. Note that in this fashion, any N-variable logic function may be implemented using a 2 (N−1) to-1 MUX.
Indication
Ce travail nécessite de réaliser un assemblage de circuits donc se fait avec des PORT MAP.
Voici le code de départ d'un multiplexeur 8 vers 1.
-- description de la memoire de transcodage
library ieee;
use ieee.std_logic_1164.all;
entity mux8 is port (
sel: in std_logic_vector(2 downto 0);
e : in std_logic_vector(7 downto 0);
s : out std_logic
);
end entity mux8;
architecture behavior of mux8 is
begin
with sel select
s <= e(0) when "000",
e(1) when "001",
e(2) when "010",
e(3) when "011",
e(4) when "100",
e(5) when "101",
e(6) when "110",
e(7) when others;
end behavior;
TP4 Introduction au séquentiel (3 heures)
Besoin d'une horloge pour dépasser le combinatoire
Les compteurs permettent de diminuer la fréquence d'horloge. Il est absolument essentiel de bien comprendre cette propriété des compteurs ! |
Exercice 1
Vous disposez d'une horloge 50MHz en broche "B8" de votre composant FPGA SPARTAN 3E. Réaliser à l'aide d'un compteur 24 bits une horloge d'environ 3 Hz. Sortie sur une LED, le clignotement de celle-ci doit être visible à l'œil.
Indications Le fichier ucf est :
# clock pin for Basys2 Board NET "clk" LOC = "B8"; # Bank = 0, Signal name = MCLK ### NET "clk_slow" CLOCK_DEDICATED_ROUTE = FALSE;
L'horloge que l'on vient de réaliser sera utilisée presque systématiquement par la suite.
Par abus de langage on appellera compteur dans la suite un élément séquentiel qui comporte une horloge mais qui ne compte pas forcément en binaire. Dans ce dernier cas, son équation de récurrence ne peut donc pas s'écrire simplement à l'aide d'une addition.
Réaliser un graphe d'évolution simple
Avant toute chose, il nous faut nous demander comment utiliser des équations de récurrences booléennes. On vous représente ci-après la façon de procéder :
- trouver le diagramme d'évolution
- en déduire le tableau état présent/état futur
- en déduire les équations en utilisant éventuellement un tableau de Karnaugh
Lisez Des diagrammes d'évolutions aux équations de récurrences pour la partie théorique. Vous y trouverez les équations de récurrences nécessaires à la réalisation de l'exercice 2. |
Exercice 2
1°) Realize the system specified above with a state diagram. The clock is, as usual, "clk_slow" (see l'exercise 1). Add two LEDs as outputs to be able to check your VHDL program.
2°) Design a modulo-4 counter with an input D, for Down. When D is not asserted, the counter counts up, modulo-4. When D is asserted (1), the counter counts down, modulo-4. Draw a state diagram to implement it and derive the state table. Then design a complete sequential circuit using VHDL. Please use a 7 segments display to check your VHDL code.
Indication : Si vous voulez avoir une chance de voir les LEDs défiler, vous devez utiliser le compteur de l'exercice 1 pour faire une horloge lente et l'utiliser comme entrée horloge de ce qui vous est demandé. Il y a donc du PORT MAP dans l'air.
library ieee;
use ieee.std_logic_1164.all;
ENTITY cmpt_exo2 IS PORT (
clk: IN std_logic;
q0,q1: OUT std_logic);
END cmpt_exo2;
ARCHITECTURE arch_cmpt_exo2 OF cmpt_exo2 IS
SIGNAL q1q0 : std_logic_vector(1 downto 0);
BEGIN
PROCESS (clk) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
IF (clk'EVENT AND clk='1') THEN
q1q0(0) <= NOT q1q0(0);
-- add the second equation here
END IF;
END PROCESS;
-- mise a jour des sorties
q0 <= q1q0(0);
q1 <= q1q0(1);
END arch_cmpt_exo2;
Compteur décimal à sortie directe sept segments (1 digit en VHDL)
Le compteur sept segments est réalisé en VHDL et sera assemblé avec le dispositif destiné à réaliser l'horloge lente : compteur 24 bits de l'exercice 1.
Exercice 3
1°) Écrire les équations logiques a+, b+, c+, d+ ,e+, f+, g+ en fonction des entrées a, b, c, d, e, f, g. Implanter en VHDL.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY cmpt7seg IS
PORT(CLK_lent : IN STD_LOGIC;
a,b,c,d,e,f,g : OUT STD_LOGIC);
-- ou alors : s7segs : out std_logic_vector(6 downto 0));
END cmpt7seg;
Il nous reste un problème important à résoudre, c'est l'initialisation. En effet pour bien faire il faudrait étudier les 127-10=117 états restants pour voir comment ils se connectent sur notre cycle. C'est un travail important qu'il est impossible de réaliser à moins d'y passer 117 soirées (à raison d'une transition par soirée) soit presque 4 mois !!!
Pour éviter cela on va prévoir une entrée d'initialisation appelée Init au cas où à la mise sous tension on se trouve dans un état non prévu. Cette entrée fonctionnera de manière synchrone, lorsqu'elle sera à 1 un front d'horloge provoquera l'affichage du 0 en sortie du compteur.
2°) Écrire maintenant les équations de récurrence trouvées en 2°) en ajoutant convenablement l'entrée Init.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY cmpt7seg IS
PORT(CLK_lent, Init : IN STD_LOGIC;
a,b,c,d,e,f,g : OUT STD_LOGIC);
-- ou alors : s7segs : out std_logic_vector(6 downto 0));
END cmpt7seg;
Exercice 4
Refaire le même travail que l'exo4 en utilisant un case when et toujours "clk_slow" comme horloge.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY cmpt7seg IS
PORT(CLK_lent : IN STD_LOGIC;
s_7segs : OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END cmpt7seg;
Remarquez l'utilisation du STD_LOGIC_VECTOR au lieu des sorties individuelles. Le fait qu'il soit en OUT implique que l'on utilisera un signal interne pour les "CASE".
Indication : Implanter un diagramme d'évolution en VHDL peut se faire de manière systématique :
TP5 M1102 : VHDL et Compteurs
Exercice 1
Cet exercice ne sera réalisé que par les étudiants qui ne sont pas allés jusqu'au bout du TP 4.
Nous vous donnons deux composants VHDL et on vous demande d'en réaliser un assemblage.
On vous donne les deux composants VHDL suivants. On vous demande de les transformer en symbole (en complétant les transitions de « cmpt7seg » ) et de les réunir à l'aide d'un programme TOP.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY cmpt24bits IS
PORT(clk_50MHz : IN STD_LOGIC;
clk_slow : OUT STD_LOGIC);
END cmpt24bits;
ARCHITECTURE acmpt24bits OF cmpt24bits IS
signal cmpt : std_logic_vector(23 downto 0);
BEGIN
process(clk_50MHz) begin
if rising_edge(clk_50MHz) then
cmpt <= cmpt + 1;
end if;
end process;
clk_slow <= cmpt(23);
END acmpt24bits;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY cmpt7seg IS
PORT(CLK : IN STD_LOGIC;
s_7segs : OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END cmpt7seg;
ARCHITECTURE arch OF cmpt7seg IS -- comment éviter les equations
SIGNAL s7segs : STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
PROCESS(clk) BEGIN
IF (clk'EVENT AND clk='1') THEN
CASE s7segs is --style case when
WHEN "0000001" => s7segs <="???????"; -- premiere transition
WHEN "1001111" => s7segs <="???????"; -- deuxieme transition
WHEN "0010010" => s7segs <="???????"; -- troisieme transition
WHEN "0000110" => s7segs <="???????";
WHEN "1011100" => s7segs <="???????";
WHEN "0100100" => s7segs <="???????";
WHEN "0100000" => s7segs <="???????";
WHEN "0001111" => s7segs <="???????";
WHEN "0000000" => s7segs <="???????";
WHEN OTHERS => s7segs <="0000001"; -- dernière transition
END CASE;
END IF;
END PROCESS;
s_7segs <=s7segs;
END arch;
Nous allons reprendre le problème du compteur sept segments mais de façon plus normale.
Compteur à sortie sept segments sur deux digits en VHDL
Cette partie doit être réalisée avec les afficheurs sept segments reliés à la carte.
Nous allons réaliser cet exercice en plusieurs étapes.
Exercice 2
Nous désirons implanter un ensemble composé d'un compteur 8 bits et sortant sa valeur sur deux afficheurs sept segments ( affichage de 00 à FF)...
Attention, le poids faible doit être à droite !!!
1°) Réaliser d'abord un compteur simple 8 bit associé à une division par 224 et sortant directement sur des LEDs. La seule entrée est clk qui se trouve en "B8" sur le FPGA. Les 8 sorties sont reliées aux 8 LEDs de la carte. Remarquez que le seul compteur qui nous intéresse est le compteur 8 bits de droite, les deux autres étant là pour ralentir l'horloge.
2°) Réaliser maintenant l'affichage des 4 bits de poids faibles sur un seul afficheur.
3°) Réaliser maintenant l'affichage des 8 bits du compteur sur deux afficheurs. La figure donne en principe ce que l'on cherche à faire.
Compteur BCD sur deux digits
Nous cherchons maintenant à modifier le compteur de l'exercice précédent (exercice 2) pour qu'il affiche de 00 à 99.
Exercice 3
Réaliser un compteur BCD 4 bits cascadable. Il sera ensuite cascadé pour fournir un compteur BCD sur 8 bits (deux digits).
Indication : une aide pour réaliser un compteur BCD peut être trouvée ici. Vous devez le modifier pour le rendre cascadable.
Exercice 4 Compteur/décompteur BCD sur deux digits
Réaliser un compteur/décompteur BCD 4 bits. Prévoir les tests correspondants à partir du schéma de l'exercice 2.
Indication : une aide pour réaliser un compteur décompteur BCD cascadable peut être trouvée ici.
TP6 : Mémoires
Le réveil
Dans la partie droite de la figure ci-dessus, vous pouvez apercevoir le diagramme d'évolution du réveil qui sera utilisé comme exemple par la suite.
A partir de "Off", "key"=1 arme le réveil. Si "trip" passe à 1 (c'est à dire que l'heure courante devient égale à l'heure de réveil) le réveil passe en "ringing" et sonne. "trip" ne reste pas très longtemps à un (1 seconde). Son retour à 0 ne suffit pas à arrêter la sonnerie. Seul le passage de "key" à 0 peut l'arrêter. Tout est dans le diagramme d'évolution ! |
Les graphes d'évolutions et le style « case when »
On rappelle encore une fois que le style « case when » permet de ne pas chercher les équations de récurrences. Mais comme nos diagrammes d'évolutions se sont compliqués (par l'ajout d'étiquettes sur les transitions), il nous faudra ajouter des "if then". Cela est tellement intuitif que nous passons directement aux exemples. Nous commençons par présenter partiellement le réveil.
Programmation sans initialisation
Le principe consiste à déclarer d'abord un type énuméré avec une définition symbolique de chacun des états (ici Armed, Off, Ringing) :
TYPE typetat IS (Armed, Off, Ringing); -- dans architecture
SIGNAL etat : typetat;
Ensuite dans un « case when » on détaillera toutes les transitions possibles comme montré ci-dessous dans le cas où l'on ne s'intéresse pas à une initialisation :
-- sans initialisation
BEGIN
PROCESS (clock) BEGIN
IF clock'EVENT AND clock='1' THEN
CASE etat IS
WHEN Off => IF key ='1' THEN etat <= Armed;
ELSE etat <= Off;
END IF;
....
END CASE;
END IF;
END PROCESS;
....
L'idée générale est donc d'utiliser un « case » sur les états avec des « if » pour gérer l'ensemble des transitions.
Exercice 1
Réaliser le réveil ci-dessus en n'oubliant pas de ralentir l'horloge du séquenceur pour éviter les problèmes de rebonds.
Compteur à sortie sept segments avec mémoire
Nous allons utiliser un compteur normal, c'est à dire qui compte en binaire sur 4 bits suivi d'une mémoire pour le transcodage.
Présentation des RAM16X8S
Pour les utiliser, il ne pas oublier les lignes
library UNISIM;
use UNISIM.Vcomponents.ALL;
devant toute entité qui utilise ces mémoires.
Le composant correspondant est (donné ici pour information) :
component RAM16X8S
-- synopsys translate_off
generic( INIT_00 : bit_vector := x"0000";
INIT_01 : bit_vector := x"0000";
INIT_02 : bit_vector := x"0000";
INIT_03 : bit_vector := x"0000";
INIT_04 : bit_vector := x"0000";
INIT_05 : bit_vector := x"0000";
INIT_06 : bit_vector := x"0000";
INIT_07 : bit_vector := x"0000");
-- synopsys translate_on
port ( A0 : in std_logic;
A1 : in std_logic;
A2 : in std_logic;
A3 : in std_logic;
D : in std_logic_vector (7 downto 0);
WCLK : in std_logic;
WE : in std_logic;
O : out std_logic_vector (7 downto 0));
end component;
Il n'est pas à déclarer puisque c'est justement les deux lignes qu'on a rajouté qui le fait. Par contre toute utilisation nécessite un "PORT MAP" précédé par un "GENERIC MAP".
Exercice 2 Travail à réaliser (VHDL)
Calculer les valeurs hexadécimales contenues dans cette ROM RAM16X8S pour réaliser le transcodage qui convient.
Reprendre le diviseur de fréquence par 2**24.
Assembler le tout.
Exercice 3 : Texte défilant
Donner le contenu de la RAM pour afficher le texte : "bonjour A touS" qui défile sur un afficheur.
Réaliser l'ensemble et tester. Faire constater.
Indication : Il n'y a que très peu de choses à changer par rapport à l'exercice 2.
Exercice 4 : Chenillard sur LEDs
1°) On reprend l'exercice précédent mais on sort maintenant sur 8 LEDs (schéma ci-contre). On vous demande de réaliser un chenillard aller et retour. Il faut donc changer le fichier ucf et le contenu de la RAM16X8S.
2°) DS 2014. Les sorties précédentes sont maintenant utilisées comme adresses d'une RAM16x8s comme dans la figure ci-contre. Donner le contenu de la RAM pour afficher le chenillard ci-contre. Réaliser l'ensemble et tester. Faire constater.
Autre métode pour utiliser des RAMs
Si vous voulez que votre outil de synthèse infère une RAM/ROM il vous faut écrire votre RAM/ROM avec un style spécifique. Nous présentons ici un exemple sur lequel nous nous appuierons dans la suite : ROM avec sortie Registered
--
-- ROMs Using Block RAM Resources.
-- VHDL code for a ROM with registered output (template 1)
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity rams_21a is
port (clk : in std_logic;
en : in std_logic;
addr : in std_logic_vector(5 downto 0);
data : out std_logic_vector(19 downto 0));
end rams_21a;
architecture syn of rams_21a is
type rom_type is array (63 downto 0) of std_logic_vector (19 downto 0);
signal ROM : rom_type:=
(X"0200A", X"00300", X"08101", X"04000", X"08601", X"0233A",
X"00300", X"08602", X"02310", X"0203B", X"08300", X"04002",
X"08201", X"00500", X"04001", X"02500", X"00340", X"00241",
X"04002", X"08300", X"08201", X"00500", X"08101", X"00602",
X"04003", X"0241E", X"00301", X"00102", X"02122", X"02021",
X"00301", X"00102", X"02222", X"04001", X"00342", X"0232B",
X"00900", X"00302", X"00102", X"04002", X"00900", X"08201",
X"02023", X"00303", X"02433", X"00301", X"04004", X"00301",
X"00102", X"02137", X"02036", X"00301", X"00102", X"02237",
X"04004", X"00304", X"04040", X"02500", X"02500", X"02500",
X"0030D", X"02341", X"08201", X"0400D");
begin
process (clk)
begin
if (clk'event and clk = '1') then
if (en = '1') then
data <= ROM(conv_integer(addr));
end if;
end if;
end process;
end syn;
Exercice 5 : Travail à réaliser
1°) En partant de l'exercice 2, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la RAM16X8S mais une ROM décrit en VHDL comme ci-dessus. Assembler le tout, vérifier.
2°) En partant de l'exercice 3, on vous demande de modifier toute la partie mémoire : on n'utilisera plus la RAM16X8S mais une ROM décrit en VHDL comme ci-dessus. Assembler le tout, vérifier.
3°) Pouvez-vous imaginer une architecture qui fasse défiler le texte sur 4 digits.
Exercice 6 : Barregraphe sur LEDs
On désire afficher une valeur de 0 (tout éteint) à 8 (tout allumé) sur les 8 LEDs. Toute valeur supérieure à 8 affichera 8 (effet de saturation).
- Expliquer pourquoi on doit prendre une RAM16X8S.
- Calculer son contenu et tester avec le même schéma que exo2.
- Implanter et tester en prenant un compteur qui compte de 0 à 8 seulement.
- On complique maintenant le compteur. Il devient un compteur/décompteur.