Cours:TP M1102 TP 4 Corr : Différence entre versions

De troyesGEII
Aller à : navigation, rechercher
m (Question 1)
m (Question 1)
Ligne 184 : Ligne 184 :
 
</source>
 
</source>
  
Et voici donc le programme complet :
+
Voici le composant compteur sept segments avec des équations de récurrences :
 +
<source lang=vhdl>
 +
-- Compteur 7 segments
 +
library IEEE;
 +
use IEEE.STD_LOGIC_1164.ALL;
 +
ENTITY cmpt7seg IS
 +
  PORT(CLK_lent : IN STD_LOGIC;
 +
  a,b,c,d,e,f,g : INOUT STD_LOGIC);
 +
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
 +
END cmpt7seg;
 +
 
 +
ARCHITECTURE arch_cmpt7seg of cmpt7seg is
 +
  signal zero,un,deux,trois,quatre,cinq,six,sept,huit,neuf : std_logic;
 +
BEGIN
 +
  zero <= g and not f and not e and not d and not c and not b and not a;    --"1000000" pour allumer 0
 +
  un <= g and f and e and d and not c and not b and a;                      --"1111001" pour allumer 1
 +
  deux <= not g and f and not e and not d and c and not b and not a;        --"0100100" pour allumer 2
 +
  trois <= not g and f and e and not d and not c and not b and not a;        --"0110000" pour allumer 3
 +
  quatre <= not g and not f and e and d and not c and not b and  a;          --"0011001" pour allumer 4
 +
  cinq <= not g and not f and e and not d and not c and b and not a;        --"0010010" pour allumer 5
 +
  six <= not g and not f and not e and not d and not c and b and not a;      --"0000010" pour allumer 6
 +
  sept <= g and f and e and d and not c and not b and not a;                --"1111000" pour allumer 7
 +
  huit <= not g and not f and not e and not d and not c and not b and not a; --"0000000" pour allumer 8
 +
  neuf <= not g and not f and e and not d and not c and not b and not a;    --"0010000" pour allumer 9
 +
 
 +
 
 +
  PROCESS (clk_lent) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
 +
    IF (clk_lent'EVENT AND clk_lent='1') THEN
 +
      g <= neuf OR zero OR six;
 +
      f <= zero OR un OR deux OR six;
 +
      e <= zero OR deux OR trois OR quatre OR six OR huit;
 +
      d <= zero OR trois OR six;
 +
      c <= un;
 +
      b <= quatre OR cinq;
 +
      a <= zero OR trois;
 +
    END IF;
 +
  END PROCESS;
 +
END arch_cmpt7seg;
 +
</source>
 +
 
 +
 
 +
Et voici donc le programme complet avec l'horloge lente :
  
 
<source lang=vhdl>
 
<source lang=vhdl>
 +
library IEEE;
 +
use IEEE.STD_LOGIC_1164.ALL;
 +
ENTITY compteur IS PORT (
 +
  clk: IN std_logic;
 +
  HEX0: OUT std_logic_vector(6 downto 0));
 +
END compteur;
 +
 +
ARCHITECTURE arch_compteur OF compteur IS
 +
-- les somposants :
 +
COMPONENT cmpt7seg IS
 +
  PORT(CLK_lent : IN STD_LOGIC;
 +
  a,b,c,d,e,f,g : OUT STD_LOGIC);
 +
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
 +
END COMPONENT cmpt7seg;
 +
 +
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_hologe_lente : std_logic;
 +
BEGIN
 +
  i1 : cmpt24bits PORT MAP(
 +
    clk_50MHz => clk,
 +
clk_slow => s_hologe_lente);
 +
 +
  i2 : cmpt7seg PORT MAP (
 +
    clk_lent => s_hologe_lente,
 +
a => HEX0(0),
 +
    b => HEX0(1),
 +
c => HEX0(2),
 +
d => HEX0(3),
 +
e => HEX0(4),
 +
f => HEX0(5),
 +
g => HEX0(6));
 +
END arch_compteur;
 +
 +
-- Compteur 7 segments
 
library IEEE;  
 
library IEEE;  
 
use IEEE.STD_LOGIC_1164.ALL;  
 
use IEEE.STD_LOGIC_1164.ALL;  
 
ENTITY cmpt7seg IS
 
ENTITY cmpt7seg IS
 
   PORT(CLK_lent : IN STD_LOGIC;
 
   PORT(CLK_lent : IN STD_LOGIC;
   a,b,c,d,e,f,g : OUT STD_LOGIC);
+
   a,b,c,d,e,f,g : INOUT STD_LOGIC);
 
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
 
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
 
END cmpt7seg;
 
END cmpt7seg;
  
 
ARCHITECTURE arch_cmpt7seg of cmpt7seg is
 
ARCHITECTURE arch_cmpt7seg of cmpt7seg is
   signal zero,un,deux,trois,quatre,cinq,sic,sept,huit,neuf : std_logic;
+
   signal zero,un,deux,trois,quatre,cinq,six,sept,huit,neuf : std_logic;
 
BEGIN
 
BEGIN
 
   zero <= g and not f and not e and not d and not c and not b and not a;    --"1000000" pour allumer 0
 
   zero <= g and not f and not e and not d and not c and not b and not a;    --"1000000" pour allumer 0
Ligne 210 : Ligne 289 :
  
  
   PROCESS (clk) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
+
   PROCESS (clk_lent) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
     IF (clk'EVENT AND clk='1') THEN
+
     IF (clk_lent'EVENT AND clk_lent='1') THEN
       g <= zero OR un OR sept;
+
       g <= neuf OR zero OR six;
       f <= un OR deux OR trois 0R sept;
+
       f <= zero OR un OR deux OR six;
       e <= un OR trois OR quatre OR cinq OR sept OR neuf;
+
       e <= zero OR deux OR trois OR quatre OR six OR huit;
       d <= un 0R quatre OR sept;
+
       d <= zero OR trois OR six;
       c <= deux;
+
       c <= un;
       b <= cinq OR six;
+
       b <= quatre OR cinq;
       a <= un OR quatre;
+
       a <= zero OR trois;
 
     END IF;
 
     END IF;
 
   END PROCESS;
 
   END PROCESS;
 
END arch_cmpt7seg;
 
END arch_cmpt7seg;
 +
 +
-- 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;
 
</source>
 
</source>
 +
 +
Le compilateur de Quartus permet le mélange des "INOUT" et "OUT" comme cela est fait ici :
 +
* un INOUT dans l'entité
 +
* un OUT dans la déclaration du composant
 +
* un OUT dans le composant global
 +
'''<big>Tous les compilateurs ne permettent pas cela !!! </big>'''
  
 
==Exercice 4==
 
==Exercice 4==

Version du 28 septembre 2020 à 16:48

TP 4

Exercice 1

Voici donc le compteur qui divise la fréquence. Il est bon de savoir calculer par avance la fréquence de ce genre de compteur :

  • compteur 1 bit divise par deux
  • compteur 2 bits divise par 4 = 2^2
  • compteur 3 bits divise par 8 = 2^3
  • ....
  • compteur 24 bits (b23,b22,...,b1,b0) divise par 2^24 soit 50000000/2^24 = 2,98 Hz
-- Vérifié le 28/09/20
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;

Le petit fichier de contrainte peut être exprimé par :

To,Direction,Location,I/O Bank,VREF Group,Fitter Location,I/O Standard,Reserved,Current Strength,Slew Rate,Differential Pair,Strict Preservation

clk_50MHz,Input,PIN_P11,,,PIN_P11,3.3-V LVTTL,,,,,
clk_slow,Unknown,PIN_A8,7,B7_N0,PIN_A8,3.3-V LVTTL,,,,,

Exercice 2

Voici le programme VHDL complet qui comprend deux composants reliés ensemble pour en faire un troisième :

  • composant diviseur de fréquence le l'exercice 1
  • composant diagramme d'évolution demandé dans l'énoncé
  • composant global pour les tests visuels à l’œil
-- Vérifié le 28/09/20
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY compteur IS PORT (
  clk: IN std_logic;
  q0,q1: OUT std_logic);
END compteur;

ARCHITECTURE arch_compteur OF compteur IS
-- les somposants :
COMPONENT cmpt_exo2 IS PORT (
  clk: IN std_logic;
  q0,q1: OUT std_logic);
END COMPONENT cmpt_exo2;

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_hologe_lente : std_logic;
BEGIN
  i1 : cmpt24bits PORT MAP(
    clk_50MHz => clk,
	 clk_slow => s_hologe_lente);
  i2 : cmpt_exo2 PORT MAP (
    clk => s_hologe_lente,
	 q0 => q0,
    q1 => q1);
END arch_compteur;

-- diagramme d'évolution demandé
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library ieee;
use ieee.std_logic_1164.all;
ENTITY cmpt_exo2 IS PORT (
  clk: IN std_logic;
  q0,q1: OUT std_logic);
END cmpt_exo2;
ARCHITECTURE arch_cmpt_exo2 OF cmpt_exo2 IS
  SIGNAL q1q0 : std_logic_vector(1 downto 0);
BEGIN
  PROCESS (clk) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
    IF (clk'EVENT AND clk='1') THEN
      q1q0(0) <= NOT q1q0(0);
      -- add the second equation here
		q1q0(1) <= q1q0(0) XOR q1q0(1);
    END IF;
  END PROCESS;
  -- mise a jour des sorties
  q0 <= q1q0(0);
  q1 <= q1q0(1);
END arch_cmpt_exo2;

-- 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;

Pour compléter voici 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,Input,PIN_P11,,,PIN_P11,3.3-V LVTTL,,,,,
q0,Unknown,PIN_A8,7,B7_N0,PIN_A8,3.3-V LVTTL,,,,,
q1,Unknown,PIN_A9,7,B7_N0,,3.3-V LVTTL,,,,,

Exercice 3

Question 1

Un peu long à faire avec des étudiants pour trouver les équations de récurrences. Une version plus simple à réaliser est donnée dans l'exercice suivant.

Voici quand même le

tableau État présent/État futur
État présent État futur
g f e d c b a g+ f+ e+ d+ c+ b+ a+
1 0 0 0 0 0 0 1 1 1 1 0 0 1
1 1 1 1 0 0 1 0 1 0 0 1 0 0
0 1 0 0 1 0 0 0 1 1 0 0 0 0
0 1 1 0 0 0 0 0 0 1 1 0 0 1
0 0 1 1 0 0 1 0 0 1 0 0 1 0
0 0 1 0 0 1 0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 1 0 0 0 0 0 0

Pour simplifier l'écriture des équations de récurrences, nous allons utiliser des notations intermédiaires. Ne disposant pas de la possibilité d'écrire les équations logiques correctement dans ce WIKI, nous allons les écrire en VHDL :

zero <= g and not f and not e and not d and not c and not b and not a;     --"1000000" pour allumer 0
un <= g and f and e and d and not c and not b and a;                       --"1111001" pour allumer 1
deux <= not g and f and not e and not d and c and not b and not a;         --"0100100" pour allumer 2
trois <= not g and f and e and not d and not c and not b and not a;        --"0110000" pour allumer 3
quatre <= not g and not f and e and d and not c and not b and  a;          --"0011001" pour allumer 4
cinq <= not g and not f and e and not d and not c and b and not a;         --"0010010" pour allumer 5
six <= not g and not f and not e and not d and not c and b and not a;      --"0000010" pour allumer 6
sept <= g and f and e and d and not c and not b and not a;                 --"1111000" pour allumer 7
huit <= not g and not f and not e and not d and not c and not b and not a; --"0000000" pour allumer 8
neuf <= not g and not f and e and not d and not c and not b and not a;     --"0010000" pour allumer 9

Voici le composant compteur sept segments avec des équations de récurrences :

-- Compteur 7 segments
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
ENTITY cmpt7seg IS
  PORT(CLK_lent : IN STD_LOGIC;
  a,b,c,d,e,f,g : INOUT STD_LOGIC);
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
END cmpt7seg;

ARCHITECTURE arch_cmpt7seg of cmpt7seg is
  signal zero,un,deux,trois,quatre,cinq,six,sept,huit,neuf : std_logic;
BEGIN
  zero <= g and not f and not e and not d and not c and not b and not a;     --"1000000" pour allumer 0
  un <= g and f and e and d and not c and not b and a;                       --"1111001" pour allumer 1
  deux <= not g and f and not e and not d and c and not b and not a;         --"0100100" pour allumer 2
  trois <= not g and f and e and not d and not c and not b and not a;        --"0110000" pour allumer 3
  quatre <= not g and not f and e and d and not c and not b and  a;          --"0011001" pour allumer 4
  cinq <= not g and not f and e and not d and not c and b and not a;         --"0010010" pour allumer 5
  six <= not g and not f and not e and not d and not c and b and not a;      --"0000010" pour allumer 6
  sept <= g and f and e and d and not c and not b and not a;                 --"1111000" pour allumer 7
  huit <= not g and not f and not e and not d and not c and not b and not a; --"0000000" pour allumer 8
  neuf <= not g and not f and e and not d and not c and not b and not a;     --"0010000" pour allumer 9


  PROCESS (clk_lent) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
    IF (clk_lent'EVENT AND clk_lent='1') THEN
      g <= neuf OR zero OR six;
      f <= zero OR un OR deux OR six;
      e <= zero OR deux OR trois OR quatre OR six OR huit;
      d <= zero OR trois OR six;
      c <= un;
      b <= quatre OR cinq;
      a <= zero OR trois;
    END IF;
  END PROCESS;
END arch_cmpt7seg;


Et voici donc le programme complet avec l'horloge lente :

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY compteur IS PORT (
  clk: IN std_logic;
  HEX0: OUT std_logic_vector(6 downto 0));
END compteur;

ARCHITECTURE arch_compteur OF compteur IS
-- les somposants :
COMPONENT cmpt7seg IS
  PORT(CLK_lent : IN STD_LOGIC;
  a,b,c,d,e,f,g : OUT STD_LOGIC);
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
END COMPONENT cmpt7seg;

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_hologe_lente : std_logic;
BEGIN
  i1 : cmpt24bits PORT MAP(
    clk_50MHz => clk,
	 clk_slow => s_hologe_lente);
	 
  i2 : cmpt7seg PORT MAP (
    clk_lent => s_hologe_lente,
	 a => HEX0(0),
    b => HEX0(1),
	 c => HEX0(2),
	 d => HEX0(3),
	 e => HEX0(4),
	 f => HEX0(5),
	 g => HEX0(6));
END arch_compteur;

-- Compteur 7 segments
library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
ENTITY cmpt7seg IS
  PORT(CLK_lent : IN STD_LOGIC;
  a,b,c,d,e,f,g : INOUT STD_LOGIC);
-- ou  alors : s7segs : out std_logic_vector(6 downto 0));
END cmpt7seg;

ARCHITECTURE arch_cmpt7seg of cmpt7seg is
  signal zero,un,deux,trois,quatre,cinq,six,sept,huit,neuf : std_logic;
BEGIN
  zero <= g and not f and not e and not d and not c and not b and not a;     --"1000000" pour allumer 0
  un <= g and f and e and d and not c and not b and a;                       --"1111001" pour allumer 1
  deux <= not g and f and not e and not d and c and not b and not a;         --"0100100" pour allumer 2
  trois <= not g and f and e and not d and not c and not b and not a;        --"0110000" pour allumer 3
  quatre <= not g and not f and e and d and not c and not b and  a;          --"0011001" pour allumer 4
  cinq <= not g and not f and e and not d and not c and b and not a;         --"0010010" pour allumer 5
  six <= not g and not f and not e and not d and not c and b and not a;      --"0000010" pour allumer 6
  sept <= g and f and e and d and not c and not b and not a;                 --"1111000" pour allumer 7
  huit <= not g and not f and not e and not d and not c and not b and not a; --"0000000" pour allumer 8
  neuf <= not g and not f and e and not d and not c and not b and not a;     --"0010000" pour allumer 9


  PROCESS (clk_lent) BEGIN -- ou cmpt:PROCESS (clk) BEGIN
    IF (clk_lent'EVENT AND clk_lent='1') THEN
      g <= neuf OR zero OR six;
      f <= zero OR un OR deux OR six;
      e <= zero OR deux OR trois OR quatre OR six OR huit;
      d <= zero OR trois OR six;
      c <= un;
      b <= quatre OR cinq;
      a <= zero OR trois;
    END IF;
  END PROCESS;
END arch_cmpt7seg;

-- 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;

Le compilateur de Quartus permet le mélange des "INOUT" et "OUT" comme cela est fait ici :

  • un INOUT dans l'entité
  • un OUT dans la déclaration du composant
  • un OUT dans le composant global

Tous les compilateurs ne permettent pas cela !!!

Exercice 4

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
ENTITY cmpt7seg IS
  PORT(CLK : IN STD_LOGIC;
    s_7segs : OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END cmpt7seg;
ARCHITECTURE arch OF cmpt7seg IS -- comment éviter les equations
  SIGNAL s7segs : STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
  PROCESS(clk) BEGIN
    IF (clk'EVENT AND clk='1') THEN
     CASE s7segs is --style case when
       WHEN "1000000" => s7segs <="1111001"; -- premiere transition 
       WHEN "1111001" => s7segs <="0100100"; -- deuxieme transition
       WHEN "0100100" => s7segs <="0110000"; -- troisieme transition
       WHEN "0110000" => s7segs <="0011001";
       WHEN "0011001" => s7segs <="0010010";
       WHEN "0010010" => s7segs <="0000010";
       WHEN "0000010" => s7segs <="1111000";
       WHEN "1111000" => s7segs <="0000000";
       WHEN "0000000" => s7segs <="0010000";
       WHEN "0010000" => s7segs <="1000000"; -- dernière transition
-- dans tous les autres cas on revient sur 8 ce qui utilise 42 LE contre 45 LE pour bouclage à 0 !!!!
       WHEN OTHERS => s7segs <="0000000"; 
     END CASE;
   END IF;
  END PROCESS;
  s_7segs <=s7segs;
END arch;