diff --git a/Classes/01_transmit/PAMmapper.m b/Classes/01_transmit/PAMmapper.m index 451c85b..6ff22ec 100644 --- a/Classes/01_transmit/PAMmapper.m +++ b/Classes/01_transmit/PAMmapper.m @@ -14,9 +14,10 @@ classdef PAMmapper % Detailed explanation goes here obj.M = M; obj.unipolar = unipolar; - + obj.thresholds = obj.get_demodulation_thresholds(); + end function out = map(obj,signal_in) @@ -39,7 +40,7 @@ classdef PAMmapper function pam_sig = map_(obj,bitpattern) - switch log2(obj.M) + switch obj.M case 1 % 2-ASK: BPSK / OOK pam_sig=bitpattern(:,1); @@ -48,7 +49,7 @@ classdef PAMmapper pam_sig=2*pam_sig-1; end - case 2 + case 4 % 4-ASK: pam_sig=2*bitpattern(:,1)+(bitpattern(:,1)==bitpattern(:,2)); @@ -58,8 +59,21 @@ classdef PAMmapper pam_sig = pam_sig .* 1/sqrt(5); + case 6 + + m = 1; + if size(bitpattern,2)>size(bitpattern,1) + bitpattern = bitpattern'; %vector aufrecht stellen + end + % LUT based mapping + for k = 1:5:fix(length(bitpattern)/5)*5 + pam_sig(m:m+1,1) = obj.thresholds(bin2dec(int2str(bitpattern(k:k+4)'))+1,:); + m = m+2; + end - case 3 + pam_sig = pam_sig/sqrt(10); + + case 8 % 8-ASK: x1 = bitpattern(:,1); x2 = (bitpattern(:,1)==bitpattern(:,3)); @@ -72,7 +86,7 @@ classdef PAMmapper end - case 4 + case 16 % 16-ASK: x1 = bitpattern(:,1); x2 = (bitpattern(:,1)==bitpattern(:,4)); @@ -94,9 +108,9 @@ classdef PAMmapper %28.03.2023 - Silas Oett. - Extracted from digi_demod.m % - switch log2(obj.M) + switch obj.M - case 1 + case 2 % 2-ASK if obj.unipolar @@ -105,7 +119,7 @@ classdef PAMmapper thres=0; end - case 2 + case 4 % 4-ASK if obj.unipolar==0 thres=[-2,0,2]; @@ -114,7 +128,11 @@ classdef PAMmapper end thres = thres .* 1/sqrt(5); - case 3 + case 6 %PAM 6 + + thres = [-3 5;-1 5;-3 -5;-1 -5;-5 3;-5 1;-5 -3;-5 -1;-1 3;-1 1;-1 -3;-1 -1;-3 3;-3 1;-3 -3;-3 -1;3 5;1 5;3 -5;1 -5;5 3;5 1;5 -3;5 -1;1 3;1 1;1 -3;1 -1;3 3;3 1;3 -3;3 -1]; + + case 8 % 8-ASK if obj.unipolar==0 thres=-6:2:6; @@ -122,7 +140,7 @@ classdef PAMmapper thres=0.5:6.5; end - case 4 + case 16 % 16-ASK if obj.unipolar==0 && scale_mode==1 thres=-14:2:14; @@ -135,44 +153,67 @@ classdef PAMmapper end function [data_out] = demap_(obj,data_in) - data_in= data_in'; - % create output - if ~isempty(obj.thresholds) - a = squeeze(repmat(real(data_in),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten - b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1])); %Threshold in 3 Spalten - comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3 - - comp_real=repmat(real(data_in),[1 1 length(obj.thresholds)]) > repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1]); - - else - comp_real=[]; + if obj.M ~= 6 + + % create output + if ~isempty(obj.thresholds) + a = squeeze(repmat(real(data_in),[1 1 length(obj.thresholds)])); %Eingangssignal in 3 spalten + b = squeeze(repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1])); %Threshold in 3 Spalten + comp_real = a > b; %check for each symbol/ sampling if it exeeds the obj.thresholdseshold 1, 2 or 3 + + comp_real=repmat(real(data_in),[1 1 length(obj.thresholds)]) > repmat(reshape(obj.thresholds(:).',[1 1 length(obj.thresholds)]),[1 length(data_in) 1]); + + else + comp_real=[]; + end + + s1=size(comp_real,1); + s2=size(comp_real,2); end - s1=size(comp_real,1); - s2=size(comp_real,2); + switch obj.M - - switch log2(obj.M) - - case 1 + case 2 % 2-ASK data_out=comp_real(:,:,1); - case 2 + case 4 % 4-ASK data_out=[comp_real(:,:,2); ones(s1,s2) - comp_real(:,:,1) + comp_real(:,:,3)]; + case 6 - case 3 + data_in = data_in/(sqrt(mean(abs(data_in).^2))); + data_in = data_in*sqrt(10); + + if size(data_in,2) > 1 + data_in = data_in.'; + end + + if length(data_in)/2 ~= round(length(data_in)/2) + data_in = [data_in;0]; + end + + m = 1; + for n = 1:2:length(data_in) + dist = sqrt((data_in(n)-obj.thresholds(:,1)).^2+(data_in(n+1)-obj.thresholds(:,2)).^2); + [~,dd_idx] = min(dist); + % dec_out(n:n+1) = LUT(dd_idx,:); + data_out(m:m+4) = bitget(dd_idx-1,5:-1:1); + m = m+5; + end + + + case 8 % 8-ASK data_out=[comp_real(:,:,4); comp_real(:,:,1)-comp_real(:,:,3)+comp_real(:,:,5)-comp_real(:,:,7); 1-comp_real(:,:,2)+comp_real(:,:,6)]; - case 4 + case 16 % 16-ASK data_out=[comp_real(:,:,8); comp_real(:,:,1)-comp_real(:,:,3)+comp_real(:,:,5)-comp_real(:,:,7)+comp_real(:,:,9)-comp_real(:,:,11)+comp_real(:,:,13)-comp_real(:,:,15); diff --git a/Classes/02_etc/Filter.m b/Classes/02_etc/Filter.m index 35b017a..10118a3 100644 --- a/Classes/02_etc/Filter.m +++ b/Classes/02_etc/Filter.m @@ -180,7 +180,7 @@ classdef Filter < handle function show(obj) - obj.signal_length = 512; + obj.signal_length = 512*8; [H_,~] = obj.buildFilter(); figure() diff --git a/Classes/04_DSP/EQ_silas.m b/Classes/04_DSP/EQ_silas.m index 39cbfa3..5cf4eb7 100644 --- a/Classes/04_DSP/EQ_silas.m +++ b/Classes/04_DSP/EQ_silas.m @@ -182,7 +182,6 @@ classdef EQ_silas < handle % Calculate the Error obj.error = obj.e_dc + obj.e_ffe - obj.e_dfe - obj.d(obj.Nb(1)-1+m-obj.delay); - if obj.mu_ffe_train ~= 0 %update FFE coefficients with LMS obj.e = obj.e - obj.error*conj(x_in_vnle_format)*obj.mu_ffe_train; diff --git a/Functions/calc_ber.m b/Functions/calc_ber.m index fb5a9af..c5cd69a 100644 --- a/Functions/calc_ber.m +++ b/Functions/calc_ber.m @@ -41,13 +41,13 @@ if length(data_ref) == length(data_in) ber = sum(errors)/sum(bits); else - errormsg('Sequence length does not match'); + error('Sequence length does not match'); end function [data_,reference_]=trimseq(data,reference,skipstart,skip_end) data_ = logical(data(skipstart+1:end-skip_end,:))'; - + delta_bits = length(reference) - length(data); skip_end = max(skip_end,delta_bits); diff --git a/projects/MPI_April/mpi_simulation_cspr.m b/projects/MPI_April/mpi_simulation_cspr.m index ca1f15c..c93efad 100644 --- a/projects/MPI_April/mpi_simulation_cspr.m +++ b/projects/MPI_April/mpi_simulation_cspr.m @@ -9,33 +9,40 @@ datarate = 448e9; kover = 4; fsym = round(datarate*1e-9 / log2(M))*1e9; -%fsym = 50e9; fdac = 256e9; fadc = 256e9; -lowpass_cutoff = fsym/2 * 1.5; +lowpass_cutoff = fsym/2 * 1.1; awg_bw = lowpass_cutoff; mod_bw = lowpass_cutoff; phd_bw = lowpass_cutoff; scp_bw = lowpass_cutoff; -mpi_path=50; - -LP_awg = Filter('filtdegree',2,"f_cutoff",awg_bw,"fs",fdac*kover,"filterType","butterworth"); -LP_laser = Filter('filtdegree',4,"f_cutoff",mod_bw,"fs",fdac*kover,"filterType",filtertypes.gaussian); +LP_awg = Filter('filtdegree',4,"f_cutoff",90e9,"fs",fdac*kover,"filterType",filtertypes.butterworth); +LP_laser = Filter('filtdegree',2,"f_cutoff",100e9,"fs",fdac*kover,"filterType",filtertypes.gaussian); LP_opt = Filter('filtdegree',4,"f_cutoff",fsym/log2(M).*1.5,"fs",fdac*kover,"filterType",filtertypes.gaussian); -LP_phd = Filter('filtdegree',2,"f_cutoff",phd_bw,"fs",fdac*kover,"filterType",filtertypes.butterworth); -LP_scpe = Filter('filtdegree',2,"f_cutoff",scp_bw,"fs",fadc,"filterType","butterworth"); +LP_phd = Filter('filtdegree',2,"f_cutoff",70e9,"fs",fdac*kover,"filterType",filtertypes.butterworth); +LP_scpe = Filter('filtdegree',4,"f_cutoff",110e9,"fs",fadc,"filterType",filtertypes.butterworth); + +figure(2) +LP_awg.showHere; +% LP_laser.showHere; +% LP_opt.showHere; +% LP_phd.showHere; +% LP_scpe.showHere; % 1) PRBS Generation O = 18; %order of prbs N = 2^(O-1); %length of prbs [~,seed] = prbs(O,1); %initialize first seed of prbs bitpattern=[]; - for i = 1:log2(M) [bitpattern(:,i),seed] = prbs(O,N,seed); end +if M == 6 + bitpattern = reshape(bitpattern,[],1); + bitpattern = bitpattern(1:end-mod(length(bitpattern),5)); +end % 2 ) Build Inf. signal class bits = Informationsignal(bitpattern); @@ -56,17 +63,18 @@ X = LP_laser.process(X); X = X.normalize("mode","oneone"); sir = [20:2:36]; %decibel = attenuation of interference path - laser_linewidth = [1e5 1e6 3e6 10e6]; + laser_linewidth = [1e5 1e6 10e6]; pn_key = [1:10]; vp = [0.25,0.5,0.75,1]; vb = [1:0.1:1.8]; - rop = -9:3; + rop = [-5:0]; % sir = 25; % laser_linewidth = 1e6; -% pn_key = 1; -% vp = 0.8; -% vb = 1; +% pn_key = 9; +% vp = 0.5; +% vb = [1:0.1:1.8]; +mpi_path=50; cnt = 1; for s = 1:length(sir) @@ -81,7 +89,7 @@ for s = 1:length(sir) u_pi = 2; vbias = -vb(m); extmodlaser = EML("mode",eml_mode.im_cosinus,"power",3,"fsimu",X.fs,"lambda",1290,"bias",vbias,"u_pi",u_pi,"linewidth",laser_linewidth(l),"randomkey",pn_key(pnk)); - E = X.*vp(1); + E = X.*vp(n); % E.signal = min(max(E.signal,-0.2),0.2); @@ -119,7 +127,7 @@ for s = 1:length(sir) % Fiber Combined_sig = Fiber("fsimu",Combined_sig.fs,"fiber_length",2,"alpha",0.3,"D",0,"lambda0",1310,"gamma",0,"Dslope",0.08).process(Combined_sig); - parfor i = 1:length(rop) + for i = 1:length(rop) % Set ROP Rx_sig = Amplifier("amp_mode","ideal_no_noise","gain_mode","gain","amplification_db",rop(i)).process(Combined_sig); @@ -132,16 +140,16 @@ for s = 1:length(sir) Rx_sig = LP_phd.process(Rx_sig); % Scope - Rx_sig = Scope("fsimu",Rx_sig.fs,"fadc",fadc,... + Scpe_sig = Scope("fsimu",Rx_sig.fs,"fadc",fadc,... "delay",0,"fixed_delay",0,"lpf_bw",scp_bw,"filtertype",filtertypes.butterworth,... "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... "adcresolution",16,"quantbuffer",0.1,'block_dc',1,'lpf_active',1,'H_lpf',LP_scpe).process(Rx_sig); % Sample to 2x fsym - Rx_sig = Rx_sig.resample("fs_in",fadc,"fs_out",2*fsym); + Scpe_sig = Scpe_sig.resample("fs_in",fadc,"fs_out",2*fsym); % Sync Rx signal with reference - [Rx_sig,D,cuts] = Rx_sig.tsynch("reference",digimod_out,"fs_ref",fsym); + [Scpe_sig,D,cuts] = Scpe_sig.tsynch("reference",digimod_out,"fs_ref",fsym); % % % simple EQ (optimum mudc: 0.05 -> 0.005) % EQ_sig = EQ_silas_plain("Ne",[20,8,8],"Nb",[2,0,0],"trainlength",4096,"mu_dc_dd",0.005,"mu_dc_train",0.05,... @@ -149,12 +157,12 @@ for s = 1:length(sir) % % EQ_sig = EQ("K",2,"plottrain",0,"plotfinal",0,... % "training_length",4096,"training_loops",3,... -% "Ne",[20,8,8],"Nb",[2,0,0],... -% "DCmu",0.005,"DDmu",[0.0004 0.0006 0.0003 0.005],"DFEmu",0.005,"FFEmu",0.00,... +% "Ne",[50,8,8],"Nb",[2,0,0],... +% "DCmu",0.00,"DDmu",[0.0004 0.0006 0.0003 0.005],"DFEmu",0.005,"FFEmu",0.00,... % "dd_loops",3,"epsilon",[10 100 1000 ],"M",2,... -% "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0).process(Rx_sig,digimod_out); +% "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0).process(Scpe_sig,digimod_out); - EQ_sig = EQ_silas("Ne",[20,2,0],"Nb",[2,0,0],"trainlength",4096,... + EQ_sig = EQ_silas("Ne",[50,8,8],"Nb",[2,0,0],"trainlength",4096,... "sps",2,... "mu_dc_dd",0.00,... "mu_dc_train",0.00,... @@ -166,18 +174,18 @@ for s = 1:length(sir) "trainloops",3,... "eq_parallelization_blocklength",1, ... "eq_updatelatency",1,... - "eq_avg_blocklength",0).process(Rx_sig,digimod_out); + "eq_avg_blocklength",0).process(Scpe_sig,digimod_out); % Demap Rx_Bits = PAMmapper(M,0).demap(EQ_sig); - - Rx_symboldecision = PAMmapper(M,0).decide_pamlevel(EQ_sig,"symbol_levels",unique(digimod_out.signal)); - - levels = PAMmapper(M,0).separate_pamlevels(EQ_sig); - %levels = PAMmapper(M,0).separate_pamlevels(Rx_sig.resample("fs_in",Rx_sig.fs,"fs_out",fsym)); - - level_avg(s,l,pnk,n,m,i,:) = mean(levels,'omitnan'); - level_std(s,l,pnk,n,m,i,:) = std(levels,'omitnan'); +% +% Rx_symboldecision = PAMmapper(M,0).decide_pamlevel(EQ_sig,"symbol_levels",unique(digimod_out.signal)); +% +% levels = PAMmapper(M,0).separate_pamlevels(EQ_sig); +% %levels = PAMmapper(M,0).separate_pamlevels(Rx_sig.resample("fs_in",Rx_sig.fs,"fs_out",fsym)); +% +% level_avg(s,l,pnk,n,m,i,:) = mean(levels,'omitnan'); +% level_std(s,l,pnk,n,m,i,:) = std(levels,'omitnan'); % BER [~,errors_bm,BER(s,l,pnk,n,m,i),errors] = calc_ber(Rx_Bits.signal,bitpattern,"skip_front",0,"skip_end",0,"returnErrorLocation",1); @@ -191,12 +199,22 @@ for s = 1:length(sir) end end end - save('big_run_easy_EQ_one_nonlin'); + save('pam_level_comp'); disp('saved_run2'); end end end +% figure('Name','spectrum') +% tiledlayout(4,1) +% nexttile +% spectrum_plot(E.signal,E.fs,'spectrum'); +% nexttile +% spectrum_plot(Opt.signal,Opt.fs,'spectrum'); +% nexttile; +% spectrum_plot(Rx_sig.signal,Rx_sig.fs,'spectrum'); +% nexttile +% spectrum_plot(EQ_sig.signal,EQ_sig.fs,'spectrum');