我正在使用 Lattice XP2-5E 芯片对 FPGA 板进行编程。板上还有 4 行 2 列 LED 灯,我试图用 4 个方向按钮和一个复位按钮来控制它们。例如,如果(第 1 行/第 1 列)LED 亮起,如果我按下右按钮,(第 1 行/第 2 列)LED 将亮起,(第 1 行/第 1 列)LED 将熄灭。
由于没有实现内置的硬件去抖动电路,我需要实现一个 VHDL 解决方案。滴答频率为 25 MHz,最小按钮保持时间为 25 ms。代码如下所示:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
entity SKLOP is
port ( btn_center : in std_logic;
btn_left : in std_logic;
btn_right : in std_logic;
btn_up : in std_logic;
btn_down : in std_logic;
clk_25m : in std_logic;
led : out std_logic_vector (7 downto 0));
end SKLOP;
architecture behv of SKLOP is
type state_type is (s0, s1, s2, s3, s4, s5, s6, s7);
signal CurS : state_type := s0;
signal NxtS : state_type := s0;
signal counter : std_logic_vector (22 downto 0) := (others => '0');
signal is_ok : std_logic := '0';
signal btn_press : std_logic := '0';
signal start_cnt : std_logic := '0';
begin
process(is_ok) -- state switching
begin
if(btn_left = '1' and rising_edge(is_ok)) then
case CurS is
when s0 =>
NxtS <= s0;
when s1 =>
NxtS <= s1;
when s2 =>
NxtS <= s2;
when s3 =>
NxtS <= s3;
when s4 =>
NxtS <= s0;
when s5 =>
NxtS <= s1;
when s6 =>
NxtS <= s2;
when s7 =>
NxtS <= s3;
end case;
end if;
if(btn_right = '1' and rising_edge(is_ok)) then
case CurS is
when s0 =>
NxtS <= s4;
when s1 =>
NxtS <= s5;
when s2 =>
NxtS <= s6;
when s3 =>
NxtS <= s7;
when s4 =>
NxtS <= s4;
when s5 =>
NxtS <= s5;
when s6 =>
NxtS <= s6;
when s7 =>
NxtS <= s7;
end case;
end if;
if(btn_up = '1' and rising_edge(is_ok)) then
case CurS is
when s0 =>
NxtS <= s0;
when s1 =>
NxtS <= s0;
when s2 =>
NxtS <= s1;
when s3 =>
NxtS <= s2;
when s4 =>
NxtS <= s4;
when s5 =>
NxtS <= s4;
when s6 =>
NxtS <= s5;
when s7 =>
NxtS <= s6;
end case;
end if;
if(btn_down = '1' and rising_edge(is_ok)) then
case CurS is
when s0 =>
NxtS <= s1;
when s1 =>
NxtS <= s2;
when s2 =>
NxtS <= s3;
when s3 =>
NxtS <= s3;
when s4 =>
NxtS <= s5;
when s5 =>
NxtS <= s6;
when s6 =>
NxtS <= s7;
when s7 =>
NxtS <= s7;
end case;
end if;
if(btn_center = '1' and rising_edge(is_ok)) then
NxtS <= s0;
end if;
end process;
process(CurS) -- output of state machine
begin
case CurS is
when s0 =>
led <= "10000000";
when s1 =>
led <= "01000000";
when s2 =>
led <= "00100000";
when s3 =>
led <= "00010000";
when s4 =>
led <= "00001000";
when s5 =>
led <= "00000100";
when s6 =>
led <= "00000010";
when s7 =>
led <= "00000001";
end case;
end process;
process(clk_25m) -- debouncing
begin
if(btn_center = '1' or btn_right = '1' or btn_left = '1' or btn_up = '1' or btn_down = '1') then
btn_press <= '1';
else
btn_press <= '0';
end if;
if(rising_edge(btn_press)) then
start_cnt <= '1';
end if;
if(falling_edge(btn_press)) then
start_cnt <= '1';
end if;
if(rising_edge(clk_25m)) then
if(counter /= "10111110101111000010000" and start_cnt = '1') then
counter <= counter + '1';
is_ok <= '0';
elsif(start_cnt = '1' and btn_press = '1') then
is_ok <= '1';
CurS <= NxtS;
start_cnt <= '0';
counter <= "00000000000000000000000";
end if;
end if;
end process;
end behv;
有时代码会按预期工作,但通常会打开多个 LED 灯或没有打开 LED - 我想知道这怎么可能 - 有时按下按钮时状态不会改变(即使按住按钮超过 25 毫秒)。
似乎是什么问题。我的想法不多了。