Skip to content
Snippets Groups Projects
Security_Door.vhd 6.87 KiB
Newer Older
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Security_Door is

--frequency of basys3 board clock
 generic(freq : integer := 100000000);

 Port ( A : in STD_LOGIC;
        B : in STD_LOGIC;
        C : in STD_LOGIC;
        D : in STD_LOGIC;
        E : in STD_LOGIC;
        F : in STD_LOGIC;
        
        
        --buttons
        SEND : in std_logic;
        RESET : in std_logic;
        
        
        --clock        
        clk : in std_logic;
        
        --locked_test : out std_logic;
        
        --for seven segment display
        ANODE : out std_logic_vector (3 downto 0); --all digits declared although only 3 and 0 are used 
        LED_out : out STD_LOGIC_VECTOR (6 downto 0));
        
end Security_Door;

architecture Behavioral of Security_Door is

    signal slow_clk_enable: std_logic;
    signal Q1, Q2, Q2_bar, q0: std_logic;

    --signal declarations
    
    ---user input
    signal input : std_logic_vector(5 downto 0); 
    
    ---hardset password
    signal password : std_logic_vector(5 downto 0);
    
    --count for displayed countdown
    signal count : integer range 2 to 11;
    
    --locked flag 
    signal locked: boolean := true;
    
    --ticks to innumerate clock ticks
    signal ticks: integer := 0;
   
    --counters for flashing function
    signal flashCount: integer;
    signal flashCountX: integer;
    
    --count for debouncing button (0.25 seconds)
    constant buttonCount: integer := 25000000;
    signal buttonReset: integer := 0;
    type button_state is (idle, waiting, pressed);
    signal user_in : button_state := idle;
    
    signal send_in : button_state := idle;
    signal reset_in : button_state := idle;
    constant button_active : std_logic := '1';
    signal buttonticks : integer := 0;
    signal send_out : integer := 0;
    signal reset_out : integer := 0;
    
    signal send_pressed : boolean := false;
    signal reset_pressed : boolean := false;
    
    type LED_state is (flashing, lockedLED, unlockedLED);
    signal LED : LED_state := lockedLED;
    
    signal internalReset : boolean := true;
    
    signal DB_SEND : std_logic;
    
    signal o : std_logic;

begin

--concat input from switches into a vector to be able to compare it to the password
input <= A & B & C & D & E & F;

--declare password
password <= "110011";


clock_enable_generator: entity work.clock_enable_debouncing_button PORT MAP 
      ( clk => clk,
        slow_clk_enable => slow_clk_enable
      );
Debouncing_FF0: entity work.DFF_Debouncing_Button PORT MAP 
      ( clk => clk,
        clock_enable => slow_clk_enable,
        D => SEND,
        Q => Q0
      ); 

Debouncing_FF1: entity work.DFF_Debouncing_Button PORT MAP 
      ( clk => clk,
        clock_enable => slow_clk_enable,
        D => Q0,
        Q => Q1
      );      
Debouncing_FF2: entity work.DFF_Debouncing_Button PORT MAP 
      ( clk => clk,
        clock_enable => slow_clk_enable,
        D => Q1,
        Q => Q2
      ); 
 Q2_bar <= not Q2;
 DB_SEND <= Q1 and Q2_bar;
 
--main

main:        
process(clk) is
    begin
    
        if rising_edge(clk) then
        if (DB_SEND = '1' and internalReset) then
        
            --password is right
            if (input = password) then
            
                locked <= false;
                --locked_test <= '0';
                ticks <= 0;
                count <= 11;
                LED <= unlockedLED;
                internalReset <= false;
                
                if ticks = freq - 1 then --after one second
                    ticks <= 0;
                        --relocks after 10 seconds
                        if count = 0 then
                            locked <= true;
                            --locked_test <= '1';
                            LED <= lockedLED;
                            --send_out <= 0; --reset send_out to prevent infinite loop
                            --user has to reset
                            internalReset <= true;
                        else
                            --decrease count after a second
                            count <= count - 1;
                        end if;
                 else
                    ticks <= ticks + 1;
                 end if;
                 
            --if password is wrong, user has to reset after       
            else 
                locked <= true;
                --locked_test <= '1';
                --flashing lights (until reset?)
                ticks <= 0;
                --flashcount will change 20 times -> 10 on 10 off -> for 5 seconds
                flashCount <= 20;
                LED <= lockedLED;
                internalReset <= false;
                
                if ticks = 4999 then
                    ticks <= 0;
                    
                    if flashCount = 0 then
                        LED <= lockedLED;
                        locked <= true;
                        --locked_test <= '1';
                        --send_out <= 0;
                        internalReset <= true;
                    else
                        flashCount <= flashcount - 1;
                    end if;
                else
                ticks <= ticks + 1;
               end if;
            end if;
            
        --if send is not pressed nothing happens
        else 
            locked <= true;
            --locked_test <= '1';
            LED <= lockedLED;
            internalReset <= true;
           
        end if;
        end if;
end process;

process (flashCount, count, locked, LED)

    begin
    ANODE <= "1111";
    LED_out <= "1111111";
        case (LED) is 
            when flashing =>
                ANODE <= "0000";
                if ((flashCount mod 2) = 0) then
                    LED_out <= "1111111";
                else
                    LED_out <= "1111110";
                end if;
            
            when unlockedLED =>
                ANODE <= "1110";
                case count is
                    --when 1 => LED_out <= "0000001"; -- "0"     --display of U is one second, so numbers displayed will be 9-1
                    when 2 => LED_out <= "1001111"; -- "1" 
                    when 3 => LED_out <= "0010010"; -- "2" 
                    when 4 => LED_out <= "0000110"; -- "3" 
                    when 5 => LED_out <= "1001100"; -- "4" 
                    when 6 => LED_out <= "0100100"; -- "5" 
                    when 7 => LED_out <= "0100000"; -- "6" 
                    when 8 => LED_out <= "0001111"; -- "7" 
                    when 9 => LED_out <= "0000000"; -- "8"     
                    when 10 => LED_out <= "0000100"; -- "9" 
                    when 11 => LED_out <= "1000001"; -- "U"
                    
                end case;
                
            when lockedLED =>
                ANODE<= "0111";
                LED_out <= "1110001";
        end case;
end process;



end Behavioral;