%% OFDM Demodulation of Streaming Samples
%
% This example shows how to use the OFDM Demodulator block to demodulate 
% complex time-domain OFDM samples to subcarriers for a vector input.
% This example model supports HDL code generation for the OFDMDemod subsystem.

% Copyright 2019 The MathWorks, Inc.

%% Set up input data parameters
% 
rng('default');
numOFDMSym = 2;
maxFFTLen = 128;
DCRem = true;
RoundingMethod = 'floor';
Normalize = false;
cpFraction = 1;
fftLen = 64;
cpLen = 16;
numLG = 6;
numRG = 5;
if DCRem
    NullInd = [1:numLG fftLen/2+1 fftLen-numRG+1:fftLen];
else
    NullInd = [1:numLG fftLen-numRG+1:fftLen]; %#ok<UNRCH>
end
symbOffset = floor(cpFraction*cpLen);
vecLen = 2;

%% Generate frames of random input samples
%
data = randn(fftLen,numOFDMSym)+1i*randn(fftLen,numOFDMSym);
dataIn = ofdmmod(data,fftLen,cpLen);

%% Convert the framed input data to a stream of samples and import the input stream to Simulink(R)
%
data = dataIn(:);
valid = true(length(dataIn)/vecLen,1);
fftSig = fftLen*ones(length(dataIn),1);
CPSig = cpLen*ones(length(dataIn),1);
LGSig = numLG*ones(length(dataIn),1);
RGSig = numRG*ones(length(dataIn),1);
resetSig = false(length(data),1);
sampleTime = 1/vecLen;
stopTime = (maxFFTLen*3*numOFDMSym)/vecLen;

%% Run the Simulink model
%
modelname = 'genhdlOFDMDemodulatorModel';
open_system(modelname);
out = sim(modelname);

%% Export the stream of demodulated samples of the Simulink block to the MATLAB(R) workspace
%
simOut = squeeze(out.dataOut(:,1,out.validOut==1));

%% Demodulate random input samples using |ofdmdemod_baseline| function
%
[dataOut1] = ofdmdemod_baseline(dataIn,fftLen,cpLen,symbOffset,NullInd.',[],Normalize,RoundingMethod);
matOut = dataOut1(:);

%% Compare the output of the Simulink model against the output of |ofdmdemod_baseline| function
%
figure('units','normalized','outerposition',[0 0 1 1])
subplot(2,1,1)
plot(real(matOut(:)));
hold on;
plot(real(simOut(:)));
grid on
legend('Reference','Simulink')
xlabel('Sample Index')
ylabel('Magnitude')
title('Comparison of Simulink block and MATLAB function - Real part')

subplot(2,1,2)
plot(imag(matOut(:)));
hold on;
plot(imag(simOut(:)));
grid on
legend('Reference','Simulink')
xlabel('Sample Index')
ylabel('Magnitude')
title('Comparison of Simulink block and MATLAB function - Imaginary part')

sqnrRealdB=10*log10(var(real(simOut(:)))/abs(var(real(simOut(:)))-var(real(matOut(:)))));
sqnrImagdB=10*log10(var(imag(simOut(:)))/abs(var(imag(simOut(:)))-var(imag(matOut(:)))));

fprintf('\n OFDM Demodulator: \n SQNR of real part is %.2f dB',sqnrRealdB);
fprintf('\n SQNR of imaginary part is %.2f dB\n',sqnrImagdB);

