dsp_options.storage_path = 'Z:\2024\sioe_labor\'; dsp_options.max_occurences = 1; database = DBHandler("dataBase", 'labor_highspeed', "type", 'mysql' ); run_id = 2776; dataTable = queryRunid(run_id, database); fsym = dataTable.symbolrate; M = double(dataTable.pam_level); duob_mode = db_mode(strrep(dataTable.db_mode,'"','')); % if database.checkIfRunExists('Results','run_id',run_id) % disp(['Already got at least one reulst for run id: ',num2str(run_id),' ']) % return % end % Load and Sync signal data from DB [Tx_bits, Symbols, Scpe_cell, ~] = loadAndSyncSignalDataFromDb(dataTable, dsp_options); % Preprocess signal Scpe_sig = preprocessSignal(Scpe_cell{1}, Symbols, fsym); Scpe_sig.spectrum("fignum",1,"displayname",'Rx') %% ffe_order = [50, 5, 5]; mu_ffe = [0.0001, 0.0008, 0.001]; mu_dfe = 0.0004; eq_ = EQ("Ne",ffe_order,"Nb",[0,0,0],"training_length",2^14,"training_loops",5,"dd_loops",5,"K",2,"DCmu",0.005,"DDmu",[mu_ffe mu_dfe],"DFEmu",0.005,"FFEmu",0,"plotfinal",0,"ideal_dfe",1); mlse_ = MLSE("DIR",[1,1],"duobinary_output",0,"M",M,"trellis_states",PAMmapper(M,0).levels,'scale_mode',2,'trellis_exclusion',0,'trellis_state_mode',3); %Duobinary Targeting db_ref_sequence = Duobinary().encode(Symbols); db_ref_constellation = unique(db_ref_sequence.signal); [eq_signal, eq_noise] = eq_.process(Scpe_sig,db_ref_sequence); %% if 0 [mlse_sig_sd,LLR,GMI_MLSE] = mlse_.process(eq_signal,Symbols); else % Ml MLSE ml_mlse_equalizer = ML_MLSE("epochs_tr",20,"epochs_dd",1,"len_tr",length(eq_signal),... "mu_dd",0.01,"mu_tr",0.01,"order",11,"sps",2,... "traceback_depth",128,"L",1,"delta",4,'adaptive_mu',0); [mlse_sig_sd,ref_sig] = ml_mlse_equalizer.process(Scpe_sig,db_ref_sequence); end %% mlse_sig_sd_decoded = Duobinary().decode(mlse_sig_sd,"M",M); ref_sig_decoded = Duobinary().decode(db_ref_sequence,"M",M); mlse_sig_bits = PAMmapper(M,0,"eth_style",0).demap(mlse_sig_sd_decoded); ref_sig_bits = PAMmapper(M,0,"eth_style",0).demap(ref_sig_decoded); err = sum(ref_sig_decoded.signal ~= mlse_sig_sd_decoded.signal); [bits_db,errors_db,ber_db,a] = calc_ber(mlse_sig_bits.signal,ref_sig_bits.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1); %% switch duob_mode case db_mode.no_db % TX Data is not precoded: % A) Emulate diff precoding mlse_sig_hd_precoded = Duobinary().encode(mlse_sig_hd,"M",M); mlse_sig_hd_precoded = Duobinary().decode(mlse_sig_hd_precoded,"M",M); tx_symbols_precoded = Duobinary().encode(Symbols); 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); 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); %B) Just determine BER rx_bits_mlse = PAMmapper(M,0,"eth_style",options.eth_style_symbol_mapping).demap(mlse_sig_hd); [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 % 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! mlse_sig_hd_decoded = Duobinary().encode(mlse_sig_hd,"M",M); mlse_sig_hd_decoded = Duobinary().decode(mlse_sig_hd_decoded,"M",M); rx_bits_mlse_decoded = PAMmapper(M,0,"eth_style",0).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); burst_db_precoded = count_error_bursts(a, 40); % B) Omit the Coding by comparing with demapped TX symbol sequence Tx_bits_ = PAMmapper(M,0,"eth_style",0).demap(Symbols); rx_bits_mlse = PAMmapper(M,0,"eth_style",0).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 %% SHOW Loss during training mu = logspace(-3,-0.8,12); ber_ml_mlse = zeros(size(mu)); ber_training = []; ce_training = []; parfor i = 1:numel(mu) ml_mlse_equalizer = ML_MLSE("epochs_tr",200,"epochs_dd",1,"len_tr",length(Scpe_sig),... "mu_dd",mu(i),"mu_tr",mu(i),"order",11,"sps",2,... "traceback_depth",128,"L",2,"delta",4,'adaptive_mu',0); [y_ml_mlse,y_ref] = ml_mlse_equalizer.process(Scpe_sig,Symbols); ref_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ref); ml_mlse_bits = PAMmapper(M, 0, "eth_style", 0).demap(y_ml_mlse); [~, errors, ber_ml_mlse(i), errpos] = calc_ber(ml_mlse_bits.signal, ref_bits.signal, "skip_front", 10, "skip_end", 10, "returnErrorLocation", 1); fprintf('ML MLSE BER: %.2e \n',ber_ml_mlse(i)); ber_training(i,:) = ml_mlse_equalizer.ber; ce_training(i,:) = ml_mlse_equalizer.ce; end %% figure();hold on plot(mu,ber_ml_mlse,'DisplayName','ML-based MLSE'); beautifyBERplot; xlim([mu(1), mu(end)]); xlabel('mu'); ylabel('BER'); title('PAM-4; M=3; AWGN Channel'); ylim([1e-5 0.1]); %% figure() hold on; cols = cbrewer2('Spectral',12); for i = 1:12 plot(1:200,ber_training(i,:),'DisplayName', sprintf('mu=%.3f ',mu(i)),'Color',cols(i,:)); end set(gca,'YScale','log'); xlabel('Epoch'); ylabel('BER'); title('PAM-4; L=3; SNR=20; AWGN Channel'); plot(1:200,ml_mlse_equalizer_adap.ber,'DisplayName','Adaptive mu');