Mauvaises Pratiques

Mauvaises Pratiques

Conflits

Dans la description ci dessous, count est affecté :

  • dans le process ( lors du reset )
  • En parallèle du process en recevant count_int
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity compteur_base is
port(
  clk, reset : in  std_logic;
  count      : out std_logic_vector(3 downto 0)
);
end compteur_base;

architecture arch_compteur_base of compteur_base is
  signal count_int : unsigned(3 downto 0);
begin
  process(clk, reset)
  begin
    if reset='1' then count <= (others => '0'); -- ERREUR
    elsif rising_edge(clk) then
      if count_int = "1111" then
        count_int <= (others => '0'); -- fin de comptage
      else
        count_int <= count_int + 1;   -- "+" (unsigned,int)
      end if;
    end if;
  end process;

  count <= std_logic_vector(count_int); -- copie de count_int
end arch_compteur_base;

Ce forçage multiple correspond à un conflit ; la solution consite à gérer uniquement count_int dans le process et considérer count comme une copie de count_int en faisant count <= count_int en parallèle du process.

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity compteur_base is
port(
  clk, reset : in  std_logic;
  count      : out std_logic_vector(3 downto 0)
);
end compteur_base;

architecture arch_compteur_base of compteur_base is
  signal count_int : unsigned(3 downto 0);
begin
  process(clk, reset)
  begin
    if reset = '1' then
      count_int <= (others => '0');
    elsif rising_edge(clk) then
      if count_int = "1111" then
        count_int <= (others => '0'); -- fin de comptage
      else
        count_int <= count_int + 1;   -- "+" (unsigned,int)
      end if;
    end if;
  end process;

  count <= std_logic_vector(count_int); -- copie de count_int
end arch_compteur_base;

ET logique avec CLK

library IEEE;
use IEEE.std_logic_1164.all;

entity registre is
port(
  clk, reset, load : in  std_logic;
  d_in             : in  std_logic_vector(7 downto 0);
  d_out            : out std_logic_vector(7 downto 0)
);
end registre;

architecture arch_registre of registre is
begin
  process(clk, reset)
  begin
    if reset = '1' then
      d_out <= (others => '0');
    elsif rising_edge(clk) and load = '1' then
      d_out <= d_in;
    end if;
  end process;
end arch_registre;

Le ET logique entre load et rising_edge(clk) a pour effet de générer une porte ET entre load et clk.
Si cela ne change pas grand chose à la simulation, le composant décrit n’est plus synchrone à clk et pourra présenter un fonctionnement aléatoire dans un composant synthétisé.

registre_avec_et.svg


Gestion des Signaux dans un Process

library IEEE;
use IEEE.std_logic_1164.all;

entity manip_signaux is
port(
  a : in  std_logic;
  s : out std_logic
);
end manip_signaux;

architecture arch_manip_signaux of manip_signaux is
  signal interne : std_logic;
begin
  process(a)
  begin
    interne <= a;  -- affectation de interne effective sur end process
    s <= interne;
  end process;
end arch_manip_signaux;

L’affectation de interne étant effective sur end process, s reçoit la valeur de interne au moment où on est entré dans le process, d’où le décalage.

manip_signaux.png


Process Combinatoire

library IEEE;
use IEEE.std_logic_1164.all;

entity multiplexeur_faux is
port(
  E0, E1, E2, E3 : in  std_logic_vector(7 downto 0);
  sel             : in  std_logic_vector(1 downto 0);
  S               : out std_logic_vector(7 downto 0)
);
end multiplexeur_faux;

architecture arch_multiplexeur_faux of multiplexeur_faux is
begin
  process(E0, E1, E2, E3)
  begin
    if sel = "11" then
      S <= E3;
    elsif sel = "10" then
      S <= E2;
    elsif sel = "01" then
      S <= E1;
    else
      S <= E0;  -- cas par défaut obligatoire
    end if;
  end process;
end arch_multiplexeur_faux;

sel ne figurant pas dans la liste de sensibilité du process, S n’est pas modifié au moment où sel change (puisqu’on n’entre pas dans le process).
Par conséquent on mémorise la valeur de S avec des bascules, il ne s’agit donc plus d’un composant combinatoire.

multiplexeur__process_faux.png


if then else : priorite

La structure if then elsif n’est pas équivalente à if then if

La première séquence induit une notion de priorité, de telle sorte que le reset est prioritaire : si reset=‘1’ on ignore la suite.
Dans le deuxième cas, même si reset=‘1’, on effectuera le chargement du registre si load=‘1’ (seule la dernière affectation est prise en compte).

library IEEE;
use IEEE.std_logic_1164.all;

entity registre is
port(
  clk, reset, load : in  std_logic;
  d_in             : in  std_logic_vector(7 downto 0);
  d_out            : out std_logic_vector(7 downto 0)
);
end registre;

architecture arch_registre of registre is
begin
  process(clk, reset)
  begin
    if reset = '1' then
      d_out <= (others => '0');
    elsif rising_edge(clk) then
      if load = '1' then
        d_out <= d_in;
      end if;
    end if;
  end process;
end arch_registre;
library IEEE;
use IEEE.std_logic_1164.all;

entity registre is
port(
  clk, reset, load : in  std_logic;
  d_in             : in  std_logic_vector(7 downto 0);
  d_out            : out std_logic_vector(7 downto 0)
);
end registre;

architecture arch_registre of registre is
begin
  process(clk, reset)
  begin
    if reset = '1' then
      d_out <= (others => '0');
    end if;

    if rising_edge(clk) then
      if load = '1' then
        d_out <= d_in;
      end if;
    end if;
  end process;
end arch_registre;