本设计为一个四位密码锁,复位后的初始密码为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]}]
密码正确
密码错误