OpenCores
URL https://opencores.org/ocsvn/wdsp/wdsp/trunk

Subversion Repositories wdsp

[/] [wdsp/] [trunk/] [rtl/] [vhdl/] [WISHBONE_FFT/] [fft_core_pipeline1.vhd] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log

-- N point FFT 
-- Uses R2^2SDF algorithm 
-- 
-- Generics used: 
-- N - number of points taken - powers of 2 only, ranging f 8 to 1024 points. 
-- input_ width - bit width  of the input vector 
--  twiddle  width - width of the twiddle factors stored in the ROM 
-- add_g - Adder growth - Adders grow 0 or 1 bits each time they are used 
--         Exculdes adders in the complex multiplier (that is handled by mult_g) 
-- mult_g - multiplier growth - 0 to twiddle_width+        1 - Growth during the complex 
--   multiplier stages 
--  
-- Width of output vector is as follows (num_stages=log2(N): 
--    N      width 
--   8,16    input_width + (num_stages * add_g) + mult_g 
--   32,64   input_width + (num_            stages * add_g) + 2*mult_g 
-- 128,256    input_width + (num_stage            s * add_g) + 3*mult_g 
-- 512,1024   input_width + (num_stages            * add_g) + 4*mult_g 
--  
-- Due to the way this system was made parameterizable, there are many signals 
-- that will remain unconnected.  This is normal. 
--  
-- Default generics are for a simple 64 point FFT 
 
-- Each stage with complex multiplier introduces a 1/2 gain
 
--Changes made by Alex-Parrado to the original version of Adam Robert Miller
 
	--Pipeline registers and clock enables, have been added. Clock frequency above of 100 MHz for all FFT sizes
 
	--Synchronous ROMs for proper RAM block inferring. MATLAB scripts have been modified.
 
 
 
LIBRARY ieee; 
USE ieee.std_logic_1164.ALL; 
 
USE ieee.numeric_std.ALL; 
--USE ieee.std_logic_arith.ALL; 
use ieee.math_real.all;
use work.fft_pkg .all; 
 
entity fft_core_pipeline1 is 
  generic (  
	input_width : integer :=16; 
   twiddle_width : integer :=16; 
   N : integer :=1024; 
   add_g : integer:=0;--1;  --Either 0 or 1 only. 
   mult_g : integer:=0--9  --Can be any number from 0 to twiddle_width+1 
   ); 
  port (  clock : in std_logic; 
   resetn : in std_logic; 
   enable : in std_logic; 
	clear : in std_logic;
	enable_out: out std_logic;
	frame_ready: out std_logic;
	index : out std_logic_vector(integer(ceil(log2(real((N)))))-1 downto 0);
      xin_r : in std_logic_vector(input_width-1 downto 0); 
      xin_i : in std_logic_vector(input_width-1 downto 0); 
      Xout_r : out std_logic_vector (input_width+((integer(ceil(log2(real((N)))))-1)/2)*mult_g+integer(ceil(log2(real((N)))))*add_g-1 downto 0); 
      Xout_i : out std_logic_vector (input_width+((integer(ceil(log2(real((N)))))-1)/2)*mult_g+integer(ceil(log2(real((N)))))*add_g-1 downto 0) 
   ); 
end fft_core_pipeline1; 
 
architecture structure of fft_core_pipeline1 is 
--Signal declarations 
constant num_stages: integer :=integer(ceil(log2(real((N))))); 
signal control: std_logic_vector(num_stages-1 downto 0); 
signal bit_reverse_index: std_logic_vector(num_stages-1 downto 0); 
type stage_array is array (1 to num_stages-1) of 
 std_logic_vector(input_width+(num_stages*add_g)+(((num_stages-1)/2)*mult_g)-1  downto 0); 
signal stoscon_r: stage_array; 
signal  stoscon_i: stage_array; 
type rom_array is array (1 to (num_stages-1)/2) of std_logic_vector(twiddle_width-1 downto 0); 
signal rtoscon_r: rom_array; 
signal rtoscon_i: rom_array; 
 
type enables_array is array (0 to num_stages+1) of std_logic_vector(0 downto 0); 
signal enables: enables_array;
 
 
type counter_registers_array is array (0 to num_stages+1) of std_logic_vector(num_stages-1 downto 0); 
signal counter_registers: counter_registers_array;
 
--
 
signal xin_r_reg :  std_logic_vector(input_width-1 downto 0); 
signal xin_i_reg :  std_logic_vector(input_width-1 downto 0); 
 
signal t_ff: std_logic_vector(0 downto 0);
signal en_t_ff:std_logic_vector(0 downto 0);
signal clear_t_ff:std_logic;
 
 
--component declarations 
component counterhle 
  generic (width : integer); 
 
  port (   clock : in std_logic; 
   resetn : in std_logic; 
   enable :  in std_logic;
	clear : in std_logic;	
      countout :  out std_logic_vector(width-1 downto 0) 
    ); 
end component; 
 
component rom1 
  generic (
		data_width :  integer; 
		address_width : integer); 
  port (
      clk: in std_logic;
		address: IN     std_logic_vector (address_width-1 DOWNTO 0); 
        datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0); 
        datai     : OUT    std_logic_vector (data_width-1  DOWNTO 0)    
    ); 
end component; 
 
component rom2 
  generic (
	data_width : integer; 
	address_width : integer); 
  port  (
  clk: in std_logic;
	address    : IN     std_logic_vector (address_width-1 DOWNTO 0); 
    datar     : OUT     std_logic_vector (data_width-1 DOWNTO 0); 
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)    
   ); 
end component; 
 
component rom3 
  generic (
	data_width : integer; 
	address_width : integer); 
  port  (
  clk: in std_logic;
	address    : IN     std_logic_vector (address_width-1 DOWNTO 0); 
    datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0); 
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)     
    ); 
end component; 
 
component rom4 
  generic (
	data_width : integer; 
	address_width : integer); 
  port  (
  clk: in std_logic;
	address    : IN     std_logic_vector (address_width-1 DOWNTO 0); 
    datar     : OUT    std_logic_vector (data_width-1 DOWNTO 0); 
    datai     : OUT    std_logic_vector (data_width-1 DOWNTO 0)    
   ); 
end component; 
 
component stage_I 
     generic  (
		data_width : INTEGER; 
		add_g : INTEGER; 
		shift_stages : INTEGER); 
  port  (
		prvs_r :in std_logic_vector(data_width-1-add_g downto 0); 
		prvs_i :in std_logic_vector(data_width-1-add_g downto 0); 
		s :in std_logic; 
		clock : in std_logic; 
		enable: in std_logic; 
		resetn : in std_logic; 
   tonext_r :out std_logic_vector(data_width-1 downto 0);     
   tonext_i :out std_logic_vector(data_width-1 downto 0)); 
end component; 
 
component stage_II 
     generic  (
		data_width : INTEGER; 
		add_g : INTEGER; 
		mult_g : INTEGER; 
		twiddle_width : INTEGER; 
		shift_stages : INTEGER
		); 
  port  (
		prvs_r :in std_logic_vector(data_width-1-add_g downto 0); 
		prvs_i :in std_logic_vector(data_width-1-add_g downto 0) ; 
		t :in std_logic; 
		s :in std_logic; 
		clock : in std_logic; 
		enable: in std_logic; 
		resetn : in std_logic; 
		fromrom_r :in std_logic_vector (twiddle_width-1 downto 0) ; 
		fromrom_i :in std_logic_vector(twiddle_width-1 downto 0); 
		tonext_r :out std_logic_vector(data_width+mult_g-1 downto 0);     
		tonext_i :out std_logic_vector(data_width+mult_g-1 downto 0)); 
end component;
 
component stage_I_last 
  generic  (
		data_width : INTEGER;
		add_g : INTEGER
		); 
  port (
		prvs_r :in std_logic_vector(data_width-1-add_g downto 0);  
		prvs_i :in std_logic_vector(data_width-1-add_g downto 0); 
        s :in std_logic; clock : in std_logic; resetn : in std_logic; 
		  enable: in std_logic; 
		tonext_r :out std_logic_vector(data_width-1 downto 0);    
		tonext_i :out std_logic_vector(data_width-1 downto 0)); 
end component;   
 
component stage_II_last 
  generic  (
		data_width : INTEGER; 
		add_g : INTEGER
		); 
  port  (
		prvs_r :in std_logic_vector(data_width-1-add_g downto 0); 
		prvs_i :in std_logic_vector(data_width-1-add_g downto 0); 
		t :in std_logic; 
		s :in std_logic; 
		clock : in std_logic; 
		enable: in std_logic; 
		resetn :  in std_logic; 
		tonext_r :out std_logic_vector(data_width-1 downto 0);    
		tonext_i :out std_logic_vector(data_width-1 downto 0)); 
end component;   
 
component shiftreg1 
  generic (
		data_width : integer
); 
  port (
		clock : IN std_logic;  
		enable: in std_logic; 
		clear: in std_logic; 
        read_data  : OUT    std_logic_vector (data_width-1 DOWNTO 0); 
        write_data : IN     std_logic_vector (data_width-1 DOWNTO 0); 
		resetn     : IN     std_logic          
		); 
end component; 
 
begin 
 
controller : component counterhle 
     generic map (
		width=>num_stages
) 
  port map (
		clock=>clock,
		resetn=>resetn,
		clear => clear,
		enable=>enable, 
		countout=>control
		); 
 
 
-- Counter, pipeline registers
counter_registers(0)<=control;
forcounterregs: for i in 0 to num_stages generate
counterregi: shiftreg1
generic  map(
		data_width=>num_stages
)
  port map (
		clock=>clock,
		enable=>'1',
		clear => clear,
        read_data=>counter_registers(i+1),
        write_data=>counter_registers(i), 
		resetn=>resetn
		); 
 
end generate;
 
 
--Enable, pipeline registers
enables(0)(0)<=enable;
forenablesregs: for i in 0 to num_stages generate
enableregi: shiftreg1
generic  map(
		data_width=>1
)
  port map (
		clock=>clock,
		enable=>'1',
		clear => clear,
        read_data=>enables(i+1),
        write_data=>enables(i), 
		resetn=>resetn
		); 
 
end generate;
 
 
 
--Input registers
reginputr: shiftreg1
generic  map(
		data_width=>input_width
)
  port map (
		clock=>clock,
		enable=>'1',
		clear => '0',
        read_data=>xin_r_reg,
        write_data=>xin_r, 
		resetn=>resetn
		); 
 
reginputi: shiftreg1
generic  map(
		data_width=>input_width
)
  port map (
		clock=>clock,
		enable=>'1',
		clear => '0',
        read_data=>xin_i_reg,
        write_data=>xin_i, 
		resetn=>resetn
		); 
 
 
stages : for i in 1 to num_stages generate 
--  constan ity : in r :=i rem 2;  t par tege
--  constant shift_stages : integer := 2**(num_stages - i); 
--  consta nt rom_loc : integer :=i/2; 
--  constant data_width : integer :=input_width + (i*add_g) + (((i-1)/2)*mult_g); 
--  constant s: integer :      =(num_stages-i); 
--  constant t    : integer :=(num_stages-i+1); 
     initial_stage: if i=1 generate 
    initial_stage_I :  component stage_I 
      generic map (
		data_width=>input_width + (i*add_g)+(((i-1)/2)*mult_g),  
		add_g=>add_g, 
		shift_stages=>2**(num_stages - i)) 
    port map (
		prvs_r=>xin_r_reg,prvs_i=>xin_i_reg,s=>counter_registers(i)((num_stages-i)),
		clock=>clock,
		enable=>enables(i)(0),
		resetn=>resetn, 
		tonext_r=>stoscon_r(i)(input_width+(i*add_g) + (( (i-1)/2)*mult_g)-1 downto 0), 
        tonext_i=>stoscon_i(i)(input_width+ (i*add_g) + (( (i-1)/2)*mult_g)-1 downto 0)); 
  end generate initial_stage; 
 
  even_stages: if ((i rem 2)=0) and (i/=num_stages) generate 
    inner_stage_II : component stage_II 
      generic map (
		data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g), 
		add_g=>add_g,mult_g=>mult_g, 
		twiddle_width=>twiddle_width, 
		shift_stages=>2**(num_stages - i)
		) 
    port map ( 
		prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i -1)/2)*mult_g)-1-add_g downto 0), 
		prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		t=>counter_registers(i)((num_stages-i+1)),
		s=>counter_registers(i)((num_stages-i)),clock=>clock,resetn=>resetn,     
		enable=>enables(i)(0),		
		fromrom_r=>rtoscon_r(i/2),fromrom_i=>rtoscon_i(i/2), 
        tonext_r=>stoscon_r(i)(input_width + (i*add_g) + (((i-1)/2)*mult_g)+mult_g-1 downto 0), 
        tonext_i=>stoscon_i(i)(input_width +  (i*add_g) + (((i-1)/2)*mult_g)+mult_g-1 downto 0)
		); 
 
    first_rom: if (i/2)=1 generate 
    rom_1 : component rom1 
 
    generic map (
		data_width=>twiddle_width, 
		address_width=>(num_stages-i+1)+1
		) 
      port map ( 
		clk=>clock,
		address=>counter_registers(i-1)((num_stages-i+1) downto 0 ),       
		datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)); 
  end   generate first_rom; 
 
       second_rom: if (i/2)=2 generate 
    rom_2 : component rom2 
     generic map (
		data_width=>twiddle_width, 
		address_width=>(num_stages-i+1)+1
		) 
    port map ( 
	 clk=>clock,
		address=>counter_registers(i-1)((num_stages-i+1  ) downto 0),        
		datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
		); 
  end generate second_rom; 
 
    third_rom: if (i/2)=3 generate 
   rom_3 : component rom3 
    generic map (
 
		data_width  =>twiddle_width, 
		address_width=>(num_stages-i+1)+1
		) 
    port map ( 
	 clk=>clock,
		address=>counter_registers(i-1)((num_stages-i+1) downto 0),        
		datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
		); 
    end generate third_rom;  
 
    fourth_rom: if (i/2)=4 generate 
    rom_4 : component rom4 
     generic map (
		data_width=>twiddle_width, 
		address_width=>(num_stages-i+1)+1
		) 
    port map ( 
	 clk=>clock,
		address=>counter_registers(i-1)((num_stages-i+1) downto 0),       
		datar=>rtoscon_r(i/2),datai=>rtoscon_i(i/2)
		); 
  end generate fourth_rom;  
 
  end generate even_stages; 
 
 
 
  odd_stages: if (((i rem 2)=1) and (i/=num_stages)) and (i/=1)
  generate 
    inner_stage_I : component stage_I 
         generic map (
		data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g),  
		add_g=>add_g, 
		shift_stages=>2**(num_stages - i)
		) 
   port map ( 
		prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		prvs_i=>stoscon_i(i-1)(input_width + (i*add_g)  + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		s=>counter_registers(i)( (num_stages-i)),
		enable=>enables(i)(0),
		clock=>clock,
		resetn=>resetn, 
		tonext_r=>stoscon_r(i)(input_width+ (i*add_g) + ( ((i -1)/2)*mult_g)-1 downto 0), 
		tonext_i=>stoscon_i(i)(input_width +  (i*add_g) + ( ((i- 1)/2)*mult_g)-1 downto 0)
		); 
  end generate odd_stages; 
 
  end_on_even: if (i=num_stages) and ((i rem 2)=0) generate 
    last_stage_II : component stage_II_last 
      generic map (
		data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g), 
		add_g=>add_g
		) 
   port map ( 
		prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		t=>counter_registers(i)((num_stages-i+1)),
		s=>counter_registers(i)((num_stages-i)),clock=>clock ,
		resetn=>resetn, 
		enable=>enables(i)(0),
		tonext_r=>Xout_r,
		tonext_i=>Xout_i
		); 
  end generate end_on_even; 
 
  end_on_odd: if (i=num_stages) and ((i rem 2)=1) generate 
    last_stage_I : component stage_I_last 
      generic map (
		data_width=>input_width + (i*add_g) + (((i-1)/2)*mult_g), add_g=>add_g
		) 
   port map ( 
		prvs_r=>stoscon_r(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		prvs_i=>stoscon_i(i-1)(input_width + (i*add_g) + (((i-1)/2)*mult_g)-1-add_g downto 0), 
		s=>counter_registers(i)( (num_stages-i)),
		clock=>clock,
		enable=>enables(i)(0),
		resetn=>resetn, 
		tonext_r=>Xout_r,
		tonext_i=>Xout_i
		); 
 
 
  end generate end_on_odd; 
 
end generate stages; 
 
--Frequency bin with bit reversal
bit_reverse_index<=std_logic_vector(unsigned(counter_registers(num_stages+1))+1);
 
bit_reverse: for i in 0 to num_stages-1 generate
			index(i)<=bit_reverse_index(num_stages-1-i);
 
end generate;
 
 
--T flip-flop for enable_out generation control
 
tff: shiftreg1 generic  map(
		data_width=>1
)
  port map (
		clock=>clock,
		enable=>((en_t_ff(0) or clear_t_Ff) and enables(num_stages)(0))  or clear,
		clear => clear or clear_t_ff,
        read_data=>t_ff,
        write_data=>en_t_ff, 
		resetn=>resetn
		); 
 
 
 
en_t_ff(0)<= '1' when (unsigned(counter_registers(num_stages+1))=(N-1)) else '0';
clear_t_ff <= '1' when (unsigned(counter_registers(num_stages+1))=(N-1) and t_ff(0)='1') else '0';
 
--Enable out includes pipeline latency 
enable_out<=enables(num_stages+1)(0) when (t_ff="1")  else '0' ;
 
 
--Frame ready, falling edge detector
 
process(resetn,clock)
      variable detect : std_ulogic_vector (1 downto 0);
   begin
      if resetn ='0' then
         detect := "00";
 
      elsif rising_edge(clock) then
 
		if (clear ='1') then
 
		frame_ready<='0';
 
		else
 
         detect(1) := detect(0); -- record last value of sync in detect(1)
         detect(0) := t_ff(0) ; --record current sync in detect(0)
 
         if detect = "01" then -- rising_edge
 
			frame_ready<='0';
 
         elsif detect = "10" then --falling_edge
 
frame_ready<='1';		
 
 
         end if;
 
			end if;
 
      end if;
end process;
 
 
 
 
end; 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.