From 2868887a157873dd3d9f63e152f7da8cd8e3157b Mon Sep 17 00:00:00 2001 From: Silas Oettinghaus Date: Wed, 7 Jun 2023 13:50:56 +0200 Subject: [PATCH] =?UTF-8?q?minor=20changes=20b=C3=BCro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Classes/00_signals/Signal.m | 19 ++-- Classes/02_etc/Filter.m | 6 +- Classes/03_receive/Photodiode.m | 1 + filter_debug.m | 70 +++++++++++++ setup_simulation.m | 174 ++++++++++++++++++-------------- 5 files changed, 186 insertions(+), 84 deletions(-) create mode 100644 filter_debug.m diff --git a/Classes/00_signals/Signal.m b/Classes/00_signals/Signal.m index 7d76852..e5b551c 100644 --- a/Classes/00_signals/Signal.m +++ b/Classes/00_signals/Signal.m @@ -168,19 +168,22 @@ classdef Signal fig = findall(groot, 'Type', 'figure', 'Name', 'power density'); if isvalid(fig) fig = get(fig); + ax = gca; hold on else figure('name','power density'); + ax = gca; end else fig = findall(groot, 'Type', 'figure', 'Name', options.figurename); if isvalid(fig) - fig = get(fig); + ax = fig.CurrentAxes; hold on else figure('name',options.figurename); + ax = gca; + hold on end - end @@ -200,10 +203,12 @@ classdef Signal psd = psd/length(Fsignal); %smoothing - psd = smooth(psd,100); + psd = smooth(psd,50); psd_plot = 20*log10(psd); + psd_plot(psd_plot<-120) = -120; + testParseval = 1; if testParseval == 1 @@ -225,9 +230,9 @@ classdef Signal if ~isempty(options.displayname) - plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5,'DisplayName',options.displayname); + plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5,'DisplayName',options.displayname,'Parent',ax); else - plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5); + plot(freq_vec*1e-9,psd_plot,'Linewidth',0.5,'Parent',ax); end xlabel('Frequency [GHz]') @@ -235,9 +240,9 @@ classdef Signal %Wavelength Axis freq_vec = physconst('LightSpeed')*linspace(-fsamp/2,fsamp/2,length(psd))./((physconst('LightSpeed')/1550e-9)^2); if ~isempty(options.displayname) - plot(freq_vec*1e9,psd_plot,'Linewidth',0.5,'DisplayName',options.displayname); + plot(freq_vec*1e9,psd_plot,'Linewidth',0.5,'DisplayName',options.displayname,'Parent',ax); else - plot(freq_vec*1e9,psd_plot,'Linewidth',0.5); + plot(freq_vec*1e9,psd_plot,'Linewidth',0.5,'Parent',ax); end xlabel('Wavelength [nm]') diff --git a/Classes/02_etc/Filter.m b/Classes/02_etc/Filter.m index f6164c6..e328e68 100644 --- a/Classes/02_etc/Filter.m +++ b/Classes/02_etc/Filter.m @@ -175,14 +175,14 @@ classdef Filter % hold on % plot(w/(2*pi)*obj.fsamp*1e-9,20*log10(abs(H)),'LineWidth',3); % ax = gca; -% ylim([-6 0]) +% %ylim([-6 0]) % grid on % xlabel('Freq in GHz') % ylabel('Magnitude (dB)') - % freqz(B, A) - %hfvt = fvtool(B,A); +% freqz(B, A, 2048, obj.fsamp); + % hfvt = fvtool(B,A); end end diff --git a/Classes/03_receive/Photodiode.m b/Classes/03_receive/Photodiode.m index c48b7cc..a1e5bdb 100644 --- a/Classes/03_receive/Photodiode.m +++ b/Classes/03_receive/Photodiode.m @@ -56,6 +56,7 @@ classdef Photodiode % Magnitude squared detection yout = sum( abs(xin) .^2*obj.responsivity, 2 ) ; + % Shot Noise shot_noise = sqrt(k * obj.fsimu .* yout) .* randn(size(yout,1),1); diff --git a/filter_debug.m b/filter_debug.m new file mode 100644 index 0000000..9d095fc --- /dev/null +++ b/filter_debug.m @@ -0,0 +1,70 @@ + +clear +%% Set Simulation Variables + +O = 18; %order of prbs +N = 2^(O-1); %length of prbs +[~,seed] = prbs(O,1); %initialize first seed of prbs + +% Modulation +M = 4; %PAM-M +bitpattern = zeros(N,log2(M)); + +% Symbol Rate +fsym = 112e9; + +% DAC Rate +fdac = 120e9; + +% Simulation oversampling rate "k"; +kover = 16; + +% ADC Rate +fadc = 256e9; + +% Simulation frequency in "analog domain" +fsimu = kover * fdac ; + + + +%% CONSTRUCT ALL CLASSES + +digimod = PAMmapper(M,0); + +pulsef = Pulseformer("pulseform","rrc","fdac",fdac,"fsym",fsym,"pulselength",32,"rrcalpha",0.05); + +awg = AWG('preset','M8199B','fdac',fdac,'kover',kover,'lpf_active',1,'f_cutoff',56e9,'lpf_type',filtertypes.gaussian,'bit_resolution',5.5); + +lp_laser = Filter('filtdegree',1,"f_cutoff",30e9,"fsamp",fdac,"filterType",filtertypes.bessel_inp); + + + +%% PROCESS + +% PRBS Generation +for i = 1:log2(M) + [bitpattern(:,i),seed] = prbs(O,N,seed); +end + +% Build Inf. signal class +bits = Informationsignal(bitpattern); + +% Digi Mod +mod_out = digimod.map(bits); +% merken für EQ training +reference = mod_out; + +% shape shape +mod_out = pulsef.process(mod_out); +test = applyPulseShaping(reference.signal,fsym,fdac); + +% AWG -> ELECTRICAL DOMAIN +X = lp_laser.process(mod_out); +%X.spectrum(fsimu,"displayname",'AWG out','figurename','after AWG'); + + + + + + + diff --git a/setup_simulation.m b/setup_simulation.m index b34e7e7..b095486 100644 --- a/setup_simulation.m +++ b/setup_simulation.m @@ -1,8 +1,10 @@ -clear -%% Set Simulation Variables -O = 18; %order of prbs +rng(2023); + +%% Set Simulation Variables + +O = 17; %order of prbs N = 2^(O-1); %length of prbs [~,seed] = prbs(O,1); %initialize first seed of prbs @@ -26,7 +28,6 @@ fadc = 256e9; fsimu = kover * fdac ; - %% CONSTRUCT ALL CLASSES digimod = PAMmapper(M,0); @@ -39,13 +40,13 @@ lp_laser = Filter('filtdegree',1,"f_cutoff",60e9,"fsamp",fdac,"filterType",fi u_pi = 4.6; vbias = (0.5*u_pi)-u_pi; -extmodlaser = EML("mode",eml_mode.im_cosinus,"power",5,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",10000); +extmodlaser = EML("mode",eml_mode.im_cosinus,"power",15,"fsimu",fsimu,"lambda",1550,"bias",vbias,"u_pi",u_pi,"linewidth",10000); amp = Amplifier("amp_mode","ideal_no_noise","amplification_db",0,"gain_mode","output_power"); -fib = Fiber("fsimu",fdac*kover,"fiber_length",0,"alpha",0.2,"D",17,"lambda0",1550,"gamma",0); +fib = Fiber("fsimu",fdac*kover,"fiber_length",1,"alpha",0.2,"D",17,"lambda0",1550,"gamma",0); -optatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",5); +optatten = Amplifier("amp_mode","ideal_no_noise","gain_mode","output_power","amplification_db",0); edfaamp = Amplifier("amp_mode","edfa_increase_nase","gain_mode","output_power","amplification_db",0,"nase_mode","generate_ase","noifig",5); @@ -54,98 +55,123 @@ phdiode = Photodiode("fsimu",fdac*kover,"dark_current",2e-08,"responsivity", lp_diode = Filter('filtdegree',1,"f_cutoff",80e9,"fsamp",fdac,"filterType",filtertypes.bessel_inp); scp = Scope("fsimu",fdac*kover,"fadc",fadc,... - "delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,... - "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... - "adcresolution",6,"quantbuffer",0.1); - -eq = EQ("K",2,"plottrain",0,"plotfinal",1,... - "training_length",4096,"training_loops",5,... - "Ne",[50,0,0],"Nb",[0,0,0],... - "DCmu",0.005,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.005,"FFEmu",0.000,... - "dd_loops",2,"epsilon",[10 100 1000 ],"M",4,... - "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",1,"rho",0.0005,"ideal_dfe",0,"DB_aim",0); + "delay",0,"fixed_delay",0,"lpf_bw",113e9,"filtertype",filtertypes.butterworth,... + "samplingdelay",0,"rand_samplingdelay",0,"freq_offset",0,"samp_jitter",0,... + "adcresolution",6,"quantbuffer",0.1); +eq = EQ("K",2,"plottrain",0,"plotfinal",0,... + "training_length",4096,"training_loops",5,... + "Ne",[30,0,0],"Nb",[0,0,0],... + "DCmu",0.005,"DDmu",[0.0004 0.0004 0.0004 0.0004 ],"DFEmu",0.002,"FFEmu",0.00,... + "dd_loops",2,"epsilon",[10 100 1000 ],"M",4,... + "thres",[0.005 0.004 0.0005 ],"l1act",0,"delay",0,"rho",0.0005,"ideal_dfe",0,"DB_aim",0); %% PROCESS -% PRBS Generation -for i = 1:log2(M) - [bitpattern(:,i),seed] = prbs(O,N,seed); +output_pow = 0 +for lp1 = 1:length(output_pow) + + % change parameters + optatten.amplification_db = output_pow(lp1); + + + % PRBS Generation + for i = 1:log2(M) + [bitpattern(:,i),seed] = prbs(O,N,seed); + end + + bitpattern = prms_out'; + + % Build Inf. signal class + bits = Informationsignal(bitpattern); + + % Digi Mod + mod_out = digimod.map(bits); + + % merken für EQ training + reference = mod_out; + + % shape shape + mod_out = pulsef.process(mod_out); + test = applyPulseShaping(reference.signal,fsym,fdac); + + % AWG -> ELECTRICAL DOMAIN + X = awg.process(mod_out); + + X = lp_laser.process(X); + + X = X.normalize; + + % Laser; Modulation -> OPTICAL DOMAIN + X = extmodlaser.process(X); + %X.spectrum(fsimu,"displayname",'laser out','figurename','after laser'); + + %X = amp.process(X); + + % Fiber Propagation + X = fib.process(X); + X = optatten.process(X); + X = edfaamp.process(X); + + % Photo Diode -> ELECTRICAL DOMAIN + X = phdiode.process(X); + X = lp_diode.process(X); + %X.spectrum(fsimu,"displayname",'diode out','figurename','after diode'); + % Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) + X = scp.process(X); + + % Resample to Symbol Rate + X = X.resample("fs_out",2*fsym,"fs_in",fadc); + + % INFORMATION SIGNAL + X = X.normalize; + + % Equalizer + eq_out = eq.process(X,reference); + rx_series = eq_out.signal; + + % Digi Demod + demap_out = digimod.demap(eq_out); + + % BER + [bits,errors,BER] = calc_ber(demap_out.signal(:,1:end-1),bitpattern(1:end,:)',0); + disp(['BER: ', sprintf('%2E',BER), ' ERRORS: ' ,num2str(sum(errors))]); + + bercurve(lp1) = BER; + errorscurve(lp1) = sum(errors); end -% Build Inf. signal class -bits = Informationsignal(bitpattern); -% Digi Mod -mod_out = digimod.map(bits); -% merken für EQ training -reference = mod_out; -% shape shape -mod_out = pulsef.process(mod_out); -test = applyPulseShaping(reference.signal,fsym,fdac); -% AWG -> ELECTRICAL DOMAIN -X = awg.process(mod_out); -X = lp_laser.process(X); -X = X.normalize; -% Laser; Modulation -> OPTICAL DOMAIN -X = extmodlaser.process(X); -X.spectrum(fsimu,"displayname",'laser out','figurename','after laser'); -%X = amp.process(X); -% Fiber Propagation -X = fib.process(X); -X = optatten.process(X); -X = edfaamp.process(X); -% Photo Diode -> ELECTRICAL DOMAIN -X = phdiode.process(X); -X = lp_diode.process(X); -X.spectrum(fsimu,"displayname",'diode out','figurename','after diode'); -% Oscilloscope (Sampling to f_adc; Quantization; Bandwidth Limitation) -X = scp.process(X); -% Resample to Symbol Rate -X = X.resample("fs_out",2*fsym,"fs_in",fadc); -% INFORMATION SIGNAL -X = X.normalize; -% Equalizer -eq_out = eq.process(X,reference); -rx_series = eq_out.signal; -% Digi Demod -demap_out = digimod.demap(eq_out); - -% BER -[bits,errors,BER] = calc_ber(demap_out.signal(:,1:end-1),bitpattern(1:end,:)',0); -disp(['BER: ', sprintf('%2E',BER)]); - -% disp(demap_out.logbook); %% Generate some Plots if 0 col = cbrewer2('Paired',8); - + figure(22) clf -% subplot(3,1,1) -% hold on -% plot(reference.signal(10000:end-20),'DisplayName','Tx','Color',col(1,:),'LineWidth',3); -% plot(rx_series(10000:end-20),'DisplayName','Rx','Color',col(6,:)); -% title('Modulated Sequence Tx - Rx'); -% legend -% hold off + % subplot(3,1,1) + % hold on + % plot(reference.signal(10000:end-20),'DisplayName','Tx','Color',col(1,:),'LineWidth',3); + % plot(rx_series(10000:end-20),'DisplayName','Rx','Color',col(6,:)); + % title('Modulated Sequence Tx - Rx'); + % legend + % hold off subplot(2,1,1) hold on plot(reference.signal(4150:4175),'DisplayName','Tx','Color',col(1,:),'LineWidth',3); @@ -160,10 +186,10 @@ if 0 title('Bitpattern Tx - Rx'); legend hold off - - + + xax = 1:eq_out.length; - + figure(12) sgtitle('') subplot(1,4,1:2) @@ -173,7 +199,7 @@ if 0 xlabel('Sampling Index') ylabel('Amplitude') legend - + subplot(1,4,3:4) scatter(xax,eq_out.signal,4,'.','MarkerEdgeColor',col(6,:),'DisplayName','After EQ'); xlim([1, xax(end)]);