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

    %% HDL Fractional Delay (Farrow) Filter
% This example illustrates how to generate HDL code for a fractional
% delay (Farrow) filter for timing recovery in a digital modem. A Farrow filter
% structure provides variable fractional delay for the received data stream
% prior to downstream symbol sampling. This special FIR filter structure
% permits simple handling of filter coefficients by an efficient
% polynomial interpolation formula implementation to provide variable
% fractional resampling.
%
% In a typical digital modem application, the fractionally resampled data
% output from a Farrow filter is passed along to a symbol sampler
% with optional carrier recovery. For more details of this complete application
% please refer to "Timing Recovery Using Fixed-Rate Resampling"
% for Simulink(R) and Communications System Toolbox(TM).

% Copyright 2004-2012 The MathWorks, Inc.

%% Design the Filter
% To design a fractional delay filter using the Cubic Lagrange interpolation
% method, first create a specification object with filter order |3| and an
% arbitrary fractional delay of |0.3|. Next, create a farrow filter object
% |Hd|, using the design method of the specification object with argument
% |lagrange|. This method is also called with property |FilterStructure|
% and its value |fd|. You can look into the details of the filter object
% |Hd| by using the |info| command.

fDelay = 0.3;
filtdes = fdesign.fracdelay(fDelay, 'N', 3);
Hd = design(filtdes,'lagrange', 'FilterStructure', 'farrowfd');
info(Hd)

%%
% The fractional delay for the Farrow filter is tunable and can be altered
% to lead a different magnitude response. You can see this by creating a set
% of filters that are copies of the pre-designed filter |Hd| with each
% differing in their |fracdelay| values.

for d=0:9,
    h(d+1) = copy(Hd);
    h(d+1).fracdelay = d/10;
end
fvtool(h,'Color','white')
fvtool(h,'Analysis','PhaseDelay','Color','white')

%% Quantize the Filter
% Set the filter object to fixed-point mode to quantize it.  Assume
% eight-bit fixed-point input data with eight-bit coefficients. Modify the
% fixed-point data word lengths and fraction lengths accordingly. The
% |CoeffFracLength| property is set automatically because coefficient
% autoscaling is set to |on| by default by the property |CoeffAutoscale|. 

Hd.arithmetic            = 'fixed';
Hd.InputWordLength       = 8;
Hd.InputFracLength       = 7;
Hd.CoeffWordLength       = 8;

%% Generate HDL Code from the Quantized Filter
% Starting with the correctly quantized filter, you can generate VHDL or
% Verilog code using the |generatehdl| command. You create a temporary work
% directory and then use the |generatehdl| command using the appropriate
% property-value pairs. After generating the HDL code using |VHDL| for the
% |TargetLanguage| property in this case, you can open the generated VHDL file in
% the editor by clicking on the hyperlink displayed in the command line display
% messages.

workingdir = tempname;
generatehdl(Hd, 'Name', 'hdlfarrow', ...  
                'TargetLanguage', 'VHDL',...
                'TargetDirectory', workingdir);

%% Generate HDL Test Bench
% To verify the HDL code, you can generate an HDL test bench to simulate the
% HDL code using an HDL simulator. The test bench will verify the results of
% the HDL code with the results of the MATLAB(R) |filter| command. The 
% stimuli for the filter input |filter_in| port and fractional delay
% |filter_fd| port can be specified using properties |TestbenchStimulus|,
% |TestbenchUserStimulus| and |TestbenchFracDelayStimulus|.
%
% Predefined stimulus for the filter input |filter_in| port can be specified
% for input data stimulus using the property |TestbenchStimulus| as with the other
% filter structures. You can specify your own stimulus for the input data by
% using the property |TestbenchUserStimulus| and passing a MATLAB vector as
% the value.
%
% You can specify the fractional delay stimulus using the property
% |TestbenchFracdelayStimulus|. A vector of double between |0| and |1| is
% generated automatically by specifying either |RandSweep| or |RampSweep|.
% The default behavior is to provide a fractional delay stimulus of a
% constant set to the |fracdelay| value of the filter object.
%
% The following command specifies the input stimulus to |chirp|, and the
% fractional delay vector is set to a constant |0.3| for all the simulation
% time. This is the default behavior when the |TestbenchFracDelayStimulus|
% property is not set otherwise.
generatehdl(Hd, 'Name', 'hdlfarrow', ...
    'GenerateHDLTestbench', 'on', ...
    'TestBenchName', 'hdlfarrow_default_tb',...
    'TargetLanguage', 'VHDL',...
    'TargetDirectory', workingdir);

%%      
% To automatically generate  the test vector for a fractional delay port, 
% specify |RampSweep| for |TestBenchFracDelayStimulus|. It generates a
% vector of values between |0| and |1| sweeping in a linear fashion. The length
% of this vector is equal to the input stimulus vector.

generatehdl(Hd, 'Name', 'hdlfarrow', ...
    'GenerateHDLTestbench', 'on', ...
    'TestBenchName', 'hdlfarrow_rampsweep_tb',...
    'TargetLanguage', 'VHDL',...
    'TestBenchStimulus', 'chirp',...
    'TestbenchFracDelaystimulus', 'Rampsweep', ...
    'TargetDirectory', workingdir);
%%
% You can generate a customized input stimulus vector using MATLAB commands
% and pass it to the test bench stimulus properties for the user defined input
% and |fracdelay| stimuli. An input test vector |userinputstim| is generated
% using the |chirp| command and the fractional delay test vector |userfdstim| is
% generated of length equal to the input test vector. 

t=-2:0.01:2;                           % +/-2 secs @ 100 Hz sample rate
userinputstim = chirp(t,100,1,200,'q'); % Start @100Hz, cross 200Hz at t=1sec 
leninput = length(userinputstim);
samplefdvalues = [0.1, 0.34, 0.78, 0.56, 0.93, 0.25, 0.68, 0.45];
samplesheld = ceil(leninput/length(samplefdvalues));
ix = 1;
for n = 1:length(samplefdvalues)-1
    userfdstim(ix: ix + samplesheld-1) =  repmat(samplefdvalues(n),1, samplesheld);
    ix = ix + samplesheld;
end
userfdstim(ix:leninput)= repmat(samplefdvalues(end),1 , leninput-length(userfdstim));

generatehdl(Hd, 'Name', 'hdlfarrow', ...
    'GenerateHDLTestbench', 'on', ...
    'TestBenchName', 'hdlfarrow_userdefined_tb',...
    'TargetLanguage', 'VHDL',...
    'TestBenchUserStimulus', userinputstim,...
    'TestbenchFracDelaystimulus', userfdstim, ...
    'TargetDirectory', workingdir);

%% ModelSim(R) Simulation Results
% The following display shows the ModelSim(R) HDL simulator after running
% the VHDL test bench. 

%%
% <<../hdlfarrow_screen.JPG>>
% 

%% Conclusion
% In this example, we showed how you can design a double-precision fractional
% delay filter to meet the given specifications. We also showed how you can
% quantize the filter and generate VHDL code. Then we showed how you can
% generate VHDL test benches using several options to specify the input
% and fracdelay stimulus vector.
%
% You can use any HDL simulator to verify these results.  You
% can also experiment with Verilog for both filters and
% test benches.