Summary: You will apply the fast Fourier transform (FFT) to analyze the spectral content of an input signal in real time. You will use a length-64 Hamming window and no zero-padding. After computing the FFT, you will compute the squared-magnitude of the sampled spectrum and send it to the output for display on the oscilloscope.
You will use the FFT to compute the spectrum of a windowed
input. For your implementation, use a 64-point Hamming
window. You may use the MATLAB function
save_coef (available as save_coef.m
to save the window to a file that you can then include in your
code with the .copy directive.
The FFT routine fft.asm computes an in-place,
complex FFT. The length of the FFT is defined as a label
K_FFT_SIZE, and the algorithm assumes that the
input starts at data memory location fft_data.
To have your code assemble for a 64-point FFT, you will have
to include the following label definitions in your code.
K_FFT_SIZE .set 64 ; size of FFT
K_LOGN .set 6 ; number of stages (log_2(N))
In addition to defining these constants, you will have to
include twiddle-factor tables for the FFT.
Copy these tables (twiddle1 and
twiddle2) into your work directory. Note that
the tables are each 512 points long, representing values
from 0 to just shy of 180 degrees, and must be accessed as a
circular buffer. To include these tables at the proper
location in memory with the appropriate labels referenced by
the FFT, use the following:
.sect ".data"
.align 1024
sine .copy "twiddle1"
.align 1024
cosine .copy "twiddle2"
To run the FFT code, use the instruction call
fft where fft is a label at the
beginning of the available fft.asm code.
The FFT provided requires that the input be in
bit-reversed order, with alternating real and
imaginary components. Bit-reversed addressing is a
convenient way to order input
| Input Order | Binary Representation | Bit-Reversed Representation | Output Order |
|---|---|---|---|
| 0 | 000 | 000 | 0 |
| 1 | 001 | 100 | 4 |
| 2 | 010 | 010 | 2 |
| 3 | 011 | 110 | 6 |
| 4 | 100 | 001 | 1 |
| 5 | 101 | 101 | 5 |
| 6 | 110 | 011 | 3 |
| 7 | 111 | 111 | 7 |
The following routine performs the bit-reversed reordering
of the input data. The routine assumes that the input is
stored in data memory starting at the location labeled
input_data and consists of alternating real and
imaginary parts. Because our input data in this exercise is
purely real, you will have to set the imaginary parts to
zero by zeroing out every other memory location.
1 bit_rev:
2 SSBX FRCT ; fractional mode is on
3 STM #input_data,AR3 ; AR3 -> 1 st original input
4 STM #fft_data,AR7 ; AR7 -> data processing buffer
5 MVMM AR7,AR2 ; AR2 -> 1st bit1 reversed data
6 STM #K_FFT_SIZE-1,BRC
7 RPTBD bit_rev_end-1
8 STM #K_FFT_SIZE,AR0 ; AR0 = 1/2 size of circ buffer
9 MVDD *AR3+,*AR2+
10 MVDD *AR3-,*AR2+
11 MAR *AR3+0B
12 bit_rev_end:
13 RET ; return to Real FFT main module
As mentioned, in the above code input_data is a
label indicating the start of the input data and
fft_data is a label indicating the start of a
circular buffer where the bit-reversed data will be written.
Include the bit_rev routine in your code and
call it using the call bit_rev command in the
appropriate location. Note that although AR7
is not used by the bit-reversed routine directly, it is used
extensively in the FFT routine to keep track of the start of
the FFT data space.
In general, to have a pointer index memory in bit-reversed
order, the AR0 register needs to be set to
one-half the length of the circular buffer; a statement such
as ARx+0B is used to move the ARx
pointer to the next location. For more information
regarding the bit-reversed addressing mode, refer to
page 5-18 in the CPU
and Peripherals manual. See Figure 4-10
in the Applications
Guide to view the ordering of the data expected by
the FFT routine.
fft call.Once the DFT has been computed, calculate the squared-magnitude of the spectrum for display.
squr and
squra useful in implementing Equation 1. Why do we display the squared-magnitude
instead of the magnitude itself?
Because the squared magnitude is always nonnegative, you can
replace one of the magnitude values with a -1.0 as a trigger
pulse for display on the oscilloscope. This is easily
performed by replacing the DC term,