% =========================================================================
% Listing 1. MATLAB main script for BER/SER evaluation.
% =========================================================================
clc;
clear;
close all;
N = 64; % OFDM subcarriers
cpLen = 16; % Cyclic Prefix
M = 64;
bitsPerSymbol = 6;
channelLength = 6;
SNRdB = 0:2:24;
numFrames = 3000;
BER = zeros(size(SNRdB));
SER = zeros(size(SNRdB));
% =========================================================================
% Listing 2. MATLAB simulation function with LS channel estimation.
% =========================================================================
% 64-QAM CONSTELLATION
levels = -7:2:7;
[I,Q] = meshgrid(levels,levels);
constellation = I(:)+1i*Q(:);
constellation = constellation ./ ...
sqrt(mean(abs(constellation).^2));
% PILOT
pilotFreq = ones(N,1);
% LOOP SNR
for snrIdx = 1:length(SNRdB)
snr = SNRdB(snrIdx);
fprintf('Running SNR = %d dB\n',snr);
bitErrors = 0;
symbolErrors = 0;
totalBits = 0;
totalSymbols = 0;
% LOOP FRAME
for frame = 1:numFrames
% RAYLEIGH CHANNEL
powerProfile = [0.40 0.25 0.15 ...
0.10 0.06 0.04];
h = (randn(channelLength,1)+ ...
1i*randn(channelLength,1))/sqrt(2);
h = h .* sqrt(powerProfile(:));
% RANDOM BITS
txBits = randi([0 1], ...
N*bitsPerSymbol,1);
txBitMatrix = reshape( ...
txBits,bitsPerSymbol,[]).';
weights = 2.^(bitsPerSymbol-1:-1:0).';
txIndex = txBitMatrix*weights;
% 64QAM MODULATION
txDataFreq = ...
constellation(txIndex+1);
% OFDM MODULATION
pilotTime = ifft(pilotFreq,N);
dataTime = ifft(txDataFreq,N);
pilotTx = [ ...
pilotTime(end-cpLen+1:end)
pilotTime];
dataTx = [ ...
dataTime(end-cpLen+1:end)
dataTime];
% CHANNEL
pilotRx = conv(pilotTx,h);
dataRx = conv(dataTx,h);
% AWGN
signalPower = mean(abs(dataRx).^2);
noisePower = ...
signalPower/(10^(snr/10));
noisePilot = ...
sqrt(noisePower/2)* ...
(randn(size(pilotRx)) + ...
1i*randn(size(pilotRx)));
noiseData = ...
sqrt(noisePower/2)* ...
(randn(size(dataRx)) + ...
1i*randn(size(dataRx)));
pilotRx = pilotRx + noisePilot;
dataRx = dataRx + noiseData;
% TRUNCATE
pilotRx = pilotRx(1:length(pilotTx));
dataRx = dataRx(1:length(dataTx));
% REMOVE CP
pilotRx = pilotRx( ...
cpLen+1:cpLen+N);
dataRx = dataRx( ...
cpLen+1:cpLen+N);
% FFT
Ypilot = fft(pilotRx,N);
Ydata = fft(dataRx,N);
% LS CHANNEL ESTIMATION
Hls = Ypilot ./ pilotFreq;
Hls(abs(Hls)<1e-10)=1e-10;
% EQUALIZER
equalized = Ydata ./ Hls;
% DETECTOR
distance = abs( ...
equalized(:) - ...
constellation(:).' ...
).^2;
[~,pos] = min(distance,[],2);
rxIndex = pos - 1;
% SER
symbolErrors = symbolErrors + ...
sum(rxIndex~=txIndex);
% DECIMAL -> BITS
rxBitMatrix = ...
zeros(length(rxIndex), ...
bitsPerSymbol);
for b = 1:bitsPerSymbol
rxBitMatrix(:,b) = ...
bitget(rxIndex,...
bitsPerSymbol-b+1);
end
rxBits = reshape( ...
rxBitMatrix.',[],1);
% BER
bitErrors = bitErrors + ...
sum(rxBits~=txBits);
totalBits = totalBits + ...
length(txBits);
totalSymbols = ...
totalSymbols + N;
end
BER(snrIdx) = ...
bitErrors/totalBits;
SER(snrIdx) = ...
symbolErrors/totalSymbols;
fprintf('BER = %.4e\n',BER(snrIdx));
fprintf('SER = %.4e\n\n',SER(snrIdx));
end
% PLOT
BER(BER==0)=1e-8;
SER(SER==0)=1e-8;
figure;
semilogy(SNRdB,BER,...
'bo-','LineWidth',2,...
'MarkerSize',8);
hold on;
semilogy(SNRdB,SER,...
'rs--','LineWidth',2,...
'MarkerSize',8);
grid on;
xlabel('SNR (dB)');
ylabel('Error Rate');
title('OFDM 64-QAM over Rayleigh Channel using LS Estimation');
legend('BER','SER',...
'Location','southwest');
xlim([0 24]);
set(gca,'FontSize',12);