📄 elec_lock.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library altera;
use altera.maxplus2.all;
entity elec_lock is
port(
clk_4M:in std_logic;
col:in std_logic_vector(3 downto 0);
f_keyboard:out std_logic_vector(1 downto 0);
f_scan:out std_logic_vector(3 downto 0);
enlock:out std_logic;
s_alert:out std_logic;
s_state:out std_logic;
BCD_code:out std_logic_vector(15 downto 0);
LED_wrong:out std_logic_vector(3 downto 0);
flag_no:out std_logic;
f1:out std_logic_vector(3 downto 0);
f2:out std_logic_vector(3 downto 0);
LED_seg:out std_logic_vector(6 downto 0));
end elec_lock;
--信号f_keyboard,s_state,BCD_code,flag_no,f1,f2用于波形仿真时验证系统功能
--实际应用时可去除。
architecture behavior of elec_lock is
component debouncing
port(
clk:in std_logic;
d_in:in std_logic;
d_out:out std_logic);
end component;
signal clk:std_logic;
signal fkeyboard:std_logic_vector(1 downto 0);
signal fdisplay:std_logic_vector(1 downto 0);
signal fscan:std_logic_vector(3 downto 0);
signal f1hz:std_logic;
signal key_in:std_logic_vector(3 downto 0);
signal num:std_logic_vector(3 downto 0);
signal ff1:std_logic_vector(3 downto 0);
signal ff2:std_logic_vector(3 downto 0);
signal key_pressed:std_logic;
signal flag_num:std_logic;
signal flag:std_logic;
signal in_code:std_logic_vector(15 downto 0);
signal code:std_logic_vector(15 downto 0);
signal db:std_logic_vector(3 downto 0);
signal n:integer range 0 to 4;
signal num_wrong:integer range 0 to 3;
signal state:std_logic;
signal alert:std_logic;
signal clear:std_logic;
signal set_code:std_logic;
signal o_lock:std_logic;
signal q1,q2:std_logic;
signal LEDseg:std_logic_vector(6 downto 0);
begin
s_state<=state;
s_alert<=alert;
flag_no<=flag_num;
BCD_code<=in_code;
f1<=ff1;
f2<=ff2;
f_keyboard<=fkeyboard;
f_scan<=fscan;
LED_seg<=LEDseg;
count:block
signal Q:std_logic_vector(21 downto 0);
begin
process(clk_4M)
begin
if clk_4M'event and clk_4M='1' then
Q<=Q+1;
end if;
end process;
clk<=Q(0);
f1hz<=Q(2); --for testing
--f1hz=Q(21); --for reality
fkeyboard<=Q(5 downto 4);
fdisplay<=Q(5 downto 4);
end block;
key_scan:block
signal row:std_logic_vector(3 downto 0);
begin
row<="1110" when fkeyboard=0 else
"1101" when fkeyboard=1 else
"1011" when fkeyboard=2 else
"0111" ;
fscan<=row;
end block;
debounced:block
begin
u1:debouncing port map(d_in=>col(0),d_out=>key_in(0),clk=>clk);
u2:debouncing port map(d_in=>col(1),d_out=>key_in(1),clk=>clk);
u3:debouncing port map(d_in=>col(2),d_out=>key_in(2),clk=>clk);
u4:debouncing port map(d_in=>col(3),d_out=>key_in(3),clk=>clk);
end block;
key_decoder:block
signal y:std_logic_vector(5 downto 0);
signal c0,c1:std_logic;
begin
process(clk)
begin
y<=fkeyboard&key_in;
if clk'event and clk='1' then
case y is
when "101011"=>num<="0000";
when "000111"=>num<="0001";
when "001011"=>num<="0010";
when "001101"=>num<="0011";
when "001110"=>num<="0100";
when "010111"=>num<="0101";
when "011011"=>num<="0110";
when "011101"=>num<="0111";
when "011110"=>num<="1000";
when "100111"=>num<="1001";
when others=>num<="1111";
end case;
end if;
if clk'event and clk='1' then
case y is
when "101101"=>ff1<="0001";
when "101110"=>ff1<="0010";
when "110111"=>ff1<="0100";
when others=>ff1<="1000";
end case;
end if;
if clk'event and clk='1' then
case y is
when "111011"=>ff2<="0001";
when "111101"=>ff2<="0010";
when "111110"=>ff2<="0100";
when others=>ff2<="1000";
end case;
end if;
end process;
flag_num<=not(num(3) and num(2) and num(1) and num(0));
flag<=flag_num or ff2(0);
key_pressed<=not(num(0) and num(1) and num(2) and num(3) and ff1(3) and ff2(3));
process(clk)
begin
if clk'event and clk='1' then
c1<=c0;
c0<=ff2(2);
end if;
end process;
clear<=c1 and not c0;
end block;
func_select:block
begin
process(clk)
begin
if clk'event and clk='1' then
if ff1(1)='1' then
set_code<='1';
o_lock<='0';
elsif ff1(2)='1' then
set_code<='0';
o_lock<='1';
end if;
end if;
end process;
end block;
storage:block
begin
process(flag)
begin
if ff2(1)='1' or ff1(1)='1' or ff1(2)='1' or clear='1' then
in_code<=(others=>'1');
n<=0;
elsif flag'event and flag='1' then
if n<4 and ff2(0)='0' then
in_code<=in_code(11 downto 0)#
n<=n+1;
elsif ff2(0)='1' then
in_code<="1111"&in_code(15 downto 4);
if n>0 then
n<=n-1;
end if;
end if;
end if;
end process;
end block;
key_func:block
signal set_new:std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
if state='1' then
if n=4 then
if set_code='1' and ff2(2)='1' then
code<=in_code;
q1<='1';
q2<='0';
set_new<='1';
elsif o_lock='1' and ff2(2)='1' and alert='0'then
if set_new='0' then
if in_code="0001001000110100" then
q1<='0';
q2<='1';
else
if num_wrong<3 then
LED_wrong(num_wrong)<='1';
num_wrong<=num_wrong+1;
else
num_wrong<=3;
end if;
end if;
else
if code=in_code then
q1<='0';
q2<='1';
else
if num_wrong<3 then
LED_wrong(num_wrong)<='1';
num_wrong<=num_wrong+1;
else
num_wrong<=3;
end if;
end if;
end if;
end if;
end if;
elsif state='0' then
q1<='1';
q2<='0';
num_wrong<=0;
LED_wrong<="0000";
end if;
end if;
if num_wrong=3 then
alert<='1';
else alert<='0';
end if;
end process;
enlock<=q1 and not q2;
--BCD_code<=in_code;
end block;
set_state:block
signal counter:integer range 0 to 60;
signal s_flag:std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
s_flag<=(not q1 and q2 and ff2(2)) or ff1(0);
if s_flag='1' then
state<='0';
elsif ff1(1)='1' or ff1(2)='1' then
state<='1';
elsif counter=60 then
state<='0';
end if;
end if;
end process;
process(key_pressed,f1hz)
begin
if key_pressed='1' then
counter<=0;
elsif f1hz'event and f1hz='1' then
if counter<60 then
counter<=counter+1;
else counter<=60;
end if;
end if;
end process;
end block;
display:block
begin
db<=in_code(15 downto 12) when fdisplay=0 else
in_code(11 downto 8) when fdisplay=1 else
in_code(7 downto 4) when fdisplay=2 else
in_code(3 downto 0);
end block;
seven_segment:block
begin
LEDseg<="0111111" when db=0 else
"0000110" when db=1 else
"1011011" when db=2 else
"1001111" when db=3 else
"1100110" when db=4 else
"1101101" when db=5 else
"1111101" when db=6 else
"0000111" when db=7 else
"1111111" when db=8 else
"1101111" when db=9 else
"0000000";
end block;
end behavior;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -