td 3 vhdl

12
TD3 VHDL Compteurs et registres 1 TD3 VHDL Compteurs et registres La logique abordée dans ce chapitre est parfois appelée logique séquentielle régulière. Définition On appelle logique séquentielle régulière toute logique séquentielle pour laquelle le calcul de l'état futur en fonction de l'état présent s'exprime facilement avec des opérateurs simples et classiques, par exemple l'opérateur addition pour décrire un compteur. Les compteurs sont des éléments très utiles en VHDL. Il permettent de gérer tout ce qui est temporisation et évidemment le comptage. Le compteur simple Il est possible d'utiliser un style "case when" (présenté en début de ce livre) pour programmer un compteur. Cela devient vite fastidieux cependant, lorsque le nombre de bits du compteur augmente. Exercice 1 Combien d'états comporte un compteur de n bits et donc combien de lignes pour chacun des « case » ? Application numérique : prendre n=16. Eviter une programmation trop fastidieuse L'idéal serait donc de pouvoir écrire quelque chose du style compteur <= compteur + 1; Cela peut se faire en respectant les conditions suivantes : utilisation de la librairie IEEE 1164 utilisation de la librairie IEEE ARITH utilisation de la librairie IEEE UNSIGNED déclaration de compteur comme std_logic_vector Avec XILINX cela se fait avec les lignes (devant chacune des entités concernées) : library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -- WARP : use work.std_arith.all; use ieee.std_logic_unsigned.all; Mais cette façon de faire n'est pas portable comme le montre le commentaire ci-dessus. Elle reste pourtant très simple par rapport à la façon portable que l'on va présenter maintenant. Les différences commencent par l'utilisation d'autres librairies. Il s'agit maintenant d'utiliser : library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; Jusque là les changements sont limités mais tout commence à se dégrader avec la suite : remplacer systématiquement compteur <= compteur+1; par

description

apprendre vhdl

Transcript of td 3 vhdl

Page 1: td 3 vhdl

TD3 VHDL Compteurs et registres 1

TD3 VHDL Compteurs et registresLa logique abordée dans ce chapitre est parfois appelée logique séquentielle régulière.

Définition

On appelle logique séquentielle régulière toute logique séquentielle pour laquelle le calcul de l'état futur en fonction de l'état présent s'exprimefacilement avec des opérateurs simples et classiques, par exemple l'opérateur addition pour décrire un compteur.

Les compteurs sont des éléments très utiles en VHDL. Il permettent de gérer tout ce qui est temporisation etévidemment le comptage.

Le compteur simpleIl est possible d'utiliser un style "case when" (présenté en début de ce livre) pour programmer un compteur. Celadevient vite fastidieux cependant, lorsque le nombre de bits du compteur augmente.

Exercice 1Combien d'états comporte un compteur de n bits et donc combien de lignes pour chacun des « case » ? Applicationnumérique : prendre n=16.

Eviter une programmation trop fastidieuseL'idéal serait donc de pouvoir écrire quelque chose du style

compteur <= compteur + 1;

Cela peut se faire en respectant les conditions suivantes :•• utilisation de la librairie IEEE 1164•• utilisation de la librairie IEEE ARITH•• utilisation de la librairie IEEE UNSIGNED•• déclaration de compteur comme std_logic_vectorAvec XILINX cela se fait avec les lignes (devant chacune des entités concernées) :

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all; -- WARP : use work.std_arith.all;

use ieee.std_logic_unsigned.all;

Mais cette façon de faire n'est pas portable comme le montre le commentaire ci-dessus. Elle reste pourtant trèssimple par rapport à la façon portable que l'on va présenter maintenant. Les différences commencent par l'utilisationd'autres librairies. Il s'agit maintenant d'utiliser :

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

Jusque là les changements sont limités mais tout commence à se dégrader avec la suite : remplacer systématiquement

compteur <= compteur+1;

par

Page 2: td 3 vhdl

TD3 VHDL Compteurs et registres 2

compteur <= std_logic_vector(unsigned(compteur)+1);

Oui, nous savons bien que c'est douloureux, mais comme on dit, on a rien sans rien.Remarque : La bonne solution est en fait de déclarer le signal de la manière suivante :

signal compteur : unsigned;

et de l'incrémenter avec

compteur <= compteur + 1;

De cette façon votre code sera portable car respectant le standard défini par l'IEEE (malgré leurs noms lesbibliothèques ieee.std_logic_arith, ieee.std_logic_unsigned et ieee.std_logic_signed ne font pas partie du standardIEEE mais sont des extensions propriétaires développées par Synopsys et dont l'implémentation peut varier suivantles outils de développement).Voici schématiquement le calcul de l'état futur en fonction de l'état présent pour un compteur :

Remarquez que la fonction de calcul s'écrit de manière très simple à l'aide de l'opérateur d'addition.

Exercice 2Vous disposez d'une horloge rapide et vous voulez en réaliser une plus lente dont la fréquence est divisée par 32768.Proposez un compteur avec comme entrée h_rapide et comme sortie h_lente (toutes deux sur un bit). Le compteurintermédiaire sera réalisé par un signal.

Possibilité d'utiliser un signal de type integerPlutôt que de déclarer des std_logic_vector vous pouvez utiliser le type integer. Dans ce cas le compilateur peutavoir des problèmes pour trouver le nombre de bits nécessaire pour le compteur. Il faudra donc utiliser unecomparaison supplémentaire :

architecture a_cmpt of cmpt is

signal Count : integer :=0;

process begin

if (Clk'event and Clk='0') then

if (Count=7) then Count <=0; -- sur 3 bits

else Count <=Count+1;

end if;

end if;

end process;

end a_cmpt;

Nous n'utiliserons pas ce type de programmation dans ce document. Il est juste donné par souci d'exhaustivité.

Page 3: td 3 vhdl

TD3 VHDL Compteurs et registres 3

Compteur avec Remise à Zéro (RAZ)L'entrée RAZ( Remise à Zéro) (Reset en anglais) sur un compteur est une entrée qui permet de mettre la valeur ducompteur à 0. Elle peut être synchrone (prise en compte seulement sur front d'horloge) ou asynchrone. Pour la suitede la section nous utiliserons l'entité que l'on donne maintenant :

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

ENTITY Compteur IS

PORT (

clk,raz :IN std_logic;

q : BUFFER std_logic_vector(3 downto 0));

END Compteur;

Cette entité va nous permettre de présenter la technique synchrone et asynchrone (process seulement) :

-- ******* methode synchrone **********

PROCESS(clk) BEGIN

IF clk'event and clk='1' THEN

IF raz='1' THEN

q<=(OTHERS=>'0');

ELSE

q<=q+1;

END IF;

END IF;

END PROCESS;

et

-- ******** methode asynchrone *********

PROCESS(clk,raz) BEGIN

IF raz='1' THEN

q<=(OTHERS=>'0');

ELSIF clk'event and clk='1' THEN

q<=q+1;

END IF;

END PROCESS;

On peut remarquer que la liste de sensibilité n'est pas la même dans les deux cas : "clk" pour le synchrone et"clk,raz" pour l'asynchrone.''

Remarque sur le type BUFFER : Xilinx déconseille d'utiliser le type BUFFER dans une entité, particulièrementquand il s'agit d'un signal interne au FPGA (pas une sortie physique). Il conseille plutôt d'utiliser un signal pourcompter et une sortie spécifique pour sortir le ou les bits utiles. Pour l'initialisation synchrone, par exemple, leprogramme complet sera la suivant :

library ieee;

use ieee.std_logic_1164.all;

Page 4: td 3 vhdl

TD3 VHDL Compteurs et registres 4

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

ENTITY Compteur IS

PORT (

clk,raz :IN std_logic;

qs : OUT std_logic_vector(3 downto 0)); -- sortie véritable

END Compteur;

ARCHITECTURE aCmpt OF Compteur IS

SIGNAL q : std_logic_vector(3 downto 0); -- signal intermédiaire

BEGIN

-- toujours faire :

qs <= q;

-- et en même temps RAZ synchrone

PROCESS(clk) BEGIN

IF clk'event and clk='1' THEN

IF raz='1' THEN

q<=(OTHERS=>'0');

ELSE

q<=q+1;

END IF;

END IF;

END PROCESS;

END aCmpt;

On s'efforcera de respecter cette mise en garde par la suite.

Exercice 3Réaliser un compteur avec SET et RESET synchrones et asynchrones.Modifier ce compteur pour qu'il compte jusqu'à 24.

Compteur avec chargement parallèleLe chargement parallèle est en général asynchrone dans les circuits existants. Nous allons le conserver comme tel :

library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_arith.all;

use ieee.std_logic_unsigned.all;

ENTITY Compteur IS

PORT (

clk,load :IN std_logic;

qs : OUT std_logic_vector(3 downto 0);

qe : IN std_logic_vector(3 downto 0));

END Compteur;

ARCHITECTURE acmpt OF Compteur IS

SIGNAL q :std_logic_vector(3 downto 0);

BEGIN

qs <= q;

Page 5: td 3 vhdl

TD3 VHDL Compteurs et registres 5

PROCESS(clk,load) BEGIN

IF load='1' THEN

q<=qe;

-- ou q<=31; valeur predefinie

ELSIF clk'event and clk='1' THEN

q<=q+1;

END IF;

END PROCESS;

END acmpt;

Compteur 4 bits BCD avec validation d'horlogePour terminer ce chapitre on présente un compteur BCD, c'est à dire qui compte de 0 à 9 qui est emprunté auWikiBook anglais VHDL for FPGA Design [1].

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Counter2_VHDL is

port( Clock_enable: in std_logic;

Clock: in std_logic;

Reset: in std_logic;

Output: out std_logic_vector(3 downto 0));

end Counter2_VHDL;

architecture Behavioral of Counter2_VHDL is

signal temp: std_logic_vector(3 downto 0);

begin

process(Clock,Reset) begin

if Reset='1' then

temp <= "0000";

elsif(Clock'event and Clock='1') then

if Clock_enable='0' then

if temp="1001" then

temp<="0000";

else

temp <= temp + 1;

end if;

else

temp <= temp;

end if;

end if;

end process;

Output <= temp;

end Behavioral;

Page 6: td 3 vhdl

TD3 VHDL Compteurs et registres 6

Résultats de simulation

Vous pouvez remarquer que dans cet exemple c'est Output(3) qui est le poids faible, ce qui est conforme à sadéclaration "0 to 3". Je préfère quant à moi utiliser un "3 downto 0" ce qui laisse le poids faible avec le numéro 0.

Compteur BCD cascadableIl n'est pas difficile de trouver le code correspondant sur Internet. Voici par exemple :

-- Fichier : compteur_bcd10.vhdl

-- Description : Compteur BCD de 0 a 9

library IEEE; -- On inclus la librairie IEEE

use IEEE.std_logic_1164.all;

ENTITY compteur_bcd10 IS -- Définition des entrées/sorties

PORT(clk, en, clr : IN std_logic;

rco : OUT std_logic;

q : OUT INTEGER RANGE 0 TO 9);

END compteur_bcd10;

ARCHITECTURE behav OF compteur_bcd10 IS

SIGNAL cnt : INTEGER RANGE 0 TO 9; -- signal interne

BEGIN

q <= cnt; -- q, la sortie vaut la valeur du compte actuel en tout temps

PROCESS(clk, clr) -- Process sensible à l’horloge et au “clear” BEGIN

IF (clr=’1’) THEN -- “clear” asynchrone cnt <= 0;

rco <= ’0’; ELSIF (clk’EVENT AND clk=’1’) THEN -- au front montant IF (en=’1’) THEN -- si enable est à 1 IF (cnt = 9) THEN -- Si on atteint 9 on fait un rco

cnt <= 0; -- et on remet le compteur a 0

rco <= ’1’; ELSE -- Sinon on compte

cnt <= cnt + 1;

rco <= ’0’; END IF;

END IF;

Page 7: td 3 vhdl

TD3 VHDL Compteurs et registres 7

END IF;

END PROCESS;

END behav;

TemporisationL'application la plus courante des compteurs est la temporisation.

Exercice 4 : réalisation des signaux de synchronisation d'un écran VGAOn désire réaliser les deux signaux hsynch et vsynch nécessaire au bon fonctionnement d'un écran VGA. Ils sontcaractérisés par les durées suivantes :

Les signaux VGA : bleu, vert, rouge, synchronisation horizontale et synchronisation verticale

On peut distinguer sur cette spécification un exemple de signaux rouge, vert et bleu en haut, puis les deux signauxqui nous intéressent vraiment "hsynch" et "vsynch". Techniquement la réalisation de ces deux signaux est faite àl'aide de deux compteurs de la manière suivante :

Page 8: td 3 vhdl

TD3 VHDL Compteurs et registres 8

Architecture pour réaliser les signaux VGA

On vous demande de répondre aux questions suivantes :1°) Calculer la période de P88.2°) Le compteur 0 -> XXX commence à compter au début des 25,6 ms. Jusqu'à combien doit-il compter pour réaliserces 25,6 ms ?3°) Il lui faut réaliser ensuite 0,64 ms, jusqu'à combien doit-il compter ? Il lui faut réaliser ensuite 3,8 ms, jusqu'àcombien doit-il compter ? Il lui faut réaliser ensuite la période complète 31,75 ms, jusqu'à combien doit-il compter ?(C'est la valeur de XXX à un près) On arrondit en général XXX à 799. Déduire de tout cela la valeur de ZZZ et TTT.4°) Ce sont les hsynch qui incrémentent le compteur 0->YYY. Quelle est la période correspondante (si l'on prendXXX=799) ?5°) Combien de temps dure la période des 480 lignes avec le résultat de la question 4° (à comparer à 15,24 ms de laspécification VGA).6°) A l'aide du résultat de 4°) trouver de combien doit compter le compteur pour réaliser le temps de 0,35 ms.7°) A l'aide du résultat de 4°) trouver de combien doit compter le compteur pour réaliser le temps de 64 ms.8°) A l'aide du résultat de 4°) trouver de combien doit compter le compteur pour réaliser la période complète de 16,6ms. Est-il normal d'arrondir à 520 ?9°) En déduire les valeurs de UUU et VVV ?

Registre à décalageL'opérateur de concaténation "&" est utile pour ce genre de registre. Voici un exemple de registre à décalage vers lagauche (vers les poids forts) :

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity ShiftReg is

port(clk,entree : in std_logic;

q : out std_logic_vector(7 downto 0));

end ShiftReg;

architecture aShiftReg of ShiftReg is

signal dataq : std_logic_vector(7 downto 0);

begin

process(clk) begin

Page 9: td 3 vhdl

TD3 VHDL Compteurs et registres 9

if clk'event and clk='0' then

-- c'est ici que l'on concatène

dataq <= entree & dataq(7 downto 1);

end if;

end process;

process(dataq)begin

q<=dataq;

end process;

end aShiftReg;

Autre exemple de registre à décalage 4 bitsCet exemple est encore tiré du WikiBook VHDL for FPGA Design [2].

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Shift_register_VHDL is

port( Clock: in std_logic;

L,w: in std_logic;

Output: out std_logic_vector(3 downto 0);

Input: in std_logic_vector( 3 downto 0));

end Shift_register_VHDL;

architecture Behavioral of Shift_register_VHDL is

signal temp: std_logic_vector(3 downto 0);

begin

process

begin

wait until Clock'event and Clock='1';

if L='1' then

temp <= Input;

else

for i in 0 to 2 loop

temp(i) <= temp(i+1);

end loop;

temp(3) <= w;

end if;

end process;

Output <= temp;

end Behavioral;

Page 10: td 3 vhdl

TD3 VHDL Compteurs et registres 10

Résultats de simulation

Et maintenant quelques définitions avant de passer à l'exercice suivant.

Définition

• Les aléas de fonctionnement correspondent à des valeurs de tensions inattendues sur un fil et de durée très courtes. On les appelle aussi parasitesélectriques.

•• Les rebonds se produisent essentiellement avec des interrupteurs mécaniques : il s'agit bien d'un rebond mécanique souvent inévitable. Maislorsque l'interrupteur agit comme une horloge, cela peut devenir embêtant. Il existe plusieurs techniques pour éliminer ces rebonds.

Nous proposons une méthode qui utilise un registre à décalage à travers un exercice.

Exercice 5 (filtrage de rebonds et/ou aléas)L'architecture peut être décrite comme suit : un registre à décalage 4 bits sensible aux fronts descendants de T9, unebascule D qui mémorise l'état de notre sortie et une partie combinatoire qui génère un 1 à l'entrée de la bascule D dèsque le registre est rempli par 4 bits à 1 et que sortie vaut 0.

Filtrer les rebonds

Cette figure peut être expliquée de la manière suivante :•• si l'on est avec une horloge à 0 (sortie de la bascule D) seuls une série de 1 dans tout le registre peut le mettre à

un.

Page 11: td 3 vhdl

TD3 VHDL Compteurs et registres 11

•• si l'on est avec une horloge à 1 (sortie de la bascule D) seuls une série de 0 dans tout le registre peut le mettre àzéro.

Compléter les chronogrammes ci-dessous.

Chronogrammes à compléter

Références[1] http:/ / en. wikibooks. org/ wiki/ VHDL_for_FPGA_Design/ 4-Bit_BCD_Counter_with_Clock_Enable[2] http:/ / en. wikibooks. org/ wiki/ VHDL_for_FPGA_Design

Page 12: td 3 vhdl

Sources et contributeurs de l’article 12

Sources et contributeurs de l’articleTD3 VHDL Compteurs et registres  Source: http://fr.wikibooks.org/w/index.php?oldid=397425  Contributeurs: JackPotte, Matthieu Michon, SergeMoutou, 17 modifications anonymes

Source des images, licences et contributeursFile:Compteur.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:Compteur.png  Licence: GNU Free Documentation License  Contributeurs: SergeMoutouImage:Counter_bcd_enable_f.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:Counter_bcd_enable_f.png  Licence: GNU Free Documentation License  Contributeurs:MOJO1985Image:VGASpecification.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VGASpecification.png  Licence: GNU Free Documentation License  Contributeurs: SergeMoutouImage:VHDLFig13.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig13.png  Licence: inconnu  Contributeurs: SergeMoutouImage:Shift reg f.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:Shift_reg_f.png  Licence: GNU Free Documentation License  Contributeurs: MOJO1985Image:VHDLFig14.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig14.png  Licence: inconnu  Contributeurs: SergeMoutouImage:VHDLFig15.png  Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig15.png  Licence: inconnu  Contributeurs: SergeMoutou

LicenceCreative Commons Attribution-Share Alike 3.0 Unported//creativecommons.org/licenses/by-sa/3.0/