본문 바로가기
programming language/MATLAB

MATLAB 16 QAM BER Simulation

by 남성 2014. 4. 4.

오늘은 MATLAB 을 이용한 16 QAM BER Simulation코드에 대해 소개해 보려 합니다.

 

예전에 제가 작성했던 코드들도 있지만~

 

아래 주소를 보니 16 QAM 의 Gray coding 부터 이론적인 BER 성능 까지 자세히 설명되어 있더군요.

   

http://www.dsplog.com/2008/06/05/16qam-bit-error-gray-mapping/

   

코드는 위 블로그의 약간 아래 쪽을 보시면~ 링크가 되어 있습니다.

 

못찾으실 분들을 위해 링크를 걸죠, 아래 주소를 오른쪽 클릭한 후에 파일로 다운로드 받거나 그냥 클릭하고 들어가서 전체 선택후에 m 파일에 붙여넣기 해도 됩니다.

 

http://www.dsplog.com/db-install/wp-content/uploads/2008/06/script_16qam_gray_mapping_bit_error_rate.m

 

혹시 못 찾으실 분들을 위해 코드도 넣습니다. 다시 한번 밝히지만 아래 코드는 Krishna Pillai, http://www.dsplog.com 님이 작성하신 겁니다.

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 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        : 05 June 2008

% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

 

% Bit Error Rate for 16-QAM modulation using Gray modulation mapping

 

clear

N = 10^5; % number of symbols

M = 16; % constellation size

k = log2(M); % bits per symbol

 

% defining the real and imaginary PAM constellation

% for 16-QAM

alphaRe = [-(2*sqrt(M)/2-1):2:-1 1:2:2*sqrt(M)/2-1];

alphaIm = [-(2*sqrt(M)/2-1):2:-1 1:2:2*sqrt(M)/2-1];

k_16QAM = 1/sqrt(10);

 

Eb_N0_dB = [0:15]; % multiple Es/N0 values

Es_N0_dB = Eb_N0_dB + 10*log10(k);

 

% Mapping for binary <--> Gray code conversion

ref = [0:k-1];

map = bitxor(ref,floor(ref/2));

[tt ind] = sort(map);

 

for ii = 1:length(Eb_N0_dB)

 

% symbol generation

% ------------------

ipBit = rand(1,N*k,1)>0.5; % random 1's and 0's

ipBitReshape = reshape(ipBit,k,N).';

bin2DecMatrix = ones(N,1)*(2.^[(k/2-1):-1:0]) ; % conversion from binary to decimal

% real

ipBitRe = ipBitReshape(:,[1:k/2]);

ipDecRe = sum(ipBitRe.*bin2DecMatrix,2);

ipGrayDecRe = bitxor(ipDecRe,floor(ipDecRe/2));

% imaginary

ipBitIm = ipBitReshape(:,[k/2+1:k]);

ipDecIm = sum(ipBitIm.*bin2DecMatrix,2);

ipGrayDecIm = bitxor(ipDecIm,floor(ipDecIm/2));

% mapping the Gray coded symbols into constellation

modRe = alphaRe(ipGrayDecRe+1);

modIm = alphaIm(ipGrayDecIm+1);

% complex constellation

mod = modRe + j*modIm;

s = k_16QAM*mod; % normalization of transmit power to one

 

% noise

% -----

n = 1/sqrt(2)*[randn(1,N) + j*randn(1,N)]; % white guassian noise, 0dB variance

 

y = s + 10^(-Es_N0_dB(ii)/20)*n; % additive white gaussian noise

 

% demodulation

% ------------

y_re = real(y)/k_16QAM; % real part

y_im = imag(y)/k_16QAM; % imaginary part

 

% rounding to the nearest alphabet

ipHatRe = 2*floor(y_re/2)+1;

ipHatRe(find(ipHatRe>max(alphaRe))) = max(alphaRe);

ipHatRe(find(ipHatRe<min(alphaRe))) = min(alphaRe);

ipHatIm = 2*floor(y_im/2)+1;

ipHatIm(find(ipHatIm>max(alphaIm))) = max(alphaIm);

ipHatIm(find(ipHatIm<min(alphaIm))) = min(alphaIm);

 

% Constellation to Decimal conversion

ipDecHatRe = ind(floor((ipHatRe+4)/2+1))-1; % LUT based

ipDecHatIm = ind(floor((ipHatIm+4)/2+1))-1; % LUT based

 

% converting to binary string

ipBinHatRe = dec2bin(ipDecHatRe,k/2);

ipBinHatIm = dec2bin(ipDecHatIm,k/2);

 

% converting binary string to number

ipBinHatRe = ipBinHatRe.';

ipBinHatRe = ipBinHatRe(1:end).';

ipBinHatRe = reshape(str2num(ipBinHatRe).',k/2,N).' ;

 

ipBinHatIm = ipBinHatIm.';

ipBinHatIm = ipBinHatIm(1:end).';

ipBinHatIm = reshape(str2num(ipBinHatIm).',k/2,N).' ;

 

% counting errors for real and imaginary

nBitErr(ii) = size(find([ipBitRe- ipBinHatRe]),1) + size(find([ipBitIm - ipBinHatIm]),1) ;

 

end

simBer = nBitErr/(N*k);

theoryBer = (1/k)*3/2*erfc(sqrt(k*0.1*(10.^(Eb_N0_dB/10))));

 

close all; figure

semilogy(Eb_N0_dB,theoryBer,'bs-','LineWidth',2);

hold on

semilogy(Eb_N0_dB,simBer,'mx-','LineWidth',2);

axis([0 15 10^-5 1])

grid on

legend('theory', 'simulation');

xlabel('Eb/No, dB')

ylabel('Bit Error Rate')

title('Bit error probability curve for 16-QAM modulation')

 

실행 시키고 조금만 기다려 보면~~ Krishna Pillai의 블로그에 있는것과 같이 다음과 같은 시뮬레이션 결과를 확인 할 수 있습니다.

 

 

위 코드를 배포 하실 때는 원저자를 명시하셔야 합니다.


태그

, ,

댓글8

  • 홍팡 2015.07.31 17:20

    안녕하세요
    매틀랩 공부를 하다가 우연히 들어오게 되었습니다!
    혹시 64QAM도 시뮬레이션 돌리려면 어디어디 수정해야하는지 알수있을까요?ㅜ
    답글

    • 남성 2015.08.01 13:45 신고

      간단하게 말씀 드리면 mapping 과 demapping 부분 그리고 파워 계산 부분이 바뀌어야하는데 위 코드에서 바꾸려면 대부분 다 바뀌어야 할 것 같네요.

  • 홍팡 2015.08.03 15:49

    죄송합니다만 조금만 더 알려주실 수 있을까요??
    16QAM 에 대해 도움을 많이 얻어서 감사합니다
    답글

    • 남성 2015.08.03 19:39 신고

      for 문 내의 시뮬레이션 과정은 반복적으로 비트를 생성해서 16qam 으로 변조하고 잡음을 넣어주고 복조하는 과정인데 결국에는 이 내부가 대부분 바뀌어야 할거라는 말씀 입니다.

      아래 주소의 글을 보시면 constellation 을 확인 할 수 있는데 64 qam constellation 대로 비트를 심볼로 맵핑하고 수신단에서는 심볼을 다시 비트로 demapping 하는 과정이 필요 할 겁니다.

      http://iamaman.tistory.com/205

      이 과정을 생각하면 위 코드의 많은 부분이 바뀌게 되어 어디 한군데만 바뀌면 된다라고 하기가 힘들것 같습니다.

    • 홍팡 2015.08.04 16:04

      그렇군요.. 감사합니다.

      마지막으로 죄송합니다만 혹시 64QAM 코드도 가지고 계시다면
      공유 부탁드려도 될까요?? 제 비루한 코딩실력으로 변경하기가 쉽지가 않아서요.
      감사합니다.

    • 남성 2015.08.04 19:56 신고

      아래 주소에 포스팅 했습니다.

      http://iamaman.tistory.com/1631

      자주 방문해 주세요. ^^

  • 홍팡 2015.08.09 16:50

    아 정말 감사합니다 많은 도움이 되었습니다!
    답글