-
Notifications
You must be signed in to change notification settings - Fork 5
/
run_me_qpsk.m
115 lines (89 loc) · 4.04 KB
/
run_me_qpsk.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
% decision feedback equalizer
% References: See Section 5.1.8 in the book "Digital Communications and
% Signal Processing" by K Vasudevan
% QPSK modulation
clear all
close all
clc
training_len = 10^4; %length of the training sequence
snr_dB = 10; % snr in dB
ff_filter_len = 30; % feedforward filter length
fb_filter_len = 20; % feedback filter length
data_len = 10^6; % length of the data sequence
% snr parameters
snr = 10^(0.1*snr_dB);
noise_var_1D = 0.5*2*1/(2*snr); % noise variance
% --------------- training phase ------------------------------------------
% source
training_a = randi([0 1],1,2*training_len);
% qpsk mapper
training_seq = 1-2*training_a(1:2:end) + 1i*(1-2*training_a(2:2:end));
% impulse response of the channel
fade_chan = [0.9+0.9i 0.1+0.1i 0.1+0.1i 0.1+0.1i 0.1+0.1i];
fade_chan = fade_chan/norm(fade_chan);
chan_len = length(fade_chan);
% awgn
noise = normrnd(0,sqrt(noise_var_1D),1,training_len+chan_len-1)+normrnd(0,sqrt(noise_var_1D),1,training_len+chan_len-1);
% channel output
chan_op = conv(fade_chan,training_seq)+noise;
% ------------ LMS update of taps------------------------------------------
ff_filter = zeros(1,ff_filter_len); % feedforward filter initialization
fb_filter = zeros(1,fb_filter_len); % feedback filter initialization
ff_filter_ip = zeros(1,ff_filter_len); % feedforward filter input vector
fb_filter_ip = zeros(1,fb_filter_len); % feedback filter input vector
fb_filter_op = 0; % feedback filter output symbol
% estimating the autocorrelation of received sequence at zero lag
Rvv0 = (chan_op*chan_op')/(training_len+chan_len-1);
% maximum step size
max_step_size = 2/(ff_filter_len*(Rvv0)+fb_filter_len*(2));
step_size = 0.125*max_step_size; % step size
for i1=1:training_len-ff_filter_len+1 % steady state part
ff_filter_ip(2:end)=ff_filter_ip(1:end-1);
ff_filter_ip(1) = chan_op(i1);
ff_filter_op = ff_filter*ff_filter_ip.'; % feedforward filter output
ff_and_fb = ff_filter_op-fb_filter_op;
error = ff_and_fb-training_seq(i1); % instantaneous
% hard decision
temp1 = real(ff_and_fb)<0;
temp2 = imag(ff_and_fb)<0;
quantizer_op = 1-2*temp1 + 1i*(1-2*temp2);
% LMS update
ff_filter=ff_filter-step_size*error*conj(ff_filter_ip);
fb_filter=fb_filter+step_size*error*conj(fb_filter_ip);
fb_filter_ip(2:end)=fb_filter(1:end-1);
fb_filter_ip(1) = quantizer_op;
fb_filter_op = fb_filter*fb_filter_ip.';
end
%------- data transmission phase----------------------------
% source
data_a = randi([0 1],1,2*data_len);
% qpsk mapper
data_seq = 1-2*data_a(1:2:end)+1i*(1-2*data_a(2:2:end));
% awgn
noise = normrnd(0,sqrt(noise_var_1D),1,data_len+chan_len-1)+...
1i*normrnd(0,sqrt(noise_var_1D),1,data_len+chan_len-1);
% channel output
chan_op = conv(fade_chan,data_seq)+noise;
dec_seq = zeros(1,data_len-ff_filter_len+1);% output from dfe
ff_filter_ip = zeros(1,ff_filter_len); % feedforward filter input
fb_filter_ip = zeros(1,fb_filter_len); % feedback filter input
fb_filter_op = 0; % feedback filter output symbol
for i1=1:data_len-ff_filter_len+1 % steady state part
ff_filter_ip(2:end)=ff_filter_ip(1:end-1);
ff_filter_ip(1) = chan_op(i1);
ff_filter_op = ff_filter*ff_filter_ip.';
ff_and_fb = ff_filter_op-fb_filter_op;
% hard decision
temp1 = real(ff_and_fb)<0;
temp2 = imag(ff_and_fb)<0;
dec_seq(i1) = 1-2*temp1 +1i*(1-2*temp2);
fb_filter_ip(2:end)=fb_filter(1:end-1);
fb_filter_ip(1) = dec_seq(i1);
fb_filter_op = fb_filter*fb_filter_ip.'; % feedback filter output
end
% demapping symbols back to bits
dec_a = zeros(1,2*(data_len-ff_filter_len+1));
dec_a(1:2:end) = real(dec_seq)<0;
dec_a(2:2:end) = imag(dec_seq)<0;
% bit error rate
ber = nnz(dec_a-data_a(1:2*(data_len-ff_filter_len+1)))/(2*(data_len-ff_filter_len+1))