Cours:TP M1102 TP 6 Corr
Il s’agit d’une page protégée.
Sommaire
TP6
Exercice 1 : le réveil
Il n'y a pas grand chose à dire sur la correction à part que l'on n'utilise pas l'horloge 50 MHz directement mais le 3Hz que l'on sait fabriquer depuis le tp 3.
-- Vérifié OK le 29/09/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY tp6 IS PORT (
clk, key, trip : IN std_logic;
Led0: OUT std_logic);
END tp6;
ARCHITECTURE arch_tp6 OF tp6 IS
-- les composants :
COMPONENT SequSonnerie IS
PORT(
clock,Key,Trip,ena :IN std_logic;
Ring :OUT std_logic
);
END COMPONENT SequSonnerie;
COMPONENT cmpt24bits IS
PORT(clk_50MHz : IN STD_LOGIC; -- une seule entrée
clk_slow : OUT STD_LOGIC); -- une seule sortie
END COMPONENT cmpt24bits;
-- LE FIL INTENE
SIGNAL s_horloge_lente : std_logic;
BEGIN
i1 : cmpt24bits PORT MAP(
clk_50MHz => clk,
clk_slow => s_horloge_lente);
i2 : SequSonnerie PORT MAP (
clock => s_horloge_lente,
Key => Key,
Trip => Trip,
ena => '1',
Ring => led0);
END arch_tp6;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY SequSonnerie IS
PORT(
clock,Key,Trip,ena :IN std_logic;
Ring :OUT std_logic
);
END SequSonnerie;
ARCHITECTURE arch_SequSonnerie OF SequSonnerie IS
TYPE typetat IS (Armed, Off, Ringing);
SIGNAL etatp, etatf : typetat;
BEGIN
-- partie séquentielle
PROCESS (clock) BEGIN -- 1er process
IF Clock ='1' AND Clock'EVENT THEN
IF ena = '1' then
etatp <= etatf;
END IF;
END IF;
END PROCESS;
PROCESS(etatp) BEGIN --2eme process
CASE etatp IS
WHEN Off => IF key ='1' THEN etatf <= Armed;
ELSE etatf <= Off;
END IF;
WHEN Armed => IF Key = '0' THEN
etatf <= Off;
ELSIF Trip ='1' THEN
etatf <= Ringing;
ELSE etatf <= Armed;
END IF;
WHEN Ringing => IF Key ='0' THEN
etatf <= Off;
ELSE etatf <= Ringing;
END IF;
END CASE;
END PROCESS;
-- partie combinatoire
Ring <= '1' WHEN etatp=Ringing ELSE
'0';
END arch_SequSonnerie;
-- horloge lente 3 Hz
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; -- une seule entrée
clk_slow : OUT STD_LOGIC); -- une seule sortie
END cmpt24bits;
ARCHITECTURE arch_cmpt24bits 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); -- partie combinatoire de construction de l'horloge lente
END arch_cmpt24bits;
Voici le fichier de contraintes associé :
To,Direction,Location,I/O Bank,VREF Group,Fitter Location,I/O Standard,Reserved,Current Strength,Slew Rate,Differential Pair,Strict Preservation clk,Input,PIN_P11,,,,3.3-V LVTTL,,,,, Key,Unknown,PIN_C10,7,B7_N0,PIN_C10,3.3-V LVTTL,,,,, Trip,Unknown,PIN_C11,7,B7_N0,PIN_C11,3.3-V LVTTL,,,,, LED0,Unknown,PIN_A8,7,B7_N0,PIN_A8,3.3-V LVTTL,,,,,
Exercice 2
Voici le programme corrigé :
-- Vérifié OK le 29/09/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- pour la mémoire
LIBRARY lpm;
USE lpm.lpm_components.ALL;
entity tp6 is port(
clk_50 : in std_logic;
hex0 : out std_logic_vector(6 downto 0));
end tp6;
architecture arch_top of tp6 is
COMPONENT cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
COMPONENT cmpt24bits IS
PORT(clk_50MHz : IN STD_LOGIC;
clk_slow : OUT STD_LOGIC);
END COMPONENT;
SIGNAL s_clk_slow : std_logic;
SIGNAL s_transcod : std_logic_vector(3 downto 0);
begin
lent: cmpt24bits port map(
clk_50MHz => clk_50,
clk_slow => s_clk_slow);
cmpt: cmpt4bits port map(
clk => s_clk_slow,
cnt => s_transcod);
ic3 : lpm_rom GENERIC MAP (
LPM_ADDRESS_CONTROL => "UNREGISTERED",
LPM_FILE => "TP6exo2.mif",
LPM_WIDTH => 8,
LPM_WIDTHAD => 4)
PORT MAP (
outclock => s_clk_slow,
address => s_transcod,
q(6 downto 0) => hex0
);
end arch_top;
-- horloge lente 3 Hz
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; -- une seule entrée
clk_slow : OUT STD_LOGIC); -- une seule sortie
END cmpt24bits;
ARCHITECTURE arch_cmpt24bits 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); -- partie combinatoire de construction de l'horloge lente
END arch_cmpt24bits;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END cmpt4bits;
ARCHITECTURE arch_cmpt4bits OF cmpt4bits IS
signal cmpt : std_logic_vector(3 downto 0);
BEGIN
process(clk) begin
if rising_edge(clk) then
cmpt <= cmpt + 1;
end if;
end process;
cnt <= cmpt;
END arch_cmpt4bits;
Nous donnons maintenant le fichier mif :
DEPTH = 16; WIDTH = 8; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN [0..0f] : 0; 0000 : 40; 0001 : 79; 0002 : 24; 0003 : 30; 0004 : 19; 0005 : 12; 0006 : 02; 0007 : 78; 0008 : 00; 0009 : 10; 000a : 08; 000b : 03; 000c : 46; 000d : 21; 000e : 06; 000f : 0e; END;
Ce fichier mif doit s'appeler TP6exo2.mif et se trouver dans le répertoire du projet ! Ce qui décide de cela est la ligne
-- Pour trouver le nom du fichier mif et son chemin
LPM_FILE => "TP6exo2.mif",
dans l'instanciation de la mémoire. Ceci peut naturellement être changé.
Vient maintenant le fichier de contraintes :
To,Direction,Location,I/O Bank,VREF Group,Fitter Location,I/O Standard,Reserved,Current Strength,Slew Rate,Differential Pair,Strict Preservation clk_50,Input,PIN_P11,,,,3.3-V LVTTL,,,,, Key,Unknown,PIN_C10,7,B7_N0,PIN_C10,3.3-V LVTTL,,,,, Trip,Unknown,PIN_C11,7,B7_N0,PIN_C11,3.3-V LVTTL,,,,, LED0,Unknown,PIN_A8,7,B7_N0,PIN_A8,3.3-V LVTTL,,,,, HEX0[0],Unknown,PIN_C14,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[1],Unknown,PIN_E15,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[2],Unknown,PIN_C15,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[3],Unknown,PIN_C16,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[4],Unknown,PIN_E16,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[5],Unknown,PIN_D17,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[6],Unknown,PIN_C17,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[7],Unknown,PIN_D15,7,B7_N0,,3.3-V LVTTL,,,,,
Le fait que l'ensemble des données ci-dessus (fichier .mif) finisse dans un mémoire interne du FPGA est indiqué dans le rapport de compilation (Compilation Report) sous la forme :
Total memory bits 128 / 1,677,312 ( < 1 % )
Cela vous précise que vous n'utilisez même pas 1% de la mémoire disponible dans votre FPGA.
Exercice 3
Seul le fichier .mif est à changer par rapport à l'exercice 2. Voici le nouveau contenu :
DEPTH = 16; WIDTH = 8; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN [0..0f] : 0; 0000 : 03; 0001 : 23; 0002 : 2b; 0003 : 71; 0004 : 23; 0005 : 63; 0006 : 2f; 0007 : 7f; 0008 : 08; 0009 : 7f; 000a : 07; 000b : 23; 000c : 63; 000d : 12; 000e : 7f; 000f : 7f; END;
Exercice 4
Question 1
Le fichier VHDL est changé de manière très mineure par rapport à celui de l'exercice 2. Les sorties s'appellent toujours HEX0 sont sur 8 bits maintenant et sont maintenant destinées aux leds.
-- testé 0K le 29/09/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- pour la mémoire
LIBRARY lpm;
USE lpm.lpm_components.ALL;
entity tp6 is port(
clk_50 : in std_logic;
hex0 : out std_logic_vector(7 downto 0)); -- changé pour exercice 4
end tp6;
architecture arch_top of tp6 is
COMPONENT cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
COMPONENT cmpt24bits IS
PORT(clk_50MHz : IN STD_LOGIC;
clk_slow : OUT STD_LOGIC);
END COMPONENT;
SIGNAL s_clk_slow : std_logic;
SIGNAL s_transcod : std_logic_vector(3 downto 0);
begin
lent: cmpt24bits port map(
clk_50MHz => clk_50,
clk_slow => s_clk_slow);
cmpt: cmpt4bits port map(
clk => s_clk_slow,
cnt => s_transcod);
ic3 : lpm_rom GENERIC MAP (
LPM_ADDRESS_CONTROL => "UNREGISTERED",
LPM_FILE => "TP6exo2.mif",
LPM_WIDTH => 8,
LPM_WIDTHAD => 4)
PORT MAP (
outclock => s_clk_slow,
address => s_transcod,
q => hex0 -- changé pour exercice 4
);
end arch_top;
-- horloge lente 3 Hz
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; -- une seule entrée
clk_slow : OUT STD_LOGIC); -- une seule sortie
END cmpt24bits;
ARCHITECTURE arch_cmpt24bits 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); -- partie combinatoire de construction de l'horloge lente
END arch_cmpt24bits;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END cmpt4bits;
ARCHITECTURE arch_cmpt4bits OF cmpt4bits IS
signal cmpt : std_logic_vector(3 downto 0);
BEGIN
process(clk) begin
if rising_edge(clk) then
cmpt <= cmpt + 1;
end if;
end process;
cnt <= cmpt;
END arch_cmpt4bits;
Le nouveau fichier de contrainte est :
To,Direction,Location,I/O Bank,VREF Group,Fitter Location,I/O Standard,Reserved,Current Strength,Slew Rate,Differential Pair,Strict Preservation clk_50,Input,PIN_P11,,,,3.3-V LVTTL,,,,, HEX0[0],Unknown,PIN_A8,7,B7_N0,PIN_A8,3.3-V LVTTL,,,,, HEX0[1],Unknown,PIN_A9,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[2],Unknown,PIN_A10,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[3],Unknown,PIN_B10,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[4],Unknown,PIN_D13,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[5],Unknown,PIN_C13,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[6],Unknown,PIN_E14,7,B7_N0,,3.3-V LVTTL,,,,, HEX0[7],Unknown,PIN_D14,7,B7_N0,,3.3-V LVTTL,,,,,
Et enfin le nouveau fichier .mif est :
DEPTH = 16; WIDTH = 8; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN [0..0f] : 0; 0000 : 01; 0001 : 02; 0002 : 04; 0003 : 08; 0004 : 10; 0005 : 20; 0006 : 40; 0007 : 80; 0008 : 40; 0009 : 20; 000a : 10; 000b : 08; 000c : 04; 000d : 02; 000e : 01; 000f : ff; END;
Question 2
Seul le fichier .mif est à changer :
DEPTH = 16; WIDTH = 8; ADDRESS_RADIX = HEX; DATA_RADIX = HEX; CONTENT BEGIN [0..0f] : 0; 0000 : 04; 0001 : 02; 0002 : 04; 0003 : 08; 0004 : 04; 0005 : 02; 0006 : 01; 0007 : 02; 0008 : 04; 0009 : 08; 000a : 10; 000b : 20; 000c : 40; 000d : 80; 000e : 40; 000f : ff; END;
Information supplémentaire sur les LPM
Nous donnons pour information l'ensemble de la question 2 entièrement réalisé avec des compteurs LPM. Notez que Ceci est réalisé dans les règles de l'art : la même horloge est utilisée par les deux compteurs et la mémoire.
--Vérifié OK le 29/09/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
-- pour la mémoire et les deux compteurs
LIBRARY lpm;
USE lpm.lpm_components.ALL;
entity tp6 is port(
clk_50 : in std_logic;
hex0 : out std_logic_vector(7 downto 0)); -- changé pour exercice 4
end tp6;
architecture arch_top of tp6 is
SIGNAL s_clk_slow : std_logic;
SIGNAL s_eno : std_logic;
SIGNAL s_transcod : std_logic_vector(3 downto 0);
begin
-- compteur 24 bits
ic1: lpm_counter GENERIC MAP (
LPM_WIDTH => 24
)
PORT MAP (CLOCK => clk_50,
eq(0) => s_eno); -- pas possible avec :(2^24 - 1) = 16777215
-- compteur 4 bits
ic2: lpm_counter GENERIC MAP (
LPM_WIDTH => 4
)
PORT MAP (CLOCK => clk_50,
cnt_en => s_eno,
q => s_transcod);
ic3 : lpm_rom GENERIC MAP (
LPM_ADDRESS_CONTROL => "UNREGISTERED",
LPM_FILE => "TP6exo2.mif",
LPM_WIDTH => 8,
LPM_WIDTHAD => 4)
PORT MAP (
outclock => clk_50,
address => s_transcod,
q => hex0 -- changé pour exercice 4
);
end arch_top;
Notez aussi comme le code est devenu compact.
Exercice 5
Question 1
Le nouveau fichier VHDL est
-- Testé 0K le 1/10/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tp6 is port(
clk_50 : in std_logic;
hex0 : out std_logic_vector(6 downto 0));
end tp6;
architecture arch_top of tp6 is
-- compteur 4 bits
COMPONENT cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
-- compteur 24 bits pour l'horloge lente
COMPONENT cmpt24bits IS
PORT(clk_50MHz : IN STD_LOGIC;
clk_slow : OUT STD_LOGIC);
END COMPONENT;
COMPONENT rams_21a is
port (clk : in std_logic;
en : in std_logic;
addr : in std_logic_vector(3 downto 0);
data : out std_logic_vector(7 downto 0));
end COMPONENT rams_21a;
SIGNAL s_clk_slow : std_logic;
SIGNAL s_transcod : std_logic_vector(3 downto 0);
begin
lent: cmpt24bits port map(
clk_50MHz => clk_50,
clk_slow => s_clk_slow);
cmpt: cmpt4bits port map(
clk => s_clk_slow,
cnt => s_transcod);
ic3 : rams_21a PORT MAP (
clk => s_clk_slow,
en => '1',
addr => s_transcod,
data(6 downto 0) => hex0
);
end arch_top;
-- horloge lente 3 Hz
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; -- une seule entrée
clk_slow : OUT STD_LOGIC); -- une seule sortie
END cmpt24bits;
ARCHITECTURE arch_cmpt24bits 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); -- partie combinatoire de construction de l'horloge lente
END arch_cmpt24bits;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
ENTITY cmpt4bits IS
PORT(clk : IN STD_LOGIC;
cnt : OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END cmpt4bits;
ARCHITECTURE arch_cmpt4bits OF cmpt4bits IS
signal cmpt : std_logic_vector(3 downto 0);
BEGIN
process(clk) begin
if rising_edge(clk) then
cmpt <= cmpt + 1;
end if;
end process;
cnt <= cmpt;
END arch_cmpt4bits;
--
-- 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(3 downto 0);
data : out std_logic_vector(7 downto 0));
end rams_21a;
architecture syn of rams_21a is
type rom_type is array (0 to 15) of std_logic_vector (7 downto 0);
-- contenu de la ROM
signal ROM : rom_type:=
(X"40", X"79", X"24", X"30", X"19", X"12",
X"02", X"78", X"00", X"10", X"08", X"03",
X"46", X"21", X"06", X"0E");
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;
Mais le rapport de compilation donne :
Total memory bits 0 / 1,677,312 ( 0 % )
ce qui indique que le compilateur n'a pas utilisé de mémoire interne pour réaliser cette mémoire !
Question 2
Vous n'avez qu'à changer le fichier de contraintes pour que les sorties se fassent sur les leds. ATTENTION cependant la taille de le sortie sur 7 segments est à adpter pour les 8 leds.
Le contenu de la mémoire est à changer aussi.
Question 3
Cette question dispose de son corriger accessible tout le temps et présente dans l'énoncé.
Gilles Millon m'a proposé une autre solution. Je ne sais plus s'il l'a réalisée en pratique, mais si c'est le cas il peut la mettre ici.