メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

ソフトウェア無線を使用した 5G NR 同期信号のキャプチャ

R2024a 以降

この例では、ソフトウェア無線 (SDR) を使用して同期信号バースト (SS バースト) をキャプチャする方法を示します。次に、この例では、キャプチャを解析して最も強い同期信号ブロック (SSB) の特定を試みます。また、NR セル サーチおよび MIB と SIB1 の復元の例を使用し、キャプチャを MAT ファイルに保存してさらに解析することができます。

はじめに

An SDR captures a signal from a 5G cell tower and passes it to the 5G Toolbox for analysis.

ユーザー端末 (UE) は、初期同期手順を実行する際、事前定義された中心周波数のセットをスキャンし、SS バーストを検索しなければなりません。UE は、SSB を検出すると、セル ID を識別し、MIB とシステム情報ブロック タイプ 1 (SIB1) を復元します。

UE が検索する周波数は、TS 38.101-1 の Table 5.4.3.3-1 [1] で定義されているグローバル同期チャネル番号 (GSCN) によって決まります。この例では、対象の動作帯域の GSCN 値を選択して中心周波数を計算する方法について説明します。この例では、中心周波数を決定した後、指定された周波数で波形をキャプチャするように SDR 受信機を設定します。ゲイン、キャプチャ帯域幅、キャプチャ アンテナなど、SDR 受信機の追加パラメーターを指定できます。この例では、SDR 受信機が波形をキャプチャした後、波形内で最も強い SSB の位置の特定を試みます。波形に SSB が含まれており、MIB と SIB1 の完全な復元を実行する場合は、NR セル サーチおよび MIB と SIB1 の復元の例を使用し、波形を MAT ファイルに保存してさらに解析することができます。

必要なハードウェアとソフトウェア

この例では、Wireless Testbench™ サポート パッケージおよび Communication Toolbox™ サポート パッケージでサポートされている SDR を使用します。この例で使用できる無線機と必要な製品に関する情報を次のリストに示します。

  • 300 シリーズ USRP™ 無線機または USRP X410 (Wireless Testbench™ Support Package for NI™ USRP Radios および Wireless Testbench Support Package for NI™ USRP Radios が必要)。詳細については、Install Support Package for NI USRP Radios (Wireless Testbench)およびSupported Radio Devices (Wireless Testbench)を参照してください。

  • ADALM-PLUTO (Communications Toolbox Support Package for Analog Devices® ADALM-PLUTO Radio が必要)。詳細については、ADALM-Pluto 無線機を参照してください。

  • USRP E310/E312 (Communications Toolbox Support Package for USRP™ Embedded Series Radio が必要)。詳細については、USRP Embedded Series 無線機を参照してください。

  • 200 シリーズ USRP 無線機 (Communications Toolbox Support Package for USRP Radio が必要)。詳細については、USRP 無線機およびSupported Hardware and Required Softwareを参照してください。

SDR パラメーターの構成

SDR 受信機オブジェクトの設定

ドロップダウン リストから、SDR のデバイス名、キャプチャ アンテナ構成、および無線機のゲインを指定します。

Wireless Testbench と共に NI USRP ハードウェアを使用している場合、[更新] をクリックすると、保存済みの無線設定構成名がドロップダウン リストの上部に表示されます。

radioOptions = hSDRBase.getDeviceNameOptions;
rx = hSDRReceiver(radioOptions(1)) ;
antennaOptions = getAntennaOptions(rx);
rx.ChannelMapping = antennaOptions(1);
rx.Gain = 50;

キャプチャ中心周波数の指定

キャプチャ中心周波数を決定する場合、GSCN 値とカスタム中心周波数のいずれかを指定できます。

GSCN 値を決定するには、まず、キャプチャする NR 動作帯域を決定しなければなりません。hSynchronizationRasterInfo クラスの FR1DLOperatingBand プロパティに格納されているテーブルを使用して、選択可能な動作帯域とその周波数範囲を検査します。TS 38.101-1 の Table 5.2-1 では、FR1DLOperatingBand プロパティに格納されるテーブルが定義されています。

fr1BandInfo = hSynchronizationRasterInfo.FR1DLOperatingBand
fr1BandInfo=49×2 table
           Lower Bound (MHz)    Upper Bound (MHz
           _________________    ________________

    n1           2110                 2170      
    n2           1930                 1990      
    n3           1805                 1880      
    n5            869                  894      
    n7           2620                 2690      
    n8            925                  960      
    n12           729                  746      
    n13           746                  756      
    n14           758                  768      
    n18           860                  875      
    n20           791                  821      
    n24          1525                 1559      
    n25          1930                 1995      
    n26           859                  894      
    n28           758                  803      
    n29           717                  728      
      ⋮

キャプチャする帯域を決定したら、下の編集フィールドでそれを指定します。

この例では、選択可能な GSCN 値、SS バーストのサブキャリア間隔、および SS バーストのブロック パターンを含む構造体を抽出します。hSynchronizationRasterInfo クラスの SynchronizationRasterFR1 プロパティに格納される情報は、TS 38.101-1 の Table 5.4.3.3-1 から取得されます。

syncRasterInfo = hSynchronizationRasterInfo.SynchronizationRasterFR1;
band = "n77";
bandRasterInfo = syncRasterInfo.(band)
bandRasterInfo = struct with fields:
             SCS: 30
    BlockPattern: 'C'
            GSCN: [7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 … ] (1×619 double)

対象動作帯域の GSCN 値を選択した後、下の編集フィールドで GSCN パラメーターを指定します。

カスタム中心周波数を使用する場合は、useCenterFrequency を選択してカスタム中心周波数を入力します。

useCustomCenterFrequency = false;
GSCN = 7791;
if useCustomCenterFrequency
    rx.CenterFrequency =  3520e6; %#ok<*UNRCH>
else
    rx.CenterFrequency = hSynchronizationRasterInfo.gscn2frequency(GSCN);
end

サブキャリア間隔の決定

この例では、中心周波数に基づいて、中心周波数が含まれる動作帯域に関係する選択可能なサブキャリア間隔のオプション (15 kHz または 30 kHz) を決定します。

[更新] をクリックすると、選択可能なサブキャリア間隔のオプションが表示され、サブキャリア間隔を選択できます。この例では、サブキャリア間隔を使用して、キャプチャされた波形を解析します。

scsOptions = hSynchronizationRasterInfo.getSCSOptions(rx.CenterFrequency);
scs =  scsOptions(1) ;

最小キャプチャ サンプル レートの決定

nrOFDMInfo関数を使用して、SSB の最適なキャプチャ サンプル レートを計算します。または、カスタム サンプル レートを指定します。

nrbSSB = 20; % Number of resource blocks in an SSB
scsNumeric = double(extract(scs,digitsPattern));
ofdmInfo = nrOFDMInfo(nrbSSB,scsNumeric);
rx.SampleRate = ofdmInfo.SampleRate;

波形キャプチャの開始

framesPerCapture パラメーターを使用して、完全にキャプチャできるフレームの最小数を指定します。

framesPerCapture = 2;
captureDuration = seconds((framesPerCapture+1)*10e-3);

波形の取得を開始します。

waveform = capture(rx,captureDuration);
release(rx);

最も強い SSB の位置の特定

findSSB ローカル関数を使用して、キャプチャされた波形に有効な SSB が存在するかどうかを特定します。

detectedSSB = findSSB(waveform,rx.CenterFrequency,scs,rx.SampleRate);

その他の調査

波形の保存

この例でキャプチャした波形において有効な SSB が検出された場合は、波形を MAT ファイルに保存し、NR セル サーチおよび MIB と SIB1 の復元の例を使ってより詳細な解析を行います。

MAT ファイルのファイル名を指定します。この例では、波形を保存するときに、GSCN 値とキャプチャ日をファイル名に追加します。

fileNamePrefix = "capturedWaveform";
if detectedSSB
    saveWaveform(rx,waveform,scs,fileNamePrefix)
end

複数の GSCN のスキャン

これまでの例では、単一の波形のみをキャプチャし、その初期解析を実行しました。次のコードを使用すると、複数の GSCN 値を指定して中心周波数のセットをスキャンし、有効な SSB を検索することができます。この例では、検出された SSB ごとに SSB を表示し、キャプチャした波形を MAT ファイルに保存します。

この例でスキャンする GSCN 値のベクトルを指定します。有効な GSCN 値を決定するには、「キャプチャ中心周波数の指定」のセクションを参照してください。

GSCNs = [7884 7923 7981];

SDR 受信機がキャプチャするフレームの数を設定します。

framesPerCapture = 2;

scanGSCNs ローカル関数を使用して、指定された GSCN で有効な SSB の検索を開始します。この関数には、いずれかの入力として hSDRReceiver オブジェクトが必要です。SDR 受信機をまだ設定していない場合は、「SDR 受信機オブジェクトの設定」のセクションを参照してください。

scanGSCNs(rx,GSCNs,framesPerCapture,fileNamePrefix);

No SSB Detected at GSCN 7923 (3610.56 MHz).

参考文献

  1. 3GPP TS 38.101-1. "NR; User Equipment (UE) radio transmission and reception; Part 1: Range 1 Standalone" 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

ローカル関数

これらの機能は、有効な SSB の位置を特定するのに役立ちます。

function scanGSCNs(rx,gscns,framesPerCapture,fileNamePrefix)
% SCANGSCNS uses the SDR receiver RX to capture a waveform at each GSCN in
% GSCNS. The functions analyzes each captured waveform for a valid SSB and
% subsequently saves the waveform to a MAT-file with the file name
% containing FILENAMEPREFIX. The duration of each captured waveform depends
% on FRAMESPERCAPTURE.
    captureDuration = seconds((framesPerCapture+1)*10e-3);

    for gscn = gscns

        % Set up center frequency and sample rate based on GSCN
        rx.CenterFrequency = hSynchronizationRasterInfo.gscn2frequency(gscn);
        scsOptions = hSynchronizationRasterInfo.getSCSOptions(rx.CenterFrequency);
        for scs = scsOptions
            scsNumeric = double(extract(scs,digitsPattern));
            nrbSSB = 20; % Number of resource blocks in an SSB
            ofdmInfo = nrOFDMInfo(nrbSSB,scsNumeric);
    
            % The receiver only captures a wide enough bandwidth to detect a
            % SSB. To find and decode the SIB1 the sample rate will need
            % increased.
            rx.SampleRate = ofdmInfo.SampleRate;
    
            % Capture waveform
            waveform = capture(rx,captureDuration);
            release(rx);
    
            % Search for a valid SSB
            detectedSSB = findSSB(waveform,rx.CenterFrequency,scs,rx.SampleRate);
    
            if detectedSSB
                saveWaveform(rx,waveform,scs,fileNamePrefix)
            end
        end
    end
end

function saveWaveform(rx,waveform,scs,fileNamePrefix)
% SAVEWAVEFORM saves the WAVEFORM and other parameters to a MAT-file with
% the name containing FILENAMEPREFIX.
    % Initialize parameters that are to be saved to the MAT-file
    sampleRate = rx.SampleRate;
    fPhaseComp = rx.CenterFrequency;
    minChannelBW = hSynchronizationRasterInfo.getMinimumBandwidth(scs,rx.CenterFrequency);
    ssbBlockPattern = hSynchronizationRasterInfo.getBlockPattern(scs,rx.CenterFrequency);

    % Determine the number of SSBs in the SS burst
    if fPhaseComp > 3e9
        L_max = 8;
    else
        L_max = 4;
    end

    % Append GSCN and capture date to user supplied file name and save file
    gscn = hSynchronizationRasterInfo.frequency2gscn(rx.CenterFrequency);
    fileName = fileNamePrefix+"_"+gscn+string(datetime('now',Format='_yyyy_MM_dd'))+".mat";
    save(fileName,"waveform","sampleRate","fPhaseComp","minChannelBW","ssbBlockPattern","L_max")
end
function detectedSSB = findSSB(waveform,centerFrequency,scs,sampleRate)
% FINDSSB returns a logical value that depends on if WAVEFORM contains a
% valid SSB.
    ssbBlockPattern = hSynchronizationRasterInfo.getBlockPattern(scs,centerFrequency);
    scsNumeric = double(extract(scs,digitsPattern));
    searchBW = 3*scsNumeric;
    displayFigure = false;
    [correctedWaveform,~,NID2] = hSSBurstFrequencyCorrect(waveform,ssbBlockPattern,sampleRate,searchBW,displayFigure);

    % Create a reference grid for timing estimation
    nrbSSB = 20;
    refGrid = zeros([nrbSSB*12 2]);
    refGrid(nrPSSIndices,2) = nrPSS(NID2);

    % Calculate timing offset and demodulate the grid
    nSlot = 0;
    timingOffset = nrTimingEstimate(correctedWaveform,nrbSSB,scsNumeric,nSlot,refGrid,SampleRate=sampleRate);
    correctedWaveform = correctedWaveform(1+timingOffset:end,:);
    rxGrid = nrOFDMDemodulate(correctedWaveform,nrbSSB,scsNumeric,nSlot,SampleRate=sampleRate);
    rxGrid = rxGrid(:,2:5,:);

    % Extract the received SSS symbols from the SS/PBCH block
    sssIndices = nrSSSIndices;
    sssRx = nrExtractResources(sssIndices,rxGrid);

    % Correlate received SSS symbols with each possible SSS sequence
    sssEst = zeros(1,336);
    for NID1 = 0:335
        ncellid = (3*NID1) + NID2;
        sssRef = nrSSS(ncellid);
        sssEst(NID1+1) = sum(abs(mean(sssRx .* conj(sssRef),1)).^2);
    end

    % Determine NID1 by finding the strongest correlation
    NID1 = find(sssEst==max(sssEst)) - 1;

    % Form overall cell identity from estimated NID1 and NID2
    ncellid = (3*NID1) + NID2;

    % Calculate PBCH DM-RS indices
    dmrsIndices = nrPBCHDMRSIndices(ncellid);

    % Perform channel estimation using DM-RS symbols for each possible
    % DM-RS sequence and estimate the SNR
    dmrsEst = zeros(1,8);
    for ibar_SSB = 0:7
        refGrid = zeros([240 4]);
        refGrid(dmrsIndices) = nrPBCHDMRS(ncellid,ibar_SSB);
        [hest,nest] = nrChannelEstimate(rxGrid,refGrid,'AveragingWindow',[0 1]);
        dmrsEst(ibar_SSB+1) = 10*log10(mean(abs(hest(:).^2)) / nest);
    end

    % Record ibar_SSB for the highest SNR
    ibar_SSB = find(dmrsEst==max(dmrsEst)) - 1;

    % Channel Estimation using PBCH DM-RS and SSS
    refGrid = zeros([nrbSSB*12 4]);
    refGrid(dmrsIndices) = nrPBCHDMRS(ncellid,ibar_SSB);
    refGrid(sssIndices) = nrSSS(ncellid);
    [hest,nest] = nrChannelEstimate(rxGrid,refGrid,'AveragingWindow',[0 1]);

    % Extract the received PBCH symbols from the SS/PBCH block
    [pbchIndices,pbchIndicesInfo] = nrPBCHIndices(ncellid);
    pbchRx = nrExtractResources(pbchIndices,rxGrid);

    % Configure 'v' for PBCH scrambling according to TS 38.211 Section
    % 7.3.3.1 'v' is also the 2 LSBs of the SS/PBCH block index for
    % L_max=4, or the 3 LSBs for L_max=8 or 64.
    if centerFrequency <= 3e9
        L_max = 4;
        v = mod(ibar_SSB,L_max);
    else
        L_max = 8;
        v = ibar_SSB;
    end
    ssbIndex = v;

    % PBCH equalization and CSI calculation
    pbchHest = nrExtractResources(pbchIndices,hest);
    [pbchEq,csi] = nrEqualizeMMSE(pbchRx,pbchHest,nest);
    Qm = pbchIndicesInfo.G / pbchIndicesInfo.Gd;
    csi = repmat(csi.',Qm,1);
    csi = reshape(csi,[],1);

    % PBCH demodulation
    pbchBits = nrPBCHDecode(pbchEq,ncellid,v,nest);

    % Apply CSI
    pbchBits = pbchBits .* csi;

    % Perform BCH decoding
    polarListLength = 8;
    [~,crcBCH] = nrBCHDecode(pbchBits,polarListLength,L_max,ncellid);
    gscn = hSynchronizationRasterInfo.frequency2gscn(centerFrequency);
    if crcBCH == 0
        % Plot grid and highlight strongest SSB
        demodRB = 30;
        rxGrid = nrOFDMDemodulate(correctedWaveform,demodRB,scsNumeric,nSlot,SampleRate=sampleRate);
        % Extract 4 symbols of grid if exists
        if size(rxGrid,2) < 56
            last = size(rxGrid,2);
        else
            last = 14*4;
        end
        figure;imagesc(abs(rxGrid(:,1:last,1))); axis xy
        xlabel('OFDM symbol'); ylabel('Subcarrier');
        ttl = sprintf('Resource Grid of SS Burst at GSCN %d (%.2f MHz)',gscn,centerFrequency/1e6);
        title(ttl)
        ssbFreqOrigin = 12*(demodRB-nrbSSB)/2 + 1;
        startSymbol = 1;
        numSymbolsSSB = 4;
        rectangle('Position',[startSymbol+0.5 ssbFreqOrigin-0.5 numSymbolsSSB 12*nrbSSB],EdgeColor='r',LineWidth=1.5)
        str = sprintf('Strongest SSB: %d',ssbIndex);
        text(startSymbol,ssbFreqOrigin-nrbSSB,0,str,FontSize=12,Color='w');
        detectedSSB = true;
        drawnow
    else
        detectedSSB = false;
        fprintf("<strong>No SSB Detected at GSCN %d (%.2f MHz).</strong>\n",gscn,centerFrequency/1e6);
    end
end

参考

トピック