Prise en main carte FPGA Icebreaker
OBJECTIF :
Réaliser un chronomètre sur la carte FPGA ; l’affichage est fait sur un afficheur 7 segments.
Le contrôle du comptage ( pause, start, init ) est réalisé via les boutons poussoirs de la carte.
Diviseur de fréquence
L’horloge de base de la carte FPGA a une fréquence 12MHz.
On souhaite, pour le comptage principal, une incrémentation toutes les secondes.
Le composant div_freq_1s a pour rôle de fournir un signal fs asymétrique de fréquence 1Hz, qui sera utilisé dans la suite par le compteur principal,
et un signal fs_sym symtétrique de fréquence 1 Hz, qui permettra de faire clignoter LED1.
Compléter le code ci-dessous, vérifier en simulation le bon fonctionnement du composant, puis effectuer la synthèse logique.
REMARQUE : comme le temps de simulation sera trop long pour une fréquence de sortie 1Hz, nous effectuerons une simulation de durée 5ms pour des fréquence de fs et fs_sym de 1kHz. La synthèse ( implantation sur la carte ) sera faite pour une fréquence 1Hz.
Diviseur de Fréquence
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity div_freq_1s is
port( clk,reset : in std_logic;
fs : out std_logic;
fs_sym : out std_logic);
end div_freq_1s;
architecture arch_div_freq_1s of div_freq_1s is
signal count_int : unsigned (23 downto 0);
begin
process(clk,reset)
begin
if reset='1' then count_int <= (others => '0');
elsif rising_edge(clk) then
if count_int= --### A COMPLETER ###--
then count_int <= (others => '0');
else count_int <= count_int + 1; -- "+"(unsigned,int)
end if;
end if;
end process;
fs_sym <= '0' when count_int < --### A COMPLETER ###--
else '1';
fs <= '1' when count_int = x"000000"
else '0';
end arch_div_freq_1s;
--======================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use work.all;
entity icebreaker is
port( CLK, BTN_N : std_logic ;
BTN1, BTN2, BTN3 : in std_logic;
LED1, LED2, LED3, LED4 : out std_logic ;
P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10 : out std_logic
);
end icebreaker;
architecture arch_icebreaker of icebreaker is
signal reset, clk_count, clk_sym_1s : std_logic ;
signal dash : std_logic;
begin
reset <= not(BTN_N);
div_freq0 : entity div_freq_1s port map (
clk => CLK,
reset => reset,
fs => clk_count,
fs_sym => LED1
);
end arch_icebreaker;
Compteur Principal
Ajouter le composant compteur au système, et vérifier par une simulation son fonctionnement.
Affichage 7 Segments
La broche P1A10 permet de sélectionner l’afficheur MSB ou LSB
Compléter le code ci-dessous, vérifier le fonctionnement en simulation, puis effectuer la synthèse.
Affichage 7 Segments
library IEEE;
use IEEE.std_logic_1164.all;
entity dec_sev_seg is
port( din : in std_logic_vector( 3 downto 0 );
dout : out std_logic_vector ( 6 downto 0));
end dec_sev_seg;
architecture arch_dec_sev_seg of dec_sev_seg is
signal conv : std_logic_vector( 6 downto 0);
begin -- GFEDCBA
conv <= "0111111" when din = x"0"
else "0000110" when din = x"1"
else "1011011" when din = x"2"
else "1001111" when din = x"3"
--## A COMPLETER ##--
else "1111001" when din = x"E"
else "1110001" when din = x"F"
else "0000000";
dout <= not(conv);
end arch_dec_sev_seg;
--======================================================================
library IEEE;
use IEEE.std_logic_1164.all;
use work.all;
entity icebreaker is
port( CLK, BTN_N : std_logic ;
BTN1, BTN2, BTN3 : in std_logic;
LED1, LED2, LED3, LED4 : out std_logic ;
P1A1, P1A2, P1A3, P1A4, P1A7, P1A8, P1A9, P1A10 : out std_logic
);
end icebreaker;
architecture arch_icebreaker of icebreaker is
signal reset : std_logic ;
signal sev_seg : std_logic_vector(6 downto 0);
begin
reset <= not(BTN_N);
dec_sev_seg0 : entity dec_sev_seg port map (
din => "0111",
dout => sev_seg
);
P1A10 <= '0';
P1A1 <= sev_seg(0);
P1A2 <= sev_seg(1);
P1A3 <= sev_seg(2);
P1A4 <= sev_seg(3);
P1A7 <= sev_seg(4);
P1A8 <= sev_seg(5);
P1A9 <= sev_seg(6);
end arch_icebreaker;
Comptage hexadecimal 4 bits et affichage
Réaliser le système suivant.
On devrait constater un comptage de 0 à F sur un des afficheurs 7 segments.
Commande du chronomètre avec les boutons poussoirs
La gestion des commandes des boutons poussoirs peut être représentée par un diagramme d’états.
Effectuer la description de la machine d’états correspondante, en tenant compte des exemples vus précédemments.
Comptage decimal 8 bits et affichage
Les 2 afficheurs 7 segments utilisent les mêmes broches, la sélection d’un afficheur se fait avec P1A10.
En pilotant un multiplexeur et P1A10 avec une horloge à , on peut mettre à jour alternativement ces afficheurs
et donner l’illusion d’un fonctionnement simultané.
Le composant count_split a pour rôle de transformer une valeur de comptage désormais sur 8bits en 2 digits sur 4 bits représentant un comptage décimal ( de 0 à 99 ).
Ex: valeur du comptage : 45, en hexa : x"2D", en binaire : “00101011”
Je dois fournir en sortie de count_split : x"4" et x"5"
- Pour trouver le digit décimal, je peux effectuer une division par 10 ( division entière ) : 45/10 = 4
- Pour trouver les unités, je multiplie ce digit décimal par 10, et je soustrait cette valeur à 45 : 45-4*10 = 5