HDL Sample Rate Conversion Using Farrow Filters
This example shows how you can design and implement hardware efficient sample rate converters for an arbitrary factor using polynomial-based (Farrow) structures. Sample rate conversion (SRC) between arbitrary factors is useful for many applications including symbol synchronizations in digital receivers, speech coding, audio sampling, etc. This example shows how you can convert the sampling rate of an audio signal from 8kHz to 44.1 kHz.
Overview
To resample the incoming signal from 8 kHz
to 44.1 kHz
, you must interpolate by 441 and decimate by 80. This SRC can be implemented using polyphase structures. However using the polyphase structures for any arbitrary factor usually results in large number of coefficients leading to a lot of memory requirement and area. This example shows how to efficiently implement SRC with a mix of polyphase and Farrow filter structures.
Design of Interpolating Stages
First, interpolate the original 8 kHz
signal by a factor of 4
using a cascade of FIR halfband filters. This interpolation results in an intermediate signal of 32 kHz
. Polyphase filters are particularly well adapted for interpolation or decimation by an integer factor and for fractional rate conversions when the interpolation and the decimation factors are low. Design the interpolating stages for the specifications given.
L = 4; % Interpolation factor FsOut = 32e3; % Output sample rate TW = 0.125 * 2 * FsOut / L; % Transition width (Hz) Astop = 50; % Minimum stopband attenuation (dB) FIRCascade = designMultistageInterpolator(L,FsOut,TW,Astop,'CostMethod','design');
Design of Farrow Filter
The signal output from the above interpolating stages needs to be further interpolated from 32 kHz
to 44.1 kHz
. This operation is done by a Farrow rate converter filter designed with a cubic Lagrange polynomial.
FsInp = 32e3; % Input sample rate FsOut = 44.1e3; % Output sample rate TOL = 0; % Output rate tolerance NP = 3; % Polynomial order farrowFilter = dsp.FarrowRateConverter(FsInp, FsOut, TOL, NP);
To prevent the datapath from growing to very large word lengths, quantize the filter stages such that the inputs to each stage are 12 bits and the outputs are 12 bits.
cascadeOutNT = numerictype([],12,11); FIRCascade.Stage1.FullPrecisionOverride = false; FIRCascade.Stage1.OutputDataType = 'Custom'; FIRCascade.Stage1.CustomOutputDataType = cascadeOutNT; FIRCascade.Stage2.FullPrecisionOverride = false; FIRCascade.Stage2.OutputDataType = 'Custom'; FIRCascade.Stage2.CustomOutputDataType = cascadeOutNT; farrowOutNT = numerictype(1,12,11); farrowFilter.OutputDataType = farrowOutNT;
Cascade of Complete SRC and Magnitude Response
The overall filter is obtained by creating a cascade of the interpolating stages and the Farrow filter.
sampleRateConverter = cascade(FIRCascade.Stage1, FIRCascade.Stage2, farrowFilter);
The magnitude response of the cascaded SRC filter shows that it meets the 50 dB minimum stopband attenuation specification.
Fs = 32e3*441; % The highest clock rate is 14.112 MHz W = linspace(0,44.1e3,2048); % Define the frequency range analysis fvt = fvtool(sampleRateConverter,'FrequencyRange','Specify freq. vector', ... 'FrequencyVector',W,'Fs',Fs, ... 'NormalizeMagnitudeto1','on', 'Color', 'white'); legend(fvt,'Cascade of FIR and Farrow Rate Converter Response',... 'Location','NorthEast')
Generate HDL & Test Bench
You can now generate VHDL code for the cascaded SRC using the generatehdl
command. You can also generate the VHDL test bench by passing the 'TestBenchUserStimulus'
and 'GenerateHDLTestbench'
properties into the generatehdl
command. The VHDL code can be simulated in any HDL simulator to verify the results.
workingdir = tempname; inpFrameSz = 640; tVector = linspace(0.005, 7.5, inpFrameSz); srcTBStim = (chirp(tVector, 0, 1, 150))'; generatehdl(sampleRateConverter, ... 'TargetDirectory', workingdir, ... 'InputDataType', numerictype(1,12,11), ... 'OptimizeForHDL', 'on', ... 'GenerateHDLTestbench', 'on', ... 'TestBenchUserStimulus', srcTBStim, ... 'ErrorMargin', 2);
### Starting VHDL code generation process for filter: casfilt ### Cascade stage # 1 ### Starting VHDL code generation process for filter: casfilt_stage1 ### Generating: /tmp/Bdoc23b_2361005_716704/tpf312e515_61d8_4eaa_bb53_bf4fc1d1741d/casfilt_stage1.vhd ### Starting generation of casfilt_stage1 VHDL entity ### Starting generation of casfilt_stage1 VHDL architecture ### Successful completion of VHDL code generation process for filter: casfilt_stage1 ### Cascade stage # 2 ### Starting VHDL code generation process for filter: casfilt_stage2 ### Generating: /tmp/Bdoc23b_2361005_716704/tpf312e515_61d8_4eaa_bb53_bf4fc1d1741d/casfilt_stage2.vhd ### Starting generation of casfilt_stage2 VHDL entity ### Starting generation of casfilt_stage2 VHDL architecture ### Successful completion of VHDL code generation process for filter: casfilt_stage2 ### Cascade stage # 3 ### Starting VHDL code generation process for filter: casfilt_stage3 ### Generating: /tmp/Bdoc23b_2361005_716704/tpf312e515_61d8_4eaa_bb53_bf4fc1d1741d/casfilt_stage3.vhd ### Starting generation of casfilt_stage3 VHDL entity ### Starting generation of casfilt_stage3 VHDL architecture ### Successful completion of VHDL code generation process for filter: casfilt_stage3 ### Generating: /tmp/Bdoc23b_2361005_716704/tpf312e515_61d8_4eaa_bb53_bf4fc1d1741d/casfilt.vhd ### Starting generation of casfilt VHDL entity ### Starting generation of casfilt VHDL architecture ### Successful completion of VHDL code generation process for filter: casfilt ### HDL latency is 1325 samples ### Starting generation of VHDL Test Bench. ### Generating input stimulus ### Done generating input stimulus; length 640 samples.
Warning: HDL optimization may cause small numeric differences that will be flagged as errors when running this testbench.
### Generating Test bench: /tmp/Bdoc23b_2361005_716704/tpf312e515_61d8_4eaa_bb53_bf4fc1d1741d/casfilt_tb.vhd ### Creating stimulus vectors ... ### Done generating VHDL Test Bench.
ModelSim® Simulation Results
The following display shows the ModelSim® HDL simulator results after running the VHDL test bench.
Conclusion
This example showed how you can design a sample rate converter using a Farrow structure, and how to analyze the response, quantize it, and generate bit-accurate VHDL code and test bench.