%% Clear all the variables in the workspace, close all figure windows
% clear all; close all

%% Behavioral Turbo Decoder
% Turbo decoding of soft bits obtained from a noisy constellation
turboFrameSize = 6144;
txBits = randi([0 1],turboFrameSize,1);
codedData = lteTurboEncode(txBits);
txSymbols = lteSymbolModulate(codedData,'QPSK');
noise = 0.5*complex(randn(size(txSymbols)),randn(size(txSymbols)));
rxSymbols = txSymbols + noise;
scatter(real(rxSymbols),imag(rxSymbols),'co'); hold on;
scatter(real(txSymbols),imag(txSymbols),'rx')
legend('Rx constellation','Tx constellation')
softBits = lteSymbolDemodulate(rxSymbols,'QPSK','Soft');
rxBits = lteTurboDecode(softBits);

%% Simulink hardware-targeted model settings
% Open the model
modelname = 'TurboDecoderFramedDataHDLExample';
open_system(modelname);

% Settings for Frame Input From Workspace block
inframesize = length(softBits);

% Setting for Turbo Decoder block
% rate 1/3 code - Systematic + 2 Parity, 12 tail bits
numTurboIterations = 6;
insamplesize = 3;
numtailbits = 12;
outframesize = (inframesize-numtailbits)/insamplesize;

% Settings for Frame To Samples block
idlecyclesbetweensamples = 0;
% approximate latency from Turbo Decoder block per half-iteration
tdlatency = (ceil(turboFrameSize/32)+4)*32;
% approximate delay in frames for Turbo Decoder output
algframedelay = (2*numTurboIterations + 2)*(ceil(tdlatency/turboFrameSize));
% leave sufficient gap between frames
idlecyclesbetweenframes = (inframesize/insamplesize)*algframedelay;
% The option to compose output from interleaved input samples should be
% checked off in the block
set_param([modelname '/Frame To Samples'],...
    'InterleaveSamples','on');

% Settings for Samples To Frame block
% Exact setting, includes idle cycles introduced
totalframesize = ((inframesize/insamplesize)*...
    (idlecyclesbetweensamples+1))+idlecyclesbetweenframes;
% Conservative setting, same size as Turbo Decoder output frame
% totalframesize = outframesize;
outsamplesize = 1;

% simulation time
numFrames = 1; % number of frames to run
simTime = numFrames;

% input frame data for model
% use same data as lteTurboDecode, converted to fixed point
inframes = fi(softBits, 1, 5, 2);

%% Run the model
sim(modelname);

%% Process output of HDL model and compare to behavioral simulation output
% Gather all the data into one array
rxBits_hdl = outframes_logdata(:);

% Check number of bit mismatches
numBitsDiff = sum(rxBits_hdl ~= rxBits);
fprintf(['\nLTE Turbo Decoder: Behavioral and ' ...
    'HDL simulation differ by %d bits\n\n'], numBitsDiff);

% close the model and figures
bdclose(modelname);
close all;
