duobinary cleanup (currently it is a mess)
This commit is contained in:
@@ -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
|
||||||
|
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')
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ classdef Metricstruct
|
|||||||
eqParam_id (1,1) double {mustBeNumeric} = NaN
|
eqParam_id (1,1) double {mustBeNumeric} = NaN
|
||||||
date_of_processing (1,1) datetime = datetime('now')
|
date_of_processing (1,1) datetime = datetime('now')
|
||||||
|
|
||||||
numBits (1,1) double {mustBeInteger, mustBeNonnegative} = 0
|
numBits (1,1) double = 0
|
||||||
BER (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
|
BER (1,1) double = 0
|
||||||
numBitErr (1,1) double {mustBeInteger, mustBeNonnegative} = 0
|
numBitErr (1,1) double = 0
|
||||||
BER_precoded (1,1) double {mustBeNumeric, mustBeNonnegative} = 0
|
BER_precoded (1,1) double = 0
|
||||||
numBitErr_precoded (1,1) double {mustBeInteger, mustBeNonnegative} = 0
|
numBitErr_precoded (1,1) double = 0
|
||||||
|
|
||||||
SNR (1,1) double {mustBeNumeric} = NaN
|
SNR (1,1) double {mustBeNumeric} = NaN
|
||||||
SNR_level (:,1) double {mustBeNumeric} = []
|
SNR_level (:,1) double {mustBeNumeric} = []
|
||||||
|
|||||||
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
|
||||||
@@ -11,8 +11,10 @@ arguments
|
|||||||
options.showAnalysis = 0;
|
options.showAnalysis = 0;
|
||||||
options.eth_style_symbol_mapping = 0;
|
options.eth_style_symbol_mapping = 0;
|
||||||
options.postFFE = [];
|
options.postFFE = [];
|
||||||
|
options.decoding_mode db_decoder = db_decoder.sequencedetection;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
%Duobinary Targeting
|
%Duobinary Targeting
|
||||||
db_ref_sequence = Duobinary().encode(tx_symbols);
|
db_ref_sequence = Duobinary().encode(tx_symbols);
|
||||||
db_ref_constellation = unique(db_ref_sequence.signal);
|
db_ref_constellation = unique(db_ref_sequence.signal);
|
||||||
@@ -21,17 +23,23 @@ db_ref_constellation = unique(db_ref_sequence.signal);
|
|||||||
if ~isempty(options.postFFE)
|
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);
|
pam_sig_sd = mlse_.process(eq_signal);
|
||||||
else
|
else
|
||||||
[mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
[pam_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,tx_symbols);
|
||||||
|
end
|
||||||
|
pam_sig_hd = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).quantize(pam_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;
|
||||||
end
|
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
|
% precoding to mitigate error propagation, most prominently used in
|
||||||
% combination with duobinary signaling to avoid catastrophic error
|
% combination with duobinary signaling to avoid catastrophic error
|
||||||
@@ -42,58 +50,62 @@ switch options.precode_mode
|
|||||||
% 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);
|
if options.decoding_mode == db_decoder.sequencedetection
|
||||||
mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded,"M",M);
|
pam_sig_hd_precoded = Duobinary().encode(pam_sig_hd,"M",M);
|
||||||
|
pam_sig_hd_precoded = Duobinary().decode(pam_sig_hd_precoded,"M",M);
|
||||||
|
else
|
||||||
|
pam_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);
|
||||||
|
|
||||||
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
tx_bits_precoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(tx_symbols_precoded);
|
||||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_precoded);
|
|
||||||
|
|
||||||
[~,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);
|
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(pam_sig_hd_precoded);
|
||||||
|
|
||||||
|
[bits_db,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);
|
if options.decoding_mode == db_decoder.sequencedetection
|
||||||
|
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);
|
||||||
|
else
|
||||||
|
ber_db = NaN;
|
||||||
|
errors_db = NaN;
|
||||||
|
end
|
||||||
|
|
||||||
case db_mode.db_precoded
|
case db_mode.db_precoded
|
||||||
|
|
||||||
% 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);
|
if options.decoding_mode == db_decoder.sequencedetection
|
||||||
mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M);
|
pam_sig_hd_decoded = Duobinary().encode(pam_sig_hd,"M",M);
|
||||||
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd_decoded);
|
pam_sig_hd_decoded = Duobinary().decode(pam_sig_hd_decoded,"M",M);
|
||||||
[~,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);
|
else
|
||||||
burst_db_precoded = count_error_bursts(a, 40);
|
pam_sig_hd_decoded = pam_sig_hd;
|
||||||
% 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);
|
|
||||||
rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_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);
|
|
||||||
burst_db = count_error_bursts(a, 40);
|
|
||||||
|
|
||||||
cols = linspecer(8);
|
|
||||||
figure();hold on;
|
|
||||||
stem(1:40,burst_db,'LineWidth',1,'Color',cols(4,:),'Marker','_','DisplayName','w/o diff. precoder');
|
|
||||||
stem(1:40,burst_db_precoded,'LineWidth',1,'Color',cols(3,:),'Marker','.','LineStyle','-','DisplayName','w diff. precoder');
|
|
||||||
xlabel('Bit Error Burst Length')
|
|
||||||
ylabel('Occurence')
|
|
||||||
set(gca, 'yscale', 'log');
|
|
||||||
end
|
end
|
||||||
|
|
||||||
% M = numel(unique(tx_symbols.signal));
|
rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(pam_sig_hd_decoded);
|
||||||
rx_bits = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd);
|
[bits_db,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);
|
||||||
|
burst_db_precoded = count_error_bursts(a, 40);
|
||||||
|
|
||||||
[bits_db,errors_db,ber_db,errorIndice_db] = calc_ber(rx_bits.signal,tx_bits.signal,"skip_front",100,"skip_end",150,"returnErrorLocation",1);
|
% B) Omit the Coding by comparing with demapped TX symbol sequence
|
||||||
|
if options.decoding_mode == db_decoder.sequencedetection
|
||||||
|
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(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);
|
||||||
|
burst_db = count_error_bursts(a, 40);
|
||||||
|
else
|
||||||
|
ber_db = NaN;
|
||||||
|
errors_db = NaN;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
switch options.decoding_mode
|
||||||
|
case db_decoder.sequencedetection %MLSE
|
||||||
|
|
||||||
alpha = arburg(eq_noise.signal,1);%pf_.coefficients(2);
|
|
||||||
alpha = alpha(2);
|
|
||||||
if isa(mlse_,'MLSE_viterbi')
|
if isa(mlse_,'MLSE_viterbi')
|
||||||
gmi_mlse = NaN;
|
gmi_mlse = NaN;
|
||||||
air_mlse = NaN;
|
air_mlse = NaN;
|
||||||
@@ -101,6 +113,12 @@ 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 = NaN;
|
||||||
|
air_mlse = NaN;
|
||||||
|
end
|
||||||
|
|
||||||
db_results = struct();
|
db_results = struct();
|
||||||
db_results.metrics = Metricstruct;
|
db_results.metrics = Metricstruct;
|
||||||
@@ -116,7 +134,7 @@ 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 = NaN;
|
||||||
|
|
||||||
% Create DB results structure
|
% Create DB results structure
|
||||||
db_results.config = Equalizerstruct();
|
db_results.config = Equalizerstruct();
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ if 1
|
|||||||
|
|
||||||
uloops = struct;
|
uloops = struct;
|
||||||
uloops.precomp = [1];
|
uloops.precomp = [1];
|
||||||
uloops.bitrate = [300].*1e9; %[300,330,360,390,420,450,480] [224,336,360,390,420,448] for MPI
|
uloops.bitrate = [360].*1e9; %[300,330,360,390,420,450,480] [224,336,360,390,420,448] for MPI
|
||||||
% uloops.laser_wavelength = [1293,1297.5,1302,1306.5,1310,1313.4,1318,1322.7,1327.4];
|
% uloops.laser_wavelength = [1293,1297.5,1302,1306.5,1310,1313.4,1318,1322.7,1327.4];
|
||||||
uloops.laser_wavelength = [1293];
|
uloops.laser_wavelength = [1290];
|
||||||
uloops.M = [4];
|
uloops.M = [4];
|
||||||
uloops.link_length = [0:2:10]; % 1,2,3,5,6,8,10
|
uloops.link_length = [0]; % 1,2,3,5,6,8,10
|
||||||
uloops.alpha = [0];
|
uloops.alpha = [0];
|
||||||
|
|
||||||
wh = DataStorage(uloops);
|
wh = DataStorage(uloops);
|
||||||
@@ -19,21 +19,23 @@ if 1
|
|||||||
end
|
end
|
||||||
|
|
||||||
%%
|
%%
|
||||||
figure
|
% figure
|
||||||
hold on
|
% hold on
|
||||||
for alpha = uloops.alpha
|
%
|
||||||
a=wh.getStoValue('ber',1, [300].*1e9 , 1293, 4, uloops.link_length,alpha);
|
% a=wh.getStoValue('ber',1, [360].*1e9 , 1290, 4, uloops.link_length,alpha);
|
||||||
ffe = cellfun(@(x) x.ffe_results.metrics.BER, a);
|
% ffe = cellfun(@(x) x.ffe_results.metrics.BER, a);
|
||||||
plot(uloops.link_length,ffe,'DisplayName',sprintf('Alpha: %d',alpha),'LineStyle','-','HandleVisibility','on');
|
% plot(uloops.link_length,ffe,'DisplayName',sprintf('FFE'),'LineStyle','-','HandleVisibility','on');
|
||||||
end
|
% dbt = cellfun(@(x) x.dbt_results.metrics.BER, a);
|
||||||
|
% plot(uloops.link_length,dbt,'DisplayName',sprintf('DBt'),'LineStyle','-','HandleVisibility','on');
|
||||||
set(gca, 'YScale', 'log');
|
%
|
||||||
ylim([5e-5 0.4]);
|
%
|
||||||
yline([3.8e-3, 2e-2],'HandleVisibility','off');
|
% set(gca, 'YScale', 'log');
|
||||||
legend
|
% ylim([5e-5 0.4]);
|
||||||
beautifyBERplot()
|
% yline([3.8e-3, 2e-2],'HandleVisibility','off');
|
||||||
ylabel('BER');
|
% legend
|
||||||
|
% beautifyBERplot()
|
||||||
|
% ylabel('BER');
|
||||||
|
%
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,66 +3,59 @@ function [output] = imdd_model(varargin)
|
|||||||
simulation_mode = 1;
|
simulation_mode = 1;
|
||||||
|
|
||||||
%%% Change folder
|
%%% Change folder
|
||||||
curFolder = pwd;
|
% curFolder = pwd;
|
||||||
funcFolder=fileparts(mfilename('fullpath'));
|
% funcFolder=fileparts(mfilename('fullpath'));
|
||||||
if ~isempty(funcFolder)
|
% if ~isempty(funcFolder)
|
||||||
cd(funcFolder);
|
% cd(funcFolder);
|
||||||
end
|
% end
|
||||||
|
|
||||||
%%% Run parameters
|
%%% Run parameters
|
||||||
% TX
|
|
||||||
M = 4;
|
|
||||||
fsym = 180e9;
|
|
||||||
|
|
||||||
apply_pulsef = 1;
|
% --- TX Architecture ---
|
||||||
fdac = 256e9;
|
M = 4; % PAM order
|
||||||
fadc = 256e9;
|
fsym = 180e9; % Symbol rate
|
||||||
|
apply_pulsef = 1; % Pulse shaping flag
|
||||||
|
fdac = 256e9; % DAC sampling rate
|
||||||
|
fadc = 256e9; % ADC sampling rate
|
||||||
random_key = 1;
|
random_key = 1;
|
||||||
|
rcalpha = 0.05; % Roll-off factor
|
||||||
|
kover = 16; % Oversampling factor
|
||||||
|
duob_mode = db_mode.db_precoded;
|
||||||
|
|
||||||
rcalpha = 0.05;
|
% --- TX Optics (EML / Laser) ---
|
||||||
kover = 16;
|
|
||||||
|
|
||||||
vbias_rel = 0.5;
|
vbias_rel = 0.5;
|
||||||
u_pi = 3;
|
u_pi = 3;
|
||||||
vbias = -vbias_rel * u_pi;
|
vbias = -vbias_rel * u_pi;
|
||||||
|
|
||||||
laser_wavelength = 1293;
|
laser_wavelength = 1293;
|
||||||
laser_linewidth = 0;
|
laser_linewidth = 0;
|
||||||
tx_bw_nyquist = 0.8;
|
tx_bw_nyquist = 0.8;
|
||||||
|
|
||||||
% Channel
|
% --- Channel ---
|
||||||
link_length = 1;
|
link_length = 1;
|
||||||
|
alpha = 0;
|
||||||
|
|
||||||
% RX
|
% --- RX & Equalization ---
|
||||||
rop = -8;
|
rop = -2;
|
||||||
rx_bw_nyquist = 0.8;
|
rx_bw_nyquist = 0.8;
|
||||||
|
len_tr = 4096 * 2;
|
||||||
|
|
||||||
|
% VNLE / FFE / DFE Orders
|
||||||
vnle_order1 = 50;
|
vnle_order1 = 50;
|
||||||
vnle_order2 = 7;
|
vnle_order2 = 7;
|
||||||
vnle_order3 = 7;
|
vnle_order3 = 7;
|
||||||
|
|
||||||
vnle_order = [vnle_order1, vnle_order2, vnle_order3];
|
vnle_order = [vnle_order1, vnle_order2, vnle_order3];
|
||||||
dfe_order = [0 0 0];
|
dfe_order = [0, 0, 0];
|
||||||
|
dfe_ = sum(dfe_order) > 0;
|
||||||
|
|
||||||
pf_ncoeffs = 1;
|
pf_ncoeffs = 1;
|
||||||
|
|
||||||
alpha = 0;
|
% Equalizer Step Sizes
|
||||||
|
|
||||||
len_tr = 4096*2;
|
|
||||||
|
|
||||||
mu_ffe1 = 0.0001;
|
mu_ffe1 = 0.0001;
|
||||||
mu_ffe2 = 0.0008;
|
mu_ffe2 = 0.0008;
|
||||||
mu_ffe3 = 0.001;
|
mu_ffe3 = 0.001;
|
||||||
mu_dc = 0.005;
|
mu_ffe = [mu_ffe1, mu_ffe3, mu_ffe3];
|
||||||
% mu_dc = 0;
|
|
||||||
|
|
||||||
mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3];
|
|
||||||
mu_dfe = 0.0004;
|
mu_dfe = 0.0004;
|
||||||
|
mu_dc = 0.005;
|
||||||
|
|
||||||
dfe_ = sum(dfe_order)>0;
|
|
||||||
|
|
||||||
duob_mode = db_mode.no_db;
|
|
||||||
|
|
||||||
%%% change specific parameter if given in varargin
|
%%% change specific parameter if given in varargin
|
||||||
% Parse optional input arguments
|
% Parse optional input arguments
|
||||||
@@ -109,12 +102,12 @@ Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rc","pulselength",1
|
|||||||
'duobinary_mode',duob_mode,...
|
'duobinary_mode',duob_mode,...
|
||||||
"mrds_code",0,"mrds_blocklength",512).process();
|
"mrds_code",0,"mrds_blocklength",512).process();
|
||||||
|
|
||||||
Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
% Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
%%%%% AWG
|
%%%%% AWG
|
||||||
% El_sig = M8199A("kover",kover).process(Digi_sig);
|
% El_sig = M8199A("kover",kover).process(Digi_sig);
|
||||||
El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig);
|
El_sig = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",0,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",1).process(Digi_sig);
|
||||||
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0);
|
El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',1);
|
||||||
% El_sig = El_sig.setPower(0,"dBm");
|
% El_sig = El_sig.setPower(0,"dBm");
|
||||||
|
|
||||||
%%%%% Low-pass el. components %%%%%%
|
%%%%% Low-pass el. components %%%%%%
|
||||||
@@ -132,7 +125,7 @@ El_sig = El_sig .* scaling;
|
|||||||
%%%%% MODULATE E/O CONVERSION %%%%%%
|
%%%%% MODULATE E/O CONVERSION %%%%%%
|
||||||
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1,"alpha",alpha).process(El_sig);
|
[Opt_sig] = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",El_sig.fs,"lambda",laser_wavelength,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth,"randomkey",random_key+1,"alpha",alpha).process(El_sig);
|
||||||
|
|
||||||
Opt_sig.spectrum("displayname",'Opt Spectrum','fignum',10,'normalizeTo0dB',1);
|
% Opt_sig.spectrum("displayname",'Opt Spectrum','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig);
|
Opt_sig = Fiber("fsimu",Opt_sig.fs,"fiber_length",link_length,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.07).process(Opt_sig);
|
||||||
|
|
||||||
@@ -150,7 +143,6 @@ Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bwl,"fs",fdac*kover,"filterType",fi
|
|||||||
% %%%%%% Low-pass Scope %%%%%%
|
% %%%%%% Low-pass Scope %%%%%%
|
||||||
Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true);
|
Lp_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth,"active",true);
|
||||||
|
|
||||||
% Rx_sig.spectrum("displayname",'Analog Rx Spectrum','fignum',100,'normalizeTo0dB',1);
|
|
||||||
|
|
||||||
%%%%%% Scope %%%%%%
|
%%%%%% Scope %%%%%%
|
||||||
Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
Scpe_sig = Scope("fsimu",fdac*kover,"fadc",fadc,...
|
||||||
@@ -165,15 +157,18 @@ Scpe_sig = Scpe_sig.resample("fs_out",2*fsym);
|
|||||||
Scpe_sig.signal = Scpe_sig.signal(1:2*length(Symbols));
|
Scpe_sig.signal = Scpe_sig.signal(1:2*length(Symbols));
|
||||||
|
|
||||||
%%%%%% Sync Rx signal with reference %%%%%%
|
%%%%%% Sync Rx signal with reference %%%%%%
|
||||||
[Scpe_sig,~] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",1);
|
[Scpe_sig,~] = Scpe_sig.tsynch("reference",Symbols,"fs_ref",fsym,"debug_plots",0);
|
||||||
|
|
||||||
Scpe_sig = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.5,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig);
|
Scpe_sig = Filter('filtdegree',4,"f_cutoff",Symbols.fs.*0.5,"fs",Scpe_sig.fs,"filterType",filtertypes.gaussian,"active",true).process(Scpe_sig);
|
||||||
|
|
||||||
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
Scpe_sig = Scpe_sig - mean(Scpe_sig.signal);
|
||||||
|
|
||||||
|
Scpe_sig.spectrum("displayname",'Filtered Digital Spectrum','fignum',100,'normalizeTo0dB',1);
|
||||||
|
|
||||||
|
|
||||||
%%% EQUALIZING
|
%%% EQUALIZING
|
||||||
|
|
||||||
|
if 0
|
||||||
% -------------------- FFE --------------------
|
% -------------------- FFE --------------------
|
||||||
ffe_order = [50, 0, 0];
|
ffe_order = [50, 0, 0];
|
||||||
eq_ffe = EQ("Ne",ffe_order,"Nb",[0,0,0], ...
|
eq_ffe = EQ("Ne",ffe_order,"Nb",[0,0,0], ...
|
||||||
@@ -186,7 +181,8 @@ output.ffe_results = ffe(eq_ffe,M,Scpe_sig,Symbols,Tx_bits, ...
|
|||||||
"eth_style_symbol_mapping",0);
|
"eth_style_symbol_mapping",0);
|
||||||
|
|
||||||
output.ffe_results.metrics.print
|
output.ffe_results.metrics.print
|
||||||
|
end
|
||||||
|
if 0
|
||||||
% -------------------- DFE --------------------
|
% -------------------- DFE --------------------
|
||||||
eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0], ...
|
eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0], ...
|
||||||
"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||||
@@ -198,7 +194,8 @@ output.dfe_results = ffe(eq_dfe,M,Scpe_sig,Symbols,Tx_bits, ...
|
|||||||
"eth_style_symbol_mapping",0);
|
"eth_style_symbol_mapping",0);
|
||||||
|
|
||||||
output.dfe_results.metrics.print("description",'DFE');
|
output.dfe_results.metrics.print("description",'DFE');
|
||||||
|
end
|
||||||
|
if 0
|
||||||
|
|
||||||
% -------------------- VNLE + MLSE --------------------
|
% -------------------- VNLE + MLSE --------------------
|
||||||
pf_ncoeffs = 1;
|
pf_ncoeffs = 1;
|
||||||
@@ -213,18 +210,20 @@ mlse_ = MLSE("duobinary_output",0,'M',M,'trellis_states',PAMmapper(M,0).levels);
|
|||||||
|
|
||||||
[output.vnle_results, output.mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
[output.vnle_results, output.mlse_results] = vnle_postfilter_mlse(eq_v, pf_, mlse_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "eth_style_symbol_mapping", 0);
|
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "eth_style_symbol_mapping", 0);
|
||||||
|
output.mlse_results.metrics.print("description",'MLSE');
|
||||||
|
end
|
||||||
|
if 1
|
||||||
|
|
||||||
|
%% -------------------- DB target --------------------
|
||||||
% -------------------- DB target --------------------
|
|
||||||
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,'trellis_states',PAMmapper(M,0).levels);
|
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,'trellis_states',PAMmapper(M,0).levels);
|
||||||
ffe_order = [50, 5, 5];
|
ffe_order = [50, 5, 5];
|
||||||
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
eq_ = EQ("Ne",ffe_order,"Nb",dfe_order,"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
|
||||||
"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1);
|
"K",2,"DCmu",mu_dc,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1,"DB_aim",0);
|
||||||
output.dbt_results = duobinary_target(eq_,mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
|
output.dbt_results = duobinary_target(eq_,mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", []);
|
"precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [],"decoding_mode","memoryless");
|
||||||
|
|
||||||
output.dbt_results.metrics.print("description",'Duobinary');
|
output.dbt_results.metrics.print("description",'Duobinary');
|
||||||
|
end
|
||||||
|
|
||||||
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
||||||
fprintf('\n')
|
fprintf('\n')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ freqresp = ChannelFreqResp("Nacq",1024,"Navg",64,"Ncp",70,"f_ref",256e9);
|
|||||||
%
|
%
|
||||||
Digi_sig = freqresp.buildOFDM();
|
Digi_sig = freqresp.buildOFDM();
|
||||||
|
|
||||||
Digi_sig.spectrum("fignum",1112,"displayname",['maxamp:',num2str(maxamp)]);
|
Digi_sig.spectrum("fignum",1112);
|
||||||
|
|
||||||
Digi_sig = Filter('filtdegree',3,"f_cutoff",70e9,"fs",256e9,"filterType",filtertypes.butterworth,"active",true).process(Digi_sig);
|
Digi_sig = Filter('filtdegree',3,"f_cutoff",70e9,"fs",256e9,"filterType",filtertypes.butterworth,"active",true).process(Digi_sig);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
M = 6;
|
M = 4;
|
||||||
apply_precode = 1;
|
apply_precode = 0;
|
||||||
|
|
||||||
bitpattern = [];
|
bitpattern = [];
|
||||||
s = RandStream('twister','Seed',1);
|
s = RandStream('twister','Seed',1);
|
||||||
@@ -51,6 +51,8 @@ disp(['BER: ',sprintf('%.1E',ber),' - - PAM-',num2str(M)]);
|
|||||||
figure(200)
|
figure(200)
|
||||||
clf
|
clf
|
||||||
hold on
|
hold on
|
||||||
|
start = 100;
|
||||||
|
burstwidth = 10;
|
||||||
idxs = start-10:start+burstwidth+10;
|
idxs = start-10:start+burstwidth+10;
|
||||||
scatter(idxs,d.signal(idxs),'DisplayName',['Orig Signal'],'Marker','o');
|
scatter(idxs,d.signal(idxs),'DisplayName',['Orig Signal'],'Marker','o');
|
||||||
scatter(idxs,d_burst.signal(idxs),'DisplayName',['Error Signal'],'Marker','x');
|
scatter(idxs,d_burst.signal(idxs),'DisplayName',['Error Signal'],'Marker','x');
|
||||||
|
|||||||
75
test/memoryless_decoding.m
Normal file
75
test/memoryless_decoding.m
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
% einstellungen
|
||||||
|
M = 4;
|
||||||
|
apply_precode_at_tx = 0;
|
||||||
|
emulate_precode = 1;
|
||||||
|
|
||||||
|
% daten erzeugen
|
||||||
|
bitpattern = [];
|
||||||
|
s = RandStream('twister','Seed',1);
|
||||||
|
for i = 1:log2(M)
|
||||||
|
N = 2^(17-1); %length of prbs
|
||||||
|
bitpattern(:,i) = randi(s,[0 1], N, 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
if M == 6
|
||||||
|
bitpattern = reshape(bitpattern',[],1);
|
||||||
|
bitpattern = bitpattern(1:end-mod(length(bitpattern),5));
|
||||||
|
end
|
||||||
|
|
||||||
|
tx_bits = Informationsignal(bitpattern);
|
||||||
|
tx_symbols = PAMmapper(M,0).map(tx_bits);
|
||||||
|
|
||||||
|
if apply_precode_at_tx
|
||||||
|
|
||||||
|
tx_symbols = Duobinary().precode(tx_symbols);
|
||||||
|
|
||||||
|
if emulate_precode
|
||||||
|
% ansatz 1B) Omit precode (einfach precoded empfangen, nichts weiter machen und normal prozessieren - möglich weil konstellation sich nicht ändert)
|
||||||
|
rx_symbols = tx_symbols;
|
||||||
|
bits_rx = PAMmapper(M,0).demap(rx_symbols);
|
||||||
|
% beachten, dass man die tx_bits anpassen muss, da man ja mit precoded symbolen vergleicht
|
||||||
|
tx_bits = PAMmapper(M,0).demap(tx_symbols);
|
||||||
|
else
|
||||||
|
% ansatz 1A) Precode normal:
|
||||||
|
% Entschiedene Symbole codieren: d_DB(n) = d(n) + d(n-1) (im Fall von PAM4 7 level [0 1 2 3 4 5 6])
|
||||||
|
symbols_db = Duobinary().encode(tx_symbols);
|
||||||
|
% Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4
|
||||||
|
rx_symbols = Duobinary().decode(symbols_db);
|
||||||
|
bits_rx = PAMmapper(M,0).demap(rx_symbols);
|
||||||
|
end
|
||||||
|
|
||||||
|
[~,~,ber,~] = calc_ber(tx_bits.signal,bits_rx.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);
|
||||||
|
disp(['BER: ',sprintf('%.1E',ber)]);
|
||||||
|
assert(ber == 0)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if emulate_precode
|
||||||
|
% emulate precode:
|
||||||
|
% Entschiedene Symbole codieren: d_DB(n) = d(n) + d(n-1) (im Fall von PAM4 7 level [0 1 2 3 4 5 6])
|
||||||
|
symbols_db = Duobinary().encode(tx_symbols); % das wäre der FFE mit db target
|
||||||
|
|
||||||
|
% Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4
|
||||||
|
rx_symbols = Duobinary().decode(symbols_db); % modulo
|
||||||
|
bits_rx = PAMmapper(M,0).demap(rx_symbols); % demappen
|
||||||
|
|
||||||
|
% ref symbole precoden, auch hier muss man wieder etwas fummeln wegen der emulation:
|
||||||
|
% encode + decode == remove precoding (mathematisch die gleiche operation)
|
||||||
|
tx_symbols_ref = Duobinary().encode(tx_symbols);
|
||||||
|
tx_symbols_ref = Duobinary().decode(tx_symbols_ref);
|
||||||
|
tx_bits = PAMmapper(M,0).demap(tx_symbols_ref);
|
||||||
|
|
||||||
|
else
|
||||||
|
% normal detection without any precode stuff
|
||||||
|
symbols_db = Duobinary().encode(tx_symbols);
|
||||||
|
|
||||||
|
rx_symbols = tx_symbols;
|
||||||
|
bits_rx = PAMmapper(M,0).demap(rx_symbols);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
[~,~,ber,~] = calc_ber(tx_bits.signal,bits_rx.signal,"skip_front",1,"skip_end",1,"returnErrorLocation",1);
|
||||||
|
disp(['BER: ',sprintf('%.1E',ber)]);
|
||||||
|
assert(ber == 0)
|
||||||
|
end
|
||||||
|
|
||||||
Reference in New Issue
Block a user