Fixed-Point Filter Design in MATLAB
Design filters for use with fixed-point input. The example analyzes the effect of coefficient quantization on filter design. You must have the Fixed-Point Designer™ software to run this example.
Introduction
Fixed-point filters are commonly used in digital signal processors where data storage and power consumption are key limiting factors. With the constraints you specify, DSP System Toolbox™ software allows you to design efficient fixed-point filters. The filter for this example is a lowpass equiripple FIR filter. Design the filter first for floating-point input to obtain a baseline. You can use this baseline for comparison with the fixed-point filter.
FIR Filter Design
The lowpass FIR filter has the following specifications:
Sample rate: 2000 Hz
Center frequency: 450 Hz
Transition width: 100 Hz
Equiripple design
Maximum 1 dB of ripple in the passband
Minimum 80 dB of attenuation in the stopband
samplingFrequency = 2000; centerFrequency = 450; transitionWidth = 100; passbandRipple = 1; stopbandAttenuation = 80; designSpec = fdesign.lowpass('Fp,Fst,Ap,Ast',... centerFrequency-transitionWidth/2, ... centerFrequency+transitionWidth/2, ... passbandRipple,stopbandAttenuation, ... samplingFrequency); LPF = design(designSpec,'equiripple',... SystemObject=true)
LPF = dsp.FIRFilter with properties: Structure: 'Direct form' NumeratorSource: 'Property' Numerator: [-0.0013 -0.0055 -0.0112 -0.0125 -0.0048 0.0062 0.0081 -0.0022 -0.0104 -0.0027 0.0115 0.0093 -0.0098 -0.0171 0.0039 0.0242 0.0073 -0.0286 -0.0247 0.0268 0.0498 -0.0134 -0.0887 -0.0298 0.1895 0.3983 0.3983 0.1895 ... ] (1x52 double) InitialConditions: 0 Use get to show all properties
View the baseline frequency response. The dotted red lines show the design specifications used to create the filter.
filterAnalyzer(LPF)
Full-Precision Fixed-Point Operation
The fixed-point properties of the filter are contained in the Fixed-point properties
section in the display of the object. By default, the filter uses full-precision arithmetic to deal with fixed-point inputs. With full-precision arithmetic, the filter uses as many bits for the product, accumulator, and output as needed to prevent any overflow or rounding. If you do not want to use full-precision arithmetic, you can set the FullPrecisionOverride
property to false
and then set the product, accumulator, and output data types independently.
rng default inputWordLength = 16; fixedPointInput = fi(randn(100,1),true,inputWordLength); floatingPointInput = double(fixedPointInput); floatingPointOutput = LPF(floatingPointInput); release(LPF) fullPrecisionOutput = LPF(fixedPointInput); norm(floatingPointOutput-double(fullPrecisionOutput),'inf')
ans = 6.8994e-05
The result of full-precision fixed-point filtering comes very close to floating point, but the results are not exact. The reason for this is coefficient quantization. In the fixed-point filter, the CoefficientsDataType
property has the same word length (16) for the coefficients and the input. The frequency response of the filter in full-precision mode shows this more clearly. The measure
function shows that the minimum stopband attenuation of this filter with quantized coefficients is 76.6913 dB, less than the 80 dB specified for the floating-point filter.
LPF.CoefficientsDataType
ans = 'Same word length as input'
filterAnalyzer(LPF)
measure(LPF)
ans = Sample Rate : 2 kHz Passband Edge : 400 Hz 3-dB Point : 416.2891 Hz 6-dB Point : 428.1081 Hz Stopband Edge : 500 Hz Passband Ripple : 0.96325 dB Stopband Atten. : 76.6913 dB Transition Width : 100 Hz
The filter was last used with fixed-point input and is still in a locked state. For that reason, filterAnalyzer
displays the fixed-point frequency response. The dash-dot response is that of the reference floating-point filter, and the solid plot is the response of the filter that was used with fixed-point input. The desired frequency response cannot be matched because the coefficient word length has been restricted to 16 bits. This accounts for the difference between the floating-point and fixed-point designs. Increasing the number of bits allowed for the coefficient word length makes the quantization error smaller and enables you to match the design requirement for 80 dB of stopband attenuation. Use a coefficient word length of 24 bits to achieve an attenuation of 80.1275 dB.
LPF24bitCoeff = design(designSpec,'equiripple',... SystemObject=true); LPF24bitCoeff.CoefficientsDataType = 'Custom'; coeffNumerictype = numerictype(fi(LPF24bitCoeff.Numerator,true,24)); LPF24bitCoeff.CustomCoefficientsDataType = numerictype(true,... coeffNumerictype.WordLength,coeffNumerictype.FractionLength); fullPrecisionOutput32bitCoeff = LPF24bitCoeff(fixedPointInput); norm(floatingPointOutput-double(fullPrecisionOutput32bitCoeff),'inf')
ans = 4.1077e-07
filterAnalyzer(LPF24bitCoeff)
measure(LPF24bitCoeff)
ans = Sample Rate : 2 kHz Passband Edge : 400 Hz 3-dB Point : 416.2901 Hz 6-dB Point : 428.1091 Hz Stopband Edge : 500 Hz Passband Ripple : 0.96329 dB Stopband Atten. : 80.1275 dB Transition Width : 100 Hz
Design Parameters and Coefficient Quantization
In many fixed-point design applications, the coefficient word length is not flexible. For example, supposed you are restricted to work with 14 bits. In such cases, the requested minimum stopband attenuation of 80 dB cannot be reached. A filter with 14-bit coefficient quantization can achieve a minimum attenuation of only 67.2987 dB.
LPF14bitCoeff = design(designSpec,'equiripple',... SystemObject=true); coeffNumerictype = numerictype(fi(LPF14bitCoeff.Numerator,true,14)); LPF14bitCoeff.CoefficientsDataType='Custom'; LPF14bitCoeff.CustomCoefficientsDataType = numerictype(true, ... coeffNumerictype.WordLength,coeffNumerictype.FractionLength); measure(LPF14bitCoeff,Arithmetic='fixed')
ans = Sample Rate : 2 kHz Passband Edge : 400 Hz 3-dB Point : 416.2939 Hz 6-dB Point : 428.1081 Hz Stopband Edge : 500 Hz Passband Ripple : 0.96405 dB Stopband Atten. : 67.2987 dB Transition Width : 100 Hz
For FIR filters in general, each bit of coefficient word length provides approximately 5 dB of stopband attenuation. Accordingly, if your filter's coefficients are always quantized to 14 bits, you can expect the minimum stopband attenuation to be only around 70 dB. In such cases, it is more practical to design the filter with stopband attenuation less than 70 dB. Relaxing this requirement results in a design of lower order.
designSpec.Astop = 60; LPF60dBStopband = design(designSpec,'equiripple',... SystemObject=true); LPF60dBStopband.CoefficientsDataType='Custom'; coeffNumerictype = numerictype(fi(LPF60dBStopband.Numerator,true,14)); LPF60dBStopband.CustomCoefficientsDataType = numerictype(true, ... coeffNumerictype.WordLength,coeffNumerictype.FractionLength); measure(LPF60dBStopband,Arithmetic='fixed')
ans = Sample Rate : 2 kHz Passband Edge : 400 Hz 3-dB Point : 419.3391 Hz 6-dB Point : 432.9718 Hz Stopband Edge : 500 Hz Passband Ripple : 0.92801 dB Stopband Atten. : 59.1829 dB Transition Width : 100 Hz
order(LPF14bitCoeff)
ans = 51
order(LPF60dBStopband)
ans = 42
The filter order decreases from 51 to 42, implying that fewer taps are required to implement the new FIR filter. If you still want a high minimum stopband attenuation without compromising on the number of bits for coefficients, you must relax the other filter design constraint: the transition width. Increasing the transition width might enable you to get higher attenuation with the same coefficient word length. However, it is almost impossible to achieve more than 5 dB per bit of coefficient word length, even after relaxing the transition width.
designSpec.Astop = 80; transitionWidth = 200; designSpec.Fpass = centerFrequency-transitionWidth/2; designSpec.Fstop = centerFrequency+transitionWidth/2; LPF300TransitionWidth = design(designSpec,'equiripple',... SystemObject=true); LPF300TransitionWidth.CoefficientsDataType='Custom'; coeffNumerictype = numerictype(fi(LPF300TransitionWidth.Numerator,... true, 14)); LPF300TransitionWidth.CustomCoefficientsDataType = numerictype(true,... coeffNumerictype.WordLength,coeffNumerictype.FractionLength); measure(LPF300TransitionWidth,Arithmetic='fixed')
ans = Sample Rate : 2 kHz Passband Edge : 350 Hz 3-dB Point : 385.4095 Hz 6-dB Point : 408.6465 Hz Stopband Edge : 550 Hz Passband Ripple : 0.74045 dB Stopband Atten. : 74.439 dB Transition Width : 200 Hz
As you can see, increasing the transition width to 200 Hz allows 74.439 dB of stopband attenuation with 14-bit coefficients, compared to the 67.2987 dB attained when the transition width was set to 100 Hz. An added benefit of increasing the transition width is that the filter order also decreases, in this case from 51 to 27.
order(LPF300TransitionWidth)
ans = 27