Filter Design HDL Coder 

This example illustrates how to generate HDL code for a 5th order Butterworth filter. The cutofffrequency for this filter is very low relative to the sample rate, leading to a filter that is difficult to make practical. Also, small input (8bit) and output (9bit) word sizes cause the quantized filter to require scaling to be realizable.
On this page… 

Generate HDL Code from the Quantized Filter Generate a Test Bench from the Quantized Filter 
Use the CD sampling rate of 44.1 kHz and a cutoff frequency of 500 Hz. First, create the filter design object, then create the doubleprecision filter. Convert it from the default structure (DF2SOS) to the desired structure, DF1SOS. Finally, examine the response in log frequency using fvtool.
Fs = 44100; Fn = Fs/2; F3db = 500; filtdes = fdesign.lowpass('n,f3db', 5, F3db, Fs); Hd = design(filtdes,'butter'); Hd = convert(Hd, 'df1sos'); fvtool(Hd, 'Fs', Fs, 'FrequencyScale', 'log');
Set the filter object to fixedpoint mode to quantize it. Assume 8bit fixedpoint input and output data with 12bit coefficients and 20bit adders and states. Check the response with fvtool.
Hd.arithmetic = 'fixed'; Hd.InputWordLength = 8; Hd.InputFracLength = 7; Hd.OutputWordLength = 9; Hd.OutputMode = 'SpecifyPrecision'; Hd.OutputFracLength = 7; Hd.CoeffWordLength = 12; Hd.AccumWordLength = 20; Hd.NumStateWordLength = 20; Hd.DenStateWordLength = 20; Hd.CastBeforeSum = false; Hd.RoundMode = 'nearest'; Hd.OverflowMode = 'wrap'; fvtool(Hd, 'Fs', Fs, 'FrequencyScale', 'log');
In the plot above, fvtool shows that the quantized passband is approximately 2 dB lower than the desired response. Adjust the coefficient word length from 12 to 16 to get the quantized response closer to the reference doubleprecision response and zoom in on the passband response. The quantized filter is now just over 0.1 dB lower than the reference filter.
Hd.CoeffWordLength = 16; fvtool(Hd, 'Fs', Fs, 'FrequencyScale', 'log'); axis([0 1.0 1 1]);
A key step for hardware realization of the filter design is to check whether the scale values are reasonable and adjust the scale value if needed. First, examine the quantized scale values relative to the input specificationan 8bit value with fraction length of 7 bits. Since the first two scale values are smaller than the input settings, most of the input values are quantized away. To correct this, the filter needs to be scaled.
scales = Hd.scalevalues .* 2^Hd.InputFracLength % Now scale the filter using the frequency domain infinity norm. scale(Hd,'Linf'); % After scaling, the scale value are all one in this case. scales = Hd.scalevalues
scales = 0.1589 0.1536 4.4043 128.0000 scales = 1 1 1 1
Generate HDL Code from the Quantized Filter
Starting with the correctly quantized filter, generate VHDL or Verilog code. You have the option of generating a VHDL or Verilog test bench to verify that the HDL design matches the MATLAB® filter.
Create a temporary work directory. Generate VHDL code for the filter and open the generated file in the editor.
To generate Verilog instead, change the value of the property 'TargetLanguage', from 'VHDL' to 'Verilog'.
workingdir = tempname; generatehdl(Hd,'Name', 'hdlbutter', 'TargetLanguage', 'VHDL',... 'TargetDirectory', workingdir); edit(fullfile(workingdir, 'hdlbutter.vhd'));
### Starting VHDL code generation process for filter: hdlbutter ### Starting VHDL code generation process for filter: hdlbutter ### Generating: <a href="matlab:edit('/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter.vhd')">/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter.vhd</a> ### Starting generation of hdlbutter VHDL entity ### Starting generation of hdlbutter VHDL architecture ### Firstorder section, # 1 ### Secondorder section, # 2 ### Secondorder section, # 3 ### HDL latency is 2 samples ### Successful completion of VHDL code generation process for filter: hdlbutter
Generate a Test Bench from the Quantized Filter
Since the passband of this filter is so low relative to the sampling rate, a custom input stimulus is a better way to test the filter implementation. Build the test input with one cycle of each of 50 to 300 Hz in 50 Hz steps.
Generate a VHDL test bench to verify that the results match the MATLAB results exactly.
After generating the test bench, open the generated file in the editor.
userstim = []; for n = [50, 100, 150, 200, 250, 300] userstim = [ userstim, sin(2*pi*n/Fs*(0:Fs/n))]; end generatehdl(Hd, 'Name', 'hdlbutter',... 'TargetLanguage', 'VHDL',... 'TargetDirectory', workingdir, ... 'GenerateHDLTestbench', 'on', ... 'TestBenchUserStimulus', userstim); edit(fullfile(workingdir, 'hdlbutter_tb.vhd'));
### Starting VHDL code generation process for filter: hdlbutter ### Starting VHDL code generation process for filter: hdlbutter ### Generating: <a href="matlab:edit('/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter.vhd')">/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter.vhd</a> ### Starting generation of hdlbutter VHDL entity ### Starting generation of hdlbutter VHDL architecture ### Firstorder section, # 1 ### Secondorder section, # 2 ### Secondorder section, # 3 ### HDL latency is 2 samples ### Successful completion of VHDL code generation process for filter: hdlbutter ### Starting generation of VHDL Test Bench ### Generating input stimulus ### Done generating input stimulus; length 2166 samples. ### Generating Test bench: <a href="matlab:edit('/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter_tb.vhd')">/tmp/R2014ad_229_3389/tpdcf24151_7bf8_41f9_a2ac_1852a9fbd4bd/hdlbutter_tb.vhd</a> ### Creating stimulus vectors... ### Done generating VHDL Test Bench
Generate HDL Code and Test Bench Using FDHDLTool
HDL code and its test bench can optionally be generated using the FDHDLTOOL command that opens the dialog that lets you customize and generate Verilog or VHDL code and test benches for a copy of the quantized filter.
The GUI is customized to filter 'Hd' in such a way that only the relevant widgets are available for setting. To generate HDL and testbench you should first go to the working directory by cd(workingdir) and then call the FDHDLTOOL command.
fdhdltool(Hd)
You can modify the default settings and click Generate to generate HDL and/or testbench.
The following display shows the ModelSim HDL simulator after running the VHDL test bench. Compare the ModelSim result with the MATLAB result below.
xrange = (0:length(userstim)  1); y = filter(Hd, userstim); subplot(2,1,1); plot(xrange, userstim); axis([0 length(userstim) 1.1 1.1]); title('HDL Butterworth filter in Stimulus.'); xlabel('Sample #'); subplot(2,1,2); plot(xrange, y); axis([0 length(userstim) 1.1 1.1]); title('HDL Butterworth filter out Response.'); xlabel('Sample #');
You designed a doubleprecision Butterworth filter to meet the given specification. You then quantized the filter and discovered problems. Requantizing the coefficients and scaling the filter corrected these problems. You then generated VHDL filter code and VHDL test bench.
You can use the ModelSim HDL Simulator, to verify these results. You can also experiment with VHDL and Verilog for both filters and test benches.