メインコンテンツ

このページは機械翻訳を使用して翻訳されました。最新版の英語を参照するには、ここをクリックします。

RF 劣化要因と補正を伴うエンドツーエンドの DVB-S2 シミュレーション

この例では、一定のコーディングと変調を備えた単一ストリームのデジタルビデオ放送衛星第 2 世代 (DVB-S2 ) リンクのビット エラー レート ( BER ) とパケット エラー レート (PER) を測定する方法を示します。この例では、シンボル タイミングとキャリア同期戦略について詳細に説明し、ノイズの多い状況で RF フロントエンドの障害を推定する方法に重点を置いています。単一ストリーム信号は RF フロントエンド障害を追加し、波形を加法性ホワイト ガウス ノイズ (AWGN)チャネルに渡します。

はじめに

DVB-S2受信機は、入力シンボル レートの 20% 程度の大きな搬送周波数誤差とかなりの位相ノイズの影響を受けます。Bose-Chaudhuri-Hocquenghem (BCH) コードや低密度パリティ検査 (LDPC) コードなどの強力な前方誤り訂正 ( FEC ) メカニズムの使用により、 DVB-S2システムは、シンボルあたりのエネルギー対ノイズ電力スペクトル密度比 (Es/No) の非常に低い値、つまりシャノン限界に近い値で動作します。

ETSI EN 302 307-1セクション6表13[1]は、さまざまな変調方式と符号化レートに対するAWGNチャネル上の準誤りなし(QEF)パフォーマンス要件をまとめています。さまざまな伝送モードでの動作 Es/No範囲は、QEF パフォーマンスが観察される Es/No ポイントから +2 または -2 dB と見なすことができます。動作 Es/No範囲が狭いため、キャリアとシンボルのタイミング同期戦略は設計上の問題として困難を伴います。

この図は、ワークフローの例をまとめたものです。

メイン処理ループ

この例では、Es/No を 20 dB に設定して 25 個の物理レイヤー(PL) フレームのデータを処理し、 BERと PER を計算します。変調信号には搬送周波数オフセット、サンプリング クロック オフセット、位相ノイズ障害が適用され、AWGN が信号に追加されます。

受信機では、整合フィルタリングの後、タイミングおよびキャリア回復操作が実行され、送信されたデータが回復されます。PL フレームを抽出するために、歪んだ波形はさまざまなタイミングおよびキャリア回復戦略を通じて処理されます。キャリア回復アルゴリズムはパイロット支援型です。データ フレームをデコードするには、変調方式、符号化レート、FEC フレーム タイプなどの物理レイヤー伝送パラメーターをPL ヘッダーから復元します。入力ビット ストリームを再生成するには、ベースバンド (BB) ヘッダーをデコードします。

DVB-S2 規格はパケット化された送信モードと連続送信モードをサポートしているため、BB フレームはユーザー パケットの連結またはビット ストリームのいずれかになります。BB ヘッダーを復元して、送信モードを決定します。BB フレームがユーザー パケットの連結である場合、各パケットの巡回冗長検査 (CRC) ステータスがデコードされたビットとともに返され、その後 PER とBERが測定されます。

これらのブロック図は、同期と入力ビット回復のワークフローを示しています。

DVB-S2 LDPCパリティ行列データセットをダウンロード

この例では、DVB-S2 LDPCパリティ マトリックスを含む MAT ファイルを読み込みます。MAT ファイルが MATLAB ® パス上にない場合は、次のコマンドを使用して MAT ファイルをダウンロードし、解凍します。

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-S2構成

DVB-S2送信構成パラメーターを定義するには、cfgDVBS2 構造を指定します。ScalingMethodプロパティは、MODCODが[18, 28]の範囲内にある場合(つまり、変調方式がAPSKのみの場合)に適用されます。UPLプロパティは、StreamFormatを「GS」に設定した場合に適用されます。

cfgDVBS2.StreamFormat = "TS";
cfgDVBS2.FECFrame = "normal";
cfgDVBS2.MODCOD = 18;                             % 16APSK 2/3
cfgDVBS2.DFL = 42960;
cfgDVBS2.ScalingMethod = "Unit average power";
cfgDVBS2.RolloffFactor = 0.35;
cfgDVBS2.HasPilots = true;
cfgDVBS2.SamplesPerSymbol = 2
cfgDVBS2 = struct with fields:
        StreamFormat: "TS"
            FECFrame: "normal"
              MODCOD: 18
                 DFL: 42960
       ScalingMethod: "Unit average power"
       RolloffFactor: 0.3500
           HasPilots: 1
    SamplesPerSymbol: 2

シミュレーション パラメーター

DVB-S2 規格は柔軟なチャネル帯域幅をサポートします。36 MHz などの一般的なチャネル帯域幅を使用します。チャネル帯域幅は変更できます。この例で実装されているcoarse周波数同期アルゴリズムは、入力シンボル レートの最大 20% までの搬送周波数オフセットを追跡できます。シンボル レートは B/(1+R) として計算されます。ここで、B はチャネル帯域幅、R は送信フィルタのロールオフ係数です。この例で実装されているアルゴリズムは、サンプリング クロックのオフセットを最大 10 ppm まで修正できます。

simParams.sps = cfgDVBS2.SamplesPerSymbol;             % Samples per symbol
simParams.numFrames = 25;                              % Number of frames to be processed
simParams.chanBW = 36e6;                               % Channel bandwidth in Hertz
simParams.cfo = 3e6;                                   % Carrier frequency offset in Hertz
simParams.sco = 5;                                     % Sampling clock offset in parts
                                                       % per million
simParams.phNoiseLevel = "Low";         % Phase noise level provided as
                                                       % "Low", "Medium", or "High"
simParams.EsNodB = 20;                                 % Energy per symbol to noise ratio
                                                       % in decibels

この表は、送信信号に適用される位相ノイズを生成するために使用される位相ノイズマスク (dBc/Hz) を定義します。

dvbs2PhaseNoiseMask.png

RF障害により歪んだDVB-S2波形を生成する

DVB-S2波形を作成するには、simParams および cfgDVBS2 構造体を入力として HelperDVBS2RxInputGenerate ヘルパー関数を使用します。この関数は、データ信号、送信および受信波形、および受信機処理構造を返します。受信波形は、搬送周波数、タイミング位相オフセット、位相ノイズによって劣化し、AWGNチャネルを通過します。受信機処理パラメーター構造 rxParams には、参照パイロット フィールド、パイロット インデックス、カウンタ、およびバッファが含まれます。受信したシンボルのコンスタレーションと、送信波形と受信波形のスペクトルをプロットします。

[data,txOut,rxIn,rxParams] = HelperDVBS2RxInputGenerate(cfgDVBS2,simParams);

% Received signal constellation plot
rxConst = comm.ConstellationDiagram(Title = "Received data", ...
    AxesLimits = [-1 1], ...
    ShowReferenceConstellation = false, ...
    SamplesPerSymbol = simParams.sps);
rxConst(rxIn(1:length(txOut)))

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

受信機パラメーターの設定

受信機では、受信データに対してシンボルタイミング同期が実行され、その後にフレーム同期が実行されます。受信機アルゴリズムには、coarse周波数障害補正アルゴリズムとfine周波数障害補正アルゴリズムが含まれます。搬送周波数推定アルゴリズムは、入力シンボル レートの最大 20% までの搬送周波数オフセットを追跡できます。周波数ロック ループ (FLL) として実装されるcoarse周波数推定により、周波数オフセットは、fine周波数推定器が追跡できるレベルまで低減されます。シンボル タイミングとcoarse周波数補正に推奨されるループ帯域幅は、Es/No 設定によって異なります。

Es/No を減らすと、ループ帯域幅を減らして、取得中にさらに多くのノイズを除去できます。シンボル同期装置とcoarseFLL が収束するために必要なフレーム数は、ループ帯域幅の設定によって異なります。信号が弱い場合は、rxParams.symbSyncLoopBW = 1e-4 に設定し、rxParams.symbSyncLock = ceil(1e5/rxParams.plFrameSize) に設定します。

フレーム同期には PL ヘッダーが使用されます。キャリア同期はデータ支援型であるため、フレーム同期ではフレームの開始を正確に検出する必要があります。Es/No は、フレーム同期の精度を決定する上で重要な役割を果たします。QPSK 変調フレームが 3 dB 未満の Es/No 値で復元されている場合、正確な検出のために複数のフレームでフレーム同期を実行する必要があります。

fine周波数推定では、入力シンボル レートの最大 4% までの搬送周波数オフセットを追跡できます。残留搬送波周波数オフセットを位相推定アルゴリズムで許容可能なレベルまで低減するには、fine周波数推定で複数のパイロット ブロックを処理する必要があります。位相推定アルゴリズムは、入力シンボル レートの 0.02% 未満の残留搬送周波数誤差を処理できます。fine位相補償は、大きな位相ノイズが存在するAPSK変調方式にのみ必要です。

これらの設定は、同期処理のために rxParams 構造に割り当てられます。低い Es/No 値に対してこれらのパラメーターを設定する方法の詳細については、詳細な調査 セクションを参照してください。

rxParams.carrSyncLoopBW = 1e-3;              % Coarse frequency estimator loop bandwidth
                                             % normalized by symbol rate
rxParams.symbSyncLoopBW = 8e-3;              % Symbol timing synchronizer loop bandwidth
                                             % normalized by symbol rate
rxParams.symbSyncLock  = 5;                  % Number of frames required for symbol
                                             % timing error convergence
rxParams.frameSyncLock = 1;                  % Number of frames required for frame
                                             % synchronization
rxParams.hasFinePhaseCompensation = false;   % Flag to indicate whether fine phase
                                             % compensation is used
rxParams.finePhaseSyncLoopBW = 3.5e-4;       % Fine phase compensation loop bandwidth
                                             % normalized by symbol rate

% Total frames taken for symbol timing and frame synchronization to happen
rxParams.initialTimeSync = rxParams.symbSyncLock + rxParams.frameSyncLock;
% Initialize number of frames required for coarse carrier synchronization
% to total number of frames processed in simulation
rxParams.initialTimeFreqSync = simParams.numFrames;

% Create time frequency synchronization System object by using
% HelperDVBS2TimeFreqSynchronizer helper object
timeFreqSync = HelperDVBS2TimeFreqSynchronizer( ...
    CarrSyncLoopBW = rxParams.carrSyncLoopBW, ...
    SymbSyncLoopBW = rxParams.symbSyncLoopBW, ...
    SamplesPerSymbol = simParams.sps, ...
    DataFrameSize = rxParams.xFecFrameSize, ...
    SymbSyncTransitFrames = rxParams.symbSyncLock, ...
    FrameSyncAveragingFrames = rxParams.frameSyncLock);

% Create fine phase compensation System object by using
% HelperDVBS2FinePhaseCompensator helper object. Fine phase
% compensation is only required for 16 and 32 APSK modulated frames
if cfgDVBS2.MODCOD >= 18 && rxParams.hasFinePhaseCompensation
    finePhaseSync = HelperDVBS2FinePhaseCompensator( ...
        DataFrameSize = rxParams.xFecFrameSize, ...
        NormalizedLoopBandwidth = rxParams.finePhaseSyncLoopBW);
end

normFlag = cfgDVBS2.MODCOD >= 18 && strcmpi(cfgDVBS2.ScalingMethod,"Outer radius as 1");

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

% Initialize data indexing variables
stIdx = 0;
% Variables for storing symbol synchronization output length, estimated coarse
% frequency offset, and average coarse frequency offset for every PL frame
[symSyncOutLen,cCFOEst,cCFOEstMean] = deal([]);
% Boolean variable to identify whether simulation has reached last frame, coarse
% frequency offset tracking, and fine frequency offset estimation has
% converged
[isLastFrame,isCoarseFreqLocked,isFineFreqLocked] = deal(false);
% Initialize the variable to store estimated fine frequency offset across
% PL frames
rxParams.fineFreqEstTemp = zeros(simParams.numFrames-rxParams.initialTimeSync,1);
rxParams.totalSyncFrames = simParams.numFrames;
% Counter to track the number of PL frames are used for fine frequency
% offset estimation
numFreqEst = 0;
% For short FEC frames, more PL frames are required to observing the frequency
% offset estimation performance
if cfgDVBS2.FECFrame == "short"
    cF = 5;
    fF = 4;
else
    cF = 3;
    fF = 3;
end
dataSize = rxParams.inputFrameSize;
plFrameSize = rxParams.plFrameSize;

タイミングおよびキャリア同期とデータ回復

受信データを同期し、入力ビット ストリームを復元するには、次の手順に従って、歪んだDVB-S2波形サンプルを 1 フレームずつ処理します。

  1. マッチドフィルタリングを適用し、シンボルごとに 2 つのサンプルのレートで出力します。

  2. シンボル レートで生成された出力を持つ Gardner タイミング エラー検出器を使用して、シンボル タイミング同期を適用します。Gardner TED はデータ支援ではないため、キャリア同期の前に実行されます。

  3. フレーム同期を適用して、フレームの開始を検出し、パイロットの位置を識別します。

  4. coarse周波数オフセット補正を推定して適用します。

  5. fine周波数オフセット補正を推定して適用します。

  6. 残留搬送周波数と位相ノイズを推定し、補正します。

  7. PL ヘッダーをデコードし、送信パラメーターを計算します。

  8. PL フレームを復調およびデコードします。

  9. BB ヘッダーに対して CRC チェックを実行し、チェックに合格した場合はヘッダーパラメーターを回復します。

  10. BB フレームからデータまたはパケットの入力ストリームを再生成します。

while stIdx < length(rxIn)

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

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

    % After coarse frequency offset loop is converged, the FLL works with a
    % reduced loop bandwidth.
    if rxParams.frameCount < rxParams.initialTimeFreqSync
        isCoarseFreqLocked = false;
    else
        isCoarseFreqLocked = true;
    end

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

    % Apply matched filtering, symbol timing synchronization, frame
    % synchronization, and coarse frequency offset compensation.
    if rxParams.frameCount > 1
        [coarseFreqSyncOut,syncIndex,phEst] = timeFreqSync(syncIn,isCoarseFreqLocked);
        % Calculate coarse frequency offset estimate from phaseEst
        coarseCFOEst = diff(phEst(1:simParams.sps:end)/(2*pi));
        if rxParams.frameCount <= rxParams.initialTimeSync
           symSyncOutLen = [symSyncOutLen;length(coarseFreqSyncOut)];
            if any(abs(diff(symSyncOutLen(1:rxParams.frameCount-1))) > 5)
                error("Symbol timing synchronization failed. The loop will not " + ...
                    "converge. No frame will be recovered. Update the symbSyncLoopBW " + ...
                    "parameter according to the EsNo setting for proper loop convergence.");
            end
        end
        if rxParams.frameCount > rxParams.initialTimeSync + 1
            cCFOEstMean=[cCFOEstMean;mean(coarseCFOEst)]; %#ok<*AGROW>
            cCFOEst = [cCFOEst;coarseCFOEst];
            % Check for FLL convergence based on estimated coarse frequency
            % offset values across frames
            if length(cCFOEstMean) > cF
                diffVal = diff(abs(cCFOEstMean));
                if all(diffVal(end-(cF-1)) < 0.01) && ~isCoarseFreqLocked
                    isCoarseFreqLocked = true;
                    rxParams.initialTimeFreqSync = rxParams.frameCount;
                elseif isLastFrame && ~isCoarseFreqLocked
                    fprintf("%s\n",["Coarse frequency error estimation failed. Try analyzing the cCFOEst " ...
                        "across frames and see whether carrier synchronization is properly done. Try reducing the " ...
                        "carrSyncLoopBW parameters. Check with proper frame synchronization happened"]);
                end
            end
        end
        rxParams.syncIndex = syncIndex;

        % The PL frame start index lies somewhere in the middle of the chunk being processed.
        % From fine frequency estimation onwards, the processing happens as a PL frame.
        % A buffer is used to store symbols required to fill one PL frame.
        if isLastFrame
            resCnt = resSymb - length(coarseFreqSyncOut);
            if resCnt <= 0
                fineFreqIn = [rxParams.cfBuffer; coarseFreqSyncOut(1:resSymb)];
            else
                fineFreqIn = [rxParams.cfBuffer; coarseFreqSyncOut; zeros(resCnt, 1)];
            end
        elseif rxParams.frameCount > 1
            fineFreqIn = [rxParams.cfBuffer; coarseFreqSyncOut(1:rxParams.plFrameSize-length(rxParams.cfBuffer))];
        end

        % Estimate the fine frequency error by using the HelperDVBS2FineFreqEst
        % helper function.
        % Add 1 to the conditional check because the buffer used to get one PL
        % frame introduces a delay of one to the loop count.
        if (rxParams.frameCount > rxParams.initialTimeFreqSync + 1) && ...
                ~isFineFreqLocked
            rxParams.fineFreqCorrVal = HelperDVBS2FineFreqEst( ...
                fineFreqIn(rxParams.pilotInd),rxParams.numPilots, ...
                rxParams.refPilots,rxParams.fineFreqCorrVal);
            % Normalize the frequency estimate by the input symbol rate
            % freqEst = angle(R)/(pi*(N+1)), where N (18) is the number of elements
            % used to compute the mean of auto correlation (R) in
            % HelperDVBS2FineFreqEst.
            freqEst = angle(rxParams.fineFreqCorrVal)/(pi*(19));
            rxParams.fineFreqEstTemp(1:end-1) = rxParams.fineFreqEstTemp(2:end);
            rxParams.fineFreqEstTemp(end) = freqEst;
            numFreqEst = numFreqEst+1;
            fprintf("Estimated carrier frequency offset in Hz = %f\n",(coarseCFOEst(end)+freqEst).*Rsymb);
            % Check normalized fine frequency offset estimation has converged within
            % an order of 1e-4
            if numFreqEst>=5
                cg = abs(diff(rxParams.fineFreqEstTemp));
                if all(cg(end-fF:end) < 1e-4)
                    isFineFreqLocked = true;
                    rxParams.totalSyncFrames = rxParams.frameCount;
                      dataStInd = rxParams.frameCount;
                elseif isLastFrame && ~isFineFreqLocked
                    fprintf("%s\n",["Fine frequency error estimation failed. Try analyzing the pilot fields "...
                        "in the PL frame to debug the issue."])
                end
            end
        end

        if isFineFreqLocked
            freqEst = angle(rxParams.fineFreqCorrVal)/(pi*(19));
            % Generate the symbol indices using frameCount and plFrameSize.
            % Subtract 2 from the rxParams.frameCount because the buffer used to get one
            % PL frame introduces a delay of one to the count.
            ind = (rxParams.frameCount-2)*plFrameSize:(rxParams.frameCount-1)*plFrameSize-1;
            phErr = exp(-1j*2*pi*freqEst*ind);
            fineFreqOut = fineFreqIn.*phErr(:);

            % Estimate the phase error estimation by using the HelperDVBS2PhaseEst
            % helper function.
            [phEstRes,rxParams.prevPhaseEst] = HelperDVBS2PhaseEst( ...
                fineFreqOut,rxParams.refPilots,rxParams.prevPhaseEst,rxParams.pilotInd);

            % Compensate for the residual frequency and phase offset by using
            % the
            % HelperDVBS2PhaseCompensate helper function.
            % Use two frames for initial phase error estimation. Starting with the
            % second frame, use the phase error estimates from the previous frame and
            % the current frame in compensation.
            % Add 2 to the frame count comparison to account for delays: One
            % frame due to rxParams.cfBuffer delay and two frames used for phase
            % error estimate.
            if rxParams.frameCount >= rxParams.totalSyncFrames + 2
                coarsePhaseCompOut = HelperDVBS2PhaseCompensate(rxParams.ffBuffer, ...
                    rxParams.pilotEst,rxParams.pilotInd,phEstRes(2));
                % MODCOD >= 18 corresponds to APSK modulation schemes
                if cfgDVBS2.MODCOD >= 18 && rxParams.hasFinePhaseCompensation
                    phaseCompOut = finePhaseSync(coarsePhaseCompOut);
                else
                    phaseCompOut = coarsePhaseCompOut;
                end
            end

            rxParams.ffBuffer = fineFreqOut;
            rxParams.pilotEst = phEstRes;

            % The phase compensation on the data portion is performed by
            % interpolating the phase estimates computed on consecutive pilot
            % blocks. The second phase estimate is not available for the data
            % portion after the last pilot block in the last frame. Therefore,
            % the slope of phase estimates computed on all pilot blocks in the
            % last frame is extrapolated and used to compensate for the phase
            % error on the final data portion.
            if isLastFrame
                pilotBlkLen = 36;    % Symbols
                pilotBlkFreq = 1476; % Symbols
                avgSlope = mean(diff(phEstRes(2:end)));
                chunkLen = rxParams.plFrameSize - rxParams.pilotInd(end) + ...
                    rxParams.pilotInd(pilotBlkLen);
                estEndPh = phEstRes(end) + avgSlope*chunkLen/pilotBlkFreq;
                coarsePhaseCompOut1 = HelperDVBS2PhaseCompensate(rxParams.ffBuffer, ...
                    rxParams.pilotEst,rxParams.pilotInd,estEndPh);
                % MODCOD >= 18 corresponds to APSK modulation schemes
                if cfgDVBS2.MODCOD >= 18 && rxParams.hasFinePhaseCompensation
                    phaseCompOut1 = finePhaseSync(coarsePhaseCompOut1);
                else
                    phaseCompOut1 = coarsePhaseCompOut1;
                end
            end
        end

        % Recover the input bit stream.
        if rxParams.frameCount >= rxParams.totalSyncFrames + 2
            isValid = true;
            if isLastFrame
                syncOut = [phaseCompOut; phaseCompOut1];
            else
                syncOut = phaseCompOut;
            end
        else
            isValid = false;
            syncOut = [];
        end

        % Update the buffers and counters.
        rxParams.cfBuffer = coarseFreqSyncOut(rxParams.syncIndex:end);

        if isValid  % Data valid signal
            % Decode the PL header by using the dvbsPLHeaderRecover
            % function
            rxPLHeader = syncOut(1:90);
            phyParams = dvbsPLHeaderRecover(rxPLHeader,Mode="DVB-S2/S2X regular");
            M = phyParams.ModulationOrder;
            R = eval(phyParams.LDPCCodeIdentifier);
            fecFrame = phyParams.FECFrameLength;
            pilotStat = phyParams.HasPilots;            
            xFECFrameLen = fecFrame/log2(M);
            % Validate the decoded PL header.
            if M ~= rxParams.modOrder || R ~= rxParams.codeRate || ...
                    fecFrame ~= rxParams.cwLen || ~pilotStat
                fprintf("%s\n","PL header decoding failed")
                dataStInd = dataStInd + 1;
            else % Demodulation and decoding
                    rxFrame = syncOut(1:plFrameSize);
                    % Estimate noise variance by using
                    % HelperDVBS2NoiseVarEstimate helper function.
                    nVar = HelperDVBS2NoiseVarEstimate(rxFrame,rxParams.pilotInd,...
                        rxParams.refPilots,normFlag);
                    % Recover the input bit stream by using
                    % dvbs2BitRecover function
                    [decBitsTemp, isFrameLost, pktCRC]  = dvbs2BitRecover(rxFrame,nVar);
                    decBits = decBitsTemp{:};

                    if ~isFrameLost && length(decBits) ~= dataSize
                        isFrameLost = true;
                    end
                    if ~isFrameLost && ~(strcmpi(cfgDVBS2.StreamFormat,"GS") && ~rxParams.UPL)
                        % Compute the packet error rate for TS or GS packetized
                        % mode.
                        pktsErr = pktsErr + numel(pktCRC{:}) - sum(pktCRC{:});
                        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 baseband header
                    % is considered a frame loss.
                    numFramesLost = isFrameLost + numFramesLost;
                    fprintf("%s(Number of frames lost = %1d)\n",ts,numFramesLost)
                    % Compute the bits in error.
                    bitInd = (dataStInd-1)*dataSize+1:dataStInd*dataSize;
                    if isLastFrame && ~isFrameLost
                        bitsErr = bitsErr + sum(data(bitInd) ~= decBits);
                    else
                        if ~isFrameLost
                            bitsErr = bitsErr + sum(data(bitInd) ~= decBits);
                        end
                    end
                    dataStInd = dataStInd + 1;
            end
        end
    end
    stIdx = endIdx;
    rxParams.frameCount = rxParams.frameCount + 1;
end
Estimated carrier frequency offset in Hz = 3019975.374357
Estimated carrier frequency offset in Hz = 3012287.586473
Estimated carrier frequency offset in Hz = 3008105.479653
Estimated carrier frequency offset in Hz = 3005952.086303
Estimated carrier frequency offset in Hz = 3004454.246413
Estimated carrier frequency offset in Hz = 3003852.095336
Estimated carrier frequency offset in Hz = 3003342.796983
BB header decoding passed.(Number of frames lost = 0)
BB header decoding passed.(Number of frames lost = 0)
BB header decoding passed.(Number of frames lost = 0)
BB header decoding passed.(Number of frames lost = 0)

可視化とエラーログ

同期されたデータのコンスタレーションをプロットし、BER と PER を計算します。

% Synchronized data constellation plot
syncConst = comm.ConstellationDiagram(Title = "Synchronized data", ...
    AxesLimits = [-2 2], ...
    ShowReferenceConstellation = false);
syncConst(syncOut)

pause(0.5)
% Error metrics display
% For GS continuous streams
if strcmpi(cfgDVBS2.StreamFormat,"GS") && ~rxParams.UPL
    if (simParams.numFrames-rxParams.totalSyncFrames == numFramesLost)
        fprintf("All frames are lost. No bits are retrieved from BB frames.")
    else
        ber = bitsErr/((dataStInd-rxParams.totalSyncFrames)*dataSize);
        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(cfgDVBS2.StreamFormat,"TS")
            pktLen = 1504;
        else
            pktLen = cfgDVBS2.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

その他の調査

DVB-S2 規格の動作 Es/No範囲は非常に狭いため、正確な推定を行うには、シンボル同期装置とcoarseFLL の正規化されたループ帯域幅を非常に小さくする必要があります。これらのパラメーターは rxParams.symbSyncLoopBW および rxParams.carrSyncLoopBW を介して設定されます。

シンボルタイミング同期パラメーターを構成する

正規化されたループ帯域幅が 1e-4 に設定されたシンボル タイミング シンクロナイザーを使用してシミュレーションを実行してみてください。シンボル タイミング ループが収束しない場合は、rxParams.symbSyncLoopBW を減らして、rxParams.symbSyncLock を増やしてみてください。タイミング ループの収束を達成するには、比率 rxParams.symbSyncLoopBW/simParams.sps が 1e-5 より大きくなければなりません。

フレーム同期パラメーターを構成する

シンボル タイミング同期パラメーターの設定セクションに記載されている表から rxParams.symbSyncLock 値を選択します。Es/Noの設定に基づいて、rxParams.frameSyncLockを[1, 15]フレームの範囲の値に設定します。出力が期待どおりでない場合は、フレーム同期に必要なフレーム数を増やします。

キャリア同期パラメーターの設定

PSK信号の場合は 1e-4、 APSK信号の場合は 4e-4 の正規化ループ帯域幅で構成されたcoarseFLL を使用してシミュレーションを実行してみてください。FLLトラッキングパフォーマンスは複数のフレームにわたって計算され、次の段階であるfine周波数オフセット補正に移行するタイミングの収束基準が設計されます。一定の範囲内の振動パターンが収束基準として考慮されます。大まかな周波数オフセット推定を可視化するには、cCFOEst をプロットします。

fine周波数オフセットは、フレームごとに複数のパイロット ブロックにわたって平均化されます。推定値が複数のフレームにわたって 1e-4 のオーダーで収束する場合、それはfine周波数オフセット推定値であるとみなされます。残留搬送周波数オフセットがシンボルレートの 0.02% 未満の場合にのみ適切な位相オフセット推定を行うことができるため、この収束基準が使用されます。

fine位相補償 PLL は、位相ノイズがかなり大きい 16 APSKおよび 32 APSK変調方式にのみ使用されます。

rxParams 構造に設定された同期パラメーターを調整した後、更新された構成のBERシミュレーションを実行します。

サポート ファイル

この例では、次のヘルパー関数を使用します。

参考文献

  1. ETSI規格 EN 302 307-1 V1.4.1(2014-11)。デジタル ビデオ放送 (DVB)。放送、インタラクティブ サービス、ニュース収集、およびその他のブロードバンド衛星アプリケーション向けの第 2 世代のフレーミング構造、チャネルコーディングおよび変調システム ( DVB-S2)

  2. ETSI規格 TR 102 376-1 V1.2.1(2015-11)。デジタル ビデオ放送 (DVB)、放送、インタラクティブ サービス、ニュース ギャザリング、およびその他のブロードバンド衛星アプリケーション向けの第 2 世代システムの実装ガイドライン (DVB-S2)

  3. メンガリ、ウンベルト、アルド・ダンドレア。デジタル受信機の同期技術New York: プレナムプレス、1997年。

  4. E.カシーニ、R.デ・ガウデンツィ、アルベルト・ジネージ。「DVB-S2 モデム アルゴリズムの設計と一般的な衛星チャネルでのパフォーマンス」国際衛星通信ネットワークジャーナル 22、第3号(2004年):281-318.

  5. マイケル・ライス、Digital Communications:離散時間アプローチ 。New York: プレンティスホール、2008年。

参考

オブジェクト

トピック