Main Content

Implement CIC Decimation Filter for HDL

This example shows how to use the CIC Decimation HDL Optimized block to filter and downsample data. You can generate HDL code from the subsystem in the Simulink(R)model.

  1. Generate frames of random input samples.

  2. Generate reference output data from the dsp.CICDecimation System object™.

  3. Run the Simulink model that contains the CIC Decimation HDL Optimized block.

  4. Compare the Simulink block output data with the reference data.

Set up input data parameters. The model uses these workspace variables to configure the CIC Decimation HDL Optimized block. The block supports variable decimation factor specified at an input port. Choose a range for the input decimFactor and set the Decimation factor parameter of the block to the maximum expected decimation factor.

R = 8; % Decimation factor
M = 1; % Differential delay
N = 3; % Number of sections

varRValue = [4,R];

numFrames = length(varRValue);
dataSamples = cell(1,numFrames);
varRtemp = cell(1,numFrames);
cicFcnOutput = [];
WL = 0; % Word length
FL = 0; % Fraction length

Generate frames of random input samples. To generate reference output data for comparison, apply the samples to the dsp.CICDecimation System object. This object does not support variable decimation rate, so you must create and release the object for each change in the decimation factor.

for i = 1:numFrames
    framesize = varRValue(i)*randi([5 20],1,1);
    dataSamples{i} = fi(randn(framesize,1),1,16,8);
    varRtemp{i} = fi(varRValue(i)*ones(framesize,1),0,12,0);
    obj = dsp.CICDecimator('DifferentialDelay',M,'NumSections',N,'DecimationFactor',varRValue(i));
    cicOut = step(obj,dataSamples{i}).';
    WL = max([WL,cicOut.WordLength]);
    FL = max([FL,cicOut.FractionLength]);
    cicFcnOutput = [fi(cicFcnOutput,1,WL,FL),cicOut];
    release(obj);
end

Generate a stream of samples by converting frames to samples, and provide those samples (sampleIn) as input to the Simulink model along with the corresponding valid signal (validIn) and decimation rate (varRIn).

idlecyclesbetweensamples = 0;
idlecyclesbetweenframes = 4+N;

% The block has a latency of 3+N cycles for fixed decimation rate and 4+N
% for variable decimation rates when Gain correction is Off. To flush
% remaining data before changing the decimation rate, run the model by
% inserting required number of idle cycles after each frame.

sampleIn = []; validIn = []; varRIn = [];

for ij = 1:numFrames

    dataInFrame =  dataSamples{ij};

    data = []; valid=[]; varR = [];
    for ii = 1:length(dataInFrame)
        data = [data dataInFrame(ii) ...
            zeros(1,idlecyclesbetweensamples)];
        valid = [valid true(1,1) ...
            false(1,idlecyclesbetweensamples)];
        varR = [varR varRtemp{ij}(ii) ...
            zeros(1,idlecyclesbetweensamples)];
    end

    sampleIn = cast([sampleIn,data,zeros(1,idlecyclesbetweenframes)],'like',dataInFrame);
    validIn = logical([validIn,valid,zeros(1,idlecyclesbetweenframes)]);
    varRIn = fi([varRIn,varR,zeros(1,idlecyclesbetweenframes)],0,12,0);

end

sampletime = 1;
simTime = length(validIn);

Run the Simulink model.

modelname = 'HDLCICDecimationModel';
open_system(modelname);
sim(modelname);

Capture the output data from the Simulink model, and compare it against the output from the dsp.CICDecimation System object.

sampleOut = squeeze(sampleOut_ts.Data).';
validOut  = squeeze(validOut_ts.Data);
cicOutput = sampleOut(validOut);

fprintf('\nHDL CIC Decimation\n');
difference = (abs(cicOutput-cicFcnOutput(1:length(cicOutput)))>0);
fprintf('\nTotal number of samples differed between Simulink block output and MATLAB function output is: %d \n',sum(difference));
HDL CIC Decimation

Total number of samples differed between Simulink block output and MATLAB function output is: 0 

See Also

Blocks