library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity lock is port( code: in std_logic_vector(3 downto 0); mode: in std_logic_vector(1 downto 0); clk, rst: in std_logic; unlock: out std_logic; alarm, err: buffer std_logic ); type passwd is array (3 downto 0) of integer; end lock; architecture arc of lock is signal pwd: passwd; signal state: integer := 0; signal cnt: integer := 0; -- which bit (admin) or failure time (users) begin process(clk, rst) begin if (rst = '0') then unlock <= '0'; err <= '0'; state <= 0; if (alarm = '1') then cnt <= 0; end if; elsif (clk'event and clk = '0') then if (alarm = '1') then if (CONV_INTEGER(code) = 8) then -- enter admin passwd 8888 if (cnt > 2) then cnt <= 0; alarm <= '0'; state <= 0; err <= '0'; else cnt <= cnt + 1; end if; else cnt <= 0; end if; elsif (mode = "00" and err = '0') then -- set passwd case state is when 0 => pwd(0) <= CONV_INTEGER(code); state <= 1; when 1 => pwd(1) <= CONV_INTEGER(code); state <= 2; when 2 => pwd(2) <= CONV_INTEGER(code); state <= 3; when 3 => pwd(3) <= CONV_INTEGER(code); state <= 7; unlock <= '1'; when others => NULL; end case; elsif (mode = "01") then -- check passwd case state is when 0 => if (CONV_INTEGER(code) = pwd(0)) then state <= 4; err <= '0'; else err <= '1'; if (cnt > 1) then alarm <= '1'; cnt <= 0; else cnt <= cnt + 1; end if; end if; when 4 => if (CONV_INTEGER(code) = pwd(1)) then state <= 5; else err <= '1'; state <= 0; if (cnt > 1) then alarm <= '1'; cnt <= 0; else cnt <= cnt + 1; end if; end if; when 5 => if (CONV_INTEGER(code) = pwd(2)) then state <= 6; else err <= '1'; state <= 0; if (cnt > 1) then alarm <= '1'; cnt <= 0; else cnt <= cnt + 1; end if; end if; when 6 => if (CONV_INTEGER(code) = pwd(3)) then state <= 7; unlock <= '1'; cnt <= 0; else err <= '1'; state <= 0; if (cnt > 1) then alarm <= '1'; cnt <= 0; else cnt <= cnt + 1; end if; end if; when others => NULL; end case; end if; end if; end process; end arc;