このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
ソフトウェア無線を使用した 5G NR 同期信号のキャプチャ
この例では、ソフトウェア無線 (SDR) を使用して同期信号バースト (SS バースト) をキャプチャする方法を示します。次に、この例では、キャプチャを解析して最も強い同期信号ブロック (SSB) の特定を試みます。また、NR セル サーチおよび MIB と SIB1 の復元の例を使用し、キャプチャを MAT ファイルに保存してさらに解析することができます。
はじめに
ユーザー端末 (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).
参考文献
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