VHDL button debouncing in state machine application - vhdl

I'm programming an FPGA board w/ Lattice XP2-5E chip. On board are also 4 rows and 2 columns of LED lights which I'm trying to control with 4 directional push-buttons and one reset push-button. For instance, if (1st row/1st column) LED is turned on and if I press button right, (1st row/2nd column) LED would turn on and (1st row/1st column) LED would turn off.
Since there is no built-in hardware debouncing circuit implemented, I need to implement a VHDL solution. Tick rate is 25 MHz and minimal button hold time is 25 ms. Code is shown below:
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;
Sometimes the code works as intended but often times there are multiple LED lights turned on or no LED are turned on - I wonder how can this be even possible - and sometimes the state doesn't change when pushing a button (even when holding a button for much longer than 25 ms).
What seems to be the problem. I am running out of ideas.

Related

Can't find the issues and latches are generated

My code generates two latches, could please someone help me finding why?
According to Xilinx ISE latches are generated because of "try_counter" which is a counter for how many times you get a numeric sequence wrong. (which is the main point of my code).
I don't know what else to do.
entity moore is
Port ( badgeSx : in STD_LOGIC;
badgeDx : in STD_LOGIC;
col : in std_logic_vector (1 to 3);
row : in std_logic_vector (1 to 4);
clk : in std_logic;
rst : in std_logic;
unlock : out STD_LOGIC
);
end moore;
architecture Behavioral of moore is
type stato is (s0, s1, s2, s3, s4, s5, s6, s7, s8, s9);
signal current_state,next_state : stato;
signal badge : std_logic_vector(1 downto 0);
signal count, new_count: integer range 0 to 28;
signal temp_unlock : std_logic :='0';
signal timeover : std_logic :='0';
begin
badge <= badgeDx & badgeSx; --concatenazione dei badge
--processo sequenziale
current_state_register: process(clk)
begin
if rising_edge(clk) then
if (rst = '1') then
current_state <= s0;
count <= 0;
else
current_state <= next_state;
count <= new_count;
end if;
end if;
end process;
process (current_state,badge,col,row,timeover)
variable try_counter: integer range 0 to 3;
begin
case current_state is
when s0 =>
try_counter := 0;
temp_unlock <= '0';
unlock <='0';
if(badge ="01" and row = "0000" and col = "000" ) then
next_state <= s1;
else
next_state <= s0;
end if;
when s1 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s2 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s2;
else
next_state <= s3;
end if;
when s3 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s4 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s4;
else
next_state <= s5;
end if;
when s5 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s6 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s6;
else
next_state <= s7;
end if;
when s7 =>
temp_unlock <= '1';
unlock <= '0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
elsif (timeover ='1' or badge = "10" or try_counter = 3) then
next_state <= s0;
else
next_state <= s1;
try_counter := try_counter +1;
end if;
when s8 =>
temp_unlock <= '0';
unlock <='0';
if (badge = "00" and col ="001" and row = "0001" and timeover = '0') then
next_state <= s8;
else
next_state <= s9;
end if;
when s9 =>
temp_unlock <= '0';
unlock <= '1';
if (badge = "10") then
next_state <= s0;
else
next_state <= s5;
end if;
when others =>
next_state <= s0;
end case;
end process;
Contatore_TIMER : process(temp_unlock,count)
begin
if temp_unlock = '1' then
if count = 28 then
new_count<=0;
timeover<='1';
else
new_count<=count+1;
timeover<='0';
end if;
else
new_count<=0;
timeover <= '0';
end if;
end process;
end Behavioral;
The code nearly works as expected (I mean it compiles and I don't get any error) but the RTL schematic isn't what it is supposed to be since it synthesises latches in the process.
In the apparently combinatorial process with process (current_state,badge,col,row,timeover), the variable try_counter is used to store information (sequential behaviour), which is only updated when process evaluation is triggered. This will very likely to generate the 2 latches, which matches the value range from 0 to 3 for try_counter.
To fix this, you can define try_counter as a signal, and include it in the sensitivity list for the process.
Having try_counter as a signal will also ease debugging, since the current state can easily be inspected in waveforms.

De-bounced button press resulting in successive state transitions

I am programming an FPGA that uses push buttons as input signals. It has a finite state machine with 11 states that transition from state to state using specific button presses.
For example, in my design, state s0 goes to state s1 using a button press. This is the same transition case from state s1 to s2 and from state s2 to s3. This state transition system is implemented in my VHDL code using case statements.
LEDs light up in each state to keep track of which state the board is currently in.
My issue is that when my_btnL = '1' is true while in state s0, the board shows that it has moved to state s3.
What I think is happening is that it is indeed going to state s1 and s2 but the same button press in state s0 is also being read in state s1 and s2. This happens so fast that the boards doesn't have enough time to show the LED indications for state s1 and s2. It stops at state s3 because state s3 moves to state s4 using a different button.
So my question is how do I make the button press signal have a rising edge and a falling edge such that a single button press is read only in one state and not the ones that follow it?
The press button signals are de-bounced but this only makes the signal a uniform square wave.
In the following code btnC, btnL, btnR,... are the push buttons:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
entity digital_lock is
Port (
my_btnC, clk, my_btnU, my_btnR, my_btnL, my_btnD: in std_logic;
my_sw: in std_logic_vector(3 downto 0);
hex0, hex1, hex2, hex3: out std_logic_vector (3 downto 0);
my_led: out std_logic_vector(15 downto 0)
);
end digital_lock;
architecture Behavioral of digital_lock is
type state IS (s0, s1, s2, s3, s4 ,s5 ,s6, s7, s8, s9, s10,s11);
signal my_state: state;
signal my_status: unsigned(1 downto 0);
signal num1, num2, num3, key1, key2, key3: std_logic_vector(3 downto 0);
signal number, final_key: std_logic_vector(11 downto 0);
begin
FSM: process(clk, my_btnC)
begin
if(my_btnC ='1') then
my_state <= s0;
elsif rising_edge(clk) then
case my_state is
when s0 =>
my_status <= "00";
my_led <= "1100000000000000";
hex3 <= "0000";
hex2 <= "0000";
hex1 <= "0000";
hex0 <= "0000";
if(my_btnL ='1') then
my_state <= s1;
else
my_state <= s0;
end if;
when s1 =>
key1 <= my_sw;
hex0 <= key1;
my_led <= "0000000000000001";
if(my_btnL='1') then
my_state <= s2;
else
my_state <= s1;
end if;
when s2 =>
key2 <= my_sw;
hex0 <= key2;
my_led <= "0000000000000010";
if(my_btnL ='1') then
my_state <= s3;
else
my_state <= s2;
end if;
when s3 =>
key3 <= my_sw;
hex0 <= key3;
my_led <= "0000000000000011";
if(my_btnR= '1') then
my_state <= s4;
else
my_state <= s3;
end if;
when s4 =>
final_key(11 downto 8) <= key1;
final_key(7 downto 4) <= key2;
final_key(3 downto 0) <= key3;
my_led <= "0000000000000100";
if(my_btnU ='1') then
my_state <= s5;
else
my_state <= s4;
end if;
when s5 =>
num1 <= my_sw;
hex0 <= num1;
my_led <= "0000000000000101";
if(my_btnD ='1') then
my_state <= s0;
elsif (my_btnL ='1') then
my_state <= s6;
else
my_state <= s5;
end if;
when s6 =>
num2 <= my_sw;
hex0 <= num2;
my_led <= "0000000000000110";
if(my_btnD ='1') then
my_state <= s0;
elsif(my_btnL ='1') then
my_state <= s7;
else
my_state <= s6;
end if;
when s7 =>
num3 <= my_sw;
hex0 <= num3;
my_led <= "0000000000000111";
if(my_btnD ='1') then
my_state <= s0;
elsif(my_btnR = '1') then
my_state <= s8;
else
my_state <= s7;
end if;
when s8 =>
number(11 downto 8) <= num1;
number(7 downto 4) <= num2;
number(3 downto 0) <= num3;
my_led <= "0000000000001000";
if(number = final_key) then
my_state <= s9;
else
my_state <= s10;
end if;
when s9 =>
my_led <= "1111111111111111";
if(my_btnD = '1') then
my_state <= s0;
else
my_state <= s9;
end if;
when s10 =>
my_status <= my_status + 1;
if(my_status >= 3) then
my_state <= s11;
elsif(my_status < 3) then
my_state <= s5;
end if;
when s11 =>
my_led <= "0000000000000000";
hex0 <= "1111";
hex1 <= "1111";
hex2 <= "1111";
hex3 <= "1111";
my_state <= s11;
end case;
end if;
end process;
end Behavioral;
An edge detector for a de-bounced signal in the same clock domain as the state machine can be done with a flip flop with the signal input and a gate to detect the preferred state on the input (following the input edge) while the flip flop is in the other state.
signal my_btnL_event: std_logic;
signal my_btnLd: std_logic; -- architecture declarative items
process (clk)
begin
if rising_edge(clk) then
my_btnLd <= my_btnL;
end if;
my_btnL_event <= my_btnL and not my_btnLd;
Where you'd use my_btnL_event in place of my_btnL for transitioning between states.
Note this would require my_btnL to go invaid before going valid again assuming adequate de-bounce.
The my_btnL_event assignment could be expressed in multiple ways, such as an by an if statement or a conditional signal assignment.

3-bit finite state machine in VHDL

entity project4 is
Port ( clk : in STD_LOGIC;
reset : in STD_LOGIC;
x : in STD_LOGIC_VECTOR (1 downto 0);
myoutputs : out STD_LOGIC_VECTOR (2 downto 0));
end project4;
architecture Behavioral of project4 is
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
signal state: state_type;
begin
process1: process(clk,reset)
begin
if (reset ='0') THEN state <= s0;
myoutputs <= "000";
ELSE IF (clk'EVENT AND clk='1') THEN
case state is
when s0 =>
if (x="00") THEN
state <= s1;
myoutputs <= "001";
ELSE IF (x="01") THEN
state <= s7;
myoutputs <= "111";
ELSE IF (x="10") THEN
state <= s2;
myoutputs <= "010";
ELSE
state <=s4;
myoutputs <= "100";
END IF;
when s1 =>
if (x="00") THEN
state <= s2;
myoutputs <="010";
ELSE IF (x ="01") THEN
state <= s0;
myoutputs <= "000";
ELSE IF (x ="10") THEN
state <=s0;
myoutputs <= "000";
ELSE
state <= s0;
myoutputs <="000";
END IF;
when s2 =>
if (x="00") THEN
state <= s3;
myoutputs <="011";
ELSE IF (x="01") THEN
state <= s1;
myoutputs <="001";
ELSE IF (x="10") THEN
state <=s5;
myoutputs <="110";
ELSE
state <=s3;
myoutputs <="011";
END IF;
when s3 =>
if (x="00") THEN
state <=s4;
myoutputs <="100";
ELSE IF (x="01") THEN
state <= s2;
myoutputs <="010";
ELSE IF (x="10") THEN
state <= s1;
myoutputs <= "001";
ELSE
state <=s1;
myoutputs <= "001";
END IF;
when s4 =>
if (x="00") THEN
state <=s5;
myoutputs <="101";
ELSE IF (x="01") THEN
state <= s3;
myoutputs <="011";
ELSE IF (x="10") THEN
state <= s5;
myoutputs <="101";
ELSE
state <= s5;
myoutputs <="101";
END IF;
when s5 =>
if (x="00") THEN
state <= s6;
myoutputs <="110";
ELSE IF (x="01") THEN
state <= s4;
myoutputs <= "100";
ELSE IF (x="10") THEN
state <= s7;
myoutputs <= "111";
ELSE
state <= s7;
myoutputs <= "111";
END IF;
when s6 =>
if (x="00") THEN
state <= s7;
myoutputs <= "111";
ELSE IF (x="01") THEN
state <= s5;
myoutputs <="101";
ELSE IF (x="10") THEN
state <= s4;
myoutputs <="100";
ELSE
state <= s2;
myoutputs <="010";
END IF;
when s7 =>
if (x="00") THEN
state <= s0;
myoutputs <="000";
ELSE IF (x="01") THEN
state <= s6;
myoutputs <="110";
ELSE IF (x="10") THEN
state <= s3;
myoutputs <="011";
ELSE
state <= s6;
myoutputs <= "110";
END IF;
end case;
end process process1;
process2: process(state)
begin
case state is
when s0 => myoutputs <= "000";
when s1 => myoutputs <= "001";
when s2 => myoutputs <= "010";
when s3 => myoutputs <= "011";
when s4 => myoutputs <= "100";
when s5 => myoutputs <= "101";
when s6 => myoutputs <= "110";
when s7 => myoutputs <= "111";
end case;
end process process2;
end Behavioral;
Here's entire code.
Can someone tell me what causes the error? I'm just not getting it.
(Syntax error near "when".)
Use elsif not else if
Constructing a Minimal, Complete, and Verifiable example from your linked code by adding a context clause:
library ieee;
use ieee.std_logic_1164.all;
entity project4 is
port (
clk: in std_logic;
reset: in std_logic;
x: in std_logic_vector (1 downto 0);
myoutputs: out std_logic_vector (2 downto 0)
);
end entity project4;
architecture behavioral of project4 is
type state_type is (s0,s1,s2,s3,s4,s5,s6,s7);
signal state: state_type;
begin
process1:
process (clk, reset)
begin
if reset ='0' then
state <= s0;
myoutputs <= "000";
else if clk'event and clk='1' then
case state is
when s0 =>
if x = "00" then
state <= s1;
myoutputs <= "001";
else if x = "01" then
state <= s7;
myoutputs <= "111";
else if x = "10" then
state <= s2;
myoutputs <= "010";
else
state <= s4;
myoutputs <= "100";
end if;
when s1 =>
if x = "00" then
state <= s2;
myoutputs <= "010";
else if
x = "01" then
state <= s0;
myoutputs <= "000";
else if x = "10" then
state <= s0;
myoutputs <= "000";
else
state <= s0;
myoutputs <= "000";
end if;
when s2 =>
if x = "00" then
state <= s3;
myoutputs <= "011";
else if x = "01" then
state <= s1;
myoutputs <= "001";
else if x = "10" then
state <= s5;
myoutputs <= "110";
else
state <= s3;
myoutputs <= "011";
end if;
when s3 =>
if x = "00" then
state <= s4;
myoutputs <= "100";
else if x = "01" then
state <= s2;
myoutputs <= "010";
else if x = "10" then
state <= s1;
myoutputs <= "001";
else
state <= s1;
myoutputs <= "001";
end if;
when s4 =>
if x = "00" then
state <= s5;
myoutputs <= "101";
else if x = "01" then
state <= s3;
myoutputs <= "011";
else if x = "10" then
state <= s5;
myoutputs <= "101";
else
state <= s5;
myoutputs <= "101";
end if;
when s5 =>
if x = "00" then
state <= s6;
myoutputs <= "110";
else if x = "01" then
state <= s4;
myoutputs <= "100";
else if x = "10" then
state <= s7;
myoutputs <= "111";
else
state <= s7;
myoutputs <= "111";
end if;
when s6 =>
if x = "00" then
state <= s7;
myoutputs <= "111";
else if x = "01" then
state <= s5;
myoutputs <= "101";
else if x = "10" then
state <= s4;
myoutputs <= "100";
else
state <= s2;
myoutputs <= "010";
end if;
when s7 =>
if x = "00" then
state <= s0;
myoutputs <= "000";
else if x = "01" then
state <= s6;
myoutputs <= "110";
else if x = "10" then
state <= s3;
myoutputs <= "011";
else
state <= s6;
myoutputs <= "110";
end if;
end case;
end process process1;
process2:
process(state)
begin
case state is
when s0 => myoutputs <= "000";
when s1 => myoutputs <= "001";
when s2 => myoutputs <= "010";
when s3 => myoutputs <= "011";
when s4 => myoutputs <= "100";
when s5 => myoutputs <= "101";
when s6 => myoutputs <= "110";
when s7 => myoutputs <= "111";
end case;
end process process2;
end behavioral;
And using a couple of different VHDL tools:
ghdl -a project4.vhdl
project4.vhdl:39:13: 'end' is expected instead of 'when'
ghdl: compilation error
and
nvc -a project4.vhdl
** Error: unexpected when while parsing if statement, expecting end
File project4.vhdl, Line 39
when s1 =>
^^^^
** Error: unexpected when while parsing if statement, expecting end
File project4.vhdl, Line 55
when s2 =>
^^^^
** Error: unexpected when while parsing if statement, expecting end
File project4.vhdl, Line 70
when s3 =>
^^^^
>...
explains what the problem is. You're using else if instead of elsif which results in the wrong number of end statements (end if;).
Fixing those 17 instances of else if and we find you left out the end if for the first if statement:
ghdl -a project4.vhdl
project4.vhdl:146:9: 'if' is expected instead of 'process'
ghdl: compilation error
Adding that right before the end process:
end if; -- added
end process process1;
and your design analyzes.
Whether or not your code is functional is left to you.
(Okay, there's another problem you drive myoutputs from two processes which will cause Xs, you should remove the second process. Each process that assigns a signal has a driver for that signal, and std_logic is a resolved type, meaning the two drivers values will presented to a resolution function, which for package std_logic_1164 will result in Xs for conflicting values on the two drivers.)
So there were 18 syntax errors, plus the code isn't functional, myoutputs having driver conflicts.
I removed superfluous parentheses and added spaces and indentation for readability.
So adding a small testbench:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity project4_tb is
end entity;
architecture foo of project4_tb is
signal clk: std_logic := '0';
signal reset: std_logic;
signal x: std_logic_vector (1 downto 0);
signal myoutputs: std_logic_vector (2 downto 0);
begin
DUT:
entity work.project4
port map (
clk => clk,
reset => reset,
x => x,
myoutputs => myoutputs
);
CLOCK:
process
begin
wait for 5 ns;
clk <= not clk;
if now > 360 ns then
wait;
end if;
end process;
STIMULI:
process
begin
wait for 6 ns;
reset <= '0';
wait for 10 ns;
reset <= '1';
for i in 0 to 3 loop
x <= std_logic_vector(to_unsigned(i,x'length));
wait for 80 ns;
end loop;
wait;
end process;
end architecture;
We can see what your design does in simulation:

Traffic VHDL simulation issues

I have updated the program, it does finish but now I am trying simulate the project. I am able to get the clock clear and lights on the pins, but I am not able to get the lights to work and count and states are not even showing. I believe I have this all set correctly but I could be wrong. Thank you once again Morten Zilmer for the help with the Error code.
http://tinypic.com/r/24yog0z/8
This is the simulation of the file,
entity traffic is
port (clk: in std_logic;
clr: in std_logic;
lights: out std_logic_vector (5 downto 0));
end traffic;
architecture traffic of traffic is
type state_type is (s0, s1, s2, s3, s4, s5);
signal state: state_type;
signal count : std_logic_vector (3 downto 0);
constant sec5: std_logic_vector (3 downto 0) := "1111";
constant sec1: std_logic_vector (3 downto 0) := "0011";
begin
process(clk, clr)
begin
if clr = '1' then
state<= s0;
count <= x"0";
elsif (clk'event and clk = '1') then
case state is
when s0 =>
if count <= sec5 then
state <= s0;
count <= count +1;
else
state <= s1;
count <= x"0";
end if;
when s1 =>
if count <= sec1 then
state <= s1;
count <= count +1;
else
state <= s2;
count <= x"0";
end if;
when s2 =>
if count <= sec1 then
state <= s2;
count <= count +1;
else
state <= s3;
count <= x"0";
end if;
when s3 =>
if count <= sec5 then
state <= s3;
count <= count +1;
else
state <= s4;
count <= x"0";
end if;
when s4 =>
if count <= sec1 then
state <= s4;
count <= count +1;
else
state <= s5;
count <= x"0";
end if;
when s5 =>
if count <= sec1 then
state <= s5;
count <= count +1;
else
state <= s0;
count <= x"0";
end if;
when others =>
state <= s0;
end case;
end if;
end process;
c2 : process (state)
begin
case state is
when s0 => lights <= "100001";
when s1 => lights <= "100010";
when s2 => lights <= "100100";
when s3 => lights <= "001100";
when s4 => lights <= "010100";
when s5 => lights <= "100100";
when others => lights <= "100001";
end case;
end process;
end traffic;
Change elseif to elsif, for valid VHDL syntax.

VHDL keypad code issues

I have a 4x3 keypad, i wrote this FSM for interfacing it with my Nexys2 board, trouble I am having here is
When I run the code, the LEDs glow without any key pressed, it shows random combinations automatically
When I press a key it shows that particular combination then goes on to the next condition of ROW without any key pressed. And sometimes it does not even respond if i press a key.
What is happening? What is wrong with this code? I am clueless. Can someone point out the mistakes and suggest some solution? Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity keypad_3x4 is
Port ( CLK : in STD_LOGIC;
RESET : in STD_LOGIC;
ROW : in STD_LOGIC_VECTOR (3 downto 0);
COL : out STD_LOGIC_VECTOR (2 downto 0);
LED : out STD_LOGIC_VECTOR (3 downto 0)
);
end keypad_3x4;
architecture Behavioral of keypad_3x4 is
architecture Behavioral of keypad_3x4 is
TYPE STATE_TYPE is
( RESET_ST,
S1,
S2,
S3,
S4,
S5,
S6
);
signal state: STATE_TYPE;
begin
process (CLK, RESET)
begin
if (RESET = '1') then
state <= RESET_ST;
elsif (CLK'event and CLK = '1') then
case (state) is
WHEN RESET_ST =>
LED <= (others => '0');
COL <= (others => '0');
state <= S1;
WHEN S1 =>
COL <= "001"; --C1 selected
LED <= (others => '0');
state <= S2;
WHEN S2 =>
if ROW <= "0001" then
led <= "0001"; --1
elsif ROW <= "0010" then
led <= "0100"; --4
elsif ROW <= "0100" then
led <= "0111"; --7
elsif ROW <= "1000" then
led <= "1111"; --*
else
LED <= (others => '0');
state <= S3;
end if;
WHEN S3 =>
COL <= "010"; --C2 selected
LED <= (others => '0');
state <= S4;
WHEN S4 =>
if ROW <= "0001" then
led <= "0010"; --2
elsif ROW <= "0010" then
led <= "0101"; --5
elsif ROW <= "0100" then
led <= "1000"; --8
elsif ROW <= "1000" then
led <= "0000"; --0
else
LED <= (others => '0');
state <= S5;
end if;
WHEN S5 =>
COL <= "100"; --C3 selected
LED <= (others => '0');
state <= S6;
WHEN S6 =>
if ROW <= "0001" then
led <= "0011"; --3
elsif ROW <= "0010" then
led <= "0110"; --6
elsif ROW <= "0100" then
led <= "1001"; --9
elsif ROW <= "1000" then
led <= "1111"; --#
else
LED <= (others => '0');
state <= RESET_ST;
end if;
WHEN others =>
state <= RESET_ST;
END case;
END if;
END process;
end Behavioral;

Resources