# ----------------------------------------------------------------------------- # (C) Bibix # The content below includes confidential, proprietary information of # Bibix. All use, disclosure, and/or reproduction is prohibited # unless authorized in writing. All rights reserved. # ----------------------------------------------------------------------------- # File : fft_r2_16p.arx # Description : Radix-2 decimation-in-frequency 16-point parallel FFT with # external twiddle factors # Author : Sabih Gerez, Bibix # based on work by Rene Moll, DSE # Creation date: Sepbember 1, 2011 # ----------------------------------------------------------------------------- # $Rev: 162 $ # $Author: sabih $ # $Date: 2011-09-11 00:42:39 +0200 (Sun, 11 Sep 2011) $ # $Log$ # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # The description below is a straightforward implementation of a # 16-point textbook decimation-in-frequency FFT. The 16 inputs are # supposed to be delivered in parallel. # # The structure is as follows assuming that inputs are at the left and # outputs at the right: # - The 16-point FFT is built by first instantiating 8 butterflies and # properly connecting them to 2 8-point FFTs at their right. # - The 8-point FFT is built by first instantiating 4 butterflies and # properly connecting them to 2 4-point FFTs at their right. # - The 4-point FFT is built by first instantiating 2 butterflies and # properly connecting them to 2 more butterflies at their right. # # There are registers at the outputs of a butterfly, giving the design # a latency of 4. # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Complex multiplier # ----------------------------------------------------------------------------- component complex_mult # Generic - settings IO_WL : generic integer = 10 # Word length IO_IWL : generic integer = 2 # Integer word length # Generic - types T_IO : generic type = signed(IO_WL, IO_IWL) T_MULT : generic type = signed(2*IO_WL,2*IO_IWL) # Ports x_real : in T_IO x_imag : in T_IO y_real : in T_IO y_imag : in T_IO z_real : out T_IO z_imag : out T_IO variable m1 : T_MULT m2 : T_MULT m3 : T_MULT m4 : T_MULT begin m1 = convert(T_MULT, x_real * y_real) m2 = convert(T_MULT, x_imag * y_imag) m3 = convert(T_MULT, x_real * y_imag) m4 = convert(T_MULT, x_imag * y_real) z_real = convert(T_IO, m1 - m2) z_imag = convert(T_IO, m3 + m4) end # ----------------------------------------------------------------------------- # Radix-2 butterfly # Decimation in frequency # ----------------------------------------------------------------------------- component fft_r2_bf # Generic - settings IO_WL : generic integer = 10 # Word length IO_IWL : generic integer = 2 # Integer word length # Generic - types T_IO : generic type = signed(IO_WL, IO_IWL) T_MULT : generic type = signed(2*IO_WL,2*IO_IWL) # Ports a_real_in : in T_IO a_imag_in : in T_IO b_real_in : in T_IO b_imag_in : in T_IO twiddle_real : in T_IO twiddle_imag : in T_IO a_real_out : out T_IO a_imag_out : out T_IO b_real_out : out T_IO b_imag_out : out T_IO variable cmult_real : T_IO cmult_imag : T_IO register a_real_reg : T_IO = 0 a_imag_reg : T_IO = 0 b_real_reg : T_IO = 0 b_imag_reg : T_IO = 0 generate # multiplication along bottom path of butterfly cmult : complex_mult T_IO = T_IO T_MULT = T_MULT x_real => twiddle_real x_imag => twiddle_imag y_real => cmult_real y_imag => cmult_imag z_real => b_real_reg z_imag => b_imag_reg begin # addition along top path a_real_reg = a_real_in + b_real_in a_imag_reg = a_imag_in + b_imag_in # subtraction along bottom path cmult_real = a_real_in - b_real_in cmult_imag = a_imag_in - b_imag_in # connect registers to outputs a_real_out = a_real_reg a_imag_out = a_imag_reg b_real_out = b_real_reg b_imag_out = b_imag_reg end # ----------------------------------------------------------------------------- # 4 point Radix-2 FFT # ----------------------------------------------------------------------------- component fft_r2_4p # Generic - settings IO_WL : generic integer = 10 # Word length IO_IWL : generic integer = 2 # Integer word length # Generic - types T_IO : generic type = signed(IO_WL, IO_IWL) T_MULT : generic type = signed(2*IO_WL,2*IO_IWL) # Ports x0_real : in T_IO x0_imag : in T_IO x1_real : in T_IO x1_imag : in T_IO x2_real : in T_IO x2_imag : in T_IO x3_real : in T_IO x3_imag : in T_IO twiddle_0_real : in T_IO twiddle_0_imag : in T_IO twiddle_1_real : in T_IO twiddle_1_imag : in T_IO y0_real : out T_IO y0_imag : out T_IO y1_real : out T_IO y1_imag : out T_IO y2_real : out T_IO y2_imag : out T_IO y3_real : out T_IO y3_imag : out T_IO variable int_0_real : T_IO int_0_imag : T_IO int_1_real : T_IO int_1_imag : T_IO int_2_real : T_IO int_2_imag : T_IO int_3_real : T_IO int_3_imag : T_IO generate # Input butterflies (2 points) bf_in_1 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x0_real a_imag_in => x0_imag b_real_in => x2_real b_imag_in => x2_imag twiddle_real => twiddle_0_real twiddle_imag => twiddle_0_imag a_real_out => int_0_real a_imag_out => int_0_imag b_real_out => int_2_real b_imag_out => int_2_imag bf_in_2 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x1_real a_imag_in => x1_imag b_real_in => x3_real b_imag_in => x3_imag twiddle_real => twiddle_1_real twiddle_imag => twiddle_1_imag a_real_out => int_1_real a_imag_out => int_1_imag b_real_out => int_3_real b_imag_out => int_3_imag # Output butterflies (2 points) bf_out_1 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => int_0_real a_imag_in => int_0_imag b_real_in => int_1_real b_imag_in => int_1_imag twiddle_real => twiddle_0_real twiddle_imag => twiddle_0_imag a_real_out => y0_real a_imag_out => y0_imag b_real_out => y1_real b_imag_out => y1_imag bf_out_2 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => int_2_real a_imag_in => int_2_imag b_real_in => int_3_real b_imag_in => int_3_imag twiddle_real => twiddle_0_real twiddle_imag => twiddle_0_imag a_real_out => y2_real a_imag_out => y2_imag b_real_out => y3_real b_imag_out => y3_imag begin end # ----------------------------------------------------------------------------- # 8 point Radix-2 FFT # ----------------------------------------------------------------------------- component fft_r2_8p # Generic - settings IO_WL : generic integer = 10 # Word length IO_IWL : generic integer = 2 # Integer word length # Generic - types T_IO : generic type = signed(IO_WL, IO_IWL) T_MULT : generic type = signed(2*IO_WL,2*IO_IWL) # Ports x0_real : in T_IO x0_imag : in T_IO x1_real : in T_IO x1_imag : in T_IO x2_real : in T_IO x2_imag : in T_IO x3_real : in T_IO x3_imag : in T_IO x4_real : in T_IO x4_imag : in T_IO x5_real : in T_IO x5_imag : in T_IO x6_real : in T_IO x6_imag : in T_IO x7_real : in T_IO x7_imag : in T_IO y0_real : out T_IO y0_imag : out T_IO y1_real : out T_IO y1_imag : out T_IO y2_real : out T_IO y2_imag : out T_IO y3_real : out T_IO y3_imag : out T_IO y4_real : out T_IO y4_imag : out T_IO y5_real : out T_IO y5_imag : out T_IO y6_real : out T_IO y6_imag : out T_IO y7_real : out T_IO y7_imag : out T_IO twiddle_0_real : in T_IO twiddle_0_imag : in T_IO twiddle_1_real : in T_IO twiddle_1_imag : in T_IO twiddle_2_real : in T_IO twiddle_2_imag : in T_IO twiddle_3_real : in T_IO twiddle_3_imag : in T_IO variable int_real : array[8] of T_IO int_imag : array[8] of T_IO generate # Input butterflies (2 points) bf_in_1 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x0_real a_imag_in => x0_imag b_real_in => x4_real b_imag_in => x4_imag twiddle_real => twiddle_0_real twiddle_imag => twiddle_0_imag a_real_out => int_real[0] a_imag_out => int_imag[0] b_real_out => int_real[4] b_imag_out => int_imag[4] bf_in_2 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x1_real a_imag_in => x1_imag b_real_in => x5_real b_imag_in => x5_imag twiddle_real => twiddle_1_real twiddle_imag => twiddle_1_imag a_real_out => int_real[1] a_imag_out => int_imag[1] b_real_out => int_real[5] b_imag_out => int_imag[5] bf_in_3 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x2_real a_imag_in => x2_imag b_real_in => x6_real b_imag_in => x6_imag twiddle_real => twiddle_2_real twiddle_imag => twiddle_2_imag a_real_out => int_real[2] a_imag_out => int_imag[2] b_real_out => int_real[6] b_imag_out => int_imag[6] bf_in_4 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x3_real a_imag_in => x3_imag b_real_in => x7_real b_imag_in => x7_imag twiddle_real => twiddle_3_real twiddle_imag => twiddle_3_imag a_real_out => int_real[3] a_imag_out => int_imag[3] b_real_out => int_real[7] b_imag_out => int_imag[7] # Output butterflies (4 points) fft4_out_1 : fft_r2_4p T_IO = T_IO T_MULT = T_MULT x0_real => int_real[0] x0_imag => int_imag[0] x1_real => int_real[1] x1_imag => int_imag[1] x2_real => int_real[2] x2_imag => int_imag[2] x3_real => int_real[3] x3_imag => int_imag[3] twiddle_0_real => twiddle_0_real twiddle_0_imag => twiddle_0_imag twiddle_1_real => twiddle_2_real twiddle_1_imag => twiddle_2_imag y0_real => y0_real y0_imag => y0_imag y1_real => y1_real y1_imag => y1_imag y2_real => y2_real y2_imag => y2_imag y3_real => y3_real y3_imag => y3_imag fft4_out_2 : fft_r2_4p T_IO = T_IO T_MULT = T_MULT x0_real => int_real[4] x0_imag => int_imag[4] x1_real => int_real[5] x1_imag => int_imag[5] x2_real => int_real[6] x2_imag => int_imag[6] x3_real => int_real[7] x3_imag => int_imag[7] twiddle_0_real => twiddle_0_real twiddle_0_imag => twiddle_0_imag twiddle_1_real => twiddle_2_real twiddle_1_imag => twiddle_2_imag y0_real => y4_real y0_imag => y4_imag y1_real => y5_real y1_imag => y5_imag y2_real => y6_real y2_imag => y6_imag y3_real => y7_real y3_imag => y7_imag begin end # ----------------------------------------------------------------------------- # 16 point Radix-2 FFT # ----------------------------------------------------------------------------- component top # Generic - settings IO_WL : generic integer = 10 # Word length IO_IWL : generic integer = 6 # Integer word length # Generic - types T_IO : generic type = signed(IO_WL, IO_IWL) T_MULT : generic type = signed(2*IO_WL,2*IO_IWL) # Ports x0_real : in T_IO x0_imag : in T_IO x1_real : in T_IO x1_imag : in T_IO x2_real : in T_IO x2_imag : in T_IO x3_real : in T_IO x3_imag : in T_IO x4_real : in T_IO x4_imag : in T_IO x5_real : in T_IO x5_imag : in T_IO x6_real : in T_IO x6_imag : in T_IO x7_real : in T_IO x7_imag : in T_IO x8_real : in T_IO x8_imag : in T_IO x9_real : in T_IO x9_imag : in T_IO x10_real : in T_IO x10_imag : in T_IO x11_real : in T_IO x11_imag : in T_IO x12_real : in T_IO x12_imag : in T_IO x13_real : in T_IO x13_imag : in T_IO x14_real : in T_IO x14_imag : in T_IO x15_real : in T_IO x15_imag : in T_IO y0_real : out T_IO y0_imag : out T_IO y1_real : out T_IO y1_imag : out T_IO y2_real : out T_IO y2_imag : out T_IO y3_real : out T_IO y3_imag : out T_IO y4_real : out T_IO y4_imag : out T_IO y5_real : out T_IO y5_imag : out T_IO y6_real : out T_IO y6_imag : out T_IO y7_real : out T_IO y7_imag : out T_IO y8_real : out T_IO y8_imag : out T_IO y9_real : out T_IO y9_imag : out T_IO y10_real : out T_IO y10_imag : out T_IO y11_real : out T_IO y11_imag : out T_IO y12_real : out T_IO y12_imag : out T_IO y13_real : out T_IO y13_imag : out T_IO y14_real : out T_IO y14_imag : out T_IO y15_real : out T_IO y15_imag : out T_IO variable # twiddle factors (workaround for Arx not accepting constants) twiddle_0_real : T_IO twiddle_0_imag : T_IO twiddle_1_real : T_IO twiddle_1_imag : T_IO twiddle_2_real : T_IO twiddle_2_imag : T_IO twiddle_3_real : T_IO twiddle_3_imag : T_IO twiddle_4_real : T_IO twiddle_4_imag : T_IO twiddle_5_real : T_IO twiddle_5_imag : T_IO twiddle_6_real : T_IO twiddle_6_imag : T_IO twiddle_7_real : T_IO twiddle_7_imag : T_IO # intermediate signals (connecting 8 2-point butterflies to 2 # 8-point FFTs) int_real : array[16] of T_IO int_imag : array[16] of T_IO generate # Input butterflies (2 points) bf_in_1 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x0_real a_imag_in => x0_imag b_real_in => x8_real b_imag_in => x8_imag twiddle_real => twiddle_0_real twiddle_imag => twiddle_0_imag a_real_out => int_real[0] a_imag_out => int_imag[0] b_real_out => int_real[8] b_imag_out => int_imag[8] bf_in_2 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x1_real a_imag_in => x1_imag b_real_in => x9_real b_imag_in => x9_imag twiddle_real => twiddle_1_real twiddle_imag => twiddle_1_imag a_real_out => int_real[1] a_imag_out => int_imag[1] b_real_out => int_real[9] b_imag_out => int_imag[9] bf_in_3 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x2_real a_imag_in => x2_imag b_real_in => x10_real b_imag_in => x10_imag twiddle_real => twiddle_2_real twiddle_imag => twiddle_2_imag a_real_out => int_real[2] a_imag_out => int_imag[2] b_real_out => int_real[10] b_imag_out => int_imag[10] bf_in_4 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x3_real a_imag_in => x3_imag b_real_in => x11_real b_imag_in => x11_imag twiddle_real => twiddle_3_real twiddle_imag => twiddle_3_imag a_real_out => int_real[3] a_imag_out => int_imag[3] b_real_out => int_real[11] b_imag_out => int_imag[11] bf_in_5 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x4_real a_imag_in => x4_imag b_real_in => x12_real b_imag_in => x12_imag twiddle_real => twiddle_4_real twiddle_imag => twiddle_4_imag a_real_out => int_real[4] a_imag_out => int_imag[4] b_real_out => int_real[12] b_imag_out => int_imag[12] bf_in_6 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x5_real a_imag_in => x5_imag b_real_in => x13_real b_imag_in => x13_imag twiddle_real => twiddle_5_real twiddle_imag => twiddle_5_imag a_real_out => int_real[5] a_imag_out => int_imag[5] b_real_out => int_real[13] b_imag_out => int_imag[13] bf_in_7 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x6_real a_imag_in => x6_imag b_real_in => x14_real b_imag_in => x14_imag twiddle_real => twiddle_6_real twiddle_imag => twiddle_6_imag a_real_out => int_real[6] a_imag_out => int_imag[6] b_real_out => int_real[14] b_imag_out => int_imag[14] bf_in_8 : fft_r2_bf T_IO = T_IO T_MULT = T_MULT a_real_in => x7_real a_imag_in => x7_imag b_real_in => x15_real b_imag_in => x15_imag twiddle_real => twiddle_7_real twiddle_imag => twiddle_7_imag a_real_out => int_real[7] a_imag_out => int_imag[7] b_real_out => int_real[15] b_imag_out => int_imag[15] # Output butterflies (8 points) fft8_out_1 : fft_r2_8p T_IO = T_IO T_MULT = T_MULT x0_real => int_real[0] x0_imag => int_imag[0] x1_real => int_real[1] x1_imag => int_imag[1] x2_real => int_real[2] x2_imag => int_imag[2] x3_real => int_real[3] x3_imag => int_imag[3] x4_real => int_real[4] x4_imag => int_imag[4] x5_real => int_real[5] x5_imag => int_imag[5] x6_real => int_real[6] x6_imag => int_imag[6] x7_real => int_real[7] x7_imag => int_imag[7] twiddle_0_real => twiddle_0_real twiddle_0_imag => twiddle_0_imag twiddle_1_real => twiddle_2_real twiddle_1_imag => twiddle_2_imag twiddle_2_real => twiddle_4_real twiddle_2_imag => twiddle_4_imag twiddle_3_real => twiddle_6_real twiddle_3_imag => twiddle_6_imag y0_real => y0_real y0_imag => y0_imag y1_real => y1_real y1_imag => y1_imag y2_real => y2_real y2_imag => y2_imag y3_real => y3_real y3_imag => y3_imag y4_real => y4_real y4_imag => y4_imag y5_real => y5_real y5_imag => y5_imag y6_real => y6_real y6_imag => y6_imag y7_real => y7_real y7_imag => y7_imag fft8_out_2 : fft_r2_8p T_IO = T_IO T_MULT = T_MULT x0_real => int_real[8] x0_imag => int_imag[8] x1_real => int_real[9] x1_imag => int_imag[9] x2_real => int_real[10] x2_imag => int_imag[10] x3_real => int_real[11] x3_imag => int_imag[11] x4_real => int_real[12] x4_imag => int_imag[12] x5_real => int_real[13] x5_imag => int_imag[13] x6_real => int_real[14] x6_imag => int_imag[14] x7_real => int_real[15] x7_imag => int_imag[15] twiddle_0_real => twiddle_0_real twiddle_0_imag => twiddle_0_imag twiddle_1_real => twiddle_2_real twiddle_1_imag => twiddle_2_imag twiddle_2_real => twiddle_4_real twiddle_2_imag => twiddle_4_imag twiddle_3_real => twiddle_6_real twiddle_3_imag => twiddle_6_imag y0_real => y8_real y0_imag => y8_imag y1_real => y9_real y1_imag => y9_imag y2_real => y10_real y2_imag => y10_imag y3_real => y11_real y3_imag => y11_imag y4_real => y12_real y4_imag => y12_imag y5_real => y13_real y5_imag => y13_imag y6_real => y14_real y6_imag => y14_imag y7_real => y15_real y7_imag => y15_imag begin # assign values to twiddle factors twiddle_0_real = 1.000000000000000 twiddle_0_imag = 0.000000000000000 twiddle_1_real = 0.923879532511287 twiddle_1_imag = -0.382683432365090 twiddle_2_real = 0.707106781186548 twiddle_2_imag = -0.707106781186548 twiddle_3_real = 0.382683432365090 twiddle_3_imag = -0.923879532511287 twiddle_4_real = 0.000000000000000 twiddle_4_imag = -1.000000000000000 twiddle_5_real = -0.382683432365090 twiddle_5_imag = -0.923879532511287 twiddle_6_real = -0.707106781186548 twiddle_6_imag = -0.707106781186548 twiddle_7_real = -0.923879532511287 twiddle_7_imag = -0.382683432365090 end