Gestion d'un parking

Le but de ce système est de gérer la disponibilité des places d’un parking.

L’élément principal du système est un compteur qui s’incrémente si le capteur d’entrée vaut 1 et se décrémente si le capteur de sortie vaut 1.

Un registre permet de stocker le nombre de places max admissible dans le parking.

Une comparaison entre la valeur de comptage et celle du registre permet d’indiquer si le parking est complet ou pas.

Q1. A partir d’un fichier vierge, proposer la description de l’ensemble des composants de ce système, et réaliser l’instanciation de ces composants pour créer l’entité gestion_parking.

La démonstration du fonctionnement de l’ensemble doit se faire avec un test pertinent

gestion_parking.svg

Comparateur

Composant combinatoire, la syntaxe doit être :

signal <= valeur when condition else autre_valeur;

Soustracteur

result <= B - A

RAPPEL : Une opération arithmétique se fait entre opérandes de type signed ou unsigned.

Registre

Composant Synchrone, reset asynchrone –> process(clk,reset)

Compteur

Composant Synchrone, reset asynchrone –> process(clk,reset)

Le comptage doit se faire avec des unsigned

Détecteur de Front Montant

Le capteur peut fournir une information à 1 pendant plusieurs coups d’horloge.

Or le compteur ne doit s’incrémenter ou se décrémenter qu’une fois pour une voiture.

La solution consiste à utiliser une machine d’état pour détecter un front montant.

A l’issue d’un front montant de l’entrée, la sortie vaut 1 pendant une période de clk.

chrono_detect_front.svg

diag_etat_detect_front.svg

NB : Transition de la machine d’états “=1” –> Transition inconditionnelle (toujours vrai)

La description des machines d’états en VHDL répond à une syntaxe très précise reposant sur la machine de Moore ou de Mealy.

Il est demandé de respecter cette syntaxe.


Eléments de Correction

gestion_parking.vhd
library IEEE;
use IEEE.std_logic_1164.all;

entity registre is
port( 	clk,reset,load	:	in std_logic;
	d_in 		: 	in std_logic_vector(3 downto 0);
	d_out 		: 	out std_logic_vector(3 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;
use IEEE.numeric_std.all;

entity compteur is
port( 	clk,reset,up, down	:	in  std_logic;
	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 up='1' then			
				if count_int="1111" then count_int <= (others => '0'); -- fin de comptage
				else count_int <= count_int + 1; -- "+"(unsigned,int)
				end if;
			elsif down='1' then			
				if count_int="0000" then count_int <= (others => '1'); -- 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;
---------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity comparateur is
port(A,B : in std_logic_vector(3 downto 0);
	sup_egal,inf : out std_logic);
end comparateur;

architecture arch_comparateur of comparateur is
begin

sup_egal <= '1' when A >= B else '0';
inf <= '1' when A < B else '0';

end arch_comparateur;

---------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
  
entity detect_front is
  port( clk, reset : in std_logic;
        E : in std_logic;
        front_montant : out std_logic);
end detect_front;

architecture arch_detect_front of detect_front is
type etats_me is (E_0, E_1, E_2);
signal  etat_cr, etat_sv : etats_me;

begin
  
process(clk, reset)
    begin    
    if reset='1' then etat_cr <= E_0 ;
    elsif rising_edge(clk) then etat_cr <= etat_sv ; end if;
end process;

process(etat_cr, E)
    begin
  etat_sv <= etat_cr ; front_montant <= '0' ;  
  case etat_cr is    
  when E_0 => if E='1' then etat_sv <= E_1 ; end if;  
  when E_1 => etat_sv <= E_2 ;
              front_montant <= '1' ;                
  when E_2 => if E='0' then etat_sv <= E_0 ; end if; 
  end case;
  end process;
end arch_detect_front;   
---------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use work.all;


entity gestion_parking is
port( reset,clk, ld_reg, capt_entree, capt_sortie : in std_logic;
	nb_max : in	std_logic_vector(3 downto 0);
	complet, places_dispos : out std_logic);
end gestion_parking;


architecture arch_gestion_parking of gestion_parking is
signal up,down : std_logic;
signal comptage, val_max : std_logic_vector( 3 downto 0);
begin



detect_front_up : entity detect_front port map (
					clk		=> clk,
					reset		=> reset,
        				E 		=> capt_entree,
        				front_montant	=> up
						);

detect_front_down : entity detect_front port map (
					clk		=> clk,
					reset		=> reset,
        				E 		=> capt_sortie,
        				front_montant	=> down
						);

compt:entity compteur port map (
					clk		=> clk,
					reset		=> reset,
					up		=> up,
					down		=> down,
					count		=> comptage
						);
reg:entity registre port map (
					clk		=> clk,
					reset		=> reset,
					load		=> ld_reg,
					d_in 		=> nb_max,
					d_out 		=> val_max
						);
comp:entity comparateur port map (
					A		=> comptage,
					B		=> val_max,
					sup_egal	=> complet,
					inf		=> places_dispos
						);

end arch_gestion_parking;