226 lines
10 KiB
Matlab
226 lines
10 KiB
Matlab
classdef TransmissionPerformance
|
|
% TransmissionPerformance
|
|
%
|
|
% This class calculates the best possible net data rate (in bits/s)
|
|
% from a given gross rate (bits/s) and a measured channel quality
|
|
% parameter (either bit error ratio (BER) or NGMI). The class uses
|
|
% lookup tables for three different FEC modes:
|
|
%
|
|
% 1. SD+HD concatenated (uses overall code rate and an NGMI threshold)
|
|
% 2. SD+HD concatenated with punctured LDPC (uses overall code rate and an NGMI threshold)
|
|
% 3. HD-only (uses a code rate and a BER threshold)
|
|
%
|
|
% The basic algorithm is as follows:
|
|
% 1. Given a measured quality (NGMI or BER) for each measurement, find in
|
|
% the table the first (i.e. “best”) entry that is satisfied by the
|
|
% measured value. For NGMI the condition is measured NGMI >= threshold,
|
|
% while for BER the condition is measured BER <= threshold.
|
|
% 2. Use the corresponding overall code rate to compute:
|
|
%
|
|
% net rate = gross rate * code rate.
|
|
%
|
|
% USAGE EXAMPLE (array inputs):
|
|
%
|
|
% tp = TransmissionPerformance;
|
|
% % Suppose we have 3 measurements:
|
|
% % Gross rates: 10, 15, and 20 Gbps
|
|
% % Measured NGMI: 0.92, 0.88, and 0.85
|
|
% % Measured BER: 1e-4, 7e-3, and 2e-2
|
|
% netrates = tp.calculatenetrate([10e9 15e9 20e9], ...
|
|
% 'NGMI', [0.92 0.88 0.85], ...
|
|
% 'BER', [1e-4 7e-3 2e-2]);
|
|
%
|
|
% The returned structure netrates will contain the net rates (and the
|
|
% used code rates and thresholds) for each mode in vector form.
|
|
|
|
properties (Constant)
|
|
%% Lookup Table for SD+HD concatenated (using NGMI)
|
|
% Overall code rate and NGMI threshold for each row.
|
|
OVERALLCODERATES_SDHD = [0.7519, 0.7602, 0.7684, 0.7766, 0.7850, ...
|
|
0.7932, 0.8014, 0.8098, 0.8180, 0.8262, ...
|
|
0.8345, 0.8428, 0.8510, 0.8593, 0.8676, ...
|
|
0.8733, 0.8790, 0.8848, 0.8905, 0.8962, ...
|
|
0.9019, 0.9077, 0.9134, 0.9191, 0.9248, ...
|
|
0.9306, 0.9363, 0.9420, 0.9477, 0.9535];
|
|
NGMITHRESHOLDS_SDHD = [0.8116, 0.8167, 0.8241, 0.8317, 0.8401, ...
|
|
0.8459, 0.8512, 0.8574, 0.8685, 0.8746, ...
|
|
0.8829, 0.8892, 0.8958, 0.9022, 0.9090,...
|
|
0.9150, 0.9210, 0.9270, 0.9330, 0.9390, ...
|
|
0.9450, 0.9510, 0.9570, 0.9630, 0.9690, ...
|
|
0.9750, 0.9810, 0.9870, 0.9930, 0.9990];
|
|
|
|
ISPUNCT_LDPI = [zeros(1,15),ones(1,15)];
|
|
|
|
%% Lookup Table for HD-only mode (using BER)
|
|
% For HD-only, the table gives the code rate and the maximum acceptable BER.
|
|
CODE_RATES_HD = [0.7500, 0.8000, 0.8123, 0.8333, 0.8571, ...
|
|
0.8750, 0.8889, 0.9000, 0.9091, 0.9167, 0.9412];
|
|
BERTHRESHOLDS_HD = [2.12e-2, 1.76e-2, 1.62e-2, 1.44e-2, 1.25e-2, ...
|
|
1.03e-2, 9.29e-3, 8.33e-3, 7.54e-3, 7.04e-3, 4.70e-3];
|
|
|
|
%% LUT for KP4-FEC and Inner Code https://grouper.ieee.org/groups/802/3/dj/public/23_03/patra_3dj_01b_2303.pdf
|
|
|
|
CODE_RATE_KP4_AND_INNER = [0.885799];
|
|
BERTHRESHOLDS_KP4_AND_INNER = 4.85e-3;
|
|
|
|
% https://www.ieee802.org/3/bs/public/14_11/parthasarathy_3bs_01a_1114.pdf
|
|
CODE_RATE_KP4 = [1/(1+0.052)];%Reed-Solomon RS(544, 514) == KP4
|
|
BERTHRESHOLDS_KP4 = 2.2e-4;
|
|
|
|
CODE_RATE_HDFEC = [1/(1+0.067)]; %Beyond 300 Gbps Short-Reach Links Using TFLN MZMs With 500 mVpp and Linear Equalization
|
|
BERTHRESHOLDS_HDFEC = 3.8e-3;
|
|
|
|
CODE_RATE_O_FEC = [1/(1+0.15)]; %Stefano im Meeting
|
|
BERTHRESHOLDS_O_FEC = 2e-2;
|
|
|
|
|
|
|
|
end
|
|
|
|
methods
|
|
function netrates = calculateNetRate(obj, grossRate, varargin)
|
|
% calculatenetrate Calculate the net data rate(s) from measured data.
|
|
%
|
|
% netrates = tp.calculatenetrate(grossRate, 'BER', berValue, 'NGMI', ngmiValue)
|
|
%
|
|
% INPUTS:
|
|
% grossRate - (scalar or vector) gross data rate(s) [bits/s]
|
|
%
|
|
% Optional name/value pairs:
|
|
% 'BER' - (scalar or vector) measured bit error ratio(s)
|
|
% 'NGMI' - (scalar or vector) measured NGMI value(s)
|
|
%
|
|
% At least one of 'BER' or 'NGMI' must be provided.
|
|
%
|
|
% OUTPUT:
|
|
% netrates - a structure with the following fields (if available):
|
|
% .SDHD - for SD+HD concatenated (using NGMI)
|
|
% .SDHD_LDPC - for SD+HD with punctured LDPC (using NGMI)
|
|
% .HD - for HD-only (using BER)
|
|
%
|
|
% Each sub-structure contains fields:
|
|
% .CodeRate - the chosen overall code rate from the table (vector)
|
|
% .Threshold - the threshold value used from the table (vector)
|
|
% .<BER/NGMI> - net rate computed as grossRate * CodeRate (vector)
|
|
|
|
% Parse inputs.
|
|
p = inputParser;
|
|
addRequired(p, 'grossRate', @(x) isnumeric(x));
|
|
addParameter(p, 'BER', [], @(x) isnumeric(x));
|
|
addParameter(p, 'NGMI', [], @(x) isnumeric(x));
|
|
parse(p, grossRate, varargin{:});
|
|
|
|
ber = p.Results.BER;
|
|
ngmi = p.Results.NGMI;
|
|
|
|
if isempty(ber) && isempty(ngmi)
|
|
error('At least one of ''BER'' or ''NGMI'' must be provided.');
|
|
end
|
|
|
|
% Determine the number of measurements.
|
|
numMeasurements = max([numel(grossRate), numel(ngmi), numel(ber)]);
|
|
|
|
% Broadcast scalars if needed.
|
|
if isscalar(grossRate) && numMeasurements > 1
|
|
grossRate = repmat(grossRate, 1, numMeasurements);
|
|
elseif numel(grossRate) ~= numMeasurements
|
|
error('grossRate must be scalar or have %d elements.', numMeasurements);
|
|
end
|
|
|
|
if ~isempty(ngmi)
|
|
if isscalar(ngmi) && numMeasurements > 1
|
|
ngmi = repmat(ngmi, 1, numMeasurements);
|
|
elseif numel(ngmi) ~= numMeasurements
|
|
error('NGMI must be scalar or have %d elements.', numMeasurements);
|
|
end
|
|
end
|
|
|
|
if ~isempty(ber)
|
|
if isscalar(ber) && numMeasurements > 1
|
|
ber = repmat(ber, 1, numMeasurements);
|
|
elseif numel(ber) ~= numMeasurements
|
|
error('BER must be scalar or have %d elements.', numMeasurements);
|
|
end
|
|
end
|
|
|
|
% Initialize the output structure.
|
|
netrates = struct;
|
|
if ~isempty(ngmi)
|
|
netrates.SDHD.GrossRate = NaN(1, numMeasurements);
|
|
netrates.SDHD.NetRate = NaN(1, numMeasurements);
|
|
netrates.SDHD.punctLDPI = NaN(1, numMeasurements);
|
|
netrates.SDHD.CodeRate = NaN(1, numMeasurements);
|
|
netrates.SDHD.Threshold = NaN(1, numMeasurements);
|
|
end
|
|
if ~isempty(ber)
|
|
netrates.HD.GrossRate = NaN(1, numMeasurements);
|
|
netrates.HD.NetRate = NaN(1, numMeasurements);
|
|
netrates.HD.CodeRate = NaN(1, numMeasurements);
|
|
netrates.HD.Threshold = NaN(1, numMeasurements);
|
|
|
|
netrates.KP4_hamming.GrossRate = NaN(1, numMeasurements);
|
|
netrates.KP4_hamming.NetRate = NaN(1, numMeasurements);
|
|
netrates.KP4_hamming.CodeRate = NaN(1, numMeasurements);
|
|
netrates.KP4_hamming.Threshold = NaN(1, numMeasurements);
|
|
end
|
|
|
|
% Process each measurement individually.
|
|
for i = 1:numMeasurements
|
|
|
|
% --- NGMI-based modes ---
|
|
if ~isempty(ngmi)
|
|
% SD+HD concatenated mode.
|
|
idx = find(obj.NGMITHRESHOLDS_SDHD <= ngmi(i), 1, 'last');
|
|
if ~isempty(idx)
|
|
codeRate = obj.OVERALLCODERATES_SDHD(idx);
|
|
netrates.SDHD.NetRate(i) = grossRate(i) * codeRate;
|
|
netrates.SDHD.GrossRate(i) = grossRate(i) ;
|
|
netrates.SDHD.CodeRate(i) = codeRate;
|
|
netrates.SDHD.Threshold(i) = obj.NGMITHRESHOLDS_SDHD(idx);
|
|
netrates.SDHD.punctLDPI(i) = obj.ISPUNCT_LDPI(idx);
|
|
end
|
|
|
|
end
|
|
|
|
% --- BER-based mode (HD-only) ---
|
|
if ~isempty(ber)
|
|
% Loop through the BER thresholds from the best (highest code rate)
|
|
% to the worst until the measured BER is acceptable.
|
|
idxBER = [];
|
|
for j = length(obj.BERTHRESHOLDS_HD):-1:1
|
|
if ber(i) <= obj.BERTHRESHOLDS_HD(j)
|
|
idxBER = j;
|
|
break;
|
|
end
|
|
end
|
|
if ~isempty(idxBER)
|
|
codeRate = obj.CODE_RATES_HD(idxBER);
|
|
netrates.HD.NetRate(i) = grossRate(i) * codeRate;
|
|
netrates.HD.GrossRate(i) = grossRate(i) ;
|
|
netrates.HD.CodeRate(i) = codeRate;
|
|
netrates.HD.Threshold(i) = obj.BERTHRESHOLDS_HD(idxBER);
|
|
end
|
|
idxBER = [];
|
|
for j = length(obj.BERTHRESHOLDS_KP4_AND_INNER):-1:1
|
|
if ber(i) <= obj.BERTHRESHOLDS_KP4_AND_INNER(j)
|
|
idxBER = j;
|
|
break;
|
|
end
|
|
end
|
|
if ~isempty(idxBER)
|
|
codeRate = obj.CODE_RATE_KP4_AND_INNER(idxBER);
|
|
netrates.KP4_hamming.NetRate(i) = grossRate(i) * codeRate;
|
|
netrates.KP4_hamming.GrossRate(i) = grossRate(i) ;
|
|
netrates.KP4_hamming.CodeRate(i) = codeRate;
|
|
netrates.KP4_hamming.Threshold(i) = obj.BERTHRESHOLDS_KP4_AND_INNER(idxBER);
|
|
end
|
|
|
|
|
|
end
|
|
|
|
|
|
end
|
|
end
|
|
end
|
|
end
|