Main Content

End­­-to­­-End DVB-S2X Simulation with RF Impairments and Corrections in Wideband Mode

This example shows how to measure the bit error rate (BER) and packet error rate (PER) of a single stream Digital Video Broadcasting Satellite Second Generation extended (DVB-S2X) link that has constant coding and modulation for wideband mode using time slicing. The example describes the symbol timing, frame, and carrier synchronization strategies in detail, emphasizing on how to correct the RF front-end impairments under severe noise conditions. The single stream signal adds RF front-end impairments and then passes the waveform through an additive white Gaussian noise (AWGN) channel.

Introduction

Wideband mode is an optional transmission format in the DVB-S2/S2X standard for high symbol-rate satellite carriers for broadcasting, professional, and interactive services. This format adopts wideband satellite transponder (200­­–500 MHz) on a single frequency and uses the time slicing concept defined in the DVB-S2/S2X standard (ETSI EN 302 307-2 Annex M) [1].

Multiple services are time sliced at the transmitter in the form of physical layer (PL) frames, which are transmitted serially in time. Each service is provided as an independent input stream to the dvbs2xWaveformGenerator System object® and the maximum number of streams possible is 8. Each service is identified by a time slicing number (TSN) transmitted as part of the PL header.

In time slicing receiver, the user selects and decodes a specific stream pertaining to the required service. Based on the TSN information in the header, the receiver decodes certain PL frames and discards others. Thus, FEC decoding speed is equivalent to that of a regular DVB-S2 application in the order of 100 or 200 Mbps. This approach significantly reduces the complexity of the receiving device and in turn creates the opportunity for new applications like high speed data links over the Ka band (26­­–40 GHz). The information about the relevant time slicing number is already known to the receiver.

This example designs the synchronization aspects of a DVB-S2X receiver using a time slicing receiver in wideband mode. The example supports all modulation schemes from QPSK to 256APSK. ETSI EN 302 307-2 Section 6 Table 20a and Table 20c [1] summarizes the Quasi-Error-Free (QEF) performance requirement over an AWGN channel for different modulation schemes and code rates. Very low signal to noise ratio (VL-SNR) physical layer signaling (PLS) codes are not supported.

In the example, 4 services are given as independent input streams to the dvbs2xWaveformGenerator System object and the receiver recovers input data stream pertaining to service 2 to demonstrate the time slicing feature. This diagram summarizes the example workflow.

Main Processing Loop

The example processes five PL frames of data per service with the Es/No set to 15 dB, and then computes the BER and PER of the required service PL frames. Carrier frequency offset, frequency drift, sampling clock offset, and phase noise impairments are applied to the modulated signal, and AWGN is added to the signal.

At the receiver, after matched filtering, perform the timing and carrier recovery operations to recover the transmitted data. To select the PL frames of the required service, the PL header is decoded and depending on the TSN value, appropriate frames are selected for decoding. Along with the TSN, the physical layer transmission parameters, such as the modulation scheme, code rate, and FEC frame type, are recovered from the PL header to enable demodulation and decoding. To regenerate the input bit stream, decode the baseband (BB) header.

Because the DVB-S2X standard supports packetized and continuous modes of transmission, the BB frame can be either a concatenation of user packets or a stream of bits. The BB header is recovered to determine the mode of transmission. If the BB frame is a concatenation of user packets, the packet cyclic redundancy check (CRC) status of each packet is returned along with the decoded bits, and then the PER and BER are measured. If the BB frame is a stream of bits, only the decoded bits are returned, and then BER is measured.

These block diagrams show the synchronization and input bit recovery workflows.

Download DVB-S2X LDPC Parity Matrices Data Set

This example loads a MAT-file with DVB-S2X LDPC parity matrices. If the MAT-file is not available on the MATLAB® path, use these commands to download and unzip the MAT-file.

if ~exist('dvbs2xLDPCParityMatrices.mat','file')
    if ~exist('s2xLDPCParityMatrices.zip','file')
        url = 'https://ssd.mathworks.com/supportfiles/spc/satcom/DVB/s2xLDPCParityMatrices.zip';
        websave('s2xLDPCParityMatrices.zip',url);
        unzip('s2xLDPCParityMatrices.zip');
    end
    addpath('s2xLDPCParityMatrices');
end

DVB-S2X Configuration

Specify the cfgDVBS2X structure to define DVB-S2X transmission configuration parameters. PLSDecimalCode 129 and 131 are not supported because they are used for generating VL-SNR frames. Only the regular frames are supported. Set HasTimeSlicing to true to enable time slicing operation.

cfgDVBS2X.StreamFormat = "TS";
cfgDVBS2X.HasTimeSlicing = true;
cfgDVBS2X.NumInputStreams = 4;
cfgDVBS2X.PLSDecimalCode = 143;                            % 8PSK 23/36
cfgDVBS2X.DFL = 41128;                                     % Data field length in bits for
                                                           % code rate 23/36
cfgDVBS2X.PLScramblingIndex = 0;
cfgDVBS2X.RolloffFactor = 0.35;
cfgDVBS2X.SamplesPerSymbol = 2;

Simulation Parameters

The DVB-S2X standard for a wideband transponder supports channel bandwidths from 200 to 500 MHz. The symbol rate is calculated as B/(1+R), where B is the channel bandwidth, and R is the transmit filter roll-off factor.

This table defines the phase noise mask (dBc/Hz) used to generate the phase noise that is applied to the transmitted signal. These noise masks are taken from ETSI EN 302 307-1 Annex M.3 [2].

The peak Doppler and frequency drift considered are typically expected from a low Earth orbit (LEO) satellite in motion.

simParams.serviceNumber = 2;                            % time slicing number to be processed
simParams.sps = cfgDVBS2X.SamplesPerSymbol;             % Samples per symbol
simParams.numFrames = 5;                                % Number of frames to be processed
simParams.chanBW = 200e6;                               % Channel bandwidth in Hertz
rolloffFac = cfgDVBS2X.RolloffFactor;
simParams.Fsymb =  simParams.chanBW/(1 + rolloffFac);   % Symbol rate in symbols/sec
simParams.cfo = 0.02*simParams.Fsymb;                   % Carrier frequency offset in Hertz
                                                        % due to oscillator instabilities
simParams.dopplerRate = 3e4;                            % Doppler rate in Hertz/sec
simParams.peakDoppler = 1e6;                            % Peak Doppler shift in Hertz
simParams.sco = 10;                                     % Sampling clock offset in parts
                                                        % per million
simParams.phNoiseLevel = "Level-1";          % Phase noise level
simParams.EsNodB = 15                                   % Energy per symbol to noise ratio
simParams = struct with fields:
    serviceNumber: 2
              sps: 2
        numFrames: 5
           chanBW: 200000000
            Fsymb: 1.4815e+08
              cfo: 2.9630e+06
      dopplerRate: 30000
      peakDoppler: 1000000
              sco: 10
     phNoiseLevel: "Level-1"
           EsNodB: 15

Generate DVB-S2X Wideband Waveform Distorted with RF Impairments

To create a DVB-S2X waveform, use the HelperDVBS2XWidebandRxInputGenerate helper function with the simParams and cfgDVBS2X structures as inputs. The function returns the transmitted data bits, transmitted, and received waveforms, physical layer configuration parameters as a structure, and a receiver processing structure. The received waveform is impaired with carrier frequency, frequency drift, sampling clock offsets, and phase noise and then passed through an AWGN channel. The receiver processing parameters structure, rxParams, includes the reference pilot fields, pilot indices, counters, and buffers. Plot the constellation of the received symbols and the spectrum of the transmitted and received waveforms.

[data,txOut,rxIn,phyConfig,rxParams] = HelperDVBS2XWidebandRxInputGenerate(cfgDVBS2X, ...
    simParams);
% Display the physical layer configuration
phyConfig
phyConfig = struct with fields:
              FECFrame: {'normal'  'normal'  'normal'  'normal'}
      ModulationScheme: {'8PSK'  '8PSK'  '8PSK'  '8PSK'}
    LDPCCodeIdentifier: {'23/36'  '23/36'  '23/36'  '23/36'}

% Received signal constellation plot
rxConst = comm.ConstellationDiagram(Title = "Received data", ...
    XLimits = [-1 1], YLimits = [-1 1], ...
    ShowReferenceConstellation = false, ...
    SamplesPerSymbol = simParams.sps);
rxConst(rxIn(1:rxParams.plFrameSize*simParams.sps))

% Transmitted and received signal spectrum visualization
Fsamp = simParams.Fsymb*simParams.sps;
specAn = spectrumAnalyzer(SampleRate = Fsamp, ...
    ChannelNames = ["Transmitted waveform" "Received waveform"], ...
    ShowLegend = true);
specAn([txOut,rxIn(1:length(txOut))]);

Configure Receiver Parameters

At the receiver, matched filtering is performed on the received data and is then followed by symbol timing synchronization, frame synchronization and carrier synchronization. The symbol timing estimator is non-data aided. The preferred loop bandwidth for symbol timing compensation depends on the Es/No setting.

The frame synchronization uses the PL header and two pilot blocks. Es/No plays a crucial role in determining the accuracy of the frame synchronization. The frame synchronization is performed on successive frames for accurate detection.

The coarse frequency error estimation is performed on the PL header. The fine frequency error estimation can estimate carrier frequency offsets up to 3% of the input symbol rate. The fine frequency estimation must process multiple pilot blocks for the residual carrier frequency offset to be reduced to levels acceptable for the phase estimation algorithm. The phase estimation algorithm can handle residual carrier frequency error up to 0.03% of the input symbol rate.

rxParams.symbSyncLoopBW = 1e-4;          % Symbol timing synchronizer loop bandwidth
                                         % normalized by symbol rate
rxParams.numFramesForFineFreqLock = 3;   % Number of frames required for fine
                                         % frequency estimation

% Create coarse frequency synchronization System object by using
% HelperDVBS2XWidebandCoarseFrequencySynchronizer helper object
freqSync = HelperDVBS2XWidebandCoarseFrequencySynchronizer(SampleRate = simParams.Fsymb);

% Create frame synchronization System object by using
% HelperDVBS2XWidebandFrameSynchronizer helper object
frameSync = HelperDVBS2XWidebandFrameSynchronizer(...
    PLScramblingIndex = cfgDVBS2X.PLScramblingIndex);

% Create symbol timing synchronization System object by using
% comm.SymbolSynchronizer object
symSync = comm.SymbolSynchronizer(TimingErrorDetector = "Gardner (non-data-aided)", ...
    NormalizedLoopBandwidth = rxParams.symbSyncLoopBW, DampingFactor = 1/sqrt(2));

% Create matched filter System object by using
% comm.RaisedCosineReceiveFilter object
decFac = simParams.sps/2;
rxFilter = comm.RaisedCosineReceiveFilter( ...
    RolloffFactor = 0.35, ...
    InputSamplesPerSymbol = simParams.sps, DecimationFactor = decFac);
b = rxFilter.coeffs;
rxFilter.Gain = sum(b.Numerator);

% Initialize error computing parameters
[numFramesLost,pktsErr,bitsErr,pktsRec] = deal(0);

% Initialize data indexing variables
stIdx = 0;
isLastFrame = false;
symBuffer = [];

plFrameSize = rxParams.plFrameSize;
dataSize = rxParams.inputFrameSize;
winLen = plFrameSize;
rxParams.fineFreqCorrVal = zeros(rxParams.numFramesForFineFreqLock,1);
pilotBlkLen = rxParams.pilotBlkLength;

Timing and Carrier Synchronization and Data Recovery

To synchronize the received data, select the appropriate stream (service) and recover the input data, process the distorted DVB-S2X waveform samples one frame at a time by following these steps.

  1. Apply matched filtering, outputting at the rate of two samples per symbol.

  2. Apply symbol timing synchronization using the Gardner timing error detector with an output generated at the symbol rate.

  3. Apply frame synchronization to detect the start of frame.

  4. Estimate and apply coarse frequency offset correction.

  5. Estimate and apply fine frequency offset correction.

  6. Estimate and compensate for residual carrier frequency and phase noise.

  7. Demodulate and decode the PL header.

  8. Select the PL frames corresponding to the required service based on TSN.

  9. Demodulate and decode the PL frames.

  10. Perform CRC check on the BB header, if the check passes, recover the header parameters.

  11. Regenerate the input stream of data or packets from BB frames.

while stIdx < length(rxIn)

    % Use one DVB-S2X PL frame for each iteration.
    endIdx = stIdx + plFrameSize*simParams.sps;

    % In the last iteration, all the remaining samples in the received
    % waveform are used.
    isLastFrame = endIdx > length(rxIn);
    endIdx(isLastFrame) = length(rxIn);
    rxData = rxIn(stIdx+1:endIdx);

    % Retrieve the last frame samples.
    if isLastFrame
        resSampCnt = plFrameSize*rxParams.sps - length(rxData);
        % Inadequate number of samples to fill last frame
        syncIn = [rxData; zeros(resSampCnt,1)];
    else
        syncIn = rxData;
    end

    % Perform matched filtering and downsample the signal to 2 samples per
    % symbol.
    filtOut = rxFilter(syncIn);

    % Apply symbol timing synchronization.
    symSyncOut = symSync(filtOut);

    % Apply frame synchronization
    syncIndex =  frameSync(symSyncOut);
    rxParams.syncIndex = [rxParams.syncIndex;syncIndex];

    if length(rxParams.syncIndex) > 1
        % The PL frame start index lies somewhere in the middle of the data
        % being processed. From coarse frequency compensation onwards, the
        % processing happens as a PL frame. A buffer is used to store symbols
        % required to fill one PL frame.
        stIdx1 = rxParams.syncIndex(1);
        endIdx1 = winLen+rxParams.syncIndex(2);

        cfoIn = symBuffer(stIdx1:endIdx1-1);
        % Extract the number of pilots based on frame length
        numPilots = rxParams.possPilotBlks(rxParams.possFrameSizes == length(cfoIn));

        % Apply coarse frequency synchronization.
        [coarseFreqSyncOut,cEstFreq] = freqSync(cfoIn);

        % Extract the pilot indices and PL scrambled pilots based on number
        % of pilots
        pilotInd = rxParams.pilotIndices(1:numPilots(1));
        pilotVal = rxParams.pilotValues(1:numPilots(1));
        numPilotBlks = numPilots(1)/pilotBlkLen;

        % Estimate the fine frequency error by using the HelperDVBS2FineFreqEst
        % helper function.
        corrVal = HelperDVBS2FineFreqEst(coarseFreqSyncOut(pilotInd),numPilotBlks, ...
            pilotVal,0,pilotBlkLen,rxParams.NumLags);

        % Use the correlation values calculated over pilot fields spanning over
        % multiple frames to calculate the fine frequency error estimate.
        % The estimation uses a sliding window technique.
        fineFreqEst = angle(sum([rxParams.fineFreqCorrVal;corrVal]))/(pi*(rxParams.NumLags));

        ind = (rxParams.frameCount-2)*plFrameSize:(rxParams.frameCount-1)*plFrameSize-1;
        phErr = exp(-1j*2*pi*fineFreqEst*ind).';
        freqCompOut = coarseFreqSyncOut.*phErr(:);

        phErrEst = HelperDVBS2PhaseEst(freqCompOut, ...
            pilotVal,0,pilotInd);
        phaseCompOut = HelperDVBS2PhaseCompensate(freqCompOut, ...
            phErrEst,pilotInd,0,2);

        % Decode the PL header by using the dvbsPLHeaderRecover function                
        phyParams = dvbsPLHeaderRecover(phaseCompOut(1:180),Mode="DVB-S2X wideband");
        plsDecCode = phyParams.PLSDecimalCode;
        timeSliceNum = phyParams.TimeSlicingNumber;
        % Validate the decoded PL header.
        if plsDecCode~=cfgDVBS2X.PLSDecimalCode
            fprintf("%s\n","PL header decoding failed. PLS code is incorrectly decoded")
        else
            if timeSliceNum == simParams.serviceNumber
                % Estimate noise variance by using
                % HelperDVBS2NoiseVarEstimate helper function.
                nVar = HelperDVBS2NoiseVarEstimate(phaseCompOut,pilotInd, ...
                    pilotVal,rxParams.normFlag);
                % Recover the input bit stream by using the
                % dvbs2xBitRecover function.
                [decBitsTemp, isFrameLost, pktCRC]  = dvbs2xBitRecover(phaseCompOut,nVar,Mode="wideband",...
                    TimeSlicingNumber=timeSliceNum,PLScramblingIndex=cfgDVBS2X.PLScramblingIndex);
                decBits = decBitsTemp{:};
                % Recover the input bit stream by using
                % HelperDVBS2StreamRecover helper function.
                if strcmpi(cfgDVBS2X.StreamFormat,"GS") && ~rxParams.UPL
                    if ~isFrameLost && length(decBits) ~= dataSize(timeSliceNum)
                        isFrameLost = true;
                    end
                else                    
                    if ~isFrameLost && length(decBits) ~= dataSize(timeSliceNum)
                        isFrameLost = true;
                        pktCRC = zeros(0,1,"logical");
                    end
                    % Compute the PER for TS or GS packetized mode.
                    % Number of packets in error based on packet CRC status
                    pktsErr = pktsErr + numel(pktCRC{:}) - nnz(pktCRC{:});
                    % Number of packets recovered from the baseband frame
                    pktsRec = pktsRec + numel(pktCRC{:});
                end
                if ~isFrameLost
                    ts = sprintf("%s","BB header decoding passed.");
                else
                    ts = sprintf("%s","BB header decoding failed.");
                end
                % Compute the number of frames lost. CRC failure of the
                % baseband header is considered a frame loss.
                numFramesLost = isFrameLost + numFramesLost;
                frameIdx = ceil((rxParams.frameCount-1)/cfgDVBS2X.NumInputStreams);
                fprintf("%s(Number of frames lost = %1d, service %d, frame number = %d)\n",...
                    ts,numFramesLost,timeSliceNum,frameIdx)
                % Compute the bits in error.
                if ~isFrameLost
                    dataInd = (frameIdx-1)*dataSize(timeSliceNum)+1:frameIdx*dataSize(timeSliceNum);
                    errs = nnz(data{timeSliceNum}(dataInd) ~= decBits);
                    bitsErr = bitsErr + errs;
                end
            end
        end
        symBuffer = symBuffer(endIdx1+1-rxParams.syncIndex(2):end);
        winLen = length(symBuffer);
        rxParams.fineFreqCorrVal(1:end-1) = rxParams.fineFreqCorrVal(2:end);
        rxParams.fineFreqCorrVal(end) = corrVal;
        rxParams.syncIndex =  rxParams.syncIndex(end);
    end
    symBuffer = [symBuffer;symSyncOut];  %#ok<AGROW>
    stIdx = endIdx;
    rxParams.frameCount = rxParams.frameCount + 1;
end
BB header decoding passed.(Number of frames lost = 0, service 2, frame number = 1)
BB header decoding passed.(Number of frames lost = 0, service 2, frame number = 2)
BB header decoding passed.(Number of frames lost = 0, service 2, frame number = 3)
BB header decoding passed.(Number of frames lost = 0, service 2, frame number = 4)
BB header decoding passed.(Number of frames lost = 0, service 2, frame number = 5)

Visualization and Error Logs

Plot the constellation of the synchronized data and compute the BER and PER.

% Synchronized data constellation plot
syncConst = comm.ConstellationDiagram(Title = "Synchronized data", ...
    XLimits = [-1.7 1.7], YLimits = [-1.7 1.7], ...
    ShowReferenceConstellation = false);
syncConst(phaseCompOut)

% Error metrics display
% For GS continuous streams
if strcmpi(cfgDVBS2X.StreamFormat,"GS") && ~rxParams.UPL
    if (simParams.numFrames == numFramesLost)
        fprintf("All frames are lost. No bits are retrieved from BB frames.")
    else
        numFramesRec = simParams.numFrames - numFramesLost;
        ber = bitsErr/(numFramesRec*dataSize(timeSliceNum));
        fprintf("BER           : %1.2e\n",ber)
    end
else
    % For GS and TS packetized streams
    if pktsRec == 0
        fprintf("All frames are lost. No packets are retrieved from BB frames.")
    else
        if strcmpi(cfgDVBS2X.StreamFormat,"TS")
            pktLen = 1504;
        else
            pktLen = cfgDVBS2X.UPL;      % UP length including sync byte
        end
        ber = bitsErr/(pktsRec*pktLen);
        per = pktsErr/pktsRec;
        fprintf("PER: %1.2e\n",per)
        fprintf("BER: %1.2e\n",ber)
    end
end
PER: 0.00e+00
BER: 0.00e+00

Further Exploration

This section explains how to set some of the fields of rxParams to make the example work for low SNR conditions.

Configure Symbol Timing Synchronization Parameters

Because the operating Es/No range of the DVB-S2X standard is very low, you must use small value for rxParams.symbSyncLoopBW parameter for proper symbol synchronization. If the symbol timing loop does not converge, try decreasing the rxParams.symbSyncLoopBW parameter. To achieve convergence of the timing loop, the ratio rxParams.symbSyncLoopBW/simParams.sps must be greater than 1e-5.

Configure Carrier Synchronization Parameters

The HelperDVBS2PhaseEst helper function can estimate the phase offset accurately only if the residual carrier frequency offset (CFO) is less than 0.0003 times the symbol rate. Use the second output argument cEstFreq from the step call of freqSync and the fine frequency offset error estimate fineFreqEst to calculate the overall CFO estimated.

% normCFOEst = cEstFreq/simParams.Fsymb + fineFreqEst;
% actCFO = (simParams.cfo + simParams.peakDoppler)/simParams.Fsymb;
% residualErr = abs(actCFO - normCFOEst);

Increase the rxParams.numFramesForFineFreqLock value to improve the accuracy of the fine frequency error estimate if residualErr is not less than the desired result.

Appendix

The example uses these helper functions:

Bibliography

  1. ETSI Standard EN 302 307-2 V1.1.1(2015-11). Digital Video Broadcasting (DVB); Second Generation Framing Structure, Channel Coding and Modulation Systems for Broadcasting, Interactive Services, News Gathering and other Broadband Satellite Applications; Part 2: DVB-S2 extensions (DVB-S2X).

  2. ETSI Standard EN 302 307-1 V1.4.1(2014-11). Digital Video Broadcasting (DVB); Second Generation Framing Structure, Channel Coding and Modulation Systems for Broadcasting, Interactive Services, News Gathering and other Broadband Satellite Applications (DVB-S2).

  3. ETSI Standard TR 102 376-1 V1.2.1(2015-11). Digital Video Broadcasting (DVB); Implementation Guidelines for the Second Generation System for Broadcasting, Interactive Services, News Gathering and other Broadband Satellite Applications (DVB-S2).

  4. P. Kim and D. Oh, "Frame detection for DVB-S2 based time slice," The 18th IEEE International Symposium on Consumer Electronics (ISCE 2014), 2014, pp. 1-2, doi: 10.1109/ISCE.2014.6884410.

  5. Casini, E., et al. “DVB-S2 Modem Algorithms Design and Performance over Typical Satellite Channels.” International Journal of Satellite Communications and Networking, vol. 22, no. 3, May 2004, pp. 281–318.

  6. Michael Rice, Digital Communications: A Discrete-Time Approach. New York: Prentice Hall, 2008.

See Also

Objects

Related Topics