このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
NR PDSCH スループット
この参照シミュレーションでは、3GPP NR 規格で定義されているように、5G New Radio (NR) リンクの物理ダウンリンク共有チャネル (PDSCH) のスループットを測定する方法を示します。この例では、PDSCH とダウンリンク共有チャネル (DL-SCH) を実装します。送信機モデルには、PDSCH 復調基準信号 (DM-RS) と PDSCH 位相トラッキング基準信号 (PT-RS) が含まれます。この例では、クラスター遅延線 (CDL) とタップ付き遅延線 (TDL) の両方の伝播チャネルをサポートします。完全な同期と完全なチャネル推定、あるいは実用的な同期と実用的なチャネル推定を実行できます。シミュレーションの合計時間を短縮するために、Parallel Computing Toolbox™ を使用して、SNR ループの SNR 点を並列に処理できます。
はじめに
この例では、3GPP NR 規格 [ 1 ]、[ 2 ]、[ 3 ]、[ 4 ] で定義されているように、5G リンクの PDSCH スループットを測定します。
この例では、次の 5G NR の機能をモデル化します。
DL-SCH トランスポート チャネル符号化
レイヤー数に応じた複数のコードワード
PDSCH、PDSCH DM-RS、PDSCH PT-RS の生成
可変サブキャリア間隔とフレーム numerology (2^n * 15 kHz)
ノーマル サイクリック プレフィックスと拡張サイクリック プレフィックス
TDL と CDL の伝播チャネル モデル
シミュレーションのその他の機能は、次のとおりです。
SVD を使用した PDSCH サブバンド プリコーディング
CP-OFDM 変調
スロット単位および非スロット単位での PDSCH と DM-RS のマッピング
完全な同期と完全なチャネル推定、あるいは実用的な同期と実用的なチャネル推定
16 個のプロセスを使用する HARQ 操作
この例では、キャリア全体にまたがる単一の bandwidth part を使用する
次の図は、実装される処理チェーンを示しています。わかりやすくするために、DM-RS と PT-RS の生成は省略しています。
この例で実装されている手順の詳細については、5G NR 通信リンクのモデル化とDL-SCH および PDSCH の送受信処理チェーンを参照してください。
この例では、広帯域とサブバンド両方のプリコーディングをサポートします。プリコーディング行列は、割り当て内 (広帯域の場合) またはサブバンド内のすべての PDSCH PRB でチャネル推定を平均化し、SVD を使用して決定されます。
シミュレーションの合計を短縮するために、Parallel Computing Toolbox を使用して、SNR ループの SNR 点を並列に処理できます。
シミュレーションの長さと SNR 点
シミュレーションの長さを 10 ms のフレームの数で設定します。有意なスループットの結果を得るためには、多数の NFrame を使用する必要があります。シミュレーションを行うための SNR 点を設定します。各レイヤーの SNR は RE ごとに定義され、すべてのアンテナにおいて信号とノイズの影響があります。この例で使用している SNR 定義の説明については、リンク シミュレーションで使用する SNR の定義を参照してください。
simParameters = struct(); % Clear simParameters variable to contain all key simulation parameters simParameters.NFrames = 2; % Number of 10 ms frames simParameters.SNRIn = [-5 0 5]; % SNR range (dB)
チャネル推定器の構成
logical 変数 PerfectChannelEstimator
は、チャネル推定と同期の動作を制御します。true
に設定すると、完全なチャネル推定と同期が使用されます。それ以外の場合、受信した PDSCH DM-RS の値に基づいて、実用的なチャネル推定と同期が使用されます。
simParameters.PerfectChannelEstimator = true;
シミュレーション診断
変数 DisplaySimulationInformation
は、各サブフレームに使用される HARQ プロセス ID などのシミュレーション情報の表示を制御します。CRC エラーの場合、RV シーケンスへのインデックスの値も表示されます。
simParameters.DisplaySimulationInformation = true;
DisplayDiagnostics
フラグは、レイヤーごとの EVM のプロットを有効にします。このプロットは、イコライズ後の受信信号の品質を監視します。レイヤーごとの EVM の Figure は以下を表示します。
スロット単位でのレイヤーごとの EVM。これは時間とともに変化する EVM を表示します。
リソース ブロック単位でのレイヤーごとの EVM。これは EVM の周波数を示します。
この Figure はシミュレーションとともに変化し、スロットごとに更新されます。通常、低い SNR またはチャネル フェージングは、信号品質の低下 (高 EVM) につながる可能性があります。チャネルは各レイヤーに異なる影響を与えるため、EVM 値はレイヤー間で異なる場合があります。
場合によっては、一部のレイヤーの EVM が他のレイヤーよりもはるかに高くなることがあります。そのような低品質のレイヤーは、CRC エラーを引き起こす可能性があります。この動作は、SNR が低いか、チャネル条件に対して使用するレイヤーが多すぎることが原因である可能性があります。この状況は、SNR を高くし、レイヤー数を減らし、アンテナ数を増やし、送信の堅牢性を高める (変調スキームとターゲット符号化率を低くする) ことを組み合わせることで回避できます。
simParameters.DisplayDiagnostics = false;
キャリアと PDSCH の構成
シミュレーションの主なパラメーターを設定します。これには、次が含まれます。
リソース ブロックの帯域幅 (リソース ブロックごとに 12 個のサブキャリア)。
サブキャリア間隔: 15、30、60、120 (kHz)
サイクリック プレフィックス長: normal または extended
セル ID
送信アンテナ数と受信アンテナ数
DL-SCH と PDSCH のパラメーターを含むサブ構造体も指定します。これには、次が含まれます。
ターゲット符号化率
割り当て済みリソース ブロック数 (PRBSet)
変調スキーム: 'QPSK'、'16QAM'、'64QAM'、'256QAM'
レイヤーの数
PDSCH マッピング タイプ
DM-RS 構成パラメーター
PT-RS 構成パラメーター
その他のシミュレーション全体のパラメーターは、次のとおりです。
伝播チャネル モデル遅延プロファイル (TDL または CDL)
% Set waveform type and PDSCH numerology (SCS and CP type) simParameters.Carrier = nrCarrierConfig; % Carrier resource grid configuration simParameters.Carrier.NSizeGrid = 51; % Bandwidth in number of resource blocks (51 RBs at 30 kHz SCS for 20 MHz BW) simParameters.Carrier.SubcarrierSpacing = 30; % 15, 30, 60, 120 (kHz) simParameters.Carrier.CyclicPrefix = 'Normal'; % 'Normal' or 'Extended' (Extended CP is relevant for 60 kHz SCS only) simParameters.Carrier.NCellID = 1; % Cell identity % PDSCH/DL-SCH parameters simParameters.PDSCH = nrPDSCHConfig; % This PDSCH definition is the basis for all PDSCH transmissions in the BLER simulation simParameters.PDSCHExtension = struct(); % This structure is to hold additional simulation parameters for the DL-SCH and PDSCH % Define PDSCH time-frequency resource allocation per slot to be full grid (single full grid BWP) simParameters.PDSCH.PRBSet = 0:simParameters.Carrier.NSizeGrid-1; % PDSCH PRB allocation simParameters.PDSCH.SymbolAllocation = [0,simParameters.Carrier.SymbolsPerSlot]; % Starting symbol and number of symbols of each PDSCH allocation simParameters.PDSCH.MappingType = 'A'; % PDSCH mapping type ('A'(slot-wise),'B'(non slot-wise)) % Scrambling identifiers simParameters.PDSCH.NID = simParameters.Carrier.NCellID; simParameters.PDSCH.RNTI = 1; % PDSCH resource block mapping (TS 38.211 Section 7.3.1.6) simParameters.PDSCH.VRBToPRBInterleaving = 0; % Disable interleaved resource mapping simParameters.PDSCH.VRBBundleSize = 4; % Define the number of transmission layers to be used simParameters.PDSCH.NumLayers = 2; % Number of PDSCH transmission layers % Define codeword modulation and target coding rate % The number of codewords is directly dependent on the number of layers so ensure that % layers are set first before getting the codeword number if simParameters.PDSCH.NumCodewords > 1 % Multicodeword transmission (when number of layers being > 4) simParameters.PDSCH.Modulation = {'16QAM','16QAM'}; % 'QPSK', '16QAM', '64QAM', '256QAM' simParameters.PDSCHExtension.TargetCodeRate = [490 490]/1024; % Code rate used to calculate transport block sizes else simParameters.PDSCH.Modulation = '16QAM'; % 'QPSK', '16QAM', '64QAM', '256QAM' simParameters.PDSCHExtension.TargetCodeRate = 490/1024; % Code rate used to calculate transport block sizes end % DM-RS and antenna port configuration (TS 38.211 Section 7.4.1.1) simParameters.PDSCH.DMRS.DMRSPortSet = 0:simParameters.PDSCH.NumLayers-1; % DM-RS ports to use for the layers simParameters.PDSCH.DMRS.DMRSTypeAPosition = 2; % Mapping type A only. First DM-RS symbol position (2,3) simParameters.PDSCH.DMRS.DMRSLength = 1; % Number of front-loaded DM-RS symbols (1(single symbol),2(double symbol)) simParameters.PDSCH.DMRS.DMRSAdditionalPosition = 2; % Additional DM-RS symbol positions (max range 0...3) simParameters.PDSCH.DMRS.DMRSConfigurationType = 2; % DM-RS configuration type (1,2) simParameters.PDSCH.DMRS.NumCDMGroupsWithoutData = 1;% Number of CDM groups without data simParameters.PDSCH.DMRS.NIDNSCID = 1; % Scrambling identity (0...65535) simParameters.PDSCH.DMRS.NSCID = 0; % Scrambling initialization (0,1) % PT-RS configuration (TS 38.211 Section 7.4.1.2) simParameters.PDSCH.EnablePTRS = 0; % Enable or disable PT-RS (1 or 0) simParameters.PDSCH.PTRS.TimeDensity = 1; % PT-RS time density (L_PT-RS) (1, 2, 4) simParameters.PDSCH.PTRS.FrequencyDensity = 2; % PT-RS frequency density (K_PT-RS) (2 or 4) simParameters.PDSCH.PTRS.REOffset = '00'; % PT-RS resource element offset ('00', '01', '10', '11') simParameters.PDSCH.PTRS.PTRSPortSet = []; % PT-RS antenna port, subset of DM-RS port set. Empty corresponds to lower DM-RS port number % Reserved PRB patterns, if required (for CORESETs, forward compatibility etc) simParameters.PDSCH.ReservedPRB{1}.SymbolSet = []; % Reserved PDSCH symbols simParameters.PDSCH.ReservedPRB{1}.PRBSet = []; % Reserved PDSCH PRBs simParameters.PDSCH.ReservedPRB{1}.Period = []; % Periodicity of reserved resources % Additional simulation and DL-SCH related parameters % % PDSCH PRB bundling (TS 38.214 Section 5.1.2.3) simParameters.PDSCHExtension.PRGBundleSize = []; % 2, 4, or [] to signify "wideband" % % HARQ process and rate matching/TBS parameters simParameters.PDSCHExtension.XOverhead = 6*simParameters.PDSCH.EnablePTRS; % Set PDSCH rate matching overhead for TBS (Xoh) to 6 when PT-RS is enabled, otherwise 0 simParameters.PDSCHExtension.NHARQProcesses = 16; % Number of parallel HARQ processes to use simParameters.PDSCHExtension.EnableHARQ = true; % Enable retransmissions for each process, using RV sequence [0,2,3,1] % LDPC decoder parameters % Available algorithms: 'Belief propagation', 'Layered belief propagation', 'Normalized min-sum', 'Offset min-sum' simParameters.PDSCHExtension.LDPCDecodingAlgorithm = 'Normalized min-sum'; simParameters.PDSCHExtension.MaximumLDPCIterationCount = 6; % Define the overall transmission antenna geometry at end-points % If using a CDL propagation channel then the integer number of antenna elements is % turned into an antenna panel configured when the channel model object is created simParameters.NTxAnts = 8; % Number of PDSCH transmission antennas (1,2,4,8,16,32,64,128,256,512,1024) >= NumLayers if simParameters.PDSCH.NumCodewords > 1 % Multi-codeword transmission simParameters.NRxAnts = 8; % Number of UE receive antennas (even number >= NumLayers) else simParameters.NRxAnts = 2; % Number of UE receive antennas (1 or even number >= NumLayers) end % Define data type ('single' or 'double') for resource grids and waveforms simParameters.DataType = 'single'; % Define the general CDL/TDL propagation channel parameters simParameters.DelayProfile = 'CDL-C'; % Use CDL-C model (Urban macrocell model) simParameters.DelaySpread = 300e-9; simParameters.MaximumDopplerShift = 5; % Cross-check the PDSCH layering against the channel geometry validateNumLayers(simParameters);
このシミュレーションは、サンプル レートなどのベースバンド波形に関するさまざまな情報に依存しています。
waveformInfo = nrOFDMInfo(simParameters.Carrier); % Get information about the baseband waveform after OFDM modulation step
伝播チャネル モデルの構築
シミュレーション用のチャネル モデル オブジェクトを作成します。CDL と TDL の両方のチャネル モデルをサポートします [ 5 ]。
% Constructed the CDL or TDL channel model object if contains(simParameters.DelayProfile,'CDL','IgnoreCase',true) channel = nrCDLChannel; % CDL channel object % Turn the number of antennas into antenna panel array layouts. If % NTxAnts is not one of (1,2,4,8,16,32,64,128,256,512,1024), its value % is rounded up to the nearest value in the set. If NRxAnts is not 1 or % even, its value is rounded up to the nearest even number. channel = hArrayGeometry(channel,simParameters.NTxAnts,simParameters.NRxAnts); simParameters.NTxAnts = prod(channel.TransmitAntennaArray.Size); simParameters.NRxAnts = prod(channel.ReceiveAntennaArray.Size); else channel = nrTDLChannel; % TDL channel object % Set the channel geometry channel.NumTransmitAntennas = simParameters.NTxAnts; channel.NumReceiveAntennas = simParameters.NRxAnts; end % Assign simulation channel parameters and waveform sample rate to the object channel.DelayProfile = simParameters.DelayProfile; channel.DelaySpread = simParameters.DelaySpread; channel.MaximumDopplerShift = simParameters.MaximumDopplerShift; channel.SampleRate = waveformInfo.SampleRate;
チャネルのマルチパス成分によって、遅延サンプルの最大数を取得します。これは、最も遅延の大きいチャネル パスとチャネル フィルターの実装遅延に基づいて計算します。これは、チャネル フィルターをフラッシュして受信信号を取得するために後で必要になります。
chInfo = info(channel); maxChDelay = chInfo.MaximumChannelDelay;
処理ループ
各 SNR 点でのスループットを測定するために、以下の手順に従って、送信インスタンスごとの PDSCH データを解析します。
現在の HARQ プロセスの更新。提供された HARQ プロセスの送信ステータスをチェックし、再送が必要かどうかを決定します。そうでない場合は、新しいデータを生成します。
リソース グリッドの生成。
nrDLSCH
System object を呼び出して、チャネル符号化を実行します。このオブジェクトは、入力のトランスポート ブロックに対して動作し、再送が必要な場合はトランスポート ブロックの内部コピーを保持します。関数nrPDSCH
を使用して、PDSCH の符号化ビットを変調します。次に、結果として得られた信号にプリコーディングを適用します。波形の生成。生成されたグリッドを OFDM 変調します。
ノイズを含むチャネルのモデル化。CDL または TDL のフェージング チャネルに波形を渡します。AWGN を付加します。この例で使用している SNR 定義の説明については、リンク シミュレーションで使用する SNR の定義を参照してください。
同期と OFDM 復調の実行。完全な同期では、チャネル インパルス応答を再構築して受信波形を同期させます。実用的な同期では、受信波形と PDSCH DM-RS の相関をとります。次に、同期した信号を OFDM 復調します。
チャネル推定の実行。完全なチャネル推定では、チャネル インパルス応答を再構築して OFDM 復調を実行します。実用的なチャネル推定では、PDSCH DM-RS を使用します。
イコライズと CPE 補償の実行。推定チャネルを MMSE イコライズします。PT-RS シンボルを使用して共通位相誤差 (CPE) を推定した後、PT-RS OFDM 基準シンボルの範囲内にある各 OFDM シンボルの誤差を補正します。
プリコーディング行列の計算。特異値分解 (SVD) を使用して、次回の送信用のプリコーディング行列 W を生成します。
PDSCH の復号化。受信コードワードの推定を取得するために、関数
nrPDSCHDecode
を使用して、送信アンテナと受信アンテナのすべてのペアについて復元した PDSCH シンボルを、ノイズ推定とともに復調し、デスクランブルします。ダウンリンク共有チャネル (DL-SCH) の復号化およびブロック CRC エラーのある HARQ プロセスの更新。復号化されたソフト ビットのベクトルを
nrDLSCHDecoder
System object に渡します。このオブジェクトはコードワードを復号化し、システムのスループットを判定するために使用されるブロック CRC エラーを返します。
% Array to store the maximum throughput for all SNR points maxThroughput = zeros(length(simParameters.SNRIn),1); % Array to store the simulation throughput for all SNR points simThroughput = zeros(length(simParameters.SNRIn),1); % Set up redundancy version (RV) sequence for all HARQ processes if simParameters.PDSCHExtension.EnableHARQ % In the final report of RAN WG1 meeting #91 (R1-1719301), it was % observed in R1-1717405 that if performance is the priority, [0 2 3 1] % should be used. If self-decodability is the priority, it should be % taken into account that the upper limit of the code rate at which % each RV is self-decodable is in the following order: 0>3>2>1 rvSeq = [0 2 3 1]; else % HARQ disabled - single transmission with RV=0, no retransmissions rvSeq = 0; end % Create DL-SCH encoder system object to perform transport channel encoding encodeDLSCH = nrDLSCH; encodeDLSCH.MultipleHARQProcesses = true; encodeDLSCH.TargetCodeRate = simParameters.PDSCHExtension.TargetCodeRate; % Create DL-SCH decoder system object to perform transport channel decoding % Use layered belief propagation for LDPC decoding, with half the number of % iterations as compared to the default for belief propagation decoding decodeDLSCH = nrDLSCHDecoder; decodeDLSCH.MultipleHARQProcesses = true; decodeDLSCH.TargetCodeRate = simParameters.PDSCHExtension.TargetCodeRate; decodeDLSCH.LDPCDecodingAlgorithm = simParameters.PDSCHExtension.LDPCDecodingAlgorithm; decodeDLSCH.MaximumLDPCIterationCount = simParameters.PDSCHExtension.MaximumLDPCIterationCount; for snrIdx = 1:numel(simParameters.SNRIn) % comment out for parallel computing % parfor snrIdx = 1:numel(simParameters.SNRIn) % uncomment for parallel computing % To reduce the total simulation time, you can execute this loop in % parallel by using the Parallel Computing Toolbox. Comment out the 'for' % statement and uncomment the 'parfor' statement. If the Parallel Computing % Toolbox is not installed, 'parfor' defaults to normal 'for' statement. % Because parfor-loop iterations are executed in parallel in a % nondeterministic order, the simulation information displayed for each SNR % point can be intertwined. To switch off simulation information display, % set the 'displaySimulationInformation' variable above to false % Reset the random number generator so that each SNR point will % experience the same noise realization rng('default'); % Take full copies of the simulation-level parameter structures so that they are not % PCT broadcast variables when using parfor simLocal = simParameters; waveinfoLocal = waveformInfo; % Take copies of channel-level parameters to simplify subsequent parameter referencing carrier = simLocal.Carrier; pdsch = simLocal.PDSCH; pdschextra = simLocal.PDSCHExtension; decodeDLSCHLocal = decodeDLSCH; % Copy of the decoder handle to help PCT classification of variable decodeDLSCHLocal.reset(); % Reset decoder at the start of each SNR point pathFilters = []; % Prepare simulation for new SNR point SNRdB = simLocal.SNRIn(snrIdx); fprintf('\nSimulating transmission scheme 1 (%dx%d) and SCS=%dkHz with %s channel at %gdB SNR for %d 10ms frame(s)\n', ... simLocal.NTxAnts,simLocal.NRxAnts,carrier.SubcarrierSpacing, ... simLocal.DelayProfile,SNRdB,simLocal.NFrames); % Specify the fixed order in which we cycle through the HARQ process IDs harqSequence = 0:pdschextra.NHARQProcesses-1; % Initialize the state of all HARQ processes harqEntity = HARQEntity(harqSequence,rvSeq,pdsch.NumCodewords); % Reset the channel so that each SNR point will experience the same % channel realization reset(channel); % Total number of slots in the simulation period NSlots = simLocal.NFrames * carrier.SlotsPerFrame; % Obtain a precoding matrix (wtx) to be used in the transmission of the % first transport block estChannelGridAnts = getInitialChannelEstimate(carrier,simLocal.NTxAnts,channel,simLocal.DataType); newWtx = hSVDPrecoders(carrier,pdsch,estChannelGridAnts,pdschextra.PRGBundleSize); % Timing offset, updated in every slot for perfect synchronization and % when the correlation is strong for practical synchronization offset = 0; % Loop over the entire waveform length for nslot = 0:NSlots-1 % Update the carrier slot numbers for new slot carrier.NSlot = nslot; % Calculate the transport block sizes for the transmission in the slot [pdschIndices,pdschIndicesInfo] = nrPDSCHIndices(carrier,pdsch); trBlkSizes = nrTBS(pdsch.Modulation,pdsch.NumLayers,numel(pdsch.PRBSet),pdschIndicesInfo.NREPerPRB,pdschextra.TargetCodeRate,pdschextra.XOverhead); % HARQ processing for cwIdx = 1:pdsch.NumCodewords % If new data for current process and codeword then create a new DL-SCH transport block if harqEntity.NewData(cwIdx) trBlk = randi([0 1],trBlkSizes(cwIdx),1); setTransportBlock(encodeDLSCH,trBlk,cwIdx-1,harqEntity.HARQProcessID); % If new data because of previous RV sequence time out then flush decoder soft buffer explicitly if harqEntity.SequenceTimeout(cwIdx) resetSoftBuffer(decodeDLSCHLocal,cwIdx-1,harqEntity.HARQProcessID); end end end % Encode the DL-SCH transport blocks codedTrBlocks = encodeDLSCH(pdsch.Modulation,pdsch.NumLayers, ... pdschIndicesInfo.G,harqEntity.RedundancyVersion,harqEntity.HARQProcessID); % Get precoding matrix (wtx) calculated in previous slot wtx = newWtx; % Create resource grid for a slot pdschGrid = nrResourceGrid(carrier,simLocal.NTxAnts,OutputDataType=simLocal.DataType); % PDSCH modulation and precoding pdschSymbols = nrPDSCH(carrier,pdsch,codedTrBlocks); [pdschAntSymbols,pdschAntIndices] = nrPDSCHPrecode(carrier,pdschSymbols,pdschIndices,wtx); % PDSCH mapping in grid associated with PDSCH transmission period pdschGrid(pdschAntIndices) = pdschAntSymbols; % PDSCH DM-RS precoding and mapping dmrsSymbols = nrPDSCHDMRS(carrier,pdsch); dmrsIndices = nrPDSCHDMRSIndices(carrier,pdsch); [dmrsAntSymbols,dmrsAntIndices] = nrPDSCHPrecode(carrier,dmrsSymbols,dmrsIndices,wtx); pdschGrid(dmrsAntIndices) = dmrsAntSymbols; % PDSCH PT-RS precoding and mapping ptrsSymbols = nrPDSCHPTRS(carrier,pdsch); ptrsIndices = nrPDSCHPTRSIndices(carrier,pdsch); [ptrsAntSymbols,ptrsAntIndices] = nrPDSCHPrecode(carrier,ptrsSymbols,ptrsIndices,wtx); pdschGrid(ptrsAntIndices) = ptrsAntSymbols; % OFDM modulation txWaveform = nrOFDMModulate(carrier,pdschGrid); % Pass data through channel model. Append zeros at the end of the % transmitted waveform to flush channel content. These zeros take % into account any delay introduced in the channel. This is a mix % of multipath delay and implementation delay. This value may % change depending on the sampling rate, delay profile and delay % spread txWaveform = [txWaveform; zeros(maxChDelay,size(txWaveform,2))]; %#ok<AGROW> [rxWaveform,pathGains,sampleTimes] = channel(txWaveform); % Add AWGN to the received time domain waveform % Normalize noise power by the IFFT size used in OFDM modulation, % as the OFDM modulator applies this normalization to the % transmitted waveform. Also normalize by the number of receive % antennas, as the channel model applies this normalization to the % received waveform, by default SNR = 10^(SNRdB/10); N0 = 1/sqrt(simLocal.NRxAnts*double(waveinfoLocal.Nfft)*SNR); noise = N0*randn(size(rxWaveform),"like",rxWaveform); rxWaveform = rxWaveform + noise; if (simLocal.PerfectChannelEstimator) % Perfect synchronization. Use information provided by the % channel to find the strongest multipath component pathFilters = getPathFilters(channel); [offset,mag] = nrPerfectTimingEstimate(pathGains,pathFilters); else % Practical synchronization. Correlate the received waveform % with the PDSCH DM-RS to give timing offset estimate 't' and % correlation magnitude 'mag'. The function % hSkipWeakTimingOffset is used to update the receiver timing % offset. If the correlation peak in 'mag' is weak, the current % timing estimate 't' is ignored and the previous estimate % 'offset' is used [t,mag] = nrTimingEstimate(carrier,rxWaveform,dmrsIndices,dmrsSymbols); offset = hSkipWeakTimingOffset(offset,t,mag); % Display a warning if the estimated timing offset exceeds the % maximum channel delay if offset > maxChDelay warning(['Estimated timing offset (%d) is greater than the maximum channel delay (%d).' ... ' This will result in a decoding failure. This may be caused by low SNR,' ... ' or not enough DM-RS symbols to synchronize successfully.'],offset,maxChDelay); end end rxWaveform = 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 slot being demodulated rxGrid = nrOFDMDemodulate(carrier,rxWaveform); [K,L,R] = size(rxGrid); if (L < carrier.SymbolsPerSlot) rxGrid = cat(2,rxGrid,zeros(K,carrier.SymbolsPerSlot-L,R)); end if (simLocal.PerfectChannelEstimator) % Perfect channel estimation, using the value of the path gains % provided by the channel. This channel estimate does not % include the effect of transmitter precoding estChannelGridAnts = nrPerfectChannelEstimate(carrier,pathGains,pathFilters,offset,sampleTimes); % Get perfect noise estimate (from the noise realization) noiseGrid = nrOFDMDemodulate(carrier,noise(1+offset:end ,:)); noiseEst = var(noiseGrid(:)); % Get PDSCH resource elements from the received grid and % channel estimate [pdschRx,pdschHest,~,pdschHestIndices] = nrExtractResources(pdschIndices,rxGrid,estChannelGridAnts); % Apply precoding to channel estimate pdschHest = nrPDSCHPrecode(carrier,pdschHest,pdschHestIndices,permute(wtx,[2 1 3])); else % Practical channel estimation between the received grid and % each transmission layer, using the PDSCH DM-RS for each % layer. This channel estimate includes the effect of % transmitter precoding [estChannelGridPorts,noiseEst] = hSubbandChannelEstimate(carrier,rxGrid,dmrsIndices,dmrsSymbols,pdschextra.PRGBundleSize,'CDMLengths',pdsch.DMRS.CDMLengths); % Average noise estimate across PRGs and layers noiseEst = mean(noiseEst,'all'); % Get PDSCH resource elements from the received grid and % channel estimate [pdschRx,pdschHest] = nrExtractResources(pdschIndices,rxGrid,estChannelGridPorts); % Remove precoding from estChannelGridPorts to get channel % estimate w.r.t. antennas estChannelGridAnts = precodeChannelEstimate(carrier,estChannelGridPorts,conj(wtx)); end % Equalization [pdschEq,csi] = nrEqualizeMMSE(pdschRx,pdschHest,noiseEst); % Common phase error (CPE) compensation if ~isempty(ptrsIndices) % 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,~,~,ptrsHestIndices,ptrsLayerIndices] = nrExtractResources(ptrsIndices,rxGrid,estChannelGridAnts,tempGrid); ptrsHest = nrPDSCHPrecode(carrier,ptrsHest,ptrsHestIndices,permute(wtx,[2 1 3])); % 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 symLoc = pdschIndicesInfo.PTRSSymbolSet(1)+1:pdschIndicesInfo.PTRSSymbolSet(end)+1; tempGrid(:,symLoc,:) = tempGrid(:,symLoc,:).*exp(-1i*cpe(symLoc)); % Extract PDSCH symbols pdschEq = tempGrid(pdschIndices); end % Decode PDSCH physical channel [dlschLLRs,rxSymbols] = nrPDSCHDecode(carrier,pdsch,pdschEq,noiseEst); % Display EVM per layer, per slot and per RB if (simLocal.DisplayDiagnostics) plotLayerEVM(NSlots,nslot,pdsch,size(pdschGrid),pdschIndices,pdschSymbols,pdschEq); end % Scale LLRs by CSI csi = nrLayerDemap(csi); % CSI layer demapping for cwIdx = 1:pdsch.NumCodewords Qm = length(dlschLLRs{cwIdx})/length(rxSymbols{cwIdx}); % bits per symbol csi{cwIdx} = repmat(csi{cwIdx}.',Qm,1); % expand by each bit per symbol dlschLLRs{cwIdx} = dlschLLRs{cwIdx} .* csi{cwIdx}(:); % scale by CSI end % Decode the DL-SCH transport channel decodeDLSCHLocal.TransportBlockLength = trBlkSizes; [decbits,blkerr] = decodeDLSCHLocal(dlschLLRs,pdsch.Modulation,pdsch.NumLayers,harqEntity.RedundancyVersion,harqEntity.HARQProcessID); % Store values to calculate throughput simThroughput(snrIdx) = simThroughput(snrIdx) + sum(~blkerr .* trBlkSizes); maxThroughput(snrIdx) = maxThroughput(snrIdx) + sum(trBlkSizes); % Update current process with CRC error and advance to next process procstatus = updateAndAdvance(harqEntity,blkerr,trBlkSizes,pdschIndicesInfo.G); if (simLocal.DisplaySimulationInformation) fprintf('\n(%3.2f%%) NSlot=%d, %s',100*(nslot+1)/NSlots,nslot,procstatus); end % Get precoding matrix for next slot newWtx = hSVDPrecoders(carrier,pdsch,estChannelGridAnts,pdschextra.PRGBundleSize); end % Display the results dynamically in the command window if (simLocal.DisplaySimulationInformation) fprintf('\n'); end fprintf('\nThroughput(Mbps) for %d frame(s) = %.4f\n',simLocal.NFrames,1e-6*simThroughput(snrIdx)/(simLocal.NFrames*10e-3)); fprintf('Throughput(%%) for %d frame(s) = %.4f\n',simLocal.NFrames,simThroughput(snrIdx)*100/maxThroughput(snrIdx)); end
Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at -5dB SNR for 2 10ms frame(s) (2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission failed (RV=0,CR=0.474736). (5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission failed (RV=0,CR=0.474736). (7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission failed (RV=0,CR=0.474736). (10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission failed (RV=0,CR=0.474736). (12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission failed (RV=0,CR=0.474736). (15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission failed (RV=0,CR=0.474736). (17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission failed (RV=0,CR=0.474736). (20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission failed (RV=0,CR=0.474736). (22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission failed (RV=0,CR=0.474736). (25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission failed (RV=0,CR=0.474736). (27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission failed (RV=0,CR=0.474736). (30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission failed (RV=0,CR=0.474736). (32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission failed (RV=0,CR=0.474736). (35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission failed (RV=0,CR=0.474736). (37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission failed (RV=0,CR=0.474736). (40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission failed (RV=0,CR=0.474736). (42.50%) NSlot=16, HARQ Proc 0: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (45.00%) NSlot=17, HARQ Proc 1: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (47.50%) NSlot=18, HARQ Proc 2: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (50.00%) NSlot=19, HARQ Proc 3: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (52.50%) NSlot=20, HARQ Proc 4: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (55.00%) NSlot=21, HARQ Proc 5: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (57.50%) NSlot=22, HARQ Proc 6: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (60.00%) NSlot=23, HARQ Proc 7: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (62.50%) NSlot=24, HARQ Proc 8: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (65.00%) NSlot=25, HARQ Proc 9: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (67.50%) NSlot=26, HARQ Proc 10: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (70.00%) NSlot=27, HARQ Proc 11: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (72.50%) NSlot=28, HARQ Proc 12: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (75.00%) NSlot=29, HARQ Proc 13: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (77.50%) NSlot=30, HARQ Proc 14: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (80.00%) NSlot=31, HARQ Proc 15: CW0: Retransmission #1 passed (RV=2,CR=0.474736). (82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission failed (RV=0,CR=0.474736). (85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission failed (RV=0,CR=0.474736). (87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission failed (RV=0,CR=0.474736). (90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission failed (RV=0,CR=0.474736). (92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission failed (RV=0,CR=0.474736). (95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission failed (RV=0,CR=0.474736). (97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission failed (RV=0,CR=0.474736). (100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission failed (RV=0,CR=0.474736). Throughput(Mbps) for 2 frame(s) = 24.1728 Throughput(%) for 2 frame(s) = 40.0000 Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at 0dB SNR for 2 10ms frame(s) (2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). (22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736). (25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736). (27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736). (30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736). (32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736). (35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736). (37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736). (40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736). (42.50%) NSlot=16, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (45.00%) NSlot=17, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (47.50%) NSlot=18, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (50.00%) NSlot=19, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (52.50%) NSlot=20, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (55.00%) NSlot=21, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (57.50%) NSlot=22, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (60.00%) NSlot=23, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). (62.50%) NSlot=24, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736). (65.00%) NSlot=25, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736). (67.50%) NSlot=26, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736). (70.00%) NSlot=27, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736). (72.50%) NSlot=28, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736). (75.00%) NSlot=29, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736). (77.50%) NSlot=30, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736). (80.00%) NSlot=31, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736). (82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). Throughput(Mbps) for 2 frame(s) = 60.4320 Throughput(%) for 2 frame(s) = 100.0000 Simulating transmission scheme 1 (8x2) and SCS=30kHz with CDL-C channel at 5dB SNR for 2 10ms frame(s) (2.50%) NSlot=0, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (5.00%) NSlot=1, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (7.50%) NSlot=2, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (10.00%) NSlot=3, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (12.50%) NSlot=4, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (15.00%) NSlot=5, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (17.50%) NSlot=6, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (20.00%) NSlot=7, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). (22.50%) NSlot=8, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736). (25.00%) NSlot=9, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736). (27.50%) NSlot=10, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736). (30.00%) NSlot=11, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736). (32.50%) NSlot=12, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736). (35.00%) NSlot=13, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736). (37.50%) NSlot=14, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736). (40.00%) NSlot=15, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736). (42.50%) NSlot=16, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (45.00%) NSlot=17, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (47.50%) NSlot=18, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (50.00%) NSlot=19, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (52.50%) NSlot=20, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (55.00%) NSlot=21, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (57.50%) NSlot=22, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (60.00%) NSlot=23, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). (62.50%) NSlot=24, HARQ Proc 8: CW0: Initial transmission passed (RV=0,CR=0.474736). (65.00%) NSlot=25, HARQ Proc 9: CW0: Initial transmission passed (RV=0,CR=0.474736). (67.50%) NSlot=26, HARQ Proc 10: CW0: Initial transmission passed (RV=0,CR=0.474736). (70.00%) NSlot=27, HARQ Proc 11: CW0: Initial transmission passed (RV=0,CR=0.474736). (72.50%) NSlot=28, HARQ Proc 12: CW0: Initial transmission passed (RV=0,CR=0.474736). (75.00%) NSlot=29, HARQ Proc 13: CW0: Initial transmission passed (RV=0,CR=0.474736). (77.50%) NSlot=30, HARQ Proc 14: CW0: Initial transmission passed (RV=0,CR=0.474736). (80.00%) NSlot=31, HARQ Proc 15: CW0: Initial transmission passed (RV=0,CR=0.474736). (82.50%) NSlot=32, HARQ Proc 0: CW0: Initial transmission passed (RV=0,CR=0.474736). (85.00%) NSlot=33, HARQ Proc 1: CW0: Initial transmission passed (RV=0,CR=0.474736). (87.50%) NSlot=34, HARQ Proc 2: CW0: Initial transmission passed (RV=0,CR=0.474736). (90.00%) NSlot=35, HARQ Proc 3: CW0: Initial transmission passed (RV=0,CR=0.474736). (92.50%) NSlot=36, HARQ Proc 4: CW0: Initial transmission passed (RV=0,CR=0.474736). (95.00%) NSlot=37, HARQ Proc 5: CW0: Initial transmission passed (RV=0,CR=0.474736). (97.50%) NSlot=38, HARQ Proc 6: CW0: Initial transmission passed (RV=0,CR=0.474736). (100.00%) NSlot=39, HARQ Proc 7: CW0: Initial transmission passed (RV=0,CR=0.474736). Throughput(Mbps) for 2 frame(s) = 60.4320 Throughput(%) for 2 frame(s) = 100.0000
結果
測定したスループットを表示します。これは、使用可能なリソースを所与とするリンクの最大スループットがデータ伝送に占める割合として計算されます。
figure; plot(simParameters.SNRIn,simThroughput*100./maxThroughput,'o-.') xlabel('SNR (dB)'); ylabel('Throughput (%)'); grid on; title(sprintf('%s (%dx%d) / NRB=%d / SCS=%dkHz', ... simParameters.DelayProfile,simParameters.NTxAnts,simParameters.NRxAnts, ... simParameters.Carrier.NSizeGrid,simParameters.Carrier.SubcarrierSpacing)); % Bundle key parameters and results into a combined structure for recording simResults.simParameters = simParameters; simResults.simThroughput = simThroughput; simResults.maxThroughput = maxThroughput;
次の Figure は、10,000 サブフレーム (NFrames = 1000
、SNRIn = -18:2:16
) のシミュレーションで取得したスループットの結果を示しています。
参考文献
3GPP TS 38.211. "NR; Physical channels and modulation." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
3GPP TS 38.212. "NR; Multiplexing and channel coding." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
3GPP TS 38.213. "NR; Physical layer procedures for control." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
3GPP TS 38.214. "NR; Physical layer procedures for data." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
3GPP TR 38.901. "Study on channel model for frequencies from 0.5 to 100 GHz." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.
ローカル関数
function validateNumLayers(simParameters) % Validate the number of layers, relative to the antenna geometry numlayers = simParameters.PDSCH.NumLayers; ntxants = simParameters.NTxAnts; nrxants = simParameters.NRxAnts; antennaDescription = sprintf('min(NTxAnts,NRxAnts) = min(%d,%d) = %d',ntxants,nrxants,min(ntxants,nrxants)); if numlayers > min(ntxants,nrxants) error('The number of layers (%d) must satisfy NumLayers <= %s', ... numlayers,antennaDescription); end % Display a warning if the maximum possible rank of the channel equals % the number of layers if (numlayers > 2) && (numlayers == min(ntxants,nrxants)) warning(['The maximum possible rank of the channel, given by %s, is equal to NumLayers (%d).' ... ' This may result in a decoding failure under some channel conditions.' ... ' Try decreasing the number of layers or increasing the channel rank' ... ' (use more transmit or receive antennas).'],antennaDescription,numlayers); %#ok<SPWRN> end end function estChannelGrid = getInitialChannelEstimate(carrier,nTxAnts,propchannel,dataType) % Obtain channel estimate before first transmission. This can be used to % obtain a precoding matrix for the first slot. ofdmInfo = nrOFDMInfo(carrier); chInfo = info(propchannel); maxChDelay = chInfo.MaximumChannelDelay; % Temporary waveform (only needed for the sizes) tmpWaveform = zeros((ofdmInfo.SampleRate/1000/carrier.SlotsPerSubframe)+maxChDelay,nTxAnts,dataType); % Filter through channel [~,pathGains,sampleTimes] = propchannel(tmpWaveform); % Perfect timing synch pathFilters = getPathFilters(propchannel); offset = nrPerfectTimingEstimate(pathGains,pathFilters); % Perfect channel estimate estChannelGrid = nrPerfectChannelEstimate(carrier,pathGains,pathFilters,offset,sampleTimes); end function estChannelGrid = precodeChannelEstimate(carrier,estChannelGrid,W) % Apply precoding matrix W to the last dimension of the channel estimate [K,L,R,P] = size(estChannelGrid); estChannelGrid = reshape(estChannelGrid,[K*L R P]); estChannelGrid = nrPDSCHPrecode(carrier,estChannelGrid,reshape(1:numel(estChannelGrid),[K*L R P]),W); estChannelGrid = reshape(estChannelGrid,K,L,R,[]); end function plotLayerEVM(NSlots,nslot,pdsch,siz,pdschIndices,pdschSymbols,pdschEq) % Plot EVM information persistent slotEVM; persistent rbEVM persistent evmPerSlot; if (nslot==0) slotEVM = comm.EVM; rbEVM = comm.EVM; evmPerSlot = NaN(NSlots,pdsch.NumLayers); figure; end evmPerSlot(nslot+1,:) = slotEVM(pdschSymbols,pdschEq); subplot(2,1,1); plot(0:(NSlots-1),evmPerSlot,'o-'); xlabel('Slot number'); ylabel('EVM (%)'); legend("layer " + (1:pdsch.NumLayers),'Location','EastOutside'); title('EVM per layer per slot'); subplot(2,1,2); [k,~,p] = ind2sub(siz,pdschIndices); rbsubs = floor((k-1) / 12); NRB = siz(1) / 12; evmPerRB = NaN(NRB,pdsch.NumLayers); for nu = 1:pdsch.NumLayers for rb = unique(rbsubs).' this = (rbsubs==rb & p==nu); evmPerRB(rb+1,nu) = rbEVM(pdschSymbols(this),pdschEq(this)); end end plot(0:(NRB-1),evmPerRB,'x-'); xlabel('Resource block'); ylabel('EVM (%)'); legend("layer " + (1:pdsch.NumLayers),'Location','EastOutside'); title(['EVM per layer per resource block, slot #' num2str(nslot)]); drawnow; end