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;
function ind_p(i, j, n_pack, n_butt : integer) return integer is
begin
return j+n_pack*2**(i+1)+n_butt;
end ind_p;
function ind_i(i, j, n_pack, n_butt : integer) return integer is
begin
return j+n_pack*2**(i+1)+n_butt+2**i;
end ind_i;
signal in_ifft_I : fft_data(N-1 downto 0);
signal in_ifft_Q : fft_data(N-1 downto 0);
signal out_ifft_I : fft_data(N-1 downto 0);
signal out_ifft_Q : fft_data(N-1 downto 0);
signal out_ifft2_I : fft_data(N-1 downto 0);
signal out_ifft2_Q : fft_data(N-1 downto 0);
signal tmp_ifft_I : fft_data_2(N-1 downto 0);
signal tmp_ifft_Q : fft_data_2(N-1 downto 0);
signal tmp_ifft2_I : fft_data_2(N-1 downto 0);
signal tmp_ifft2_Q : fft_data_2(N-1 downto 0);
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);
signal sigtmp2_I : sig_tmp(log2N downto 0, N-1 downto 0);
signal sigtmp2_Q : sig_tmp(log2N downto 0, N-1 downto 0);
signal n_pack : integer := 0;
signal n_butt : integer := 0;
begin
fft_x : if ifft=false generate
pas_de_croisement : for k in 0 to N-1 generate
in_ifft_I(k) <= p_I(k);
in_ifft_Q(k) <= p_Q(k);
x_I(k) <= out_ifft_I(k);
x_Q(k) <= out_ifft_Q(k);
end generate pas_de_croisement;
end generate fft_x;
ifft_x : if ifft=true generate
croisement : for k in 0 to N-1 generate
in_ifft_I(k) <= p_Q(k);
in_ifft_Q(k) <= p_I(k);
x_I(k) <= out_ifft2_Q(k);
x_Q(k) <= out_ifft2_I(k);
end generate croisement;
div_ifft : for k in 0 to N-1 generate
tmp_ifft_I(k) <= sxt(out_ifft_I(k)(Dwidth-1 downto log2N-1),Dwidth+1);
tmp_ifft2_I(k) <= signed(tmp_ifft_I(k))+signed(conv_std_logic_vector(1,Dwidth+1));
out_ifft2_I(k) <= tmp_ifft2_I(k)(Dwidth downto 1);
tmp_ifft_Q(k) <= sxt(out_ifft_Q(k)(Dwidth-1 downto log2N-1),Dwidth+1);
tmp_ifft2_Q(k) <= signed(tmp_ifft_Q(k))+signed(conv_std_logic_vector(1,Dwidth+1));
out_ifft2_Q(k) <= tmp_ifft2_Q(k)(Dwidth downto 1);
end generate div_ifft;
end generate ifft_x;
init : for j in 0 to N-1 generate
sigtmp_I(0,j) <= in_ifft_I(j);
sigtmp_Q(0,j) <= in_ifft_Q(j);
end generate init;
etages : for i in 0 to log2N-1 generate
constant k : natural := 2**(i+1)-1;
begin
gentab :
for idx in 0 to 2**i-1 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
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,ind_p(i,j,n_pack,n_butt));
sigtmp2_I(i,j+N/2) <= sigtmp_I(i,ind_i(i,j,n_pack,n_butt));
sigtmp2_Q(i,j) <= sigtmp_Q(i,ind_p(i,j,n_pack,n_butt));
sigtmp2_Q(i,j+N/2) <= sigtmp_Q(i,ind_i(i,j,n_pack,n_butt));
sigtmp_I(i+1,ind_p(i,j,n_pack,n_butt)) <= sigtmp2_I(i+1,j);
sigtmp_I(i+1,ind_i(i,j,n_pack,n_butt)) <= sigtmp2_I(i+1,j+N/2);
sigtmp_Q(i+1,ind_p(i,j,n_pack,n_butt)) <= sigtmp2_Q(i+1,j);
sigtmp_Q(i+1,ind_i(i,j,n_pack,n_butt)) <= sigtmp2_Q(i+1,j+N/2);
if_butt : if (n_butt=n_pack) generate
n_pack <= n_pack+1;
n_butt <= 0;
end generate if_butt;
if_butt2 : if (n_butt<n_pack) generate
n_butt <= n_butt+1;
end generate if_butt2;
end generate papillons;
end generate etages;
end rtl;