fpga - VHDL button debouncing in state machine application -


i'm programming fpga board w/ lattice xp2-5e chip. on board 4 rows , 2 columns of led lights i'm trying control 4 directional push-buttons , 1 reset push-button. instance, if (1st row/1st column) led turned on , if press button right, (1st row/2nd column) led turn on , (1st row/1st column) led turn off.

since there no hardware debouncing circuit implemented, need implement software solution. tick rate 25 mhz , minimal button hold time 25 ms. code shown below:

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all;  entity sklop 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      type state_type (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' , rising_edge(is_ok))             case curs                 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' , rising_edge(is_ok))             case curs                 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' , rising_edge(is_ok))             case curs                 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' , rising_edge(is_ok))             case curs                 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' , rising_edge(is_ok))             nxts <= s0;         end if;      end process;      process(curs)                                   -- output of state machine     begin         case curs             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')             btn_press <= '1';         else             btn_press <= '0';         end if;          if(rising_edge(btn_press))             start_cnt <= '1';         end if;         if(falling_edge(btn_press))             start_cnt <= '1';         end if;          if(rising_edge(clk_25m))             if(counter /= "10111110101111000010000" , start_cnt = '1')                 counter <= counter + '1';                 is_ok <= '0';             elsif(start_cnt = '1' , btn_press = '1')                 is_ok <= '1';                 curs <= nxts;                 start_cnt <= '0';                 counter <= "00000000000000000000000";             end if;         end if;      end process;  end behv; 

sometimes code works intended times there multiple led lights turned on or no led turned on - wonder how can possible - , state doesn't change when pushing button (even when holding button longer 25 ms).

what seems problem. running out of ideas.


Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -