Voorbeeld Mealy FSM: verkeerslichten met timer
We voegen twee tellers toe om ervoor te zorgen dat de verkeerslichten langer rood en groen blijven dan oranje.
- We veronderstellen dat de tellers op nul blijven staan zolang het start signaal hoog is.
- Als het start signaal laag wordt, telt de overeenkomstige teller op totdat een maximum is bereikt. Bij de korte teller is dit maximum (“0111”) kleiner dan bij de lange teller (“1111”).
- Bij het bereiken van het maximum wordt het ready signaal hoog.
FSM schematisch:
Teller met maximum waarde als parameter
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity teller is
generic( max_waarde: std_logic_vector(3 downto 0));
port( clk, start: in std_logic;
ready: out std_logic);
end teller;
architecture arch of teller is
signal tel_waarde: std_logic_vector(3 downto 0);
begin
p_teller: process(clk)
begin
if clk'event and clk = '1' then
if start = '1' then
tel_waarde <= "0000";
ready <= '0';
elsif tel_waarde = max_waarde then
tel_waarde <= "0000";
ready <= '1';
else
tel_waarde <= tel_waarde + 1;
ready <= '0';
end if;
end if;
end process;
end arch;
Datapad
library ieee;
use ieee.std_logic_1164.all;
entity datapad is
port( clk, start_kort, start_lang: in std_logic;
ready_kort, ready_lang: out std_logic);
end datapad;
architecture arch of datapad is
component teller is
generic(max_waarde: std_logic_vector(3 downto 0));
port( clk, start: in std_logic;
ready: out std_logic);
end component;
begin
teller_lang: teller
generic map(max_waarde => "1111")
port map( clk => clk,
start => start_lang,
ready => ready_lang);
teller_kort: teller
generic map(max_waarde => "0111")
port map( clk => clk,
start => start_kort,
ready => ready_kort);
end arch;
- In het datapad wordt de parameteriseerbare teller twee maal geïnstantieerd.
- In de eerste instantiatie wordt de maximale waarde ingesteld op “1111”.
- In de tweede instantiatie wordt de maximale waarde ingesteld op “0111”.
Next state functie
p_next: process(state, rst, ready_lang, ready_kort)
begin
if rst = '1' then
next_state <= rst_state;
else
case state is
when rst_state => next_state <= green_state;
when green_state => if ready_lang = '1' then
next_state <= yellow_state;
else
next_state <= green_state;
end if;
when yellow_state => if ready_kort = '1' then
next_state <= red_state;
else
next_state <= yellow_state;
end if;
when red_state => if ready_lang = '1' then
next_state <= geen_state;
else
next_state <= red_state;
end if;
when others => next_state <= rst_state;
end case;
end if;
end process;
State register
p_reg: process(clk)
begin
if clk'event and clk = '1' then
state <= next_state;
end if;
end process;
Output functie
p_out: process(state, ready_lang, ready_kort)
begin
case state is
when rst_state =>
red <= '0'; yellow <= '0'; green <= '0'; start_lang <= '1'; start_kort <= '0';
when green_state =>
red <= '0'; yellow <= '0'; green <= '1'; start_lang <= '0';
if ready_lang = '1' then start_kort <= '1';
else start_kort <= '0';
end if;
when yellow_state =>
red <= '0'; yellow <= '1'; green <= '0'; start_kort <= '0';
if ready_kort = '1' then start_lang <= '1';
else start_lang <= '0';
end if;
when red_state =>
red <= '1'; yellow <= '0'; green <= '0'; start_kort <= '0';
if ready_lang = '1' then start_lang <= '1';
else start_lang <= '0';
end if;
when others =>
red <= '0'; yellow <= '0'; green <= '0'; start_lang <= '0'; start_kort <= '0';
end case;
end process;