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?).


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?

  • \$\begingroup\$ 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. \$\endgroup\$
    – user16324
    Commented Mar 8, 2014 at 20:24
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Zuofu
    Commented Mar 8, 2014 at 22:34
  • \$\begingroup\$ 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. \$\endgroup\$
    – Devenda
    Commented Mar 9, 2014 at 9:52
  • \$\begingroup\$ 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). \$\endgroup\$
    – Devenda
    Commented Mar 9, 2014 at 15:39
  • \$\begingroup\$ That sounds like a format problem, not a scaling problem. \$\endgroup\$
    – mng
    Commented Mar 9, 2014 at 21:33

1 Answer 1


Normally there should not be any scaling to be done.. Just make your filter In/out 18 bit wide...

also , do not forget the anti-aliasing filter at the output...


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.