duobinary cleanup (currently it is a mess)

This commit is contained in:
Silas Oettinghaus
2026-02-23 09:17:26 +01:00
parent c0a0a415a8
commit 18ccaf8c12
9 changed files with 364 additions and 251 deletions

View File

@@ -4,11 +4,11 @@ if 1
uloops = struct;
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];
uloops.laser_wavelength = [1290];
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];
wh = DataStorage(uloops);
@@ -19,21 +19,23 @@ if 1
end
%%
figure
hold on
for alpha = uloops.alpha
a=wh.getStoValue('ber',1, [300].*1e9 , 1293, 4, uloops.link_length,alpha);
ffe = cellfun(@(x) x.ffe_results.metrics.BER, a);
plot(uloops.link_length,ffe,'DisplayName',sprintf('Alpha: %d',alpha),'LineStyle','-','HandleVisibility','on');
end
set(gca, 'YScale', 'log');
ylim([5e-5 0.4]);
yline([3.8e-3, 2e-2],'HandleVisibility','off');
legend
beautifyBERplot()
ylabel('BER');
% figure
% hold on
%
% a=wh.getStoValue('ber',1, [360].*1e9 , 1290, 4, uloops.link_length,alpha);
% ffe = cellfun(@(x) x.ffe_results.metrics.BER, a);
% plot(uloops.link_length,ffe,'DisplayName',sprintf('FFE'),'LineStyle','-','HandleVisibility','on');
% 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');
% legend
% beautifyBERplot()
% ylabel('BER');
%

View File

@@ -3,66 +3,59 @@ function [output] = imdd_model(varargin)
simulation_mode = 1;
%%% Change folder
curFolder = pwd;
funcFolder=fileparts(mfilename('fullpath'));
if ~isempty(funcFolder)
cd(funcFolder);
end
% curFolder = pwd;
% funcFolder=fileparts(mfilename('fullpath'));
% if ~isempty(funcFolder)
% cd(funcFolder);
% end
%%% Run parameters
% TX
M = 4;
fsym = 180e9;
apply_pulsef = 1;
fdac = 256e9;
fadc = 256e9;
% --- TX Architecture ---
M = 4; % PAM order
fsym = 180e9; % Symbol rate
apply_pulsef = 1; % Pulse shaping flag
fdac = 256e9; % DAC sampling rate
fadc = 256e9; % ADC sampling rate
random_key = 1;
rcalpha = 0.05; % Roll-off factor
kover = 16; % Oversampling factor
duob_mode = db_mode.db_precoded;
rcalpha = 0.05;
kover = 16;
% --- TX Optics (EML / Laser) ---
vbias_rel = 0.5;
u_pi = 3;
vbias = -vbias_rel*u_pi;
vbias = -vbias_rel * u_pi;
laser_wavelength = 1293;
laser_linewidth = 0;
tx_bw_nyquist = 0.8;
% Channel
% --- Channel ---
link_length = 1;
alpha = 0;
% RX
rop = -8;
rx_bw_nyquist = 0.8;
% --- RX & Equalization ---
rop = -2;
rx_bw_nyquist = 0.8;
len_tr = 4096 * 2;
vnle_order1 = 50;
vnle_order2 = 7;
vnle_order3 = 7;
% VNLE / FFE / DFE Orders
vnle_order1 = 50;
vnle_order2 = 7;
vnle_order3 = 7;
vnle_order = [vnle_order1, vnle_order2, vnle_order3];
dfe_order = [0, 0, 0];
dfe_ = sum(dfe_order) > 0;
vnle_order=[vnle_order1,vnle_order2,vnle_order3];
dfe_order = [0 0 0];
pf_ncoeffs = 1;
pf_ncoeffs = 1;
alpha = 0;
len_tr = 4096*2;
mu_ffe1 = 0.0001;
mu_ffe2 = 0.0008;
mu_ffe3 = 0.001;
mu_dc = 0.005;
% mu_dc = 0;
mu_ffe = [mu_ffe1 mu_ffe3 mu_ffe3];
mu_dfe = 0.0004;
dfe_ = sum(dfe_order)>0;
duob_mode = db_mode.no_db;
% Equalizer Step Sizes
mu_ffe1 = 0.0001;
mu_ffe2 = 0.0008;
mu_ffe3 = 0.001;
mu_ffe = [mu_ffe1, mu_ffe3, mu_ffe3];
mu_dfe = 0.0004;
mu_dc = 0.005;
%%% change specific parameter if given in varargin
% Parse optional input arguments
@@ -109,12 +102,12 @@ Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rc","pulselength",1
'duobinary_mode',duob_mode,...
"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
% 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.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");
%%%%% Low-pass el. components %%%%%%
@@ -132,7 +125,7 @@ El_sig = El_sig .* scaling;
%%%%% 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.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);
@@ -150,7 +143,6 @@ Rx_sig = Filter('filtdegree',4,"f_cutoff",rx_bwl,"fs",fdac*kover,"filterType",fi
% %%%%%% Low-pass Scope %%%%%%
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 %%%%%%
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));
%%%%%% 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 = Scpe_sig - mean(Scpe_sig.signal);
Scpe_sig.spectrum("displayname",'Filtered Digital Spectrum','fignum',100,'normalizeTo0dB',1);
%%% EQUALIZING
if 0
% -------------------- FFE --------------------
ffe_order = [50, 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);
output.ffe_results.metrics.print
end
if 0
% -------------------- DFE --------------------
eq_dfe = EQ("Ne",ffe_order,"Nb",[2,0,0], ...
"training_length",len_tr,"training_loops",5,"dd_loops",5, ...
@@ -198,33 +194,36 @@ output.dfe_results = ffe(eq_dfe,M,Scpe_sig,Symbols,Tx_bits, ...
"eth_style_symbol_mapping",0);
output.dfe_results.metrics.print("description",'DFE');
end
if 0
% -------------------- VNLE + MLSE --------------------
pf_ncoeffs = 1;
ffe_order3 = [50, 5, 5];
eq_v = EQ("Ne",ffe_order3,"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);
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
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, ...
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "eth_style_symbol_mapping", 0);
output.mlse_results.metrics.print("description",'MLSE');
end
if 1
% -------------------- VNLE + MLSE --------------------
pf_ncoeffs = 1;
ffe_order3 = [50, 5, 5];
eq_v = EQ("Ne",ffe_order3,"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);
pf_ = Postfilter("ncoeff",pf_ncoeffs,"useBurg",1);
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, ...
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", [], "eth_style_symbol_mapping", 0);
% -------------------- DB target --------------------
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,'trellis_states',PAMmapper(M,0).levels);
ffe_order = [50, 5, 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);
output.dbt_results = duobinary_target(eq_,mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
"precode_mode", duob_mode, 'showAnalysis', 0, "postFFE", []);
output.dbt_results.metrics.print("description",'Duobinary');
%% -------------------- DB target --------------------
mlse_db_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,'trellis_states',PAMmapper(M,0).levels);
ffe_order = [50, 5, 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,"DB_aim",0);
output.dbt_results = duobinary_target(eq_,mlse_db_, M, Scpe_sig, Symbols, Tx_bits, ...
"precode_mode", duob_mode, 'showAnalysis', 1, "postFFE", [],"decoding_mode","memoryless");
output.dbt_results.metrics.print("description",'Duobinary');
end
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
fprintf('\n')