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

Subversion Repositories tcp_socket

[/] [tcp_socket/] [trunk/] [chips2/] [docs/] [source/] [examples/] [example_5.rst] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 jondawson
 
2
 
3
Fast Fourier Transform
4
----------------------
5
 
6
This example builds on the Taylor series example. We assume that the sin and
7
cos routines have been placed into a library of math functions math.h, along
8
with the definitions of :math:`\pi`, M_PI.
9
 
10
The `Fast Fourier Transform (FFT) `_
11
is an efficient method of decomposing discretely sampled signals into a frequency spectrum, it
12
is one of the most important algorithms in Digital Signal Processing (DSP).
13
`The Scientist and Engineer's Guide to Digital Signal Processing `_
14
gives a straight forward introduction, and can be viewed on-line for free.
15
 
16
The example shows a practical method of calculating the FFT using the
17
`Cooley-Tukey algorithm `_.
18
 
19
 
20
.. code-block:: c
21
 
22
    /* fft.c */
23
    /* Jonathan P Dawson */
24
    /* 2013-12-23 */
25
 
26
    #include "math.h"
27
 
28
    /*globals*/
29
    const int n = 1024;
30
    const int m = 10;
31
    float twiddle_step_real[m];
32
    float twiddle_step_imaginary[m];
33
 
34
 
35
    /*calculate twiddle factors and store them*/
36
    void calculate_twiddles(){
37
        unsigned stage, subdft_size, span;
38
        for(stage=1; stage<=m; stage++){
39
            subdft_size = 1 << stage;
40
            span = subdft_size >> 1;
41
            twiddle_step_real[stage] = cos(M_PI/span);
42
            twiddle_step_imaginary[stage] = -sin(M_PI/span);
43
        }
44
    }
45
 
46
    /*bit reverse*/
47
    unsigned bit_reverse(unsigned forward){
48
        unsigned reversed=0;
49
        unsigned i;
50
        for(i=0; i
51
            reversed <<= 1;
52
            reversed |= forward & 1;
53
            forward >>= 1;
54
        }
55
        return reversed;
56
    }
57
 
58
    /*calculate fft*/
59
    void fft(float reals[], float imaginaries[]){
60
 
61
        int stage, subdft_size, span, i, ip, j;
62
        float sr, si, temp_real, temp_imaginary, imaginary_twiddle, real_twiddle;
63
 
64
        //read data into array
65
        for(i=0; i
66
            ip = bit_reverse(i);
67
            if(i < ip){
68
                temp_real = reals[i];
69
                temp_imaginary = imaginaries[i];
70
                reals[i] = reals[ip];
71
                imaginaries[i] = imaginaries[ip];
72
                reals[ip] = temp_real;
73
                imaginaries[ip] = temp_imaginary;
74
            }
75
        }
76
 
77
        //butterfly multiplies
78
        for(stage=1; stage<=m; stage++){
79
            report(stage);
80
            subdft_size = 1 << stage;
81
            span = subdft_size >> 1;
82
 
83
            //initialize trigonometric recurrence
84
 
85
            real_twiddle=1.0;
86
            imaginary_twiddle=0.0;
87
 
88
            sr = twiddle_step_real[stage];
89
            si = twiddle_step_imaginary[stage];
90
 
91
            for(j=0; j
92
                for(i=j; i
93
                    ip=i+span;
94
 
95
                    temp_real      = reals[ip]*real_twiddle      - imaginaries[ip]*imaginary_twiddle;
96
                    temp_imaginary = reals[ip]*imaginary_twiddle + imaginaries[ip]*real_twiddle;
97
 
98
                    reals[ip]       = reals[i]-temp_real;
99
                    imaginaries[ip] = imaginaries[i]-temp_imaginary;
100
 
101
                    reals[i]       = reals[i]+temp_real;
102
                    imaginaries[i] = imaginaries[i]+temp_imaginary;
103
                }
104
                //trigonometric recreal_twiddlerence
105
                temp_real=real_twiddle;
106
                real_twiddle      = temp_real*sr - imaginary_twiddle*si;
107
                imaginary_twiddle = temp_real*si + imaginary_twiddle*sr;
108
            }
109
        }
110
    }
111
 
112
    void main(){
113
        float reals[n];
114
        float imaginaries[n];
115
        unsigned i;
116
 
117
        /* pre-calculate sine and cosine*/
118
        calculate_twiddles();
119
 
120
        /* generate a 64 sample cos wave */
121
        for(i=0; i
122
            reals[i] = 0.0;
123
            imaginaries[i] = 0.0;
124
        }
125
        for(i=0; i<=64; i++){
126
            reals[i] = sin(2.0 * M_PI * (i/64.0));
127
        }
128
 
129
        /* output time domain signal to a file */
130
        for(i=0; i
131
            file_write(reals[i], "x_re");
132
            file_write(imaginaries[i], "x_im");
133
        }
134
 
135
        /* transform into frequency domain */
136
        fft(reals, imaginaries);
137
 
138
        /* output frequency domain signal to a file */
139
        for(i=0; i
140
            file_write(reals[i], "fft_x_re");
141
            file_write(imaginaries[i], "fft_x_im");
142
        }
143
    }
144
 
145
The C code includes a simple test routine that calculates the frequency spectrum of a 64 point sine wave.
146
 
147
.. image:: images/example_5.png
148
 

powered by: WebSVN 2.1.0

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