Created
December 21, 2016 21:45
-
-
Save nesteruk/beb1c3f9a6cc9dac2f5043da4b9b34ec to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library ieee; | |
use ieee.std_logic_1164.all; | |
entity combination_lock is | |
port ( | |
key : in std_logic_vector(3 downto 0); | |
hex3, hex2, hex1, hex0 : out std_logic_vector(0 to 6); | |
clock_50: in std_logic | |
); | |
end entity; | |
architecture rtl of combination_lock is | |
function hex_digit(x:integer; hide_zero:boolean := false) | |
return std_logic_vector is | |
begin | |
case x is | |
when 0 => | |
if hide_zero then | |
return "1111111"; | |
else | |
return "0000001"; | |
end if; | |
when 1 => return "1001111"; | |
when 2 => return "0010010"; | |
when 3 => return "0000110"; | |
when 4 => return "1001100"; | |
when 5 => return "0100100"; | |
when 6 => return "0100000"; | |
when 7 => return "0001111"; | |
when 8 => return "0000000"; | |
when 9 => return "0000100"; | |
when others => return "1111111"; | |
end case; | |
end function; | |
type state is (ready, ok1, ok2, ok3, yes, err1, err2, err3, fail); | |
signal current_state : state := ready; | |
subtype door_digit is integer range 1 to 4; | |
type door_code_type is array(0 to 3) of door_digit; | |
signal digit_entered : integer; | |
signal last_key, kd1, kd2 : std_logic_vector(3 downto 0); | |
-- the code to unlock the door | |
constant unlock_code : door_code_type := ( 4, 3, 2, 1 ); | |
signal entered_digits : door_code_type; | |
signal entry_position : integer range -1 to 3 := -1; | |
begin -- architecture | |
hex3 <= "1111110" when current_state = ready | |
else "1111111" when current_state = yes | |
else hex_digit(entered_digits(0)); | |
hex2 <= "1111110" when current_state = ready | |
else hex_digit(entered_digits(1)); | |
hex1 <= "1111110" when current_state = ready | |
else hex_digit(entered_digits(2)); | |
hex0 <= "1111110" when current_state = ready | |
else hex_digit(entered_digits(3)); | |
process(clock_50) is | |
begin | |
if rising_edge(clock_50) and digit_entered /= -1 then | |
-- advance the entry position | |
entry_position <= (entry_position + 1) rem 4; | |
-- write the entered digit | |
entered_digits(entry_position) <= digit_entered; | |
-- is the entered digit the right one? | |
if digit_entered = unlock_code(entry_position) then | |
if current_state = ready then | |
current_state <= ok1; | |
elsif current_state = ok1 then | |
current_state <= ok2; | |
elsif current_state = ok2 then | |
current_state <= ok3; | |
elsif current_state = ok3 then | |
current_state <= yes; | |
else | |
current_state <= ok1; | |
end if; | |
end if; | |
end if; | |
end process; | |
process(clock_50) is | |
begin | |
if rising_edge(clock_50) then | |
kd2 <= kd1; | |
kd1 <= key; -- deal with metastability risk | |
if kd2(3) = '1' and last_key(3) /= '1' then | |
digit_entered <= 1; | |
elsif kd2(2) = '1' and last_key(2) /= '1' then | |
digit_entered <= 2; | |
elsif kd2(1) = '1' and last_key(1) /= '1' then | |
digit_entered <= 3; | |
elsif kd2(0) = '1' and last_key(0) /= '1' then | |
digit_entered <= 4; | |
else | |
digit_entered <= -1; | |
end if; | |
last_key <= kd2; | |
end if; | |
end process; | |
end architecture; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment