top of page

FIR filter design

Aim of the lesson:

In this lesson we will learn how to design a floating point FIR filter with given parameters, and how to generate the fixed point coefficients, which we can later use in the DSC unit.

Prerequisites:

Download the start-up files from here. common.inc - contains some configurations for the assembly instructions. The fft.h contains our function headers, while fft.s contains the radix-2 FFT implementation. A test square wave signal is defined in input_samples.c. The FFT twiddle factors are written in  twiddle.c for a 64, 128, 256, or 512 points transform.

Testing the Algorithm:

Create a new project, copy the previously downloaded files into said project.

Create a new main c file, and add the proper configuration bit settings (same as in lab1).

Define two external variables: one for the pre-calculated twiddle factors in the program memory space, and one for the input signal in Y memory.

In order for the FFT algorithm to work correctly (without overflow or saturation), the input data must be in the range of [-0.5, 0.5], so we must scale the data by shifting it to the right - or dividing by 2 since inherently the Q15 data is in the range of [-1.0, 1.0].

The FFT function expects a complex signal, which can be constructed by setting the real part to our samples, and the imaginary part to 0.

This whole section can and MUST be optimized when using with real data:

The complex input data structure will be preallocated in Y memory space, and filled with 0s.

The sampled data will be scaled and saved in the real part of the data structure, all while treating the data as a fixed size FIFO buffer.

Now we can call the FFT function providing the buffer length, the complex input buffer, the base address and the page number of the twiddle factors.

Simulate the code written so far. What is the problem?

Bit reverse reordering:

If you've been paying attention in the courses, the FFT algorithm creates a bit-reversed result from a normal vector, which must be reordered. Luckily for us the DSP engine has this functionality built in:

Create a new .s assembly file, add the common.inc to the includes, create a global BitReverseComplex function.

Save DSRPAG, and set it to 0x0001. Save MODCON and XBREV - registers which will be used for bit reverse setup.

​

Write the algorithm, load XBREV, MODCON and DSRPAG registers at the end.

Generating the magnitude:

The FFT algorithm generates a complex set of data, but we only need the magnitude of the data

The square root is missing since the logarithmic plot can be rewritten, and as such a computation heavy mathematical instruction can be neglected

Write the magnitude calculator assembly function, simulate the program, save the result in a .csv file, and plot it in MATLAB or Python, and compare it with the image below.

bottom of page