www.gusucode.com > hdlverifier 案例代码 matlab源码程序 > hdlfilter/hdlbutter.m
%% HDL Butterworth Filter % This example illustrates how to generate HDL code for a 5th % order Butterworth filter. The cutoff-frequency for this filter is very % low relative to the sample rate, leading to a filter that is difficult % to make practical. Also, small input (8-bit) and output (9-bit) word % sizes cause the quantized filter to require scaling to be realizable. % Copyright 2004-2016 The MathWorks, Inc. %% Design the Filter % Use the CD sampling rate of 44.1 kHz and a cut-off frequency of 500 % Hz. First, create the filter design object, then create the % DF1 Biquad Filter System object. Finally, examine the % response in log frequency using fvtool. Fs = 44100; F3db = 500; filtdes = fdesign.lowpass('n,f3db', 5, F3db, Fs); butterFilter = design(filtdes,'butter',... 'SystemObject',true,'FilterStructure','df1sos'); fvtool(butterFilter, 'Fs', Fs, 'FrequencyScale', 'log'); %% Create the Quantized Filter % Apply the fixed point settings to the filter object. Assume % 9-bit fixed-point output data with 12-bit coefficients, % 20-bit states, full precision products, and 32-bit adders. % Check the response with fvtool. butterFilter.NumeratorCoefficientsDataType = 'Custom'; butterFilter.CustomNumeratorCoefficientsDataType = numerictype([],12); butterFilter.CustomDenominatorCoefficientsDataType = numerictype([],12); butterFilter.CustomScaleValuesDataType = numerictype([],12); butterFilter.SectionInputDataType = 'Custom'; butterFilter.CustomSectionInputDataType = numerictype([],20,15); butterFilter.SectionOutputDataType = 'Custom'; butterFilter.CustomSectionOutputDataType = numerictype([],20,15); butterFilter.NumeratorProductDataType = 'Full precision'; butterFilter.DenominatorProductDataType = 'Full precision'; butterFilter.NumeratorAccumulatorDataType = 'Custom'; butterFilter.CustomNumeratorAccumulatorDataType = numerictype([],32,24); butterFilter.DenominatorAccumulatorDataType = 'Custom'; butterFilter.CustomDenominatorAccumulatorDataType = numerictype([],32,25); butterFilter.OutputDataType = 'Custom'; butterFilter.CustomOutputDataType = numerictype([],9,7); butterFilter.RoundingMethod = 'nearest'; butterFilter.OverflowAction = 'wrap'; fvtool(butterFilter, 'Fs', Fs, 'FrequencyScale', 'log','Arithmetic','fixed'); %% Requantize the Filter % 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 double-precision response and zoom in on the % passband response. The quantized filter is now just over 0.1 dB lower % than the reference filter. butterFilter.CustomNumeratorCoefficientsDataType = numerictype([],16); butterFilter.CustomDenominatorCoefficientsDataType = numerictype([],16); butterFilter.CustomScaleValuesDataType = numerictype([],16); fvtool(butterFilter, 'Fs', Fs, 'FrequencyScale', 'log','Arithmetic','fixed'); axis([0 1.0 -1 1]); %% Examine the Scale Values % 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 specification--an 8-bit 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. scaless = butterFilter.ScaleValues .* 2^7; disp(scaless); %% % Now scale the filter using the frequency domain infinity norm. % After scaling, the scale value are all one in this case. scale(butterFilter,'Linf'); scaless = butterFilter.ScaleValues; disp(scaless); %% Generate HDL Code and Test Bench 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(R) filter. % % To generate Verilog instead, change the value of the property % 'TargetLanguage', from 'VHDL' to 'Verilog'. % % 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. % % Assume 8-bit signed fixed-point input with 7 bits of fraction. % % Generate a VHDL test bench to verify that the results % match the MATLAB results exactly. % % Create a temporary work directory. Generate VHDL code for the filter and % a VHDL test bench to verify that the results match the MATLAB results exactly. % % Open the generated VHDL file for the filter in the editor. workingdir = tempname; userstim = []; for n = [50, 100, 150, 200, 250, 300] userstim = [userstim, sin(2*pi*n/Fs*(0:Fs/n))]; %#ok end generatehdl(butterFilter, 'Name', 'hdlbutter',... 'TargetLanguage', 'VHDL',... 'TargetDirectory', workingdir, ... 'GenerateHDLTestbench', 'on', ... 'TestBenchUserStimulus', userstim, ... 'InputDataType',numerictype(1,8,7)); edit(fullfile(workingdir, 'hdlbutter.vhd')); % Open the generated VHDL test bench in the editor. edit(fullfile(workingdir, 'hdlbutter_tb.vhd')); %% Generate HDL Code and Test Bench Using FDHDLTool % HDL code and test bench can optionally be generated using the % FDHDLTOOL command that opens the dialog which lets you customize and % generate Verilog or VHDL code and test benches for the quantized filter. % % The GUI is customized to 'butterFilter' in such a way that only the % relevant widgets are available to set. To generate HDL code and test bench you % should first go to the working directory and then call the FDHDLTOOL command. fdhdltool(butterFilter, numerictype(1,8,7)); %% % You can modify the default settings and click Generate to generate HDL % and/or test bench. %% ModelSim(R) Simulation Results % The following display shows the ModelSim HDL simulator after running % the VHDL test bench. Compare the ModelSim result with the MATLAB % result below. %% % <<../butter_screen.jpg>> xrange = (0:length(userstim) - 1); y = butterFilter(fi(userstim.',1,8,7)); 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 #'); %% Conclusion % You designed a Butterworth filter to meet the given specification. % You then quantized the filter and discovered that the passband % requirement was not met. Requantizing the coefficients and scaling % the filter fixed this issue. You then generated VHDL code for the filter % and a 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.