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

1111. appearing after print sequence - php -

java - WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/board/] in DispatcherServlet with name 'appServlet' -

Ruby on Rails, ActiveRecord, Postgres, UTF-8 and ASCII-8BIT encodings -