基于VHDL的密码锁

本设计为一个四位密码锁,复位后的初始密码为1234,没有操作时显示模块显示8888;当处于输入密码模式时,通过四个拨动开关和两个按键来实现密码的输入,四个拨动开关对应于四个二进制数,经过译码就会得到十进制数,当输入密码正确时,显示HELLO,当输入密码错误时,显示ERROR,输入密码完后要通过拨动开关退出输入密码状态,如果想要修改密码则需要通过拨动开关进入改密状态;密码输入正确才能修改密码,处于改密状态时,会显示当前的密码,修改完通过拨动开关退出改密状态。

library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY E_lock IS
PORT(
    clk,res : in std_logic;  --时钟,复位信号(按键)
    password : in std_logic_vector(3 downto 0);  --输入密码(开关)
    
    --LED灯定义,显示状态
    led : out std_logic_vector(3 downto 0); --led灯
    Led10 : out std_logic_vector(9 downto 0);
    Leduser : OUT STD_LOGIC; 
    Ledset  : OUT STD_LOGIC; 
    
    --按键模块定义
enter : in std_logic;   --确认键(按键)
backc: in std_logic;
    
    --用户键登录(当为1时,输入密码;当为0时,显示8888)
    user : in std_logic;  --用户键(开关)
    
    --修改密码(当为1时,修改密码;当为0时,不修改)
    set_code  : in std_logic;  --改密键(开关)
    
    --数码管显示模块定义
    seg7 : out std_logic_vector(6 downto 0); --数码管显示内容(共阴极)
    seg7_0 : out std_logic_vector(6 downto 0);
    segselect4 : out std_logic_vector(3 downto 0);  --数码管片选(高电平有效)
    segselect4_0 : out std_logic_vector(3 downto 0)  --数码管片选(高电平有效)
);
END E_lock;

-- //****************************************************************************************************
-- //  模块名称:信号赋值
-- //  功能描述:
-- //****************************************************************************************************
ARCHITECTURE behave OF E_lock IS
--初始密码信号
SIGNAL chushi_code : STD_LOGIC_VECTOR(15 DOWNTO 0) := "0001001000110100";   --初始密码1234

--存储输入的密码并编译
SIGNAL one_password : std_logic_vector(3 downto 0);

SIGNAL code0,code1,code2,code3 : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0000";

--旧密码和新密码
SIGNAL old_code,new_code : STD_LOGIC_VECTOR(15 DOWNTO 0);

--分频信号定义
signal count_khz : std_logic_vector(17 downto 0);
signal count_hz : std_logic_vector(28 downto 0);
signal khz,hz : std_logic;

--数码管选择输出内容信号
SIGNAL data,data_0 : std_logic_vector(3 downto 0) := "0000";

--数码管循环显示信号
SIGNAL n : std_logic_vector(2 downto 0) := "000";

--状态机,10个状态
TYPE STATES IS(s,s0,s1,s2,s3,suser,sset,sopen,serror,spanduan);
SIGNAL state : STATES;  --给状态机赋初始值

BEGIN

-- //****************************************************************************************************
-- //  模块名称:主函数模块
-- //  功能描述:
-- //****************************************************************************************************
PROCESS(khz,res)
BEGIN
    --复位,赋值初始状态,规定用户没输入密码
    if(res = '0') then    
        state <= s;  --初始设置,设置初始密码为1234
        chushi_code <= "0001001000110100"; 
        old_code <= chushi_code;
--        yes_code <= '0';
--        no_code  <= '0';
        code3 <= chushi_code(15 downto 12);
        code2 <= chushi_code(11 downto 8);
        code1 <= chushi_code(7 downto 4);
        code0 <= chushi_code(3 downto 0); 
        
        led <= "0000";
        Led10 <= "0000000000";
        Ledset <= '0';
        Leduser <= '0';
    elsif Rising_edge(khz) then
    --状态机的状态
    case state is
    
    -- //****************************************************************************************************
    -- //  模块名称:s状态模块
    -- //  功能描述:选择进入哪个模块
    -- //****************************************************************************************************
    when s =>
        led <= "0000";
        Ledset <= '0';
        Leduser <= '0';  
        Led10 <= "0000000000";       
        if (user = '1'and set_code = '0') then  --处于用户状态(只有这个情况才能输入密码)
            code3 <= "1000";
            code2 <= "1000";
            code1 <= "1000";
            code0 <= "1000"; 
            Leduser <= '1';
            state <= suser;          
        else  --其他情况为初始状态
            code3 <= "1000";
            code2 <= "1000";
            code1 <= "1000";
            code0 <= "1000"; 
            state <= s;            
        end if;
                        
    -- //****************************************************************************************************
    -- //  模块名称:用户状态
    -- //  功能描述:输入密码验证密码是否相等
    -- //****************************************************************************************************
    when suser =>
        --输入第一位密码(输入完按一下enter键)
        if(user = '1'and set_code = '0'and enter = '1') then
            led(3) <= '1'; --表示完成第一位密码输入
            code3 <= one_password;
            state <= s0;
        --退出用户状态(即不想输入密码了)
        elsif(user = '0'and set_code = '0') then
            state <= s;            
        end if;
       
    -- //****************************************************************************************************
    -- //  模块名称:改密状态,可以查看密码
    -- //  功能描述:修改原密码
    -- //****************************************************************************************************
    when sset =>
        --输入第一位密码(输入完按一下enter键)
        if(user = '1'and set_code = '1'and enter = '1') then
            led(3) <= '1'; --表示完成第一位密码输入
            new_code(15 downto 12) <= one_password;
            code3 <= one_password;
            state <= s0;
        --退出改密状态(即不想修改密码了)
        elsif(user = '0'and set_code = '0') then
                state <= s;            
        end if;
    
    -- //****************************************************************************************************
    -- //  模块名称:s0状态,输入第二位密码
    -- //  功能描述:
    -- //****************************************************************************************************
    when s0 =>        
        --用户状态下输入第二位密码(输入完按一下enter键)
        if(user = '1'and set_code = '0'and enter = '0'and backc = '1') then
            led(2) <= '1'; --表示完成第二位密码输入
            code2 <= one_password;
            state <= s1;
            
        --改密状态下输入第二位密码(输入完按一下enter键)
        elsif(user = '1'and set_code = '1'and enter = '0'and backc = '1') then
            led(2) <= '1'; --表示完成第二位密码输入
            new_code(11 downto 8) <= one_password;
            code2 <= one_password;
            state <= s1;
            
        --退出用户或改密状态(即不想输入或修改密码了)
        elsif(user = '0'and set_code = '0') then
                Leduser <= '0';
                state <= s; 
        end if;  
    
    -- //****************************************************************************************************
    -- //  模块名称:s1状态,输入第三位密码
    -- //  功能描述:
    -- //****************************************************************************************************
    when s1 =>
        --用户状态下输入第三位密码(输入完按一下enter键)
        if(user = '1'and set_code = '0'and enter = '1') then
            led(1) <= '1'; --表示完成第三位密码输入
            code1 <= one_password;
            state <= s2;
            
        --改密状态下输入第三位密码(输入完按一下enter键)
        elsif(user = '1'and set_code = '1'and enter = '1') then
            led(1) <= '1'; --表示完成第二位密码输入
            new_code(7 downto 4) <= one_password;
            code1 <= one_password;
            state <= s2;
                
        --退出用户或改密状态(即不想输入或修改密码了)
        elsif(user = '0'and set_code = '0') then
                Leduser <= '0';
                state <= s;       
        end if;         
    
    -- //****************************************************************************************************
    -- //  模块名称:s2状态,输入第四位密码
    -- //  功能描述:
    -- //****************************************************************************************************
    when s2 =>
        --输入第四位密码(输入完按一下enter键)
        if(user = '1'and set_code = '0'and enter = '0' and backc = '1') then
            led(0) <= '1'; --表示完成第四位密码输入,密码输入完成
            code0 <= one_password;
            state <= spanduan;
            
        --改密状态下输入第三位密码(输入完按一下enter键)
        elsif(user = '1'and set_code = '1'and enter = '0' and backc = '1') then
            led(0) <= '1'; --表示完成第二位密码输入
            new_code(3 downto 0) <= one_password;
            code0 <= one_password;
            state <= s3;
                
        --退出用户或改密状态(即不想输入或修改密码了)
        elsif(user = '0'and set_code = '0') then
                Leduser <= '0';
                state <= s;           
        end if;      
         
    -- //****************************************************************************************************
    -- //  模块名称:密码修改成功
    -- //  功能描述:
    -- //****************************************************************************************************   
    when s3 =>
        if(enter = '1') then
            old_code <= new_code;  
            state <= s;
        end if;
        
    -- //****************************************************************************************************
    -- //  模块名称:密码正确状态
    -- //  功能描述:
    -- //****************************************************************************************************
    when spanduan =>
        if(code3 = old_code(15 downto 12) and code2 = old_code(11 downto 8)
       and code1 = old_code(7 downto 4) and code0 = old_code(3 downto 0)) then
            state <= sopen; 
        else
            state <= serror;     
        end if;              
        
    -- //****************************************************************************************************
    -- //  模块名称:密码正确状态
    -- //  功能描述:
    -- //****************************************************************************************************
    when sopen =>       
        led <= "1111";
        Led10 <= "1111111111";
        Ledset <= '1';
        Leduser <= '1';        
        if(user = '0'and set_code = '0') then
            Leduser <= '0';
            state <= s; 
       elsif (user = '1'and set_code = '1') then  --处于改密状态(只有这个情况才能修改密码,可查看密码)
                           code3 <= old_code(15 downto 12);
                           code2 <= old_code(11 downto 8);
                           code1 <= old_code(7 downto 4);
                           code0 <= old_code(3 downto 0); 
                           led <= "0000";
                           Led10 <= "0000000000";
                           Leduser <= '0';                      
                           Ledset <= '1';
                           state <= sset; 
        end if;  
               
    -- //****************************************************************************************************
    -- //  模块名称:密码错误状态
    -- //  功能描述:
    -- //****************************************************************************************************
    when serror =>
        if(user = '0'and set_code = '0') then
            Leduser <= '0';
            state <= s; 
        end if;  
              
    -- //****************************************************************************************************
    -- //  模块名称:防止状态机跑飞
    -- //  功能描述:
    -- //****************************************************************************************************
    when others =>
        state <= s;       
    end case;
end if;
end process;
                        
-- //****************************************************************************************************
-- //  模块名称:100MHz时钟分频产生1KHz用于数码管显示
-- //  功能描述:
-- //****************************************************************************************************
process(res,clk)
begin
    if res = '0' then
    khz <= '0'; count_khz <= (others => '0');
    elsif Rising_edge(clk) then
    count_khz <= count_khz + '1';
        if count_khz >= 100000 then
           count_khz <= (others => '0');
        end if;
        if count_khz >= 50000 then
            khz <= '1';
        else
            khz <= '0';
        end if;
    end if;
end process;

-- //****************************************************************************************************
-- //  模块名称:100MHz时钟分频产生1Hz用于计时
-- //  功能描述:
-- //****************************************************************************************************
process(res,clk)
begin
    if res = '0' then
    hz <= '0'; count_hz <= (others => '0');
    elsif Rising_edge(clk) then
    count_hz <= count_hz + '1';
        if count_hz >= 100000000 then
           count_hz <= (others => '0');
        end if;
        if count_hz >= 50000000 then
            hz <= '1';
        else
            hz <= '0';
        end if;
    end if;
end process;

-- //****************************************************************************************************
-- //  模块名称:译码模块
-- //  功能描述:
-- //****************************************************************************************************
PROCESS(clk)             --由password触发的进程,输入译码
BEGIN
    CASE password IS
        WHEN "0000" => one_password <= "0000"; --输入密码为0
        WHEN "0001" => one_password <= "0001"; --输入密码为1
        WHEN "0010" => one_password <= "0010"; --输入密码为2
        WHEN "0011" => one_password <= "0011"; --输入密码为3
        WHEN "0100" => one_password <= "0100"; --输入密码为4
        WHEN "0101" => one_password <= "0101"; --输入密码为5
        WHEN "0110" => one_password <= "0110"; --输入密码为6
        WHEN "0111" => one_password <= "0111"; --输入密码为7
        WHEN "1000" => one_password <= "1000"; --输入密码为8
        WHEN "1001" => one_password <= "1001"; --输入密码为9
        WHEN OTHERS  => one_password <= "0000";
    END CASE;                                                                         
END PROCESS;

-- //****************************************************************************************************
-- //  模块名称:数码管显示内容
-- //  功能描述:
-- //****************************************************************************************************
process (clk)                           --数码管1显示内容                                                       
  Begin
      case data is
           when "0000" => seg7 <= "0111111";              --数码管显示内容为0
           when "0001" => seg7 <= "0000110";              --数码管显示内容为1
           when "0010" => seg7 <= "1011011";              --数码管显示内容为2
           when "0011" => seg7 <= "1001111";              --数码管显示内容为3
           when "0100" => seg7 <= "1100110";              --数码管显示内容为4
           when "0101" => seg7 <= "1101101";              --数码管显示内容为5
           when "0110" => seg7 <= "1111101";              --数码管显示内容为6
           when "0111" => seg7 <= "0000111";              --数码管显示内容为7
           when "1000" => seg7 <= "1111111";              --数码管显示内容为8
           when "1001" => seg7 <= "1101111";              --数码管显示内容为9
           
           when "1010" => seg7 <= "1110110";  --H
           when "1011" => seg7 <= "1111001";  --E
           when "1100" => seg7 <= "0111000";  --L
           when "1101" => seg7 <= "1110111";  --R
           when others  => seg7 <= "0000110";              --数码管显示内容为1
           end case;
   end process;
process (clk)                           --数码管2显示内容                                                       
     Begin
         case data_0 is
              when "0000" => seg7_0 <= "0111111";              --数码管显示内容为0
              when "0001" => seg7_0 <= "0000110";              --数码管显示内容为1
              when "0010" => seg7_0 <= "1011011";              --数码管显示内容为2
              when "0011" => seg7_0 <= "1001111";              --数码管显示内容为3
              when "0100" => seg7_0 <= "1100110";              --数码管显示内容为4
              when "0101" => seg7_0 <= "1101101";              --数码管显示内容为5
              when "0110" => seg7_0 <= "1111101";              --数码管显示内容为6
              when "0111" => seg7_0 <= "0000111";              --数码管显示内容为7
              when "1000" => seg7_0 <= "1111111";              --数码管显示内容为8
              when "1001" => seg7_0 <= "1101111";              --数码管显示内容为9
              
              when "1010" => seg7_0 <= "1110110";  --H
              when "1011" => seg7_0 <= "1111001";  --E
              when "1100" => seg7_0 <= "0111000";  --L
              when "1101" => seg7_0 <= "1110111";  --R
              when others  => seg7_0 <= "0000110";              --数码管显示内容为1
              end case;
      end process;   
-- //****************************************************************************************************
-- //  模块名称:数码管显示模块
-- //  功能描述:
-- //****************************************************************************************************
process(khz)                                                                          --数码管显示模块:固定显示4位密码
begin
if Rising_edge(khz) then
    --密码正确显示
    if(state = sopen) then
        case n is
            when "000" => segselect4 <= "1000"; data <= "1010";          --H         
            when "001" => segselect4 <= "0100"; data <= "1011";          --E          
            when "010" => segselect4 <= "0010"; data <= "1100";          --L       
            when "011" => segselect4 <= "0001"; data <= "1100";          --L
            when "100" => segselect4_0 <= "1000"; data_0 <= "0000";      --O       
            when others => segselect4 <= "0000"; data<="1111";
                           segselect4_0 <= "0000"; data_0<="1111";
        end case;     
        n <= n+1;
        if(n="101") then
            n <= "000";
        end if;       
    
    --密码错误显示 
    elsif(state = serror) then
        case n is
            when "000" => segselect4 <= "1000"; data <= "1011";       --E       
            when "001" => segselect4 <= "0100"; data <= "1101";       --R          
            when "010" => segselect4 <= "0010"; data <= "1101";       --R          
            when "011" => segselect4 <= "0001"; data <= "0000";       --O 
            when "100" => segselect4_0 <= "1000"; data_0 <= "1101";   --R           
            when others => segselect4 <= "0000"; data <= "1111";
                           segselect4_0 <= "0000"; data_0<="1111";
        end case;      
        n <= n+1;
        if(n="101") then
            n <= "000";
        end if; 
    
    else
        case n is
            when "000" => segselect4 <= "1000"; data<=code3;                  
            when "001" => segselect4 <= "0100"; data<=code2;                   
            when "010" => segselect4 <= "0010"; data<=code1;                   
            when "011" => segselect4 <= "0001"; data<=code0;                    
            when others => segselect4 <= "0000"; data<="1111";
                            segselect4_0 <= "0000"; data_0<="1111";
        end case;     
        n <= n+1;
        if(n="100") then
            n <= "000";
        end if;
    end if;
end if;
end process;
end behave;
约束文件:
##/系统时钟和复位
set_property -dict {PACKAGE_PIN P17 IOSTANDARD LVCMOS33} [get_ports clk ]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports res ]

##//管理员等按键///
set_property -dict {PACKAGE_PIN P5 IOSTANDARD LVCMOS33} [get_ports user ]
set_property -dict {PACKAGE_PIN P2 IOSTANDARD LVCMOS33} [get_ports set_code ]
#set_property -dict {PACKAGE_PIN P4 IOSTANDARD LVCMOS33} [get_ports set ]
set_property -dict {PACKAGE_PIN R11 IOSTANDARD LVCMOS33} [get_ports enter ]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports backc ]

##//输入密码开关///
set_property -dict {PACKAGE_PIN R2 IOSTANDARD LVCMOS33} [get_ports {password[0]}]
set_property -dict {PACKAGE_PIN M4 IOSTANDARD LVCMOS33} [get_ports {password[1]}]
set_property -dict {PACKAGE_PIN N4 IOSTANDARD LVCMOS33} [get_ports {password[2]}]
set_property -dict {PACKAGE_PIN R1 IOSTANDARD LVCMOS33} [get_ports {password[3]}]

##//LED0~LED15
set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {led[0]}]
set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {led[1]}]
set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {led[2]}]
set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {led[3]}]
set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {Led10[0]} ]
set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {Led10[1]} ]
set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {Led10[2]} ]
set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {Led10[3]} ]
set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {Led10[4]} ]
set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {Led10[5]} ]
set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33} [get_ports {Led10[6]} ]
set_property -dict {PACKAGE_PIN J5 IOSTANDARD LVCMOS33} [get_ports {Led10[7]} ]
set_property -dict {PACKAGE_PIN K6 IOSTANDARD LVCMOS33} [get_ports {Led10[8]} ]
set_property -dict {PACKAGE_PIN L1 IOSTANDARD LVCMOS33} [get_ports {Led10[9]} ]
set_property -dict {PACKAGE_PIN M1 IOSTANDARD LVCMOS33} [get_ports Leduser ]
set_property -dict {PACKAGE_PIN K3 IOSTANDARD LVCMOS33} [get_ports Ledset ]




#///8个数码管位选信号/
set_property -dict {PACKAGE_PIN G2 IOSTANDARD LVCMOS33} [get_ports {segselect4[3]}]
set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports {segselect4[2]}]
set_property -dict {PACKAGE_PIN C1 IOSTANDARD LVCMOS33} [get_ports {segselect4[1]}]
set_property -dict {PACKAGE_PIN H1 IOSTANDARD LVCMOS33} [get_ports {segselect4[0]}]

set_property -dict {PACKAGE_PIN G1 IOSTANDARD LVCMOS33} [get_ports {segselect4_0[3]}]
set_property -dict {PACKAGE_PIN F1 IOSTANDARD LVCMOS33} [get_ports {segselect4_0[2]}]
set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {segselect4_0[1]}]
set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports {segselect4_0[0]}]

#///数码管段选信号//
set_property -dict {PACKAGE_PIN B4 IOSTANDARD LVCMOS33} [get_ports {seg7[0]}]
set_property -dict {PACKAGE_PIN A4 IOSTANDARD LVCMOS33} [get_ports {seg7[1]}]
set_property -dict {PACKAGE_PIN A3 IOSTANDARD LVCMOS33} [get_ports {seg7[2]}]
set_property -dict {PACKAGE_PIN B1 IOSTANDARD LVCMOS33} [get_ports {seg7[3]}]
set_property -dict {PACKAGE_PIN A1 IOSTANDARD LVCMOS33} [get_ports {seg7[4]}]
set_property -dict {PACKAGE_PIN B3 IOSTANDARD LVCMOS33} [get_ports {seg7[5]}]
set_property -dict {PACKAGE_PIN B2 IOSTANDARD LVCMOS33} [get_ports {seg7[6]}]

set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports {seg7_0[0]}]
set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports {seg7_0[1]}]
set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports {seg7_0[2]}]
set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports {seg7_0[3]}]
set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports {seg7_0[4]}]
set_property -dict {PACKAGE_PIN E2 IOSTANDARD LVCMOS33} [get_ports {seg7_0[5]}]
set_property -dict {PACKAGE_PIN D2 IOSTANDARD LVCMOS33} [get_ports {seg7_0[6]}]

密码正确
在这里插入图片描述
密码错误
在这里插入图片描述

  • 16
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值