Last active
October 27, 2022 10:06
-
-
Save sp5wwp/8fe498e831128867690835770f5d0417 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
clear; clc; | |
G1=23; %G_1 polynomial in octal notation | |
G2=35; %G_2 -//- | |
K=5; %convolutional encoder constraint length | |
symbols=10000; %test message length in symbols | |
depth=11; %bit resolution of the soft decoder | |
head=20; %run-up for the root-nyquist filter in symbols | |
span=8; %rnyq filter span | |
sps=10; %samples per symbol | |
alpha=0.5; %bandwidth excess | |
start=0.0; %start SNR, dB | |
stop=3.0; %end SNR, dB | |
step=1.0; %step, dB | |
%pick one of the filters | |
%flt=rcosdesign(alpha, span, sps); %tx and rx filter | |
flt=rNyquistM(span*sps, sps, alpha, 25000, 0.0, 0.0, 10000)'; | |
%generate sample symbol stream | |
s=randi([0, 3], 1, symbols); | |
s=(s-1.5)*2.0; | |
%convert the symbol stream to binary stream | |
msg=[]; | |
for i=1:symbols | |
if s(i)==3 | |
msg=[msg 0 1]; | |
elseif s(i)==1 | |
msg=[msg 0 0]; | |
elseif s(i)==-1 | |
msg=[msg 1 0]; | |
elseif s(i)==-3 | |
msg=[msg 1 1]; | |
end | |
end | |
%generate the trellis and encode the data with K-1 flushing bits at the end | |
trel=poly2trellis(K, [G1 G2]); | |
coded=convenc([msg zeros(1, K-1)], trel); %data with flushing bits | |
%convert the coded bitstream to symbol stream | |
coded_symbols=[]; | |
for i=1:2:length(coded)-1 | |
if coded(i)==0 && coded(i+1)==1 | |
coded_symbols=[coded_symbols 3]; | |
elseif coded(i)==0 && coded(i+1)==0 | |
coded_symbols=[coded_symbols 1]; | |
elseif coded(i)==1 && coded(i+1)==0 | |
coded_symbols=[coded_symbols -1]; | |
elseif coded(i)==1 && coded(i+1)==1 | |
coded_symbols=[coded_symbols -3]; | |
end | |
end | |
%upsample the symbol stream | |
%the symbol stream has a 'run-up' part so that the root nyquist filter can | |
%settle. there's also a tail to flush the filter | |
s=upsample([ones(1, head) coded_symbols ones(1, span)], sps); | |
%let's get the party started | |
%we iterate for SNRs in the given range | |
n=1; | |
for snr=start:step:stop | |
%filter the symbol stream with a root nyquist filter (at the 'transmitter') | |
%apply some AWGN (that's the 'radio channel') | |
%filter again (at the 'receiver') | |
sigf=filter(flt, 1, s); | |
sigf=awgn(sigf, snr, 'measured'); | |
sigf=filter(flt, 1, sigf); | |
%recover the encoded message | |
rx_msg=[]; | |
for i=head+span:length(s)/sps-1 | |
rx_symb=sigf(1+i*sps); | |
%bit 1 | |
if rx_symb<=-1 | |
rx_msg=[rx_msg 2^depth-1]; | |
elseif rx_symb<=1 | |
rx_msg=[rx_msg floor(-(2^depth-1)/2*rx_symb+(2^depth-1)/2)]; | |
else | |
rx_msg=[rx_msg 0]; | |
end | |
%bit 0 | |
if rx_symb<=-3 | |
rx_msg=[rx_msg 2^depth-1]; | |
elseif rx_symb<=-1 | |
rx_msg=[rx_msg floor(-(2^depth-1)/2*rx_symb-(2^depth-1)/2)]; | |
elseif rx_symb<=1 | |
rx_msg=[rx_msg 0]; | |
elseif rx_symb<=3 | |
rx_msg=[rx_msg floor((2^depth-1)/2*rx_symb-(2^depth-1)/2)]; | |
else | |
rx_msg=[rx_msg 2^depth-1]; | |
end | |
end | |
%decode the message using soft viterbi decoder | |
decoded=vitdec(rx_msg, trel, K-1, 'trunc', 'soft', depth); | |
%calculate the bit error rate | |
ber(n)=biterr(msg, decoded(1:symbols*2))/symbols/2; | |
n=n+1; | |
end | |
%plot the BER curve | |
x=linspace(start, stop, n-1); | |
semilogy(x, ber); | |
grid on; | |
xlabel("SNR (dB)"); | |
ylabel("Bit Error Rate"); | |
yline(0.01, 'red'); %red line at 1% BER |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment