# How to scale output of FIR filter implemented in VHDL

For a DSP school project we need to implement sound effects in a SPARTAN 6 FPGA using VHDL.

We tried to keep it simple and start off with a simple (100Tab) FIR filter.

As coefficients we used those created by the MATLAB FDATool.

The MATLAB output are 8bit hex values (like:01,fa,00,fd,fb,03,f4,0b,ed,...).

The filter seems to be functioning. The impulse response looks like one of a FIR filter and the music does sound filtered.

But the distortion is big and the music doesn't sound good.

We think this is due to 'bad' scaling.

The CODEC output (filter input) is 18bit wide, the filter output is 48bit. But the CODEC input (scaled filter output) is only 18bit.

How should we scale the 48bit output to make it fit the 18bit CODEC input?

We tried dividing the 48bit output by a scalar (more or less the same as shifting). We also tried just removing some MSB values (which we estimated would never be used) and then dividing by a scalar.

None of these methods seems satisfactory and the signal gets distorted.

Would there be a better method to scale the output? We thought of scaling the coefficients but in their current form they just become 0 (sum all coefficients and divide every single coefficient with this value, good for fixed point values but not with these (MATLAB) values?).

EDIT:

After more investigation it appears that all distortion is due to the scaling. I think this is caused by the removal of MSB when a small scalar is chosen (not enough shifting, so some MSB's containing info are removed). But also due to the removal of LSB's when keeping all MSB'S.

So my question still stands: What would be the optimal way of implementing scaling?

• Start by taking the 18 MSBs to the codec. If that's distorted you have a different problem than scaling. If it's clean but too quiet, then scale by selecting different bits. – Brian Drummond Mar 8 '14 at 20:24
• Also, you need to capture the data and look at it, not just assume (from listening) that the issue is due to scaling. Take a known input (say a sine wave), capture filtered samples into blockRAM or external SDRAM, pull it into MATLAB and see if it is at all reasonable. I suspect that your problems are not in the scaling. – Zuofu Mar 8 '14 at 22:34
• After using the 18 MSB's the distortion was still present, but when making a Allpass (bandpass 0k to 20k) there is no distortion at all. I will try and visualize the output signal. – Devenda Mar 9 '14 at 9:52
• After more testing I came to the conclusion that my filter is working fine. I think that the scaling/conversion steps don't take account for the sign bit. That's what introduces the horrible noise at higher input amplitudes (or smaller scaling). – Devenda Mar 9 '14 at 15:39
• That sounds like a format problem, not a scaling problem. – mng Mar 9 '14 at 21:33