%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % All rights reserved by Krishna Pillai, http://www.dsplog.com % The file may not be re-distributed without explicit authorization % from Krishna Pillai. % Checked for proper operation with Octave Version 3.0.0 % Author : Krishna Pillai % Email : krishna@dsplog.com % Version : 1.0 % Date : 14th December 2008 % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Script for computing BER with Binary Convolutional Code % and Viterbi decoding. % Convolutional code of Rate-1/2, Generator polynomial - [7,5] octal % Hard decision decoding is used. clear N = 10^6 ;% number of bits or symbols Eb_N0_dB = [0:1:10]; % multiple Eb/N0 values Ec_N0_dB = Eb_N0_dB - 10*log10(2); ref = [0 0 ; 0 1; 1 0 ; 1 1 ]; ipLUT = [ 0 0 0 0;... 0 0 0 0;... 1 1 0 0;... 0 0 1 1 ]; for yy = 1:length(Eb_N0_dB) % Transmitter ip = rand(1,N)>0.5; % generating 0,1 with equal probability % convolutional coding, rate - 1/2, generator polynomial - [7,5] octal cip1 = mod(conv(ip,[1 1 1 ]),2); cip2 = mod(conv(ip,[1 0 1 ]),2); cip = [cip1;cip2]; cip = cip(:).'; s = 2*cip-1; % BPSK modulation 0 -> -1; 1 -> 0 n = 1/sqrt(2)*[randn(size(cip)) + j*randn(size(cip))]; % white gaussian noise, 0dB variance % Noise addition y = s + 10^(-Ec_N0_dB(yy)/20)*n; % additive white gaussian noise % receiver - hard decision decoding cipHat = real(y)>0; % Viterbi decoding pathMetric = zeros(4,1); % path metric survivorPath_v = zeros(4,length(y)/2); % survivor path for ii = 1:length(y)/2 r = cipHat(2*ii-1:2*ii); % taking 2 coded bits % computing the Hamming distance between ip coded sequence with [00;01;10;11] rv = kron(ones(4,1),r); hammingDist = sum(xor(rv,ref),2); if (ii == 1) || (ii == 2) % branch metric and path metric for state 0 bm1 = pathMetric(1,1) + hammingDist(1); pathMetric_n(1,1) = bm1; survivorPath(1,1) = 1; % branch metric and path metric for state 1 bm1 = pathMetric(3,1) + hammingDist(3); pathMetric_n(2,1) = bm1; survivorPath(2,1) = 3; % branch metric and path metric for state 2 bm1 = pathMetric(1,1) + hammingDist(4); pathMetric_n(3,1) = bm1; survivorPath(3,1) = 1; % branch metric and path metric for state 3 bm1 = pathMetric(3,1) + hammingDist(2); pathMetric_n(4,1) = bm1; survivorPath(4,1) = 3; else % branch metric and path metric for state 0 bm1 = pathMetric(1,1) + hammingDist(1); bm2 = pathMetric(2,1) + hammingDist(4); [pathMetric_n(1,1) idx] = min([bm1,bm2]); survivorPath(1,1) = idx; % branch metric and path metric for state 1 bm1 = pathMetric(3,1) + hammingDist(3); bm2 = pathMetric(4,1) + hammingDist(2); [pathMetric_n(2,1) idx] = min([bm1,bm2]); survivorPath(2,1) = idx+2; % branch metric and path metric for state 2 bm1 = pathMetric(1,1) + hammingDist(4); bm2 = pathMetric(2,1) + hammingDist(1); [pathMetric_n(3,1) idx] = min([bm1,bm2]); survivorPath(3,1) = idx; % branch metric and path metric for state 3 bm1 = pathMetric(3,1) + hammingDist(2); bm2 = pathMetric(4,1) + hammingDist(3); [pathMetric_n(4,1) idx] = min([bm1,bm2]); survivorPath(4,1) = idx+2; end pathMetric = pathMetric_n; survivorPath_v(:,ii) = survivorPath; end % trace back unit currState = 1; ipHat_v = zeros(1,length(y)/2); for jj = length(y)/2:-1:1 prevState = survivorPath_v(currState,jj); ipHat_v(jj) = ipLUT(currState,prevState); currState = prevState; end % counting the errors nErrViterbi(yy) = size(find([ip- ipHat_v(1:N)]),2); end simBer_Viterbi = nErrViterbi/N; % simulated ber - Viterbi decoding BER theoryBer = 0.5*erfc(sqrt(10.^(Eb_N0_dB/10))); % theoretical ber uncoded AWGN close all figure semilogy(Eb_N0_dB,theoryBer,'bd-','LineWidth',2); hold on semilogy(Eb_N0_dB,simBer_Viterbi,'mp-','LineWidth',2); axis([0 10 10^-5 0.5]) grid on legend('theory - uncoded', 'simulation - Viterbi (rate-1/2, [7,5]_8)'); xlabel('Eb/No, dB'); ylabel('Bit Error Rate'); title('BER for BCC with Viterbi decoding for BPSK in AWGN');