Altera FPGA hardware (has an issue) vs ModelSim simulation (ok) - self implemented UART - vhdl

I have an issue with self implemented UART in VHDL.
I wrote VHDL code which generates proper waveform when running on Altera ModelSim:
UART.vhd:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
entity UART is
port (
clk_10mhz: in STD_LOGIC;
uart_clk: out STD_LOGIC;
txPin: out STD_LOGIC
);
end entity;
architecture Test of UART is
signal txStart: STD_LOGIC := '0';
signal txIdle: STD_LOGIC;
signal txData: STD_LOGIC_VECTOR(7 downto 0);
component TX is
port (
clk_in: in STD_LOGIC;
start: in STD_LOGIC;
data: in STD_LOGIC_VECTOR(7 downto 0);
tx: out STD_LOGIC;
txIdle: out STD_LOGIC;
debug_clk: out STD_LOGIC
);
end component TX;
begin
process (clk_10mhz)
variable clkDividerCounter : integer range 0 to 10000000;
variable textToSend : string(1 to 31) := "Hello darkness my old friend!" & LF & CR;
variable currentCharacterIndex : integer range 1 to 31 := 1;
variable startSending : std_logic := '0';
variable characterReceivedByTX : std_logic := '1';
begin
if (rising_edge(clk_10mhz)) then
if (startSending = '1') then
if (txIdle = '0') then
characterReceivedByTX := '1';
end if;
if (txIdle = '1' and characterReceivedByTX = '1') then
txData <= std_logic_vector(to_unsigned(character'pos(textToSend(currentCharacterIndex)), 8));
txStart <= '1';
if (currentCharacterIndex < 31) then
currentCharacterIndex := currentCharacterIndex + 1;
characterReceivedByTX := '0';
else
txStart <= '0';
currentCharacterIndex := 1;
startSending := '0';
end if;
end if;
else
if (clkDividerCounter < 10000000) then
clkDividerCounter := clkDividerCounter + 1;
startSending := '0';
else
clkDividerCounter := 0;
startSending := '1';
end if;
end if;
end if;
end process;
u1: TX port map (clk_10mhz, txStart, txData, txPin, txIdle, uart_clk);
end Test;
TX.vhd:
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use ieee.numeric_std.ALL;
entity TX is
port (
clk_in: in STD_LOGIC;
start: in STD_LOGIC;
data: in STD_LOGIC_VECTOR(7 downto 0);
tx: out STD_LOGIC := '1';
txIdle: out STD_LOGIC := '1';
debug_clk: out STD_LOGIC := '0'
);
end entity;
architecture Test of TX is
signal idle: STD_LOGIC := '1';
begin
process (clk_in)
variable bitIndex : integer range 0 to 9;
variable clkDividerCounter : integer range 0 to 1042;
variable dataFrame : STD_LOGIC_VECTOR(9 downto 0);
variable dataFrameCurrentIndex : integer range 0 to 9;
begin
if (rising_edge(clk_in)) then
if (start = '1' and idle = '1') then
dataFrame(0) := '0';
dataFrame(8 downto 1) := data;
dataFrame(9) := '1';
dataFrameCurrentIndex := 0;
idle <= '0';
end if;
if (idle = '0') then
if (clkDividerCounter < 521) then
debug_clk <= '0';
else
debug_clk <= '1';
end if;
if (clkDividerCounter < 1041) then
clkDividerCounter := clkDividerCounter + 1;
else
if (dataFrameCurrentIndex < 9) then
tx <= dataFrame(dataFrameCurrentIndex);
dataFrameCurrentIndex := dataFrameCurrentIndex + 1;
else
tx <= dataFrame(dataFrameCurrentIndex);
idle <= '1';
end if;
clkDividerCounter := 0;
end if;
else
debug_clk <= '0';
end if;
end if;
end process;
txIdle <= idle;
end Test;
Unfortunately, on hardware, instead of "Hello darkness my old friend!" sent, it sends "HHello darkness my old friend!" with double H at the beginning.
I checked it on SignalTap II and waveform confirms the problem:
What can cause this problem? How may I debug such an issue?

Related

How can i implement byte addressable memory in VHDL?

I want to make 4kb byte addressable memory. sorry I'm new in VHDL
I wanted my code works first write 4byte number in adress 8 (rdwr=1, addr=1000, size=10(2^2byte), idata=10001100)
then wait 8 cycles to implement writing time(ivalid=0)
Second read 4byte number from adress 8(rdwr=0, addr=1000, size=10(2^2byte))
In my purpose, the "ready" signal should be '0' while waiting for writing time
but the signal is always 'U' in simulation. I tried to figure out what is the problem but i couldn't
Can anyone help me where did a make mistake?
Here is my code
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity Memory is
port (
clk: in std_logic;
ready: out std_logic; -- 0: busy, 1: ready
ivalid: in std_logic; -- 0: invalid, 1: valid
rdwr: in std_logic; -- 0: read, 1: write
addr: in unsigned(11 downto 0); -- byte address
size: in std_logic_vector(1 downto 0); -- 00/01/10/11: 1/2/4/8 bytes
idata: in std_logic_vector(63 downto 0);
ovalid: out std_logic; -- 0: invalid, 1: valid
odata: out std_logic_vector(63 downto 0)
);
end entity;
architecture Behavioral of Memory is
type ram_type is array (0 to (2**12)-1) of std_logic_vector(7 downto 0);
signal RAM : ram_type;
signal state : std_logic := '1'; --if ready '1'
signal queue : std_logic := '0'; --if something to do '1'
signal timer : integer := 0; --timer
signal curr_addr : unsigned(11 downto 0);
signal curr_size : std_logic_vector(1 downto 0);
signal curr_data : std_logic_vector(63 downto 0);
signal write : std_logic := '0';
signal read : std_logic := '0';
begin
process(clk)
variable vstate : std_logic := state;
variable vqueue : std_logic := queue; --if something to do '1'
variable vtimer : integer := timer; --timer
variable vcurr_addr : unsigned(11 downto 0) := curr_addr;
variable vcurr_size : std_logic_vector(1 downto 0) := curr_size;
variable vcurr_data : std_logic_vector(63 downto 0) := curr_data;
variable vwrite : std_logic := write;
variable vread : std_logic := read;
begin
--get input
if(rising_edge(clk)) then
ovalid <= '0';
if(vstate='1') then
if(ivalid='1') then
vcurr_addr := addr;
vcurr_size := size;
if(rdwr='0') then
--read
vread := '1';
else
vwrite := '1';
vcurr_data := idata;
end if;
vqueue := '1';
vtimer := 2**(to_integer(unsigned(vcurr_size)))-1;
end if;
end if;
--process
if(vqueue = '1') then
if(vtimer > 0) then
--wait for next cycle
ready <= '0';
vstate := '0';
vtimer := vtimer - 1;
else
--ok to go
if(vwrite = '1') then
--write
for x in 0 to 2**(to_integer(unsigned(vcurr_size)))-1 loop
for y in 0 to 7 loop
RAM(to_integer(vcurr_addr) + x)(y) <= vcurr_data(y + 8*x);
end loop;
end loop;
elsif(vread = '1') then
--read
for x in 0 to 7 loop
for y in 0 to 7 loop
if(x < 2**(to_integer(unsigned(vcurr_size)))) then
odata(y + 8*x) <= RAM(to_integer(vcurr_addr) + x)(y);
else
odata(y + 8*x) <= '0';
end if;
end loop;
end loop;
ovalid <= '1';
end if;
vqueue := '0';
vstate := '1';
ready <= '1';
end if;
end if;
--save variable to signals
state <= vstate;
queue <= vqueue;
timer <= vtimer;
curr_addr <=vcurr_addr;
curr_size <=vcurr_size;
curr_data<= vcurr_data;
write <= vwrite;
read <= vread;
end if;
end process;
end architecture;

How to fix 'ERROR:Xst - basic_stringFATAL_ERROR' error in Xilinx fpga?

I have been trying to synthesize a vhdl code which simulates perfectly in Active HDL but I get the following error when synthesizing.
ERROR:Xst - basic_stringFATAL_ERROR:Xst:Portability/export/Port_Main.h:159:1.18 - This application has discovered an exceptional condition from which it cannot recover. For technical support on this issue, please visit http://www.xilinx.com/support.
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.all;
--use IEEE.NUMERIC_STD_UNSIGNED.all;
library work;
use work.common.all;
library UNISIM;
use UNISIM.VComponents.all;
entity main is
port(
CLK : in STD_LOGIC;
reset : in STD_LOGIC;
V_Out : out STD_LOGIC
);
end main;
--}} End of automatically maintained section
architecture main of main is
signal text : string (1 to 15) := "This is a Test.";
signal text_len : integer := 15;
signal x : integer := 50;
signal y : integer := 50;
type vramt is array (0 to H_480_272p_AV*V_480_272p_AV-1) of std_logic_vector (0 downto 0);
signal vram : vramt := (others => (others => '0'));
--signal vram : std_logic_vector(H_480_272p_AV*V_480_272p_AV-1 downto 0) := (others => '0');
attribute RAM_STYLE : string;
attribute RAM_STYLE of vram: signal is "BLOCK";
signal vram_we : std_logic;
signal vram_addr, vram_wraddr : INTEGER range 0 to H_480_272p_AV*V_480_272p_AV-1;
signal rom_addr : std_logic_vector(10 downto 0);
signal rom_data : std_logic_vector(7 downto 0);
begin
inst_get_char : entity work.Font_Rom PORT MAP (
clk => CLK,
addr => rom_addr,
data => rom_data
);
Process (CLK)
begin
if rising_edge (CLK) then
if vram_addr = H_480_272p_AV*V_480_272p_AV-1 then
vram_addr <= 0;
end if;
vram_addr <= vram_addr + 1;
V_Out <= vram(vram_addr)(0);
end if;
end process;
Process (CLK)
variable char_count : integer := 1;
variable pix_line : integer := 0;
variable bit_count : integer := 0;
variable curr_char : std_logic_vector(7 downto 0);
variable bit_data : std_logic;
begin
if rising_edge(CLK) then
if bit_count = 0 then
rom_addr <= std_logic_vector(to_unsigned(character'pos(text(char_count)), 7)) & std_logic_vector(to_unsigned(pix_line, 4));
end if;
bit_data := rom_data(bit_count);
vram_wraddr <= (y + pix_line)*H_480_272p_AV + (x + bit_count + (8* (char_count-1)));
vram(vram_wraddr)(0) <= bit_data;
if bit_count = 7 then
bit_count := 0;
if pix_line = 15 then
pix_line := 0;
if char_count = text_len then
char_count := 1;
else
char_count := char_count + 1;
end if;
else
pix_line := pix_line + 1;
end if;
else
bit_count := bit_count + 1;
end if;
end if;
end Process;
end main;

FIFO using vhdl

I am writing a VHDL for fifo , but when i simulate there is no output?i cantt view the output in behavioral simulation.its like There's no data in data_in for read to be writing to the output of fifo.In my code is to write data into the FIFO first push the data onto the DataIn bus and then strobe the WriteEn input high for one clock cycle.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use std.textio.all;
use IEEE.NUMERIC_STD.ALL;
entity fifo_mem is
port ( clk : in std_logic;
reset : in std_logic;
enr : in std_logic;
enw : in std_logic;
data_in : in std_logic_vector (15 downto 0); --input data
data_out : out std_logic_vector(15 downto 0); --output data
fifo_empty : out std_logic;
fifo_full : out std_logic );
end fifo_mem;
architecture Behavioral of fifo_mem is
type fifo_type is array(0 to 10) of bit_vector (15 downto 0);
signal memory : fifo_type :=(others => (others => '0'));
signal readptr,writeptr : integer := 0; --read and write pointers.
signal empty,full : std_logic ;
impure function InitRamFromFile (RamFileName : in string) return fifo_type is
FILE RamFile : text is in RamFileName;
variable RamFileLine : line;
variable RAM : fifo_type;
begin
for I in 0 to 10 loop
readline (RamFile, RamFileLine);
read (RamFileLine, RAM(I));
end loop;
return RAM;
end function;
signal RAM : fifo_type :=InitRamFromFile("C:\Users\hp\Desktop\file\file1.txt");
begin
fifo_empty <= empty;
fifo_full <= full;
process(Clk,reset)
--this is the number of elements stored in fifo at a time.
--this variable is used to decide whether the fifo is empty or full.
variable num_elem : integer := 0;
begin
if(reset = '1') then
data_out <= (others => '0');
empty <= '0';
full <= '0';
readptr <= 0;
writeptr <= 0;
num_elem := 0;
elsif(rising_edge(Clk)) then
if(enr = '1' and empty = '0') then --read
data_out <=to_stdlogicvector(RAM(readptr));
readptr <= readptr + 1;
num_elem := num_elem-1;
end if;
if(enw ='1' and full = '0') then --write
RAM(writeptr)<= to_bitvector(data_in);
writeptr <= writeptr +1;
num_elem := num_elem+1;
end if;
if(readptr = 10) then --resetting read pointer.
readptr <= 0;
end if;
if(writeptr = 10) then --resetting write pointer.
writeptr <= 0;
end if;
--setting empty and full flags.
if(num_elem = 0) then
empty <= '1';
else
empty <= '0';
end if;
if(num_elem = 10) then
full <= '1';
else
full <= '0';
end if;
end if;
end process;
end Behavioral;

How to resolve "Register/latch pins with no clock driven by root clock pin" error in Vivado?

As a learning exercise I am doing some HDMI experiments on an FPGA using VHDL. When coming to implement it in Vivado (2017.1) I am encountering the following warning in the timing report:
There are 11 register/latch pins with no clock driven by root clock pin: Hsync_i_reg/Q (HIGH)
I have opened the implemented schematic and looked for the pin in question. It seems to be connected to the same clock that everything else is connected to (and those are not flagged in the timing report), so I am confused as to what the errors above are referring to. Here are some shots from the schematics:
Here is the VHDL code of the offending design:
library ieee;
use ieee.std_logic_1164.all;
entity ctrl_gen is
generic (
ha: integer := 96; --hpulse
hb: integer := 144; --hpulse+hbp
hc: integer := 784; --hpulse+hbp+hactive
hd: integer := 800; --hpulse+hbp+hactive+hfp
va: integer := 2; --vpulse
vb: integer := 35; --vpulse+vbp
vc: integer := 515; --vpulse+vbp+vactive
vd: integer := 525 --vpulse+vbp+vactive+vfp
);
port (
clk25: in std_logic; --tmds clock (25mhz)
hsync: out std_logic; --horizontal sync
vsync: out std_logic; --vertical sync
hactive: out std_logic; --active portion of hsync
vactive: out std_logic; --active portion of vsync
dena: out std_logic --display enable
);
end entity;
architecture behavioral of ctrl_gen is
signal hsync_i, hactive_i, vactive_i, vsync_i : std_logic;
begin
-- horizontal signals generation
hproc : process (clk25)
variable hcount: integer range 0 to hd := 0;
begin
if rising_edge(clk25) then
hcount := hcount + 1;
if (hcount=ha) then
hsync_i <= '1';
elsif (hcount=hb) then
hactive_i <= '1';
elsif (hcount=hc) then
hactive_i <= '0';
elsif (hcount=hd) then
hsync_i <= '0';
hcount := 0;
end if;
end if;
end process;
-- vertical signals generation
vproc : process (hsync_i)
variable vcount: integer range 0 to vd := 0;
begin
if falling_edge(hsync_i) then
vcount := vcount + 1;
if (vcount=va) then
vsync_i <= '1';
elsif (vcount=vb) then
vactive_i <= '1';
elsif (vcount=vc) then
vactive_i <= '0';
elsif (vcount=vd) then
vsync_i <= '0';
vcount := 0;
end if;
end if;
end process;
dena <= hactive_i and vactive_i;
hsync <= hsync_i;
vactive <= vactive_i;
hactive <= hactive_i;
end behavioral;
On reflection, I think that the warning is telling me that Hsync_i_reg/Q is the clock used for the Vcount registers, not that Hsync_i_reg itself if not connected to the root clock pin?
Is the method I have used bad practice and unlikely to work? The overall design is not working and I'm trying to understand whether this is the cause.
Thanks.
I see potential design issues. First being the use of variable for objects that are actually clocked signals. Secondly, you're using a generated signal as a clock input. That's also not nice.
I would modify your code to the following (not tested if it completely does what your code did before)
library ieee;
use ieee.std_logic_1164.all;
entity ctrl_gen is
generic (
ha: integer := 96; --hpulse
hb: integer := 144; --hpulse+hbp
hc: integer := 784; --hpulse+hbp+hactive
hd: integer := 800; --hpulse+hbp+hactive+hfp
va: integer := 2; --vpulse
vb: integer := 35; --vpulse+vbp
vc: integer := 515; --vpulse+vbp+vactive
vd: integer := 525 --vpulse+vbp+vactive+vfp
);
port (
clk25: in std_logic; --tmds clock (25mhz)
hsync: out std_logic; --horizontal sync
vsync: out std_logic; --vertical sync
hactive: out std_logic; --active portion of hsync
vactive: out std_logic; --active portion of vsync
dena: out std_logic --display enable
);
end entity;
architecture behavioral of ctrl_gen is
signal hsync_i, hactive_i, vactive_i, vsync_i : std_logic;
signal hcount: integer range 0 to hd-1 := 0;
signal vcount: integer range 0 to vd-1 := 0;
begin
-- horizontal signals generation
hproc : process (clk25)
begin
if rising_edge(clk25) then
if hcount < hd-1 then
hcount <= hcount + 1;
else
hcount <= 0;
end if;
if (hcount=ha-1) then
hsync <= '1';
end if;
if (hcount=hb-1) then
hactive_i <= '1';
end if;
if (hcount=hc-1) then
hactive_i <= '0';
end if;
if (hcount=hd-1) then
hsync <= '0';
end if;
end if;
end process;
-- vertical signals generation
vproc : process (clk25)
begin
if rising_edge(clk25) then
if hcount = hd-1 then -- moment of falling_edge hsync.
if vcount < vd-1 then
vcount <= vcount + 1;
else
vcount <= 0;
end if;
if (vcount=va-1) then
vsync <= '1';
end if;
if (vcount=vb-1) then
vactive_i <= '1';
end if;
if (vcount=vc-1) then
vactive_i <= '0';
end if;
if (vcount=vd-1) then
vsync <= '0';
end if;
end if;
end if;
end process;
dena <= hactive_i and vactive_i;
vactive <= vactive_i;
hactive <= hactive_i;
end behavioral;
I think:
signal hcount: integer range 0 to hd-1 := 0;
signal vcount: integer range 0 to vd-1 := 0;
Is not a valid synthesis type for hcount, vcount: it should be std_logic_vector

VHDL - SNES Interface via controller port using FPGA

I am working on trying to interface a cheap FPGA (the ep2c5t144 Altera Cyclone II mini board) with a SNES in order to ACT as a SNES controller. So far, it seems to work on and off... with the current problem being, it works for about 1 second after switched on... but then seems to get stuck in a state until it is reset.
Since I have spent a long time looking at the code for a logic issue, I'm starting to wonder whether it's some strange quirk of using FPGAs, but I've already tried testing for any states which aren't defined, and that hasn't fixed the problem. I will post the SNES code below, and the output from my cheap logic analyser which shows the problem. Warning, the code is quite messy... especially with me changing thing around to try to fix it. Any ideas at all with be much appreciated!
Many thanks in advance for any help!
Problem from logic analyser:
When a request works - State transitions occur as expected
When a request fails - SEEMS to incorrectly transition directly to "working" state and get stuck for some reason
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity snes_controller is
generic (
hp : integer := 300
);
port (
clk : in std_logic;
latch : in std_logic;
data : out std_logic := '0';
clock : in std_logic;
enable : in std_logic;
btn_B : in std_logic;
btn_Y : in std_logic;
btn_select : in std_logic;
btn_start : in std_logic;
btn_up : in std_logic;
btn_down : in std_logic;
btn_left : in std_logic;
btn_right : in std_logic;
btn_A : in std_logic;
btn_X : in std_logic;
btn_L : in std_logic;
btn_R : in std_logic;
helpA : out std_logic := '0';
helpB : out std_logic := '0';
helpC : out std_logic := '0';
helpD : out std_logic := '0';
helpE : out std_logic := '0'
);
end entity;
architecture Behav of snes_controller is
signal buttons : unsigned(16 downto 0) := "10000000000000000";
type state_type is (s_idle, s_latching_1, s_latching_2, s_working);
signal state : state_type := s_idle;
type cycle_type is (c_high, c_low);
signal cycle : cycle_type := c_high;
begin
process (clk)
variable i : integer range 0 to 16;
variable count : integer range 0 to hp;
begin
if(rising_edge(clk)) then
data <= not buttons(i);
if(state = s_latching_1 or state = s_latching_2 or state = s_working) then
if(count < hp) then
count := count+1;
else
count := 0;
if(state = s_latching_1) then
if(latch = '1') then
state <= s_latching_2;
buttons(0) <= btn_B;
buttons(1) <= btn_Y;
buttons(2) <= btn_select;
buttons(3) <= btn_start;
buttons(4) <= btn_up;
buttons(5) <= btn_down;
buttons(6) <= btn_left;
buttons(7) <= btn_right;
buttons(8) <= btn_A;
buttons(9) <= btn_X;
buttons(10) <= btn_L;
buttons(11) <= btn_R;
else
state <= s_idle;
end if;
elsif(state = s_latching_2) then
state <= s_working;
i := 0;
cycle <= c_high;
elsif(state = s_working) then
if(latch = '1') then
state <= s_idle;
helpD <= '1';
elsif(cycle = c_low) then
cycle <= c_high;
if(i < 16) then
i := i+1;
else
state <= s_idle;
helpD <= '0';
helpE <= '0';
end if;
else
cycle <= c_low;
end if;
end if;
end if;
elsif(state = s_idle) then
if(latch = '1') then
state <= s_latching_1;
count := 0;
i := 0;
end if;
else
helpE <= '1';
state <= s_idle;
count := 0;
i := 0;
end if;
end if;
end process;
process(state)
begin
if(state = s_idle) then
helpA <= '0';
helpB <= '0';
elsif(state = s_latching_1) then
helpA <= '1';
helpB <= '0';
elsif(state = s_latching_2) then
helpA <= '0';
helpB <= '1';
elsif(state = s_working) then
helpA <= '1';
helpB <= '1';
else
helpA <= clk;
helpB <= not clk;
end if;
if(cycle = c_low) then
helpC <= '0';
elsif(cycle = c_high) then
helpC <= '1';
end if;
end process;
end Behav;
You are using asynchronous external inputs and feed them into a synchronous, clock-based, state machine. Metastability in sampling may lead to your problem. Make sure you implement at least a two-flop synchronizer for every input signal.
Read more about it here: http://webee.technion.ac.il/~ran/papers/Metastability%20and%20Synchronizers.posted.pdf
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity snes_controller is
generic (
hp : integer := 300
);
port (
clk : in std_logic;
latch : in std_logic;
data : out std_logic := '0';
clock : in std_logic;
enable : in std_logic;
btn_B : in std_logic;
btn_Y : in std_logic;
btn_select : in std_logic;
btn_start : in std_logic;
btn_up : in std_logic;
btn_down : in std_logic;
btn_left : in std_logic;
btn_right : in std_logic;
btn_A : in std_logic;
btn_X : in std_logic;
btn_L : in std_logic;
btn_R : in std_logic;
helpA : out std_logic := '0';
helpB : out std_logic := '0';
helpC : out std_logic := '0';
helpD : out std_logic := '0';
helpE : out std_logic := '0'
);
end entity;
architecture Behav of snes_controller is
signal synch0 : unsigned(11 downto 0) := (others => '0');
signal synch1 : unsigned(11 downto 0) := (others => '0');
signal synch2 : unsigned(11 downto 0) := (others => '0');
signal buttons : unsigned(16 downto 0) := "10000000000000000";
type state_type is (s_idle, s_latching_1, s_latching_2, s_working);
signal state : state_type := s_idle;
type cycle_type is (c_high, c_low);
signal cycle : cycle_type := c_high;
begin
process (clk)
variable i : integer range 0 to 16;
variable count : integer range 0 to hp;
begin
if(rising_edge(clk)) then
synch0(0) <= btn_B;
synch0(1) <= btn_Y;
synch0(2) <= btn_select;
synch0(3) <= btn_start;
synch0(4) <= btn_up;
synch0(5) <= btn_down;
synch0(6) <= btn_left;
synch0(7) <= btn_right;
synch0(8) <= btn_A;
synch0(9) <= btn_X;
synch0(10) <= btn_L;
synch0(11) <= btn_R;
synch1 <= synch0;
synch2 <= synch1;
data <= not buttons(i);
if(state = s_latching_1 or state = s_latching_2 or state = s_working) then
if(count < hp) then
count := count+1;
else
count := 0;
if(state = s_latching_1) then
if(latch = '1') then
state <= s_latching_2;
buttons(11 downto 0) <= synch2(11 downto 0);
else
state <= s_idle;
end if;
elsif(state = s_latching_2) then
state <= s_working;
i := 0;
cycle <= c_high;
elsif(state = s_working) then
if(latch = '1') then
state <= s_idle;
helpD <= '1';
elsif(cycle = c_low) then
cycle <= c_high;
if(i < 16) then
i := i+1;
else
state <= s_idle;
helpD <= '0';
helpE <= '0';
end if;
else
cycle <= c_low;
end if;
end if;
end if;
elsif(state = s_idle) then
if(latch = '1') then
state <= s_latching_1;
count := 0;
i := 0;
end if;
else
helpE <= '1';
state <= s_idle;
count := 0;
i := 0;
end if;
end if;
end process;
process(state)
begin
if(state = s_idle) then
helpA <= '0';
helpB <= '0';
elsif(state = s_latching_1) then
helpA <= '1';
helpB <= '0';
elsif(state = s_latching_2) then
helpA <= '0';
helpB <= '1';
elsif(state = s_working) then
helpA <= '1';
helpB <= '1';
else
helpA <= clk;
helpB <= not clk;
end if;
if(cycle = c_low) then
helpC <= '0';
elsif(cycle = c_high) then
helpC <= '1';
end if;
end process;
end Behav;
Additionally, I suggest to create some sort of filter to handle debouncing of button clicks. http://www.eng.utah.edu/~cs5780/debouncing.pdf

Resources