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

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 <= (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); -- count 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.

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 defaut 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 considérée)

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;