⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elec_lock.vhd

📁 用于模仿密码锁的工作过程。完成密码锁的核心控制功能。可实现数码输入、清除、退位、设置密码、错误提示、系统报警、解除报警、系统关闭等功能。
💻 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)&num;
          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 + -