Add PAMmapper bit mapping and Gray penalty visualization
This commit is contained in:
@@ -504,9 +504,118 @@ classdef PAMmapper
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function bitmap = showBitMapping(obj)
|
function [ax, mapping_table] = plotBitMapping(obj)
|
||||||
|
[constellation, bitmap] = obj.getConstellationBitMapping();
|
||||||
|
constellation = constellation .* obj.get_scaling;
|
||||||
|
bit_labels = string(cellstr(char(bitmap + '0')));
|
||||||
|
|
||||||
bitmap = obj.demap((obj.levels ./ obj.scaling)');
|
if obj.M == 6
|
||||||
|
[~, order] = sortrows([-constellation(:,2), constellation(:,1)]);
|
||||||
|
constellation = constellation(order, :);
|
||||||
|
bit_labels = bit_labels(order);
|
||||||
|
|
||||||
|
mapping_table = table(constellation(:,1), constellation(:,2), bit_labels, ...
|
||||||
|
'VariableNames', {'symbol_1', 'symbol_2', 'bits'});
|
||||||
|
|
||||||
|
fig = figure("Name", sprintf("PAM-%d Bit Mapping", obj.M));
|
||||||
|
ax = axes(fig);
|
||||||
|
scatter(ax, constellation(:,1), constellation(:,2), 60, "filled");
|
||||||
|
hold(ax, "on");
|
||||||
|
grid(ax, "on");
|
||||||
|
box(ax, "on");
|
||||||
|
|
||||||
|
x_step = min(diff(unique(constellation(:,1))));
|
||||||
|
y_step = min(diff(unique(constellation(:,2))));
|
||||||
|
text(ax, constellation(:,1), constellation(:,2) + 0.18*y_step, bit_labels, ...
|
||||||
|
"HorizontalAlignment", "center", "FontName", "Consolas");
|
||||||
|
|
||||||
|
xlabel(ax, "Symbol 1");
|
||||||
|
ylabel(ax, "Symbol 2");
|
||||||
|
title(ax, sprintf("PAM-%d Mapping", obj.M));
|
||||||
|
axis(ax, "equal");
|
||||||
|
xticks(ax, unique(constellation(:,1)));
|
||||||
|
yticks(ax, unique(constellation(:,2)));
|
||||||
|
xlim(ax, [min(constellation(:,1)) - 0.8*x_step, max(constellation(:,1)) + 1.4*x_step]);
|
||||||
|
ylim(ax, [min(constellation(:,2)) - 0.6*y_step, max(constellation(:,2)) + 0.9*y_step]);
|
||||||
|
else
|
||||||
|
constellation = constellation(:);
|
||||||
|
mapping_table = table(constellation, bit_labels, ...
|
||||||
|
'VariableNames', {'symbol', 'bits'});
|
||||||
|
|
||||||
|
fig = figure("Name", sprintf("PAM-%d Bit Mapping", obj.M));
|
||||||
|
ax = axes(fig);
|
||||||
|
scatter(ax, constellation, zeros(size(constellation)), 60, "filled");
|
||||||
|
hold(ax, "on");
|
||||||
|
grid(ax, "on");
|
||||||
|
box(ax, "on");
|
||||||
|
text(ax, constellation, 0.08*ones(size(constellation)), bit_labels, ...
|
||||||
|
"HorizontalAlignment", "center", "FontName", "Consolas");
|
||||||
|
|
||||||
|
xlabel(ax, "Symbol");
|
||||||
|
title(ax, sprintf("PAM-%d Mapping", obj.M));
|
||||||
|
yticks(ax, []);
|
||||||
|
ylim(ax, [-0.2 0.2]);
|
||||||
|
xticks(ax, constellation);
|
||||||
|
if numel(constellation) > 1
|
||||||
|
x_step = min(diff(unique(constellation)));
|
||||||
|
else
|
||||||
|
x_step = 1;
|
||||||
|
end
|
||||||
|
xlim(ax, [min(constellation) - 0.8*x_step, max(constellation) + 0.8*x_step]);
|
||||||
|
end
|
||||||
|
|
||||||
|
if nargout == 0
|
||||||
|
disp(mapping_table);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function bitmap = showBitMapping(obj)
|
||||||
|
[~, bitmap] = obj.getConstellationBitMapping();
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [Gp, details] = graypenalty(obj)
|
||||||
|
[constellation, bit_labels] = obj.getConstellationBitMapping();
|
||||||
|
|
||||||
|
num_points = size(constellation, 1);
|
||||||
|
dist2 = inf(num_points);
|
||||||
|
|
||||||
|
for idx = 1:num_points
|
||||||
|
delta = constellation - constellation(idx, :);
|
||||||
|
dist2(idx, :) = sum(delta.^2, 2).';
|
||||||
|
end
|
||||||
|
|
||||||
|
dist2(1:num_points+1:end) = inf;
|
||||||
|
min_dist2 = min(dist2(:));
|
||||||
|
is_neighbor = abs(dist2 - min_dist2) < 1e-12;
|
||||||
|
|
||||||
|
hamming_dist = zeros(num_points);
|
||||||
|
for idx = 1:num_points
|
||||||
|
hamming_dist(idx, :) = sum(bit_labels ~= bit_labels(idx, :), 2).';
|
||||||
|
end
|
||||||
|
|
||||||
|
Gp = sum(hamming_dist(is_neighbor)) / nnz(is_neighbor);
|
||||||
|
|
||||||
|
if nargout > 1
|
||||||
|
details = struct( ...
|
||||||
|
"constellation", constellation, ...
|
||||||
|
"bit_labels", bit_labels, ...
|
||||||
|
"neighbor_mask", is_neighbor, ...
|
||||||
|
"nearest_distance", sqrt(min_dist2));
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function [constellation, bitmap] = getConstellationBitMapping(obj)
|
||||||
|
|
||||||
|
if obj.M == 6
|
||||||
|
constellation = obj.thresholds ./ obj.scaling;
|
||||||
|
bitmap = obj.demap(reshape(constellation.', [], 1));
|
||||||
|
bitmap = reshape(bitmap, 5, []).';
|
||||||
|
else
|
||||||
|
constellation = (obj.levels ./ obj.scaling)';
|
||||||
|
bitmap = obj.demap(constellation);
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options)
|
|||||||
|
|
||||||
ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
ffe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, ...
|
"precode_mode", duob_mode, ...
|
||||||
'showAnalysis', showAnalysis, ...
|
'showAnalysis', options.debug_plots, ...
|
||||||
"postFFE", [], ...
|
"postFFE", [], ...
|
||||||
"eth_style_symbol_mapping", 0);
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ function output = dsp_scope_signal(Scpe_sig_raw, Symbols, Tx_bits, options)
|
|||||||
|
|
||||||
dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
dfe_results = ffe(eq_dfe, M, Scpe_sig, Symbols, Tx_bits, ...
|
||||||
"precode_mode", duob_mode, ...
|
"precode_mode", duob_mode, ...
|
||||||
'showAnalysis', showAnalysis, ...
|
'showAnalysis', options.debug_plots, ...
|
||||||
"postFFE", [], ...
|
"postFFE", [], ...
|
||||||
"eth_style_symbol_mapping", 0);
|
"eth_style_symbol_mapping", 0);
|
||||||
|
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ function displayAnalysis(eq_noise, eq_signal_sd, rx_signal, eq_, tx_symbols, M,
|
|||||||
legend on
|
legend on
|
||||||
end
|
end
|
||||||
|
|
||||||
|
show2Dconstellation(eq_signal_sd, tx_symbols,"displayname",'Visualization of symbol correlation','fignum',340);
|
||||||
|
|
||||||
% try
|
% try
|
||||||
% figure(240); hold on; plot(pow2db(movmean(eq_.debug_struct.error_tr',100)));ylim([-30,3]);title('error training');
|
% figure(240); hold on; plot(pow2db(movmean(eq_.debug_struct.error_tr',100)));ylim([-30,3]);title('error training');
|
||||||
%
|
%
|
||||||
@@ -188,6 +190,6 @@ function displayAnalysis(eq_noise, eq_signal_sd, rx_signal, eq_, tx_symbols, M,
|
|||||||
% figure(242); hold on; plot(pow2db(movmean(eq_.debug_struct.update',1000)));title('update step dd');
|
% figure(242); hold on; plot(pow2db(movmean(eq_.debug_struct.update',1000)));title('update step dd');
|
||||||
% end
|
% end
|
||||||
|
|
||||||
eq_signal_sd.eye(eq_signal_sd.fs,M,"displayname",'Eye','fignum',105);
|
% eq_signal_sd.eye(eq_signal_sd.fs,M,"displayname",'Eye','fignum',105);
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -30,7 +30,7 @@ end
|
|||||||
rx_symbols = eq_signal; %./ rms(eq_signal);
|
rx_symbols = eq_signal; %./ rms(eq_signal);
|
||||||
correct_symbols = ref_symbols;
|
correct_symbols = ref_symbols;
|
||||||
|
|
||||||
col = cbrewer2('Paired',numel(unique(correct_symbols))*2);
|
col = cbrewer2('Paired',numel(unique(correct_symbols))*3);
|
||||||
ccnt = -1;
|
ccnt = -1;
|
||||||
|
|
||||||
levels = unique(correct_symbols);
|
levels = unique(correct_symbols);
|
||||||
|
|||||||
11
Theory/Mapping_Coding/Gray_penalty.m
Normal file
11
Theory/Mapping_Coding/Gray_penalty.m
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
function [Gp, details] = Gray_penalty(use_eth_mapping)
|
||||||
|
%GRAY_PENALTY Average bit errors per nearest-neighbor PAM-6 symbol error.
|
||||||
|
|
||||||
|
if nargin < 1
|
||||||
|
use_eth_mapping = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
mapper = PAMmapper(6, 0, "eth_style", use_eth_mapping);
|
||||||
|
mapper.plotBitMapping();
|
||||||
|
[Gp, details] = mapper.graypenalty();
|
||||||
|
end
|
||||||
@@ -17,30 +17,42 @@ if 1
|
|||||||
|
|
||||||
uloops = struct;
|
uloops = struct;
|
||||||
uloops.precomp = [0];
|
uloops.precomp = [0];
|
||||||
uloops.bitrate = [300].*1e9; %[300,330,360,390,420,450,480] [224,336,360,390,420,448] for MPI
|
uloops.fsym = 180e9;
|
||||||
|
% uloops.bitrate = 100e9;
|
||||||
% uloops.laser_wavelength = [1293,1297.5,1302,1306.5,1310,1313.4,1318,1322.7,1327.4];
|
% uloops.laser_wavelength = [1293,1297.5,1302,1306.5,1310,1313.4,1318,1322.7,1327.4];
|
||||||
uloops.laser_wavelength = [1293];
|
uloops.laser_wavelength = [1310];
|
||||||
uloops.M = [4];
|
uloops.M = [6];
|
||||||
uloops.link_length = 1;
|
uloops.link_length = 1;
|
||||||
% uloops.link_length = [0:2:10]; % 1,2,3,5,6,8,10
|
% uloops.link_length = [0:2:10]; % 1,2,3,5,6,8,10
|
||||||
uloops.channel_alpha = [0.5];
|
uloops.channel_alpha = [0.8];
|
||||||
uloops.duob_mode = db_mode.no_db;
|
uloops.duob_mode = db_mode.no_db;
|
||||||
uloops.decoding_mode = "memoryless";
|
uloops.decoding_mode = "memoryless";
|
||||||
uloops.channel_mode = "awgn_alphad";
|
uloops.channel_mode = "awgn_alphad"; %awgn_alphad
|
||||||
uloops.channel_snr_dB = [20:-2:0];
|
uloops.channel_snr_dB = [20];
|
||||||
|
uloops.rop = -6;
|
||||||
|
|
||||||
wh = DataStorage(uloops);
|
wh = DataStorage(uloops);
|
||||||
wh.addStorage("ber");
|
wh.addStorage("ber");
|
||||||
|
|
||||||
wh = submit_handle(@imdd_model,wh,"parallel",1);
|
wh = submit_handle(@imdd_model,wh,"parallel",0);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
%%
|
%%
|
||||||
figure
|
figure
|
||||||
hold on
|
hold on
|
||||||
|
if isfield(uloops, 'fsym') && isfield(uloops, 'bitrate')
|
||||||
|
error('Define only one of uloops.fsym or uloops.bitrate.');
|
||||||
|
elseif isfield(uloops, 'fsym')
|
||||||
|
rateLookup = uloops.fsym;
|
||||||
|
elseif isfield(uloops, 'bitrate')
|
||||||
|
rateLookup = uloops.bitrate;
|
||||||
|
else
|
||||||
|
error('Define either uloops.fsym or uloops.bitrate.');
|
||||||
|
end
|
||||||
|
|
||||||
for alpha = uloops.channel_alpha
|
for alpha = uloops.channel_alpha
|
||||||
a=wh.getStoValue('ber',0, [300].*1e9 , 1293, 4, uloops.link_length,alpha,uloops.duob_mode,uloops.decoding_mode,uloops.channel_mode,uloops.channel_snr_dB);
|
a=wh.getStoValue('ber',0, rateLookup, uloops.laser_wavelength, uloops.M, uloops.link_length,alpha,uloops.duob_mode,uloops.decoding_mode,uloops.channel_mode,uloops.channel_snr_dB);
|
||||||
gmi_ffe = cellfun(@(x) x.ffe_results.metrics.GMI, a);
|
gmi_ffe = cellfun(@(x) x.ffe_results.metrics.GMI, a);
|
||||||
alpha_ffe = cellfun(@(x) x.ffe_results.metrics.Alpha, a);
|
alpha_ffe = cellfun(@(x) x.ffe_results.metrics.Alpha, a);
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ end
|
|||||||
%%% Run parameters
|
%%% Run parameters
|
||||||
% TX
|
% TX
|
||||||
M = 4;
|
M = 4;
|
||||||
fsym = 180e9;
|
fsym = 150e9;
|
||||||
|
bitrate = [];
|
||||||
|
|
||||||
apply_pulsef = 1;
|
apply_pulsef = 0;
|
||||||
fdac = 256e9;
|
fdac = 4*fsym;%256e9;
|
||||||
fadc = 256e9;
|
fadc = 4*fsym;%256e9;
|
||||||
random_key = 1;
|
random_key = 1;
|
||||||
|
|
||||||
rcalpha = 0.05;
|
rcalpha = 0.05;
|
||||||
@@ -28,7 +29,7 @@ vbias = -vbias_rel*u_pi;
|
|||||||
|
|
||||||
laser_wavelength = 1293;
|
laser_wavelength = 1293;
|
||||||
laser_linewidth = 0;
|
laser_linewidth = 0;
|
||||||
tx_bw_nyquist = 0.8;
|
tx_bw_nyquist = 0.65;
|
||||||
|
|
||||||
% Channel
|
% Channel
|
||||||
link_length = 1;
|
link_length = 1;
|
||||||
@@ -38,7 +39,7 @@ channel_alpha = 0;
|
|||||||
channel_delay_symbols = 1;
|
channel_delay_symbols = 1;
|
||||||
|
|
||||||
% RX
|
% RX
|
||||||
rop = -8;
|
rop = 2;
|
||||||
rx_bw_nyquist = 0.8;
|
rx_bw_nyquist = 0.8;
|
||||||
|
|
||||||
vnle_order1 = 50;
|
vnle_order1 = 50;
|
||||||
@@ -68,7 +69,7 @@ dfe_ = sum(dfe_order)>0;
|
|||||||
|
|
||||||
duob_mode = db_mode.no_db;
|
duob_mode = db_mode.no_db;
|
||||||
decoding_mode = [];
|
decoding_mode = [];
|
||||||
bitrate = fsym * log2(M);
|
providedFields = string.empty;
|
||||||
|
|
||||||
%%% change specific parameter if given in varargin
|
%%% change specific parameter if given in varargin
|
||||||
% Parse optional input arguments
|
% Parse optional input arguments
|
||||||
@@ -76,28 +77,38 @@ if ~isempty(varargin)
|
|||||||
var_s = varargin{1};
|
var_s = varargin{1};
|
||||||
if isstruct(var_s)
|
if isstruct(var_s)
|
||||||
fields = fieldnames(var_s);
|
fields = fieldnames(var_s);
|
||||||
|
providedFields = string(fields);
|
||||||
for i = 1:numel(fields)
|
for i = 1:numel(fields)
|
||||||
if isnumeric(fields{i})
|
fieldName = fields{i};
|
||||||
eval([fields{i}, ' = ', num2str( var_s.(fields{i}) ), ';']);
|
if ~isvarname(fieldName)
|
||||||
fprintf("%s <-- %.2f \n", fields{i}, var_s.(fields{i}));
|
error('Invalid parameter name "%s".', fieldName);
|
||||||
else
|
|
||||||
eval([fields{i}, ' = ', 'var_s.(fields{',num2str(i),'})' , ';']);
|
|
||||||
end
|
end
|
||||||
|
eval([fieldName, ' = var_s.(fieldName);']);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error('Optional variables should be passed as a struct.');
|
error('Optional variables should be passed as a struct.');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
hasFsym = any(providedFields == "fsym");
|
||||||
|
hasBitrate = any(providedFields == "bitrate");
|
||||||
|
|
||||||
fsym_ = floor( bitrate*1e-9./log2(M) ).*1e9;
|
if M == 6
|
||||||
|
bitsPerSymbol = 2.5;
|
||||||
if fsym_ ~= fsym
|
else
|
||||||
fsym = fsym_;
|
bitsPerSymbol = log2(M);
|
||||||
% fprintf('Adapted symbolrate to %d GBd, to match provided bitrate of %d GBit/s using PAM %d \n',fsym.*1e-9,bitrate.*1e-9, M);
|
if abs(bitsPerSymbol - round(bitsPerSymbol)) > 1e-12
|
||||||
|
error('Unsupported PAM order M=%d. Only powers of two and PAM-6 are supported.', M);
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if hasFsym && hasBitrate
|
||||||
|
error('either bitrate or symbolrate!')
|
||||||
|
elseif hasBitrate
|
||||||
|
fsym = bitrate / bitsPerSymbol;
|
||||||
|
else
|
||||||
|
bitrate = fsym * bitsPerSymbol;
|
||||||
|
end
|
||||||
|
|
||||||
f_nyquist = fsym/2;
|
f_nyquist = fsym/2;
|
||||||
|
|
||||||
@@ -114,7 +125,6 @@ Pform = Pulseformer("fsym",fsym,"fdac",4*fsym,"pulse","rc","pulselength",1
|
|||||||
|
|
||||||
Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
Digi_sig.spectrum("displayname",'Digi Spectrum','fignum',10,'normalizeTo0dB',1);
|
||||||
|
|
||||||
|
|
||||||
channel_mode = lower(string(channel_mode));
|
channel_mode = lower(string(channel_mode));
|
||||||
|
|
||||||
switch channel_mode
|
switch channel_mode
|
||||||
@@ -122,7 +132,7 @@ switch channel_mode
|
|||||||
|
|
||||||
%%%%% AWG
|
%%%%% AWG
|
||||||
% El_sig = M8199A("kover",kover).process(Digi_sig);
|
% 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 = AWG("fdac",fdac,"f_cutoff",fsym,"lpf_active",1,"kover",kover,"bit_resolution",12,"upsampling_method","samplehold","precomp_sinc_rolloff",0).process(Digi_sig);
|
||||||
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0);
|
% El_sig.spectrum("displayname",'Digi Spectrum','fignum',100,'normalizeTo0dB',0);
|
||||||
% El_sig = El_sig.setPower(0,"dBm");
|
% El_sig = El_sig.setPower(0,"dBm");
|
||||||
|
|
||||||
@@ -199,7 +209,6 @@ dspParameters.use_vnle_mlse = 1;
|
|||||||
dspParameters.use_dbtgt = 0;
|
dspParameters.use_dbtgt = 0;
|
||||||
dspParameters.use_dbenc = 0;
|
dspParameters.use_dbenc = 0;
|
||||||
dspParameters.use_ml_mlse = 0;
|
dspParameters.use_ml_mlse = 0;
|
||||||
dspParameters.showAnalysis = 0;
|
|
||||||
dspParameters.pf_ncoeffs = pf_ncoeffs;
|
dspParameters.pf_ncoeffs = pf_ncoeffs;
|
||||||
dspParameters.ffe_order_ffe = [50, 0, 0];
|
dspParameters.ffe_order_ffe = [50, 0, 0];
|
||||||
dspParameters.ffe_order_dfe = [50, 0, 0];
|
dspParameters.ffe_order_dfe = [50, 0, 0];
|
||||||
@@ -217,7 +226,7 @@ scopeOutput = dsp_scope_signal(Rx_sig, Symbols, Tx_bits, ...
|
|||||||
"parameters", dspParameters, ...
|
"parameters", dspParameters, ...
|
||||||
"preprocess_mode", "auto", ...
|
"preprocess_mode", "auto", ...
|
||||||
"tx_pulseformer", txPulseformer, ...
|
"tx_pulseformer", txPulseformer, ...
|
||||||
"debug_plots", false);
|
"debug_plots", true);
|
||||||
|
|
||||||
output = struct();
|
output = struct();
|
||||||
output.ffe_results = scopeOutput.ffe_package;
|
output.ffe_results = scopeOutput.ffe_package;
|
||||||
@@ -230,3 +239,4 @@ output.mlmlse_results = scopeOutput.mlmlse_package;
|
|||||||
|
|
||||||
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
disp('- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ')
|
||||||
fprintf('\n')
|
fprintf('\n')
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user