library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.math_real.all;
library work;
use work.fft_pack.all;
entity fft_g is
generic(
Dwidth : integer:=8;
Twidth : integer:=8;
N : integer:=128;
log2N : integer:=7;
pipelined : integer:=1;
ifft : boolean:=false);
port(
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
p_I : in fft_data(N-1 downto 0);
p_Q : in fft_data(N-1 downto 0);
x_I : out fft_data(N-1 downto 0);
x_Q : out fft_data(N-1 downto 0);
overflow : out std_logic_vector(log2N-1 downto 0));
end fft_g;
architecture rtl of fft_g is
component butt is
generic(
Dwidth : integer;
Twidth : integer;
pipelined : integer);
port(
clk : in std_logic;
rst : in std_logic;
en : in std_logic;
twidd_cos : in std_logic_vector(Twidth-1 downto 0);
twidd_sin : in std_logic_vector(Twidth-1 downto 0);
p_I : in butt_data;
p_Q : in butt_data;
x_I : out butt_data;
x_Q : out butt_data);
end component butt;
type twiddtab is array(N-1 downto 0) of std_logic_vector(Twidth-1 downto 0);
signal costab : twiddtab;
signal sintab : twiddtab;
signal sigtmp_I : sig_tmp(log2N downto 0, N-1 downto 0);
signal sigtmp_Q : sig_tmp(log2N downto 0, N-1 downto 0);
shared variable n_pack : integer := 0;
shared variable n_butt : integer := 0;
begin
etages : for i in 0 to log2N-1 generate
begin
gentab :
for idx in 0 to 2**i generate
constant s : real := real(2**(Twidth-2))*sin(-real(idx)*real(2)*math_pi/real(2**i));
constant sn : std_logic_vector(Twidth-1 downto 0) := conv_std_logic_vector(integer(s),Twidth);
constant c : real := real(2**(Twidth-2))*cos(-real(idx)*real(2)*math_pi/real(2**i));
constant cn : std_logic_vector(Twidth-1 downto 0) := conv_std_logic_vector(integer(c),Twidth);
begin
costab(idx) <= cn;
sintab(idx) <= sn;
end generate;
papillons : for j in 0 to N/2-1 generate
signal sigtmp2_I : sig_tmp(log2N downto 0, N-1 downto 0);
signal sigtmp2_Q : sig_tmp(log2N downto 0, N-1 downto 0);
begin
twidd : butt
generic map(
Dwidth => Dwidth,
Twidth => Twidth,
pipelined => pipelined-1)
port map(
clk => clk,
rst => rst,
en => en,
twidd_cos => costab(j),
twidd_sin => sintab(j),
p_I(0) => sigtmp2_I(i,j),
p_I(1) => sigtmp2_I(i,j+N/2),
p_Q(0) => sigtmp2_Q(i,j),
p_Q(1) => sigtmp2_Q(i,j+N/2),
x_I(0) => sigtmp2_I(i+1,j),
x_I(1) => sigtmp2_I(i+1,j+N/2),
x_Q(0) => sigtmp2_Q(i+1,j),
x_Q(1) => sigtmp2_Q(i+1,j+N/2));
sigtmp2_I(i,j) <= sigtmp_I(i,j),
sigtmp2_I(i,j+N/2) <= sigtmp_I(i,j+n_pack*2**(i+1)+n_butt+2**i),
sigtmp2_Q(i,j) <= sigtmp_Q(i,ind_p(i,j,n_pack,n_butt)),
sigtmp2_Q(i,j+N/2) <= sigtmp_Q(i,j+n_pack*2**(i+1)+n_butt+2**i),
sigtmp_I(i+1,j+n_pack*2**(i+1)+n_butt) <= sigtmp2_I(i+1,j),
sigtmp_I(i+1,j+n_pack*2**(i+1)+n_butt+2**i) <= sigtmp2_I(i+1,j+N/2),
sigtmp_Q(i+1,j+n_pack*2**(i+1)+n_butt) = sigtmp2_Q(i+1,j),
sigtmp_Q(i+1,j+n_pack*2**(i+1)+n_butt+2**i) <= sigtmp2_Q(i+1,j+N/2));
if (n_butt=2**(i+1)-1) then
n_pack := n_pack+1;
n_butt := 0;
else
n_butt := n_butt+1;
end if;
end generate papillons;
end generate etages;
end rtl;