I'm getting very confused in how to use the FFT properly right now. I'm now using burst mode and a single output engine. I do get output from the FFT but when I use pythagoras on it (sqrt(real*real+imaginary*imaginary)) I get very high values. Sometimes with no audio input at all.
My adc puts in a binary number around 127 with silence and goes up to 4096 as full number.
Here is my code which is a state machine, which feeds the FFT. Please look at it and let me know what i'm doing wrong.
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
--------------------------------------
entity FFTStatemachine is
port( clk,clk32mhz,reset,enable,deserializerdone: IN std_logic;
enabledeserializer,writefifotestled,source_valid: OUT std_logic;
fifoinput : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
fifooutput : OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
source_exp : OUT STD_LOGIC_VECTOR (5 DOWNTO 0);
source_real : OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
source_imag : OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
source_error : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
source_sop : OUT STD_LOGIC;
source_eop :OUT STD_LOGIC
);
end entity;
--------------------------------------
architecture implementation of FFTStatemachine is
component FFT is
port (
clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
inverse : IN STD_LOGIC;
sink_valid : IN STD_LOGIC;
sink_sop : IN STD_LOGIC;
sink_eop : IN STD_LOGIC;
sink_real : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
sink_imag : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
sink_error : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
source_ready : IN STD_LOGIC;
sink_ready : OUT STD_LOGIC;
source_error : OUT STD_LOGIC_VECTOR (1 DOWNTO 0);
source_sop : OUT STD_LOGIC;
source_eop : OUT STD_LOGIC;
source_valid : OUT STD_LOGIC;
source_exp : OUT STD_LOGIC_VECTOR (5 DOWNTO 0);
source_real : OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
source_imag : OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
);
end component;
component FIFO is
port (
rdclk : IN STD_LOGIC ;
wrempty : OUT STD_LOGIC ;
wrfull : OUT STD_LOGIC ;
q : OUT STD_LOGIC_VECTOR (13 DOWNTO 0);
rdempty : OUT STD_LOGIC ;
rdfull : OUT STD_LOGIC ;
wrclk : IN STD_LOGIC ;
wrreq : IN STD_LOGIC ;
aclr : IN STD_LOGIC ;
data : IN STD_LOGIC_VECTOR (13 DOWNTO 0);
rdreq : IN STD_LOGIC
);
end component;
-- Signals & Variables --
-------------------------------------------------------------------
-- state definitions and signals ----------------------------------
-------------------------------------------------------------------
type state is (
Idle,
WriteFIFO,
FIFOLatency,
Startreading,
ReadFIFO,
Finishreading,
Finished
);
signal present_state, next_state: state;
signal enablefifolatencycounter: std_logic;
signal enablefifosamplecounter: std_logic;
signal FIFOlatencycounter: integer range 0 to 10:=0;
signal fifocounter : integer range 0 to 3000:=0;
signal done :std_logic;
--FFT local input signals
signal inverse : std_logic :='0';
signal sink_valid : std_logic;
signal sink_sop : std_logic;
signal sink_eop : std_logic;
--signal sink_real : STD_LOGIC_VECTOR (11 DOWNTO 0);
signal sink_imag : STD_LOGIC_VECTOR (13 DOWNTO 0):="00000000000000";
signal sink_error : STD_LOGIC_VECTOR (1 DOWNTO 0) :="00";
signal source_ready : STD_LOGIC;
--FFT local output signals
signal sink_ready : STD_LOGIC;
--signal source_sop : STD_LOGIC;
--signal source_eop : STD_LOGIC;
--signal source_valid : STD_LOGIC;
--FIFO local inputs
signal enablewriting : STD_LOGIC;
signal enablereading : STD_LOGIC;
signal clearfifo : STD_LOGIC;
--FIFO local outputs
signal fifo_out :std_logic_vector (13 downto 0);
signal readempty :std_logic;
signal readfull :std_logic;
signal writeempty :std_logic;
signal writefull :std_logic;
----------------------------------------------------------------------
--PORTMAPS------------------------------------------------------------
----------------------------------------------------------------------
begin
FastFourierTransform: FFT PORT MAP (clk,reset,inverse,sink_valid,sink_sop,sink_eop,fifo_out,sink_imag,sink_error,source_ready,sink_ready,source_error,source_sop,source_eop,source_valid,source_exp,source_real,source_imag);
FIFORAM : FIFO PORT MAP (clk,writeempty,writefull,fifo_out,readempty,readfull,clk32mhz,deserializerdone,clearfifo,fifoinput,enablereading);
------------------------------------------------------------------
-- sequential part of the statemachine ----------------------------
-------------------------------------------------------------------
fifooutput<=fifo_out;
writefifotestled<=sink_ready;
process(reset, clk, next_state)
begin
if (reset = '0') then
clearfifo<='1';
present_state <= Idle;
elsif (rising_edge(clk)) then
clearfifo<='0';
present_state <= next_state;
end if;
end process;
process(present_state,next_state, enable,sink_sop,fifocounter,done,writeempty,writefull,readempty,sink_ready,FIFOlatencycounter)
begin
case present_state is
when Idle =>
if enable ='1' and writeempty = '1' then
next_state <= WriteFIFO;
else
next_state <=Idle;
end if;
when WriteFIFO =>
if writefull ='1' then
next_state <= FIFOlatency;
else
next_state <=WriteFIFO;
end if;
when FIFOlatency =>
if FIFOlatencycounter = 1 then
next_state <= Startreading;
else
next_state <=FIFOlatency;
end if;
when Startreading =>
if sink_sop ='1' then
next_state <= ReadFIFO;
else
next_state <=Startreading;
end if;
when ReadFIFO =>
if fifocounter = 511 then
next_state <= Finishreading;
else
next_state <=ReadFIFO;
end if;
when Finishreading =>
if readempty ='1' then
next_state <= Finished;
else
next_state <= Finishreading;
end if;
when Finished =>
if done = '1' and sink_ready = '1' then
next_state <= Idle;
else
next_state <=Finished;
end if;
end case;
end process;
process(present_state,clk)
begin
case present_state is
when Idle=>
enablefifosamplecounter<='0';
enablefifolatencycounter<='0';
done <='0';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='0';
sink_valid <='0';
sink_eop <='0';
sink_sop <='0';
source_ready<='1';
when WriteFIFO=>
enablefifosamplecounter<='0';
enablefifolatencycounter<='0';
done <='0';
enabledeserializer<='1';
enablewriting <='1';
enablereading <='0';
sink_valid <='0';
sink_eop <='0';
sink_sop <='0';
source_ready<='1';
when FIFOLatency=>
enablefifosamplecounter<='0';
enablefifolatencycounter<='1';
done <='0';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='1';
sink_valid <='0';
sink_eop <='0';
sink_sop <='0';
source_ready<='1';
when Startreading=>
enablefifosamplecounter<='1';
enablefifolatencycounter<='0';
done <='0';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='1';
sink_valid <='1';
sink_eop <='0';
sink_sop <='1';
source_ready<='1';
when ReadFIFO=>
enablefifosamplecounter<='1';
enablefifolatencycounter<='0';
done <='0';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='1';
sink_valid <='1';
sink_eop <='0';
sink_sop <='0';
source_ready<='1';
when Finishreading=>
enablefifosamplecounter<='1';
enablefifolatencycounter<='0';
done <='0';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='1';
sink_valid <='1';
sink_eop <='1';
sink_sop <='0';
source_ready<='1';
when Finished=>
enablefifosamplecounter<='0';
enablefifolatencycounter<='0';
done <='1';
enabledeserializer<='0';
enablewriting <='0';
enablereading <='0';
sink_valid <='0';
sink_eop <='0';
sink_sop <='0';
source_ready<='1';
end case;
end process;
process(clk, enablefifosamplecounter,fifocounter)
begin
if(rising_edge(clk))and enablefifosamplecounter = '1' then
fifocounter <= fifocounter+1;
end if;
if enablefifosamplecounter = '0' then
fifocounter <=0;
end if;
end process;
process(clk,enablefifolatencycounter,FIFOlatencycounter)
begin
if(rising_edge(clk))and enablefifolatencycounter = '1' then
fifolatencycounter<=fifolatencycounter + 1;
end if;
if enablefifolatencycounter= '0' then
fifolatencycounter <=0;
end if;
end process;
end architecture;