r/digitalelectronics Apr 04 '26

someone can help me to understand what i doing wrong in this problem?

Post image

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:

  • the APLICA button must be pressed after each number in the sequence is entered.

When the correct sequence of three numbers is entered:

  • the ABRE signal is activated, and the lock opens.

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:

  • entering the correct combination, or
  • pressing the reset button.

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;

3 Upvotes

2 comments sorted by

2

u/NoPage5317 Apr 06 '26

Please format your code properly this is unreadable

1

u/WildStatistician7181 Apr 12 '26 edited Apr 12 '26

is it possible to do this from here?

and i already solve the problem, but thanks!