Main Content

Decode WLAN LDPC Streaming Data

This example shows how to simulate the WLAN LDPC Decoder block and compare the hardware-optimized results with the results from the Communication Toolbox™ function.

Generate the input to the block using the Communication Toolbox function ldpcEncode. Provide the generated data as the input to the WLAN LDPC Decoder block and the Communication Toolbox function ldpcDecode. Compare the output of the block with the output of the ldpcDecode function. This example contains two Simulink® models. One model is configured to support the WLAN standards IEEE 802.11 n/ac/ax, and other model is configured to support the standard IEEE 802.11 ad. When you run the script, the respective model is selected based on the value that you specify for the variable standard mentioned in the script.

Set Up Input Variables

Choose a series of input values for the block length and code rate according to the WLAN standard. You can change the variable values in this section based on your requirements.

standard = 'IEEE 802.11 n/ac/ax';  % IEEE 802.11 n/ac/ax or IEEE 802.11 ad
codeRateIdx = [0; 1; 2; 3];        % Code rate index
blkLenIdx = [0; 1; 2; 0];          % Block length index
numFrames = 4;
scalar = false;                    % true for scalar inputs and false
                                   % for vector inputs
algorithm = 'Min-sum';             % Min-sum or Normalized min-sum
niter = 8;                         % Number of iterations

if strcmpi(algorithm,'Min-sum')
    alpha = 1;
else
    alpha = 0.75;                  % Scaling factor, which must be in
                                   % the range [0.5:0.0625:1]
end

Generate Input Data

Generate inputs for the ldpcEncode function with the specified block length and code rate variables. Use the encoded data from the ldpcEncode function, modulate the data using a modulator function, add noise using a channel System object™, and generate log-likelihood ratio (LLR) values using a symbol demodulator function. After that, provide these LLR values as an input to the ldpcDecode function.

Create vectors of block length index and code rate index using the blockLenIdx and codeRateIdx variables, respectively. Convert the frames of LLR values to samples with a control bus signal that indicates the frame boundaries. Provide these vectors and control bus as an input to the WLAN LDPC Decoder block.

The decFrameGap variable in the script accommodates the latency of the WLAN LDPC Decoder block for the specified block length, code rate, and number of iterations. Use the nextFrame output signal to determine when the block is ready to accept the start of the next input frame.

% Initialize inputs
msg = {numFrames};                 % Input to |ldpcEncode| function
rxLLR = cell(1,numFrames);         % Input to |ldpcDecode| function
refOut = cell(1,numFrames);        % Output of |ldpcDecode| function

decSampleIn = [];
decStartIn = [];
decEndIn = [];
decValidIn = [];
decBlkLenIdxIn = [];
decCodeRateIdxIn = [];

for ii = 1:numFrames
    if strcmpi(standard,'IEEE 802.11 n/ac/ax')
        blockLenSet = [648,1296,1944];
        rateSet = {'1/2','2/3','3/4','5/6'};

        blkLen = blockLenSet(blkLenIdx(ii)+1);
        codeRate = rateSet{codeRateIdx(ii)+1};
        modelName = 'HDLWLANLDPCDecoderStd11ac';
    else
        rateSet = {'1/2','5/8','3/4','13/16'};
        blkLen = 672;
        codeRate = rateSet{codeRateIdx(ii)+1};
        modelName = 'HDLWLANLDPCDecoderStd11ad';
    end

    [rxLLR{ii},refOut{ii},msg{ii}] = inputGenForWLANLDPCDec(blkLen,codeRate,niter,alpha);

    if scalar
        decFrameGap = niter*1000 + length(msg{ii}); %#ok
        vecSize = 1;
        len = length(rxLLR{ii});
     else
        len = length(rxLLR{ii})/8;
        vecSize = 8;
        decFrameGap = niter*1000 + ceil(length(msg{ii})/8);
     end

     decIn = reshape(rxLLR{ii},vecSize,[]);

    decSampleIn = [decSampleIn decIn zeros(size(decIn,1),decFrameGap)]; %#ok<*AGROW>
    decStartIn = logical([decStartIn 1 zeros(1,len-1) zeros(1,decFrameGap)]);
    decEndIn = logical([decEndIn zeros(1,len-1) 1 zeros(1,decFrameGap)]);
    decValidIn = logical([decValidIn ones(1,len) zeros(1,decFrameGap)]);
    decBlkLenIdxIn = ([decBlkLenIdxIn repmat(blkLenIdx(ii),1,len) zeros(1,decFrameGap)]);
    decCodeRateIdxIn = ([decCodeRateIdxIn repmat(codeRateIdx(ii),1,len) zeros(1,decFrameGap)]);
end

dataIn = timeseries(fi(decSampleIn',1,4,0));
startIn = timeseries(decStartIn);
endIn = timeseries(decEndIn);
validIn = timeseries(decValidIn);

if strcmpi(standard,'IEEE 802.11 n/ac/ax')
    blockLenIdx = timeseries(fi(decBlkLenIdxIn,0,2,0));
end
codeRateIdx = timeseries(fi(decCodeRateIdxIn,0,2,0)); % For the standard
                                                      % IEEE 802.11 ad

simTime = length(decValidIn);

Run Simulink Model

The HDL WLAN LDPC Decoder subsystem contains the WLAN LDPC Decoder block. Running the model imports the input signal variables dataIn, startIn, endIn, validIn, blockLenIdx, codeRateIdx, niter, and simTime to the block from the script and exports a stream of decoded output samples dataOut and a control bus containing startOut, endOut, and validOut signals from the block to the MATLAB workspace.

open_system(modelName);
if alpha ~= 1
    set_param([modelName '/HDL WLAN LDPC Decoder/WLAN LDPC Decoder'], ...
        'Algorithm','Normalized min-sum');
    set_param([modelName '/HDL WLAN LDPC Decoder/WLAN LDPC Decoder'], ...
        'ScalingFactor',num2str(alpha));
else
    set_param([modelName '/HDL WLAN LDPC Decoder/WLAN LDPC Decoder'], ...
        'Algorithm','Min-sum');
end
sim(modelName);

Compare Simulink Block Output with MATLAB Function Output

Convert the streaming data output of the WLAN LDPC Decoder block to frames. Compare the frames with the output of the ldpcDecode function.

startIdx = find(squeeze(startOut));
endIdx = find(squeeze(endOut));
dec = squeeze(dataOut);

decHDL = {numFrames};
for ii = 1:numFrames
    idx = startIdx(ii):endIdx(ii);
    if scalar
        decHDL{ii} = dec(idx);
    else
        decHDL{ii} = dec(:,idx);
    end
    HDLOutput = decHDL{ii}(1:length(refOut{ii}));
    error = sum(abs(double(refOut{ii})-HDLOutput(:)));
   fprintf(['Decoded frame %d: Output data differs by %d bits\n'],ii,error);
end
Decoded frame 1: Output data differs by 0 bits
Decoded frame 2: Output data differs by 0 bits
Decoded frame 3: Output data differs by 0 bits
Decoded frame 4: Output data differs by 0 bits

See Also

Blocks

Functions