forked from neelabhro/QPSK-Modulation
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimulation.m
More file actions
165 lines (122 loc) · 4.7 KB
/
Copy pathsimulation.m
File metadata and controls
165 lines (122 loc) · 4.7 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
% Skeleton code for simulation chain
% History:
% 2000-06-28 written /Stefan Parkvall
% 2001-10-22 modified /George Jongren
clear;
clc;
close all;
% Initialization
EbN0_db = 10:15; % Eb/N0 values to simulate (in dB)
nr_bits_per_symbol = 2; % Corresponds to k in the report
nr_guard_bits = 10; % Size of guard sequence (in nr bits)
% Guard bits are appended to transmitted bits so
% that the transients in the beginning and end
% of received sequence do not affect the samples
% which contain the training and data symbols.
nr_data_bits = 1000; % Size of each data sequence (in nr bits)
nr_training_bits = 100; % Size of training sequence (in nr bits)
nr_blocks = 50; % The number of blocks to simulate
Q = 8; % Number of samples per symbol in baseband
% Define the pulse-shape used in the transmitter.
% Pick one of the pulse shapes below or experiemnt
% with a pulse of your own.
pulse_shape = ones(1, Q);
%pulse_shape = root_raised_cosine(Q);
% Matched filter impulse response.
mf_pulse_shape = fliplr(pulse_shape);
% Loop over different values of Eb/No.
nr_errors = zeros(1, length(EbN0_db)); % Error counter
for snr_point = 1:length(EbN0_db)
% Loop over several blocks to get sufficient statistics.
for blk = 1:nr_blocks
%%%
%%% Transmitter
%%%
% Generate training sequence.
b_train = training_sequence(nr_training_bits);
% Generate random source data {0, 1}.
b_data = random_data(nr_data_bits);
% Generate guard sequence.
b_guard = random_data(nr_guard_bits);
% Multiplex training and data into one sequence.
b = [b_guard b_train b_data b_guard];
% Map bits into complex-valued QPSK symbols.
d = qpsk(b);
% Upsample the signal, apply pulse shaping.
tx = upfirdn(d, pulse_shape, Q, 1);
%%%
%%% AWGN Channel
%%%
% Compute variance of complex noise according to report.
sigma_sqr = norm(pulse_shape)^2 / nr_bits_per_symbol / 10^(EbN0_db(snr_point)/10);
% Create noise vector.
n = sqrt(sigma_sqr/2)*(randn(size(tx))+j*randn(size(tx)));
% Received signal.
rx = tx + n;
%%%
%%% Receiver
%%%
% Matched filtering.
mf=conv(mf_pulse_shape,rx);
% Synchronization. The position and size of the search window
% is here set arbitrarily. Note that you might need to change these
% parameters. Use sensible values (hint: plot the correlation
% function used for syncing)!
t_start=1+Q*nr_guard_bits/2;
t_end=t_start+50;
t_samp = sync(mf, b_train, Q, t_start, t_end);
% Down sampling. t_samp is the first sample, the remaining samples are all
% separated by a factor of Q. Only training+data samples are kept.
r = mf(t_samp:Q:t_samp+Q*(nr_training_bits+nr_data_bits)/2-1);
% Phase estimation and correction.
phihat = phase_estimation(r, b_train);
r = r * exp(-j*phihat);
% Make decisions. Note that dhat will include training sequence bits
% as well.
bhat = detect(r);
% Count errors. Note that only the data bits and not the training bits
% are included in the comparison. The last data bits are missing as well
% since the whole impulse response due to the last symbol is not
% included in the simulation program above.
temp=bhat(1+nr_training_bits:nr_training_bits+nr_data_bits) ~= b_data;
nr_errors(snr_point) = nr_errors(snr_point) + sum(temp);
% Next block.
end
% Next Eb/No value.
end
% Compute the BER.
BER = nr_errors / nr_data_bits / nr_blocks;
%% Plots
% Periodogram
Prr = periodogram(r);
figure(1)
plot(Prr)
title('Periodogram')
%% PA 1: BER
% BER
figure(2)
plot(EbN0_db, BER)
title('BER')
hold on
% Perfect BER:
% Assume perfect
% EbN0 = 10.^(EbN0_db)/20; % not sure if dB input
BER_0 = qfunc(sqrt(2*EbN0_db)); % BER rate of QPSK, M page 128
plot(EbN0_db, BER_0)
% Exact Error probability of QPSK: why?
P = 2*qfunc(sqrt(2*EbN0_db))-(qfunc(sqrt(EbN0_db))).^2; % M page 118
plot(EbN0_db, P)
legend('Simulation', 'Theoretical value')
hold off
%% PA 2: Phase and timing sensitivity to noise
% Measure phase est error / timing est error
% What is correct phase est?
figure(3)
scatter(real(tx), imag(tx))
hold on
scatter(real(rx), imag(rx))
hold off
% What is correct timing?
% Plot for different SNR (start with very large)
% Why?
% Improved?