Vous êtes sur la page 1sur 12

TD3 VHDL Compteurs et registres

TD3 VHDL Compteurs et registres


La logique aborde dans ce chapitre est parfois appele logique squentielle rgulire.
Dfinition On appelle logique squentielle rgulire toute logique squentielle pour laquelle le calcul de l'tat futur en fonction de l'tat prsent s'exprime facilement avec des oprateurs simples et classiques, par exemple l'oprateur addition pour dcrire un compteur.

Les compteurs sont des lments trs utiles en VHDL. Il permettent de grer tout ce qui est temporisation et videmment le comptage.

Le compteur simple
Il est possible d'utiliser un style "case when" (prsent en dbut 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 numrique : prendre n=16.

Eviter une programmation trop fastidieuse


L'idal 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 dclaration de compteur comme std_logic_vector

Avec XILINX cela se fait avec les lignes (devant chacune des entits concernes) : 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 faon de faire n'est pas portable comme le montre le commentaire ci-dessus. Elle reste pourtant trs simple par rapport la faon portable que l'on va prsenter maintenant. Les diffrences 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 limits mais tout commence se dgrader avec la suite : remplacer systmatiquement compteur <= compteur+1; par

TD3 VHDL Compteurs et registres 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 dclarer le signal de la manire suivante : signal compteur : unsigned; et de l'incrmenter avec compteur <= compteur + 1; De cette faon votre code sera portable car respectant le standard dfini par l'IEEE (malgr leurs noms les bibliothques ieee.std_logic_arith, ieee.std_logic_unsigned et ieee.std_logic_signed ne font pas partie du standard IEEE mais sont des extensions propritaires dveloppes par Synopsys et dont l'implmentation peut varier suivant les outils de dveloppement). Voici schmatiquement le calcul de l'tat futur en fonction de l'tat prsent pour un compteur :

Remarquez que la fonction de calcul s'crit de manire trs simple l'aide de l'oprateur d'addition.

Exercice 2
Vous disposez d'une horloge rapide et vous voulez en raliser une plus lente dont la frquence est divise par 32768. Proposez un compteur avec comme entre h_rapide et comme sortie h_lente (toutes deux sur un bit). Le compteur intermdiaire sera ralis par un signal.

Possibilit d'utiliser un signal de type integer


Plutt que de dclarer des std_logic_vector vous pouvez utiliser le type integer. Dans ce cas le compilateur peut avoir des problmes pour trouver le nombre de bits ncessaire pour le compteur. Il faudra donc utiliser une comparaison supplmentaire : 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.

TD3 VHDL Compteurs et registres

Compteur avec Remise Zro (RAZ)


L'entre RAZ( Remise Zro) (Reset en anglais) sur un compteur est une entre qui permet de mettre la valeur du compteur 0. Elle peut tre synchrone (prise en compte seulement sur front d'horloge) ou asynchrone. Pour la suite de 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 prsenter 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 mme dans les deux cas : "clk" pour le synchrone et "clk,raz" pour l'asynchrone.
''

Remarque sur le type BUFFER : Xilinx dconseille d'utiliser le type BUFFER dans une entit, particulirement quand il s'agit d'un signal interne au FPGA (pas une sortie physique). Il conseille plutt d'utiliser un signal pour compter et une sortie spcifique pour sortir le ou les bits utiles. Pour l'initialisation synchrone, par exemple, le programme complet sera la suivant :

library ieee; use ieee.std_logic_1164.all;

TD3 VHDL Compteurs et registres 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 vritable END Compteur; ARCHITECTURE aCmpt OF Compteur IS SIGNAL q : std_logic_vector(3 downto 0); -- signal intermdiaire BEGIN -- toujours faire : qs <= q; -- et en mme 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 3
Raliser un compteur avec SET et RESET synchrones et asynchrones. Modifier ce compteur pour qu'il compte jusqu' 24.

Compteur avec chargement parallle


Le chargement parallle est en gnral 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;

TD3 VHDL Compteurs et registres 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'horloge


Pour terminer ce chapitre on prsente un compteur BCD, c'est dire qui compte de 0 9 qui est emprunt au WikiBook 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;

TD3 VHDL Compteurs et registres

Rsultats de simulation

Vous pouvez remarquer que dans cet exemple c'est Output(3) qui est le poids faible, ce qui est conforme sa dclaration "0 to 3". Je prfre quant moi utiliser un "3 downto 0" ce qui laisse le poids faible avec le numro 0.

Compteur BCD cascadable


Il 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; use IEEE.std_logic_1164.all; ENTITY compteur_bcd10 IS -- Dfinition des entres/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) BEGIN IF (clr=1) THEN cnt <= 0; rco <= 0; ELSIF (clkEVENT 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; -- clear asynchrone -- Process sensible lhorloge et au clear -- On inclus la librairie IEEE

TD3 VHDL Compteurs et registres


END IF; END PROCESS; END behav;

Temporisation
L'application la plus courante des compteurs est la temporisation.

Exercice 4 : ralisation des signaux de synchronisation d'un cran VGA


On dsire raliser les deux signaux hsynch et vsynch ncessaire au bon fonctionnement d'un cran VGA. Ils sont caractriss par les dures suivantes :

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

On peut distinguer sur cette spcification un exemple de signaux rouge, vert et bleu en haut, puis les deux signaux qui nous intressent vraiment "hsynch" et "vsynch". Techniquement la ralisation de ces deux signaux est faite l'aide de deux compteurs de la manire suivante :

TD3 VHDL Compteurs et registres

Architecture pour raliser les signaux VGA

On vous demande de rpondre aux questions suivantes : 1) Calculer la priode de P88. 2) Le compteur 0 -> XXX commence compter au dbut des 25,6 ms. Jusqu' combien doit-il compter pour raliser ces 25,6 ms ? 3) Il lui faut raliser ensuite 0,64 ms, jusqu' combien doit-il compter ? Il lui faut raliser ensuite 3,8 ms, jusqu' combien doit-il compter ? Il lui faut raliser ensuite la priode complte 31,75 ms, jusqu' combien doit-il compter ? (C'est la valeur de XXX un prs) On arrondit en gnral XXX 799. Dduire de tout cela la valeur de ZZZ et TTT. 4) Ce sont les hsynch qui incrmentent le compteur 0->YYY. Quelle est la priode correspondante (si l'on prend XXX=799) ? 5) Combien de temps dure la priode des 480 lignes avec le rsultat de la question 4 ( comparer 15,24 ms de la spcification VGA). 6) A l'aide du rsultat de 4) trouver de combien doit compter le compteur pour raliser le temps de 0,35 ms. 7) A l'aide du rsultat de 4) trouver de combien doit compter le compteur pour raliser le temps de 64 ms. 8) A l'aide du rsultat de 4) trouver de combien doit compter le compteur pour raliser la priode complte de 16,6 ms. Est-il normal d'arrondir 520 ? 9) En dduire les valeurs de UUU et VVV ?

Registre dcalage
L'oprateur de concatnation "&" est utile pour ce genre de registre. Voici un exemple de registre dcalage vers la gauche (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

TD3 VHDL Compteurs et registres if clk'event and clk='0' then -- c'est ici que l'on concatne dataq <= entree & dataq(7 downto 1); end if; end process; process(dataq)begin q<=dataq; end process; end aShiftReg;

Autre exemple de registre dcalage 4 bits


Cet 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;

TD3 VHDL Compteurs et registres

10

Rsultats de simulation

Et maintenant quelques dfinitions avant de passer l'exercice suivant.


Dfinition Les alas de fonctionnement correspondent des valeurs de tensions inattendues sur un fil et de dure trs courtes. On les appelle aussi parasites lectriques. Les rebonds se produisent essentiellement avec des interrupteurs mcaniques : il s'agit bien d'un rebond mcanique souvent invitable. Mais lorsque l'interrupteur agit comme une horloge, cela peut devenir embtant. Il existe plusieurs techniques pour liminer ces rebonds.

Nous proposons une mthode qui utilise un registre dcalage travers un exercice.

Exercice 5 (filtrage de rebonds et/ou alas)


L'architecture peut tre dcrite comme suit : un registre dcalage 4 bits sensible aux fronts descendants de T9, une bascule D qui mmorise l'tat de notre sortie et une partie combinatoire qui gnre un 1 l'entre de la bascule D ds que le registre est rempli par 4 bits 1 et que sortie vaut 0.

Filtrer les rebonds

Cette figure peut tre explique de la manire suivante : si l'on est avec une horloge 0 (sortie de la bascule D) seuls une srie de 1 dans tout le registre peut le mettre un.

TD3 VHDL Compteurs et registres si l'on est avec une horloge 1 (sortie de la bascule D) seuls une srie de 0 dans tout le registre peut le mettre zro. Complter les chronogrammes ci-dessous.

11

Chronogrammes complter

Rfrences
[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

Sources et contributeurs de larticle

12

Sources et contributeurs de larticle


TD3 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 contributeurs


File:Compteur.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:Compteur.png Licence: GNU Free Documentation License Contributeurs: SergeMoutou Image: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: MOJO1985 Image:VGASpecification.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VGASpecification.png Licence: GNU Free Documentation License Contributeurs: SergeMoutou Image:VHDLFig13.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig13.png Licence: inconnu Contributeurs: SergeMoutou Image:Shift reg f.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:Shift_reg_f.png Licence: GNU Free Documentation License Contributeurs: MOJO1985 Image:VHDLFig14.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig14.png Licence: inconnu Contributeurs: SergeMoutou Image:VHDLFig15.png Source: http://fr.wikibooks.org/w/index.php?title=Fichier:VHDLFig15.png Licence: inconnu Contributeurs: SergeMoutou

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