Interfacing HEX keypad with FPGA to display output on seven segment display

Status
Not open for further replies.

emmagood

Member level 4
Joined
Feb 13, 2010
Messages
74
Helped
3
Reputation
6
Reaction score
1
Trophy points
1,288
Visit site
Activity points
1,849
Hi there,

I am trying to interface a HEX keypad with to display the key pressed on seven segment display. I am new to HEX keypads. I have read some theory about HEX keypads. But I am unable to make the decoder. Can anyone pls provide a sample code for it in VHDL (I am OK with seven segment displays).

Thanks.

Emma Good.
 

Using google turns up many

What specific problems are you having? why not post the code that doesnt work?
 

Well I also tried to google for a sample code and got several codes. But I was unable to understand them. The lab PC is isolated (does not have internet / open USB ports). Hence not able to post the code here.
 

Using google turns up many

What specific problems are you having? why not post the code that doesnt work?

ok...I have typed the code and sketched the keypad diagram. The problem is that the seven seg display is getting stuck at 0 just after programming and not taking any other value from the keypad.

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity hex_kp is
    Port ( clk : in  STD_LOGIC;
           row : out  STD_LOGIC_VECTOR (3 downto 0);
           coloumn : in  STD_LOGIC_VECTOR (3 downto 0);
           sevenseg : out  STD_LOGIC_VECTOR (7 downto 0);
           ca : out  STD_LOGIC);
end hex_kp;

architecture Behavioral of hex_kp is

begin

process(clk)

begin
 ca <='1'; -- to enable a seven segment element 
 
 if(clk'event and clk = '1') then
 
  row <= "0111"; 
	 if(coloumn = "0111") then sevenseg <= "00000110" after 10ms;
    elsif (coloumn = "1011") then sevenseg <= "01011011" after 10ms;
	 elsif (coloumn = "1101") then sevenseg <= "01001111" after 10ms;
	 elsif (coloumn = "1110") then sevenseg <= "01110001" after 10ms;
	 end if;
	 
 row <= "1011";
    if(coloumn = "0111") then sevenseg <= "01100110" after 10ms;
    elsif (coloumn = "1011") then sevenseg <= "01101101" after 10ms;
	 elsif (coloumn = "1101") then sevenseg <= "01111101" after 10ms;
	 elsif (coloumn = "1110") then sevenseg <= "01111001" after 10ms;
    end if;
	 
 row <= "1101"; 
	 if(coloumn = "0111") then sevenseg <= "00000111" after 10ms;
    elsif (coloumn = "1011") then sevenseg <= "01111111" after 10ms;
	 elsif (coloumn = "1101") then sevenseg <= "01101111" after 10ms;
	 elsif (coloumn = "1110") then sevenseg <= "01011110" after 10ms;
	 end if;
	 
 row <= "1110";
    if(coloumn = "0111") then sevenseg <= "00111111" after 10ms;
    elsif (coloumn = "1011") then sevenseg <= "01110111" after 10ms;
	 elsif (coloumn = "1101") then sevenseg <= "01111101" after 10ms;
	 elsif (coloumn = "1110") then sevenseg <= "01011110" after 10ms;
    end if;
	 
 end if;
	 
 
end process;


end Behavioral;

 
Last edited:

emmagood,

Not entirely sure what you expect your code to do, but you're assigning row multiple times each clock cycle.

Only the last assignment will "take" as all you are doing is rescheduling assignments.

If the simulation says there are delays that is because you are writing nonsensical code with after 10ms, which won't synthesize to anything 0ns, 100ms, 1000000000s, etc are all the same to synthesis (i.e. nothing).

If you need to delay for some length of time you have to count clock cycles (i.e. you need to add a counter and use the counter to decide when you output new values of row).

I'm also not sure what you've done to deal with switch bounce as it's not readily apparent from this code.
 


Thanks for the reply. I did not know that "after <time duration>" is not synthesizable (I am still learning VHDL). Is there any list of VHDL language constructs which are synthesizable. If so, do point me to the same.

Also, for counting clock cycles, how to decide the length of internal counter. There are programs on the internet which initalises a temp signal array of lenght 0-29 and consider 10 to 8 bits of it for counting. Is that related to avoid effects due to switch bouncing. I could not understand this and hence avoided it in the code.

Thanks again,

Emma
 

Also, to add, the code at **broken link removed** is getting stuck at 2 just after programming and not reading he value of the keys pressed.

Thanks,
Emma.
 

Thanks for the reply. I did not know that "after <time duration>" is not synthesizable (I am still learning VHDL). Is there any list of VHDL language constructs which are synthesizable. If so, do point me to the same.
I actually tried a quick search and can't seem to find a nice concise table of synthesizable statements in VHDL. I learned, which were and weren't by reading a number of VHDL books and looking at others code.

Debouncing a switch is just sampling the input at long enough intervals, that you know it's at a stable value before forwarding it. If you don't do this you may misinterpret a single switch for multiple switches as the contacts of the switch "bounce". Here is a debounce circuit I ran across, it's very similar to the one I designed and use.
 

OK... and how to decide the length of the internal counter...? Also, did you find the code in the previous **broken link removed**OK.

Thanks,
Emma
 

OK... and how to decide the length of the internal counter...? Also, did you find the code in the previous **broken link removed**OK.

Thanks,
Emma
I only just glanced at the code.

The temp(10 downto 8) stuff is so that for 256 counts (temp(7 downto 0)) it stays on one branch of the case, before moving on to the next branch.

Not sure why the code would get stuck at 2 nothing sticks out. Have you tried running a simulation on that code first?
 

No... I dont know how to simulate the code.... I can give the coloumn line inputs but how do I give the mechanical switch input which will short the row and coloumn lines ...Then only I can see the output of the row line vector and thereby decide if the vector for seven segment is getting the right value..

Also any reason for taking temp vector to be 29 downto 0 and then considering 10 downto 8 instead of simply taking it to be 7 downto 0..?

Thanks,
Emma Good
 

Huh? All you have to do is hold a 4-bit value on your column input and as the rows get scanned the "key" will be detected while the row is selected. I'm not sure why this is a problem.

Also any reason for taking temp vector to be 29 downto 0 and then considering 10 downto 8 instead of simply taking it to be 7 downto 0..?
Ignore the definition of 29:0 it should have been defined as 10:0.

The counter (temp) counts 256 clocks then the upper bits 10:8 will increment (this is like any counter).
e.g. a 6-bit counter split as 5:3 and 2:0...
2:0 - 0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,0,...
5:3 - 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,...
Does that make sense now?
 
Huh? All you have to do is hold a 4-bit value on your column input and as the rows get scanned the "key" will be detected while the row is selected. I'm not sure why this is a problem.

As I have understood this, I can input the value of coloumn to be 0111,1011,1101,1110 in the test bench. Then how will one of the rows will get selected and the test bench waveform will show either 0111 or 1011 or 1101 or1110..? Consider doing a dry run of the code pls.

Thanks,
Emma
 

The rows in your code are driven by a counter so just keep the column value there for some period of time longer than the scan rate of the rows.

As only a suggestion you could use a testbench counter where you apply the upper bits to the column input.

Code:
col_cnt <= col_cnt + 1;
column <= col_cnt(14 downto 11);
This would keep the column input static for 8 passes (3-bits bigger than the 8-bit count) of the row counter (if you're using that temp(10 downto 0) counter)

Oops, this might not work exactly like you want. As you seem to only want a single column enabled at a time....
I guess you'll have to apply the 1110, 1101, 1011, 0111 in sequence using either an initialized shift register that updates on the rollover of a 11-bit col_cnt.
something like:
Code:
signal column : std_logic_vector(3 downto 0) := "1110";
column <= column(2 downto 0) & column(3);
 

I am only using waveform test bench in Xilinx ISE....

Then you should probably learn to write testbenches, it will make things easier in the long run if you continue working with FPGAs. A google search on "VHDL testbench tutorial" will result in a lot of hits.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…