简体   繁体   中英

DVB-S2: LDPC Short Format

Scope

Matlab does include a function, named dvbs2ldpc , to construct a parity check matrix to be used at LDPC encoding stage in DVB-S2 standard.

This standard counts with two different transmission modes (SHORT and NORMAL), depending on the size of the resulting codeword. However dvbs2ldpc function only applies for NORMAL one. Thus I am trying to build up a function to be used in SHORT transmission mode.

Code description

You may find below all the related code in functions dvbs2ldpcShort.m , where I am to construct a parity check matrix for SHORT transmission mode, and LDPC.m , where I perform some BER simulations to check out the results.

You may see that dvbs2ldpcShort resembles quite a lot to dvbs2ldpc , which appears in Matlab Communication Toolbox. The two only differences that I included were changing the length of the codeword and the accumulator bits of the parity check matrix that it may correspond ( please see annexes B and C from this link for further information).

Code

dvbs2ldpcShort.m

function H = dvbs2ldpcShort(R)

if R = 1/2
    Rreal = 4/9;     % Actual rate (as k = 7200 and N = 16200)
end

lenCodeWord = 16200;  % Length of codeword for DVB-S.2
NB = 360;  % Node indices parameter for DVB-S.2.

numInfoBits = lenCodeWord * Rreal;
numParityBits = lenCodeWord - numInfoBits;

[ct1, ct2] = getchecknodetable(R);

ck1 = nodeindices(ct1, numParityBits, NB);
ck2 = nodeindices(ct2, numParityBits, NB);

d = [size(ck1,2) size(ck1,1) size(ck2,2) size(ck2,1) numParityBits-1 2 1 1];
r = [ck1(:); ck2(:); 0; reshape(ones(2,1)*(1:numParityBits-1),[],1)];
S = zeros(length(r),1);
numGroup = length(d)/2;
n = 0;
ncol = 1;
for i = 1:numGroup
    p = d(2*i-1)*d(2*i);
    S(n+1:n+p) = reshape(ones(d(2*i),1)*(ncol:ncol+d(2*i-1)-1),p,1);
    ncol = ncol + d(2*i-1);
    n = n + p;
end

% Parity-check matrix (sparse) for DVB-S.2
outputFormat = 'sparse'; % Sparse matrix by default
if nargin == 2
    if ~strcmp(varargin{1}, 'sparse') && ~strcmp(varargin{1}, 'indices')
        error(message('comm:dvbs2ldpc:InvalidOutputFormat'));
    end
    outputFormat = varargin{1};
end

if strcmp(outputFormat, 'sparse')
    H = logical(sparse(double(r+1), S, 1));
else
    H = [double(r+1), double(S)];
end

%--------------------------------------------------------------------------
function ck = nodeindices(ct, M, NB)
% ct: check node table (single group)
% M: number of parity bits
% NB: block size
[N, D] = size(ct);
q = (M/NB);
b = (1:NB);
bq = (b-1).'*q;
ck = zeros(D, NB*N);
for r=1:N
    ck(:, NB*(r-1)+1:NB*r) = mod(addcr(bq, ct(r,:)), M)';
end

%--------------------------------------------------------------------------
function A = addcr(c, r)
M = length(c);
N = length(r);
A = zeros(M, N);
for m = 1:M
    A(m, :) = r + c(m);
end

%--------------------------------------------------------------------------
function [ct1, ct2] = getchecknodetable(R)
switch R
    case 1/2 % There are all cases, but here I only include the R=1/2 one
        ct1 = [20 712 2386 6354 4061 1062 5045 5158
               21 2543 5748 4822 2348 3089 6328 5876
               22 926 5701 269 3693 2438 3190 3507
               23 2802 4520 3577 5324 1091 4667 4449
               24 5140 2003 1263 4742 6497 1185 6202];
        ct2 = [0 4046 6934   
               1 2855 66
               2 6694 212
               3 3439 1158
               4 3850 4422
               5 5924 290
               6 1467 4049
               7 7820 2242
               8 4606 3080
               9 4633 7877
               10 3884 6868
               11 8935 4996
               12 3028 764
               13 5988 1057
               14 7411 3450];
end

LDPC.m

r = 1/2;
k = 7200;

ldpcEnc = comm.LDPCEncoder(dvbs2ldpcShort(r));
psk4Mod = comm.PSKModulator(4, 'BitInput',true);
EsNo = 0.2 : 0.1 : 1.2;
BER = zeros(size(EsNo));
for k = 1 : 1 : length(EsNo)
    awgnChan = comm.AWGNChannel(...
            'NoiseMethod','Signal to noise ratio (Es/No)','EsNo',EsNo(k));
    psk4Demod = comm.PSKDemodulator(4, 'BitOutput',true,...
            'DecisionMethod','Approximate log-likelihood ratio', ...
            'Variance', 1/(2*10^(awgnChan.EsNo/10)));
    ldpcDec = comm.LDPCDecoder(dvbs2ldpcShort(r));
    ber = comm.ErrorRate;
    for counter = 1:100
      data           = logical(randi([0 1], k, 1));
      encodedData    = ldpcEnc(data);
      modSignal      = psk4Mod(encodedData);
      receivedSignal = awgnChan(modSignal);
      demodSignal    = psk4Demod(receivedSignal);
      receivedBits   = ldpcDec(demodSignal);
      errorStats     = ber(data, receivedBits);
    end
    BER(k) = errorStats(1);
end

Question

The corresponding BER curve does not resemble at all to how it is for NORMAL transmission mode (these represent the BER as function of SNR. and mine are function of EbNo, but the difference shouldn't be really big at all). Instead, results seem to be unexpectedly good. Can you see anything wrong with my code?

What could be wrong in my code?

Many thanks in advance, and may you have a nice weekend!

Thanks for the note on LDPC code identifier and Effective LDPC rate.

Your example-performance should be better, because you use more redundancy: 5/9 ( 0.56 ) of code word whereas in the MATLAB example they use (1 - 2/3) = 1/3 ( 0.33 ) of code word as redundancy.

I would like to add a note also: In the ETSI standard they also use a parameter q , that is equal to q = (M/NB) ; ( M -- num of parity bits, NB = 360 ) when the n_ldpc = 64800 , but if n_ldpc = 16200 the q should be used according a table in the ETSI standard.

Let's look at my solution: dvbs2ldpc_custom

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM