I have a Micro-Nova FPGA dev board with a Xilinx Spartan-3A. I am trying to make it communicate bits over GPIO on a raspberry pi using 3 pins: REQ, ACK, DATA. The code works fine if I uncomment the bit_data assignments and comment out "bit_data := data_out(data_ofs);" and on the Pi i get a continous 10101010... etc. But if I leave the code as pasted below I get the wrong bits at random times eg. 1010110100... etc.
Any idea what could be the problem?:
VHDL on FPGA:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity xclock is
Port(CLK : in STD_LOGIC;
REQ : in STD_LOGIC;
ACK : out STD_LOGIC;
DATA : out STD_LOGIC);
end xclock;
architecture Behavioral of xclock is
begin
process(CLK)
variable data_ofs : integer range 0 to 2 := 0;
variable data_out : std_logic_vector(1 downto 0) := "01";
variable bit_data : std_logic := '0';
variable ack_data : std_logic := '0';
variable LASTREQ : std_logic := '0';
variable seconds : integer range 0 to 50000000 := 0;
variable tick : integer range 0 to 50000000 := 0;
begin
if CLK'event and CLK = '1' then
tick := tick + 1;
if tick = 49999999 then
tick := 0;
seconds := seconds + 1;
if seconds = 49999999 then
seconds := 0;
end if;
end if;
if seconds > 1 then
if REQ /= LASTREQ and REQ /= ack_data then
LASTREQ := REQ;
if REQ = '1' then
--bit_data := '1';
ack_data := '1';
else
--bit_data := '0';
ack_data := '0';
end if;
bit_data := data_out(data_ofs);
data_ofs := data_ofs + 1;
if data_ofs = 2 then
data_ofs := 0;
end if;
end if;
end if;
DATA <= bit_data;
ACK <= ack_data;
end if;
end process;
end Behavioral;
Bash script on Pi:
REQ=27
ACK=17
DATA=22
gpio -g mode $REQ out
gpio -g mode $ACK in
gpio -g mode $DATA in
gpio -g write $REQ 1
e=1
while [ 1 ]; do
while [ 1 ]; do
if [ `gpio -g read $ACK` -eq 1 ]; then
while [ 1 ]; do
d=`gpio -g read $DATA`
echo $d
if [ $d -ne $e ]; then
echo error DATA should be $e
sleep 1
else
if [ $e -eq 0 ]; then
e=1
else
e=0
fi
break
fi
done
gpio -g write $REQ 0
break;
fi
done
while [ 1 ]; do
if [ `gpio -g read $REQ` -eq 0 ]; then
while [ 1 ]; do
d=`gpio -g read $DATA`
echo $d
if [ $d -ne $e ]; then
echo error DATA should be $e
sleep 1
else
if [ $e -eq 0 ]; then
e=1
else
e=0
fi
break
fi
done
gpio -g write $REQ 1
break;
fi
sleep 1
done
done
Any help will be greatly appreciated. Pulling my hair out on this one!