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é.
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.
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.
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).
|
|