このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
NR 位相ノイズのモデリングと補償
この例では、5G OFDM システムにおける位相ノイズの影響を示し、位相トラッキング基準信号 (PT-RS) を使用して共通位相誤差 (CPE) を補償する方法を示します。この例では、CPE 補償を使用した場合と使用しない場合のエラー ベクトル振幅 (EVM) とビット エラー レート (BER) を測定します。
はじめに
5G NR では、3GPP によって位相トラッキング基準信号 (PT-RS) と呼ばれる新しい基準信号が導入されており、発振器ノイズを扱えるようになっています。発振器で発生したノイズにより、情報信号が位相変調を受け、情報信号の周波数スペクトルとタイミング特性が大きく変化することになります。この発振器に関連する現象を位相ノイズと呼びます。ローカル発振器で生成される位相ノイズは、位相ノイズのパワー スペクトル密度に応じて、ミリメートル波 (mmWave) の周波数で大幅な劣化を引き起こします。位相ノイズは、CPE とキャリア間干渉 (ICI) を発生させます。CPE は、各サブキャリアで受信シンボルを同一方向に回転させます。ICI は、サブキャリア間の直交性の喪失につながります。PT-RS が周波数領域において分散構造をもつことから、この例では主に PT-RS を使用し、システム パフォーマンスに対する CPE の影響を推定して最小化します。この例では、物理ダウンリンク共有チャネル (PDSCH) で構成される波形に位相ノイズを適用し、CPE 補償を使用した場合と使用しない場合の EVM と BER の変化を示します。次の図は、この例で実装される処理チェーンを示しています。
位相ノイズのモデル化
発振器のパワー スペクトル密度は、位相ノイズをモデル化します。この例では、多重極零点モデルを使用して、発振器のパワー スペクトル密度を概算します。simParameters
構造体の PNModel
フィールドを使用して、位相ノイズ モデルを次から選択します。'A'、'B'、または 'C'。パラメーター セット 'A' と 'B' は、それぞれ 30 GHz と 60 GHz で動作する実際の発振器 (TDoc R1-163984 に記載) から取得されます。パラメーター セット 'C' は、29.55 GHz で動作する実際の発振器 (TR 38.803 の Section 6.1.10 に記載) から取得されます。
この例では、伝送帯域幅 50 MHz に対してサブキャリア間隔が 60 kHz のキャリアを使用します。
% Configure carrier carrier = nrCarrierConfig; carrier.SubcarrierSpacing = 60; carrier.CyclicPrefix = 'normal'; carrier.NSizeGrid = 66; % Set the operating frequency and choose the phase noise model simParameters = []; simParameters.Fc = 30e9; % Frequency in Hz simParameters.PNModel = 'A'; % 'A' (TDoc R1-163984 Set A), 'B' (TDoc R1-163984 Set B), 'C' (TR 38.803) % Get the sample rate ofdmInfo = nrOFDMInfo(carrier); sr = ofdmInfo.SampleRate; % Phase noise level foffsetLog = (4:0.2:log10(sr/2)); % Model offset from 1e4 Hz to sr/2 Hz foffset = 10.^foffsetLog; % Linear frequency offset pn_PSD = hPhaseNoisePoleZeroModel(foffset,simParameters.Fc,simParameters.PNModel); % dBc/Hz % Set phase noise level pnoise = comm.PhaseNoise('FrequencyOffset',foffset,'Level',pn_PSD,'SampleRate',sr); pnoise.RandomStream = "mt19937ar with seed"; % Visualize spectrum mask of phase noise figure semilogx(foffset,pn_PSD) xlabel('Frequency offset (Hz)') ylabel('dBc/Hz') title('Phase noise magnitude response') grid on
PDSCH の構成
この例では、変調スキームを '64QAM' に設定し、レイヤー数を 1 に設定して、キャリア全体を占有する PDSCH を設定します。この例では、既定で 1 つのレイヤーと符号化されていないランダム ビットから成る 1 つのコードワードを使用します。
% Set PDSCH parameters pdsch = nrPDSCHConfig; pdsch.PRBSet = 0:carrier.NSizeGrid-1; pdsch.SymbolAllocation = [0 14]; pdsch.Modulation = '64QAM'; pdsch.NumLayers = 1; pdsch.MappingType = 'A'; pdsch.NID = 1; pdsch.RNTI = 2; % Set DM-RS parameters pdsch.DMRS.DMRSConfigurationType = 1; pdsch.DMRS.DMRSTypeAPosition = 2; pdsch.DMRS.DMRSAdditionalPosition = 0; pdsch.DMRS.DMRSLength = 1; pdsch.DMRS.DMRSPortSet = []; pdsch.DMRS.NumCDMGroupsWithoutData = 1; pdsch.DMRS.NIDNSCID = 1; pdsch.DMRS.NSCID = 0; % Set PT-RS parameters pdsch.EnablePTRS = 1; pdsch.PTRS.TimeDensity = 1; pdsch.PTRS.FrequencyDensity = 2; pdsch.PTRS.REOffset = '00'; pdsch.PTRS.PTRSPortSet = [];
波形の生成
波形は 2 フレーム生成され、simParameters
構造体のフィールド NumFrames
が波形のフレーム数を制御します。次の手順が含まれます。
PDSCH のビット容量でランダム コードワードを生成
ランダム コードワードの PDSCH シンボルを取得し、それらをグリッドにマッピング
DM-RS シンボルを生成してグリッドにマッピング
PT-RS シンボルを生成してグリッドにマッピング
すべてのフレームの完全なグリッドに対して OFDM 変調を実行
% Number of frames to generate the waveform simParameters.NumFrames = 2; % Get the number of slots in the waveform and number of symbols in a slot numSlots = carrier.SlotsPerFrame*simParameters.NumFrames; nSlotSymb = carrier.SymbolsPerSlot; % Initialize the grid for specified number of frames txGrid = zeros(carrier.NSizeGrid*12,nSlotSymb*numSlots,pdsch.NumLayers); % Processing loop txbits = []; rng('default') for slotIdx = 0:numSlots - 1 % Set slot number carrier.NSlot = slotIdx; % Get PDSCH indices and structural information [pdschInd,pdschIndicesInfo] = nrPDSCHIndices(carrier,pdsch); % Generate random codeword(s) numCW = pdsch.NumCodewords; % Number of codewords data = cell(1,numCW); for i = 1:numCW data{i} = randi([0 1],pdschIndicesInfo.G(i),1); txbits = [txbits; data{i}]; %#ok<AGROW> end % Get modulated symbols pdschSym = nrPDSCH(carrier,pdsch,data); % Get DM-RS symbols and indices dmrsSym = nrPDSCHDMRS(carrier,pdsch); dmrsInd = nrPDSCHDMRSIndices(carrier,pdsch); % Get PT-RS symbols and indices ptrsSym = nrPDSCHPTRS(carrier,pdsch); ptrsInd = nrPDSCHPTRSIndices(carrier,pdsch); % Resource element mapping to slot grid slotGrid = nrResourceGrid(carrier,pdsch.NumLayers); slotGrid(pdschInd) = pdschSym; slotGrid(dmrsInd) = dmrsSym; slotGrid(ptrsInd) = ptrsSym; % Generate txGrid for all frames by mapping slotGrid at respective % locations txGrid(:,slotIdx*nSlotSymb+1:(slotIdx+1)*(nSlotSymb),:) = slotGrid; end % Perform OFDM modulation carrier.NSlot = 0; % Reset the slot number to 0 for OFDM modulation txWaveform = nrOFDMModulate(carrier,txGrid);
位相ノイズの適用
送信波形に位相ノイズを適用します。位相ノイズの影響を明確に観察するため、この例では、熱ノイズやチャネル モデルの適用を位相ノイズに付加することはしません。この例では、すべてのレイヤーに同じ位相ノイズを適用します。
rxWaveform = pnoise(txWaveform);
受信機
イコライズされた PDSCH シンボルと復号化されたビットを返す前に、受信機は次の手順を実行します。
タイミング同期
OFDM 復調
チャネル推定
イコライズ
CPE の推定と補正
PDSCH 復号化
CPE の推定と補正のステップにおいて、受信機は simParameters
構造体の logical フィールド CompensateCPE
を使用します。この例では伝播チャネルを使用しないため、タイミング同期、チャネル推定、およびイコライズの手順は厳密には必要ありません。ただし、これらの手順は、チャネルを導入した場合の位相ノイズの影響を調査するのに役立ちます。
この例は、CPE 補償を使用した場合と使用しない場合の、イコライズされたコンスタレーション シンボル、EVM、およびビット エラー レートを示します。
ケース 1: CPE 補償なし
CPE 補償を無効にするには、simParameters
構造体のフィールド CompensateCPE
を 0 に設定します。
simParameters.CompensateCPE = 0; [eqSymbols,rxbits] = practicalReceiver(carrier,pdsch,simParameters,rxWaveform); refSymbols = getConstellationPoints(pdsch); % Display the constellation diagram figure plot(eqSymbols,'.') hold on plot(refSymbols,'+') title('Equalized Symbols Constellation Without CPE Compensation') grid on xlabel('In-Phase') ylabel('Quadrature')
% Display RMS EVM evm = comm.EVM('ReferenceSignalSource','Estimated from reference constellation','ReferenceConstellation',refSymbols); fprintf('RMS EVM (in percent) for equalized symbols without CPE compensation: %f%% \n',evm(eqSymbols))
RMS EVM (in percent) for equalized symbols without CPE compensation: 7.431048%
% Display bit error rate errorRate = nnz(rxbits-txbits)/numel(txbits); fprintf('Bit error rate without CPE compensation: %f \n',errorRate)
Bit error rate without CPE compensation: 0.005525
ケース 2: CPE 補償あり
CPE 補償を有効にするには、simParameters
構造体のフィールド CompensateCPE
を 1 に設定します。PT-RS を使用して、スロット内のすべての OFDM シンボル位置で CPE を推定します。PT-RS OFDM シンボルの範囲内の OFDM シンボル位置で CPE を補正します。
simParameters.CompensateCPE = 1; [eqSymbolsCPE,rxbitsCPE] = practicalReceiver(carrier,pdsch,simParameters,rxWaveform); % Display the constellation diagram figure plot(eqSymbolsCPE,'.') hold on plot(refSymbols,'+') title('Equalized Symbols Constellation With CPE Compensation') grid on xlabel('In-Phase') ylabel('Quadrature')
% Display RMS EVM fprintf('RMS EVM (in percent) for equalized symbols with CPE compensation: %f%% \n',evm(eqSymbolsCPE))
RMS EVM (in percent) for equalized symbols with CPE compensation: 4.557690%
% Display bit error rate errorRateCPE = nnz(rxbitsCPE-txbits)/numel(txbits); fprintf('Bit error rate with CPE compensation: %f \n',errorRateCPE)
Bit error rate with CPE compensation: 0.000052
その他の調査
位相ノイズの影響を可視化するには、搬送波周波数、サブキャリア間隔、リソース ブロック数、変調スキーム、およびフレーム数を変更します。
コンスタレーションに対する位相ノイズの影響を確認するには、位相ノイズ モデルを変更します。
異なる構成での CPE 補償の影響を解析するには、PT-RS の時間密度と周波数密度を変更します。
熱ノイズとチャネル モデルを含めて、位相ノイズの影響を可視化します。
まとめ
この例では、位相ノイズの影響を示し、PT-RS を使用して CPE を推定および補正する方法を示します。この例では、CPE 補償によって EVM が減少し、ビット エラー レートが改善されることも示します。表示されたコンスタレーション プロットは、mmWave 周波数で ICI が非常に大きく、CPE 補償に加えて ICI 補償を実行する必要があることを示しています。
ローカル関数
function [eqSymbols,rxbits] = practicalReceiver(carrier,pdsch,params,rxWaveform) % Returns equalized modulated symbols after performing the timing % estimation, OFDM demodulation, channel estimation, MMSE equalization, % CPE estimation and correction, and PDSCH decoding. % Get the current slot number, number of slots, number of symbols % per slot, and total number of symbols nSlot = carrier.NSlot; numSlots = carrier.SlotsPerFrame*params.NumFrames; nSlotSymb = carrier.SymbolsPerSlot; numTotalSymbols = numSlots*nSlotSymb; % Get reference grid with DM-RS symbols dmrsSymCell = cell(1,numSlots); dmrsIndCell = cell(1,numSlots); refGrid = zeros(carrier.NSizeGrid*12,numTotalSymbols,pdsch.NumLayers); for NSlot = 0:numSlots-1 carrier.NSlot = NSlot; slotGrid = nrResourceGrid(carrier,pdsch.NumLayers); dmrsSymCell{NSlot+1} = nrPDSCHDMRS(carrier,pdsch); dmrsIndCell{NSlot+1} = nrPDSCHDMRSIndices(carrier,pdsch); slotGrid(dmrsIndCell{NSlot+1}) = dmrsSymCell{NSlot+1}; refGrid(:,NSlot*nSlotSymb+1:(NSlot+1)*(nSlotSymb),:) = slotGrid; end % Perform timing estimation and correction carrier.NSlot = nSlot; offset = nrTimingEstimate(carrier,rxWaveform,refGrid); waveformSync = rxWaveform(1+offset:end,:); % Perform OFDM demodulation on the received data to recreate the % resource grid, including padding in the event that practical % synchronization results in an incomplete slots being demodulated rxGrid = nrOFDMDemodulate(carrier,waveformSync); [K,L,R] = size(rxGrid); if (L < numTotalSymbols) rxGrid = cat(2,rxGrid,zeros(K,numTotalSymbols-L,R)); end % Declare storage variables eqSymbols = []; % equalized symbols for constellation plot rxbits = []; for NSlot = 0:numSlots-1 % Extract grid for current slot currentGrid = rxGrid(:,NSlot*nSlotSymb+(1:nSlotSymb),:); % Get the PDSCH resources carrier.NSlot = NSlot; dmrsSymbols = dmrsSymCell{NSlot+1}; dmrsIndices = dmrsIndCell{NSlot+1}; ptrsSymbols = nrPDSCHPTRS(carrier,pdsch); ptrsIndices = nrPDSCHPTRSIndices(carrier,pdsch); [pdschIndices,pdschIndicesInfo] = nrPDSCHIndices(carrier,pdsch); % Channel estimation [estChannelGrid,noiseEst] = nrChannelEstimate(currentGrid,dmrsIndices,dmrsSymbols,"CDMLengths",pdsch.DMRS.CDMLengths); % Get PDSCH resource elements from the received grid [pdschRx,pdschHest] = nrExtractResources(pdschIndices,currentGrid,estChannelGrid); % Equalization pdschEq = nrEqualizeMMSE(pdschRx,pdschHest,noiseEst); % Common phase error (CPE) estimation and correction if params.CompensateCPE % Initialize temporary grid to store equalized symbols tempGrid = nrResourceGrid(carrier,pdsch.NumLayers); % Extract PT-RS symbols from received grid and estimated % channel grid [ptrsRx,ptrsHest,~,~,~,ptrsLayerIndices] = nrExtractResources(ptrsIndices,currentGrid,estChannelGrid,tempGrid); % Equalize PT-RS symbols and map them to tempGrid ptrsEq = nrEqualizeMMSE(ptrsRx,ptrsHest,noiseEst); tempGrid(ptrsLayerIndices) = ptrsEq; % Estimate the residual channel at the PT-RS locations in % tempGrid cpe = nrChannelEstimate(tempGrid,ptrsIndices,ptrsSymbols); % Sum estimates across subcarriers, receive antennas, and % layers. Then, get the CPE by taking the angle of the % resultant sum cpe = angle(sum(cpe,[1 3 4])); % Map the equalized PDSCH symbols to tempGrid tempGrid(pdschIndices) = pdschEq; % Correct CPE in each OFDM symbol within the range of reference % PT-RS OFDM symbols if numel(pdschIndicesInfo.PTRSSymbolSet) > 0 symLoc = pdschIndicesInfo.PTRSSymbolSet(1)+1:pdschIndicesInfo.PTRSSymbolSet(end)+1; tempGrid(:,symLoc,:) = tempGrid(:,symLoc,:).*exp(-1i*cpe(symLoc)); end % Extract PDSCH symbols pdschEq = tempGrid(pdschIndices); end % Store the equalized symbols and output them for all the slots eqSymbols = [eqSymbols; pdschEq]; %#ok<AGROW> % Decode the PDSCH symbols and get the hard bits eqbits = nrPDSCHDecode(carrier,pdsch,pdschEq); for i = 1:numel(eqbits) rxbits = [rxbits; double(eqbits{i}<0)]; %#ok<AGROW> end end end function sym = getConstellationPoints(pdsch) %getConstellationPoints Constellation points % SYM = getConstellationPoints(PDSCH) returns the constellation points % SYM based on modulation schemes provided in PDSCH configuration object. sym = []; modulation = string(pdsch.Modulation); % Convert modulation scheme to string type ncw = pdsch.NumCodewords; % Number of codewords if ncw == 2 && (numel(modulation) == 1) modulation(end+1) = modulation(1); end % Get the constellation points for cwIndex = 1:ncw qm = strcmpi(modulation(cwIndex),{'QPSK','16QAM','64QAM','256QAM'})*[2 4 6 8]'; sym = [sym; nrSymbolModulate(int2bit((0:2^qm-1)',qm),modulation(cwIndex))]; %#ok<AGROW> end end