Main Content

HDL Minimum Phase FIRT Filter

This example illustrates how to generate HDL code for a minimum phase FIRT filter with 10-bit input data. This is a bandpass filter with sample rate of 96 kHz and passband from approximately 19 kHz to 29 kHz. This type of filter is commonly used in feedback loops where linear phase is not sufficient and minimum phase or as close as is achievable is required.

Set up the Coefficients

Design the filter using firgr, which uses the generalized Remez design method. The use of the 'minphase' argument to firgr forces a minimum phase filter design. Then, use fvtool to visualize the filter response.

Fs  = 96000;
Fn  = Fs/2;
f   = [0 17000 20000 28000 31000 Fn]/Fn;
a   = [0     0     1     1     0  0];
w   = [5 1 5];
b   = firgr(44, f, a, w, 'minphase');
hfvt = fvtool(b,'Fs', Fs,...
              'MagnitudeDisplay', 'Magnitude (dB)',...
              'legend','on');
legend(hfvt,'Min Phase');

Figure Figure 1: Magnitude Response (dB) contains an axes object. The axes object with title Magnitude Response (dB), xlabel Frequency (kHz), ylabel Magnitude (dB) contains an object of type line. This object represents Min Phase.

Examine the Phase Response

Check the phase response of the filter.

hfvt = fvtool(b,'Fs', Fs,...
              'Analysis', 'phase',...
              'legend','on');
legend(hfvt, 'Min Phase');

Figure Figure 2: Phase Response contains an axes object. The axes object with title Phase Response, xlabel Frequency (kHz), ylabel Phase (radians) contains an object of type line. This object represents Min Phase.

Create the Quantized FIRT Fixed-Point Filter

Having checked the minimum phase filter design, construct a FIR filter System object with 'Direct form transposed' structure. Set the coefficient word length to 15, and use full precision for the other filter settings.

b_fixed = fi(b,1,15); % use best precision fraction length
T_coeff = numerictype(b_fixed);
minPhaseFilter = dsp.FIRFilter('Structure','Direct form transposed');
minPhaseFilter.Numerator = double(b_fixed);
minPhaseFilter.FullPrecisionOverride = false;
minPhaseFilter.CoefficientsDataType = 'Custom';
minPhaseFilter.CustomCoefficientsDataType = T_coeff;
minPhaseFilter.ProductDataType = 'Full precision';
minPhaseFilter.AccumulatorDataType = 'Full precision';
minPhaseFilter.OutputDataType = 'Same as accumulator';

Check the Fixed-Point Filter Relative to the Reference Design

Check the quantized filter relative to the reference design. The magnitude response is correct but the phase response is no longer min-phase, due to quantization.

hfvt = fvtool(minPhaseFilter, 'Fs', Fs, ...
              'Analysis', 'freq', ...
              'legend', 'on', ...
              'Arithmetic', 'fixed');
legend(hfvt, 'Min Phase');

Figure Figure 3: Magnitude Response (dB) and Phase Response contains an axes object. The axes object with title Magnitude Response (dB) and Phase Response, xlabel Frequency (kHz), ylabel Magnitude (dB) contains 2 objects of type line. These objects represent Min Phase: Quantized Magnitude, Min Phase: Reference Magnitude.

Check the Impulse Response

Plot the impulse response of the quantized filter. Many of the coefficients have quantized to zero and the overall response still meets the specification, even though the zeros have made the phase response non-minimum. These zeros lead to a smaller implementation because HDL code is not generated for multiplies by zero.

hfvt = fvtool(minPhaseFilter, 'Fs', Fs, ...
              'Analysis', 'Impulse', ...
              'legend', 'on', ...
              'Arithmetic', 'fixed');
legend(hfvt, 'Min Phase');

Figure Figure 4: Impulse Response contains an axes object. The axes object with title Impulse Response, xlabel Time (us), ylabel Amplitude contains 2 objects of type stem. These objects represent Min Phase: Quantized, Min Phase: Reference.

Generate HDL Code and Test Bench from the Quantized Filter

Starting from the quantized filter, generate VHDL or Verilog.

Create a temporary work directory. After generating the HDL code (Verilog in this case), open the generated file in the editor.

Generate a Verilog test bench to verify that the results match the results in MATLAB. Use the chirp predefined input stimulus.

To generate VHDL code and VHDL test bench instead, change the value for 'TargetLanguage' property from 'Verilog' to 'VHDL'.

Assume an input of 10-bit word length with 9-bit fractional bits.

workingdir = tempname;
generatehdl(minPhaseFilter,'Name', 'hdlminphasefilt', ...
               'TargetLanguage', 'Verilog', ...
               'GenerateHDLTestbench','on', ...
               'TestBenchStimulus', 'chirp', ...
               'TargetDirectory', workingdir, ...
               'InputDataType', numerictype(1,10,9));
### Starting Verilog code generation process for filter: hdlminphasefilt
### Starting Verilog code generation process for filter: hdlminphasefilt
### Generating: /tmp/Bdoc23b_2361005_717342/tp4c8bc6f5_d718_4065_b9ce_d9d815679752/hdlminphasefilt.v
### Starting generation of hdlminphasefilt Verilog module
### Starting generation of hdlminphasefilt Verilog module body
### Successful completion of Verilog code generation process for filter: hdlminphasefilt
### HDL latency is 2 samples
### Starting generation of VERILOG Test Bench.
### Generating input stimulus
### Done generating input stimulus; length 1069 samples.
### Generating Test bench: /tmp/Bdoc23b_2361005_717342/tp4c8bc6f5_d718_4065_b9ce_d9d815679752/hdlminphasefilt_tb.v
### Creating stimulus vectors ...
### Done generating VERILOG Test Bench.
edit(fullfile(workingdir, 'hdlminphasefilt.v'));

Plot the Test Bench Stimulus and the Filter Response

Plot the filter input stimulus and output response on separate plots.

x = generatetbstimulus(minPhaseFilter,'TestBenchStimulus','chirp','InputDataType', numerictype(1,10,9));
xrange = (0:length(x) - 1).*( Fn / (length(x) - 1))/1e3;
y = minPhaseFilter(x.');
subplot(2,1,1); plot(xrange, x); ylim(ylim.*1.1);
axis([0,50,-1.2,1.2]);
title('HDL Min Phase Filter Chirp Stimulus.');
xlabel('Frequency in kHz');
subplot(2,1,2); plot(xrange, y); ylim(ylim.*1.1);
axis([0,50,-1.2,1.2]);
title('HDL Min Phase Filter Response.');
xlabel('Frequency in kHz');

Figure contains 2 axes objects. Axes object 1 with title HDL Min Phase Filter Chirp Stimulus., xlabel Frequency in kHz contains an object of type line. Axes object 2 with title HDL Min Phase Filter Response., xlabel Frequency in kHz contains an object of type line.

Conclusion

You designed a minimum phase filter and then converted it to a FIR filter System object with transposed structure. You then generated Verilog code for the filter design and a Verilog test bench to functionally verify the results.

You can use a Verilog simulator, such as ModelSim®, to verify these results.