This example shows how to design multistage decimators and interpolators. The example Efficient Narrow Transition-Band FIR Filter Design shows how to apply the IFIR and the MULTISTAGE approaches to single-rate designs of lowpass filters. The techniques can be extended to the design of multistage decimators and/or interpolators. The IFIR approach results in a 2-stage decimator/interpolator. For the MULTISTAGE approach, the number of stages can be either automatically optimized or manually controlled.
Decimators are used to reduce the sampling-rate of a signal while simultaneously reducing the bandwidth proportionally. For example, to reduce the rate from 48 MHz to 1 MHz, a factor of 48, the following are typical specifications for a lowpass filter that will reduce the bandwidth accordingly.
Fs = 48e6; TW = 100e3; Astop = 80; % Minimum stopband attenuation M = 48; % Decimation factor
A simple multistage design given these specs is
multidecim = designMultistageDecimator(M,Fs,TW,Astop);
To analyze the resulting design, several functions are available
info(multidecim) % Provide some information on the multistage filter cost(multidecim) % Determine the implementation cost fvtool(multidecim) % Visualize overall magnitude response, group delay, etc
ans = 'Discrete-Time Filter Cascade ---------------------------- Number of stages: 5 Stage1: dsp.FIRDecimator ------- Discrete-Time FIR Multirate Filter (real) ----------------------------------------- Filter Structure : Direct-Form FIR Polyphase Decimator Decimation Factor : 2 Polyphase Length : 4 Filter Length : 7 Stable : Yes Linear Phase : Yes (Type 1) Arithmetic : double Stage2: dsp.FIRDecimator ------- Discrete-Time FIR Multirate Filter (real) ----------------------------------------- Filter Structure : Direct-Form FIR Polyphase Decimator Decimation Factor : 2 Polyphase Length : 4 Filter Length : 7 Stable : Yes Linear Phase : Yes (Type 1) Arithmetic : double Stage3: dsp.FIRDecimator ------- Discrete-Time FIR Multirate Filter (real) ----------------------------------------- Filter Structure : Direct-Form FIR Polyphase Decimator Decimation Factor : 2 Polyphase Length : 6 Filter Length : 11 Stable : Yes Linear Phase : Yes (Type 1) Arithmetic : double Stage4: dsp.FIRDecimator ------- Discrete-Time FIR Multirate Filter (real) ----------------------------------------- Filter Structure : Direct-Form FIR Polyphase Decimator Decimation Factor : 3 Polyphase Length : 11 Filter Length : 33 Stable : Yes Linear Phase : Yes (Type 1) Arithmetic : double Stage5: dsp.FIRDecimator ------- Discrete-Time FIR Multirate Filter (real) ----------------------------------------- Filter Structure : Direct-Form FIR Polyphase Decimator Decimation Factor : 2 Polyphase Length : 48 Filter Length : 95 Stable : Yes Linear Phase : Yes (Type 1) Arithmetic : double ' ans = struct with fields: NumCoefficients: 89 NumStates: 146 MultiplicationsPerInputSample: 6.6042 AdditionsPerInputSample: 5.6667
Multistage designs are efficient in terms of multiplications per input sample and overall number of filter coefficients. Compare with a single stage design.
singledecim = designMultistageDecimator(M,Fs,TW,Astop,'NumStages',1); cost(singledecim) % Determine the implementation cost fvtool(multidecim,singledecim) legend('Multistage','Singlestage')
ans = struct with fields: NumCoefficients: 2361 NumStates: 2400 MultiplicationsPerInputSample: 49.1875 AdditionsPerInputSample: 49.1667
By default, the number of stages is automatically determined to minimize the implementation cost. The number of stages can be set manually to any number between 1 and the number of prime factors in the decimation factor. Just increasing to two stages makes a significant difference.
twostagedecim = designMultistageDecimator(M,Fs,TW,Astop,'NumStages',2);
cost(twostagedecim)
ans = struct with fields: NumCoefficients: 218 NumStates: 265 MultiplicationsPerInputSample: 9.2500 AdditionsPerInputSample: 9.1667
By default, the design minimizes multiplications per input sample. It is also possible to minimize the number of coefficients.
mincoeffdecim = designMultistageDecimator(M,Fs,TW,Astop,... 'MinTotalCoeffs',true); cost(mincoeffdecim)
ans = struct with fields: NumCoefficients: 87 NumStates: 147 MultiplicationsPerInputSample: 6.8125 AdditionsPerInputSample: 6
Compared to multidecim
, the number of coefficients is lower, but the number of multiplications per input sample is higher.
By default, the best multistage configuration is determined using estimates of the number of coefficients required for each stage. A slower, but more precise method, designs all filter candidates and determines the actual number of coefficients in order to find the optimal solution.
optimaldecim = designMultistageDecimator(M,Fs,TW,Astop,... 'CostMethod','design'); cost(optimaldecim) fvtool(multidecim,optimaldecim)
ans = struct with fields: NumCoefficients: 87 NumStates: 146 MultiplicationsPerInputSample: 6.5625 AdditionsPerInputSample: 5.6667
Similar savings are possible when designing multistage interpolators. As with all interpolators, the overall design has a gain equal to the interpolation factor.
multiinterp = designMultistageInterpolator(8); fvtool(multiinterp)
The use of multistage techniques can provide significant computational savings when implementing decimators/interpolators.