Anda di halaman 1dari 22

1.

DESIGN DESCRIPTION:
Discrete Fourier transform is used convert the samples in time domain to equivalent frequency
domain. The DFT transformation for N samples is as given below:


 =

 

Where 
is equal to 




To compute DFT of N samples we require   complex multiplications and additions.


Fast Fourier transform (FFT) is an efficient algorithm to compute the discrete Fourier
transform (DFT). There are many distinct FFT algorithms involving a wide range of
mathematics, from simple complex-number arithmetic to group theory and number theory. FFT
has got wide application in speech processing, frequency estimation, communication etc.
In the below module we have used Radix 2 DIT FFT which is computed as represented in the
Figure (1.1).

Figure 1.1: Radix 2 DIT using FFT algorithm for N = 8.

1.1 Design Assumptions:

As Verilog HDL doesnt support data types that are complex in nature we have split
up the real and imaginary parts and computed them separately.

In the code all the input data is scaled by 10 to consider the fractional part and the
output data which will be generated by the code will be scaled by 100.

The twiddle factors are declared as parameters since they are constant.

The output is computed is stage wise where the output of the first stage is given as
input to the next stage.

The output of the second stage N=4 butterfly and also the twiddle factors required to
compute N=8 butterfly are scaled by 10.

2. BLOCK DIAGRAM:

Real Inputs

Real Outputs

Imaginary Inputs

Imaginary Outputs

Figure 2.1: Block diagram of DIT using FFT for N= 8

3. CONNECTION BETWEEN TEST BENCH AND MODULE:

Figure 3.1: Connection between test bench and module.

4. VERILOG CODE FOR FFT MODULE:


module FFT_main(x0r, x1r, x2r, x3r, x4r, x5r, x6r, x7r,
x0i, x1i, x2i, x3i, x4i, x5i, x6i, x7i,
enable_bar, clk, reset_bar,
X0r, X1r, X2r, X3r, X4r, X5r, X6r, X7r,
X0i, X1i, X2i, X3i, X4i, X5i, X6i, X7i, done);
// 8 bit real part of input signal scaled by 10
input signed[7:0] x0r,x1r,x2r,x3r,x4r,x5r,x6r,x7r;
// 8 bit imaginary part of input signal scaled by 10
input signed[7:0] x0i,x1i,x2i,x3i,x4i,x5i,x6i,x7i;
input enable_bar, clk, reset_bar; // Input control signals
// 16 bit real part of output signal which will be scaled by 100
output signed[15:0] X0r,X1r,X2r,X3r,X4r,X5r,X6r,X7r;
// 16 bit imaginary part of output signal which will be scaled by 100
output signed[15:0] X0i,X1i,X2i,X3i,X4i,X5i,X6i,X7i;
output done; // Output done signal will be set to high when FFT computation is completed

wire signed[7:0] x0r,x1r,x2r,x3r,x4r,x5r,x6r,x7r;


wire signed[7:0] x0i,x1i,x2i,x3i,x4i,x5i,x6i,x7i;
wire enable_bar, clk, reset_bar;
reg signed[15:0] X0r,X1r,X2r,X3r,X4r,X5r,X6r,X7r;
reg signed[15:0] X0i,X1i,X2i,X3i,X4i,X5i,X6i,X7i;
reg done;

// Initializing phase factors


parameter w80 = 1;
parameter w81r = 7, w81i = -7;
parameter w82r = 0, w82i = -1;
parameter w82s2r = 0, w82s2i = -10;
parameter w83r = -7, w83i = -7;

// w81 = 0.7-j0.7 here this value is scaled by 10


// w82 = 0-j
//w82 = 0-j scaled by 10
//w83 = -0.7-j0.7 here this value is scaled by 10

// Intermediate Registers used in the module


// Real part of output of 1st stage butterfly unit N=2
reg signed[7:0] x0s1r,x1s1r,x2s1r,x3s11r,x3s12r,x4s1r,x5s1r,x6s1r,x7s11r,x7s12r;

// Imaginary part of output of 1st stage butterfly unit N=2


reg signed[7:0] x0s1i,x1s1i,x2s1i,x3s11i,x3s12i,x4s1i,x5s1i,x6s1i,x7s11i,x7s12i;
// Real part of output of 2nd stage butterfly unit N=4
reg signed[15:0] x0s21r,x1s21r,x2s21r,x3s21r,x4s21r,x5s21r,x6s21r,x7s21r;
// Imaginary part of output of 2nd stage butterfly unit N=4
reg signed[15:0] x0s21i,x1s21i,x2s21i,x3s21i,x4s21i,x5s21i,x6s21i,x7s21i;
// Real output of 2nd stage butterfly unit N=4 after multiplying with phase or scale factor
reg signed[15:0] x0s22r,x1s22r,x2s22r,x3s22r,x4s22r,x5s22r,x6s22r,x7s22r;
/* Imaginary part of output of 2nd stage butterfly unit N=4 after multiplying with phase or
scale factor */
reg signed[15:0] x0s22i,x1s22i,x2s22i,x3s22i,x4s22i,x5s22i,x6s22i,x7s22i;
always @ (negedge clk)
begin
if (reset_bar==0)
begin
// reset all Real and Imaginary output values to zero
X0r = 0;
X1r = 0;
X2r = 0;
X3r = 0;
X4r = 0;
X5r = 0;
X6r = 0;
X7r = 0;
X0i = 0;
X1i = 0;
X2i = 0;
X3i = 0;
X4i = 0;
X5i = 0;
X6i = 0;
X7i = 0;
done = 0;
end
else // Starts if reset_bar is 1
begin
if (enable_bar==0 && reset_bar==1)
begin
// Computing the real and imaginary outputs of 1st stage butterfly N=2 output
x0s1r = x0r + x4r;

x0s1i = x0i + x4i;


x1s1r = x0r - x4r;
x1s1i = x0i - x4i;
x2s1r = x2r + x6r;
x2s1i = x2i + x6i;
x3s11r = x2r - x6r;
x3s11i = x2i - x6i;
x4s1r = x1r + x5r;
x4s1i = x1i + x5i;
x5s1r = x1r - x5r;
x5s1i = x1i - x5i;
x6s1r = x3r + x7r;
x6s1i = x3i + x7i;
x7s11r = x3r - x7r;
x7s11i = x3i - x7i;
// Multiplying the output of 1st stage butterfly N=2 by phase factors
x3s12r = (x3s11r * w82r) - (x3s11i * w82i);
x3s12i = (x3s11r * w82i) + (x3s11i * w82r);
x7s12r = (x7s11r * w82r) - (x7s11i * w82i);
x7s12i = (x7s11r * w82i) + (x7s11i * w82r);
// Computing the real and imaginary outputs of 2nd stage butterfly N=4
x0s21r = x0s1r + x2s1r;
x0s21i = x0s1i + x2s1i;
x1s21r = x1s1r + x3s12r;
x1s21i = x1s1i + x3s12i;
x2s21r = x0s1r - x2s1r;
x2s21i = x0s1i - x2s1i;
x3s21r = x1s1r - x3s12r;
x3s21i = x1s1i - x3s12i;
x4s21r = x4s1r + x6s1r;
x4s21i = x4s1i + x6s1i;
x5s21r = x5s1r + x7s12r;
x5s21i = x5s1i + x7s12i;
x6s21r = x4s1r - x6s1r;
x6s21i = x4s1i - x6s1i;
x7s21r = x5s1r - x7s12r;
x7s21i = x5s1i - x7s12i;
// Multiplying 2nd stage butterfly N=4 output by scale factor (= 10)
x0s22r = x0s21r * 10;
x0s22i = x0s21i * 10;
x1s22r = x1s21r * 10;
x1s22i = x1s21i * 10;
x2s22r = x2s21r * 10;

x2s22i = x2s21i * 10;


x3s22r = x3s21r * 10;
x3s22i = x3s21i * 10;
x4s22r = x4s21r * 10;
x4s22i = x4s21i * 10;
/* Multiplying 2nd stage butterfly N=4 output by phase factor which
are scaled during initialization */
x5s22r = (x5s21r * w81r) - (x5s21i * w81i);
x5s22i = (x5s21r * w81i) + (x5s21i * w81r);
x6s22r = (x6s21r * w82s2r) - (x6s21i * w82s2i);
x6s22i = (x6s21r * w82s2i) + (x6s21i * w82s2r);
x7s22r = (x7s21r * w83r) - (x7s21i * w83i);
x7s22i = (x7s21r * w83i) + (x7s21i * w83r);

// Computing final outputs


X0r = x0s22r + x4s22r;
X0i = x0s22i + x4s22i;
X1r = x1s22r + x5s22r;
X1i = x1s22i + x5s22i;
X2r = x2s22r + x6s22r;
X2i = x2s22i + x6s22i;
X3r = x3s22r + x7s22r;
X3i = x3s22i + x7s22i;
X4r = x0s22r - x4s22r;
X4i = x0s22i - x4s22i;
X5r = x1s22r - x5s22r;
X5i = x1s22i - x5s22i;
X6r = x2s22r - x6s22r;
X6i = x2s22i - x6s22i;
X7r = x3s22r - x7s22r;
X7i = x3s22i - x7s22i;
done = 1; // Done = 1 indicates that all the calculation are complete
end
else
begin
done = 0; // It indicates that system has been reset
end
end
end
endmodule

5. TEST BENCH FOR FFT MODULE:


module FFT_TestBench();
parameter clkDelay = 50;
// Inputs to the FFT module
reg [7:0] x0r;
reg [7:0] x1r;
reg [7:0] x2r;
reg [7:0] x3r;
reg [7:0] x4r;
reg [7:0] x5r;
reg [7:0] x6r;
reg [7:0] x7r;
reg [7:0] x0i;
reg [7:0] x1i;
reg [7:0] x2i;
reg [7:0] x3i;
reg [7:0] x4i;
reg [7:0] x5i;
reg [7:0] x6i;
reg [7:0] x7i;
reg enable_bar;
reg clk;
reg reset_bar;
// Outputs from the FFT module
wire [15:0] X0r;
wire [15:0] X1r;
wire [15:0] X2r;
wire [15:0] X3r;
wire [15:0] X4r;
wire [15:0] X5r;
wire [15:0] X6r;
wire [15:0] X7r;
wire [15:0] X0i;
wire [15:0] X1i;
wire [15:0] X2i;
wire [15:0] X3i;
wire [15:0] X4i;

wire [15:0] X5i;


wire [15:0] X6i;
wire [15:0] X7i;
wire done;
always
// initializing the clock
begin
#(clkDelay/2) clk = 1;
#(clkDelay/2) clk = 0;
end
// Instantiate the FFT_Main
FFT_main fft (.x0r(x0r), .x1r(x1r), .x2r(x2r), .x3r(x3r),
.x4r(x4r), .x5r(x5r), .x6r(x6r), .x7r(x7r),
.x0i(x0i), .x1i(x1i), .x2i(x2i), .x3i(x3i),
.x4i(x4i), .x5i(x5i), .x6i(x6i), .x7i(x7i),
.enable_bar(enable_bar),
.clk(clk),
.reset_bar(reset_bar),
.X0r(X0r), .X1r(X1r), .X2r(X2r), .X3r(X3r),
.X4r(X4r), .X5r(X5r), .X6r(X6r), .X7r(X7r),
.X0i(X0i), .X1i(X1i), .X2i(X2i), .X3i(X3i),
.X4i(X4i), .X5i(X5i), .X6i(X6i), .X7i(X7i),
.done(done)
);
// initializing the Inputs different values to test the FFT module
Initial
begin
enable_bar = 1;
// Testing output values when reset_bar is set to 0, all output values must become 0

10

reset_bar = 0;
// input pattern for [1 1 1 1 1 1 1 1]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = 10;
x1r = 10;
x2r = 10;
x3r = 10;
x4r = 10;
x5r = 10;
x6r = 10;
x7r = 10;
x0i = 0;
x1i = 0;
x2i = 0;
x3i = 0;
x4i = 0;
x5i = 0;
x6i = 0;
x7i = 0;
// input pattern for [-1 -1 -1 -1 -1 -1 -1 -1]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = -10;
x1r = -10;
x2r = -10;
x3r = -10;
x4r = -10;
x5r = -10;
x6r = -10;
x7r = -10;
x0i = 0;
x1i = 0;
x2i = 0;

11

x3i = 0;
x4i = 0;
x5i = 0;
x6i = 0;
x7i = 0;
// input pattern for [0+j, 0+j, 0+j, 0+j, 0+j, 0+j, 0+j, 0+j]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = 0;
x1r = 0;
x2r = 0;
x3r = 0;
x4r = 0;
x5r = 0;
x6r = 0;
x7r = 0;
x0i = 10;
x1i = 10;
x2i = 10;
x3i = 10;
x4i = 10;
x5i = 10;
x6i = 10;
x7i = 10;
// input pattern for [0-j, 0-j, 0-j, 0-j, 0-j, 0-j, 0-j, 0-j]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = 0;
x1r = 0;
x2r = 0;
x3r = 0;
x4r = 0;
x5r = 0;
x6r = 0;
x7r = 0;

12

x0i = -10;
x1i = -10;
x2i = -10;
x3i = -10;
x4i = -10;
x5i = -10;
x6i = -10;
x7i = -10;
// input pattern for [1+j, 2+2j, 3+j, 1+3j, 2+j, 1+2j, 1+j, 3+4j]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = 10;
x1r = 20;
x2r = 30;
x3r = 10;
x4r = 20;
x5r = 10;
x6r = 10;
x7r = 30;
x0i = 10;
x1i = 20;
x2i = 10;
x3i = 30;
x4i = 10;
x5i = 20;
x6i = 10;
x7i = 40;
// input pattern for [-1+j, 2+2j, -3-j, 1+3j, 2-j, -1+2j, 1-j, 3-4j]
// multiply all the real and imaginary input data by 10 before assigning the values
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = -10;
x1r = 20;
x2r = -30;
x3r = 10;

13

x4r = 20;
x5r = -10;
x6r = 10;
x7r = 30;
x0i = 10;
x1i = 20;
x2i = -10;
x3i = 30;
x4i = -10;
x5i = 20;
x6i = -10;
x7i = -40;
// input pattern for [-0.1+0.1j, 0.2+0.2j, -0.3-0.1j, 0.1+0.3j, 0.2-0.1j, -0.1+0.2j, 0.1-0.1j, 0.3-0.4j]
// multiply all the real and imaginary input data by 10 before assigning the value
#(2*clkDelay)
enable_bar = 0;
reset_bar = 1;
x0r = -1;
x1r = 2;
x2r = -3;
x3r = 1;
x4r = 2;
x5r = -1;
x6r = 1;
x7r = 3;
x0i = 1;
x1i = 2;
x2i = -1;
x3i = 3;
x4i = -1;
x5i = 2;
x6i = -1;
x7i = -4;
end
endmodule

14

6. SIMULATION RESULTS:
Output interpretation:
We get output in the form of {X0r X1r X2r X3r X4r X5r X6r X7r} and {X0i X1i X2i
X3i X4i X5i X6i X7i} real and imaginary respectively scaled up by 100, so the final output
would be {(X0r+jX0i) (X1r+jX1i) (X2r+jX2i) (X3r+jX3i) (X4r+jX4i) (X5r+jX5i) (X6r+jX6i)
(X7r+jX7i)} scaled down by 100.

Figure 6.1: Simulation waveform when reset_bar is 0

When reset_bar is set to 0 all the outputs of FFT Module will be cleared, yellow pointer is
pointed to the period during which reset_bar = 0.

15

Figure 6.2: Simulation waveform when x(n) = {1 1 1 1 1 1 1 1}

Above simulation waveform points to the period when x(n) = {1 1 1 1 1 1 1 1} is applied to the
input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X (k) = {800, 0, 0, 0, 0, 0, 0, 0} which is scaled by 100.
Corresponding MATLAB output is
>> fft([1 1 1 1 1 1 1 1])
Answer = 8 0 0 0

16

Figure 6.3: Simulation waveform when x(n) = {-1 -1 -1 -1 -1 -1 -1 -1}

Above simulation waveform points to the period when x (n) = {-1 -1 -1 -1 -1 -1 -1 -1} is applied
to the input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {-800, 0, 0, 0, 0, 0, 0, 0} which is scaled by 100.
Corresponding MATLAB output is
>> fft([-1 -1 -1 -1 -1 -1 -1 -1])
Answer = -8 0 0 0 0

17

Figure 6.4: Simulation waveform when x(n) = {0+j 0+j 0+j 0+j 0+j 0+j 0+j 0+j}

Above simulation waveform points to the period when x(n) = {0+j 0+j 0+j 0+j 0+j 0+j 0+j 0+j }
is applied to the input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {0+j800 0 0 0 0 0 0 0} which is scaled by 100.
Corresponding MATLAB output is
>> fft([0+j 0+j 0+j 0+j 0+j 0+j 0+j 0+j])
Answer = 0 + 8.0000i 0 0 0 0 0 0 0

18

Figure 6.5: Simulation waveform when x(n) = {0-j 0-j 0-j 0-j 0-j 0-j 0-j 0-j}

Above simulation waveform points to the period when x(n) = {0-j 0-j 0-j 0-j 0-j 0-j 0-j 0-j } is
applied to the input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {0-j800 0 0 0 0 0 0 0} which is scaled by 100. Corresponding MATLAB
output is
>> fft([0-j 0-j 0-j 0-j 0-j 0-j 0-j 0-j])
Answer = 0 - 8.0000i 0 0 0 0 0 0 0

19

Figure 6.6: Simulation waveform when x(n) = { 1+j 2+2j 3+j 1+3j 2+j 1+2j 1+j 3+4j}

Above simulation waveform points to the period when x(n) = { 1+j 2+2j 3+j 1+3j 2+j 1+2j 1+j
3+4j} is applied to the input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {(1400+j1500) (40-j60) (-400+j100) (-380+200) (0-j700) (-240-j340) (200j100) (180+j200)} which is scaled by 100. Corresponding MATLAB output is
>> fft([1+j 2+2j 3+j 1+3j 2+j 1+2j 1+j 3+4j])
Answer = {(14.0000 +15.0000i) (0.4142-0.5858i) (-4.0000+1.0000i) (-3.8284+2.0000i) (0 7.0000i)
(-2.4142-3.4142i) (2.0000-1.0000i) (1.8284+2.0000i)}

20

Figure 6.7: Simulation waveform when x(n) = {-1+j 2+2j -3-j 1+3j 2-j -1+2j 1-j 3-4j}

Above simulation waveform points to the period when x(n) = {-1+j 2+2j -3-j 1+3j 2-j -1+2j 1-j
3-4j} is applied to the input variables after scaling by 10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {(400+j100), (540+j40), (800+j500), (-160+j220), (-600-j500), (-1140+j1160),
(-200-j100), (-440-j620)} which is scaled by 100.
Corresponding MATLAB output is
>> fft([-1+j 2+2j -3-j 1+3j 2-j -1+2j 1-j 3-4j])
Answer = {(4.0000+1.0000i) (5.4853+0.3431i) (8.0000+5.0000i) (-1.5858+2.2426i) (-6.00005.0000i) (-11.4853+11.6569i) (-2.0000-1.0000i) (-4.4142-6.2426i)}

21

Figure 6.8: Simulation waveform when


x(n) = { -0.1+0.1j 0.2+0.2j -0.3-0.1j 0.1+0.3j 0.2-0.1j -0.1+0.2j 0.1-0.1j 0.3-0.4j}

Above simulation waveform points to the period when x(n) = { -0.1+0.1j, 0.2+0.2j, -0.3-0.1j,
0.1+0.3j, 0.2-0.1j, -0.1+0.2j, 0.1-0.1j, 0.3-0.4j} is applied to the input variables after scaling by
10, enable_bar = 0 and reset_bar = 1.
Output is X(k) = {(40+j10), (54+j4), (80+j50) , (-16+j22), (-60-j50) , (-114+j116), (-20-j10), (44-j62)} which is scaled by 100. Corresponding MATLAB output is
>> fft([-0.1+0.1j 0.2+0.2j -0.3-0.1j 0.1+0.3j 0.2-0.1j -0.1+0.2j 0.1-0.1j 0.3-0.4j])
Answer = {(0.4000+0.1000i) (0.5485+0.0343i) (0.8000+0.5000i) (-0.1586+0.2243i) (-0.60000.5000i) (-1.1485+1.1657i) (-0.2000-0.1000i) (-0.4414-0.6243i)}

22

Anda mungkin juga menyukai