Documentation

HDL Inverse Sinc Filter

This example illustrates how to generate HDL code for an inverse sinc (sin x/x) peaking filter that adds preemphasis to compensate for the inherent sinc response of the digital-to-analog converter (DAC). The input is a 10-bit video signal and the output is scaled to accommodate the gain of the inverse sinc response.

Design the Filter

Use a video sampling rate of 27 MHz and a passband edge frequency of 7.2 MHz. Set the allowable peak-to-peak passband ripple to 0.1 dB and the stopband attenuation to -66 dB. Then, design the filter using firceqrip, and create a symmetric FIR filter. Finally, examine the response using fvtool.

Fs           = 27e6;                  % Sampling Frequency in MHz
N            = 20;                    % Order
Fpass        = 7.2e6;                 % Passband Frequency in MHz
slope        = 0;                     % Stopband Slope
spectype     = 'passedge';            % Frequency Specification Type
isincffactor = 1;                     % Inverse Sinc Frequency Factor
isincpower   = 1;                     % Inverse Sinc Power
Dstop        = 10^(-66/20);           % Stopband Attenuation -66 dB
ripple       = 10^(0.1/20);           % Passband Ripple 0.1 dB p-p
Dpass        = (ripple - 1) / (ripple + 1);

% Calculate the coefficients using the FIRCEQRIP function.
b  = firceqrip(N, Fpass/(Fs/2), [Dpass, Dstop], 'slope', slope, ...
               spectype, 'invsinc', isincffactor, isincpower);
inverseSincFilter = dsp.FIRFilter('Numerator',b,'Structure','Direct form symmetric');
fvtool(inverseSincFilter,'Fs',Fs);
axis([0 Fs/2e6 -80 10]);

Create the Quantized Filter

Use the infinity norm of freqz to find the maximum inverse sinc gain, and then scale this gain into bits, rounding up. Next, apply fixed point settings to the filter. Check the response with fvtool.

Gbits = ceil(log2(norm(freqz(inverseSincFilter), inf)));

specifyall(inverseSincFilter);
inverseSincFilter.CustomCoefficientsDataType = numerictype(1,16,15);
inverseSincFilter.CustomOutputDataType = numerictype(1,10+Gbits,9);
inverseSincFilter.CustomProductDataType = numerictype(1,32,30);
inverseSincFilter.CustomAccumulatorDataType = numerictype(1,33,30);

fvtool(inverseSincFilter,'Fs',Fs,'Arithmetic','fixed');
axis([0 Fs/2e6 -80 10]);

Generate HDL Code from the Quantized Filter

Starting with the quantized filter, generate VHDL or Verilog code. You also have the option of generating a VHDL or Verilog test bench to verify that the HDL design matches the MATLAB® filter.

To generate VHDL instead, change the value of the property 'TargetLanguage', from 'Verilog' to 'VHDL'.

Generate a Verilog test bench to make sure that the result match the response you see in MATLAB exactly. Since this is a video filter, build and specify a stimulus similar to a line of video as the test stimulus.

Create a temporary work directory. After generating the HDL code (selecting Verilog in this case) and test bench, open the generated Verilog files in the editor.

workingdir = tempname;

Fsub        = 5e6*63/88;                     % 3.579545 MHz
VoltsperIRE = (7 + 1/7)/1000;                % IRE steps are 7.14mV
Nsamples    = 1716;                          % 27 MS/s video line
userstim = zeros(1,Nsamples);                % predefine our array

% 8 Sample raised-cosine -40 IRE
syncedge = ((cos(pi/2 *(0:7)/8).^2) - 1) * 40 * VoltsperIRE;
burst    = 20 * VoltsperIRE * sin(2*pi * Fsub/Fs * (0:Fs/(Fsub/9)));

userstim(33:40)    = syncedge;
userstim(41:170)   = repmat(-40 * VoltsperIRE, 1, 130);
userstim(171:178)  = syncedge(end:-1:1);
userstim(180:247)  = burst;
% Ramp with chroma over 1416 samples from 7.5 to 80 IRE with a 20 IRE chroma
actlen = 1416;
active = 1:actlen;
userstim(260:1675) = (((active/actlen * 72.5)+7.5) + ...
                      20 * sin(2*pi * Fsub/Fs * active)) * VoltsperIRE;
userstim(1676:Nsamples) = 72.5 * VoltsperIRE * (41:-1:1)/41;

generatehdl(inverseSincFilter, 'Name', 'hdlinvsinc', 'TargetLanguage', 'Verilog',...
    'GenerateHDLTestbench','on', ...
    'TestBenchUserStimulus', userstim,...
    'TargetDirectory', workingdir,...
    'InputDataType',numerictype(1,10,9));

edit(fullfile(workingdir, 'hdlinvsinc.v'));

edit(fullfile(workingdir, 'hdlinvsinc_tb.v'));
### Starting Verilog code generation process for filter: hdlinvsinc
### Generating: <a href="matlab:edit('/tmp/Bdoc16b_437511_55686/publish_examples1/tp3c3d7b15_d879_4a90_ae10_51e7116c6822/hdlinvsinc.v')">/tmp/Bdoc16b_437511_55686/publish_examples1/tp3c3d7b15_d879_4a90_ae10_51e7116c6822/hdlinvsinc.v</a>
### Starting generation of hdlinvsinc Verilog module
### Starting generation of hdlinvsinc Verilog module body
### Successful completion of Verilog code generation process for filter: hdlinvsinc
### HDL latency is 2 samples
### Starting generation of VERILOG Test Bench.
### Generating input stimulus
### Done generating input stimulus; length 1716 samples.
### Generating Test bench: <a href="matlab:edit('/tmp/Bdoc16b_437511_55686/publish_examples1/tp3c3d7b15_d879_4a90_ae10_51e7116c6822/hdlinvsinc_tb.v')">/tmp/Bdoc16b_437511_55686/publish_examples1/tp3c3d7b15_d879_4a90_ae10_51e7116c6822/hdlinvsinc_tb.v</a>
### Creating stimulus vectors ...
### Done generating VERILOG Test Bench.

ModelSim® Simulation Results

The following display show the ModelSim HDL simulator waveform after running the test bench. Compare the ModelSim result with the MATLAB result below.

xrange = 0:Nsamples-1;
y = inverseSincFilter(fi(userstim.',1,10,9));
subplot(2,1,1); plot(xrange, userstim);
axis([0 500 -0.4 1.1]);
title('HDL Inverse Sinc Filter In Stimulus.');
xlabel('Sample #');
subplot(2,1,2); plot(xrange, y);
axis([0 500 -0.4 1.1]);
title('HDL Inverse Sinc Filter Out Response.');
xlabel('Sample #');

Conclusion

You designed an inverse sinc filter to meet the given specification. You generated Verilog code and a Verilog test bench using an approximation of a video line as the test stimulus.

You can use an HDL Simulator, to verify these results. You can also experiment with VHDL and Verilog for both filters and test benches.

Was this topic helpful?