www.gusucode.com > hdlverifier 案例代码 matlab源码程序 > hdlfilter/hdlprogramcoeffs.m

    %% HDL Programmable FIR Filter
% This example illustrates how to generate HDL code for an FIR filter 
% with a processor interface for loading coefficients. The filter can be
% programmed to any desired response by loading the coefficients into 
% an internal coefficient memory using the processor interface. 
%
% Let us assume that we need to implement a bank of filters, having
% different responses, on a chip. If all of the filters have a direct-form
% FIR structure, and the same length, then we can use 
% a processor interface to load the coefficients for each response from
% a RAM or register file when needed.
%
% This design will add latency of a few cycles before the input samples
% can be processed with the loaded coefficients. However, it has the 
% advantage that the same filter hardware can be programmed with new
% coefficients to obtain a different filter response. This saves chip area, as
% otherwise each filter would be implemented separately on the chip.
%
% In this example, we will consider two FIR filters, one with
% a highpass response and the other with a lowpass response. We will show how the
% same filter  hardware can be programmed for each response by loading the
% corresponding set of coefficients. We will generate VHDL code for the
% filter and show the two responses using the generated VHDL test bench.

%   Copyright 2007-2016 The MathWorks, Inc.

%% Design the Filters
% Create the lowpass filter design object, then create the FIR Filter System object (Hlp).
% Then, transform it to create a FIR Filter System object with a highpass response (Hhp). 

Fpass = 0.45; % Passband Frequency
Fstop = 0.55; % Stopband Frequency                                                                                         
Apass = 1;    % Passband Attenuation (dB)
Astop = 60;   % Stopband Attenuation (dB)

f = fdesign.lowpass('Fp,Fst,Ap,Ast',Fpass,Fstop,Apass,Astop);
lpFilter = design(f, 'equiripple','FilterStructure', 'dffir','SystemObject',true); % Lowpass

hpcoeffs = firlp2hp(lpFilter.Numerator); 
hpFilter = dsp.FIRFilter('Numerator', hpcoeffs); % Highpass

%% Quantize the Filters
% Assume the coefficients need be stored in a memory of bit width 14. 
% Using this information, apply fixed point settings to the Sytem object filter.

lpFilter.FullPrecisionOverride=false;
lpFilter.CoefficientsDataType='Custom';
lpFilter.CustomCoefficientsDataType=numerictype(1,14,13);
lpFilter.OutputDataType='Same as Accumulator';
lpFilter.ProductDataType='Full precision';
lpFilter.AccumulatorDataType='Full precision';

hpFilter.FullPrecisionOverride=false;
hpFilter.CoefficientsDataType='Custom';
hpFilter.CustomCoefficientsDataType=numerictype(1,14,13);
hpFilter.OutputDataType='Same as Accumulator';
hpFilter.ProductDataType='Full precision';
hpFilter.AccumulatorDataType='Full precision';

%%
% After applying fixed point settings, it is important to verify that
% the System object filter still meets the specifications. We will use the function
% 'measure' to check if this is true.

measure(lpFilter,'Arithmetic','fixed')

%%  Verify the Filter Output
% Generate a linear swept-frequency stimulus signal using chirp.
% Use this input stimulus for filtering through the lowpass FIR filter
% first. Then change the coefficients of the filter to obtain a highpass
% response and use the same input sample to filter again. 
%
% For the above two-stage filtering operation our goal is to compare the
% filter output from MATLAB(R) with that from the generated HDL code.
%
% Plotting the input samples and the filtered output shows the lowpass and
% highpass behavior.

x =  chirp(0:199,0,199,0.4);

lpcoeffs = lpFilter.Numerator;            % store original lowpass coefficients
y1 = lpFilter(fi(x,1,14,13).');           % filter the signal

lpFilter.Numerator = hpFilter.Numerator;  % load the highpass filter coefficients
y2 = lpFilter(fi(x,1,14,13).');           % filter the signal

y = [y1; y2];                             % concatenate output signals

lpFilter.Numerator = lpcoeffs;            % restore original lowpass coefficients

subplot(2,1,1);plot([x,x]);
xlabel('Time [samples]');ylabel('Amplitude'); title('Input Stimulus');
subplot(2,1,2);plot(y);
xlabel('Time [samples]');ylabel('Amplitude'); title('Filtered Output');

%% Generate VHDL Code with Processor Interface and Test Bench
% For the quantized lowpass filter, we will generate the VHDL code with
% a processor interface by setting the property 'CoefficientSource' to
% 'ProcessorInterface'. This will result in the generated code
% having additional ports for write_address, write_enable,
% coeffs_in, and write_done signals. This interface can be used to load the
% coefficients from a host processor into an internal register file. The
% HDL has an additional shadow register that is updated from the register
% file when the 'write_done' signal is high. This enables simultaneous 
% loading and processing of data by the filter entity.
%
% To verify that the filter entity can be successively loaded with
% two different sets of filter coefficients, we will generate
% a VHDL test bench. First, the test bench loads the lowpass
% coefficients and processes the input samples. Then the test bench loads
% the coefficients corresponding to the highpass filter response, and
% processes the input samples again.
%
% The generated VHDL code and VHDL test bench can be compiled  and simulated
% using an HDL simulator such as ModelSim(R). Notice that the loading of the
% second set of coefficients and the processing of the last few input
% samples are performed simultaneously. 
%
% In order to generate the required test bench,  we set the property
% 'GenerateHDLTestbench' to 'on' and pass 'TestbenchCoeffStimulus' in the
% call to the generatehdl command. The value passed in for
% 'TestbenchCoeffStimulus' is a vector of coefficients that are to be used
% for subsequent processing of input samples. This example passes in a
% vector of coefficients corresponding to a highpass filter. 
%
% Assume 14-bit signed fixed-point input with 13 bits of fraction precision
% is needed due to fixed data path requirements of input ADC.

workingdir = tempname;

generatehdl(lpFilter, 'Name', 'FilterProgrammable', ...
                 'InputDataType', numerictype(1,14,13), ...
                 'TargetLanguage', 'VHDL', ...
                 'TargetDirectory', workingdir, ...
                 'CoefficientSource', 'ProcessorInterface', ...
                 'GenerateHDLTestbench', 'on', ...
                 'TestBenchUserStimulus', x, ...
                 'TestbenchCoeffStimulus', hpFilter.Numerator);
             
%% ModelSim(R) Simulation Results
% The following display shows the ModelSim HDL simulator after running the
% generated .do file scripts for the test bench. Compare the ModelSim result
% with the MATLAB result as plotted before. 

%%
% <<../proc_interface.JPG>>

%% Conclusion
% We designed highpass and lowpass FIR filters to meet the
% given specifications. We then quantized the filter and generated VHDL
% code for the filter, with an interface to load the coefficients from a
% processor. We then generated a VHDL test bench that showed the
% processing of input samples after loading lowpass coefficients, repeating
% the operation with the highpass coefficients. We showed how to generate
% the VHDL code that implements filter hardware that is reusable for
% different responses when different sets of coefficients are loaded via
% the port interface from a host processor.