Cours:TP printempsM4209 TP 3c Corr : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
(Page créée avec « <accesscontrol>Acces:Prof</accesscontrol> Ceci est le corrigé du TP [https://fr.wikiversity.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language/Trav... »)
 
m
Ligne 2 : Ligne 2 :
 
Ceci est le corrigé du TP [https://fr.wikiversity.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language/Travail_pratique/TPs_ATTiny861_avec_Altera#TP3c_:_r.C3.A9alisation_d.27une_sonnerie Réalisation d'une sonnerie].
 
Ceci est le corrigé du TP [https://fr.wikiversity.org/wiki/Very_High_Speed_Integrated_Circuit_Hardware_Description_Language/Travail_pratique/TPs_ATTiny861_avec_Altera#TP3c_:_r.C3.A9alisation_d.27une_sonnerie Réalisation d'une sonnerie].
 
Nous ne donnons que le code source de "lcd16x2_ctrl_demo.vhd", le fichier "lcd16x2_ctrl.vhd" étant inchangé.
 
Nous ne donnons que le code source de "lcd16x2_ctrl_demo.vhd", le fichier "lcd16x2_ctrl.vhd" étant inchangé.
 +
==Exercice 1==
 +
<source lang=vhdl>
 +
-------------------------------------------------------------------------------
 +
-- 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;
 +
Key    : 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 => Key,
 +
  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;
 +
</source>
 +
==Exercice 2==
 
<source lang=vhdl>
 
<source lang=vhdl>
 
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------

Version du 25 février 2017 à 15:31

Il s’agit d’une page protégée.

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;
	 Key    : 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 => Key,
		  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';