Simulate an end-to-end communication link employing 16-QAM using turbo codes in an AWGN channel. Estimate the bit error rate.
Set the modulation order and the range of Eb/No values to evaluate. Set the packet length to 500.
rng(10,'twister'); M = 16; % Modulation order bps = log2(M); % Bits per symbol EbNo = (2:0.5:4); pktLen = 500;
Initialize the bit error rate vector.
ber = zeros(size(EbNo));
Create System objects for a turbo encoder and decoder pair, where the interleaver indices are supplied as input arguments.
turboEnc = comm.TurboEncoder('InterleaverIndicesSource','Input port'); turboDec = comm.TurboDecoder('InterleaverIndicesSource','Input port', ... 'NumIterations',4);
Create an AWGN channel System object and an error rate counter System object.
awgnChannel = comm.AWGNChannel('NoiseMethod','Variance','Variance',1); errorRate = comm.ErrorRate;
Use the packet length and turbo encoder settings to determine actual transmitted bit rate. The turbo-coding objects are initialized to use rate-1/2 trellis for their constituent convolutional codes, resulting in a turbo encoder output with 2 parity bit streams, (in addition to the systematic stream) and 12 tail bits for the input packet. The 12 tail bits are due to the specified constraint length of 4 per constituent encoder, which leads to 3-bit outputs per stream, for a total of 4 streams (S1 P1 S2 P2).
rate = pktLen/(3*pktLen+4*3);
The processing loop performs the following steps:
Generate random binary data
Generate random interleaver indices
Turbo encode the data
Apply 16-QAM modulation
Pass the modulated signal through an AWGN channel
Demodulate the noisy signal using an LLR algorithm
Turbo decode the data
Calculate the error statistics
for k = 1:length(EbNo)
Initialize the error statistics vector, signal-to-noise ratio, and noise variance. Update the AWGN channel System object noise variance value.
errorStats = zeros(1,3); EsNo = EbNo(k) + 10*log10(bps); snrdB = EsNo + 10*log10(rate); % in dB noiseVar = 1./(10.^(snrdB/10)); awgnChannel.Variance = noiseVar; while errorStats(2) < 100 && errorStats(3) < 1e7 % Generate random binary data data = randi([0 1],pktLen,1); % Interleaver indices intrlvrInd = randperm(pktLen); % Turbo encode the data encodedData = turboEnc(data,intrlvrInd); % Modulate the encoded data modSignal = qammod(encodedData,M,'InputType','bit','UnitAveragePower',true); % Pass the signal through the AWGN channel rxSignal = awgnChannel(modSignal); % Demodulate the received signal demodSignal = qamdemod(rxSignal,M,'UnitAveragePower',true,'OutputType','llr','NoiseVariance',noiseVar); % Turbo decode the demodulated signal. Because the bit mapping from the % demodulator is opposite that expected by the turbo decoder, the % decoder input must use the inverse of demodulated signal. rxBits = turboDec(-demodSignal,intrlvrInd); % Calculate the error statistics errorStats = errorRate(data,rxBits); end % Save the BER data and reset the bit error rate object ber(k) = errorStats(1); reset(errorRate) end
Plot the bit error rate and compare it to the uncoded bit error rate.
semilogy(EbNo,ber,'-o') grid xlabel('Eb/No (dB)') ylabel('Bit Error Rate') uncodedBER = berawgn(EbNo,'qam',M); % Estimate of uncoded BER hold on semilogy(EbNo,uncodedBER) legend('Turbo','Uncoded','location','sw')