Main Content

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

5G NR ダウンリンク CSI レポート

この例では、タップ付き遅延線 (TDL) チャネル上で、TS 38.214 の Section 5.2.2 で定義されている multiple input multiple output (MIMO) シナリオのチャネル品質インジケーター (CQI)、プリコーディング マトリックス インジケーター (PMI)、およびランク インジケーター (RI) などのダウンリンク チャネル状態情報 (CSI) パラメーターを計算する方法を示します。この例では、タイプ I シングルパネル、タイプ I マルチパネル、タイプ II コードブック、および拡張タイプ II コードブックに関する CSI パラメーターの計算をサポートしています。

はじめに

CSI パラメーターは、チャネルの状態に関連する量です。ユーザー端末 (UE) は、CSI パラメーターをアクセス ネットワーク ノード (gNB) にフィードバックとして報告します。CSI フィードバックには、CQI、PMI、および RI など、いくつかのパラメーターが含まれます。UE は、チャネル状態情報基準信号 (CSI-RS) を使用して、CSI フィードバックを測定します。CSI パラメーターを受信すると、gNB はそれに応じてダウンリンク データ伝送 (変調スキーム、符号化率、トランスミッション レイヤー数、MIMO プリコーディングなど) をスケジュールします。次の図は、CSI-RS の送信、CSI の計算とフィードバック、および CSI パラメーターに基づいてスケジュールされたダウンリンク データ伝送の概要を示しています。

RI の選択

RI は、特定のチャネル条件下においてダウンリンク伝送のために使用できるレイヤーの数を定義します。RI は、ダウンリンク伝送で使用できる無相関パスの最大数にも対応しています。PMI や CQI などの他の CSI パラメーターは、RI によって提供されるランクに基づいて計算されます。与えられたチャネル条件について、関数 hRISelect は、有効なトランスミッション レイヤー数の値すべてについて CQI 値を計算します。この関数は、変調効率と符号化効率が最大となるトランスミッション レイヤーの数を返します。

PMI の選択

PMI は、プリコーディング行列に対応する一連のインデックスで構成されます。gNB は、このプリコーディング行列をダウンリンク データ伝送に適用できます。関数 hDLPMISelect は、サポートされている次のコードブックから 1 つのコードブックを考慮してプリコーディング行列を報告します。

  • タイプ I シングルパネル コードブック (TS 38.214 の Table 5.2.2.2.1-1 ~ 5.2.2.2.1-12 で定義)

  • タイプ I マルチパネル コードブック (TS 38.214 の Table 5.2.2.2.2-1 ~ 5.2.2.2.2-6 で定義)

  • タイプ II コードブック (TS 38.214 の Table 5.2.2.2.2-1 ~ 5.2.2.2.3-5 で定義)

  • 拡張タイプ II コードブック (TS 38.214 の Table 5.2.2.2.5-1 ~ 5.2.2.2.5-6 で定義)

PMI の選択は、コードブックのタイプ、トランスミッション レイヤーの数、およびその他の CSI レポート構成パラメーター (アンテナ パネルの寸法など) に基づいています。各コードブックは、一連のプリコーディング行列で構成されます。NR は、TS 38.214 の Sections 5.2.2.2.1 ~ 5.2.2.2.3 および Section 5.2.2.2.5 で規定されているコードブック設計に基づき、デュアルステージ プリコーディング行列を考慮します。

W=W1W2

ここで、

W1 は、コードブック タイプに基づいて 2 つの偏波に関する離散フーリエ変換 (DFT) のビームまたはビーム グループを表す行列です。

W2 は、コードブック タイプに基づき、次のいずれかとなります。

  • W1 からのビームの選択

  • W1 に含まれるビームの重み付け係数

  • 2 つの偏波間のコフェージング値

タイプ I シングルパネル/マルチパネル コードブックの場合、関数は、選択されたコードブックのすべてのプリコーディング行列と与えられたチャネル条件について、受信側における signal to interference plus noise ratio (SINR) を計算します。この関数は、PMI をインデックス i1i2 のセットとして報告します (タイプ I シングルパネル コードブックは TS 38.214 の Section 5.2.2.2.1、タイプ I マルチパネル コードブックは TS 38.214 の Section 5.2.2.2.2 の定義に従う)。これらのインデックスは、SINR が最大となるプリコーディング行列 W に対応します。タイプ I のシングル パネルおよびマルチ パネルのコードブックは、シングルユーザー MIMO のシナリオで役に立ちます。次の図は、タイプ I シングルパネル/マルチパネル コードブックから PMI を選択する手順を示しています。

タイプ II コードブックは、一連の直交 DFT ビームを考慮してプリコーディング行列を形成します。前述のように、W1 行列には DFT ビームに関連する情報が含まれています。この関数は、与えられたチャネル条件と DFT ビーム数に基づいて、各直交ビーム グループに含まれるすべての DFT ビームのビーム振幅スケーリングとコフェージング値 (W2) を計算し、直交ビームの線形結合がチャネルの固有ベクトルに近づくようにします。この関数は、TS 38.214 の Section 5.2.2.2.3 で定義されているように、インデックス i1i2 を報告します。これらのインデックスは、SINR が最大となるプリコーディング行列 W に対応します。タイプ II コードブックではチャネルの固有ベクトルを近似する際に複数のビームが考慮されるため、タイプ II コードブックに基づく PMI のほうがタイプ I コードブックに基づく PMI よりも正確です。タイプ II コードブックでは複数のビームが考慮されるため、マルチユーザー MIMO のシナリオではタイプ I コードブックではなくタイプ II コードブックが使用されます。次の図は、タイプ II コードブックから PMI を選択する手順を示しています。

次の図は、タイプ II コードブックで空間領域の量子化 (チャネルの固有ベクトルの近似においてビームの数を減らす処理) を行って各レイヤーの W2 行列を形成するプロセスを示しています。

タイプ II コードブックはランク 2 までしかサポートしていないため、この規格では拡張タイプ II コードブックが導入されています。拡張タイプ II コードブックに基づく PMI の計算では、タイプ II コードブックが拡張され、1 つのオーバーヘッド削減手法によってランク 4 までサポートされています。すべてのビームについて、タイプ II コードブックと同様の方法でビーム振幅スケーリングとコフェージング値 (これはビーム結合係数とも呼ばれます) が計算されます。このランク拡張によって、サブバンド数に応じてフィードバックのオーバーヘッドが線形的に増加します。このフィードバックの量によっては、アップリンクのリソースが不足する可能性があります。拡張タイプ II コードブックでは、DFT (または周波数領域の圧縮) と呼ばれるプロセスが採用されており、ビーム結合係数の周波数領域の相関を活用してフィードバックのオーバーヘッドを削減しています。

次の図は、周波数領域の圧縮プロセスを示しています。

拡張タイプ II コードブックでは、周波数領域の圧縮に加え、弱いビームの結合係数を無視してフィードバックに含まれる非ゼロ係数の数を制限しています。

CQI の選択

CQI はチャネル品質の指標です。CQI 値は範囲 [0, 15] のスカラーです。CQI 値は、与えられたチャネル条件で要求されるブロック エラー レート (BLER) を達成するためのダウンリンク伝送に適合する最も高い変調スキーム/符号化率 (MCS) の情報を提供します。

CSI 基準リソースは、TS 38.214 の Section 5.2.2.5 の定義に従って構成された、ダウンリンクの周波数領域と時間領域のリソースから成るグループです。gNB は、CSI 基準リソースと呼ばれるリソース ブロックを占有する単一の物理ダウンリンク共有チャネル (PDSCH) トランスポート ブロックを、各 CQI インデックスに対応する変調スキームとターゲット符号化率の組み合わせとともに送信します。PDSCH トランスポート ブロックが以下のトランスポート ブロックの誤り確率を超えない状態で受信できる場合、UE は可能な限り高い CQI を選択します。

  • 0.1 ('cqi-Table''table1' または 'table2' の場合)

  • 0.00001 ('cqi-Table''table3' の場合)

'cqi-Table' は、CQI と MCS の表に対応する上位レイヤーのパラメーターであり、このテーブルに対して SINR ルックアップ テーブルが計算されます。この例では、'cqi-Table''table1' として使用します (TS 38.214 の Table 5.2.2.1-2)。CQI インデックス、変調スキーム、および符号化率 (トランスポート ブロック サイズが導出される) の関係は、TS 38.214 の Table 5.2.2.1-2 ~ 5.2.2.1-4 で説明されています。

関数 hCQISelect は、報告された PMI に対応する SINR 値を考慮して CQI 値を計算します。この関数は、事前に計算された CQI インデックスと SINRi のルックアップ テーブルを基準として使用します (提供している場合)。

SINR ルックアップ テーブルを使用した CQI の選択

この関数は、すべてのレイヤーの SINR 値 (報告された PMI に対応) を各コードワードにマッピングします。コードワードごとに、関数はそれぞれの SINR とテーブルの SINRi 値を比較し、コードワード SINR より小さい最大 SINR に対して CQI 値を選択します。関数は、SINRi で動作するときに BLER が 0.1 以下になるように CQI 値を設定します。CQI インデックス 1 が BLER 条件を満たさない場合、関数は CQI インデックスを 0 に設定します。次の図は、CQI 選択の手順を示しています。

SINR ルックアップ テーブルを使用しない CQI の選択

この関数は、報告された PMI に対応するすべてのレイヤーの SINR 値を使用して、CQI 値を計算します。コードワードの数に基づいて、関数は CQI 値の組み合わせを作成し、BLER 条件を満たすものを報告します。

CQI と SINR の対応テーブル

ルックアップ テーブルを作成するには、TS 38.214 の Section 5.2.2.5 の定義に従って、CSI 基準リソースを構成してNR PDSCH スループットの例を更新します。各 CQI に対応する変調スキームと符号化率、チャネル条件、および干渉がゼロになる有限範囲の SINR 値を指定し、PDSCH スループットのシミュレーションを実行します。ターゲット BLER が達成されたときに、受信側で観測された SINR 値を各 CQI インデックスに対してマッピングします。次の図は、CQI と SINR の対応テーブルを作成する手順を示しています。

例の概要

この例では、TDL-C 遅延プロファイル、遅延スプレッド 300 ナノ秒、および最大ドップラー シフト 50 Hz の TDL チャネルで 4×4 MIMO シナリオ用の CQI インデックスおよび PMI インデックスを計算する方法を示します。実用的なチャネル推定シナリオおよび完全なチャネル推定シナリオについて、CQI 値の時間領域および周波数領域の変動と SINR 値の時間領域および周波数領域の変動を比較します。この例では、実用的なチャネル推定と完全なチャネル推定のシナリオに関し、報告されたランクに対応する PMI 値の時間領域と周波数領域の変化についても説明しています。

シミュレーションの長さと SNR 点

シミュレーションの長さを 10 ms のフレームの数で設定します。SNR (ゼロ干渉の SINR) は、リソース エレメント (RE) ごとに定義され、それぞれの受信アンテナに適用されます。この例で使用している SNR 定義の説明については、リンク シミュレーションで使用する SNR の定義を参照してください。

nFrames = 5; % Number of 10 ms frames
SNRdB = 10;  % SNR in dB

キャリア、bandwidth part、および CSI-RS の構成

サブキャリア間隔が 15 kHz の 10 MHz キャリアを表すキャリア構成オブジェクトを作成します。

carrier = nrCarrierConfig;
carrier.SubcarrierSpacing = 15;
carrier.NSizeGrid = 52;

bandwidth part (BWP) のサイズと、共通リソース ブロック 0 (CRB 0) に対応する BWP の開始位置を構成します。

NStartBWP = 0;
NSizeBWP = 52;

複数の NZP-CSI-RS リソースから成るセットで 1 つの非ゼロ電力 CSI-RS (NZP-CSI-RS) リソース セットを表す CSI-RS 構成オブジェクトを作成します。NZP-CSI-RS リソースの code division multiplexing (CDM) タイプおよび CSI-RS ポートの数が、TS 38.214 の Section 5.2.2.3.1 の定義と確実に同じになるようにします。

csirs = nrCSIRSConfig;
csirs.CSIRSType = {'nzp','nzp','nzp'};
csirs.RowNumber = [4 4 4];
csirs.NumRB = 52;
csirs.RBOffset = 0;
csirs.CSIRSPeriod = [4 0];
csirs.SymbolLocations = {0, 0, 0};
csirs.SubcarrierLocations = {0, 4, 8};
csirs.Density = {'one','one','one'};

送信アンテナと受信アンテナの数を設定します。この例では物理アンテナに対するアンテナ ポートのマッピングが考慮されていないため、送信アンテナの数が CSI-RS ポートの数と等しくなければなりません。

nTxAnts = csirs.NumCSIRSPorts(1);
nRxAnts = 4;

CSI-RS 構成オブジェクトを検証します。

validateCSIRSConfig(carrier,csirs,nTxAnts);

CSI レポート構成

CQI、PMI、および RI の計算のパラメーターを、次のフィールドをもつ構造体として指定します。

  • NSizeBWP — 物理リソース ブロック (PRB) の数に関する BWP のサイズ

  • NStartBWP — CRB 0 を基準とする BWP の開始 PRB インデックス

  • CQITable — TS 38.214 の Table 5.2.2.1-2 ~ 5.2.2.1-4 で定義された、チャネル品質インジケーター テーブル ('table1''table2''table3')

  • CodebookType — CSI パラメーター計算用のコードブック タイプ ('Type1SinglePanel''Type1MultiPanel''Type2''eType2')

  • PanelDimensionsCodebookType フィールドに対応するアンテナ パネルの寸法

CodebookType が ('Type1SinglePanel''Type2''eType2') のいずれかに設定されている場合、パネルの寸法は TS 38.214 の Table 5.2.2.2.1-2 に従って [N1 N2] の形式になります。次の図は、サポートされているパネルの寸法を示しています。

CodebookTypeType1MultiPanel' に設定されている場合、パネルの寸法は TS 38.214 の Table 5.2.2.2.2-1 に従って [Ng N1 N2] の形式になります。次の図は、サポートされているタイプ I マルチパネルの寸法を示しています。

  • CQIMode — CQI レポートのモード ('Subband''Wideband')

  • PMIMode — PMI レポートのモード ('Subband''Wideband')

  • SubbandSize — TS 38.214 の Table 5.2.1.4-2 で定義されているサブバンドのサイズ (CQIMode または PMIMode'Subband' の場合にのみ必要)

  • PRGSize — CQI 計算用のプリコーディング リソース ブロック グループ (PRG) サイズ (TS 38.214 の Section 5.2.1.4.2 で定義されているように、レポート量 'cri-RI-i1-CQI' に対してレポートを実行する必要があり、CodebookType'Type1SinglePanel' として構成されている場合にのみ必要)

  • CodebookMode — コードブックを導出する際の基準となるコードブック モード。この値は 1 または 2 でなければなりません。このフィールドは、CodebookType'Type1SinglePanel' または 'Type1MultiplePanel' として指定されている場合にのみ適用されます。CodebookType'Type1SinglePanel' として指定されている場合、このフィールドが必要になるのは、トランスミッション レイヤーの数が 1 または 2 であり、CSI-RS ポートの数が 2 より大きい場合のみです。CodebookType'Type1MultiplePanel' として指定されている場合、トランスミッション レイヤーの数にかかわらずこのフィールドが必要となりますが、CodebookMode の値 2 は Ng の値が 2 であるパネル構成にのみ適用されます。

  • CodebookSubsetRestriction — タイプ I シングルパネル/マルチパネル コードブックの場合、TS 38.214 の Section 5.2.2.2.1 で定義されているコードブック インデックス セット i1 に関連する制限パラメーター (つまり vlm または v~lm の制限パラメーター)。このフィールドは、PMI の計算対象から除外される i1 インデックスのセット ([i11 , i12 ]) を示します。タイプ II コードブックの場合、このフィールドは、TS 38.214 の Section 5.2.2.2.3 で定義されているように、k=0,1,2,3 に対する r1(k), r2(k) で示される 4 つのベクトル グループに許可される最大振幅を制限します。拡張タイプ II コードブックの場合、このフィールドは、TS 38.214 の Section 5.2.2.2.5 で定義されているように、k=0,1,2,3 に対する r1(k), r2(k) で示される 4 つのベクトル グループに許可される最大平均振幅係数を制限します。いずれのコードブック タイプでも、このフィールドはビットマップとして指定されます。

  • i2Restriction — コードブック インデックス i2 に関連する制限パラメーター。このフィールドは、PMI の計算対象から除外される i2 インデックスのセットを示します。このフィールドは、CodebookType'Type1SinglePanel' の場合にのみ適用されます。

  • RIRestriction — ランク インジケーターに関連する制限パラメーター。これは、RI の計算対象から除外されるランクのセットを意味します。

  • NumberOfBeams — 偏波ごとのビーム グループ内のビーム数。このフィールドは、CodebookType'Type2' として指定されている場合にのみ適用されます。値は {2、3、4} のいずれかでなければなりません。

  • PhaseAlphabetSize — インデックス i2 の計算で考慮される位相の範囲を表します。このフィールドは、CodebookType'Type2' として指定されている場合にのみ適用されます。値は {4、8} のいずれかでなければなりません。値 4 は QPSK に対応する位相を表し、値 8 は 8-PSK に対応する位相を表します。

  • SubbandAmplitudetrue に設定するとサブバンドごとの差動振幅のレポートを有効にし、false に設定すると PMI レポートで差動サブバンド振幅を無効にする logical スカラー。値は {truefalse} のいずれかでなければなりません。このフィールドは、CodebookType'Type2' として指定され、PMIMode'Subband' である場合に適用されます。

  • ParameterCombination — 1 ~ 8 の範囲の正のスカラー整数。これは、CodebookType'eType2' として指定されている場合に適用されます。このパラメーターは、TS 38.214 の Table 5.2.2.2.5-1 で定義されているように、ビームの数と他の 2 つのパラメーターを定義します。

  • NumberOfPMISubbandsPerCQISubband — TS 38.214 の Section 5.2.2.2.5 で定義されているように、1 つの CQI サブバンドに含まれる PMI サブバンドの数を表します。これは、正のスカラー整数で、1 または 2 でなければなりません。

CSI レポート構成パラメーターを構成します。

reportConfig.NStartBWP = NStartBWP;
reportConfig.NSizeBWP = NSizeBWP;
reportConfig.CQITable = 'table1';
reportConfig.CodebookType = 'Type1SinglePanel';
reportConfig.PanelDimensions = [2 1];
reportConfig.CQIMode = 'Subband';
reportConfig.PMIMode = 'Subband';
reportConfig.SubbandSize = 4;
reportConfig.PRGSize = [];
reportConfig.CodebookMode = 1;
reportConfig.CodebookSubsetRestriction = [];
reportConfig.i2Restriction = [];
reportConfig.RIRestriction = [];
reportConfig.NumberOfBeams = 2;                    % Applicable only when CodebookType is 'Type2'
reportConfig.SubbandAmplitude = false;             % Applicable only when CodebookType is 'Type2'
reportConfig.PhaseAlphabetSize = 4;                % Applicable only when CodebookType is 'Type2'
reportConfig.ParameterCombination = 2;             % Applicable only when CodebookType is 'eType2'
reportConfig.NumberOfPMISubbandsPerCQISubband = 2; % Applicable only when CodebookType is 'eType2'

伝播チャネル モデルの構成

TDL-C 遅延プロファイル、遅延スプレッド 300 ナノ秒、および最大ドップラー シフト 50 Hz の TDL チャネルを作成します。

channel = nrTDLChannel;
channel.NumTransmitAntennas = nTxAnts;
channel.NumReceiveAntennas = nRxAnts;
channel.DelayProfile = 'TDL-C';
channel.MaximumDopplerShift = 50;
channel.DelaySpread = 300e-9;

関数 nrOFDMInfo が返す値を使用して、チャネル モデルのサンプル レートを設定します。

waveformInfo = nrOFDMInfo(carrier);
channel.SampleRate = waveformInfo.SampleRate;

チャネルのマルチパス成分によって、遅延サンプルの最大数を取得します。遅延サンプルの最大数は、最も遅延の大きいチャネル パスとチャネル フィルターの実装遅延に基づいて計算されます。最大チャネル遅延に対応するサンプル数は、チャネル フィルターをフラッシュして受信信号を取得するために後で必要になります。

chInfo = info(channel);
maxChDelay = chInfo.MaximumChannelDelay;

処理ループ

スロットごとに、CSI-RS を生成してチャネルに送信後、受信側で処理して、CQI、PMI、および RI 値を計算します。各スロットの送受信処理の手順に従います。

  1. リソース グリッドの生成 — CSI-RS を含むスロット グリッドを生成し、スロット グリッドを CSI-RS ポートから送信アンテナにマッピングします。

  2. 波形の生成 — 関数 nrOFDMModulate を使用して、生成されたグリッドで直交周波数分割多重 (OFDM) 変調を実行します。

  3. ノイズを含むチャネルのモデル化と適用 — TDL-C フェージング チャネルに波形を渡し、加法性ホワイト ガウス ノイズ (AWGN) を付加します。SNR は RE ごとに定義され、それぞれの受信アンテナに適用されます。

  4. タイミング同期と OFDM 復調の実行 — 実用的な同期のために、受信波形を CSI-RS と関連付けます。完全な同期のために、チャネルのパス ゲインとパス フィルターを使用します。関数 nrOFDMDemodulate を使用し、同期した信号に対して OFDM 復調を実行します。

  5. チャネル推定の実行 — 実用的なチャネル推定のために、CSI-RS を使用します。完全なチャネル推定のために、チャネル スナップショットのパス ゲイン、パス フィルター、およびサンプル時間を使用します。

  6. CQI、PMI、および RI 値の計算 — 実用的なチャネル推定と完全なチャネル推定を使用して、CQI、PMI、および RI 値を計算します。

合計スロット数を計算します。

totSlots = nFrames*carrier.SlotsPerFrame;

実用的なチャネル推定と完全なチャネル推定のシナリオ用に変数を初期化して、CQI、PMI、RI、およびサブバンド SINR の値を保存します。

処理ループの完了後:

  • 変数 cqiPracticalPerSlotcqiPerfectPerSlotSINRPerSubbandPerCWPractical、および SINRPerSubbandPerCWPrerfect は、サイズ numSBs×2×totSlots の多次元配列です。numSBs の値はサブバンド数に 1 を足した数と同じです (すなわち、対応する広帯域値の後にサブバンド値が続きます)。2 番目の次元の値はコードワードが取り得る最大数を示します。

  • 変数 pmiPracticalPerSlot および pmiPerfectPerSlot は、サイズ totSlots の構造体から成る配列です。この構造体は、フィールド i1 および i2 で PMI 値を表します。

  • 変数 riPracticalPerSlot および riPerfectPerSlot は、1 行 totSlots 列のサイズの配列です。

cqiPracticalPerSlot = [];
subbandCQIPractical = [];
pmiPracticalPerSlot = struct('i1',[],'i2',[]);
SINRPerSubbandPerCWPractical = [];
cqiPerfectPerSlot = [];
subbandCQIPerfect = [];
pmiPerfectPerSlot = struct('i1',[],'i2',[]);
SINRPerSubbandPerCWPerfect = [];
riPracticalPerSlot = [];
riPerfectPerSlot = [];

% Get number of CSI-RS ports
csirsPorts = csirs.NumCSIRSPorts(1);

% Get CDM lengths corresponding to configured CSI-RS resources
cdmLengths = getCDMLengths(csirs);

% Initialize the practical timing offset as zero. It is updated in the
% slots when the correlation is strong for practical synchronization.
offsetPractical = 0;

% Initialize a variable to store the information of the slots
% where NZP-CSI-RS resources are present. It is of length totSlots.
totSlotsBinaryVec = zeros(1,totSlots);

% Set RNG state for repeatability
rng('default');

% Loop over all slots
for nslot = 0:totSlots - 1
    % Create carrier resource grid for one slot
    csirsSlotGrid = nrResourceGrid(carrier,csirsPorts);

    % Update slot number in carrier configuration object
    carrier.NSlot = nslot;

    % Generate CSI-RS indices and symbols
    csirsInd = nrCSIRSIndices(carrier,csirs);
    csirsSym = nrCSIRS(carrier,csirs);

    % Map CSI-RS to slot grid
    csirsSlotGrid(csirsInd) = csirsSym;

    % Map CSI-RS ports to transmit antennas
    wtx = eye(csirsPorts,nTxAnts);
    txGrid = reshape(reshape(csirsSlotGrid,[],csirsPorts)*wtx,size(csirsSlotGrid,1),size(csirsSlotGrid,2),nTxAnts);

    % Perform OFDM modulation to generate time-domain waveform
    txWaveform = nrOFDMModulate(carrier,txGrid);

    % Append zeros at the end of the transmitted waveform to flush channel
    % content. These zeros take into account any delay introduced in the
    % channel. The channel delay 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>

    % Transmit waveform through channel
    [rxWaveform,pathGains,sampleTimes] = channel(txWaveform);

    % Generate and add AWGN to received waveform
    SNR = 10^(SNRdB/10);                                                % Linear SNR value
    sigma = 1/(sqrt(2.0*nRxAnts*double(waveformInfo.Nfft)*SNR));        % Noise standard deviation
    noise = sigma*complex(randn(size(rxWaveform)),randn(size(rxWaveform)));
    rxWaveform = rxWaveform + noise;

    % Perform practical timing estimation. Correlate the received waveform
    % with the CSI-RS to obtain the timing offset estimate and the
    % correlation magnitude. Use the hSkipWeakTimingOffset function to
    % update the receiver timing offset. If the correlation peak is weak,
    % the current timing estimate is ignored and the previous offset is
    % used.
    [t,mag] = nrTimingEstimate(carrier,rxWaveform,csirsInd,csirsSym);
    offsetPractical = hSkipWeakTimingOffset(offsetPractical,t,mag);

    % Get path filters
    pathFilters = getPathFilters(channel);
    % Perform perfect timing estimation
    offsetPerfect = nrPerfectTimingEstimate(pathGains,pathFilters);

    % Perform time-domain offset correction for practical and
    % perfect timing estimation scenarios
    rxWaveformPractical = rxWaveform(1+offsetPractical:end,:);
    rxWaveformPerfect = rxWaveform(1+offsetPerfect:end,:);

    % Perform OFDM demodulation on previously synchronized waveforms
    rxGridPractical = nrOFDMDemodulate(carrier,rxWaveformPractical);
    rxGridPerfect = nrOFDMDemodulate(carrier,rxWaveformPerfect);

    % Append zeros when the timing synchronization results in an incomplete
    % slot
    symbPerSlot = carrier.SymbolsPerSlot;
    K = size(rxGridPractical,1);
    LPractical = size(rxGridPractical,2);
    LPerfect = size(rxGridPerfect,2);
    if LPractical < symbPerSlot
        rxGridPractical = cat(2,rxGridPractical,zeros(K,symbPerSlot-LPractical,nRxAnts));
    end
    if LPerfect < symbPerSlot
        rxGridPerfect = cat(2,rxGridPerfect,zeros(K,symbPerSlot-LPerfect,nRxAnts));
    end
    rxGridPractical = rxGridPractical(:,1:symbPerSlot,:);
    rxGridPerfect = rxGridPerfect(:,1:symbPerSlot,:);

    % Consider only the NZP-CSI-RS symbols and indices for channel estimation
    nzpCSIRSSym = csirsSym(csirsSym ~= 0);
    nzpCSIRSInd = csirsInd(csirsSym ~= 0);

    % Calculate practical channel estimate. Use a time-averaging window
    % that covers all the transmitted CSI-RS symbols.
    [PracticalHest,nVarPractical] = nrChannelEstimate(carrier,rxGridPractical, ...
        nzpCSIRSInd,nzpCSIRSSym,'CDMLengths',cdmLengths,'AveragingWindow',[0 5]);

    % Perform perfect channel estimation
    PerfectHest = nrPerfectChannelEstimate(carrier,pathGains,pathFilters,offsetPerfect,sampleTimes);

    % Get perfect noise estimate value from noise realization
    noiseGrid = nrOFDMDemodulate(carrier,noise(1+offsetPerfect:end,:));
    nVarPerfect = var(noiseGrid(:));
    if ~isempty(nzpCSIRSInd)
        % Set the totSlotsBinaryVec value corresponding to the slot
        % index where NZP-CSI-RS is present to 1
        totSlotsBinaryVec(nslot+1) = 1;

        % Calculate the RI value using practical channel estimate
        numLayersPractical = hRISelect(carrier,csirs,reportConfig,PracticalHest,nVarPractical,'MaxSE');

        % Calculate CQI and PMI values using practical channel estimate
        [cqiPractical,pmiPractical,cqiInfoPractical,pmiInfoPractical] = hCQISelect(carrier,csirs, ...
            reportConfig,numLayersPractical,PracticalHest,nVarPractical);
        numCodeWordsPr = size(cqiPractical,2);
        numSBs = size(cqiPractical,1);

        % Store CQI, PMI, RI, and subband SINR values of each slot for the
        % practical channel estimation scenario. Because the number of
        % codewords can vary based on the rank, append NaNs to the
        % CQI-related variables to account for the second codeword
        % information in the slots where only one codeword is present.
        riPracticalPerSlot(1,nslot+1) = numLayersPractical; %#ok<SAGROW> 
        cqiPracticalPerSlot(:,:,nslot+1) = [cqiPractical NaN(numSBs,2-numCodeWordsPr)]; %#ok<SAGROW> 
        pmiPracticalPerSlot(nslot+1) = pmiPractical;
        subbandCQIPractical(:,:,nslot+1) = [cqiInfoPractical.SubbandCQI NaN(numSBs,2-numCodeWordsPr)]; %#ok<SAGROW> 
        SINRPerSubbandPerCWPractical(:,:,nslot+1) = [cqiInfoPractical.SINRPerSubbandPerCW NaN(numSBs,2-numCodeWordsPr)]; %#ok<SAGROW> 

        % Calculate the RI value using perfect channel estimate
        numLayersPerfect = hRISelect(carrier,csirs,reportConfig,PerfectHest,nVarPerfect,'MaxSE');

        % Calculate CQI and PMI values using perfect channel estimate
        [cqiPerfect,pmiPerfect,cqiInfoPerfect,pmiInfoPerfect] = hCQISelect(carrier,csirs, ...
            reportConfig,numLayersPerfect,PerfectHest,nVarPerfect);
        numCodeWordsPe = size(cqiPerfect,2);

        % Store CQI, PMI, RI, and subband SINR values of each slot for the
        % perfect channel estimation scenario. Because the number of
        % codewords can vary based on the rank, append NaNs to the
        % CQI-related variables to account for the second codeword
        % information in the slots where only one codeword is present.
        riPerfectPerSlot(1,nslot+1) = numLayersPerfect; %#ok<SAGROW> 
        cqiPerfectPerSlot(:,:,nslot+1) = [cqiPerfect NaN(numSBs,2-numCodeWordsPe)]; %#ok<SAGROW> 
        subbandCQIPerfect(:,:,nslot+1) = [cqiInfoPerfect.SubbandCQI NaN(numSBs,2-numCodeWordsPe)]; %#ok<SAGROW> 
        pmiPerfectPerSlot(nslot+1) = pmiPerfect;
        SINRPerSubbandPerCWPerfect(:,:,nslot+1) = [cqiInfoPerfect.SINRPerSubbandPerCW NaN(numSBs,2-numCodeWordsPe)]; %#ok<SAGROW> 
    end
end

% Get the active slot numbers (1-based) in which NZP-CSI-RS is present
activeSlotNum = find(totSlotsBinaryVec);

% Fill the CQI, PMI and RI variables with NaNs in the slots where NZP-CSI-RS is
% absent according to codebook type
[cqiPracticalPerSlot,subbandCQIPractical,pmiPracticalPerSlot,SINRPerSubbandPerCWPractical, ...
    cqiPerfectPerSlot,subbandCQIPerfect,pmiPerfectPerSlot,SINRPerSubbandPerCWPerfect,riPracticalPerSlot, ...
    riPerfectPerSlot] = fillInactiveSlots(cqiPracticalPerSlot,subbandCQIPractical, ...
    pmiPracticalPerSlot,SINRPerSubbandPerCWPractical,cqiPerfectPerSlot,subbandCQIPerfect,pmiPerfectPerSlot, ...
    SINRPerSubbandPerCWPerfect,riPracticalPerSlot,riPerfectPerSlot,reportConfig,totSlotsBinaryVec,activeSlotNum);

実用的なチャネル推定と完全なチャネル推定のシナリオで報告された CQI、PMI、および RI 値の比較

CQI インデックスのプロット

実用的なチャネル推定と完全なチャネル推定のシナリオのために、各コードワードの広帯域 SINR 値と広帯域 CQI 値をプロットします。プロットは、CSI-RS が送信されるスロットか CQI が計算されるスロットのみを示しています。次の図は、SINR および対応する報告された CQI が、チャネル フェージングによってスロット間でどのように変化するかを示しています。

plotWidebandCQIAndSINR(cqiPracticalPerSlot,cqiPerfectPerSlot, ...
    SINRPerSubbandPerCWPractical,SINRPerSubbandPerCWPerfect,activeSlotNum);

Figure contains 2 axes objects. Axes object 1 with title Wideband SINR Values for Codeword 1, xlabel Slots, ylabel Wideband SINR Values in dB contains 2 objects of type line. These objects represent Codeword 1:Perfect channel est., Codeword 1:Practical channel est.. Axes object 2 with title Wideband CQI Values for Codeword 1, xlabel Slots, ylabel Wideband CQI Values contains 2 objects of type line. These objects represent Codeword 1:Perfect channel est., Codeword 1:Practical channel est..

実用的なチャネル推定シナリオと完全なチャネル推定シナリオについて、各コードワードのサブバンド SINR 値とサブバンド CQI 値をプロットします。CQI がそのスロットで報告されている場合、プロットは、指定されたスロット番号 (0 ベース) のサブバンド全体の SINR および CQI 値の変動を示します。それ以外の場合、CQI が報告されないため、プロットは生成されません。

関数 plotSubbandCQIAndSINR は、CQIMode'Subband' として構成されている場合にのみ、すべてのサブバンドにわたって CQI 値をプロットします。

% Provide slot number for which subband CQI values and PMI i2 indices must be plotted
slotNumForSBType1 = 0; % Consider slot number as 0 (0-based) here, because CSI is
                       % reported in that slot for the configured CSI-RS resource(s)
plotSubbandCQIAndSINR(subbandCQIPractical,subbandCQIPerfect, ...
    SINRPerSubbandPerCWPractical,SINRPerSubbandPerCWPerfect,activeSlotNum,slotNumForSBType1);

Figure contains 2 axes objects. Axes object 1 with title Estimated Subband SINR Values for Codeword 1 in Slot 0, xlabel Subbands, ylabel Subband SINR Values in dB contains 2 objects of type line. These objects represent Codeword 1:Perfect channel est., Codeword 1:Practical channel est.. Axes object 2 with title Estimated Subband CQI Values for Codeword 1 in Slot 0, xlabel Subbands, ylabel Subband CQI Values contains 2 objects of type line. These objects represent Codeword 1:Perfect channel est., Codeword 1:Practical channel est..

PMI と RI インデックスのプロット

このセクションの最初のプロットは、実用的なチャネル推定シナリオと完全なチャネル推定シナリオについて、チャネル フェージング条件による RI インデックスの変動を示しています。プロットには、CSI-RS が送信されるスロットか RI が計算されるスロットのみが表示されます。

コードブック タイプ 'Type1SinglePanel'

以下のコードは、実用的なチャネル推定シナリオと完全なチャネル推定シナリオについて、チャネル フェージング条件による PMI の変動を示しています。

TS 38.214 の Section 5.2.2.2.1 で定義されているように、PMI インデックスは i1:[i1,1,i1,2,i1,3]i2 になります。

最初のプロットは、複数のスロットにわたるランクと対応する PMI の i1 インデックスの変動を示しています。

2 番目のプロットは、次における i2 インデックスの変動を示します。

  • PMIMode'Wideband' として指定されている場合のスロット

  • PMIMode'Subband' として指定されている場合の指定スロットのサブバンド

コードブック タイプ 'Type1MultiPanel'

以下のコードは、実用的なチャネル推定シナリオと完全なチャネル推定シナリオについて、チャネル フェージング条件による PMI の変動を示しています。

TS 38.214 の Section 5.2.2.2.2 で定義されているように、PMI インデックスは i1:[i1,1,i1,2,i1,3,i1,4,1,i1,4,2,i1,4,3]i2:[i2,0,i2,1,i2,2] になります。

この場合、最初の 2 つのプロットは、スロット全体のランクと対応する PMI の i1 インデックス (i1,1i1,4,3) の変動を示しています。

3 番目のプロットは、次における各 i2 インデックス (i2,0i2,2) の変動を示しています。

  • PMIMode'Wideband' として指定されている場合のスロット

  • PMIMode'Subband' として指定されている場合の指定スロットのサブバンド

コードブック タイプ 'Type2' または 'eType2'

以下のコードは、実用的なチャネル推定シナリオと完全なチャネル推定シナリオについて、プリコーディング行列の構築に使用される DFT ベクトル (ビーム) を強調表示することにより、ビームのグリッドを示します。PMI がそのスロットで報告されている場合、プロットは、指定されたスロット番号 (0 ベース) のタイプ II または拡張タイプ II PMI 関連情報を示します。それ以外の場合、PMI が報告されないため、プロットは生成されません。

タイプ II コードブックの場合、PMI インデックスは、TS 38.214 の Section 5.2.2.2.3 で定義されています。これらのインデックスは次のとおりです。

  • i1:[i1,1,i1,2,i1,3,1,i1,4,1] および i2:[i2,1,1] (単一レイヤー用。SubbandAmplitude'false')

  • i1:[i1,1,i1,2,i1,3,1,i1,4,1] および i2:[i2,1,1,i2,2,1] (単一レイヤー用。SubbandAmplitude'true')

  • i1:[i1,1,i1,2,i1,3,1,i1,4,1,i1,3,2,i1,4,2] および i2:[i2,1,1,i2,1,2] (2 つのレイヤー用。SubbandAmplitude'false')

  • i1:[i1,1,i1,2,i1,3,1,i1,4,1,i1,3,2,i1,4,2] および i2:[i2,1,1,i2,2,1,i2,1,2,i2,2,2] (2 つのレイヤー用。SubbandAmplitude'true')

拡張タイプ II コードブックの場合、PMI インデックスは、TS 38.214 の Section 5.2.2.2.5 で定義されています。これらのインデックスは次のとおりです。

  • i1:[i1,1,i1,2,i1,5,i1,6,1,i1,7,1,i1,8,1] および i2:[i2,3,1,i2,4,1,i2,5,1] (単一レイヤー用)

  • i1:[i1,1,i1,2,i1,5,i1,6,1,i1,7,1,i1,8,1,i1,6,2,i1,7,2,i1,8,2] および i2:[i2,3,1,i2,4,1,i2,5,1,i2,3,2,i2,4,2,i2,5,2] (2 つのレイヤー用)

  • i1:[i1,1,i1,2,i1,5,i1,6,1,i1,7,1,i1,8,1,i1,6,2,i1,7,2,i1,8,2,i1,6,3,i1,7,3,i1,8,3] および i2:[i2,3,1,i2,4,1,i2,5,1,i2,3,2,i2,4,2,i2,5,2,i2,3,3,i2,4,3,i2,5,3] (3 つのレイヤー用)

  • i1:[i1,1,i1,2,i1,5,i1,6,1,i1,7,1,i1,8,1,i1,6,2,i1,7,2,i1,8,2,i1,6,3,i1,7,3,i1,8,3,i1,6,4,i1,7,4,i1,8,4] および i2:[i2,3,1,i2,4,1,i2,5,1,i2,3,2,i2,4,2,i2,5,2,i2,3,3,i2,4,3,i2,5,3,i2,3,4,i2,4,4,i2,5,4] (4 つのレイヤー用)

最初のプロットはランクの変動を示し、2 番目のプロットは実用的なチャネル推定シナリオと完全なチャネル推定シナリオにおけるビームのグリッドを示しています。

% To see the PMI and RI plots for the type I single or multi-panel
% codebooks, set the showType1PMIandRIPlots flag to true
showType1PMIandRIPlots = true;
% To see the PMI and RI plots for the type II codebooks, set the
% showType2PMI flag to true
showType2PMIRI = true;
if (strcmpi(reportConfig.CodebookType,'Type1SinglePanel') || strcmpi(reportConfig.CodebookType,'Type1MultiPanel')) && showType1PMIandRIPlots
    plotType1PMIAndRI(pmiPracticalPerSlot,pmiPerfectPerSlot,riPracticalPerSlot, ...
        riPerfectPerSlot,activeSlotNum,slotNumForSBType1);
elseif (strcmpi(reportConfig.CodebookType,'Type2') || strcmpi(reportConfig.CodebookType,'eType2')) && showType2PMIRI
    slotNumForType2PMI = 0; % 0-based
    plotType2PMIAndRI(pmiPracticalPerSlot,pmiPerfectPerSlot,riPracticalPerSlot, ...
        riPerfectPerSlot,reportConfig.PanelDimensions,reportConfig.NumberOfBeams,activeSlotNum,slotNumForType2PMI);
end

Figure contains 4 axes objects. Axes object 1 with title RI Values, xlabel Slots, ylabel RI Values contains 2 objects of type line. These objects represent Perfect channel est., Practical channel est.. Axes object 2 with title PMI: i11 Indices, xlabel Slots, ylabel i11 Indices contains 2 objects of type line. These objects represent Perfect channel est., Practical channel est.. Axes object 3 with title PMI: i12 Indices, xlabel Slots, ylabel i12 Indices contains 2 objects of type line. These objects represent Perfect channel est., Practical channel est.. Axes object 4 with title PMI: i13 Indices, xlabel Slots, ylabel i13 Indices contains 2 objects of type line. These objects represent Perfect channel est., Practical channel est..

Figure contains an axes object. The axes object with title PMI: i2 Indices for All Subbands in Slot 0, xlabel Subbands, ylabel i2 Indices contains 2 objects of type line. These objects represent Perfect channel est., Practical channel est..

まとめとその他の調査

この例では、タイプ I シングルパネル コードブックに基づく CQI や PMI などのダウンリンク CSI パラメーターと、TDL チャネルを使用する MIMO シナリオの RI を計算する方法を示します。この例では、タイプ I マルチパネル、タイプ II、および拡張タイプ II のコードブックを使用した CSI パラメーターの計算もサポートしています。

キャリア、チャネル、CSI-RS リソース構成、および CSI レポート構成パラメーター (コードブック タイプ、CQI レポートと PMI レポートのモード、サブバンド サイズなど) を変更し、計算された CQI、PMI、および時間 (スロット) と周波数 (サブバンド) にわたる RI 値の変化を観測できます。

参考文献

[1] 3GPP TS 38.214. "NR; Physical layer procedures for data." 3rd Generation Partnership Project; Technical Specification Group Radio Access Network.

ローカル関数

この例では、以下のローカル関数を使用して、CSI-RS 構成オブジェクトを検証し、計算された CQI、PMI、および RI 値をプロットします。

function validateCSIRSConfig(carrier,csirs,nTxAnts)
%   Validates the CSI-RS configuration, given the carrier specific
%   configuration object, CSI-RS configuration object, and the number of
%   transmit antennas.

    % Validate the number of CSI-RS ports
    if ~isscalar(unique(csirs.NumCSIRSPorts))
        error('nr5g:InvalidCSIRSPorts', ...
            'All the CSI-RS resources must be configured to have the same number of CSI-RS ports.');
    end

    % Validate the CDM lengths
    if ~iscell(csirs.CDMType)
        cdmType = {csirs.CDMType};
    else
        cdmType = csirs.CDMType;
    end
    if (~all(strcmpi(cdmType,cdmType{1})))
        error('nr5g:InvalidCSIRSCDMTypes', ...
            'All the CSI-RS resources must be configured to have the same CDM lengths.');
    end
    if nTxAnts ~= csirs.NumCSIRSPorts(1)
        error('nr5g:InvalidNumTxAnts',['Number of transmit antennas (' num2str(nTxAnts) ...
            ') must be equal to the number of CSI-RS ports (' num2str(csirs.NumCSIRSPorts(1)) ').']);
    end

    % Check for the overlap between the CSI-RS indices
    csirsInd = nrCSIRSIndices(carrier,csirs,"OutputResourceFormat",'cell');
    numRes = numel(csirsInd);
    csirsIndAll = cell(1,numRes);
    ratioVal = csirs.NumCSIRSPorts(1)/prod(getCDMLengths(csirs));
    for resIdx = 1:numRes
        if ~isempty(csirsInd{resIdx})
            grid = nrResourceGrid(carrier,csirs.NumCSIRSPorts(1));
            [~,tempInd] = nrExtractResources(csirsInd{resIdx},grid);
            if numel(tempInd)/numel(csirsInd{resIdx}) ~= ratioVal
                error('nr5g:OverlappedCSIRSREsSingleResource',['CSI-RS indices of resource ' ...
                    num2str(resIdx) ' must be unique. Try changing the symbol or subcarrier locations.']);
            end
            csirsIndAll{resIdx} = tempInd(:);
            for idx = 1:resIdx-1
                overlappedInd = ismember(csirsIndAll{idx},csirsIndAll{resIdx});
                if any(overlappedInd)
                    error('nr5g:OverlappedCSIRSREsMultipleResources',['The resource elements of the ' ...
                        'configured CSI-RS resources must not overlap. Try changing the symbol or ' ...
                        'subcarrier locations of CSI-RS resource ' num2str(idx) ' and resource ' num2str(resIdx) '.']);
                end
            end
        end
    end
end

function cdmLengths = getCDMLengths(csirs)
%   Returns the CDM lengths, given the CSI-RS configuration object.

    CDMType = csirs.CDMType;
    if ~iscell(csirs.CDMType)
        CDMType = {csirs.CDMType};
    end
    CDMTypeOpts = {'noCDM','fd-CDM2','CDM4','CDM8'};
    CDMLengthOpts = {[1 1],[2 1],[2 2],[2 4]};
    cdmLengths = CDMLengthOpts{strcmpi(CDMTypeOpts,CDMType{1})};
end

function [cqiPracticalPerSlot,subbandCQIPractical,pmiPracticalPerSlot,SINRPerSubbandPerCWPractical,cqiPerfectPerSlot, ...
    subbandCQIPerfect,pmiPerfectPerSlot,SINRPerSubbandPerCWPerfect,riPracticalPerSlot,riPerfectPerSlot] = fillInactiveSlots(cqiPracticalPerSlot, ...
    subbandCQIPractical,pmiPracticalPerSlot,SINRPerSubbandPerCWPractical,cqiPerfectPerSlot,subbandCQIPerfect,pmiPerfectPerSlot, ...
    SINRPerSubbandPerCWPerfect,riPracticalPerSlot,riPerfectPerSlot,reportConfig,totSlotsBinaryVec,activeSlots)
%   Returns the CQI, PMI, and RI related variables filled with NaNs in the
%   slots where NZP-CSI-RS is not present according to the codebook type from
%   the report configuration structure. Note that the CQI, PMI, and RI
%   variables are returned as empty if there are no NZP-CSI-RS resources,
%   that is, no active slots in the entire simulation duration.

    % Compute the indices of the slots and the number of slots in which
    % NZP-CSI-RS is not present
    inactiveSlotIdx = ~totSlotsBinaryVec;
    numInactiveSlots = nnz(inactiveSlotIdx);
    
    if ~isempty(activeSlots)
        numCQISBs = size(cqiPracticalPerSlot,1);
    
        % Get the codebook type
        codebookType = 'Type1SinglePanel';
        if isfield(reportConfig,'CodebookType')
            codebookType = validatestring(reportConfig.CodebookType,{'Type1SinglePanel','Type1MultiPanel','Type2','eType2'},'fillInactiveSlots','CodebookType field');
        end
    
        % Fill the CQI, PMI, and RI variables with NaNs in the slots where NZP-CSI-RS is
        % not present
        cqiPracticalPerSlot(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        subbandCQIPractical(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        SINRPerSubbandPerCWPractical(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        cqiPerfectPerSlot(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        subbandCQIPerfect(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        SINRPerSubbandPerCWPerfect(:,:,inactiveSlotIdx) = NaN(numCQISBs,2,numInactiveSlots);
        riPracticalPerSlot(inactiveSlotIdx) = NaN;
        riPerfectPerSlot(inactiveSlotIdx) = NaN;
    
        numi1Indices = 3;
        numi2Indices = 1;
        if strcmpi(codebookType,'Type1MultiPanel')
            numi1Indices = 6;
            numi2Indices = 3;
        end
        numPMISBs = size(pmiPerfectPerSlot(activeSlots(1)).i2,2);
        [pmiPerfectPerSlot(inactiveSlotIdx),pmiPracticalPerSlot(inactiveSlotIdx)] = deal(struct('i1',NaN(1,numi1Indices),'i2',NaN(numi2Indices,numPMISBs)));
    end
end

function plotWidebandCQIAndSINR(cqiPracticalPerSlot,cqiPerfectPerSlot,SINRPerSubbandPerCWPractical,SINRPerSubbandPerCWPerfect,activeSlotNum)
%   Plots the wideband SINR and wideband CQI values for each codeword
%   across all specified active slots (1-based) (in which the CQI is
%   reported as other than NaN) for practical and perfect channel
%   estimation cases.

    % Check if there are no slots in which NZP-CSI-RS is present
    if isempty(activeSlotNum)
        disp('No CQI data to plot, because there are no slots in which NZP-CSI-RS is present.');
        return;
    end
    cqiPracticalPerCW = permute(cqiPracticalPerSlot(1,:,:),[1 3 2]);
    cqiPerfectPerCW = permute(cqiPerfectPerSlot(1,:,:),[1 3 2]);
    SINRPerCWPractical = permute(SINRPerSubbandPerCWPractical(1,:,:),[1 3 2]);
    SINRPerCWPerfect = permute(SINRPerSubbandPerCWPerfect(1,:,:),[1 3 2]);

    % Extract wideband CQI indices for slots where NZP-CSI-RS is present
    cqiPracticalPerCWActiveSlots = cqiPracticalPerCW(1,activeSlotNum,:);
    cqiPerfectPerCWActiveSlots = cqiPerfectPerCW(1,activeSlotNum,:);
    widebandSINRPractical = 10*log10(SINRPerCWPractical(1,activeSlotNum,:));
    widebandSINRPerfect = 10*log10(SINRPerCWPerfect(1,activeSlotNum,:));

    if isempty(reshape(cqiPracticalPerCWActiveSlots(:,:,1),1,[]))
        disp('No CQI data to plot, because all CQI values are NaNs.');
        return;
    end

    figure();
    plotWBCQISINR(widebandSINRPerfect,widebandSINRPractical,211,activeSlotNum,'SINR');
    plotWBCQISINR(cqiPerfectPerCWActiveSlots,cqiPracticalPerCWActiveSlots,212,activeSlotNum,'CQI');
end

function plotWBCQISINR(perfectVals,practicalVals,subplotIdx,activeSlotNum,inpText)
%   Plots the wideband SINR and wideband CQI values for each codeword
%   across all specified active slots (1-based) (in which the CQI is
%   reported as other than NaN) for practical and perfect channel
%   estimation cases.

    subplot(subplotIdx)
    plot(perfectVals(:,:,1),'r-o');
    hold on;
    plot(practicalVals(:,:,1),'b-*');
    if ~all(isnan(perfectVals(:,:,2))) % Two codewords
        hold on;
        plot(perfectVals(:,:,2),'r:s');
        hold on;
        plot(practicalVals(:,:,2),'b:d');
        title(['Wideband ' inpText ' Values for Codeword 1&2']);
        legend({'Codeword 1:Perfect channel est.','Codeword 1:Practical channel est.','Codeword 2:Perfect channel est.','Codeword 2:Practical channel est.'});
    else
        title(['Wideband ' inpText ' Values for Codeword 1']);
        legend({'Codeword 1:Perfect channel est.','Codeword 1:Practical channel est.'});
    end
    xlabel('Slots');
    if strcmpi(inpText,'SINR')
        units = ' in dB';
    else
        units = '';
    end
    ylabel(['Wideband ' inpText ' Values' units]);
    xticks(1:size(perfectVals,2));
    xTickLables = num2cell(activeSlotNum(:)-1);
    xticklabels(xTickLables);
    [lowerBound,upperBound] = bounds([practicalVals(:);perfectVals(:)]);
    ylim([lowerBound-1 upperBound+3.5]);
end

function plotSubbandCQIAndSINR(subbandCQIPractical,subbandCQIPerfect,SINRPerCWPractical,SINRPerCWPerfect,activeSlotNum,nslot)
%   Plots the SINR and CQI values for each codeword across all the subbands
%   for practical and perfect channel estimation cases for the given slot
%   number (0-based) among all specified active slots (1-based). The
%   function does not plot the values if CQIMode is 'Wideband' or if the
%   CQI and SINR values are all NaNs in the given slot.

    % Check if there are no slots in which NZP-CSI-RS is present
    if isempty(activeSlotNum)
        disp('No CQI data to plot, because there are no slots in which NZP-CSI-RS is present.');
        return;
    end
    numSubbands = size(subbandCQIPractical,1);
    if numSubbands > 1 && ~any(nslot+1 == activeSlotNum) % Check if the CQI values are reported in the specified slot
        disp(['For the specified slot (' num2str(nslot) '), CQI values are not reported. Please choose another slot number.']);
        return;
    end

    % Plot subband CQI values
    if numSubbands > 1 % Subband mode
        subbandCQIPerCWPractical = subbandCQIPractical(2:end,:,nslot+1);
        subbandCQIPerCWPerfect = subbandCQIPerfect(2:end,:,nslot+1);
        subbandSINRPerCWPractical = 10*log10(SINRPerCWPractical(2:end,:,nslot+1));
        subbandSINRPerCWPerfect = 10*log10(SINRPerCWPerfect(2:end,:,nslot+1));
        figure();
        plotSBCQISINR(subbandSINRPerCWPerfect,subbandSINRPerCWPractical,numSubbands,211,nslot,'SINR')
        plotSBCQISINR(subbandCQIPerCWPerfect,subbandCQIPerCWPractical,numSubbands,212,nslot,'CQI');
    end
end

function plotSBCQISINR(perfectVals,practicalVals,numSubbands,subplotIdx,nslot,inpText)
%   Plots the SINR and CQI values for each codeword across all the subbands
%   for practical and perfect channel estimation cases for the given slot
%   number (0-based). The function does not plot the values if CQIMode is
%   'Wideband' or if the CQI and SINR values are all NaNs in the given
%   slot.

    subplot(subplotIdx)
    plot(perfectVals(:,1),'ro-');
    hold on;
    plot(practicalVals(:,1),'b*-');
    if ~all(isnan(perfectVals(:,2))) % Two codewords
        hold on;
        plot(perfectVals(:,2),'rs:');
        hold on;
        plot(practicalVals(:,2),'bd:');
        legend({'Codeword 1:Perfect channel est.','Codeword 1:Practical channel est.','Codeword 2:Perfect channel est.','Codeword 2:Practical channel est.'});
        title(['Estimated Subband ' inpText ' Values for Codeword 1&2 in Slot ' num2str(nslot)]);
    else % Single codeword
        legend({'Codeword 1:Perfect channel est.','Codeword 1:Practical channel est.'});
        title(['Estimated Subband ' inpText ' Values for Codeword 1 in Slot ' num2str(nslot)]);
    end

    if strcmpi(inpText,'SINR')
        units = ' in dB';
    else
        units = '';
    end
    xlabel('Subbands');
    ylabel(['Subband ' inpText ' Values' units]);
    xticks(1:numSubbands);
    xTickLables = num2cell(1:numSubbands);
    xticklabels(xTickLables);
    xlim([0 numSubbands+1]);
    [lowerBound,upperBound] = bounds([perfectVals(:);practicalVals(:)]);
    ylim([lowerBound-1 upperBound+3.5]);
end

function plotType1PMIAndRI(pmiPracticalPerSlot,pmiPerfectPerSlot,riPracticalPerSlot,riPerfectPerSlot,activeSlotNum,nslot)
%   Plots the RI and PMI i1 indices across all specified active slots
%   (1-based), for practical and perfect channel estimation scenarios. The
%   function also plots the i2 indices of practical and perfect channel
%   estimation scenarios across all specified active slots when the PMI
%   mode is 'Wideband' or plots i2 indices across all the subbands for the
%   specified slot number (0-based) when the PMI mode is 'Subband'.

    % Check if there are no slots in which NZP-CSI-RS is present
    if isempty(activeSlotNum)
        disp('No PMI and RI data to plot, because there are no slots in which NZP-CSI-RS is present.');
        return;
    end
    
    numi1Indices = numel(pmiPracticalPerSlot(activeSlotNum(1)).i1);
    if numi1Indices == 6
        codebookType = 'Type1MultiPanel';
    else
        codebookType = 'Type1SinglePanel';
    end
    
    % Extract wideband PMI indices (i1 values) for slots where NZP-CSI-RS
    % is present
    i1PerfectValsActiveSlots = reshape([pmiPerfectPerSlot(activeSlotNum).i1],numi1Indices,[])';
    i1PracticalValsActiveSlots = reshape([pmiPracticalPerSlot(activeSlotNum).i1],numi1Indices,[])';
    
    if isempty(i1PerfectValsActiveSlots)
        disp('No PMI and RI data to plot, because all PMI and RI values are NaNs.');
        return;
    end
    
    figure;
    % Plot RI
    plotRI(riPracticalPerSlot,riPerfectPerSlot,activeSlotNum,411);
    
    % Extract and plot i11 indices
    i11PerfectVals = i1PerfectValsActiveSlots(:,1);
    i11PracticalVals = i1PracticalValsActiveSlots(:,1);
    plotIxxIndices(i11PerfectVals,i11PracticalVals,activeSlotNum,412,'i11');

    % Extract and plot i12 indices
    i12PerfectVals = i1PerfectValsActiveSlots(:,2);
    i12PracticalVals = i1PracticalValsActiveSlots(:,2);
    plotIxxIndices(i12PerfectVals,i12PracticalVals,activeSlotNum,413,'i12');

    % Extract and plot i13 indices
    i13PerfectVals = i1PerfectValsActiveSlots(:,3);
    i13PracticalVals = i1PracticalValsActiveSlots(:,3);
    plotIxxIndices(i13PerfectVals,i13PracticalVals,activeSlotNum,414,'i13');
    
    % Plot the i141, i142 and i143 indices in type I multi-panel case
    if strcmpi(codebookType,'Type1MultiPanel')
        figure()
        % Extract and plot i141 indices
        i141PerfectVals = i1PerfectValsActiveSlots(:,4);
        i141PracticalVals = i1PracticalValsActiveSlots(:,4);
        plotIxxIndices(i141PerfectVals,i141PracticalVals,activeSlotNum,311,'i141');

        % Extract and plot i142 indices
        i142PerfectVals = i1PerfectValsActiveSlots(:,5);
        i142PracticalVals = i1PracticalValsActiveSlots(:,5);
        plotIxxIndices(i142PerfectVals,i142PracticalVals,activeSlotNum,312,'i142');
    
        % Extract and plot i143 indices
        i143PerfectVals = i1PerfectValsActiveSlots(:,6);
        i143PracticalVals = i1PracticalValsActiveSlots(:,6);
        plotIxxIndices(i143PerfectVals,i143PracticalVals,activeSlotNum,313,'i143');
    end

    % Get the number of subbands
    numSubbands = size(pmiPracticalPerSlot(activeSlotNum(1)).i2,2);
    % Get the number of i2 indices according to codebook type
    numi2Indices = 1;
    if strcmpi(codebookType,'Type1MultiPanel')
        numi2Indices = 3;
    end

    % Get number of active slots
    numActiveSlots = numel(activeSlotNum);
    % Extract i2 values
    i2PerfectVals = reshape([pmiPerfectPerSlot(activeSlotNum).i2],[numSubbands,numi2Indices,numActiveSlots]);     % Of size numActiveSlots-by-numi2Indices-numSubbands
    i2PracticalVals = reshape([pmiPracticalPerSlot(activeSlotNum).i2],[numSubbands,numi2Indices,numActiveSlots]); % Of size numActiveSlots-by-numi2Indices-numSubbands

    % Plot i2 values
    if numSubbands == 1 % Wideband mode
        figure;

        % In type I single-panel case, there is only one i2 index. The
        % first column of i2PerfectVals and i2PracticalVals corresponds to
        % i2 index. In type I multi-panel case, the i2 values are a set of
        % three indices i20, i21, and i22. Each column of i2PerfectVals and
        % i2PracticalVals correspond to i20, i21, and i22 indices. Extract
        % and plot the respective index values
        if strcmpi(codebookType,'Type1SinglePanel')
            % Extract and plot i2 values in each slot
            i2PerfectVals = reshape(i2PerfectVals(:,1,:),[],numActiveSlots).';
            i2PracticalVals = reshape(i2PracticalVals(:,1,:),[],numActiveSlots).';
            plotIxxIndices(i2PerfectVals,i2PracticalVals,activeSlotNum,111,'i2');
        else
            % Extract and plot i20 values in each slot
            i20PerfectVals = reshape(i2PerfectVals(:,1,:),[],numActiveSlots).';
            i20PracticalVals = reshape(i2PracticalVals(:,1,:),[],numActiveSlots).';
            plotIxxIndices(i20PerfectVals,i20PracticalVals,activeSlotNum,311,'i20');

            % Extract and plot i21 values in each slot
            i21PerfectVals = reshape(i2PerfectVals(:,2,:),[],numActiveSlots).';
            i21PracticalVals = reshape(i2PracticalVals(:,2,:),[],numActiveSlots).';
            plotIxxIndices(i21PerfectVals,i21PracticalVals,activeSlotNum,312,'i21');

            % Extract and plot i22 values in each slot
            i22PerfectVals = reshape(i2PerfectVals(:,3,:),[],numActiveSlots).';
            i22PracticalVals = reshape(i2PracticalVals(:,3,:),[],numActiveSlots).';
            plotIxxIndices(i22PerfectVals,i22PracticalVals,activeSlotNum,313,'i22');
        end
    else % Subband mode
        if any(nslot+1 == activeSlotNum)
    
            % In subband mode, plot the PMI i2 indices corresponding to the
            % specified slot number
            figure;

            if strcmpi(codebookType,'Type1SinglePanel')
                % Extract and plot i2 values
                pmiSBi2Perfect = pmiPerfectPerSlot(nslot+1).i2(1,:);
                pmiSBi2Practical = pmiPracticalPerSlot(nslot+1).i2(1,:);
                plotI2xIndices_SB(pmiSBi2Perfect,pmiSBi2Practical,numSubbands,nslot,111,'i2');
            else
                % Extract and plot i20 values
                pmiSBi20Perfect = pmiPerfectPerSlot(nslot+1).i2(1,:);
                pmiSBi20Practical = pmiPracticalPerSlot(nslot+1).i2(1,:);
                plotI2xIndices_SB(pmiSBi20Perfect,pmiSBi20Practical,numSubbands,nslot,311,'i20');
                
                % Extract and plot i21 values
                pmiSBi21Perfect = pmiPerfectPerSlot(nslot+1).i2(2,:);
                pmiSBi21Practical = pmiPracticalPerSlot(nslot+1).i2(2,:);
                plotI2xIndices_SB(pmiSBi21Perfect,pmiSBi21Practical,numSubbands,nslot,312,'i21');
    
                % Extract and plot i22 values
                pmiSBi22Perfect = pmiPerfectPerSlot(nslot+1).i2(3,:);
                pmiSBi22Practical = pmiPracticalPerSlot(nslot+1).i2(3,:);
                plotI2xIndices_SB(pmiSBi22Perfect,pmiSBi22Practical,numSubbands,nslot,313,'i22');
            end
        else
            disp(['For the specified slot (' num2str(nslot) '), PMI i2 indices are not reported. Please choose another slot number.'])
        end
    end
end

function plotType2PMIAndRI(pmiPracticalPerSlot,pmiPerfectPerSlot,riPracticalPerSlot,riPerfectPerSlot,panelDims,numBeams,activeSlotNum,nslot)
%   Plots the grid of beams by highlighting the beams that are used for the
%   precoding matrix generation for the specified slot number (0-based),
%   for practical and perfect channel estimation scenarios.

    % Check if there are no slots in which NZP-CSI-RS is present
    if isempty(activeSlotNum)
        disp('No PMI and RI data to plot, because there are no slots in which NZP-CSI-RS is present.');
        return;
    end
    plotRI(riPracticalPerSlot,riPerfectPerSlot,activeSlotNum,111);
    if ~any(nslot+1 == activeSlotNum)
        disp(['For the specified slot (' num2str(nslot) '), PMI values are not reported. Please choose another slot number.']);
    else
        pmiPractical = pmiPracticalPerSlot(nslot+1);
        pmiPerfect = pmiPerfectPerSlot(nslot+1);
        figure();
        plotType2GridOfBeams(pmiPractical,panelDims,numBeams,'Practical Channel Estimation Scenario',1);
        hold on;
        plotType2GridOfBeams(pmiPerfect,panelDims,numBeams,'Perfect Channel Estimation Scenario',2);
    end
end

function plotRI(riPracticalPerSlot,riPerfectPerSlot,activeSlotNum,subplotIndex)
%   Plots the RI values across all specified active slots (1-based), for
%   practical and perfect channel estimation scenarios.

    % Get number of active slots
    numActiveSlots = numel(activeSlotNum);

    % Extract RI values for slots where NZP-CSI-RS is present
    RIPerfectValsActiveSlots = riPerfectPerSlot(activeSlotNum)';
    RIPracticalValsActiveSlots = riPracticalPerSlot(activeSlotNum)';
    
    if isempty(RIPerfectValsActiveSlots)
        disp('No RI data to plot, because all RI values are NaNs.');
        return;
    end
    
    figure;
    subplot(subplotIndex);
    plot(RIPerfectValsActiveSlots,'r-o');
    hold on;
    plot(RIPracticalValsActiveSlots,'b-*');
    xlabel('Slots')
    ylabel('RI Values');
    xticks(1:numActiveSlots);
    xTickLables = num2cell(activeSlotNum(:)-1);
    xticklabels(xTickLables);
    [~,upperBound] = bounds([RIPerfectValsActiveSlots; RIPracticalValsActiveSlots]);
    xlim([0 numActiveSlots+8]);
    ylim([0 upperBound+1]);
    yticks(0:upperBound+1);
    title('RI Values')
    legend({'Perfect channel est.','Practical channel est.'});
end

function plotType2GridOfBeams(PMISet,panelDims,numBeams,chEstType,subplotNum)
%   Plots the grid of beams by highlighting the beams that are used for the
%   type II codebook based precoding matrix generation.

    N1 = panelDims(1);
    N2 = panelDims(2);    
    % Get the oversampling factors
    O1 = 4;
    O2 = 1 + 3*(N2 ~= 1);

    % Extract q1, q2 values
    qSet = PMISet.i1(1:2);
    q1 = qSet(1)-1;
    q2 = qSet(2)-1;

    % Extract i12 value
    i12 = PMISet.i1(3);
    s = 0;
    % Find the n1, n2 values for all the beams, as defined in TS 38.214
    % Section 5.2.2.2.3
    n1_i12 = zeros(1,numBeams);
    n2_i12 = zeros(1,numBeams);
    for beamIdxI = 0:numBeams-1
        i12minussVal = i12 - s;
        xValues = numBeams-1-beamIdxI:N1*N2-1-beamIdxI;
        CValues = zeros(numel(xValues),1);
        for xIdx = 1:numel(xValues)
            if xValues(xIdx) >= numBeams-beamIdxI
                CValues(xIdx) = nchoosek(xValues(xIdx),numBeams-beamIdxI);
            end
        end
        indices = i12minussVal >= CValues;
        maxIdx = find(indices,1,'last');
        xValue = xValues(maxIdx);
        ei = CValues(maxIdx);
        s = s+ei;
        ni = N1*N2 - 1 - xValue;
        n1_i12(beamIdxI+1) = mod(ni,N1);
        n2_i12(beamIdxI+1) = (ni-n1_i12(beamIdxI+1))/N1;
    end
    m1 = O1*(0:N1-1) + q1;
    m2 = O2*(0:N2-1) + q2;

    % Calculate the indices of orthogonal basis set which corresponds to
    % the reported i12 value
    m1_LBeams = O1*(n1_i12) + q1;
    m2_LBeams = O2*(n2_i12) + q2;
    OrthogonalBeams = [repmat(m1,1,length(m2));reshape(repmat(m2,length(m1),1),1,[])]';

    % Plot the grid of beams
    numCirlcesInRow = N1*O1;
    numCirlcesInCol = N2*O2;
    subplot(2,1,subplotNum);
    circleRadius = 1;
    for colIdx = 0:numCirlcesInCol-1
        for rowIdx = 0:numCirlcesInRow-1
            p = nsidedpoly(1000, 'Center', [2*rowIdx 2*colIdx], 'Radius', circleRadius);
            if any(prod(OrthogonalBeams == [rowIdx colIdx],2))
                h2 = plot(p, 'FaceColor', 'w','EdgeColor','r','LineWidth',2.5);
                hold on;
                if any(prod([m1_LBeams' m2_LBeams'] == [rowIdx colIdx],2))
                    h3 = plot(p, 'FaceColor', 'g','LineStyle','-.');                
                end
            else
                h1 = plot(p, 'FaceColor', 'w');
            end
            hold on;
        end
    end
    rowLength = 2*circleRadius*O1;
    colLength = 2*circleRadius*O2;
    for n2 = 0:N2-1
        for n1 = 0:N1-1
            x1 = -1*circleRadius + rowLength*n1;
            x2 = x1 + rowLength;
            y1 = -1*circleRadius + colLength*n2;
            y2 = y1 + colLength;
            x = [x1, x2, x2, x1, x1];
            y = [y1, y1, y2, y2, y1];
            plot(x, y, 'b-', 'LineWidth', 2);
            hold on;
        end
    end
    
    xlabel('N1O1 beams');
    ylabel('N2O2 beams');
    axis equal;
    set(gca,'xtick',[],'ytick',[]);
    legend([h1 h2 h3],{'Oversampled DFT beams',['Orthogonal basis set with [q1 q2] = [' num2str(q1) ' ' num2str(q2) ']'],'Selected beam group'},'Location','northeast');
    title(['Grid of Beams or DFT Vectors for ' chEstType]);
end

function plotIxxIndices(ixxPerfectVals,ixxPracticalVals,activeSlotNum,subplotInp,pmiIdxType)
%   Plots i11, i12, i13 indices in case of type I single-panel codebooks
%   and plots i141, i142, and i143 in case of type I multi-panel codebooks.

    % Plot ixx values
    subplot(subplotInp)
    plot(ixxPerfectVals,'r-o');
    hold on;
    plot(ixxPracticalVals,'b-*');
    xlabel('Slots')
    ylabel([pmiIdxType ' Indices']);
    % Get number of active slots
    numActiveSlots = numel(activeSlotNum);
    xticks(1:numActiveSlots);
    xTickLables = num2cell(activeSlotNum(:)-1);
    xticklabels(xTickLables);
    [lowerBound,upperBound] = bounds([ixxPerfectVals; ixxPracticalVals]);
    xlim([0 numActiveSlots+8]);
    ylim([lowerBound-2 upperBound+2]);
    title(['PMI: ' pmiIdxType ' Indices']);
    legend({'Perfect channel est.','Practical channel est.'});
end

function plotI2xIndices_SB(pmiSBi2Perfect,pmiSBi2Practical,numSubbands,nslot,subplotInp,pmiIdxType)
%   Plots i2 indices in case of type I single-panel codebooks and plots
%   i20, i21, and i22 in case of type I multi-panel codebooks.

    subplot(subplotInp)
    plot(pmiSBi2Perfect,'r-o');
    hold on;
    plot(pmiSBi2Practical,'b-*');
    title(['PMI: ' pmiIdxType ' Indices for All Subbands in Slot ' num2str(nslot)]);
    xlabel('Subbands')
    ylabel([pmiIdxType ' Indices']);
    xticks(1:numSubbands);
    xticklabels(num2cell(1:numSubbands));
    [lowerBound,upperBound] = bounds([pmiSBi2Perfect pmiSBi2Practical]);
    yticks(lowerBound:upperBound);
    yticklabels(num2cell(lowerBound:upperBound));
    xlim([0 numSubbands+1])
    ylim([lowerBound-1 upperBound+1]);
    legend({'Perfect channel est.','Practical channel est.'});
end

参考

関数

オブジェクト

関連するトピック