Composants de Base

Composants de Base

methode_1.svg

Composants Combinatoires

Porte 3 Etats

Pour un composant combinatoire, on utilise l’affectation conditionnelle
signal <= valeur when condition else autre_valeur

porte_3e.svg

library IEEE;
use IEEE.std_logic_1164.all;

entity porte_3e is
port( 	data_in		:	in std_logic_vector(15 downto 0);
	oe 		: 	in std_logic;
	data_out 	: 	out std_logic_vector(15 downto 0));
end porte_3e;

architecture arch_porte_3e of porte_3e is
begin
	data_out <= data_in when oe='1' else "ZZZZZZZZZZZZZZZZ";
end arch_porte_3e;

porte_3e.png

Multiplexeur

L’affectation conditionnelle peut être multiple, attention à bien respecter la syntaxe ci dessous :
signal <= valeur when condition
else autre_valeur when autre condition
… else valeur_par_défaut

multiplexeur.svg

library IEEE;
use IEEE.std_logic_1164.all;

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

architecture arch_multiplexeur of multiplexeur is
begin
	S <=		E3 when sel="11" else
			 E2 when sel="10" else
			 E1 when sel="01" else
			 E0 ; 		-- cas par defaut obligatoire
end arch_multiplexeur;

multiplexeur.png

Additionneur / Soustracteur

Les opérations arithmétiques sont disponibles dans la bibliothèque numeric_std et supposent l’utilisation des types signed ou unsigned ( de même nature que les std_logic_vector, à savoir des vecteurs de std_logic ).
un cast est alors nécessaire si les entrées sorties sont en std_logic_vector

add_sub.svg

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all; -- types signed / unsigned (calcul)

entity add_sub is
port( 		A,B		:	in std_logic_vector(7 downto 0);
			add_sub : 	in std_logic;
			result 	: 	out std_logic_vector(7 downto 0));
end add_sub;

architecture arch_add_sub of add_sub is
begin
	result <= 	std_logic_vector(signed(A)+signed(B)) when add_sub='1' 
				else
				std_logic_vector(signed(A)-signed(B));
end arch_add_sub;

add_sub.png


Composants Synchrones

Registre

Reset Asynchrone

Pour un composant synchrone, on priorise l’utilisation d’un process.
La porte d’entrée du process est soit le reset ( prioritaire ) , soit un changement d’état de l’horloge.
Dans le process, les instructions s’exécutent dans l’odre d’écriture, d’où la présence d’ if then else.
La fonction rising_edge() permet de tester la nature du changement d’état de l’horloge.

registre.svg

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;

registre.png

Remise à Zéro Synchrone

Pour une remise à zéro synchrone, il faut attendre un front d’horloge ; ce dernier est donc prioritaire par rapport au signal raz, et donc le signal raz n’est plus une porte d’entrée du process.

registre_raz.svg

library IEEE;
use IEEE.std_logic_1164.all;

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

architecture arch_registre_raz of registre_raz is
begin
	process(clk)
		begin
		if rising_edge(clk) then
			if raz='1' then d_out <= (others => '0');
			elsif load='1' then d_out <= d_in;
			end if;
		end if;
	end process;
end arch_registre_raz;

registre_raz.png

Compteur

Compteur de Base

Le signal count étant une sortie (out), il n’est pas possible de lire ce signal ( sauf à le déclarer en inout, mais on reservera cette syntaxe pour les bus bidirectionnels ).
On utilise alors le signal interne count_int que l’on peut lire ou modifier.
Count étant une copie de count_int, il faut réaliser l’affectation de count en parallèle du process.
En effet, il faut se rappeler que l’affectation des signaux ne se fait qu’un fois, et que cette affectation est à considérer comme effective sur le end process.
Si l’affectation de count est réalisée dans le process, count recevra la valeur de count_int au moment de l’entrée dans le process, et non après incrémentation.

compteur_base.svg

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); -- count copie de count_int

end arch_compteur_base;

compteur_base.png

Compteur Préchargeable

compteur.svg

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

entity compteur is
port( 	clk,reset,load,ce	:	in  std_logic;
	E			: 	in  std_logic_vector(3 downto 0);
	count 			: 	out std_logic_vector(3 downto 0));
end compteur;

architecture arch_compteur of compteur 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 load='1' then count_int <= unsigned(E);		
			elsif ce='1' 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 if;
	end process;

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

end arch_compteur;

compteur.png

Machine d’Etat (Séquenceur)

Le description VHDL d’une machine d’état reprend la structure de la machine de moore ou de mealy.
les 2 blocs combinatoires sont codés par un process combinatoire, le lien entre état courant et état suivant est réalisé par un registre.

me_chariot.svg

dessin_chariot.svg

moore.svg

chariot_diag.svg

cliquer sur la figure ci-dessous

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

entity me_chariot is
port( 	clk,reset	:	in std_logic;
	A,B		:	in std_logic;
	G, Dr 		: 	out std_logic);
end me_chariot;

architecture arch_me_chariot of me_chariot is
type etat_me is (GAUCHE, DROITE);
signal etat_cr, etat_sv : etat_me;
begin
----------------------------------------------------------------------------------
	process(clk,reset)	-- registre synchrone, maj etat_cr
	begin
		if reset='1' then etat_cr <= GAUCHE;
		elsif rising_edge(clk) then etat_cr <= etat_sv;
		end if;
	end process;

----------------------------------------------------------------------------------	
	process(A,B,etat_cr)	-- process combinatoire
	begin
	G <= '0'; Dr<= '0'; etat_sv <= etat_cr; -- sorties par defaut
	
	case etat_cr is
		when GAUCHE => if A='1' then etat_sv <= DROITE; end if; -- maj etat_sv
				G <= '1';	-- sorties a 1 dans cet etat

		when DROITE => if B='1' then etat_sv <= GAUCHE; end if; 
				Dr <= '1';	
	end case;	
	end process;
----------------------------------------------------------------------------------
end arch_me_chariot;

me_chariot.png