Very High Speed Integrated Circuit Hardware Description Language/Exercices/TP 3
Une page de Wikiversité.
| Exercice 3 | |||
| Leçon : Very High Speed Integrated Circuit Hardware Description Language | |||
|---|---|---|---|
Sommaire |
[modifier] TP3 : Lecture partielle d'un clavier PS/2
L'objectif de ce TP est de réaliser la lecture des codes (scancodes) d'un clavier sur un port PS/2. La différence avec le TP précédent est donc que maintenant on doit retrouver le scancode de la touche qui a été appuyée et non plus le nombre de fronts d'horloge envoyés par le clavier.
Nous allons compléter le TP précédant, c'est-à-dire utiliser l'horloge échantillonnée (sortie) comme horloge du compteur et du registre à décalage. Cette façon de faire n'est pas bonne en tous points, mais elle est simple et conduit à un séquenceur à trois états (schématisé par un GRAFCET dans la figure ci-dessous).
[modifier] Travail à réaliser =
Comme dans les travaux précédents le travail à réaliser est donné sous le forme d'un schéma.
[modifier] Schéma à réaliser
On donne le schéma global de ce que vous allez réaliser ci-dessous.
Par rapport au TP précédent on garde le compteur sur 8 bits mais il est actif sur front descendant maintenant, et toujours commandé par « sortie » qui commande aussi un registre à décalage de 11 bits. Après un transfert correct on trouvera dans ce registre les 8 bits de données, le bit de start, le bit de stop et le bit de parité. Seuls les 8 bits intéressants (Q1 ... Q8) seront transférés dans le registre d'affichage. On a ajouté d'autre part un circuit combinatoire détectant l'état cmpt=11. Sa sortie est utilisée par un séquenceur décrit par un grafcet. Son objectif est qu'une fois les 11 fronts d'horloge détectés, le transfert est lancé pour les 8 bits intéressants dans le registre d'affichage, puis il remet le compteur à 0 afin d'attendre le début d'un autre transfert.
Il est clair que la synthèse demandée est complexe. Comme toute synthèse complexe elle peut être décomposée en deux parties distinctes (voir ici pour des compléments) :
- un séquenceur
- une partie opérative
On remarquera que puisque ces deux parties utilisent une horloge commune, le séquenceur fonctionne sur front montant tandis que la partie opérative fonctionne sur front descendant.
Remarque : aucun test de parité n'est réalisé dans cette version. Les évolutions possibles sont donc ce test de parité et un séquencement un peu plus proche de l'état du bus.
Quelques scancodes :
- scancode hexadécimal pour clavier AZERTY
| Touche | Scancode | Touche | Scancode | Touche | Scancode |
| b | 0x32 | d | 0x23 | f | 0x2B |
| g | 0x34 | h | 0x33 | j | 0x3B |
| q | 0x1C | s | 0x1B | t | 0x2C |
[modifier] Éléments de VHDL donnés pour commencer votre travail
L'entité globale est :
entity tp3 is port( PS2_Clk_M16, PS2_Data_M15,Clk_T9, reset_L14 : in std_logic; sorties_aff : out std_logic_vector(6 downto 0); aff : out std_logic_vector(3 downto 0)); end tp3;
L'ensemble des composants à réaliser est maintenant :
component Counter8 -- compteur 8 bits port(horloge,reset : in std_logic; q : buffer std_logic_vector(7 downto 0)); end component; component ShiftReg -- registre a decalage 8 bits port(clk,entree : in std_logic; q : out std_logic_vector(7 downto 0)); end component; component ShiftReg11 -- registre a decalage 11 bits port(clk,entree : in std_logic; q8 : out std_logic_vector(7 downto 0)); end component; component comb -- filtrage des aleats port( entrees : in std_logic_vector(7 downto 0); eQ : in std_logic; F : out std_logic); end component; component dflipflop --bascule D port( d,clk : in std_logic; q : out std_logic); end component; component tp1 -- realise en TP 1 port ( clk : in std_logic; entrees : in std_logic_vector(7 downto 0); sorties : out std_logic_vector(6 downto 0); aff : out std_logic_vector(3 downto 0)); end component; component seq -- séquenceur (GRAFCET) port( clk, cmpt_is_11,init : in std_logic; reset,transfert : out std_logic ); end component; component compare -- comparateur port ( entrees : in std_logic_vector(7 downto 0); s_cmpt_is_11 : out std_logic ); end component;
On utilisera complètement le travail fait en tp1 et partiellement celui de TP2.
[modifier] Questions
Relever certains scancodes en plus de ceux fournis en exemple pour les tests, et en particulier celui des flèches de déplacement.
On donne sans plus de commentaires la solution du TP 3 ici :
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity tp3 is port( PS2_Clk_M16, PS2_Data_M15,Clk_T9, reset_L14 : in std_logic; sorties_aff : out std_logic_vector(6 downto 0); aff : out std_logic_vector(3 downto 0)); end tp3; architecture atp3 of tp3 is component Counter8 -- 8 bits port(horloge,reset : in std_logic; q : buffer std_logic_vector(7 downto 0)); end component; component ShiftReg -- 8 bits port(clk,entree : in std_logic; q : out std_logic_vector(7 downto 0)); end component; component ShiftReg11 -- 11 bits port(clk,entree : in std_logic; q8 : out std_logic_vector(7 downto 0)); end component; component comb -- elimination des aléats port( entrees : in std_logic_vector(7 downto 0); entree : in std_logic; F : out std_logic); end component; component dflipflop -- bascule D port( d,clk : in std_logic; q : out std_logic); end component; component tp1 -- voir le TP1 port ( clk : in std_logic; entrees : in std_logic_vector(7 downto 0); sorties : out std_logic_vector(6 downto 0); aff : out std_logic_vector(3 downto 0)); end component; component seq port( clk, cmpt_is_11,init : in std_logic; reset,transfert : out std_logic ); end component; component compare port ( entrees : in std_logic_vector(7 downto 0); s_cmpt_is_11 : out std_logic ); end component; signal sig_q8 : std_logic_vector(7 downto 0); signal sig_q,sig_d,sig_reset,sig_transfert,sig_cmpt_is_11 : std_logic; signal sig_cmpt8 : std_logic_vector(7 downto 0); signal bus_8 : std_logic_vector(7 downto 0); signal reset_L14_OR_sig_reset : std_logic; begin reset_L14_OR_sig_reset <=reset_L14 OR sig_reset; i1:ShiftReg port map(clk=>Clk_T9,entree=>PS2_Clk_M16,q=>sig_q8); i2:comb port map(entrees=>sig_q8,entree=>sig_q,F=>sig_d); i3:dflipflop port map(d=>sig_d,q=>sig_q,clk=>Clk_T9); i4:Counter8 port map(horloge=>sig_q ,reset=>reset_L14_OR_sig_reset,q=>sig_cmpt8); i5:tp1 port map(clk=>Clk_T9,entrees=>bus_8,sorties=>sorties_aff, aff=>aff); i6:Shiftreg11 port map(clk=>sig_q,entree=>PS2_Data_M15,q8=>bus_8); i7:seq port map(clk=>Clk_T9,init=>reset_L14,reset=>sig_reset,transfert=>sig_transfert, cmpt_is_11 => sig_cmpt_is_11); i8:compare port map(entrees => sig_cmpt8,s_cmpt_is_11=>sig_cmpt_is_11); end atp3; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Counter8 is port(horloge,reset : in std_logic; q : buffer std_logic_vector(7 downto 0)); end Counter8; architecture aCounter8 of Counter8 is begin process(horloge,reset) begin if reset='1' then q<="00000000"; else if(horloge'event and horloge='0') then q <= q + 1; end if; end if; end process; end aCounter8; 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 if clk'event and clk='0' then dataq <= entree& dataq(7 downto 1); end if; end process; process(dataq)begin q<=dataq; end process; end aShiftReg; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity ShiftReg11 is port(clk,entree : in std_logic; q8 : out std_logic_vector(7 downto 0)); end ShiftReg11; architecture aShiftReg11 of ShiftReg11 is signal dataq : std_logic_vector(10 downto 0); begin process(clk) begin if clk'event and clk='0' then dataq <= entree & dataq(10 downto 1); end if; end process; process(dataq)begin q8<=dataq(8 downto 1); end process; end aShiftReg11; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity comb is port( entrees : in std_logic_vector(7 downto 0); entree : in std_logic; F : out std_logic); end comb; architecture acomb of comb is -- grosse astuce ici pour eliminer aleats begin with entree select F <= entrees(7) and entrees(6) and entrees(5) and entrees(4) and entrees(3) and entrees(2) and entrees(1) and entrees(0) when '0', entrees(7) or entrees(6) or entrees(5) or entrees(4) or entrees(3) or entrees(2) or entrees(1) or entrees(0) when others; end acomb; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity dflipflop is port( d,clk : in std_logic; q : out std_logic); end dflipflop; architecture adflipflop of dflipflop is signal sigq : std_logic; begin process(clk) begin if clk'event and clk='1' then sigq <= d; end if; end process; process(sigq) begin q <= sigq; end process; end adflipflop; library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity seq is port( clk, cmpt_is_11,init : in std_logic; reset,transfert : out std_logic ); end seq; architecture aseq of seq is signal etape0,etape1,etape2 : std_logic; begin process(clk) begin if clk'event and clk = '1' then etape0 <= etape2 or (etape0 and not cmpt_is_11) or init; etape1 <= etape0 and cmpt_is_11 and not init; etape2 <= etape1 and not init; end if; end process; transfert <= etape1; reset <= etape2; end aseq; library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity compare is port ( entrees : in std_logic_vector(7 downto 0); s_cmpt_is_11 : out std_logic ); end compare; architecture acompare of compare is begin with entrees select s_cmpt_is_11 <= '1' when x"0B", '0' when others; end acompare;
