%% NR Symbol Demodulation of Complex Data Symbols
%
% This example shows how to use the NR Symbol Demodulator block to demodulate complex NR data symbols to data bits or LLR values. 
% The workflow follows these steps:
%
% # Set up input data parameters.
% # Generate frames of random input samples.
% # Convert framed input data to a stream of samples and import the stream into Simulink.
% # Run the Simulink(R) model, which contains the NR Symbol Demodulator block.
% # Export the stream of demodulated samples from Simulink to the MATLAB(R) workspace.
% # Demodulate data symbols with |nrSymbolDemodulate| function to use its output as a reference data.
% # Compare Simulink block output data with the reference MATLAB function output.

% Copyright 2019 The MathWorks, Inc.

%% 
% Set up input data parameters.
%
% Map modulation names to values. The numerical values are used to set up 
% the NR Symbol Demodulator block. The strings are used to configure the
% |nrSymbolDemodulator| function. 

rng(0);
framesize = 10;

% 0 - BPSK
% 1 - QPSK
% 2 - 16-QAM
% 3 - 64-QAM
% 4 - 256-QAM
% 5 - pi/2-BPSK
% others - QPSK
modSelVal = [0;1;2;3;4;5];
modSelStr = {'BPSK','QPSK','16QAM','64QAM','256QAM','pi/2-BPSK'};

decType = 'Soft';

numframes = length(modSelVal);
dataSymbols  = cell(1,numframes);
modSelTmp = cell(1,numframes);
nrFcnOutput = cell(1,numframes);

%% 
% Generate frames of random input samples.

for ii = 1:numframes
    dataSymbols{ii} = complex(randn(framesize,1),randn(framesize,1));
    modSelTmp{ii} = fi(modSelVal(ii)*ones(framesize,1),0,3,0);
end

%%
% Convert the framed input data to a stream of samples and input the
% stream to the NR Symbol Demodulator Simulink block.

idlecyclesbetweensamples = 0;
idlecyclesbetweenframes  = 0;
[sampleIn, ctrl] = whdlFramesToSamples(dataSymbols,idlecyclesbetweensamples,...
    idlecyclesbetweenframes);
[modSel, ~] = whdlFramesToSamples(modSelTmp,idlecyclesbetweensamples,...
    idlecyclesbetweenframes);
validIn = logical(ctrl(:,3)');

sampletime = 1;
samplesizeIn = 1;
simTime = size(ctrl,1)*8;

%%
% Run the Simulink model.

modelname = 'nrhdlSymbolDemodulatorModel';
open_system(modelname);
set_param([modelname '/NRDemod/NR Symbol Demodulator'],'DecisionType',decType)
sim(modelname);

%%
% Export the stream of demodulated samples from Simulink to the MATLAB 
% workspace.

nrHDLOutput = sampleOut(validOut).';

%%
% Demodulate data symbols with |nrSymbolDemodulate| function and use its 
% output as a reference data.

for ii = 1:numframes     
 nrFcnOutput{ii} = nrSymbolDemodulate(dataSymbols{ii},modSelStr{ii},'DecisionType',decType,1).';
end 

%%
% Compare the output of the Simulink model against the output of 
% |nrSymbolDemodulate| function.

nrFcnOutput = double(cell2mat(nrFcnOutput));

figure(1)
stem(nrHDLOutput,'b')
hold on
stem(nrFcnOutput,'--r')
grid on
legend('Reference','Simulink')
xlabel('Sample Index')
ylabel('Magnitude')
title('Comparison of Simulink block and MATLAB function')


