Merge branch 'main' of cau-git.rz.uni-kiel.de:nt/mitarbeiter/silas/imdd_simulation
This commit is contained in:
@@ -927,7 +927,7 @@ classdef Signal
|
|||||||
options.displayname = "";
|
options.displayname = "";
|
||||||
end
|
end
|
||||||
|
|
||||||
mode = 1;
|
mode = 2;
|
||||||
|
|
||||||
histpoints = 2048; %% verticale resolution
|
histpoints = 2048; %% verticale resolution
|
||||||
histpoints = floor(histpoints/2)*2+1; %% to have the eye digram centered around one point make the vertical resolution uneven
|
histpoints = floor(histpoints/2)*2+1; %% to have the eye digram centered around one point make the vertical resolution uneven
|
||||||
|
|||||||
@@ -462,10 +462,19 @@ classdef PAMmapper
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function [Signal_out] = quantize(obj,Signal_in)
|
function [Signal_out] = quantize(obj,Signal_in,options)
|
||||||
|
arguments
|
||||||
|
obj
|
||||||
|
Signal_in Signal
|
||||||
|
options.custom_const = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
if isempty(options.custom_const)
|
||||||
constellation = obj.get_levels();
|
constellation = obj.get_levels();
|
||||||
constellation = constellation ./ obj.scaling;
|
constellation = constellation ./ obj.scaling;
|
||||||
|
else
|
||||||
|
constellation = options.custom_const;
|
||||||
|
end
|
||||||
|
|
||||||
issignalclass = 0;
|
issignalclass = 0;
|
||||||
if isa(Signal_in,'Signal')
|
if isa(Signal_in,'Signal')
|
||||||
|
|||||||
82
Classes/03_electrical/CTLE.m
Normal file
82
Classes/03_electrical/CTLE.m
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
classdef CTLE < handle
|
||||||
|
|
||||||
|
properties(Access=public)
|
||||||
|
Aac_dB
|
||||||
|
Adc_dB
|
||||||
|
f_p1
|
||||||
|
f_p2
|
||||||
|
plot
|
||||||
|
end
|
||||||
|
|
||||||
|
methods(Access=public)
|
||||||
|
function obj = CTLE(options)
|
||||||
|
arguments
|
||||||
|
options.Aac_dB = 0;
|
||||||
|
options.Adc_dB = -6;
|
||||||
|
options.f_p1 = 1.5e9;
|
||||||
|
options.f_p2 = 5e9;
|
||||||
|
options.plot = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function data_out = process(obj, data_in)
|
||||||
|
|
||||||
|
x = data_in.signal(:);
|
||||||
|
Fs = data_in.fs;
|
||||||
|
N = length(x);
|
||||||
|
|
||||||
|
% CTLE Transfer Function Parameters
|
||||||
|
A_ac = 10^(obj.Aac_dB/20);
|
||||||
|
A_dc = 10^(obj.Adc_dB/20);
|
||||||
|
w1 = 2*pi*obj.f_p1;
|
||||||
|
w2 = 2*pi*obj.f_p2;
|
||||||
|
|
||||||
|
% Frequency Domain Conversion
|
||||||
|
X = fft(x);
|
||||||
|
|
||||||
|
% Generating Frequency Axis In The Range Of [-Fs/2,Fs/2]
|
||||||
|
f_fft = (0:N-1).' * (Fs/N);
|
||||||
|
f_signed = f_fft;
|
||||||
|
idxNeg = f_signed > Fs/2;
|
||||||
|
f_signed(idxNeg) = f_signed(idxNeg) - Fs;
|
||||||
|
f_pos = abs(f_signed);
|
||||||
|
w_pos = 2*pi*f_pos;
|
||||||
|
s_pos = 1j*w_pos;
|
||||||
|
|
||||||
|
% Calculate CTLE Transfer Function
|
||||||
|
H_pos = A_ac*w2 .* (s_pos + (A_dc/A_ac)*w1) ./ ((s_pos + w1).*(s_pos + w2));
|
||||||
|
|
||||||
|
% Enforce H(-f) = conj(H(f)) For Negative Bins
|
||||||
|
H = H_pos;
|
||||||
|
H(idxNeg) = conj(H_pos(idxNeg));
|
||||||
|
|
||||||
|
% Apply CTLE
|
||||||
|
Y = H .* X;
|
||||||
|
|
||||||
|
% Calculate Time Domain Signal
|
||||||
|
y = ifft(Y, 'symmetric');
|
||||||
|
data_out = data_in;
|
||||||
|
data_out.signal = y;
|
||||||
|
data_out.fs = Fs;
|
||||||
|
|
||||||
|
% Plot
|
||||||
|
if obj.plot
|
||||||
|
% plot only positive frequencies up to Fs/2
|
||||||
|
k = 1:floor(N/2)+1;
|
||||||
|
fplot = f_fft(k);
|
||||||
|
Hplot = H(k);
|
||||||
|
|
||||||
|
figure;
|
||||||
|
semilogx(fplot, 20*log10(abs(Hplot)+1e-15));
|
||||||
|
grid on; xlabel('frequency (Hz)'); ylabel('magnitude (dB)');
|
||||||
|
title('CTLE magnitude on FFT grid');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
130
Classes/03_electrical/Electrical_Hybrid.m
Normal file
130
Classes/03_electrical/Electrical_Hybrid.m
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
classdef Electrical_Hybrid < handle
|
||||||
|
|
||||||
|
properties(Access=public)
|
||||||
|
file_path
|
||||||
|
plot = 0
|
||||||
|
|
||||||
|
% If true: perform digital residual-echo cancellation using known TX
|
||||||
|
cancel_echo = 1
|
||||||
|
|
||||||
|
% If true: in addition return v_hyb and v_echo_est
|
||||||
|
return_intermediates = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
methods(Access=public)
|
||||||
|
|
||||||
|
function obj = Electrical_Hybrid(options)
|
||||||
|
arguments
|
||||||
|
options.file_path = ''
|
||||||
|
options.plot = 0
|
||||||
|
options.cancel_echo = 1
|
||||||
|
options.return_intermediates = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function [v_fe_rec, v_hyb, v_echo_est] = process(obj, v_ne_tx, v_fe_tx)
|
||||||
|
% v_ne_tx : Near-End TX signal object (Port 1)
|
||||||
|
% v_fe_tx : Far-End TX signal object (Port 2)
|
||||||
|
%
|
||||||
|
% Output:
|
||||||
|
% v_hyb : physical hybrid differential output (Port4 - Port3)
|
||||||
|
% v_echo_est : estimated residual echo due to local TX only
|
||||||
|
% v_fe_rec : v_hyb - v_echo_est (if cancel_echo enabled), else v_hyb
|
||||||
|
|
||||||
|
% --- Load S-Parameters (.s4p) ---
|
||||||
|
net = sparameters(obj.file_path);
|
||||||
|
f_s = net.Frequencies(:);
|
||||||
|
S4 = net.Parameters;
|
||||||
|
|
||||||
|
% Extract needed S-parameters for differential output:
|
||||||
|
% V3 = S31*V1 + S32*V2
|
||||||
|
% V4 = S41*V1 + S42*V2
|
||||||
|
% Vhyb = V4 - V3 = (S41-S31)*V1 + (S42-S32)*V2
|
||||||
|
S31_s = squeeze(S4(3,1,:));
|
||||||
|
S41_s = squeeze(S4(4,1,:));
|
||||||
|
S32_s = squeeze(S4(3,2,:));
|
||||||
|
S42_s = squeeze(S4(4,2,:));
|
||||||
|
|
||||||
|
% --- Time-domain signals ---
|
||||||
|
x1 = v_ne_tx.signal(:);
|
||||||
|
x2 = v_fe_tx.signal(:);
|
||||||
|
|
||||||
|
if length(x2) ~= length(x1)
|
||||||
|
error('Near-end and far-end signals must have the same length.');
|
||||||
|
end
|
||||||
|
|
||||||
|
N = length(x1);
|
||||||
|
Fs = v_ne_tx.fs;
|
||||||
|
|
||||||
|
% --- Use zero padding to avoid circular convolution artifacts ---
|
||||||
|
Nfft = 2^nextpow2(2*N); % robust choice
|
||||||
|
|
||||||
|
% --- FFT ---
|
||||||
|
V1 = fft(x1, Nfft);
|
||||||
|
V2 = fft(x2, Nfft);
|
||||||
|
|
||||||
|
% --- Frequency axis for interpolation (signed then abs) ---
|
||||||
|
f_fft = (0:Nfft-1).' * (Fs/Nfft);
|
||||||
|
f_signed = f_fft;
|
||||||
|
idxNeg = f_signed > Fs/2;
|
||||||
|
f_signed(idxNeg) = f_signed(idxNeg) - Fs; % (-Fs/2, Fs/2]
|
||||||
|
f_pos = abs(f_signed);
|
||||||
|
|
||||||
|
% --- Interpolate S-parameters onto f_pos ---
|
||||||
|
S31 = interp1(f_s, S31_s, f_pos, 'linear', 'extrap');
|
||||||
|
S41 = interp1(f_s, S41_s, f_pos, 'linear', 'extrap');
|
||||||
|
S32 = interp1(f_s, S32_s, f_pos, 'linear', 'extrap');
|
||||||
|
S42 = interp1(f_s, S42_s, f_pos, 'linear', 'extrap');
|
||||||
|
|
||||||
|
% Hermitian symmetry for real time-domain response:
|
||||||
|
% For negative frequencies enforce conj symmetry.
|
||||||
|
S31(idxNeg) = conj(S31(idxNeg));
|
||||||
|
S41(idxNeg) = conj(S41(idxNeg));
|
||||||
|
S32(idxNeg) = conj(S32(idxNeg));
|
||||||
|
S42(idxNeg) = conj(S42(idxNeg));
|
||||||
|
|
||||||
|
% --- Physical hybrid differential output ---
|
||||||
|
% Vhyb = (S41-S31)*V1 + (S42-S32)*V2
|
||||||
|
He = (S41 - S31); % residual echo transfer from local TX
|
||||||
|
Hr = (S42 - S32); % transfer from far-end TX to output
|
||||||
|
|
||||||
|
V_hyb = He .* V1 + Hr .* V2;
|
||||||
|
|
||||||
|
% --- Residual echo estimate (digital canceller model) ---
|
||||||
|
V_echo = He .* V1;
|
||||||
|
|
||||||
|
% --- Back to time-domain (take first N samples after padding) ---
|
||||||
|
v_hyb_full = ifft(V_hyb, 'symmetric');
|
||||||
|
v_echo_full = ifft(V_echo, 'symmetric');
|
||||||
|
|
||||||
|
v_hyb = v_hyb_full(1:N);
|
||||||
|
v_echo_est = v_echo_full(1:N);
|
||||||
|
|
||||||
|
% --- Optional cancellation ---
|
||||||
|
if obj.cancel_echo
|
||||||
|
v_fe_rec = v_hyb - v_echo_est;
|
||||||
|
else
|
||||||
|
v_fe_rec = v_hyb;
|
||||||
|
end
|
||||||
|
|
||||||
|
if ~obj.return_intermediates
|
||||||
|
v_hyb = [];
|
||||||
|
v_echo_est = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- Bring output in the correct form ---
|
||||||
|
v_fe_rec = Informationsignal(v_fe_rec,"fs",v_fe_tx.fs);
|
||||||
|
v_hyb = Informationsignal(v_hyb,"fs",v_fe_tx.fs);
|
||||||
|
v_echo_est = Informationsignal(v_echo_est,"fs",v_fe_tx.fs);
|
||||||
|
|
||||||
|
if obj.plot
|
||||||
|
rfplot(net)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
31
Classes/03_electrical/Electrical_Trace.m
Normal file
31
Classes/03_electrical/Electrical_Trace.m
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
classdef Electrical_Trace < handle
|
||||||
|
|
||||||
|
properties(Access=public)
|
||||||
|
file_path
|
||||||
|
end
|
||||||
|
|
||||||
|
methods(Access=public)
|
||||||
|
function obj = Electrical_Trace(options)
|
||||||
|
arguments(Input)
|
||||||
|
|
||||||
|
options.file_path = 'C:\Users\magf\Desktop\Desktop\MATLAB-Zeugs\COM Test\Mellitzz\TA_6002_6003_FX_B6_C6_B7_C7_Terminated.s4p'
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [data_out,timing_error] = process(obj, data_in)
|
||||||
|
|
||||||
|
S =
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
114
Classes/03_electrical/Electrical_Trace_BiDi.m
Normal file
114
Classes/03_electrical/Electrical_Trace_BiDi.m
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
classdef Electrical_Trace_BiDi < handle
|
||||||
|
|
||||||
|
properties(Access=public)
|
||||||
|
file_path
|
||||||
|
fsym
|
||||||
|
rolloff
|
||||||
|
K_over
|
||||||
|
plot
|
||||||
|
test
|
||||||
|
S_test
|
||||||
|
end
|
||||||
|
|
||||||
|
methods(Access=public)
|
||||||
|
function obj = Electrical_Trace_BiDi(options)
|
||||||
|
arguments(Input)
|
||||||
|
|
||||||
|
options.file_path = 'C:\Users\magf\Desktop\Desktop\MATLAB-Zeugs\COM Test\Mellitzz\TA_6002_6003_FX_B6_C6_B7_C7_Terminated.s4p'
|
||||||
|
options.fsym = 0;
|
||||||
|
options.rolloff = 0;
|
||||||
|
options.K_over = 1;
|
||||||
|
options.plot = 0;
|
||||||
|
options.test = 0;
|
||||||
|
options.S_test = [0,1;1,0];
|
||||||
|
end
|
||||||
|
|
||||||
|
fn = fieldnames(options);
|
||||||
|
for n = 1:numel(fn)
|
||||||
|
obj.(fn{n}) = options.(fn{n});
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [b_1,b_2] = process(obj, a_1, a_2)
|
||||||
|
|
||||||
|
% Rx Signal Calculation Using S-Paramters For a 2-Port Network
|
||||||
|
% [B_1(f); B_2(f)] = [S_11(f), S_12(f); S_21(f), S_22(f)] * [A_1(f); A_2(f)]
|
||||||
|
|
||||||
|
% Initialize Rx Time Domain Signals
|
||||||
|
b_1 = a_2;
|
||||||
|
b_2 = a_1;
|
||||||
|
|
||||||
|
% Loading and Extract S-Paramters
|
||||||
|
net = sparameters(obj.file_path);
|
||||||
|
f_s = net.Frequencies(:);
|
||||||
|
|
||||||
|
if ~obj.test
|
||||||
|
S2 = net.Parameters(1:2, 1:2, :);
|
||||||
|
else
|
||||||
|
S2 = repmat(obj.S_test,1,1,size(f_s,1));
|
||||||
|
end
|
||||||
|
|
||||||
|
S11_s = squeeze(S2(1,1,:));
|
||||||
|
S12_s = squeeze(S2(1,2,:));
|
||||||
|
S21_s = squeeze(S2(2,1,:));
|
||||||
|
S22_s = squeeze(S2(2,2,:));
|
||||||
|
|
||||||
|
% Setup Time Domain Signals
|
||||||
|
x1 = a_1.signal(:);
|
||||||
|
x2 = a_2.signal(:);
|
||||||
|
N = length(x1);
|
||||||
|
assert(length(x2)==N, 'a_1 and a_2 must have same length');
|
||||||
|
|
||||||
|
% Extract Time Domain Signal Frequencies
|
||||||
|
if obj.fsym == 0 && obj.rolloff == 0 && obj.K_over == 1
|
||||||
|
Fs = a_1.fs;
|
||||||
|
else
|
||||||
|
Fs = (1+obj.rolloff)*obj.fsym;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Calculate Frequency Domain Signals
|
||||||
|
A1 = fft(x1);
|
||||||
|
A2 = fft(x2);
|
||||||
|
|
||||||
|
% Calculate Frequency Axis [-Fs/2,...,Fs/2]
|
||||||
|
f_fft = (0:N-1).' * (Fs/N);
|
||||||
|
f_signed = f_fft;
|
||||||
|
idxNeg = f_signed > Fs/2;
|
||||||
|
f_signed(idxNeg) = f_signed(idxNeg) - Fs; % Now in (-Fs/2, Fs/2]
|
||||||
|
|
||||||
|
% Absolute Value Used for Interpolation
|
||||||
|
f_pos = abs(f_signed);
|
||||||
|
|
||||||
|
% Interpolate S-Parameters onto f_pos
|
||||||
|
S11_p = interp1(f_s, S11_s, f_pos, 'linear', 'extrap');
|
||||||
|
S12_p = interp1(f_s, S12_s, f_pos, 'linear', 'extrap');
|
||||||
|
S21_p = interp1(f_s, S21_s, f_pos, 'linear', 'extrap');
|
||||||
|
S22_p = interp1(f_s, S22_s, f_pos, 'linear', 'extrap');
|
||||||
|
|
||||||
|
% Apply Hermitian Symmetry: S(-f) = conj(S(f))
|
||||||
|
S11 = S11_p; S12 = S12_p; S21 = S21_p; S22 = S22_p;
|
||||||
|
S11(idxNeg) = conj(S11_p(idxNeg));
|
||||||
|
S12(idxNeg) = conj(S12_p(idxNeg));
|
||||||
|
S21(idxNeg) = conj(S21_p(idxNeg));
|
||||||
|
S22(idxNeg) = conj(S22_p(idxNeg));
|
||||||
|
|
||||||
|
% Compute Rx Frequency Domain Signals
|
||||||
|
B1 = S11 .* A1 + S12 .* A2;
|
||||||
|
B2 = S21 .* A1 + S22 .* A2;
|
||||||
|
|
||||||
|
% Calculate Rx Time Domain Signals
|
||||||
|
b_1.signal = ifft(B1, 'symmetric');
|
||||||
|
b_2.signal = ifft(B2, 'symmetric');
|
||||||
|
|
||||||
|
if obj.plot
|
||||||
|
rfplot(net)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@@ -480,7 +480,7 @@ classdef EQ < handle
|
|||||||
|
|
||||||
output_vec_weighted(m) = xbar;
|
output_vec_weighted(m) = xbar;
|
||||||
fb_sym = xbar;
|
fb_sym = xbar;
|
||||||
output_vec(m) = xbar;
|
% output_vec(m) = xbar;
|
||||||
end
|
end
|
||||||
|
|
||||||
if obj.Nb(1) > 0
|
if obj.Nb(1) > 0
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ classdef MaxVar_Timing_Recovery < handle
|
|||||||
% y = [y 0];
|
% y = [y 0];
|
||||||
% end
|
% end
|
||||||
data_out.signal = y.';
|
data_out.signal = y.';
|
||||||
|
data_out.fs = obj.fsym;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
8
Datatypes/db_decoder.m
Normal file
8
Datatypes/db_decoder.m
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
classdef db_decoder < int32
|
||||||
|
|
||||||
|
enumeration
|
||||||
|
sequencedetection (0) % use MLSE for decoding
|
||||||
|
memoryless (1) % use modulo
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
BIN
Documentations/Demystifying Duobinary.pdf
Normal file
BIN
Documentations/Demystifying Duobinary.pdf
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
function [db_results] = duobinary_target(eq_, mlse_,M, rx_signal, tx_symbols, tx_bits, options)
|
function [db_results] = duobinary_target(eq_, mlse_,M, rx_signal, tx_symbols, tx_bits, options)
|
||||||
|
|
||||||
arguments
|
arguments
|
||||||
eq_
|
eq_
|
||||||
mlse_
|
mlse_
|
||||||
M
|
M
|
||||||
@@ -11,39 +11,56 @@ arguments
|
|||||||
options.showAnalysis = 0;
|
options.showAnalysis = 0;
|
||||||
options.eth_style_symbol_mapping = 0;
|
options.eth_style_symbol_mapping = 0;
|
||||||
options.postFFE = [];
|
options.postFFE = [];
|
||||||
end
|
options.decoding_mode db_decoder = db_decoder.sequencedetection;
|
||||||
|
end
|
||||||
|
|
||||||
%Duobinary Targeting
|
|
||||||
db_ref_sequence = Duobinary().encode(tx_symbols);
|
|
||||||
db_ref_constellation = unique(db_ref_sequence.signal);
|
|
||||||
[eq_signal, eq_noise] = eq_.process(rx_signal,db_ref_sequence);
|
|
||||||
|
|
||||||
if ~isempty(options.postFFE)
|
%Duobinary Targeting
|
||||||
|
db_ref_sequence = Duobinary().encode(tx_symbols);
|
||||||
|
db_ref_constellation = unique(db_ref_sequence.signal);
|
||||||
|
[eq_signal, eq_noise] = eq_.process(rx_signal,db_ref_sequence);
|
||||||
|
|
||||||
|
if ~isempty(options.postFFE)
|
||||||
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,db_ref_sequence);
|
[eq_signal,eq_noise] = options.postFFE.process(eq_signal,db_ref_sequence);
|
||||||
end
|
end
|
||||||
|
%
|
||||||
|
|
||||||
mlse_.DIR = [1,1];
|
switch options.decoding_mode
|
||||||
%
|
case db_decoder.sequencedetection %MLSE
|
||||||
|
mlse_.DIR = [1,1];
|
||||||
if isa(mlse_,'MLSE_viterbi')
|
if isa(mlse_,'MLSE_viterbi')
|
||||||
mlse_sig_sd = mlse_.process(eq_signal);
|
mlse_sig_sd = mlse_.process(eq_signal);
|
||||||
else
|
else
|
||||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
||||||
end
|
end
|
||||||
|
pam_sig_hd = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).quantize(mlse_sig_sd);
|
||||||
|
case db_decoder.memoryless %DB Target FFE
|
||||||
|
% Hard decision on FFE output
|
||||||
|
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal,'custom_const',db_ref_constellation.');
|
||||||
|
eq_signal_hd = Duobinary().decode(eq_signal_hd);
|
||||||
|
pam_sig_hd = eq_signal_hd;
|
||||||
|
% tx_symbols = Duobinary().encode(tx_symbols);
|
||||||
|
% tx_symbols = Duobinary().decode(tx_symbols.*db_const_scale_factor);
|
||||||
|
end
|
||||||
|
|
||||||
mlse_sig_hd = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).quantize(mlse_sig_sd);
|
% precoding to mitigate error propagation, most prominently used in
|
||||||
|
% combination with duobinary signaling to avoid catastrophic error
|
||||||
% precoding to mitigate error propagation, most prominently used in
|
% behavior (see J.W.M. Bergmans, Digital Baseband Transmission and Recording -> partial response signaling)
|
||||||
% combination with duobinary signaling to avoid catastrophic error
|
switch options.precode_mode
|
||||||
% behavior (see J.W.M. Bergmans, Digital Baseband Transmission and Recording -> partial response signaling)
|
|
||||||
switch options.precode_mode
|
|
||||||
|
|
||||||
case db_mode.no_db
|
case db_mode.no_db
|
||||||
% TX Data is not precoded:
|
% TX Data is not precoded:
|
||||||
|
|
||||||
% A) Emulate diff precoding
|
% A) Emulate diff precoding
|
||||||
mlse_sig_hd_precoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
switch options.decoding_mode
|
||||||
mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded,"M",M);
|
case db_decoder.sequencedetection %MLSE
|
||||||
|
mlse_sig_hd_precoded = Duobinary().encode(pam_sig_hd);
|
||||||
|
mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded);
|
||||||
|
case db_decoder.memoryless %DB Target FFE
|
||||||
|
% mlse_sig_hd_precoded = Duobinary().encode(pam_sig_hd);
|
||||||
|
% mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded);
|
||||||
|
mlse_sig_hd_precoded = pam_sig_hd;
|
||||||
|
end
|
||||||
|
|
||||||
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
||||||
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||||
@@ -54,7 +71,8 @@ switch options.precode_mode
|
|||||||
[~,errors_db_diff_precoded,ber_db_diff_precoded,~] = calc_ber(rx_bits_mlse.signal,tx_bits_precoded.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
[~,errors_db_diff_precoded,ber_db_diff_precoded,~] = calc_ber(rx_bits_mlse.signal,tx_bits_precoded.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
%B) Just determine BER
|
%B) Just determine BER
|
||||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(pam_sig_hd);
|
||||||
|
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols);
|
||||||
[bits_mlse,errors_mlse,ber_db,~] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
[bits_mlse,errors_mlse,ber_db,~] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
case db_mode.db_precoded
|
case db_mode.db_precoded
|
||||||
@@ -62,15 +80,26 @@ switch options.precode_mode
|
|||||||
% Daten SIND TATSÄCHLICH precoded auf TX Seite:
|
% Daten SIND TATSÄCHLICH precoded auf TX Seite:
|
||||||
|
|
||||||
% A) Decode at Rx if no DB targeting was applied (we are in VNLE or MLSE EQ structure here!
|
% A) Decode at Rx if no DB targeting was applied (we are in VNLE or MLSE EQ structure here!
|
||||||
mlse_sig_hd_decoded = Duobinary().encode(mlse_sig_hd,"M",M);
|
switch options.decoding_mode
|
||||||
|
case db_decoder.sequencedetection %MLSE
|
||||||
|
mlse_sig_hd_decoded = Duobinary().encode(pam_sig_hd,"M",M);
|
||||||
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M);
|
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M);
|
||||||
|
case db_decoder.memoryless %DB Target FFE
|
||||||
|
mlse_sig_hd_decoded = pam_sig_hd;
|
||||||
|
end
|
||||||
|
|
||||||
|
tx_symbols_precoded = Duobinary().encode(tx_symbols,"M",M);
|
||||||
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded,"M",M);
|
||||||
|
|
||||||
|
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
||||||
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_decoded);
|
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_decoded);
|
||||||
[~,errors_db_diff_precoded,ber_db_diff_precoded,a] = calc_ber(rx_bits_mlse_decoded.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
|
||||||
|
[~,errors_db_diff_precoded,ber_db_diff_precoded,a] = calc_ber(rx_bits_mlse_decoded.signal,tx_bits_precoded.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
burst_db_precoded = count_error_bursts(a, 40);
|
burst_db_precoded = count_error_bursts(a, 40);
|
||||||
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
|
||||||
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols);
|
tx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols);
|
||||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(pam_sig_hd);
|
||||||
[bits_db,errors_db,ber_db,a] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
[bits_db,errors_db,ber_db,a] = calc_ber(rx_bits_mlse.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
burst_db = count_error_bursts(a, 40);
|
burst_db = count_error_bursts(a, 40);
|
||||||
|
|
||||||
@@ -81,55 +110,60 @@ switch options.precode_mode
|
|||||||
xlabel('Bit Error Burst Length')
|
xlabel('Bit Error Burst Length')
|
||||||
ylabel('Occurence')
|
ylabel('Occurence')
|
||||||
set(gca, 'yscale', 'log');
|
set(gca, 'yscale', 'log');
|
||||||
end
|
end
|
||||||
|
|
||||||
% M = numel(unique(tx_symbols.signal));
|
% M = numel(unique(tx_symbols.signal));
|
||||||
rx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
rx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(pam_sig_hd);
|
||||||
|
|
||||||
[bits_db,errors_db,ber_db,errorIndice_db] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
[bits_db,errors_db,ber_db,errorIndice_db] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
||||||
|
|
||||||
|
alpha = arburg(eq_noise.signal,1);%pf_.coefficients(2);
|
||||||
|
alpha = alpha(2);
|
||||||
|
|
||||||
|
switch options.decoding_mode
|
||||||
|
case db_decoder.sequencedetection %MLSE
|
||||||
|
if isa(mlse_,'MLSE_viterbi')
|
||||||
alpha = arburg(eq_noise.signal,1);%pf_.coefficients(2);
|
|
||||||
alpha = alpha(2);
|
|
||||||
if isa(mlse_,'MLSE_viterbi')
|
|
||||||
gmi_mlse = NaN;
|
gmi_mlse = NaN;
|
||||||
air_mlse = NaN;
|
air_mlse = NaN;
|
||||||
else
|
else
|
||||||
gmi_mlse = GMI_MLSE;
|
gmi_mlse = GMI_MLSE;
|
||||||
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_mlse ./ log2(double(M));
|
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi_mlse ./ log2(double(M));
|
||||||
end
|
end
|
||||||
|
case db_decoder.memoryless %DB Target FFE
|
||||||
|
% [gmi] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||||
|
[gmi] = calc_ngmi(eq_signal,tx_symbols);
|
||||||
|
gmi_mlse = max(gmi,0);
|
||||||
|
air_mlse = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
|
||||||
|
end
|
||||||
|
|
||||||
db_results = struct();
|
db_results = struct();
|
||||||
db_results.metrics = Metricstruct;
|
db_results.metrics = Metricstruct;
|
||||||
db_results.metrics.result_id = NaN;
|
db_results.metrics.result_id = NaN;
|
||||||
db_results.metrics.run_id = NaN;
|
db_results.metrics.run_id = NaN;
|
||||||
db_results.metrics.eqParam_id = NaN;
|
db_results.metrics.eqParam_id = NaN;
|
||||||
db_results.metrics.date_of_processing = datetime('now');
|
db_results.metrics.date_of_processing = datetime('now');
|
||||||
db_results.metrics.BER = ber_db;
|
db_results.metrics.BER = ber_db;
|
||||||
db_results.metrics.numBits = bits_db;
|
db_results.metrics.numBits = bits_db;
|
||||||
db_results.metrics.numBitErr = errors_db;
|
db_results.metrics.numBitErr = errors_db;
|
||||||
db_results.metrics.BER_precoded = ber_db_diff_precoded;
|
db_results.metrics.BER_precoded = ber_db_diff_precoded;
|
||||||
db_results.metrics.numBitErr_precoded = errors_db_diff_precoded;
|
db_results.metrics.numBitErr_precoded = errors_db_diff_precoded;
|
||||||
db_results.metrics.GMI = gmi_mlse;
|
db_results.metrics.GMI = gmi_mlse;
|
||||||
db_results.metrics.AIR = air_mlse;
|
db_results.metrics.AIR = air_mlse;
|
||||||
db_results.metrics.MLSE_dir = mlse_.DIR;
|
db_results.metrics.MLSE_dir = mlse_.DIR;
|
||||||
db_results.metrics.Alpha = alpha;
|
db_results.metrics.Alpha = alpha;
|
||||||
|
|
||||||
% Create DB results structure
|
% Create DB results structure
|
||||||
db_results.config = Equalizerstruct();
|
db_results.config = Equalizerstruct();
|
||||||
eq_.e = [];
|
eq_.e = [];
|
||||||
eq_.e2 = [];
|
eq_.e2 = [];
|
||||||
eq_.e3 = [];
|
eq_.e3 = [];
|
||||||
db_results.config.eq = jsonencode(eq_);
|
db_results.config.eq = jsonencode(eq_);
|
||||||
% mlse_.DIR = [];
|
% mlse_.DIR = [];
|
||||||
db_results.config.mlse = jsonencode(mlse_);
|
db_results.config.mlse = jsonencode(mlse_);
|
||||||
db_results.config.equalizer_structure = int32(equalizer_structure.vnle_db_mlse);
|
db_results.config.equalizer_structure = int32(equalizer_structure.vnle_db_mlse);
|
||||||
db_results.config.comment = 'function: Duobinary tgt. (VNLE -> MLSE)';
|
db_results.config.comment = 'function: Duobinary tgt. (VNLE -> MLSE)';
|
||||||
|
|
||||||
if options.showAnalysis
|
if options.showAnalysis
|
||||||
|
|
||||||
eq_signal.eye(eq_signal.fs,M,"fignum",249);
|
eq_signal.eye(eq_signal.fs,M,"fignum",249);
|
||||||
|
|
||||||
@@ -147,7 +181,7 @@ if options.showAnalysis
|
|||||||
figure(341); clf;
|
figure(341); clf;
|
||||||
showLevelHistogram(eq_signal, db_ref_sequence, "fignum", 341);
|
showLevelHistogram(eq_signal, db_ref_sequence, "fignum", 341);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
211
Functions/EQ_structures/ffe_db.m
Normal file
211
Functions/EQ_structures/ffe_db.m
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
function [ffe_results] = ffe_db(eq_, M, rx_signal, tx_symbols, tx_bits, options)
|
||||||
|
% FFE Processes signals through FFE equalizer
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% eq_ - Equalizer object
|
||||||
|
% M - Modulation order
|
||||||
|
% rx_signal - Received signal
|
||||||
|
% tx_symbols - Transmitted symbols
|
||||||
|
% tx_bits - Transmitted bits
|
||||||
|
% options - Optional parameters
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% ffe_results - Results from FFE processing
|
||||||
|
|
||||||
|
arguments
|
||||||
|
eq_
|
||||||
|
M
|
||||||
|
rx_signal
|
||||||
|
tx_symbols
|
||||||
|
tx_bits
|
||||||
|
options.db_target = 0;
|
||||||
|
options.precode_mode db_mode
|
||||||
|
options.showAnalysis = 0;
|
||||||
|
options.eth_style_symbol_mapping = 0;
|
||||||
|
options.postFFE = [];
|
||||||
|
options.database = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Process signals through equalizer
|
||||||
|
% FFE or VNLE
|
||||||
|
if options.db_target
|
||||||
|
tx_symbols_ref = Duobinary().encode(tx_symbols);
|
||||||
|
db_ref_constellation = unique(tx_symbols_ref.signal);
|
||||||
|
[eq_signal_sd, eq_noise] = eq_.process(rx_signal, tx_symbols_ref);
|
||||||
|
else
|
||||||
|
[eq_signal_sd, eq_noise] = eq_.process(rx_signal, tx_symbols);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Apply post-FFE if provided
|
||||||
|
if ~isempty(options.postFFE)
|
||||||
|
tic
|
||||||
|
[eq_signal_sd, eq_noise] = options.postFFE.process(eq_signal_sd, tx_symbols);
|
||||||
|
toc
|
||||||
|
end
|
||||||
|
|
||||||
|
try
|
||||||
|
ch_coefficients = arburg(eq_noise.signal,1);
|
||||||
|
channel_alpha = ch_coefficients(2);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Hard decision on FFE output
|
||||||
|
if options.db_target
|
||||||
|
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal_sd,'custom_const',db_ref_constellation.');
|
||||||
|
else
|
||||||
|
eq_signal_hd = PAMmapper(M, 0).quantize(eq_signal_sd);
|
||||||
|
end
|
||||||
|
|
||||||
|
if options.db_target
|
||||||
|
eq_signal_hd = Duobinary().decode(eq_signal_hd);
|
||||||
|
tx_symbols = Duobinary().encode(tx_symbols);
|
||||||
|
tx_symbols = Duobinary().decode(tx_symbols);
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Calculate BER based on precoding mode
|
||||||
|
[bits, errors, ber, error_pos, errors_precoded, ber_precoded] = calculateBER(eq_signal_hd, tx_symbols, tx_bits, options.precode_mode, M, options.eth_style_symbol_mapping);
|
||||||
|
|
||||||
|
%% Calculate performance metrics
|
||||||
|
[snr, snr_lvl] = calc_snr(tx_symbols.signal, eq_noise.signal);
|
||||||
|
% [gmi] = calc_air(eq_signal_sd, tx_symbols, "skip_front", 10000, "skip_end", 10000);
|
||||||
|
[gmi] = calc_ngmi(eq_signal_sd,tx_symbols);
|
||||||
|
gmi = max(gmi,0);
|
||||||
|
|
||||||
|
air = tx_symbols.fs .* floor(log2(double(M))*10)/10 .* gmi ./ log2(double(M));
|
||||||
|
[evm_total, evm_lvl] = calc_evm(eq_signal_sd, tx_symbols);
|
||||||
|
[std_total, std_lvl] = calc_std(eq_signal_sd, tx_symbols);
|
||||||
|
[std_rxraw_total, std_rxraw_lvl] = calc_std(rx_signal.resample("fs_out", tx_symbols.fs), tx_symbols);
|
||||||
|
|
||||||
|
%% Display analysis if requested
|
||||||
|
if options.showAnalysis
|
||||||
|
displayAnalysis(eq_noise, eq_signal_sd, rx_signal, eq_, tx_symbols, M, options.postFFE);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%% Prepare output structure
|
||||||
|
% Determine postFFE order
|
||||||
|
if ~isempty(options.postFFE)
|
||||||
|
npostFFE = options.postFFE.order;
|
||||||
|
else
|
||||||
|
npostFFE = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Create FFE results structure
|
||||||
|
ffe_results = struct();
|
||||||
|
try
|
||||||
|
eq_.e = [];
|
||||||
|
eq_.e2 = [];
|
||||||
|
eq_.e3 = [];
|
||||||
|
eq_.b = [];
|
||||||
|
eq_.b2 = [];
|
||||||
|
eq_.b3 = [];
|
||||||
|
end
|
||||||
|
|
||||||
|
ffe_results.config = Equalizerstruct();
|
||||||
|
ffe_results.config.eq = jsonencode(eq_);
|
||||||
|
ffe_results.config.equalizer_structure = int32(equalizer_structure.ffe);
|
||||||
|
ffe_results.config.comment = 'function: ffe';
|
||||||
|
|
||||||
|
ffe_results.metrics = Metricstruct;
|
||||||
|
ffe_results.metrics.result_id = NaN;
|
||||||
|
ffe_results.metrics.run_id = NaN;
|
||||||
|
ffe_results.metrics.eqParam_id = NaN;
|
||||||
|
ffe_results.metrics.date_of_processing = datetime('now');
|
||||||
|
ffe_results.metrics.BER = ber;
|
||||||
|
ffe_results.metrics.numBits = bits;
|
||||||
|
ffe_results.metrics.numBitErr = errors;
|
||||||
|
ffe_results.metrics.BER_precoded = ber_precoded;
|
||||||
|
ffe_results.metrics.numBitErr_precoded = errors_precoded;
|
||||||
|
ffe_results.metrics.SNR = snr;
|
||||||
|
ffe_results.metrics.SNR_level = snr_lvl;
|
||||||
|
ffe_results.metrics.STD = std_total;
|
||||||
|
ffe_results.metrics.STD_level = std_lvl;
|
||||||
|
ffe_results.metrics.STDrx = std_rxraw_total;
|
||||||
|
ffe_results.metrics.STDrx_level = std_rxraw_lvl;
|
||||||
|
ffe_results.metrics.GMI = gmi;
|
||||||
|
ffe_results.metrics.AIR = air;
|
||||||
|
ffe_results.metrics.EVM = evm_total;
|
||||||
|
ffe_results.metrics.EVM_level = evm_lvl;
|
||||||
|
ffe_results.metrics.Alpha = channel_alpha;
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Helper Functions
|
||||||
|
function [bits, errors, ber, error_pos, errors_precoded, ber_precoded] = calculateBER(eq_signal_hd, tx_symbols, tx_bits, precode_mode, M, eth_style)
|
||||||
|
% Calculate BER based on precoding mode
|
||||||
|
mapper = PAMmapper(M, 0, "eth_style", eth_style);
|
||||||
|
|
||||||
|
switch precode_mode
|
||||||
|
case db_mode.no_db
|
||||||
|
% TX Data is not precoded
|
||||||
|
% A) Emulate diff precoding
|
||||||
|
eq_signal_hd_precoded = Duobinary().encode(eq_signal_hd, "M", M);
|
||||||
|
eq_signal_hd_precoded = Duobinary().decode(eq_signal_hd_precoded, "M", M);
|
||||||
|
|
||||||
|
tx_symbols_precoded = Duobinary().encode(tx_symbols);
|
||||||
|
tx_symbols_precoded = Duobinary().decode(tx_symbols_precoded);
|
||||||
|
|
||||||
|
tx_bits_precoded = mapper.demap(tx_symbols_precoded);
|
||||||
|
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd_precoded);
|
||||||
|
[~, errors_precoded, ber_precoded, ~] = calc_ber(rx_bits.signal, tx_bits_precoded.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
% B) Just determine BER
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd);
|
||||||
|
tx_bits = mapper.demap(tx_symbols);
|
||||||
|
[bits, errors, ber, error_pos] = calc_ber(rx_bits.signal, tx_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
case db_mode.db_precoded
|
||||||
|
% Data is precoded on TX side
|
||||||
|
% A) Decode at Rx if no DB targeting was applied
|
||||||
|
eq_signal_hd_decoded = Duobinary().encode(eq_signal_hd, "M", M);
|
||||||
|
eq_signal_hd_decoded = Duobinary().decode(eq_signal_hd_decoded, "M", M);
|
||||||
|
rx_bits_decoded = mapper.demap(eq_signal_hd_decoded);
|
||||||
|
[~, errors_precoded, ber_precoded, ~] = calc_ber(rx_bits_decoded.signal, tx_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
|
||||||
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
tx_bits_demapped = mapper.demap(tx_symbols);
|
||||||
|
rx_bits = mapper.demap(eq_signal_hd);
|
||||||
|
[bits, errors, ber, error_pos] = calc_ber(rx_bits.signal, tx_bits_demapped.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function displayAnalysis(eq_noise, eq_signal_sd, rx_signal, eq_, tx_symbols, M, postFFE)
|
||||||
|
% Display analysis plots and metrics
|
||||||
|
|
||||||
|
% Initialize figure handles
|
||||||
|
% Corrected line - added tx_symbols as second positional argument
|
||||||
|
% showLevelScatter(rx_signal.resample("fs_out", tx_symbols.fs), tx_symbols, "fignum", 100);
|
||||||
|
|
||||||
|
warning off
|
||||||
|
showLevelScatter(eq_signal_sd, tx_symbols, "fignum", 101);
|
||||||
|
figure(gcf);hold on; plot(((1:length(eq_noise.signal)) / eq_noise.fs) * 1e6,movmean(eq_noise.signal,2000,1), 'LineWidth',3,'Color','black')
|
||||||
|
warning on
|
||||||
|
|
||||||
|
showLevelHistogram(eq_signal_sd, tx_symbols, "fignum", 102);
|
||||||
|
|
||||||
|
showEQNoisePSD(eq_noise, "fignum", 103, "displayname", 'Residual Noise after FFE');
|
||||||
|
|
||||||
|
% Figure 2: Post-FFE coefficients (if available)
|
||||||
|
if ~isempty(postFFE)
|
||||||
|
showEQcoefficients('n1', postFFE.e, "displayname", 'Coefficients', 'fignum', 104);
|
||||||
|
end
|
||||||
|
|
||||||
|
try
|
||||||
|
figure(339);hold on
|
||||||
|
showEQfilter(eq_.e, eq_signal_sd.fs.*2,"displayname",'training','fignum',339);
|
||||||
|
% showEQfilter(eq_.e, eq_signal_sd.fs.*2,"displayname",'dec. directed','fignum',339);
|
||||||
|
legend on
|
||||||
|
end
|
||||||
|
|
||||||
|
% try
|
||||||
|
% figure(240); hold on; plot(pow2db(movmean(eq_.debug_struct.error_tr',100)));ylim([-30,3]);title('error training');
|
||||||
|
%
|
||||||
|
% figure(241); hold on; plot(pow2db(movmean(eq_.debug_struct.update_tr',100)));title('update step training');
|
||||||
|
%
|
||||||
|
% figure(242); hold on; plot(pow2db(movmean(eq_.debug_struct.update',1000)));title('update step dd');
|
||||||
|
% end
|
||||||
|
|
||||||
|
eq_signal_sd.eye(eq_signal_sd.fs,M,"displayname",'Eye','fignum',105);
|
||||||
|
|
||||||
|
end
|
||||||
@@ -9,31 +9,35 @@
|
|||||||
% S0 - dispersion slope at ZDW [ps/(nm^2·km)]
|
% S0 - dispersion slope at ZDW [ps/(nm^2·km)]
|
||||||
% ------------------------------------------------------------
|
% ------------------------------------------------------------
|
||||||
|
|
||||||
lambda0_nm = 1310;
|
%% ZDW 1
|
||||||
S0 = [0.07,0.09]';
|
lambda0_nm = [1310];
|
||||||
|
S0 = [0.075,0.095]';
|
||||||
% wavelength axis around ZDW
|
% wavelength axis around ZDW
|
||||||
lambda_nm = linspace(lambda0_nm-60, lambda0_nm+60, 400);
|
lambda_nm = linspace(1240, 1360, 400);
|
||||||
|
|
||||||
% exact dispersion model
|
% exact dispersion model
|
||||||
D_exact = (S0./4) .* ( ...
|
D_exact_1 = (S0./4) .* ( ...
|
||||||
lambda_nm - (lambda0_nm^4)./(lambda_nm.^3) );
|
lambda_nm - (lambda0_nm^4)./(lambda_nm.^3) );
|
||||||
|
|
||||||
% linearized model around ZDW
|
%% ZDW 2
|
||||||
D_lin = S0 .* (lambda_nm - lambda0_nm);
|
lambda0_nm = [1320];
|
||||||
|
% exact dispersion model
|
||||||
|
D_exact_2 = (S0./4) .* ( ...
|
||||||
|
lambda_nm - (lambda0_nm^4)./(lambda_nm.^3) );
|
||||||
|
|
||||||
% plot
|
|
||||||
|
%% plot
|
||||||
figure('Color','w'); hold on;
|
figure('Color','w'); hold on;
|
||||||
cols = [0.6510 0.8078 0.8902;...
|
cols = [0.6510 0.8078 0.8902;...
|
||||||
0.1216 0.4706 0.7059;...
|
0.1216 0.4706 0.7059;...
|
||||||
0.6980 0.8745 0.5412;...
|
0.6980 0.8745 0.5412;...
|
||||||
0.2000 0.6275 0.1725];
|
0.2000 0.6275 0.1725];
|
||||||
|
|
||||||
% plot(lambda_nm, D_lin(1,:), '-', 'LineWidth',2, 'DisplayName','Linearized model','Color',[cols(1,:)]);
|
plot(lambda_nm, D_exact_1(1,:), 'LineWidth',2, 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
||||||
plot(lambda_nm, D_exact(1,:), 'LineWidth',2, 'DisplayName',sprintf('S_0 = 0.07'),'Color',[cols(2,:)]);
|
plot(lambda_nm, D_exact_1(2,:), 'LineWidth',2, 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
||||||
|
|
||||||
% plot(lambda_nm, D_lin(2,:), '-', 'LineWidth',2, 'HandleVisibility','off','Color',[cols(3,:)]);
|
|
||||||
plot(lambda_nm, D_exact(2,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('S_0 = 0.09'),'Color',[cols(4,:)]);
|
|
||||||
|
|
||||||
|
% plot(lambda_nm, D_exact_2(1,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
||||||
|
% plot(lambda_nm, D_exact_2(2,:), 'LineWidth',2, 'HandleVisibility','on', 'DisplayName',sprintf('$S_0=\SI{0.09}{\Dslope}$'),'Color',[0,0,0]);
|
||||||
|
|
||||||
xlabel('Wavelength $\lambda$ [nm]','Interpreter','latex');
|
xlabel('Wavelength $\lambda$ [nm]','Interpreter','latex');
|
||||||
ylabel('D($\lambda$) [ps/(nm km)]','Interpreter','latex');
|
ylabel('D($\lambda$) [ps/(nm km)]','Interpreter','latex');
|
||||||
@@ -44,3 +48,167 @@ xlim([min(lambda_nm) max(lambda_nm)])
|
|||||||
ylim([-5 5]);
|
ylim([-5 5]);
|
||||||
|
|
||||||
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\dispersion')
|
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\dispersion')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
%% plot_dispersion_dual_ZDW
|
||||||
|
% Visualizes two ZDW fiber types, each with an S0 tolerance range.
|
||||||
|
|
||||||
|
%% plot_dispersion_minimal_for_tikz
|
||||||
|
% Minimal setup for clean TikZ tuning
|
||||||
|
|
||||||
|
% 1. Parameters
|
||||||
|
lambda_nm = linspace(1240, 1360, 400);
|
||||||
|
S0_range = [0.075, 0.095];
|
||||||
|
ZDW_range = [1300, 1325];
|
||||||
|
|
||||||
|
% 2. Calculate Envelope and Nominal
|
||||||
|
[S_mesh, Z_mesh] = meshgrid(S0_range, ZDW_range);
|
||||||
|
D_all = zeros(length(lambda_nm), 4);
|
||||||
|
for i = 1:4
|
||||||
|
D_all(:,i) = (S_mesh(i)/4) .* (lambda_nm - (Z_mesh(i)^4)./(lambda_nm.^3));
|
||||||
|
end
|
||||||
|
D_env_min = min(D_all, [], 2);
|
||||||
|
D_env_max = max(D_all, [], 2);
|
||||||
|
D_nominal = (mean(S0_range)/4) .* (lambda_nm - (mean(ZDW_range)^4)./(lambda_nm.^3));
|
||||||
|
|
||||||
|
% 3. Plotting
|
||||||
|
figure('Color','w'); hold on;
|
||||||
|
env_col = [0.1216, 0.4706, 0.7059];
|
||||||
|
|
||||||
|
% Shaded area
|
||||||
|
[hl, hp] = boundedline(lambda_nm, (D_env_min+D_env_max)/2, ...
|
||||||
|
(D_env_max-D_env_min)/2, 'alpha', 'cmap', env_col);
|
||||||
|
set(hl, 'YData', D_nominal, 'Color', 'k', 'LineWidth', 1.5);
|
||||||
|
|
||||||
|
% Generate the outline and capture the handle
|
||||||
|
ho = outlinebounds(hl, hp);
|
||||||
|
|
||||||
|
% Change properties
|
||||||
|
set(ho, 'Color', 'k', ... % Make it black
|
||||||
|
'LineStyle', '--', ... % Make it dashed
|
||||||
|
'LineWidth', 0.5, ... % Make it thin
|
||||||
|
'HandleVisibility', 'off'); % Hide from legend
|
||||||
|
|
||||||
|
% 4. "Minimal" Measurement Lines (Tweak these in TikZ later)
|
||||||
|
% Vertical measurement at 1290nm
|
||||||
|
lambda_v = 1290;
|
||||||
|
[~, idx] = min(abs(lambda_nm - lambda_v));
|
||||||
|
y_bot = D_env_min(idx);
|
||||||
|
y_top = D_env_max(idx);
|
||||||
|
|
||||||
|
% Simple line - in TikZ this will be a single \draw command
|
||||||
|
line([lambda_v, lambda_v], [y_bot, y_top], 'Color', 'r', 'LineWidth', 1.2, 'Tag', 'VertArrow');
|
||||||
|
text(lambda_v + 2, (y_top+y_bot)/2, '$\Delta D$', 'Color', 'r', 'Interpreter', 'latex');
|
||||||
|
|
||||||
|
% Horizontal measurement at D=0
|
||||||
|
z1 = ZDW_range(1);
|
||||||
|
z2 = ZDW_range(2);
|
||||||
|
line([z1, z2], [0, 0], 'Color', [0.1 0.5 0.1], 'LineWidth', 1.2, 'Tag', 'HorizArrow');
|
||||||
|
text(mean(ZDW_range), 0.5, '$\Delta \lambda_0$', 'Color', [0.1 0.5 0.1], ...
|
||||||
|
'Interpreter', 'latex', 'HorizontalAlignment', 'center');
|
||||||
|
|
||||||
|
% 5. Aesthetics
|
||||||
|
xlabel('Wavelength $\lambda$ [nm]', 'Interpreter', 'latex');
|
||||||
|
ylabel('$D(\lambda)$ [ps/(nm km)]', 'Interpreter', 'latex');
|
||||||
|
grid on; box on;
|
||||||
|
xlim([1240 1360]); ylim([-5 5]);
|
||||||
|
line(xlim, [0 0], 'Color', [0.4 0.4 0.4], 'LineStyle', '--', 'HandleVisibility', 'off');
|
||||||
|
|
||||||
|
% Legend using the handles we have
|
||||||
|
legend([hp, hl], {'Worst-case Envelope', 'Nominal Realization'}, ...
|
||||||
|
'Location', 'northwest', 'Interpreter', 'latex');
|
||||||
|
|
||||||
|
% To export, run:
|
||||||
|
% matlab2tikz('dispersion.tex', 'standalone', true);
|
||||||
|
|
||||||
|
%% plot_dispersion_for_tikz
|
||||||
|
% Optimized for matlab2tikz compatibility with manual arrows
|
||||||
|
|
||||||
|
%% plot_dispersion_statistical_envelopes
|
||||||
|
% Visualizes hard spec limits vs. 98% statistical distribution
|
||||||
|
|
||||||
|
%% plot_dispersion_final_for_tikz
|
||||||
|
lambda_nm = linspace(1240, 1360, 400);
|
||||||
|
|
||||||
|
% 1. Statistical & Specification Parameters
|
||||||
|
p01_L = norminv(0.01, 1317, 2);
|
||||||
|
p99_L = norminv(0.99, 1317, 2);
|
||||||
|
p01_S = norminv(0.01, 0.0872, 0.0012);
|
||||||
|
p99_S = norminv(0.99, 0.0872, 0.0012);
|
||||||
|
|
||||||
|
% Scenarios: [ZDW_min, ZDW_max], [S0_min, S0_max], [Color RGB]
|
||||||
|
scenarios = { ...
|
||||||
|
[1303, 1325], [0.075, 0.0925], [0.6510, 0.8078, 0.8902]; ... % 1. Wide Spec (Gray)
|
||||||
|
[p01_L, p99_L], [p01_S, p99_S], [0.6, 0.6, 0.6] ... % 2. 98% Stats (Blue)
|
||||||
|
};
|
||||||
|
|
||||||
|
figure('Color','w'); hold on;
|
||||||
|
hp_handles = [];
|
||||||
|
|
||||||
|
% 2. Calculate and Plot Envelopes
|
||||||
|
for k = 1:size(scenarios, 1)
|
||||||
|
Zr = scenarios{k,1};
|
||||||
|
Sr = scenarios{k,2};
|
||||||
|
col = scenarios{k,3};
|
||||||
|
|
||||||
|
[S_mesh, Z_mesh] = meshgrid(Sr, Zr);
|
||||||
|
D_all = zeros(length(lambda_nm), 4);
|
||||||
|
for i = 1:4
|
||||||
|
D_all(:,i) = (S_mesh(i)/4) .* (lambda_nm - (Z_mesh(i)^4)./(lambda_nm.^3));
|
||||||
|
end
|
||||||
|
|
||||||
|
D_min_env = min(D_all, [], 2);
|
||||||
|
D_max_env = max(D_all, [], 2);
|
||||||
|
|
||||||
|
[hl, hp] = boundedline(lambda_nm, (D_min_env+D_max_env)/2, (D_max_env-D_min_env)/2, ...
|
||||||
|
'cmap','alpha', col);
|
||||||
|
|
||||||
|
hp_handles(k) = hp;
|
||||||
|
set(hl, 'Visible', 'off');
|
||||||
|
|
||||||
|
|
||||||
|
if k == 1
|
||||||
|
D_wide_min = D_min_env;
|
||||||
|
D_wide_max = D_max_env;
|
||||||
|
% ho = outlinebounds(hl, hp);
|
||||||
|
% % Change properties
|
||||||
|
% set(ho, 'Color', 'k', ... % Make it black
|
||||||
|
% 'LineStyle', '--', ... % Make it dashed
|
||||||
|
% 'LineWidth', 1, ... % Make it thin
|
||||||
|
% 'HandleVisibility', 'off'); % Hide from legend
|
||||||
|
% Capture Wide Spec (k=1) bounds for the TikZ measurement lines
|
||||||
|
hp.FaceAlpha = 0.5;
|
||||||
|
else
|
||||||
|
hp.FaceAlpha = 0.8;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% 3. Nominal Line
|
||||||
|
D_nom = (0.0872/4) .* (lambda_nm - (1317^4)./(lambda_nm.^3));
|
||||||
|
h_nom = plot(lambda_nm, D_nom, 'k', 'LineWidth', 1,'LineStyle','-');
|
||||||
|
|
||||||
|
% 4. Minimal Lines for TikZ (Measuring Wide Spec)
|
||||||
|
lambda_v = 1290;
|
||||||
|
[~, idx_v] = min(abs(lambda_nm - lambda_v));
|
||||||
|
% Vertical line showing full Wide Spec dispersion range at 1290nm
|
||||||
|
line([lambda_v, lambda_v], [D_wide_min(idx_v), D_wide_max(idx_v)], 'Color', 'k', 'Tag', 'VertArrow','LineWidth', 1);
|
||||||
|
% Horizontal line showing Wide Spec ZDW range at D=0
|
||||||
|
% line([1303, 1325], [0, 0], 'Color', 'k', 'Tag', 'HorizArrow','LineWidth', 1);
|
||||||
|
|
||||||
|
% 5. Aesthetics & Legend
|
||||||
|
xlabel('Wavelength $\lambda$ [nm]', 'Interpreter', 'latex');
|
||||||
|
ylabel('$D(\lambda)$ [ps/(nm km)]', 'Interpreter', 'latex');
|
||||||
|
grid on; box on;
|
||||||
|
xlim([1240 1360]); ylim([-5 5]);
|
||||||
|
|
||||||
|
leg_labels = { ...
|
||||||
|
'$\lambda_0 \in [1303, 1325], S_0 \in [0.075, 0.0925]$', ...
|
||||||
|
'$\lambda_0 \in [1312, 1322], S_0 \in [0.084, 0.090]$', ...
|
||||||
|
'$\lambda_0 = 1317, S_0 = 0.0872$'};
|
||||||
|
legend([hp_handles, h_nom], leg_labels, 'Location', 'northwest', 'Interpreter', 'latex', 'FontSize', 8);
|
||||||
|
|
||||||
|
% Export command (uncomment to use)
|
||||||
|
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\dispersion_slope.tikz')
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
%% ------------------------------------------------------------
|
||||||
|
% Contour plot: λ_null as function of bandwidth (f_target) and reach (L)
|
||||||
|
% ------------------------------------------------------------
|
||||||
|
|
||||||
|
% Parameters
|
||||||
|
lambda0 = 1310e-9; % [m]
|
||||||
|
S0 = 0.09; % [ps/(nm²·km)]
|
||||||
|
c = physconst('lightspeed');
|
||||||
|
|
||||||
|
% Sweep dimensions
|
||||||
|
f_targets = linspace(50e9, 130e9, 200); % [Hz] (x-axis)
|
||||||
|
L_values = linspace(0.5e3, 15e3, 200); % [m] (y-axis)
|
||||||
|
|
||||||
|
lambda_surface = zeros(numel(L_values), numel(f_targets));
|
||||||
|
Dacc_surface = zeros(numel(L_values), numel(f_targets));
|
||||||
|
|
||||||
|
% Outer loop over fiber length (since L must be scalar)
|
||||||
|
for iL = 1:numel(L_values)
|
||||||
|
L = L_values(iL);
|
||||||
|
[lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_targets, L, lambda0, S0);
|
||||||
|
|
||||||
|
% Store the 1x absolute offset |lambda - lambda0|
|
||||||
|
lambda_surface(iL, :) = abs(lambda0 - lambda_vec);
|
||||||
|
Dacc_surface(iL, :) = Dacc_vec;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Convert for plotting
|
||||||
|
lambda_surface_nm = lambda_surface * 1e9; % [nm]
|
||||||
|
L_km = L_values / 1000; % [km]
|
||||||
|
f_GHz = f_targets / 1e9; % [GHz]
|
||||||
|
|
||||||
|
%% Contour plot
|
||||||
|
figure('Color','w');
|
||||||
|
hold on;
|
||||||
|
|
||||||
|
% Define wavelength contour levels [nm]
|
||||||
|
% Focus on a clean range of 1x offset values
|
||||||
|
lambda_levels = unique([50:-10:30, 30:-5:5]);
|
||||||
|
|
||||||
|
% Contour plot
|
||||||
|
[C,h] = contour(f_GHz, L_km, lambda_surface_nm, lambda_levels, ...
|
||||||
|
'LineWidth', 1.2, ...
|
||||||
|
'ShowText', 'off');
|
||||||
|
|
||||||
|
% Colormap: Modern Blue palette with light colors removed for visibility
|
||||||
|
cmap_full = cbrewer2('Blues', 40);
|
||||||
|
colormap(cmap_full(10:end, :));
|
||||||
|
clim([min(lambda_levels) max(lambda_levels)]);
|
||||||
|
cb = colorbar;
|
||||||
|
ylabel(cb, '$\Delta \lambda$ [nm]', 'Interpreter', 'latex');
|
||||||
|
|
||||||
|
% --- MANUAL TEXTBOX ANNOTATIONS ---
|
||||||
|
% Find placement along the first-null curve for each level
|
||||||
|
for i = 1:length(lambda_levels)
|
||||||
|
lvl = lambda_levels(i);
|
||||||
|
|
||||||
|
% Re-calculate the specific (f, L) curve for this delta-lambda
|
||||||
|
lambda_target = lambda0 - (lvl * 1e-9);
|
||||||
|
LHS = -( (S0*1e3) / 4 ) * (lambda_target - (lambda0^4)/(lambda_target^3)) * lambda_target^2;
|
||||||
|
const_val = (c*0.5) / LHS;
|
||||||
|
|
||||||
|
f_curve_GHz = linspace(min(f_GHz), max(f_GHz), 500);
|
||||||
|
L_curve_km = const_val ./ (f_curve_GHz * 1e9).^2 / 1000;
|
||||||
|
|
||||||
|
% Filter for points within the plot axes
|
||||||
|
in_bounds = find(L_curve_km >= min(L_km)*1.1 & L_curve_km <= max(L_km)*0.9 & ...
|
||||||
|
f_curve_GHz >= min(f_GHz)*1.1 & f_curve_GHz <= max(f_GHz)*0.9);
|
||||||
|
|
||||||
|
if ~isempty(in_bounds)
|
||||||
|
% Specific alternating pattern for weight to minimize overlapping
|
||||||
|
if i < 9
|
||||||
|
weight = 0.05;
|
||||||
|
else
|
||||||
|
weight = 0.05 + 0.1 * mod(i, 2);
|
||||||
|
end
|
||||||
|
idx = in_bounds(max(1, min(length(in_bounds), round(length(in_bounds) * weight))));
|
||||||
|
|
||||||
|
text(f_curve_GHz(idx), L_curve_km(idx), sprintf('%g nm', lvl), ...
|
||||||
|
'Color', 'k', 'BackgroundColor', 'w', 'Margin', 1.5, ...
|
||||||
|
'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', ...
|
||||||
|
'EdgeColor', 'k', 'FontSize', 9);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Axis formatting
|
||||||
|
xlabel('Signal Bandwidth [GHz]', 'FontSize', 11);
|
||||||
|
ylabel('Fiber length [km]', 'FontSize', 11);
|
||||||
|
xticks(min(f_GHz):10:max(f_GHz));
|
||||||
|
yticks(min(L_km):2.5:max(L_km));
|
||||||
|
grid on; box on;
|
||||||
|
axis([min(f_GHz) max(f_GHz) min(L_km) max(L_km)]);
|
||||||
|
|
||||||
|
|
||||||
|
%% Optional: overlay accumulated-dispersion contours
|
||||||
|
if 0
|
||||||
|
hold on;
|
||||||
|
min_D = min(Dacc_surface(:), [], 'omitnan');
|
||||||
|
max_D = max(Dacc_surface(:), [], 'omitnan');
|
||||||
|
% Calculate 3 integer levels well within the data range
|
||||||
|
D_levels = unique(round(linspace(min_D*0.8, max_D*0.8, 3)));
|
||||||
|
|
||||||
|
[CS, h] = contour(f_GHz, L_km, Dacc_surface, D_levels, 'k--', 'LineWidth', 0.8);
|
||||||
|
clabel(CS, h, 'Color','k', 'FontSize',8);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
%% Export
|
||||||
|
% Hier erzwingen wir die rote Colormap für pgfplots, damit mat2tikz es nicht blau exportiert!
|
||||||
|
mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/02_IMDD_System/tikz/dispersion/dispersion_power_fading_contour2.tikz");
|
||||||
|
|
||||||
|
function [lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_target, L, lambda0, S0)
|
||||||
|
% lambda_for_first_null_full (stable, single-branch + validity checks)
|
||||||
|
% --------------------------------------------------------------------
|
||||||
|
% Computes the wavelength(s) at which the first IM/DD fading null
|
||||||
|
% occurs at frequency/ies f_target using the full dispersion model:
|
||||||
|
%
|
||||||
|
% D(lambda) = (S0/4)*(lambda - lambda0^4 / lambda^3)
|
||||||
|
%
|
||||||
|
% Restricted to the NORMAL-dispersion branch (λ < λ0),
|
||||||
|
% and valid only in the O-band (1260–1360 nm).
|
||||||
|
%
|
||||||
|
% Inputs:
|
||||||
|
% f_target - scalar or vector of target null frequencies [Hz]
|
||||||
|
% L - fiber length [m]
|
||||||
|
% lambda0 - zero-dispersion wavelength (ZDW) [m]
|
||||||
|
% S0 - dispersion slope at ZDW [ps/(nm²·km)]
|
||||||
|
%
|
||||||
|
% Outputs:
|
||||||
|
% lambda_vec - wavelength(s) [m] where first null occurs (clamped to O-band)
|
||||||
|
% Dacc_vec - accumulated dispersion(s) [ps/nm] (NaN if out of valid range)
|
||||||
|
% --------------------------------------------------------------------
|
||||||
|
|
||||||
|
c = physconst('lightspeed');
|
||||||
|
S0_si = S0 * 1e3; % ps/(nm²·km) -> s/(m³)
|
||||||
|
|
||||||
|
% Define O-band boundaries (in meters)
|
||||||
|
lambda_min = 1255e-9;
|
||||||
|
lambda_max = 1361e-9;
|
||||||
|
|
||||||
|
% Force column vector
|
||||||
|
f_target = f_target(:);
|
||||||
|
N = numel(f_target);
|
||||||
|
|
||||||
|
lambda_vec = NaN(N,1);
|
||||||
|
Dacc_vec = NaN(N,1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for k = 1:N
|
||||||
|
RHS = c * 0.5 / (f_target(k)^2 * L);
|
||||||
|
|
||||||
|
% Normal-dispersion branch (λ < λ0)
|
||||||
|
fun = @(lambda) -(S0_si/4).*(lambda - (lambda0^4)./(lambda.^3)).*lambda.^2 - RHS;
|
||||||
|
|
||||||
|
% Limit the search to [λ_min, λ0)
|
||||||
|
try
|
||||||
|
lambda_sol = fzero(fun, [lambda_min, lambda0 * 0.999]);
|
||||||
|
catch
|
||||||
|
% If the zero is not within bounds, skip this point
|
||||||
|
lambda_sol = NaN;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Validate solution
|
||||||
|
if isnan(lambda_sol) || lambda_sol < lambda_min || lambda_sol > lambda_max
|
||||||
|
lambda_vec(k) = NaN;
|
||||||
|
Dacc_vec(k) = NaN;
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
% Compute D(lambda) and accumulated dispersion
|
||||||
|
D_lambda = (S0_si/4) * (lambda_sol - (lambda0^4)/(lambda_sol^3)) / 1e-6; % ps/(nm·km)
|
||||||
|
Dacc_val = D_lambda * (L/1000); % ps/nm
|
||||||
|
|
||||||
|
% Sanity bound on dispersion (avoid unphysical > ±100 ps/nm)
|
||||||
|
if abs(Dacc_val) > 100
|
||||||
|
lambda_vec(k) = NaN;
|
||||||
|
Dacc_vec(k) = NaN;
|
||||||
|
else
|
||||||
|
lambda_vec(k) = lambda_sol;
|
||||||
|
Dacc_vec(k) = Dacc_val;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
142
Functions/Theory/Dissertation/dispersion_contour_bivariate.m
Normal file
142
Functions/Theory/Dissertation/dispersion_contour_bivariate.m
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
% Festen Betriebsparameter
|
||||||
|
lambda = 1290; % nm
|
||||||
|
L = 1; % km
|
||||||
|
mu_zwd = 1317; % nm
|
||||||
|
sigma_zwd = 2; % nm
|
||||||
|
mu_s0 = 0.0872; % ps / nm2 km
|
||||||
|
sigma_s0 = 0.0012; % ps / nm2 km
|
||||||
|
rho = -0.5; % Korrelation
|
||||||
|
|
||||||
|
% Gitter für lambda0 und S0
|
||||||
|
lambda0_vec = linspace(mu_zwd-10, mu_zwd+10, 100);
|
||||||
|
S0_vec = linspace(mu_s0-0.01, mu_s0+0.01, 100);
|
||||||
|
|
||||||
|
% Korrigierte meshgrid Reihenfolge
|
||||||
|
[S0, Lambda0] = meshgrid(S0_vec, lambda0_vec);
|
||||||
|
|
||||||
|
% Dispersion berechnen
|
||||||
|
D = (S0./4) .* ( lambda - (Lambda0.^4)./(lambda^3) ) * L;
|
||||||
|
|
||||||
|
% 2D Verteilung (Bivariate Gauss) berechnen
|
||||||
|
Z_x = (S0 - mu_s0) / sigma_s0;
|
||||||
|
Z_y = (Lambda0 - mu_zwd) / sigma_zwd;
|
||||||
|
PDF_2D = exp(-1 / (2 * (1 - rho^2)) * (Z_x.^2 - 2 * rho .* Z_x .* Z_y + Z_y.^2));
|
||||||
|
|
||||||
|
%% Plot zusammenbauen
|
||||||
|
figure('Color','w');
|
||||||
|
hold on % EINZIGES hold on für den gesamten Plot!
|
||||||
|
|
||||||
|
% --- 1. ZUERST: 2D Verteilung (Bivariate Gauss) "ganz unten" ---
|
||||||
|
numLevels_2D = 6;
|
||||||
|
colors_2D = cbrewer2('Greys', numLevels_2D+0);
|
||||||
|
colors_2D = colors_2D(1:numLevels_2D,:);
|
||||||
|
% Nur die Anzahl der Level übergeben!
|
||||||
|
[C2, h2] = contourf(S0, Lambda0, PDF_2D, numLevels_2D);
|
||||||
|
h2.HandleVisibility='off';
|
||||||
|
% Colormap für die rote Fläche setzen
|
||||||
|
|
||||||
|
colormap(gcf, colors_2D(1:end,:));
|
||||||
|
try
|
||||||
|
clim([min(PDF_2D(:)), max(PDF_2D(:))]);
|
||||||
|
catch
|
||||||
|
caxis([min(PDF_2D(:)), max(PDF_2D(:))]);
|
||||||
|
end
|
||||||
|
|
||||||
|
h2.EdgeColor = 'none'; % Keine schwarzen Ränder
|
||||||
|
|
||||||
|
% --- 2. DARÜBER: Dispersions-Konturlinien ---
|
||||||
|
numLevels_D = 9;
|
||||||
|
% Erzeuge glatte, auf 1 Nachkommastelle gerundete Werte
|
||||||
|
levels_D = round(linspace(min(D(:)), max(D(:)), numLevels_D), 1);
|
||||||
|
levels_D = unique(levels_D);
|
||||||
|
cmap_bg = flip(cbrewer2('Blues', length(levels_D)+3));
|
||||||
|
|
||||||
|
for i = 1:length(levels_D)
|
||||||
|
% Konturlinien zeichnen (explizit Schwarz)
|
||||||
|
[C,h] = contour(S0, Lambda0, D, [levels_D(i), levels_D(i)], ...
|
||||||
|
'Color', cmap_bg(i,:),...
|
||||||
|
'LineWidth', 1, ...
|
||||||
|
'ShowText', 'off','handlevisibility','off');
|
||||||
|
if i == 1
|
||||||
|
h.HandleVisibility='on';
|
||||||
|
h.DisplayName='$D(\lambda=1290)$';
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- 3. MANUELLE TEXTBOXEN AUF DEN LINIEN ---
|
||||||
|
% Wähle eine feste S0-Position für alle Beschriftungen (z.B. bei 0.082)
|
||||||
|
S0_label = 0.095;
|
||||||
|
|
||||||
|
for i = 1:length(levels_D)
|
||||||
|
% Berechne exakte ZDW (Y-Koordinate) durch Umstellen der D-Formel:
|
||||||
|
% Lambda0 = (lambda^3 * (lambda - 4*D / (S0 * L)))^(1/4)
|
||||||
|
zdw_label = (lambda^3 * (lambda - 4*levels_D(i) / (S0_label * L)))^0.25;
|
||||||
|
|
||||||
|
% Nur zeichnen, wenn der Punkt auch im sichtbaren Plot-Bereich liegt
|
||||||
|
if zdw_label >= min(lambda0_vec) && zdw_label <= max(lambda0_vec)
|
||||||
|
text(S0_label, zdw_label, sprintf('%0.1f', levels_D(i)), ...
|
||||||
|
'Color', 'k', ...
|
||||||
|
'BackgroundColor', 'w', ... % Weiße Box überdeckt die schwarze Linie!
|
||||||
|
'Margin', 2, ... % Abstand der Box zum Text
|
||||||
|
'HorizontalAlignment', 'center', ...
|
||||||
|
'VerticalAlignment', 'middle', ...
|
||||||
|
'FontSize', 10);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- 3. GANZ OBEN: Randverteilungen (1D Gauss) an den Achsen ---
|
||||||
|
% S0 Verteilung (unten)
|
||||||
|
s0_vals = linspace(min(S0_vec), max(S0_vec), 500);
|
||||||
|
gauss_s0 = exp(-0.5*((s0_vals - mu_s0)/sigma_s0).^2);
|
||||||
|
scale_s0 = 4;
|
||||||
|
y_s0_base = min(lambda0_vec);
|
||||||
|
plot(s0_vals, y_s0_base + gauss_s0 * scale_s0, 'LineWidth', 1,'LineStyle','--','DisplayName','$S_0$','Color',[0,0,0],'HandleVisibility','off');
|
||||||
|
% ANNOTATION S0: Automatisch platziert leicht über dem Peak
|
||||||
|
str_s0 = sprintf('\\mu_{S0} = %.4f\n\\sigma_{S0} = %.4f', mu_s0, sigma_s0);
|
||||||
|
text(0.0915,1308, str_s0, ...
|
||||||
|
'Interpreter', 'tex', ...
|
||||||
|
'HorizontalAlignment', 'left', ... % Entspricht 'right' in TikZ
|
||||||
|
'VerticalAlignment', 'middle', ...
|
||||||
|
'BackgroundColor', 'w', ... % Entspricht 'fill=white'
|
||||||
|
'EdgeColor', 'k', ... % Entspricht 'draw=black'
|
||||||
|
'Margin', 1, ... % Entspricht 'inner sep=1pt'
|
||||||
|
'FontSize', 10);
|
||||||
|
|
||||||
|
% ZDW Verteilung (links)
|
||||||
|
% ZDW Verteilung (links)
|
||||||
|
zwd_vals = linspace(min(lambda0_vec), max(lambda0_vec), 500);
|
||||||
|
gauss_zwd = exp(-0.5*((zwd_vals - mu_zwd)/sigma_zwd).^2);
|
||||||
|
scale_zwd = 0.005;
|
||||||
|
x_zwd_base = min(S0_vec);
|
||||||
|
plot(x_zwd_base + gauss_zwd * scale_zwd, zwd_vals, 'LineWidth', 1,'LineStyle','--','DisplayName','ZDW','Color',[0,0,0],'HandleVisibility','off');
|
||||||
|
|
||||||
|
% ANNOTATION ZDW: Automatisch platziert leicht rechts neben dem Peak
|
||||||
|
str_zwd = sprintf('\\mu_{ZDW} = %.1f\n\\sigma_{ZDW} = %.1f', mu_zwd, sigma_zwd);
|
||||||
|
text(0.079,1312, str_zwd, ...
|
||||||
|
'Interpreter', 'tex', ...
|
||||||
|
'HorizontalAlignment', 'left', ... % Entspricht 'right' in TikZ
|
||||||
|
'VerticalAlignment', 'middle', ...
|
||||||
|
'BackgroundColor', 'w', ... % Entspricht 'fill=white'
|
||||||
|
'EdgeColor', 'k', ... % Entspricht 'draw=black'
|
||||||
|
'Margin', 1, ... % Entspricht 'inner sep=1pt'
|
||||||
|
'FontSize', 10);
|
||||||
|
|
||||||
|
% Hilfslinien für die Mittelwerte
|
||||||
|
% xline(mu_s0,'LineWidth',0.5,'HandleVisibility','off','LineStyle',':');
|
||||||
|
% yline(mu_zwd,'LineWidth',0.5,'HandleVisibility','off','LineStyle',':');
|
||||||
|
|
||||||
|
% --- Achsenbeschriftung, Titel & Formatierung ---
|
||||||
|
xlabel('$S_0$ [$\nicefrac{\text{ps}}{(\text{nm}^2\text{ km})}$]', 'FontSize', 12);
|
||||||
|
ylabel('ZDW [nm]', 'FontSize', 12);
|
||||||
|
% title(sprintf('Dispersion: %d km; %d nm', L, lambda), 'FontSize', 14);
|
||||||
|
|
||||||
|
grid on
|
||||||
|
% Exakte Begrenzung, damit die Randverteilungen bündig anliegen
|
||||||
|
axis([min(S0_vec) max(S0_vec) min(lambda0_vec) max(lambda0_vec)]);
|
||||||
|
|
||||||
|
% legend;
|
||||||
|
hold off % EINZIGES hold off ganz am Ende!
|
||||||
|
|
||||||
|
%% Export
|
||||||
|
% Hier erzwingen wir die rote Colormap für pgfplots, damit mat2tikz es nicht blau exportiert!
|
||||||
|
mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/02_IMDD_System/tikz/dispersion/dispersion_contour_bi2.tikz");
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
%% ============================================================
|
|
||||||
% SNR vs Optical Input Power (dBm) — Shot vs Thermal vs Combined
|
|
||||||
% - Generate optical field as sine with target RMS power (verified)
|
|
||||||
% - Magnitude-square detection -> optical power
|
|
||||||
% - Photocurrent = Rd * P
|
|
||||||
% - Add shot noise + thermal noise (white, PSD-based)
|
|
||||||
% - Compute SNR for: shot-only, thermal-only, combined
|
|
||||||
% ============================================================
|
|
||||||
|
|
||||||
|
|
||||||
% Constants
|
|
||||||
k = Constant.Boltzmann;
|
|
||||||
q = Constant.ElementaryCharge;
|
|
||||||
|
|
||||||
% Receiver / PD parameters
|
|
||||||
T = 20 + 273.15; % K
|
|
||||||
R = 50; % Ohm (front-end/load)
|
|
||||||
Rd = 0.7; % A/W (responsivity)
|
|
||||||
Be = 100e9; % Hz (electrical noise bandwidth)
|
|
||||||
Id = 0; % A (dark current, optional)
|
|
||||||
|
|
||||||
% Sampling for time-domain demo (needs to be >> Be)
|
|
||||||
fs = 1e12; % Hz
|
|
||||||
N = 2^14; % samples
|
|
||||||
t = (0:N-1).'/fs;
|
|
||||||
|
|
||||||
% Choose an electrical tone within bandwidth (arbitrary for demo)
|
|
||||||
f0 = 10e9; % Hz
|
|
||||||
|
|
||||||
% Thermal current PSD (two-sided) and variance in Be
|
|
||||||
Si_th = 4*k*T/R; % A^2/Hz (two-sided)
|
|
||||||
sigma2_th = Si_th * Be; % A^2
|
|
||||||
sigma_th = sqrt(sigma2_th); % A_rms
|
|
||||||
|
|
||||||
% Optical input power sweep (in dBm)
|
|
||||||
P_dBm = linspace(-40, 10, 300);
|
|
||||||
P_W = 10.^((P_dBm - 30)/10); % W
|
|
||||||
|
|
||||||
% Pre-allocate results
|
|
||||||
SNR_shot_dB = zeros(size(P_dBm));
|
|
||||||
SNR_th_dB = zeros(size(P_dBm));
|
|
||||||
SNR_tot_dB = zeros(size(P_dBm));
|
|
||||||
|
|
||||||
% --- Main loop over optical input power
|
|
||||||
for ii = 1:numel(P_W)
|
|
||||||
Pavg = P_W(ii);
|
|
||||||
|
|
||||||
% Optical field with RMS power = Pavg:
|
|
||||||
% Let x(t) be the optical field amplitude such that |x|^2 has mean Pavg.
|
|
||||||
% Use a sinusoid: x(t) = A*sin(2*pi*f0*t), then mean(|x|^2)=A^2/2.
|
|
||||||
A = sqrt(2*Pavg); % -> mean(|x|^2) = Pavg
|
|
||||||
|
|
||||||
x = A * sin(2*pi*f0*t); % "optical field" (real for simplicity)
|
|
||||||
|
|
||||||
% Verify RMS/mean power numerically (optional)
|
|
||||||
P_meas = mean(abs(x).^2); % should be ~ Pavg
|
|
||||||
|
|
||||||
a = P_meas - Pavg;
|
|
||||||
assert(a<1);
|
|
||||||
|
|
||||||
% Magnitude-square detection -> optical power waveform
|
|
||||||
Popt = abs(x).^2; % W (instantaneous)
|
|
||||||
|
|
||||||
% Photocurrent waveform (includes DC + 2f0 component for this demo)
|
|
||||||
I_sig = Rd * Popt; % A
|
|
||||||
|
|
||||||
% Define "signal power" as the mean-squared photocurrent due to signal
|
|
||||||
% (for this sine-squared waveform, it's OK for a demo SNR definition)
|
|
||||||
P_sig = mean(I_sig.^2);
|
|
||||||
|
|
||||||
% -------- Shot noise (white) --------
|
|
||||||
% Two-sided PSD: Si_shot = 2*q*(I_photo + I_dark)
|
|
||||||
% For this demo, use average current to set the white-noise level:
|
|
||||||
Ibar = mean(I_sig) + Id;
|
|
||||||
Si_shot = 2*q*Ibar; % A^2/Hz
|
|
||||||
sigma2_sh = Si_shot * Be; % A^2
|
|
||||||
sigma_sh = sqrt(sigma2_sh); % A_rms
|
|
||||||
|
|
||||||
n_sh = sigma_sh * randn(N,1); % time-domain shot noise
|
|
||||||
|
|
||||||
% -------- Thermal noise (white Gaussian) --------
|
|
||||||
n_th = sigma_th * randn(N,1); % time-domain thermal noise
|
|
||||||
|
|
||||||
% Noise powers (mean-square) in time domain
|
|
||||||
Pn_sh = mean(n_sh.^2);
|
|
||||||
Pn_th = mean(n_th.^2);
|
|
||||||
Pn_tot = mean((n_sh + n_th).^2); % ~ Pn_sh + Pn_th (independent)
|
|
||||||
|
|
||||||
% SNRs
|
|
||||||
SNR_shot = P_sig / Pn_sh;
|
|
||||||
SNR_th = P_sig / Pn_th;
|
|
||||||
SNR_tot = P_sig / Pn_tot;
|
|
||||||
|
|
||||||
SNR_shot_dB(ii) = 10*log10(SNR_shot);
|
|
||||||
SNR_th_dB(ii) = 10*log10(SNR_th);
|
|
||||||
SNR_tot_dB(ii) = 10*log10(SNR_tot);
|
|
||||||
|
|
||||||
% Optional sanity check (can comment out)
|
|
||||||
% if ii == 1
|
|
||||||
% fprintf('Check Pavg target/meas: %.3g W / %.3g W\n', Pavg, P_meas);
|
|
||||||
% end
|
|
||||||
end
|
|
||||||
|
|
||||||
% Plot comparison
|
|
||||||
figure(1); clf; hold on;
|
|
||||||
plot(P_dBm, SNR_shot_dB, 'LineWidth', 1.5);
|
|
||||||
plot(P_dBm, SNR_th_dB, 'LineWidth', 1.5);
|
|
||||||
plot(P_dBm, SNR_tot_dB, 'LineWidth', 1.5);
|
|
||||||
grid on;
|
|
||||||
xlabel('Optical input power [dBm]');
|
|
||||||
ylabel('SNR [dB]');
|
|
||||||
title('SNR vs Optical Input Power: Shot vs Thermal vs Combined');
|
|
||||||
legend('Shot-noise only','Thermal-noise only','Shot + Thermal','Location','best');
|
|
||||||
|
|
||||||
% Print example at 0 dBm
|
|
||||||
[~,idx0] = min(abs(P_dBm - 0));
|
|
||||||
fprintf('At 0 dBm:\n');
|
|
||||||
fprintf(' SNR (shot only) = %.2f dB\n', SNR_shot_dB(idx0));
|
|
||||||
fprintf(' SNR (thermal only) = %.2f dB\n', SNR_th_dB(idx0));
|
|
||||||
fprintf(' SNR (combined) = %.2f dB\n', SNR_tot_dB(idx0));
|
|
||||||
|
|
||||||
% Also print NEP based on thermal PSD (constant NEP_th)
|
|
||||||
NEP_th = sqrt(Si_th)/Rd; % W/sqrt(Hz)
|
|
||||||
fprintf('Thermal NEP = %.3g W/sqrt(Hz)\n', NEP_th);
|
|
||||||
@@ -17,8 +17,8 @@ D_si = D_lambda * 1e-6; % → s/m²
|
|||||||
b2 = -D_si * lambda^2 / (2*pi*c); % s²/m
|
b2 = -D_si * lambda^2 / (2*pi*c); % s²/m
|
||||||
|
|
||||||
%% Frequency grid
|
%% Frequency grid
|
||||||
f_max = 150e9;
|
f_max = 200e9;
|
||||||
f = linspace(0, f_max, 4000); % [Hz]
|
f = linspace(0, f_max, 5000); % [Hz]
|
||||||
|
|
||||||
%% IM/DD transfer function (power fading)
|
%% IM/DD transfer function (power fading)
|
||||||
phi = 2*pi^2 * b2 * f.^2 * L;
|
phi = 2*pi^2 * b2 * f.^2 * L;
|
||||||
@@ -26,17 +26,22 @@ H = abs(cos(phi));
|
|||||||
|
|
||||||
%% Plot
|
%% Plot
|
||||||
figure('Color','w');
|
figure('Color','w');
|
||||||
plot(f/1e9, 10*log10(H), 'LineWidth', 1.8,'Color','black');
|
plot(f/1e9, 10*log10(H), 'LineWidth', 1,'Color','black');
|
||||||
grid on; box on;
|
grid on; box on;
|
||||||
xlabel('Frequency [GHz]');
|
xlabel('Frequency [GHz]');
|
||||||
ylabel('Magnitude [dB]');
|
ylabel('Magnitude [dB]');
|
||||||
% title(sprintf('IM/DD Power Fading: 10 km; 1275nm', lambda*1e9, L/1000),"Interpreter","latex");
|
% title(sprintf('IM/DD Power Fading: 10 km; 1275nm', lambda*1e9, L/1000),"Interpreter","latex");
|
||||||
ylim([-30 0]);
|
ylim([-20 0]);
|
||||||
|
|
||||||
%% Mark analytic first-null frequency
|
%% Mark analytic null frequencies up to order 5
|
||||||
f_null = sqrt(c*(0.5)/(abs(D_si)*lambda^2*L));
|
max_order = 3;
|
||||||
xline(f_null/1e9, 'r--', 'LineWidth', 1.2, ...
|
for n = 0:max_order
|
||||||
'Label', sprintf('f_{null}=%.1f GHz', f_null/1e9), ...
|
f_null_n = sqrt( c*(2*n + 1)/(2*abs(D_si)*lambda^2*L) );
|
||||||
'LabelOrientation', 'horizontal', 'LabelVerticalAlignment', 'bottom');
|
xline(f_null_n/1e9, '--', 'LineWidth', 1.2, ...
|
||||||
|
'Color', [0.1216, 0.4706, 0.7059]);
|
||||||
|
text(f_null_n/1e9, -15, sprintf('$f_{\\mathrm{null}, %d}=%.1f$ GHz', n, f_null_n/1e9), ...
|
||||||
|
'BackgroundColor', 'w', 'EdgeColor', 'k', 'Interpreter', 'latex', ...
|
||||||
|
'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle');
|
||||||
|
end
|
||||||
|
|
||||||
mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\power_fading.tikz')
|
% mat2tikz_improved('C:\Users\Silas\Documents\6971e0b65b380ca6d71c837f\02_IMDD_System\tikz\dispersion\power_fading.tikz')
|
||||||
@@ -1,55 +1,77 @@
|
|||||||
% Gitter für lambda0 und S0
|
|
||||||
lambda0_vec = linspace(1260,1360,200);
|
|
||||||
S0_vec = linspace(0.06,0.1,200);
|
|
||||||
[Lambda0, S0] = meshgrid(lambda0_vec, S0_vec);
|
|
||||||
|
|
||||||
% Festen Betriebsparameter
|
% Festen Betriebsparameter
|
||||||
lambda = 1293; % nm
|
lambda = 1290; % nm
|
||||||
L = 1; % km
|
L = 1; % km
|
||||||
|
|
||||||
% Dispersion berechnen (lineare Näherung)
|
mu_zwd = 1317; % nm
|
||||||
D = S0 .* ( lambda - Lambda0 ) * L;
|
sigma_zwd = 2; % nm
|
||||||
|
mu_s0 = 0.0872; % ps / nm2 km
|
||||||
|
sigma_s0 = 0.0012; % ps / nm2 km
|
||||||
|
rho = -0.5; % Korrelation
|
||||||
|
|
||||||
|
% Gitter für lambda0 und S0
|
||||||
|
lambda0_vec = linspace(mu_zwd-10, mu_zwd+10, 100);
|
||||||
|
S0_vec = linspace(mu_s0-0.01, mu_s0+0.01, 100);
|
||||||
|
|
||||||
|
% Korrigierte meshgrid Reihenfolge
|
||||||
|
[S0, Lambda0] = meshgrid(S0_vec, lambda0_vec);
|
||||||
|
|
||||||
|
% Dispersion berechnen
|
||||||
D = (S0./4) .* ( lambda - (Lambda0.^4)./(lambda^3) ) * L;
|
D = (S0./4) .* ( lambda - (Lambda0.^4)./(lambda^3) ) * L;
|
||||||
|
|
||||||
%% 2D-Konturplot nur mit Linien und Text
|
%% 2D-Konturplot
|
||||||
figure('Color','w');
|
figure('Color','w');
|
||||||
hold on
|
hold on
|
||||||
|
|
||||||
% Konturlinien
|
% --- 1. Hintergrund: Dispersions-Konturlinien (Gerundet für TikZ) ---
|
||||||
numLevels = 10;
|
numLevels_D = 10;
|
||||||
levels = linspace(min(D(:)), max(D(:)), numLevels);
|
% Erzeuge glatte, auf 1 Nachkommastelle gerundete Werte
|
||||||
[C,h] = contour(S0, Lambda0, D, levels, ...
|
|
||||||
'LineWidth',1.5, ...
|
|
||||||
'ShowText','on', ...
|
|
||||||
'LabelFormat','%0.1f');
|
|
||||||
|
|
||||||
% cbrewer2-Colormap für die Linien
|
levels_D = round(linspace(min(D(:)), max(D(:)), numLevels_D), 1);
|
||||||
cmap = cbrewer2('div','RdYlGn', numLevels);
|
levels_D = unique(levels_D); % Falls durch Rundung doppelte Werte entstehen
|
||||||
colormap(cmap);
|
|
||||||
|
|
||||||
% Achsenlinien
|
% Colormap in der Länge der verbliebenen Level erstellen
|
||||||
% yline(1310, '--k','ZDW_{mean}','LabelVerticalAlignment','top','LabelHorizontalAlignment','center');
|
cmap_bg = cbrewer2('Blues', length(levels_D));
|
||||||
x0 = 0.09;
|
|
||||||
% xline(x0, '--k','S_{0}','LabelHorizontalAlignment','left');
|
|
||||||
|
|
||||||
% Gaussian auf der x-Linie (S0 = 0.09)
|
for i = 1:length(levels_D)
|
||||||
mu_zwd = 1310; % nm
|
% WICHTIG: Das Level als [Wert, Wert] übergeben!
|
||||||
|
[C,h] = contour(S0, Lambda0, D, [levels_D(i), levels_D(i)], ...
|
||||||
|
'Color', cmap_bg(i,:),...
|
||||||
|
'LineWidth', 1.5, ...
|
||||||
|
'ShowText', 'on', ...
|
||||||
|
'LabelFormat', '%0.1f');
|
||||||
|
h.LabelColor = [0,0,0];
|
||||||
|
end
|
||||||
|
|
||||||
|
% --- NEU: Parameter für die Verteilungen ---
|
||||||
|
mu_zwd = 1317; % nm
|
||||||
sigma_zwd = 2; % nm
|
sigma_zwd = 2; % nm
|
||||||
|
mu_s0 = 0.0872; % ps / nm2 km
|
||||||
|
sigma_s0 = 0.0012; % ps / nm2 km
|
||||||
|
rho = -0.5; % Korrelation
|
||||||
|
|
||||||
|
% --- 3. Randverteilungen (1D Gauss) an den Achsen ---
|
||||||
|
s0_vals = linspace(min(S0_vec), max(S0_vec), 500);
|
||||||
|
gauss_s0 = exp(-0.5*((s0_vals - mu_s0)/sigma_s0).^2);
|
||||||
|
scale_s0 = 4; % Skalierung für die Höhe in der Ansicht
|
||||||
|
plot(s0_vals, min(lambda0_vec) + gauss_s0 * scale_s0, 'k', 'LineWidth', 2);
|
||||||
|
|
||||||
zwd_vals = linspace(min(lambda0_vec), max(lambda0_vec), 500);
|
zwd_vals = linspace(min(lambda0_vec), max(lambda0_vec), 500);
|
||||||
% PDF berechnen
|
gauss_zwd = exp(-0.5*((zwd_vals - mu_zwd)/sigma_zwd).^2);
|
||||||
gauss_pdf = (1/(sigma_zwd*sqrt(2*pi))) * exp(-0.5*((zwd_vals-mu_zwd)/sigma_zwd).^2);
|
scale_zwd = 0.005; % Skalierung für die Auslenkung in der Ansicht
|
||||||
% Normieren und auf eine sichtbare Breite skalieren
|
plot(min(S0_vec) + gauss_zwd * scale_zwd, zwd_vals, 'k', 'LineWidth', 2);
|
||||||
scale = 0.005; % passt die Maximal-Auslenkung in x-Richtung an
|
|
||||||
x_gauss = x0 + (gauss_pdf/max(gauss_pdf)) * scale;
|
|
||||||
|
|
||||||
% Plot
|
% Hilfslinien für die Mittelwerte
|
||||||
% plot(x_gauss, zwd_vals, 'LineWidth',2);
|
xline(mu_s0, '--k', 'Alpha', 0.4);
|
||||||
|
yline(mu_zwd, '--k', 'Alpha', 0.4);
|
||||||
|
|
||||||
% Achsenbeschriftung & Titel
|
% --- Achsenbeschriftung, Titel & Formatierung ---
|
||||||
% Achsenbeschriftung & Titel
|
xlabel('S0 ', 'FontSize', 12);
|
||||||
xlabel('S0 [ps / nm2 km]', 'FontSize', 12);
|
|
||||||
ylabel('ZDW [nm]', 'FontSize', 12);
|
ylabel('ZDW [nm]', 'FontSize', 12);
|
||||||
title (sprintf('Dispersion: %d km; %d nm', L, lambda), 'FontSize', 14);
|
% title(sprintf('Dispersion: %d km; %d nm', L, lambda), 'FontSize', 14);
|
||||||
|
|
||||||
|
axis([min(S0_vec) max(S0_vec) min(lambda0_vec) max(lambda0_vec)]);
|
||||||
grid on
|
grid on
|
||||||
hold off
|
hold off
|
||||||
|
|
||||||
|
%% Für den LaTeX Export
|
||||||
|
mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/02_IMDD_System/tikz/dispersion/dispersion_contour.tikz")
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
%% ------------------------------------------------------------
|
|
||||||
% Contour plot: λ_null as function of bandwidth (f_target) and reach (L)
|
|
||||||
% ------------------------------------------------------------
|
|
||||||
|
|
||||||
% Parameters
|
|
||||||
lambda0 = 1310e-9; % [m]
|
|
||||||
S0 = 0.08; % [ps/(nm²·km)]
|
|
||||||
c = physconst('lightspeed');
|
|
||||||
|
|
||||||
% Sweep dimensions
|
|
||||||
f_targets = linspace(50e9, 120e9, 100); % [Hz] (x-axis)
|
|
||||||
L_values = linspace(0.5e3, 10e3, 100); % [m] (y-axis)
|
|
||||||
|
|
||||||
lambda_surface = zeros(numel(L_values), numel(f_targets));
|
|
||||||
Dacc_surface = zeros(numel(L_values), numel(f_targets));
|
|
||||||
|
|
||||||
% Outer loop over fiber length (since L must be scalar)
|
|
||||||
for iL = 1:numel(L_values)
|
|
||||||
L = L_values(iL);
|
|
||||||
[lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_targets, L, lambda0, S0);
|
|
||||||
lambda_vec = 2*abs(lambda0 - lambda_vec);
|
|
||||||
|
|
||||||
if 0
|
|
||||||
fprintf('\n- %d km ------------------------------------\n',L);
|
|
||||||
fprintf(' f_null [GHz] lambda [nm] Dacc [ps/nm]\n');
|
|
||||||
fprintf('----------------------------------------------\n');
|
|
||||||
fprintf('%10.1f %8.2f %+8.3f\n',[f_targets(:)/1e9, lambda_vec(:)*1e9, Dacc_vec(:)].');
|
|
||||||
fprintf('----------------------------------------------\n\n');
|
|
||||||
end
|
|
||||||
|
|
||||||
lambda_surface(iL, :) = lambda_vec; % λ for each f_target
|
|
||||||
Dacc_surface(iL, :) = Dacc_vec; % corresponding accumulated dispersion
|
|
||||||
end
|
|
||||||
|
|
||||||
% Convert for plotting
|
|
||||||
lambda_surface_nm = lambda_surface * 1e9; % [nm]
|
|
||||||
L_km = L_values / 1000; % [km]
|
|
||||||
f_GHz = f_targets / 1e9; % [GHz]
|
|
||||||
|
|
||||||
%% Contour plot
|
|
||||||
figure('Color','w');
|
|
||||||
|
|
||||||
% Define wavelength contour levels [nm]
|
|
||||||
lambda_levels = [1260:10:1290, 1290:5:1300, 1300:2.5:1310];
|
|
||||||
lambda_levels = [100:-20:50, 50:-10:30,30:-5:0];
|
|
||||||
|
|
||||||
% Contour plot
|
|
||||||
contour(f_GHz, L_km, lambda_surface_nm, lambda_levels, ...
|
|
||||||
'LineWidth', 1.5, ...
|
|
||||||
'ShowText', 'on', ...
|
|
||||||
'LabelFormat', '%.0f nm');
|
|
||||||
|
|
||||||
% Colormap and colorbar
|
|
||||||
colormap((cbrewer2('RdYlGn',100)));
|
|
||||||
colorbar;
|
|
||||||
clim([0 100]);
|
|
||||||
|
|
||||||
% Axis formatting
|
|
||||||
xlabel('Signal Bandwidth [GHz]');
|
|
||||||
ylabel('Fiber length [km]');
|
|
||||||
legend('$\Delta \lambda$')
|
|
||||||
|
|
||||||
% X-axis ticks at 56 : 16 : 150 GHz
|
|
||||||
xticks(56:8:150);
|
|
||||||
|
|
||||||
grid on; box on;
|
|
||||||
|
|
||||||
|
|
||||||
%% Optional: overlay accumulated-dispersion contours
|
|
||||||
if 0
|
|
||||||
hold on;
|
|
||||||
[CS, h] = contour(f_GHz, L_km, Dacc_surface, 10, 'k--', 'LineWidth', 0.8);
|
|
||||||
clabel(CS, h, 'Color','k', 'FontSize',8);
|
|
||||||
end
|
|
||||||
|
|
||||||
function [lambda_vec, Dacc_vec] = lambda_for_first_null_full(f_target, L, lambda0, S0)
|
|
||||||
% lambda_for_first_null_full (stable, single-branch + validity checks)
|
|
||||||
% --------------------------------------------------------------------
|
|
||||||
% Computes the wavelength(s) at which the first IM/DD fading null
|
|
||||||
% occurs at frequency/ies f_target using the full dispersion model:
|
|
||||||
%
|
|
||||||
% D(lambda) = (S0/4)*(lambda - lambda0^4 / lambda^3)
|
|
||||||
%
|
|
||||||
% Restricted to the NORMAL-dispersion branch (λ < λ0),
|
|
||||||
% and valid only in the O-band (1260–1360 nm).
|
|
||||||
%
|
|
||||||
% Inputs:
|
|
||||||
% f_target - scalar or vector of target null frequencies [Hz]
|
|
||||||
% L - fiber length [m]
|
|
||||||
% lambda0 - zero-dispersion wavelength (ZDW) [m]
|
|
||||||
% S0 - dispersion slope at ZDW [ps/(nm²·km)]
|
|
||||||
%
|
|
||||||
% Outputs:
|
|
||||||
% lambda_vec - wavelength(s) [m] where first null occurs (clamped to O-band)
|
|
||||||
% Dacc_vec - accumulated dispersion(s) [ps/nm] (NaN if out of valid range)
|
|
||||||
% --------------------------------------------------------------------
|
|
||||||
|
|
||||||
c = physconst('lightspeed');
|
|
||||||
S0_si = S0 * 1e3; % ps/(nm²·km) -> s/(m³)
|
|
||||||
|
|
||||||
% Define O-band boundaries (in meters)
|
|
||||||
lambda_min = 1255e-9;
|
|
||||||
lambda_max = 1361e-9;
|
|
||||||
|
|
||||||
% Force column vector
|
|
||||||
f_target = f_target(:);
|
|
||||||
N = numel(f_target);
|
|
||||||
|
|
||||||
lambda_vec = NaN(N,1);
|
|
||||||
Dacc_vec = NaN(N,1);
|
|
||||||
|
|
||||||
for k = 1:N
|
|
||||||
RHS = c * 0.5 / (f_target(k)^2 * L);
|
|
||||||
|
|
||||||
% Normal-dispersion branch (λ < λ0)
|
|
||||||
fun = @(lambda) -(S0_si/4).*(lambda - (lambda0^4)./(lambda.^3)).*lambda.^2 - RHS;
|
|
||||||
|
|
||||||
% Limit the search to [λ_min, λ0)
|
|
||||||
try
|
|
||||||
lambda_sol = fzero(fun, [lambda_min, lambda0 * 0.999]);
|
|
||||||
catch
|
|
||||||
% If the zero is not within bounds, skip this point
|
|
||||||
lambda_sol = NaN;
|
|
||||||
end
|
|
||||||
|
|
||||||
% Validate solution
|
|
||||||
if isnan(lambda_sol) || lambda_sol < lambda_min || lambda_sol > lambda_max
|
|
||||||
lambda_vec(k) = NaN;
|
|
||||||
Dacc_vec(k) = NaN;
|
|
||||||
continue
|
|
||||||
end
|
|
||||||
|
|
||||||
% Compute D(lambda) and accumulated dispersion
|
|
||||||
D_lambda = (S0_si/4) * (lambda_sol - (lambda0^4)/(lambda_sol^3)) / 1e-6; % ps/(nm·km)
|
|
||||||
Dacc_val = D_lambda * (L/1000); % ps/nm
|
|
||||||
|
|
||||||
% Sanity bound on dispersion (avoid unphysical > ±100 ps/nm)
|
|
||||||
if abs(Dacc_val) > 100
|
|
||||||
lambda_vec(k) = NaN;
|
|
||||||
Dacc_vec(k) = NaN;
|
|
||||||
else
|
|
||||||
lambda_vec(k) = lambda_sol;
|
|
||||||
Dacc_vec(k) = Dacc_val;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -5,19 +5,34 @@ arguments
|
|||||||
end
|
end
|
||||||
cleanfigure;
|
cleanfigure;
|
||||||
matlab2tikz(char(filename), ...
|
matlab2tikz(char(filename), ...
|
||||||
'width','\fwidth', ...
|
'width', '\fwidth', ...
|
||||||
'height','\fheight', ...
|
'height', '\fheight', ...
|
||||||
'showInfo',false, ...
|
'showInfo', false, ...
|
||||||
'extraAxisOptions',{ ...
|
'extraAxisOptions', { ...
|
||||||
'legend style={font=\footnotesize}', ...
|
'xlabel style={font=\color{white!15!black}\small}', ...
|
||||||
'xlabel style={font=\color{white!15!black},font=\small},',...
|
'ylabel style={font=\color{white!15!black}\small}', ...
|
||||||
'ylabel style={font=\color{white!15!black},font=\small},',...
|
'scaled ticks=false', ...
|
||||||
|
'tick label style={/pgf/number format/fixed, /pgf/number format/1000 sep={}}', ...
|
||||||
|
'every axis/.append style={font=\scriptsize}', ...
|
||||||
'legend columns=1', ...
|
'legend columns=1', ...
|
||||||
'every axis/.append style={font=\scriptsize}',...
|
'legend style={at={(0.02,0.98)}, anchor=north west, font=\scriptsize, draw=black!100, rounded corners=2pt, inner sep=1pt, fill=white, column sep=2pt}' ...
|
||||||
'legend columns=1',...
|
|
||||||
'legend style={at={(0.02,0.98)},font=\footnotesize,draw=black!60,rounded corners=2pt,inner sep=1pt,fill=white,column sep=6pt,anchor= north west}',...
|
|
||||||
'legend style={at={(0.02,0.98)},draw=white!0!white,font=\scriptsize,inner sep=0.1pt,fill=white,column sep=1pt,anchor= north west}',...
|
|
||||||
'every axis/.append style={font=\scriptsize}',...
|
|
||||||
});
|
});
|
||||||
|
% matlab2tikz(char(filename), ...
|
||||||
|
% 'width','\fwidth', ...
|
||||||
|
% 'height','\fheight', ...
|
||||||
|
% 'showInfo',false, ...
|
||||||
|
% 'extraAxisOptions',{ ...
|
||||||
|
% 'legend style={font=\footnotesize}', ...
|
||||||
|
% 'xlabel style={font=\color{white!15!black},font=\small},',...
|
||||||
|
% 'ylabel style={font=\color{white!15!black},font=\small},',...
|
||||||
|
% 'legend columns=1', ...
|
||||||
|
% 'every axis/.append style={font=\scriptsize}',...
|
||||||
|
% 'legend columns=1',...
|
||||||
|
% 'legend style={at={(0.02,0.98)},font=\footnotesize,draw=black!60,rounded corners=2pt,inner sep=1pt,fill=white,column sep=6pt,anchor= north west}',...
|
||||||
|
% 'legend style={at={(0.02,0.98)},draw=white!0!white,font=\scriptsize,inner sep=0.1pt,fill=white,column sep=1pt,anchor= north west}',...
|
||||||
|
% 'every axis/.append style={font=\scriptsize}',...
|
||||||
|
% 'scaled ticks=false', ...
|
||||||
|
% 'tick label style={/pgf/number format/fixed, /pgf/number format/1000 sep={}}' ...
|
||||||
|
% });
|
||||||
|
|
||||||
end
|
end
|
||||||
11
Tests/02_optical/DP_Fiber_test.m
Normal file
11
Tests/02_optical/DP_Fiber_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef DP_Fiber_test < matlab.unittest.TestCase
|
||||||
|
% Test class for DP_Fiber
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for DP_Fiber
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/Optical_Demultiplex_test.m
Normal file
11
Tests/02_optical/Optical_Demultiplex_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Optical_Demultiplex_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Optical_Demultiplex
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Optical_Demultiplex
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/Optical_Multiplex_test.m
Normal file
11
Tests/02_optical/Optical_Multiplex_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Optical_Multiplex_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Optical_Multiplex
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Optical_Multiplex
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/Polarization_Controller_test.m
Normal file
11
Tests/02_optical/Polarization_Controller_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Polarization_Controller_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Polarization_Controller
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Polarization_Controller
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/CNLSE_plain_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/CNLSE_plain_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef CNLSE_plain_test < matlab.unittest.TestCase
|
||||||
|
% Test class for CNLSE_plain
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for CNLSE_plain
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/CNLSE_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/CNLSE_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef CNLSE_test < matlab.unittest.TestCase
|
||||||
|
% Test class for CNLSE
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for CNLSE
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/canUseGPU_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/canUseGPU_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef canUseGPU_test < matlab.unittest.TestCase
|
||||||
|
% Test class for canUseGPU
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for canUseGPU
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/getNLstepsize_original_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/getNLstepsize_original_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef getNLstepsize_original_test < matlab.unittest.TestCase
|
||||||
|
% Test class for getNLstepsize_original
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for getNLstepsize_original
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/getNLstepsize_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/getNLstepsize_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef getNLstepsize_test < matlab.unittest.TestCase
|
||||||
|
% Test class for getNLstepsize
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for getNLstepsize
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/lin_step_original_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/lin_step_original_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef lin_step_original_test < matlab.unittest.TestCase
|
||||||
|
% Test class for lin_step_original
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for lin_step_original
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/lin_step_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/lin_step_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef lin_step_test < matlab.unittest.TestCase
|
||||||
|
% Test class for lin_step
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for lin_step
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/nl_step_original_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/nl_step_original_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef nl_step_original_test < matlab.unittest.TestCase
|
||||||
|
% Test class for nl_step_original
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for nl_step_original
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/nl_step_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/nl_step_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef nl_step_test < matlab.unittest.TestCase
|
||||||
|
% Test class for nl_step
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for nl_step
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/02_optical/dp_fiber_lib/split_step_loop_test.m
Normal file
11
Tests/02_optical/dp_fiber_lib/split_step_loop_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef split_step_loop_test < matlab.unittest.TestCase
|
||||||
|
% Test class for split_step_loop
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for split_step_loop
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/CIC_filter_test.m
Normal file
11
Tests/04_DSP/CIC_filter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef CIC_filter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for CIC_filter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for CIC_filter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -12,7 +12,7 @@ classdef Duobinary_test < matlab.unittest.TestCase
|
|||||||
properties (MethodSetupParameter)
|
properties (MethodSetupParameter)
|
||||||
% Define method-level parameters for PRBS and bit pattern
|
% Define method-level parameters for PRBS and bit pattern
|
||||||
% i.e.: useprbs = {0,1};
|
% i.e.: useprbs = {0,1};
|
||||||
useprbs = struct('true', 1); % variations: {0, 1}
|
useprbs = struct('true', 0); % variations: {0, 1}
|
||||||
M = struct('M2', 2, 'M4', 4, 'M6', 6, 'M8', 8); % variations: {2, 4, 6, 8}
|
M = struct('M2', 2, 'M4', 4, 'M6', 6, 'M8', 8); % variations: {2, 4, 6, 8}
|
||||||
O = struct('O10', 10,'O11', 11,'O12', 12,'O13', 13, 'O15', 15, 'O17', 17, 'O18', 18, 'O19', 19); % variations: {10, 15, 17}
|
O = struct('O10', 10,'O11', 11,'O12', 12,'O13', 13, 'O15', 15, 'O17', 17, 'O18', 18, 'O19', 19); % variations: {10, 15, 17}
|
||||||
end
|
end
|
||||||
|
|||||||
11
Tests/04_DSP/Equalizer/FFE_DCremoval_adaptive_mu_test.m
Normal file
11
Tests/04_DSP/Equalizer/FFE_DCremoval_adaptive_mu_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef FFE_DCremoval_adaptive_mu_test < matlab.unittest.TestCase
|
||||||
|
% Test class for FFE_DCremoval_adaptive_mu
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for FFE_DCremoval_adaptive_mu
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/FFE_DCremoval_level_test.m
Normal file
11
Tests/04_DSP/Equalizer/FFE_DCremoval_level_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef FFE_DCremoval_level_test < matlab.unittest.TestCase
|
||||||
|
% Test class for FFE_DCremoval_level
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for FFE_DCremoval_level
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/FFE_Kalman_Feedback_test.m
Normal file
11
Tests/04_DSP/Equalizer/FFE_Kalman_Feedback_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef FFE_Kalman_Feedback_test < matlab.unittest.TestCase
|
||||||
|
% Test class for FFE_Kalman_Feedback
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for FFE_Kalman_Feedback
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/FFE_Kalman_test.m
Normal file
11
Tests/04_DSP/Equalizer/FFE_Kalman_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef FFE_Kalman_test < matlab.unittest.TestCase
|
||||||
|
% Test class for FFE_Kalman
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for FFE_Kalman
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/FFE_MLSE_test.m
Normal file
11
Tests/04_DSP/Equalizer/FFE_MLSE_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef FFE_MLSE_test < matlab.unittest.TestCase
|
||||||
|
% Test class for FFE_MLSE
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for FFE_MLSE
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/ML_MLSE_GPU_test.m
Normal file
11
Tests/04_DSP/Equalizer/ML_MLSE_GPU_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef ML_MLSE_GPU_test < matlab.unittest.TestCase
|
||||||
|
% Test class for ML_MLSE_GPU
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for ML_MLSE_GPU
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/ML_MLSE_test.m
Normal file
11
Tests/04_DSP/Equalizer/ML_MLSE_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef ML_MLSE_test < matlab.unittest.TestCase
|
||||||
|
% Test class for ML_MLSE
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for ML_MLSE
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Equalizer/Postfilter_test.m
Normal file
11
Tests/04_DSP/Equalizer/Postfilter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Postfilter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Postfilter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Postfilter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Sequence Detection/MLSE_new_test.m
Normal file
11
Tests/04_DSP/Sequence Detection/MLSE_new_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef MLSE_new_test < matlab.unittest.TestCase
|
||||||
|
% Test class for MLSE_new
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for MLSE_new
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Sequence Detection/MLSE_viterbi_test.m
Normal file
11
Tests/04_DSP/Sequence Detection/MLSE_viterbi_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef MLSE_viterbi_test < matlab.unittest.TestCase
|
||||||
|
% Test class for MLSE_viterbi
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for MLSE_viterbi
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/Godard_Timing_Recovery_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/Godard_Timing_Recovery_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Godard_Timing_Recovery_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Godard_Timing_Recovery
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Godard_Timing_Recovery
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/MaxVar_Timing_Recovery_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/MaxVar_Timing_Recovery_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef MaxVar_Timing_Recovery_test < matlab.unittest.TestCase
|
||||||
|
% Test class for MaxVar_Timing_Recovery
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for MaxVar_Timing_Recovery
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/Time_Shifter_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/Time_Shifter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Time_Shifter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Time_Shifter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Time_Shifter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_GPT_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_GPT_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Timing_Recovery_GPT_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Timing_Recovery_GPT
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Timing_Recovery_GPT
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_Move_It_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_Move_It_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Timing_Recovery_Move_It_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Timing_Recovery_Move_It
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Timing_Recovery_Move_It
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_test.m
Normal file
11
Tests/04_DSP/Timing Recovery/Timing_Recovery_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Timing_Recovery_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Timing_Recovery
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Timing_Recovery
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/Timing_Recovery_test.m
Normal file
11
Tests/04_DSP/Timing_Recovery_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Timing_Recovery_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Timing_Recovery
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Timing_Recovery
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/04_DSP/TransmissionPerformance_test.m
Normal file
11
Tests/04_DSP/TransmissionPerformance_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef TransmissionPerformance_test < matlab.unittest.TestCase
|
||||||
|
% Test class for TransmissionPerformance
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for TransmissionPerformance
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/Awg2Scope_test.m
Normal file
11
Tests/05_Lab/Awg2Scope_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Awg2Scope_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Awg2Scope
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Awg2Scope
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/AwgKeysight_test.m
Normal file
11
Tests/05_Lab/AwgKeysight_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef AwgKeysight_test < matlab.unittest.TestCase
|
||||||
|
% Test class for AwgKeysight
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for AwgKeysight
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/Exfo_laser_test.m
Normal file
11
Tests/05_Lab/Exfo_laser_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Exfo_laser_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Exfo_laser
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Exfo_laser
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/LabDeviceTemplate_test.m
Normal file
11
Tests/05_Lab/LabDeviceTemplate_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef LabDeviceTemplate_test < matlab.unittest.TestCase
|
||||||
|
% Test class for LabDeviceTemplate
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for LabDeviceTemplate
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/OSA_Advantest_test.m
Normal file
11
Tests/05_Lab/OSA_Advantest_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef OSA_Advantest_test < matlab.unittest.TestCase
|
||||||
|
% Test class for OSA_Advantest
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for OSA_Advantest
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/OptAtten_test.m
Normal file
11
Tests/05_Lab/OptAtten_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef OptAtten_test < matlab.unittest.TestCase
|
||||||
|
% Test class for OptAtten
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for OptAtten
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/OptLaserN7714A_test.m
Normal file
11
Tests/05_Lab/OptLaserN7714A_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef OptLaserN7714A_test < matlab.unittest.TestCase
|
||||||
|
% Test class for OptLaserN7714A
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for OptLaserN7714A
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/OptPowerMeter8153A_test.m
Normal file
11
Tests/05_Lab/OptPowerMeter8153A_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef OptPowerMeter8153A_test < matlab.unittest.TestCase
|
||||||
|
% Test class for OptPowerMeter8153A
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for OptPowerMeter8153A
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/ScopeKeysight_test.m
Normal file
11
Tests/05_Lab/ScopeKeysight_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef ScopeKeysight_test < matlab.unittest.TestCase
|
||||||
|
% Test class for ScopeKeysight
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for ScopeKeysight
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/05_Lab/Thor_PDFA_test.m
Normal file
11
Tests/05_Lab/Thor_PDFA_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Thor_PDFA_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Thor_PDFA
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Thor_PDFA
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/DBHandler_test.m
Normal file
11
Tests/DataBaseHandler/DBHandler_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef DBHandler_test < matlab.unittest.TestCase
|
||||||
|
% Test class for DBHandler
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for DBHandler
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/Equalizerstruct_test.m
Normal file
11
Tests/DataBaseHandler/Equalizerstruct_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Equalizerstruct_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Equalizerstruct
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Equalizerstruct
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/Metricstruct_test.m
Normal file
11
Tests/DataBaseHandler/Metricstruct_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Metricstruct_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Metricstruct
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Metricstruct
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/QueryFilter_test.m
Normal file
11
Tests/DataBaseHandler/QueryFilter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef QueryFilter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for QueryFilter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for QueryFilter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/SqlFilter_test.m
Normal file
11
Tests/DataBaseHandler/SqlFilter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef SqlFilter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for SqlFilter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for SqlFilter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/SqlOperator_test.m
Normal file
11
Tests/DataBaseHandler/SqlOperator_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef SqlOperator_test < matlab.unittest.TestCase
|
||||||
|
% Test class for SqlOperator
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for SqlOperator
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/related functions/cleanUpTable_test.m
Normal file
11
Tests/DataBaseHandler/related functions/cleanUpTable_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef cleanUpTable_test < matlab.unittest.TestCase
|
||||||
|
% Test class for cleanUpTable
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for cleanUpTable
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/DataBaseHandler/related functions/groupIt_test.m
Normal file
11
Tests/DataBaseHandler/related functions/groupIt_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef groupIt_test < matlab.unittest.TestCase
|
||||||
|
% Test class for groupIt
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for groupIt
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef removeGroupOutliers_test < matlab.unittest.TestCase
|
||||||
|
% Test class for removeGroupOutliers
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for removeGroupOutliers
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/GifWriter_test.m
Normal file
11
Tests/GifWriter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef GifWriter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for GifWriter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for GifWriter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/Moveit_wrapper_test.m
Normal file
11
Tests/Moveit_wrapper_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Moveit_wrapper_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Moveit_wrapper
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Moveit_wrapper
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/Warehouse_class/classes/DataStorage_test.m
Normal file
11
Tests/Warehouse_class/classes/DataStorage_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef DataStorage_test < matlab.unittest.TestCase
|
||||||
|
% Test class for DataStorage
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for DataStorage
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/Warehouse_class/classes/Parameter_test.m
Normal file
11
Tests/Warehouse_class/classes/Parameter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef Parameter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for Parameter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for Parameter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/Warehouse_class/classes/StorageParameter_test.m
Normal file
11
Tests/Warehouse_class/classes/StorageParameter_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef StorageParameter_test < matlab.unittest.TestCase
|
||||||
|
% Test class for StorageParameter
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for StorageParameter
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef minimal_warehouse_example_test < matlab.unittest.TestCase
|
||||||
|
% Test class for minimal_warehouse_example
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for minimal_warehouse_example
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
11
Tests/Warehouse_class/functions/interpCurve_test.m
Normal file
11
Tests/Warehouse_class/functions/interpCurve_test.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
classdef interpCurve_test < matlab.unittest.TestCase
|
||||||
|
% Test class for interpCurve
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for interpCurve
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef build_wh_test < matlab.unittest.TestCase
|
||||||
|
% Test class for build_wh
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for build_wh
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef CompleteRoutine_DifferentChannels_Fig3_test < matlab.unittest.TestCase
|
||||||
|
% Test class for CompleteRoutine_DifferentChannels_Fig3
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for CompleteRoutine_DifferentChannels_Fig3
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef CompleteRoutine_test < matlab.unittest.TestCase
|
||||||
|
% Test class for CompleteRoutine
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for CompleteRoutine
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef automate_JLT_plots_test < matlab.unittest.TestCase
|
||||||
|
% Test class for automate_JLT_plots
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for automate_JLT_plots
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef automate_PTL_plot_new_test < matlab.unittest.TestCase
|
||||||
|
% Test class for automate_PTL_plot_new
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for automate_PTL_plot_new
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef dispersion_only_test < matlab.unittest.TestCase
|
||||||
|
% Test class for dispersion_only
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for dispersion_only
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef dispersion_validation_miniskript_test < matlab.unittest.TestCase
|
||||||
|
% Test class for dispersion_validation_miniskript
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for dispersion_validation_miniskript
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef generatePlots_test < matlab.unittest.TestCase
|
||||||
|
% Test class for generatePlots
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for generatePlots
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plot3dCurve_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plot3dCurve
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plot3dCurve
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotBerVsZDW_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotBerVsZDW
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotBerVsZDW
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotBerVsZdwFailureRate_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotBerVsZdwFailureRate
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotBerVsZdwFailureRate
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotChannelSpacingAna_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotChannelSpacingAna
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotChannelSpacingAna
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotCurve_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotCurve
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotCurve
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotHistogram_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotHistogram
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotHistogram
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plotViolin_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plotViolin
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plotViolin
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
classdef plot_ber_distribution_test < matlab.unittest.TestCase
|
||||||
|
% Test class for plot_ber_distribution
|
||||||
|
|
||||||
|
methods (Test)
|
||||||
|
function testExample(testCase)
|
||||||
|
% Example test case for plot_ber_distribution
|
||||||
|
% Add your test code here
|
||||||
|
testCase.verifyTrue(true);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -3,7 +3,7 @@ function generateTests()
|
|||||||
if ismac
|
if ismac
|
||||||
cd('/Users/silasoettinghaus/Documents/MATLAB/imdd_simulation');
|
cd('/Users/silasoettinghaus/Documents/MATLAB/imdd_simulation');
|
||||||
else
|
else
|
||||||
|
cd('C:\Users\Silas\Documents\MATLAB\imdd_simulation');
|
||||||
end
|
end
|
||||||
|
|
||||||
% Define the root folders for classes and tests
|
% Define the root folders for classes and tests
|
||||||
@@ -16,7 +16,7 @@ function generateTests()
|
|||||||
end
|
end
|
||||||
|
|
||||||
% Get all .m files in the Classes folder and its subfolders
|
% Get all .m files in the Classes folder and its subfolders
|
||||||
classFiles = dir(fullfile(classesFolder, '**', '*.m'));
|
classFiles = dir(fullfile(pwd,classesFolder, '**', '*.m'));
|
||||||
|
|
||||||
% Iterate over all class files
|
% Iterate over all class files
|
||||||
for i = 1:length(classFiles)
|
for i = 1:length(classFiles)
|
||||||
|
|||||||
195
projects/ASTRO Electrical Link/Electrical_Link_GPT.m
Normal file
195
projects/ASTRO Electrical Link/Electrical_Link_GPT.m
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
%==========================================================================
|
||||||
|
% High-Speed Link Modell (Dispersion + Reflexionen + Crosstalk)
|
||||||
|
% Eigenständiges MATLAB-Skript mit Testsequenz (PRBS), Kanalmodell im f-Bereich
|
||||||
|
% und Auswertung (Eye + Spektren).
|
||||||
|
%
|
||||||
|
% Idee:
|
||||||
|
% - Hauptkanal: H11(f) = exp(-gamma(f)*l)
|
||||||
|
% - Crosstalk: H21(f) = k_xt * j*(f/fc) / (1 + j*(f/fc)) * exp(-gamma_xt(f)*l)
|
||||||
|
% (Highpass-artig: typisches FEXT-ähnliches Verhalten; simpel aber nützlich)
|
||||||
|
% - Reflexionen: optionaler 2-Tap Echo-Term (vereinfachtes Stub/Mismatch-Modell)
|
||||||
|
%
|
||||||
|
% Keine Toolboxes zwingend nötig (außer eye diagram -> optional).
|
||||||
|
%==========================================================================
|
||||||
|
|
||||||
|
clear; close all; clc;
|
||||||
|
|
||||||
|
%% ----------------------- Simulationseinstellungen -----------------------
|
||||||
|
Rb = 10e9; % Bitrate [b/s]
|
||||||
|
UI = 1/Rb; % Unit Interval [s]
|
||||||
|
os = 32; % Oversampling
|
||||||
|
Fs = Rb*os; % Abtastrate [Hz]
|
||||||
|
Ts = 1/Fs;
|
||||||
|
|
||||||
|
Nbits = 4096; % Anzahl Bits pro Lane
|
||||||
|
A = 1.0; % NRZ-Amplitude (0/1 -> +/-A)
|
||||||
|
|
||||||
|
% PRBS-Seed
|
||||||
|
rng(1);
|
||||||
|
|
||||||
|
%% ----------------------- Testsequenzen (Aggressor + Victim) -------------
|
||||||
|
% Victim-Lane Daten
|
||||||
|
b_v = randi([0 1], Nbits, 1);
|
||||||
|
x_v = A*(2*b_v - 1); % NRZ: -A/+A
|
||||||
|
|
||||||
|
% Aggressor-Lane Daten (unabhängig)
|
||||||
|
b_a = randi([0 1], Nbits, 1);
|
||||||
|
x_a = A*(2*b_a - 1);
|
||||||
|
|
||||||
|
% Upsampling (NRZ-Rechteck)
|
||||||
|
x_v_up = upsample(x_v, os);
|
||||||
|
x_a_up = upsample(x_a, os);
|
||||||
|
|
||||||
|
% Simple Zero-Order Hold (rechteckig halten)
|
||||||
|
x_v_up = filter(ones(os,1), 1, x_v_up);
|
||||||
|
x_a_up = filter(ones(os,1), 1, x_a_up);
|
||||||
|
|
||||||
|
% Am Anfang Filter-Transient entfernen / zentrieren
|
||||||
|
x_v_up = x_v_up(os:end);
|
||||||
|
x_a_up = x_a_up(os:end);
|
||||||
|
|
||||||
|
% Signal-Länge
|
||||||
|
N = length(x_v_up);
|
||||||
|
|
||||||
|
% Optional: leichte TX-RiseTime-Abbildung (1st order LP)
|
||||||
|
% (hilft, unrealistische unendliche Bandbreite zu vermeiden)
|
||||||
|
f_tx_3dB = 0.35/(35e-12); % grob: 35ps 10-90% -> f3dB ~ 0.35/tr
|
||||||
|
[x_v_up, x_a_up] = apply_1pole_lp(x_v_up, x_a_up, Fs, f_tx_3dB);
|
||||||
|
|
||||||
|
%% ----------------------- Frequenzachse (FFT) ----------------------------
|
||||||
|
% FFT-Länge als Power-of-two (schneller, weniger Circular-Artefakte)
|
||||||
|
Nfft = 2^nextpow2(N*2);
|
||||||
|
f = (0:Nfft-1).'*Fs/Nfft; % 0 ... Fs*(1-1/Nfft)
|
||||||
|
% Für Transferfunktionen brauchen wir auch negative Frequenzen implizit:
|
||||||
|
% MATLAB-FFT nutzt diese Darstellung automatisch, solange H hermitesch ist.
|
||||||
|
% Wir definieren H für alle FFT-Bins konsistent mit reellen Signalen.
|
||||||
|
|
||||||
|
%% ----------------------- RLGC-Modell (Dispersion & Loss) -----------------
|
||||||
|
% Leitungslänge
|
||||||
|
l = 0.40; % [m]
|
||||||
|
|
||||||
|
% Per-unit-length Parameter (Beispielwerte, grob PCB-ähnlich)
|
||||||
|
L = 3.2e-7; % [H/m]
|
||||||
|
C = 1.6e-10; % [F/m]
|
||||||
|
G0 = 0; % [S/m] (DC)
|
||||||
|
tanD = 0.012; % Verlustfaktor (vereinfachtes Dielektrikum-Modell)
|
||||||
|
% G(f) ~ omega*C*tanD
|
||||||
|
omega = 2*pi*f;
|
||||||
|
G = G0 + omega.*C*tanD;
|
||||||
|
|
||||||
|
% Skin-Effekt / Rauheit: R(f) ~ Rdc + k*sqrt(f)
|
||||||
|
Rdc = 0.05; % [Ohm/m]
|
||||||
|
kR = 0.20; % [Ohm/m/sqrt(Hz)] * sqrt(Hz) -> Ohm/m
|
||||||
|
R = Rdc + kR*sqrt(max(f,1)); % max(..,1) vermeidet sqrt(0)
|
||||||
|
|
||||||
|
% gamma(f) und Z0(f)
|
||||||
|
gamma = sqrt( (R + 1j*omega*L) .* (G + 1j*omega*C) ); % [1/m]
|
||||||
|
Z0 = sqrt( (R + 1j*omega*L) ./ (G + 1j*omega*C) ); % [Ohm]
|
||||||
|
|
||||||
|
% Hauptpfad-Transferfunktion (perfekt terminiert)
|
||||||
|
H11 = exp(-gamma*l);
|
||||||
|
|
||||||
|
%% ----------------------- Crosstalk-Modell (Aggressor -> Victim) ----------
|
||||||
|
% Sehr vereinfachtes FEXT-ähnliches Modell: wächst mit f, sättigt
|
||||||
|
k_xt = 0.04; % Crosstalk-Stärke (skalieren)
|
||||||
|
fc = 8e9; % Eckfrequenz der Koppelcharakteristik
|
||||||
|
|
||||||
|
% optional etwas andere Verluste auf dem Koppelpfad
|
||||||
|
gamma_xt = gamma .* (1.05 + 0.00j);
|
||||||
|
|
||||||
|
Hxt_shape = (1j*(f/fc)) ./ (1 + 1j*(f/fc)); % ~ Highpass
|
||||||
|
H21 = k_xt .* Hxt_shape .* exp(-gamma_xt*l);
|
||||||
|
|
||||||
|
%% ----------------------- Reflexions/Echo-Modell (optional) ---------------
|
||||||
|
% Einfache 2-Tap-Approximation: Hecho = 1 + a*exp(-j*2*pi*f*tau)
|
||||||
|
% (z.B. Stub/Via-Resonanz als Echo)
|
||||||
|
useEcho = true;
|
||||||
|
a_echo = 0.18; % Echo-Amplitude (|a|<1)
|
||||||
|
tau = 120e-12; % Echo-Delay [s]
|
||||||
|
|
||||||
|
if useEcho
|
||||||
|
Hecho = 1 + a_echo*exp(-1j*2*pi*f*tau);
|
||||||
|
H11 = H11 .* Hecho;
|
||||||
|
end
|
||||||
|
|
||||||
|
%% ----------------------- Kanal-Anwendung per FFT -------------------------
|
||||||
|
% Zero-padding auf Nfft
|
||||||
|
Xv = fft(x_v_up, Nfft);
|
||||||
|
Xa = fft(x_a_up, Nfft);
|
||||||
|
|
||||||
|
% Victim-Ausgang = Hauptpfad * Victim + Crosstalkpfad * Aggressor
|
||||||
|
Yv = H11 .* Xv + H21 .* Xa;
|
||||||
|
|
||||||
|
y_v = real(ifft(Yv, Nfft));
|
||||||
|
y_v = y_v(1:N); % zurück auf Originallänge
|
||||||
|
|
||||||
|
%% ----------------------- Auswertung: Eye Diagramm ------------------------
|
||||||
|
% Eye über viele UIs (ohne Toolbox: eigene Darstellung)
|
||||||
|
plot_eye(y_v, os, 2); % 2 UI Breite
|
||||||
|
|
||||||
|
%% ----------------------- Auswertung: Frequenzgänge -----------------------
|
||||||
|
figure('Name','Transferfunktionen');
|
||||||
|
subplot(2,1,1);
|
||||||
|
plot(f/1e9, 20*log10(abs(H11)+1e-15)); grid on;
|
||||||
|
xlabel('f [GHz]'); ylabel('|H_{11}| [dB]');
|
||||||
|
title('Hauptkanal (inkl. Dispersion/Loss + optional Echo)');
|
||||||
|
|
||||||
|
subplot(2,1,2);
|
||||||
|
plot(f/1e9, 20*log10(abs(H21)+1e-15)); grid on;
|
||||||
|
xlabel('f [GHz]'); ylabel('|H_{21}| [dB]');
|
||||||
|
title('Crosstalk-Pfad (Aggressor -> Victim)');
|
||||||
|
|
||||||
|
%% ----------------------- Optional: Bitfehlersicht / Sampling -------------
|
||||||
|
% Einfaches Sampling in der UI-Mitte (ohne Taktwiedergewinnung)
|
||||||
|
% (nur grobe Demo, kein echter CDR)
|
||||||
|
sampleOffset = round(os/2);
|
||||||
|
idx = sampleOffset:os:(sampleOffset + (Nbits-2)*os);
|
||||||
|
samples = y_v(idx);
|
||||||
|
|
||||||
|
% Hard Decision
|
||||||
|
bh = samples > 0;
|
||||||
|
ber = mean(bh(:) ~= b_v(1:length(bh)));
|
||||||
|
|
||||||
|
fprintf('--- Ergebnis ---\n');
|
||||||
|
fprintf('Bitrate: %.2f Gb/s, Oversampling: %d, Fs: %.2f GHz\n', Rb/1e9, os, Fs/1e9);
|
||||||
|
fprintf('Echo: %d (a=%.3f, tau=%.1f ps)\n', useEcho, a_echo, tau*1e12);
|
||||||
|
fprintf('Crosstalk k_xt=%.3f, fc=%.2f GHz\n', k_xt, fc/1e9);
|
||||||
|
fprintf('Grobe BER (ohne CDR/EQ): %.3e\n', ber);
|
||||||
|
|
||||||
|
%==========================================================================
|
||||||
|
% Lokale Hilfsfunktionen
|
||||||
|
%==========================================================================
|
||||||
|
|
||||||
|
function [x1o, x2o] = apply_1pole_lp(x1, x2, Fs, f3dB)
|
||||||
|
% 1. Ordnung Tiefpass als TX-Bandbegrenzung (optional)
|
||||||
|
if isempty(f3dB) || f3dB<=0
|
||||||
|
x1o = x1; x2o = x2; return;
|
||||||
|
end
|
||||||
|
w = 2*pi*f3dB;
|
||||||
|
a = exp(-w/Fs);
|
||||||
|
b = 1-a;
|
||||||
|
x1o = filter(b, [1 -a], x1);
|
||||||
|
x2o = filter(b, [1 -a], x2);
|
||||||
|
end
|
||||||
|
|
||||||
|
function plot_eye(y, os, nUI)
|
||||||
|
% Eye-Diagramm ohne Toolbox: Segmente von nUI*os sampeln und überlagern
|
||||||
|
Lseg = nUI*os;
|
||||||
|
nSeg = floor(length(y)/os) - nUI - 2;
|
||||||
|
if nSeg < 10
|
||||||
|
warning('Zu wenig Daten für Eye.');
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
figure('Name','Eye Diagramm');
|
||||||
|
hold on; grid on;
|
||||||
|
t = (0:Lseg-1)/os; % in UI
|
||||||
|
for k = 1:nSeg
|
||||||
|
i0 = (k-1)*os + 1;
|
||||||
|
seg = y(i0:i0+Lseg-1);
|
||||||
|
plot(t, seg);
|
||||||
|
end
|
||||||
|
xlabel('Zeit [UI]');
|
||||||
|
ylabel('Amplitude [V (rel.)]');
|
||||||
|
title(sprintf('Eye Diagramm (Breite = %d UI, Oversampling = %d)', nUI, os));
|
||||||
|
end
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user