Main Content

Implement CIC Decimation Filter for HDL

This example shows how to use a CIC Decimation HDL Optimized block to filter and downsample data. This block supports scalar and vector inputs. In this example, two Simulink® models are provided to work with scalar and vector inputs separately. You can generate the HDL code from the subsystems in these Simulink models.

Set Up Input Data Parameters

Set up these workspace variables for the models to use. These variables configure the CIC Decimation HDL Optimized block inside of them. This block supports fixed and variable decimation rates for scalar inputs and only a fixed decimation rate for vector inputs. The example runs the HDLCICDecimationModel.slx model when you set the scalar value to true and runs the HDLCICDecimationModelVectorSupport.slx model when you set the scalar value to false. For scalar inputs, choose a range for the input varRValue values and set the decimation factor value, R, to the maximum expected decimation factor. For vector inputs, the input data must be a column vector of size 1 to 64. R must be an integer multiple of input frame size.

R = 8; % Decimation factor
M = 1; % Differential delay
N = 3; % Number of sections
scalar = false; % true for scalar; false for vector
if scalar
    varRValue = [4,R];
    vecSize = 1;
    modelname = 'HDLCICDecimationModel';
else
    varRValue = R;
    fac = (factor(R));
    vecSize = fac(randi(length(fac),1,1));
    modelname = 'HDLCICDecimationModelVectorSupport';
end

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

Generate Reference Output from dsp.CICDecimation System Object™

Generate frames of random input samples and provide them as input to the dsp.CICDecimation System object. The output generated from this System object is used as a reference data for comparison. This System object does not support variable decimation rate, so you must create and release this object for any change in the decimation factor value.

for i = 1:numFrames
    framesize = varRValue(i)*randi([5 20],1,1);
    dataSamples{i} = fi(randn(vecSize,framesize),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

Convert Input to Stream of Samples and Import them to Simulink® Model

Generate a stream of samples by converting frames to samples. Provide those samples (sampleIn) and the valid signal (validIn) as inputs to the Simulink model. The latency of the block for scalar and vector inputs is calculated based on the type of input and the number of sections, N. For more information about latency, see the Gain correction parameter. To flush remaining data, run the model by inserting the required number of idle cycles after each frame using the idlecyclesbetweenframes value.

idlecyclesbetweensamples = 0;
idlecyclesbetweenframes = floor((vecSize-1)*(N/vecSize))+1 + N + (2+(vecSize+1)*N) + 9;

sampleIn = [];
validIn = [];
varRIn = [];
len = 0;

for ij = 1:numFrames

    dataInFrame =  dataSamples{ij};
    if scalar
        len = length(dataInFrame);
    else
        len = size(dataInFrame,2);
    end

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

    sampleIn = cast([sampleIn,data,zeros(vecSize,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 Simulink Model

Run the model. Running the model imports the input signal variables from the MATLAB® workspace to the CIC Decimation HDL Optimized block in the model.

open_system(modelname);
sim(modelname);

Compare Simulink Block Output with MATLAB System Object Output

Capture the output of the Simulink block. Compare that ouput with the output of 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 that differed between Simulink block output and MATLAB System object output: %d \n',sum(difference));
HDL CIC Decimation

Total number of samples that differed between Simulink block output and MATLAB System object output: 0 

See Also

Blocks