function [BER, FER] = OFDMSim(SubcarNum, Modulation, EbNo)
% SubcarNum: number of subcarriers
% Modulation: 1:BPSK; 2: QPSK, 4: 16QAM; 6: 64QAM
% EbNo [dB]
%% Channel model parameters --> 3GPP LTE EPA
PowerVector = [0, -1, -2, -3, -8, -10.2, -10.8]; % dB
DelayVector = [0, 30*10^-6, 70*10^-6, 90*10^-6, 110*10^-6, 190*10^-6, 410*10^-6]; %ms
Bandwidth = 20000; %kHz
%% OFDM sim parameters
OFDMSymPerFrame = 10;
SimTimes = 10000;
GuardInterval = SubcarNum/4;
%% Results Parameters
BitError = 0;
FrameError = 0;
for jj = 1:1:SimTimes
% Generate one Frame bits
seldataantenna=rand(1,SubcarNum*OFDMSymPerFrame*Modulation)>0.5; % rand : built in function
paradataantenna=reshape(seldataantenna,SubcarNum,OFDMSymPerFrame*Modulation); % reshape : built in function
if(Modulation==1) %BPSK Modulation
[ioutantenna,qoutantenna]=bpskmod(paradataantenna,SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==2) %QPSK Modulation
[ioutantenna,qoutantenna]=qpskmod(paradataantenna,SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==4) %16QAM Modulation
[ioutantenna,qoutantenna]=qam16mod(paradataantenna,SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==6) %64QAM Modulation
[ioutantenna,qoutantenna]=qam64mod(paradataantenna,SubcarNum,OFDMSymPerFrame,Modulation);
end
AllUserModData=ioutantenna+sqrt(-1)*qoutantenna;
% generate the time domain frame
TimeDomainSymbol = [];
for ij = 1:1:OFDMSymPerFrame
TDSymbol = conj(ifft(AllUserModData(:,ij))*sqrt(SubcarNum))';
TimeDomainSymbol = [TimeDomainSymbol, TDSymbol(SubcarNum-GuardInterval+1:SubcarNum),TDSymbol]; % [GuardInterval+ OFDM symbol]
end
% Generate channel value for this frame
[ChanFDPerfect, ChanTD] = MultiPathSim(PowerVector,DelayVector, Bandwidth,SubcarNum);
%Find the path in time domain where the value is not zero
idx = find(ChanTD~=0);
% Generate convolutin of Channel and OFDM symbol
ReceivedFrame = zeros(1, OFDMSymPerFrame*(SubcarNum+GuardInterval)+GuardInterval);
for ii = 1:1:length(idx)
ReceivedFrame(idx(ii):OFDMSymPerFrame*(SubcarNum+GuardInterval)+idx(ii)-1) = ReceivedFrame(idx(ii):OFDMSymPerFrame*(SubcarNum+GuardInterval)+idx(ii)-1)+TimeDomainSymbol*ChanTD(idx(ii));
end
% generate AWGN noise
AvePowerPerBit = sum(ReceivedFrame.*conj(ReceivedFrame))/SubcarNum/OFDMSymPerFrame/Modulation;
NoisePower = AvePowerPerBit*10^(-EbNo/10);
NoiseVector = sqrt(NoisePower/2)*(randn(1, OFDMSymPerFrame*(SubcarNum+GuardInterval)+GuardInterval)+sqrt(-1)*randn(1, OFDMSymPerFrame*(SubcarNum+GuardInterval)+GuardInterval));
% Received Frame with noise
ReceivedFramePlusNoise = ReceivedFrame + NoiseVector;
%Remove CP and generate each received OFDM symbol in Frequency-domain
OFDMFDSymboVector = [];
for ij = 1:1:OFDMSymPerFrame
EachOFDMTDSymboVector = conj(ReceivedFramePlusNoise((ij-1)*(SubcarNum+GuardInterval)+GuardInterval+1:ij*(SubcarNum+GuardInterval))');
OFDMFDSymboVector = [OFDMFDSymboVector, fft(EachOFDMTDSymboVector)/sqrt(SubcarNum)];
end
OFDMFDSymboVectorEq = [];
%Received OFDM symbol in Frequency-domain with Equlization
ChanFD = ChanFDPerfect; %Perfect channel
%ChanFD = ChanFDPerfect+ sqrt(NoisePower/2)*(randn(SubcarNum,1)+sqrt(-1)*randn(SubcarNum,1)); % Chanel estimation with error
for ij = 1:1:OFDMSymPerFrame
OFDMFDSymboVectorEq = [OFDMFDSymboVectorEq, OFDMFDSymboVector(:,ij)./ChanFD]; % ZF Equalization
% OFDMFDSymboVectorEq = [OFDMFDSymboVectorEq, conj(ChanFD).*OFDMFDSymboVector(:,ij)./(conj(ChanFD).*ChanFD+NoisePower)]; % MMSE Equalization
end
%deModulation part
if(Modulation==1) %BPSK Modulation
demodataantenna=bpskdemod(real(OFDMFDSymboVectorEq),imag(OFDMFDSymboVectorEq),SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==2) %QPSK Modulation
demodataantenna=qpskdemod(real(OFDMFDSymboVectorEq),imag(OFDMFDSymboVectorEq),SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==4) %16QAM Modulation
demodataantenna=qam16demod(real(OFDMFDSymboVectorEq),imag(OFDMFDSymboVectorEq),SubcarNum,OFDMSymPerFrame,Modulation);
end
if(Modulation==6) %64QAM Modulation
demodataantenna=qam64demod(real(OFDMFDSymboVectorEq),imag(OFDMFDSymboVectorEq),SubcarNum,OFDMSymPerFrame,Modulation);
end
noe=sum(sum(abs(paradataantenna-demodataantenna)));
BitError=BitError+noe;
if (noe>0)
FrameError= FrameError+1;
end
if (mod(jj,500)==0)
BER = BitError/SubcarNum/OFDMSymPerFrame/Modulation/jj
FER = FrameError/jj
end
end
BER = BitError/SubcarNum/OFDMSymPerFrame/Modulation/SimTimes;
FER = FrameError/SimTimes;