PR and DB fummelei

This commit is contained in:
Silas Oettinghaus
2026-04-23 16:16:45 +02:00
parent 5446275a5b
commit 8fd68c0a54
6 changed files with 104 additions and 183 deletions

View File

@@ -0,0 +1,54 @@
M = 4;
apply_precode = 1;
bits = Signalgenerator( ...
"form", signalform.prms, ...
"M", M, ...
"order", 15).process();
symbols = PAMmapper(M,0).map(bits);
bits_rx = PAMmapper(M,0).demap(symbols);
[~,~,ber_direct,~] = calc_ber(bits.signal,bits_rx.signal,"skip_front",0,"skip_end",0,"returnErrorLocation",1);
if apply_precode
symbols_tx = Duobinary().precode(symbols);
else
symbols_tx = symbols;
end
show2Dconstellation(symbols_tx,symbols_tx,"displayname",'VNLE Out','fignum',2241);
if apply_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(symbols_tx);
disp(['DB encoded -- RMS:',sprintf('%.1f',rms(symbols_db.signal)),' - - Levels -',num2str(numel(unique(symbols_db.signal)))]);
unique(symbols_db.signal)
disp('- - - - - - - - - -');
% Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4
symbols_rx = Duobinary().decode(symbols_db);
else
symbols_rx = symbols_tx;
end
% Vergleichen von b(n) und d_dec(n)
bits_rx = PAMmapper(M,0).demap(symbols_rx);
disp(['Wieder normal -- RMS:',sprintf('%.1f',rms(symbols_rx.signal)),' - - Levels -',num2str(numel(unique(symbols_rx.signal)))]);
unique(symbols_rx.signal)
disp('- - - - - - - - - -');
[~,~,ber,~] = calc_ber(bits.signal,bits_rx.signal,"skip_front",10,"skip_end",10,"returnErrorLocation",1);
disp(['BER: ',sprintf('%.1E',ber),' - - PAM-',num2str(M)]);
figure()
subplot(1,2,1)
histogram(symbols_tx.signal,100,'Normalization','probability')
subplot(1,2,2)
histogram(symbols_db.signal,100,'Normalization','probability')

View File

@@ -0,0 +1,102 @@
useprbs = 1;
M = 2;
randkey = 1;
datarate = 448e9;
fsym = round(datarate / log2(M)) ;
Tx_bits = Signalgenerator( ...
"form", signalform.prms, ...
"M", M, ...
"order", 15).process();
%%%%% Duobinary %%%%%%
close all
Symbols_tx = PAMmapper(M,0,"eth_style",0).map(Tx_bits);
Symbols_tx.fs = fsym;
precode = db_mode.db_precoded;
%%% precode
switch precode
case db_mode.db_precoded
Symbols_tx = Duobinary().precode(Symbols_tx);
case db_mode.db_encoded
Symbols_tx = Duobinary().precode(Symbols_tx);
Symbols_tx = Duobinary().encode(Symbols_tx);
case db_mode.no_db
end
for n = 10
Symbols_rx = Symbols_tx;
pos = 1;
if n~=0
for pos = 1:n
po = randi(100);
a = Symbols_rx.signal(100+pos) == Symbols_tx.signal(100+po);
while a == 1
po = po+1;
po = randi(100);
a = Symbols_rx.signal(100+pos) == Symbols_tx.signal(100+po);
end
Symbols_rx.signal(100+pos) = Symbols_tx.signal(100+po);
end
end
error_positions = ~(Symbols_rx.signal == Symbols_tx.signal);
error_positions = find(error_positions==1);
switch precode
case db_mode.db_precoded
Symbols_rx = Duobinary().encode(Symbols_rx);
Symbols_rx = Duobinary().decode(Symbols_rx);
case db_mode.db_encoded
Symbols_rx = Duobinary().decode(Symbols_rx);
end
Rx_bits = PAMmapper(M,0).demap(Symbols_rx);
%%%%% Check BER of Bit Sequence %%%%%
[~,error_num(n+1),ber,error_pos] = calc_ber(Tx_bits.signal,Rx_bits.signal,"skip_front",10,"skip_end",10,"returnErrorLocation",1);
% disp(['BER: ',sprintf('%.1E',ber),sprintf(' - Num. Err: %.1d',error_num(n+1)-2),' - - PAM-',num2str(M)]);
fprintf('n: %d - Num. Err: %.1d \n',n,error_num(n+1));
end
figure(3);
clf
%sgtitle(['BER: ',num2str(ber),' // Error is at position: ',num2str(error_pos),''])
subplot(2,2,1)
hold on
title('First Bits')
stairs(Tx_bits.signal(100:150,1),'LineStyle','-','LineWidth',2,'DisplayName','Tx Bits');
stairs(Rx_bits.signal(100:150,1),'LineWidth',2,'DisplayName','Rx Bits','LineStyle',':')
legend
subplot(2,2,2)
title('Last Bits')
hold on
stairs(Tx_bits.signal(end-50:end,1),'LineStyle','-','LineWidth',2,'DisplayName','Tx Bits');
stairs(Rx_bits.signal(end-50:end,1),'LineWidth',2,'DisplayName','Rx Bits','LineStyle',':')
legend
subplot(2,2,3)
hold on
title('First Symbols Compare')
stairs(Symbols_tx.signal(1:100,1),'LineWidth',2,'DisplayName','Tx Symbols','LineStyle','-')
stairs(Symbols_rx.signal(1:100,1),'LineStyle',':','LineWidth',2,'DisplayName','Rx Symbols');
legend
subplot(2,2,4)
hold on
title('Last Symbols Compare')
stairs(Symbols_tx.signal(end-50:end,1),'LineWidth',2,'DisplayName','Tx Symbols','LineStyle','-')
stairs(Symbols_rx.signal(end-50:end,1),'LineStyle',':','LineWidth',2,'DisplayName','Rx Symbols');
legend

View File

@@ -0,0 +1,73 @@
M = 6;
data = [1,2,3,4,5,6];
M = 6;
bitpattern = [];
s = RandStream('twister','Seed',1);
for i = 1:log2(M)
N = 2^(12-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
bits = Informationsignal(bitpattern);
symbols = PAMmapper(M,0).map(bits);
symbols_tx_prec = Duobinary().precode(symbols);
% all possible transitions (for now 36, including the "edges"
% of the QAM 32 constellation)
states = PAMmapper(6,0,"eth_style",0).levels;
pam6transitions = combvec(states,states)'; % pam6transitions =
% [-5 -5;
% -3 -5;
% -1 -5; ...
pam6transitions_serial = reshape(pam6transitions',[],1);
data = pam6transitions_serial;
data = round(data);
b = min(data);
data = data - b;
data = data ./ 2;
% THIS WAS USED!
bk = zeros(size(data));
for k = 2:numel(data)
bk(k) = mod(data(k)-bk(k-1),M);
end
%% State Analysis
x = bk;%symbols_tx_prec.signal;
levels = sort(unique(x)).'; % or provide known 1x6 level values
[~,ix] = min(abs(x - levels),[],2);
x = levels(ix); % snapped/quantized
%% TRANSITION COUNTS & PROBABILITIES
K = numel(levels);
% map to state indices 1..K
[tf, idx] = ismember(x, levels);
idx = idx(:);
from = idx(1:end-1);
to = idx(2:end);
from = idx(1:2:end);
to = idx(2:2:end);
% counts C(from,to)
C = accumarray([from,to], 1, [K K], @sum, 0);
% row-stochastic transition matrix P(to|from)
rowSums = sum(C,2);
P = C ./ max(rowSums,1);
%% 1) HEATMAP (which transitions are more probable?)
figure('Name','Transition Probabilities (to | from)');
h = heatmap(levels, levels, P, 'Colormap', parula, 'ColorbarVisible','on');
colormap(gca,[[1,1,1];flip(cbrewer2('Spectral',100))]);clim([0,ceil(max(P(:))*10)/10]);
h.XLabel = 'From state (level)';
h.YLabel = 'To state (level)';
h.Title = 'P(to | from)';

View File

@@ -0,0 +1,86 @@
% DUOBINARY CLASSES
% Define the filter taps
h_ = {1,[1 1],[1 2 1],[1 3 3 1]};
desc = {'$1$','$(1+D)$','$(1+D)^2$','$(1+D)^3$'};
for i = 1:length(h_)
h = h_{i};
[H, w] = freqz(h, 1, 1024, 1);
figure(1);
hold on
plot(w, 10*log10(abs(H)), 'LineWidth', 1, 'DisplayName',desc{i}); %todo
xlabel('Normalized Frequency');
ylabel('Amplitude in dB');
grid on;
ylim([-20,10]);
end
legend
beautifyBERplot("logscale",false,"setmarkers",false);
% mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/03_DSP_Techniques/tikz/duobinary_response.tikz")
%%
% 1+ alpha D
% Define the filter taps
h_ = {[1, 0],[1 0.3],[1 0.6],[1 0.9],[1 1],[1 2 1],[1 3 3 1]};
col = {[0 0 0],[0.2000,0.6275,0.1725],[0.1216, 0.4706, 0.7059],[0.8902,0.1020,0.1098],...
[0.2000,0.6275,0.1725],[0.9333, 0.9451, 0.9490],[0.9333, 0.9451, 0.9490]};
sty = {':','-','-','-','--','--','--'};
for i = 1:length(h_)
h = h_{i};
[H, w] = freqz(h, 1, 1024, 1);
figure(2);
hold on
dn = sprintf('$(1+ %.1f \\, D)$', h(end));
if i == 5
dn = sprintf('$(1+D)$', h(end));
elseif i == 6
dn = sprintf('$(1+D)^2$');
elseif i == 7
dn = sprintf('$(1+D)^3$');
elseif i == 1
dn = sprintf('$1$');
end
plot(w, 10*log10(abs(H)), 'LineWidth', 2,'DisplayName',dn,'Color',col{i},'LineStyle',sty{i}); %todo
xlabel('Normalized Frequency');
ylabel('Amplitude in dB');
grid on;
ylim([-20,10])
end
legend
beautifyBERplot("logscale",false,"setmarkers",false,"setcolors",false);
% mat2tikz_improved("C:/Users/Silas/Documents/6971e0b65b380ca6d71c837f/03_DSP_Techniques/tikz/partial_response_2.tikz")
%%
useprbs = 0;
M = 4;
randkey = 2;
fsym = 112e9;
Tx_bits = Signalgenerator("form", signalform.prms,"M", M,"order", 17).process();
Symbols_tx = PAMmapper(M,0).map(Tx_bits);
Symbols_tx.fs = fsym;
cnt = 1;
Symbols = Symbols_tx;
Symbols = Duobinary().precode(Symbols);
Symbols = Duobinary().encode(Symbols);
Symbols = Duobinary().decode(Symbols);
for alpha = 0:0.2:1
Symbols.signal = filter([1,alpha], 1, Symbols.signal);
Symbols.spectrum("fignum",2,"displayname",['coeff:',num2str(alpha)],"normalizeTo0dB",1,"normalizeToNyquist",0,"normalizeToSamplingRate",1);
end

View File

@@ -0,0 +1,57 @@
M = 4;
apply_precode_at_tx = 1;
bits = Signalgenerator( ...
"form", signalform.prms, ...
"M", M, ...
"order", 15).process();
symbols = PAMmapper(M,0).map(bits);
if apply_precode_at_tx
symbols_tx = Duobinary().precode(symbols);
else
symbols_tx = symbols;
end
disp(['Tx Sequenz: -- RMS:',sprintf('%.1f',rms(symbols_tx.signal)),' - - Levels -',num2str(numel(unique(symbols_tx.signal)))]);
unique(symbols_tx.signal)
disp('- - - - - - - - - -');
symbols_tx.signal = awgn(symbols_tx.signal,20,"measured",1);
show2Dconstellation(symbols_tx,symbols_tx,"displayname",'VNLE Out','fignum',2241);
if apply_precode_at_tx
% 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(symbols_tx);
disp(['DB encoded -- RMS:',sprintf('%.1f',rms(symbols_db.signal)),' - - Levels -',num2str(numel(unique(symbols_db.signal)))]);
unique(symbols_db.signal)
disp('- - - - - - - - - -');
% Entschiedene codierte Symbole decodieren: d_dec(n) = d_DB(n) mod4
symbols_rx = Duobinary().decode(symbols_db);
else
symbols_db = Duobinary().encode(symbols_tx);
symbols_rx = Duobinary().decode(symbols_db);
end
% Vergleichen von b(n) und d_dec(n)
bits_rx = PAMmapper(M,0).demap(symbols_rx);
disp(['Wieder normal -- RMS:',sprintf('%.1f',rms(symbols_rx.signal)),' - - Levels -',num2str(numel(unique(symbols_rx.signal)))]);
unique(symbols_rx.signal)
disp('- - - - - - - - - -');
[~,~,ber,~] = calc_ber(bits.signal,bits_rx.signal,"skip_front",10,"skip_end",10,"returnErrorLocation",1);
disp(['BER: ',sprintf('%.1E',ber),' - - PAM-',num2str(M)]);
figure()
subplot(1,2,1)
histogram(symbols_tx.signal,100,'Normalization','count')
subplot(1,2,2)
histogram(symbols_db.signal,100,'Normalization','count')