Filter Design HDL Coder

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. For the purpose of this example, we will show how you can convert the sampling rate of an audio signal from 8kHz to 44.1 kHz.

Overview

In order to resample the incoming signal from 8 kHz to 44.1 kHz, we will have to essentially 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. In this example, we will show you how SRC can be efficiently implemented by a mix of polyphase structures and farrow filter structure.

Design of Interpolating Stages

First, we interpolate the original 8 kHz signal by a factor of 4 using a cascade of FIR halfband filters. This will result 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. For the specifications as below, let us design the interpolating stages.

TW = .125;          % Transition Width
Astop = 50;         % Minimum stopband attenuation
f2 = fdesign.interpolator(4,'Nyquist',4,'TW,Ast',TW,Astop);
Hfir = design(f2,'multistage','HalfbandDesignMethod','equiripple');

Design of Farrow Filter

The signal output from the above interpolating stages need to be further interpolated from 32 kHz to 44.1 kHz. This will be done by a Farrow filter with cubic Lagrange polynomial. We will first design a single rate Farrow filter and then convert it to a multirate Farrow filter.

L = 441; % Interpolating factor for Farrow
M = 320; % Decimating factor for Farrow
N = 3;  % Polynomial Order
ffar = fdesign.fracdelay(0,'N',N);
Hfar = design(ffar,'lagrange');
Hfar = mfilt.farrowsrc(L,M,Hfar.Coefficients);

Cascade of Complete SRC and Magnitude Response

The overall filter is simply obtained by creating a cascade of the interpolating stages and the farrow filter.

Hsrc = cascade(Hfir.Stage(1),Hfir.Stage(2), Hfar);

Let us now quantize the filter stages such that the inputs to each stage is 12 bit wide. This will forbid the datapath to grow to very large word lengths.

%Stage 1 - FIR Interpolator (x2)
Hsrc.Stage(1).Arithmetic = 'fixed';
Hsrc.Stage(1).InputWordLength = 12;
Hsrc.Stage(1).InputFracLength = 11;
%Stage 2 - FIR Interpolator (x2)
Hsrc.Stage(2).Arithmetic = 'fixed';
Hsrc.Stage(2).InputWordLength = 12;
Hsrc.Stage(2).InputFracLength = 11;
%Stage 3 - Farrow SRC (x441/320)
Hsrc.Stage(3).Arithmetic = 'fixed';
Hsrc.Stage(3).InputWordLength = 12;
Hsrc.Stage(3).InputFracLength = 11;

Let us look at the magnitude response of the cascaded and quantized filter. The magnitude response shows that the cascaded SRC filter meets the specification of a 50 dB minimum attenuation in the stopband.

Fs = 32e3*441; % The highest clock rate is 14.112 MHz
W = linspace(0,44.1e3,2048);  % Define the frequency range analysis
hfvt = fvtool(Hsrc,'FrequencyRange','Specify freq. vector', ...
    'FrequencyVector',W,'Fs',Fs, ...
    'NormalizeMagnitudeto1','on', 'Color', 'white');
legend(hfvt,'Farrow Interpolator',...
    'Location','NorthEast')

Generate HDL & Testbench

You can now generate VHDL code for the cascaded SRC using the generatehdl command. You can also generate the VHDL testbench by passing 'GenerateHDLtestbench' property with the generatehdl command and setting it to 'on'. The VHDL code can be simulated in any HDL simulator to verify the results.

% You can now generate VHDL code for the cascaded SRC
workingdir = tempname;
generatehdl(Hsrc,  'TargetDirectory', workingdir);

%test stimulus
t = 0.005:0.005:7.5;
stim = chirp(t, 0, 1, 150);
generatehdl(Hsrc,  'TargetDirectory', workingdir, ...
    'GenerateHDLTestbench','on', ...
    'testbenchuserstim', stim);
### Starting VHDL code generation process for filter: Hsrc
### Cascade stage # 1
### Starting VHDL code generation process for filter: Hsrc_stage1
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage1.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage1.vhd</a>
### Starting generation of Hsrc_stage1 VHDL entity
### Starting generation of Hsrc_stage1 VHDL architecture
Warning: Adding extra quantizer to fir to be compatible with MATLAB filter. 
### Successful completion of VHDL code generation process for filter: Hsrc_stage1
### Cascade stage # 2
### Starting VHDL code generation process for filter: Hsrc_stage2
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage2.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage2.vhd</a>
### Starting generation of Hsrc_stage2 VHDL entity
### Starting generation of Hsrc_stage2 VHDL architecture
Warning: Adding extra quantizer to fir to be compatible with MATLAB filter. 
### Successful completion of VHDL code generation process for filter: Hsrc_stage2
### Cascade stage # 3
### Starting VHDL code generation process for filter: Hsrc_stage3
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage3.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage3.vhd</a>
### Starting generation of Hsrc_stage3 VHDL entity
### Starting generation of Hsrc_stage3 VHDL architecture
### Successful completion of VHDL code generation process for filter: Hsrc_stage3
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc.vhd</a>
### Starting generation of Hsrc VHDL entity
### Starting generation of Hsrc VHDL architecture
### Successful completion of VHDL code generation process for filter: Hsrc
### HDL latency is 1325 samples
### Starting VHDL code generation process for filter: Hsrc
### Cascade stage # 1
### Starting VHDL code generation process for filter: Hsrc_stage1
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage1.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage1.vhd</a>
### Starting generation of Hsrc_stage1 VHDL entity
### Starting generation of Hsrc_stage1 VHDL architecture
Warning: Adding extra quantizer to fir to be compatible with MATLAB filter. 
### Successful completion of VHDL code generation process for filter: Hsrc_stage1
### Cascade stage # 2
### Starting VHDL code generation process for filter: Hsrc_stage2
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage2.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage2.vhd</a>
### Starting generation of Hsrc_stage2 VHDL entity
### Starting generation of Hsrc_stage2 VHDL architecture
Warning: Adding extra quantizer to fir to be compatible with MATLAB filter. 
### Successful completion of VHDL code generation process for filter: Hsrc_stage2
### Cascade stage # 3
### Starting VHDL code generation process for filter: Hsrc_stage3
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage3.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_stage3.vhd</a>
### Starting generation of Hsrc_stage3 VHDL entity
### Starting generation of Hsrc_stage3 VHDL architecture
### Successful completion of VHDL code generation process for filter: Hsrc_stage3
### Generating: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc.vhd</a>
### Starting generation of Hsrc VHDL entity
### Starting generation of Hsrc VHDL architecture
### Successful completion of VHDL code generation process for filter: Hsrc
### HDL latency is 1325 samples
### Starting generation of VHDL Test Bench.
### Generating input stimulus
### Done generating input stimulus; length 1500 samples.
Warning: The input stimulus length 1500 is less than 27342, length of the
impulse response of the filter. Consider adding more input samples. 
### Generating Test bench: <a href="matlab:edit('/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_tb.vhd')">/tmp/BR2014bd_145981_71764/tpae564f5d_0c78_4be4_8bb0_e2753099681a/Hsrc_tb.vhd</a>
### Creating stimulus vectors ...
### Done generating VHDL Test Bench.

ModelSim® Simulation Results

The following display shows the ModelSim® HDL simulator after running the VHDL test bench.

Conclusion

In this example, we showed how you can design a sample rate converter using farrow structure. We also showed you how you can analyze the response, quantize it and generate bit accurate VHDL code and its test bench.