Main Content

Symbol Demodulation of Complex Data Symbols

This example shows how to demodulate complex data symbol using the Symbol Demodulator block. Generate a set of complex random inputs and provide them as an input to the Symbol Demodulator block and the reference functions qamdemod and pskdemod from the Communications Toolbox®. Then, compare the output of the block with the output of these functions based on type of modulation you select. To work with scalar and vector output types separately, this example provides two Simulink® models. You can generate HDL code for these models.

Set Up Input Variables

Set up input variables. You can change the variable values in this section according to your requirement. The example runs the symbolDemodulatorScalar.slx model when you set the outputType variable to 'Scalar' and the symbolDemodulatorVector.slx model when you set to 'Vector'.

frameLength = 120;                                 % Frame length
numFrames = 8;                                     % Number of frames
frameGap = 0;                                      % Frame gap
modSel = [7 6 5 4 3 2 1 0];                        % Modulation type
maxModulation = '256-QAM';                         % {'BPSK', 'QPSK', '8-PSK', '16-PSK',
                                                   % '16-QAM', '32-PSK', '64-QAM', '256-QAM'}
phaseOffset = 'pi/2';                              % Phase offset
decisionType = 'Approximate log-likelihood ratio'; % Decision type 'Approximate log-likelihood ratio' or 'Hard'
outputType = 'Vector';                             % Type of output 'Vector' or 'Scalar'

Generate Complex Random Inputs

Generate complex random inputs and required control signals.

dataIn = []; validIn = []; startIn = []; endIn = []; modSelIn = [];
for frameNo = 1:numFrames
    inpData = complex(randn(1,frameLength),randn(1,frameLength));
    totalSize = frameLength;
    data = zeros(1,totalSize,'like',inpData(1));
    validCtrl = false(1,totalSize);
    modSelCtrl = zeros(1,totalSize);

    idx  = 1:totalSize;
    data(:,idx) = inpData;
    validCtrl(idx) = true;
    modSelCtrl(idx) = modSel(frameNo);

    validIdx = find(validCtrl);
    startCtrl = zeros(size(validCtrl));
    endCtrl = zeros(size(validCtrl));
    startCtrl(validIdx(1)) = 1;
    endCtrl(validIdx(end)) = 1;

    dataIn = [dataIn,zeros(frameGap,1)',data]; %#ok
    startIn = logical([startIn,zeros(frameGap,1)',startCtrl]);
    endIn = logical([endIn,zeros(frameGap,1)',endCtrl]);
    validIn = logical([validIn,zeros(frameGap,1)',validCtrl]);
    modSelIn = [modSelIn,zeros(frameGap,1)',modSelCtrl]; %#ok
end

if strcmpi(outputType,'Vector')
    stopTime = 2*frameLength*numFrames;
else
    stopTime = 8*frameLength*numFrames;
end

Run Simulink Model

Running the model imports the input variables and control signals to the block from the script and exports a stream of demodulated output samples and control signals from the block to the MATLAB® workspace.

if strcmpi(outputType,'Vector')
    modelname = 'symbolDemodulatorVector';
else
    modelname = 'symbolDemodulatorScalar';
end

load_system(modelname);
set_param([modelname '/HDL Symbol Demod/Symbol Demodulator'],'MaxModulation',maxModulation);
set_param([modelname '/HDL Symbol Demod/Symbol Demodulator'],'PhaseOffset',phaseOffset);
set_param([modelname '/HDL Symbol Demod/Symbol Demodulator'],'DecisionType',decisionType);
sim(modelname);

Demodulate Stream Samples Using MATLAB Function

To demodulate the stream of random samples, provide them as input to the qamdemod and pskdemod functions. You can use the output of this functions as a reference to compare the output of the block. The parameters in this section are nontunable and they are specified with default configuration values.

nbps = [2, 4, 8, 16, 16, 32, 64, 256];
M = nbps(modSel+1);
offset = str2num(phaseOffset); %#ok<ST2NM>
if strcmpi(decisionType,'Approximate log-likelihood ratio')
    decType = 'approxllr';
else
    decType = 'bit';
end

defConstOrder16 = [2 3 1 0 6 7 5 4 14 15 13 12 10 11 9 8];

defConstOrder64 = [4 5 7 6 2 3 1 0 12 13 15 14 10 11 9 8 28 29 31 30 26 27 25 24 20 21 23 22 18 19 17 16 52 53 55 54 ...
            50 51 49 48 60 61	63 62 58 59 57 56 44 45 47	46 42 43 41 40	36 37 39 38 34	35 33 32];

defConstOrder256 = [8,9,11,10,14,15,13,12,4,5,7,6,2,3,1,0,24,25,27,26,30,31,29,28,20,21,23,22,18,...
            19,17,16,56,57,59,58,62,63,61,60,52,53,55,54,50,51,49,48,40,41,43,42,46,47,45,44,36,37,...
            39,38,34,35,33,32,104,105,107,106,110,111,109,108,100,101,103,102,98,99,97,96,120,121,123,...
            122,126,127,125,124,116,117,119,118,114,115,113,112,88,89,91,90,94,95,93,92,84,85,87,86,82,...
            83,81,80,72,73,75,74,78,79,77,76,68,69,71,70,66,67,65,64,200,201,203,202,206,207,205,204,...
            196,197,199,198,194,195,193,192,216,217,219,218,222,223,221,220,212,213,215,214,210,211,209,...
            208,248,249,251,250,254,255,253,252,244,245,247,246,242,243,241,240,232,233,235,234,...
            238,239,237,236,228,229,231,230,226,227,225,224,168,169,171,170,174,175,173,172,164,165,167,...
            166,162,163,161,160,184,185,187,186,190,191,189,188,180,181,183,182,178,179,177,176,152,153,155,154,...
            158,159,157,156,148,149,151,150,146,147,145,144,136,137,139,138,142,143,141,140,132,133,135,134,130,131,129,128];


refDemodOut =[];
startIdx = find(startIn==true);
for ind =1:numFrames
    modSelFr = modSel(ind);
    dataInFr = dataIn(startIdx(ind)+(0:frameLength-1));
    if modSelFr==7 || modSelFr==6 || modSelFr==4
        if modSelFr==7
            defConstOrder = defConstOrder256;
        elseif modSelFr==6
            defConstOrder = defConstOrder64;
        else
            defConstOrder = defConstOrder16;
        end
        qamRefOut = qamdemod(dataInFr, M(ind), defConstOrder,'OutputType', decType,'UnitAveragePower',true);
        refDemodOut = [refDemodOut;qamRefOut(:)]; %#ok
    else
        pskRefOut = pskdemod(dataInFr, M(ind), offset, 'OutputType', decType);
        refDemodOut = [refDemodOut;pskRefOut(:)]; %#ok
    end
end

simOut = (dataOut(:,validOut));
simDemodOut = simOut(:);

Compare Simulink Block Output with MATLAB Function Output

Compare the output of Symbol Demodulator block with the MATLAB function output.

figure('units','normalized','outerposition',[0 0 1 1])
plot(simDemodOut,'-k*');
hold on;
plot(refDemodOut,'--rd');
grid on;
legend('Block output','Reference function output')
xlabel('Number of Samples');
ylabel('Output Values');
title('Comparison of Simulink Block Output with MATLAB Function Output')

avgErr = mean(simDemodOut-refDemodOut);
sprintf('The average error between block output and reference function output is %d.',avgErr)
ans =

    'The average error between block output and reference function output is 0.'

See Also

Blocks

Functions