lunes

"Curioso Semáforo" en VHDL

Semáforo

-Este semáforo tiene 3 luces, verde, ambar y rojo,
-Esta normalmente en verde
-Para que cambie de color (verde a rojo) es necesario presionar un boton llamado stop, con lo cual el semáforo primero pasa de verde a ambar y permanece en ese estado durante 5 segundos.
-Luego pasa a rojo durante 20 segundos.
-Los últimos 5 segundos son mostrados en un display 7 segmentos
-Para luego regresar al color verde por defecto.

Diseño:

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;

ENTITY semaforo IS
PORT( Clock, Stop: IN std_logic;
Luces: OUT std_logic_vector(2 DOWNTO 0);
Display: OUT std_logic_vector(4 DOWNTO 0));
END semaforo;

ARCHITECTURE description OF semaforo IS
--SIGNAL New_Clock: std_logic:='0';
SIGNAL Cuenta: std_logic_vector(4 DOWNTO 0):=(OTHERS=>'0');
TYPE Estados IS (S0, S1, S2);
SIGNAL Estado_Actual, Estado_Siguiente: Estados;
SIGNAL Cuenta_Display: std_logic_vector(4 DOWNTO 0):=(OTHERS=>'0');
BEGIN
--
----Generacion de clock_1hz
--New_Clock_Process: PROCESS(Clock)
--VARIABLE Contador: Integer:=1;
--BEGIN
--IF RISING_EDGE(Clock) THEN
-- IF (Contador = 25000000) THEN
-- New_Clock <= NOT New_Clock;
-- Contador:=1;
-- ELSE
-- Contador := Contador+1;
-- END IF;
--END IF;
--END PROCESS New_Clock_Process;

--FSM--

Logica_estado_siguiente: PROCESS(Estado_Actual, Stop, Cuenta)
BEGIN
CASE Estado_Actual IS
WHEN S0=>
IF Stop='1' THEN
Estado_Siguiente <= S1;
ELSE
Estado_Siguiente <= S0;
END IF;

WHEN S1=>
IF Cuenta= "00101" THEN
Estado_Siguiente <= S2;
ELSE
Estado_Siguiente <= S1;
END IF;

WHEN S2=>
IF Cuenta = "11001" THEN
Estado_Siguiente <= S0;
ELSE
Estado_Siguiente <= S2;
END IF;

END CASE;
END PROCESS Logica_estado_siguiente;

Cuenta_Process: PROCESS(Clock)
BEGIN
IF RISING_EDGE(Clock) THEN
CASE Estado_Actual IS
WHEN S0 => Cuenta <= (OTHERS=>'0');
WHEN S1 => Cuenta <= Cuenta+1;
WHEN S2 => Cuenta <= Cuenta+1;
END CASE;
END IF;
END PROCESS Cuenta_Process;
--

Memoria_Estado: PROCESS(Clock)
BEGIN
IF RISING_EDGE(Clock) THEN
Estado_Actual <= Estado_Siguiente;
END IF;
END PROCESS Memoria_Estado;

--SALIDA
Luces <="001" WHEN Estado_Actual = S0 ELSE
"010" WHEN Estado_Actual = S1 ELSE
"100"; --WHEN Estado_Actual = S2;

PROCESS(Clock)
BEGIN
IF RISING_EDGE(Clock) THEN
IF Estado_Actual=S2 AND (Cuenta = "10100") THEN
Cuenta_Display<="00101";
ELSIF Estado_Actual=S2 AND (Cuenta> "10100" AND Cuenta <= "11001") THEN
Cuenta_Display<= Cuenta_Display - 1;
END IF;
END IF;
END PROCESS;

Display<=Cuenta_Display;

END description;

--Nota: Se comentó parte del código para la simulación con un Clock definido en el vector de test.
Para la implementación en el FPGA, descomentar el proceso de generación de señal de reloj de 1 Hz, asimismo descomentar la linea en donde se crea la señal New_Clock. Hecho esto, en el resto del código VHDL modificar Clock por New_Clock.
--consultas: solo dejar un comentario :)

6 comentarios: