Minor bug fixes and code formatting
[100GbE-PON.git] / main.m
CommitLineData
5117fc58
AIL
1numSymbs = 2^16;
2M = 4; % QPSK
3
4Rsym = 28e9; % symbol rate (sym/sec)
5
6%% zs: array of distances z to be simulated
7% Example: zs = 42; zs = 40:10:100; zs = [300, 500, 1000];
8zs = 42;
9plotlen = length(zs);
10
5117fc58
AIL
11%% Tx RRC filter properties
12rolloff = 0.25;
13span = 6; % filter span
14sps = 16; % samples per symbol
15
16%% Sampling frequency
17fs = Rsym * sps; % Hz
18Tsamp = 1 / fs; % s
19% t: time vector, s
20t = (0 : 1 / fs : numSymbs / Rsym - 1 / fs).';
21
22
23%% Chromatic dispersion
24D = 17; % ps / (nm km)
25lambda = 1550; % nm
26
27%% Laser phase noise
28linewidthTx = 0; % Hz
29linewidthLO = 1e6; % Hz
30
31%% Kerr effect / SSFS parameters
32gamma = 1.2; % watt^-1 / km
33alpha = 0.2; % dB/km
34dz = 2; % Step size, km
35
36%% Polarization state rotation parameters
37rot_omega = 1e3; % rad/s
38rot_phi = 2; % rad
39
40%% Launch power, per wavelength channel
41power_dBm = 0;
42power = 10 .^ (power_dBm / 10) * 1e-3; % watts
43
44%% WDM properties
45wavelength_channels = 3;
46dw = 2 * pi * 50e9; % channel spacing (rad/s)
47
48%% Shot noise
49hc = 6.62607015e-34 * 299792458; % J m
50Eperphoton = hc / (lambda * 1e-9); % J
51
52
53%% Stores result to be plotted
54ber = zeros(plotlen, 1);
55if plotlen > 1
79f1c8f1 56 fig = figure;
5117fc58
AIL
57end
58
59%% sps and Tsamp change at Tx/Rx, save these for later.
60spsOrig = sps;
61TsampOrig = Tsamp;
62
63%% Generate random data for both polarizations
64data_x = randi([0, M - 1], numSymbs, wavelength_channels, 'uint8');
65data_y = randi([0, M - 1], numSymbs, wavelength_channels, 'uint8');
66
67%% DE-QPSK modulation
68modData_x = deqpskmod(data_x);
69modData_y = deqpskmod(data_y);
70
71%% Construct waveforms for each channel separately
72A_x_wdm = zeros(numSymbs * sps, wavelength_channels);
73A_y_wdm = zeros(numSymbs * sps, wavelength_channels);
74carriers = zeros(numSymbs * sps, wavelength_channels);
75
76for w = 1 : wavelength_channels
77 %% Compute frequency offsets:
78 % ___ ___ ___ ___ ___
79 % Spectrum | | | | | | | | | |
80 % | | | | | | | | | |
81 % ____| |___| |___| |___| |___| |____ --> freq
82 % channel # 5 3 1 2 4
83 % ang freq offset -2dw -dw 0 +dw +2dw
84
85 if mod(w, 2) == 0
86 ndw = w / 2 * dw;
87 else
88 ndw = (1-w) / 2 * dw;
89 end
90 carriers(:, w) = exp(1j * ndw * t);
91 A_x_wdm(:, w) = txFilter(modData_x(:, w), rolloff, span, sps);
92 A_y_wdm(:, w) = txFilter(modData_y(:, w), rolloff, span, sps);
93end
94
95%% Sum the WDM waveforms with their frequency offsets
96A_x = sum(A_x_wdm .* carriers, 2);
97A_y = sum(A_y_wdm .* carriers, 2);
98
99%% Clear variables no longer needed to reduce memory usage
100clear modData_x modData_y A_x_wdm A_y_wdm;
101
102%% Set launch power. Divide by 2 because half power for each polarization.
103A_x = sqrt(power / 2) * A_x;
104A_y = sqrt(power / 2) * A_y;
105
106%% Rotate polarization states
107A_x = A_x .* cos(rot_omega * t) + ...
108 A_y .* sin(rot_omega * t) * exp(-1j * rot_phi);
109A_y = A_x .* -sin(rot_omega * t) * exp(1j * rot_phi) + ...
110 A_y .* cos(rot_omega * t);
111
112%% Now loop through each z
113for i = 1 : plotlen
114 z = zs(i);
115
116 sps = spsOrig;
117 Tsamp = TsampOrig;
118
119 %% Split-step Fourier
79f1c8f1 120 [Al_x, Al_y] = ssfs(A_x, A_y, D, lambda, z, dz, Tsamp, gamma, alpha);
5117fc58
AIL
121
122 %% Phase noise
79f1c8f1
AIL
123 Al_x = phaseNoise(Al_x, linewidthTx, linewidthLO, Tsamp);
124 Al_y = phaseNoise(Al_y, linewidthTx, linewidthLO, Tsamp);
5117fc58
AIL
125
126 %% Here, only receive the central channel 1.
79f1c8f1
AIL
127 % For channel n: Al_x .* conj(carriers(:, n)); etc.
128 r_x = rxFilter(Al_x, rolloff, span, sps);
129 r_y = rxFilter(Al_y, rolloff, span, sps);
5117fc58
AIL
130 % Rx filter performs downsampling as well, keep track of this
131 sps = 2;
132 Tsamp = Tsamp * spsOrig / sps;
133
134 %% Rx shot noise
135 photonpersym = mean(abs(r_x) .^ 2) / Rsym / Eperphoton;
136 snr = photonpersym;
137 r_x = awgn(r_x, snr, 'measured', 'linear');
138 r_y = awgn(r_y, snr, 'measured', 'linear');
139
140 %% -- Begin DSP channel equalization --
141 %% Chromatic dispersion compensation
142 r_x = CDCompensation(r_x, D, lambda, z, Tsamp);
143 r_y = CDCompensation(r_y, D, lambda, z, Tsamp);
144 r_x = r_x(2:2:end);
145 r_y = r_y(2:2:end);
146
147 %% Adaptive filter
148 [r_x, r_y] = pdm_adaptiveCMA(r_x, r_y);
149
150 %% Phase noise correction
151 r_x = phaseNoiseCorr(r_x, M, 0, 40).';
152 r_y = phaseNoiseCorr(r_y, M, 0, 40).';
153
154 %% Demodulate DE-QPSK
155 demod_x = deqpskdemod(r_x);
156 demod_y = deqpskdemod(r_y);
157
158 %% Calculate and store BER
159 [~, ber(i)] = biterr([data_x(:, 1); data_y(:, 1)], [demod_x; demod_y]);
160
161 q = 20 * log10(erfcinv(2*ber)*sqrt(2));
79f1c8f1 162 if i > 1
5117fc58
AIL
163 figure(fig);
164 plot(zs, q);
165 end
166end
167
168ber
169q