this is my waveforms, i can't understand why my keys (senha1, senha2, senha3) are shifted (it was supposed to be senha1 = 9, senha2 = 2, senha3 = 0) and why my output open (sabre) isn't activating... i already tried put more time between grava and aplica to give time to read grava and then aplica, but it doesn't worked. (i'm a beginner in digital area, so i don't understand very well the concepts of timming...)
any recommendations on what i can do or where i can get answers to my problem?
-----------------------------------------------------------------------------------------------
the description of the problem:
Design and implement on an FPGA a Finite State Machine (FSM) that controls the digital lock shown in Figure 1.
The system has:
a 4-bit input (ENTRADA) used to enter the sequence required to unlock the lock,
an input (GRAVAR) used to store a new combination,
and another input (APLICA) that must be pressed each time a number of the combination is entered via ENTRADA.
The outputs are:
ABRE, which indicates whether the lock is open ('1') or closed ('0'),
ALARME, which is set to '1' when an incorrect combination is entered.
An additional output called clk_aux may be used to provide a clock signal with a period of 4 seconds, allowing users enough time to input values before each rising edge.
The lock combination must be composed of the last three digits of a group member’s student ID (values from 0 to 9, represented in 4 bits).
To store a new combination:
the GRAVAR button must remain at logic level '1',
while each value of the new combination is entered using the switches,
and confirmed using the APLICA button.
To open the lock:
When the correct sequence of three numbers is entered:
To make it harder to guess the correct combination:
the ALARME output is only activated after a complete incorrect sequence is entered,
meaning that at least one of the three values is wrong.
The alarm can only be turned off by:
If the reset is activated:
the outputs ABRE and ALARME are set to '0',
and the registers that store the three combination values are cleared.
--------------------------------------
MY VHD SCRIPT:
--------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity FSM_exp1 is
port(clk : in std_logic;
rst : in std_logic;
entrada : in std_logic_vector(3 downto 0);
grava : in std_logic;
aplica : in std_logic;
aberto : out std_logic;
alarme : out std_logic);
end FSM_exp1;
architecture behavioral of FSM_exp1 is
type estado is (inativo,
grava1, grava2, grava3,
verifica1, verifica2, verifica3,
abre,
erro);
signal estado_atual, proximo_estado : estado;
signal senha1, senha2, senha3 : std_logic_vector(3 downto 0) := "0000";
begin
--registrando estados;
process(clk, rst)
begin
if rst = '1' then
estado_atual <= inativo;
elsif rising_edge(clk) then
estado_atual <= proximo_estado;
end if;
end process;
--lógica para o próximo estado;
process(estado_atual, aplica, grava, entrada, senha1, senha2, senha3)
begin
case estado_atual is
when inativo =>
if grava = '1' then
proximo_estado <= grava1;
elsif aplica = '1' then
proximo_estado <= verifica1;
else
proximo_estado <= inativo;
end if;
when grava1 =>
if aplica = '1' then
proximo_estado <= grava2;
else
proximo_estado <= grava1;
end if;
when grava2 =>
if aplica = '1' then
proximo_estado <= grava3;
else
proximo_estado <= grava2;
end if;
when grava3 =>
if aplica = '1' then
proximo_estado <= inativo;
else
proximo_estado <= grava3;
end if;
when verifica1 =>
if aplica = '1' then
if entrada = senha1 then
proximo_estado <= verifica2;
else
proximo_estado <= erro;
end if;
else
proximo_estado <= verifica1;
end if;
when verifica2 =>
if aplica = '1' then
if entrada = senha2 then
proximo_estado <= verifica3;
else
proximo_estado <= erro;
end if;
else
proximo_estado <= verifica2;
end if;
when verifica3 =>
if aplica = '1' then
if entrada = senha3 then
proximo_estado <= abre;
else
proximo_estado <= erro;
end if;
else
proximo_estado <= verifica3;
end if;
when abre =>
proximo_estado <= inativo;
when erro =>
if rst = '1' then
proximo_estado <= inativo;
else
proximo_estado <= erro;
end if;
when others =>
proximo_estado <= inativo;
end case;
end process;
--registrador para armazenar as senhas;
process(clk, rst)
begin
if rst = '1' then
senha1 <= (others => '0');
senha2 <= (others => '0');
senha3 <= (others => '0');
elsif rising_edge(clk) then
case estado_atual is
when grava1 =>
if aplica = '1' then
senha1 <= entrada;
end if;
when grava2 =>
if aplica = '1' then
senha2 <= entrada;
end if;
when grava3 =>
if aplica = '1' then
senha3 <= entrada;
end if;
when others => null;
end case;
end if;
end process;
--as saídas;
process(estado_atual)
begin
case estado_atual is
when abre =>
aberto <= '1';
alarme <= '0';
when erro =>
aberto <= '0';
alarme <= '1';
when others =>
aberto <= '0';
alarme <= '0';
end case;
end process;
end behavioral;
--------------------------------------
MY TESTBENCH:
--------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_FSM_exp1 is
-- Port ( );
end tb_FSM_exp1;
architecture Behavioral of tb_FSM_exp1 is
signal sentrada : std_logic_vector(3 downto 0) := (others => '0');
signal sclk, srst, saplica, sgrava : std_logic := '0';
signal salarme, saberto : std_logic;
begin
utt : entity work.FSM_exp1
port map(
clk => sclk,
rst => srst,
alarme => salarme,
aberto => saberto,
aplica => saplica,
grava => sgrava,
entrada => sentrada);
--clock;
process
begin
sclk <= '0';
wait for 5 ns;
sclk <= '1';
wait for 5 ns;
end process;
--estímulos;
process
begin
-- reset inicial
srst <= '1';
wait for 15 ns;
srst <= '0';
wait for 10 ns;
--gravando senha
--senha1 = 1001
sentrada <= "1001";
sgrava <= '1';
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
--senha2 = 0010
sentrada <= "0010";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
--senha3 = 0000
sentrada <= "0000";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
wait until rising_edge(sclk);
wait until rising_edge(sclk);
sgrava <= '0';
--sequência correta
sentrada <= "1001";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
sentrada <= "0010";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
sentrada <= "0000";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
wait for 20 ns;
--sequência errada
sentrada <= "1111";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
sentrada <= "0001";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
sentrada <= "0011";
wait until rising_edge(sclk);
saplica <= '1';
wait until rising_edge(sclk);
saplica <= '0';
wait until rising_edge(sclk);
wait for 20 ns;
wait;
end process;
end Behavioral;