Cours:TP printempsM4209 TP 3c Corr
Ceci est le corrigé du TP Réalisation d'une sonnerie. Nous ne donnons que le code source de "lcd16x2_ctrl_demo.vhd", le fichier "lcd16x2_ctrl.vhd" étant inchangé.
Exercice 1
-------------------------------------------------------------------------------
-- Title : Synthesizable demo for design "lcd16x2_ctrl"
-- Project :
-------------------------------------------------------------------------------
-- File : lcd16x2_ctrl_tb.vhd
-- Author : <stachelsau@T420>
-- Company :
-- Created : 2012-07-28
-- Last update: 2012-07-29
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: This demo writes writes a "hello world" to the display and
-- interchanges both lines periodically.
-------------------------------------------------------------------------------
-- Copyright (c) 2012
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-07-28 1.0 stachelsau Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-------------------------------------------------------------------------------
entity lcd16x2_ctrl_demo is
port (
clk : in std_logic;
ArmKey : in std_logic;
Trip : in std_logic;
lcd_e : out std_logic;
lcd_rs : out std_logic;
lcd_rw : out std_logic;
lcd_db : out std_logic_vector(7 downto 4);
led_out : out std_logic);
end entity lcd16x2_ctrl_demo;
-------------------------------------------------------------------------------
architecture behavior of lcd16x2_ctrl_demo is
component CounterBCD is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end component CounterBCD;
component CounterModulo6 is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end component CounterModulo6;
--
signal timer : natural range 0 to 5000000 := 0;
signal eno10Hz, s_eno, s_eno2, s_eno3 : std_logic := '0';
signal line1 : std_logic_vector(127 downto 0);
signal line2 : std_logic_vector(127 downto 0);
signal s_data16 : std_logic_vector(15 downto 0);
signal s_eno2_heure : std_logic_vector(16 downto 8);
signal s_reset : std_logic;
-- component generics
constant CLK_PERIOD_NS : positive := 20; -- 50 Mhz
-- component ports
signal rst : std_logic;
signal line1_buffer : std_logic_vector(127 downto 0);
signal line2_buffer : std_logic_vector(127 downto 0);
begin -- architecture behavior
-- component instantiation
DUT : entity work.lcd16x2_ctrl
generic map (
CLK_PERIOD_NS => CLK_PERIOD_NS)
port map (
clk => clk,
rst => rst,
lcd_e => lcd_e,
lcd_rs => lcd_rs,
lcd_rw => lcd_rw,
lcd_db => lcd_db,
line1_buffer => line1_buffer,
line2_buffer => line2_buffer);
rst <= '0';
-- see the display's datasheet for the character map
line1(127 downto 120) <= X"20";
line1(119 downto 112) <= X"20";
line1(111 downto 104) <= X"20";
line1(103 downto 96) <= X"20";
line1(95 downto 88) <= X"20";
line1(87 downto 84) <= X"3";
line1(83 downto 80) <= s_data16(15 downto 12);
line1(79 downto 76) <= X"3";
line1(75 downto 72) <= s_data16(11 downto 8);
line1(71 downto 64) <= X"3A";
line1(63 downto 60) <= X"3";
line1(59 downto 56) <= s_data16(7 downto 4);
line1(55 downto 52) <= X"3";
line1(51 downto 48) <= s_data16(3 downto 0);
line1(47 downto 40) <= X"20";
line1(39 downto 32) <= X"20";
line1(31 downto 24) <= X"20";
line1(23 downto 16) <= X"20";
line1(15 downto 8) <= X"20";
line1(7 downto 0) <= X"20";
line2(127 downto 120) <= X"20";
line2(119 downto 112) <= X"20";
line2(111 downto 104) <= X"20";
line2(103 downto 96) <= X"20";
line2(95 downto 88) <= X"20";
line2(87 downto 80) <= X"20";
line2(79 downto 72) <= X"20";
line2(71 downto 64) <= X"20";
line2(63 downto 56) <= X"20";
line2(55 downto 48) <= X"20";
line2(47 downto 40) <= X"20";
line2(39 downto 32) <= X"20";
line2(31 downto 24) <= X"20";
line2(23 downto 16) <= X"20";
line2(15 downto 8) <= X"20";
line2(7 downto 0) <= X"20";
line1_buffer <= line1; -- when switch_lines = '1' else line1;
line2_buffer <= line2; -- when switch_lines = '1' else line2;
-- timer 10 Hz
process(clk)
begin
if rising_edge(clk) then
if timer = 0 then
timer <= 5000000;
else
timer <= timer - 1;
end if;
end if;
end process;
eno10Hz <= '1' when timer = 0 else
'0';
automate_sonnerie : ENTITY work.SequSonnerie PORT MAP (
clock => clk,
Key => ArmKey,
Trip => Trip,
ena => eno10Hz,
Ring => led_out
);
MNUnit: CounterBCD port map(
EN => eno10Hz,
Clock => clk,
Reset => '0',
ENO => s_eno,
Output => s_data16(3 downto 0));
MNDiz: CounterModulo6 port map(
EN => s_eno,
Clock => clk,
Reset => '0',
ENO => s_eno2,
Output => s_data16(7 downto 4));
HHUnit: CounterBCD port map(
EN => s_eno2,
Clock => clk,
Reset => s_reset,
ENO => s_eno3,
Output => s_data16(11 downto 8));
HHDiz: CounterBCD port map(
EN => s_eno3,
Clock => clk,
Reset => s_reset,
ENO => open,
Output => s_data16(15 downto 12));
-- reset quand 23 est detecte par rebouclage
s_eno2_heure <= s_eno2 & s_data16(15 downto 8);
with s_eno2_heure select
s_reset <= '1' when "100100011",
'0' when others;
end architecture behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CounterBCD is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end CounterBCD;
architecture Behavioral of CounterBCD is
signal cmpt: std_logic_vector(3 downto 0);
signal s_en_cmpt: std_logic_vector(4 downto 0);
begin process(Clock,Reset)
begin
if(rising_edge(Clock)) then
if Reset='1' then
cmpt <= "0000";
elsif EN='1' then
if cmpt="1001" then
cmpt<="0000";
else
cmpt <= cmpt + 1;
end if;
end if;
end if;
end process;
Output <= cmpt;
s_en_cmpt <= en & cmpt;
with s_en_cmpt select
ENO <= '1' when "11001",
'0' when others;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- pour les dizaines de minutes
entity CounterModulo6 is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end CounterModulo6;
architecture Behavioral of CounterModulo6 is
signal cmpt: std_logic_vector(3 downto 0);
signal s_en_cmpt: std_logic_vector(4 downto 0);
begin process(Clock,Reset)
begin
if(rising_edge(Clock)) then
if Reset='1' then
cmpt <= "0000";
elsif EN='1' then
if cmpt="0101" then
cmpt<="0000";
else
cmpt <= cmpt + 1;
end if;
end if;
end if;
end process;
Output <= cmpt;
s_en_cmpt <= en & cmpt;
with s_en_cmpt select
ENO <= '1' when "10101",
'0' when others;
end Behavioral;
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;
Exercice 2
-------------------------------------------------------------------------------
-- Title : Synthesizable demo for design "lcd16x2_ctrl"
-- Project :
-------------------------------------------------------------------------------
-- File : lcd16x2_ctrl_tb.vhd
-- Author : <stachelsau@T420>
-- Company :
-- Created : 2012-07-28
-- Last update: 2012-07-29
-- Platform :
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: This demo writes writes a "hello world" to the display and
-- interchanges both lines periodically.
-------------------------------------------------------------------------------
-- Copyright (c) 2012
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2012-07-28 1.0 stachelsau Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
-------------------------------------------------------------------------------
entity lcd16x2_ctrl_demo is
port (
clk : in std_logic;
Armkey : in std_logic;
HHMMAlarm : in std_logic_vector(15 downto 0);
lcd_e : out std_logic;
lcd_rs : out std_logic;
lcd_rw : out std_logic;
lcd_db : out std_logic_vector(7 downto 4);
led_out : out std_logic);
end entity lcd16x2_ctrl_demo;
-------------------------------------------------------------------------------
architecture behavior of lcd16x2_ctrl_demo is
component CounterBCD is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end component CounterBCD;
component CounterModulo6 is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end component CounterModulo6;
component SequSonnerie IS
PORT(
clock,Key,Trip,ena :IN std_logic;
Ring :OUT std_logic
);
END component SequSonnerie;
--
signal timer : natural range 0 to 5000000 := 0;
signal eno10Hz, s_eno, s_eno2, s_eno3 : std_logic := '0';
signal line1 : std_logic_vector(127 downto 0);
signal line2 : std_logic_vector(127 downto 0);
signal s_data16 : std_logic_vector(15 downto 0);
signal s_eno2_heure : std_logic_vector(16 downto 8);
signal s_reset : std_logic;
signal egalite : std_logic;
-- component generics
constant CLK_PERIOD_NS : positive := 20; -- 50 Mhz
-- component ports
signal rst : std_logic;
signal line1_buffer : std_logic_vector(127 downto 0);
signal line2_buffer : std_logic_vector(127 downto 0);
begin -- architecture behavior
-- component instantiation
DUT : entity work.lcd16x2_ctrl
generic map (
CLK_PERIOD_NS => CLK_PERIOD_NS)
port map (
clk => clk,
rst => rst,
lcd_e => lcd_e,
lcd_rs => lcd_rs,
lcd_rw => lcd_rw,
lcd_db => lcd_db,
line1_buffer => line1_buffer,
line2_buffer => line2_buffer);
rst <= '0';
-- see the display's datasheet for the character map
line1(127 downto 120) <= X"20";
line1(119 downto 112) <= X"20";
line1(111 downto 104) <= X"20";
line1(103 downto 96) <= X"20";
line1(95 downto 88) <= X"20";
line1(87 downto 84) <= X"3";
line1(83 downto 80) <= s_data16(15 downto 12);
line1(79 downto 76) <= X"3";
line1(75 downto 72) <= s_data16(11 downto 8);
line1(71 downto 64) <= X"3A";
line1(63 downto 60) <= X"3";
line1(59 downto 56) <= s_data16(7 downto 4);
line1(55 downto 52) <= X"3";
line1(51 downto 48) <= s_data16(3 downto 0);
line1(47 downto 40) <= X"20";
line1(39 downto 32) <= X"20";
line1(31 downto 24) <= X"20";
line1(23 downto 16) <= X"20";
line1(15 downto 8) <= X"20";
line1(7 downto 0) <= X"20";
line2(127 downto 120) <= X"20";
line2(119 downto 112) <= X"20";
line2(111 downto 104) <= X"20";
line2(103 downto 96) <= X"20";
line2(95 downto 88) <= X"20";
line2(87 downto 84) <= X"3";
line2(83 downto 80) <= HHMMAlarm(15 downto 12);
line2(79 downto 76) <= X"3";
line2(75 downto 72) <= HHMMAlarm(11 downto 8);
line2(71 downto 64) <= X"3A";
line2(63 downto 60) <= X"3";
line2(59 downto 56) <= HHMMAlarm(7 downto 4);
line2(55 downto 52) <= X"3";
line2(51 downto 48) <= HHMMAlarm(3 downto 0);
line2(47 downto 40) <= X"20";
line2(39 downto 32) <= X"20";
line2(31 downto 24) <= X"20";
line2(23 downto 16) <= X"20";
line2(15 downto 8) <= X"20";
line2(7 downto 0) <= X"20";
line1_buffer <= line1; -- when switch_lines = '1' else line1;
line2_buffer <= line2; -- when switch_lines = '1' else line2;
-- timer 10 Hz
process(clk)
begin
if rising_edge(clk) then
if timer = 0 then
timer <= 5000000;
else
timer <= timer - 1;
end if;
end if;
end process;
eno10Hz <= '1' when timer = 0 else
'0';
MNUnit: CounterBCD port map(
EN => eno10Hz,
Clock => clk,
Reset => '0',
ENO => s_eno,
Output => s_data16(3 downto 0));
MNDiz: CounterModulo6 port map(
EN => s_eno,
Clock => clk,
Reset => '0',
ENO => s_eno2,
Output => s_data16(7 downto 4));
HHUnit: CounterBCD port map(
EN => s_eno2,
Clock => clk,
Reset => s_reset,
ENO => s_eno3,
Output => s_data16(11 downto 8));
HHDiz: CounterBCD port map(
EN => s_eno3,
Clock => clk,
Reset => s_reset,
ENO => open,
Output => s_data16(15 downto 12));
-- reset quand 23 est detecte par rebouclage
s_eno2_heure <= s_eno2 & s_data16(15 downto 8);
with s_eno2_heure select
s_reset <= '1' when "100100011",
'0' when others;
egalite <= '1' when HHMMAlarm = s_data16 else
'0';
SequenceurPourSonnerie: SequSonnerie PORT MAP(
clock => clk,
Key=> ArmKey,
Trip => egalite,
ena => eno10Hz,
Ring => led_out
);
end architecture behavior;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CounterBCD is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end CounterBCD;
architecture Behavioral of CounterBCD is
signal cmpt: std_logic_vector(3 downto 0);
signal s_en_cmpt: std_logic_vector(4 downto 0);
begin process(Clock,Reset)
begin
if(rising_edge(Clock)) then
if Reset='1' then
cmpt <= "0000";
elsif EN='1' then
if cmpt="1001" then
cmpt<="0000";
else
cmpt <= cmpt + 1;
end if;
end if;
end if;
end process;
Output <= cmpt;
s_en_cmpt <= en & cmpt;
with s_en_cmpt select
ENO <= '1' when "11001",
'0' when others;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- pour les dizaines de minutes
entity CounterModulo6 is
port( EN: in std_logic;
Clock: in std_logic;
Reset: in std_logic;
ENO : out std_logic;
Output: out std_logic_vector(3 downto 0));
end CounterModulo6;
architecture Behavioral of CounterModulo6 is
signal cmpt: std_logic_vector(3 downto 0);
signal s_en_cmpt: std_logic_vector(4 downto 0);
begin process(Clock,Reset)
begin
if(rising_edge(Clock)) then
if Reset='1' then
cmpt <= "0000";
elsif EN='1' then
if cmpt="0101" then
cmpt<="0000";
else
cmpt <= cmpt + 1;
end if;
end if;
end if;
end process;
Output <= cmpt;
s_en_cmpt <= en & cmpt;
with s_en_cmpt select
ENO <= '1' when "10101",
'0' when others;
end Behavioral;
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';