Skip to content

Instantly share code, notes, and snippets.

@nesteruk
Created December 21, 2016 21:45
Show Gist options
  • Save nesteruk/beb1c3f9a6cc9dac2f5043da4b9b34ec to your computer and use it in GitHub Desktop.
Save nesteruk/beb1c3f9a6cc9dac2f5043da4b9b34ec to your computer and use it in GitHub Desktop.
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