カーネル デザインの詳細

AI エンジンへのビームフォーミングの実装 (XAPP1352)

Document ID
XAPP1352
Release Date
2021-01-11
Revision
1.0 日本語

今回提案するビームフォーミング アーキテクチャの 1 つの特長は、ごくわずかなカーネルだけでさまざまな種類のシステム構成に対応できるという点です。たとえば、5G NR 100MHz システムでは 図 1 に示したすべてのビームフォーマーを次の図に示すように 3 個のカーネルで実装できます。これらのカーネルを、カスケード接続チェーン内の位置に応じて「最初のカーネル」、「中央のカーネル」、「最後のカーネル」と呼ぶことにします。いずれのカーネルも (8 x 8) x (8 x 12) の行列乗算を実装しており、違うのは入力および出力インターフェイスのみです。カスケード接続チェーンの最初のカーネルにはカスケード入力がありません。また、最後のカーネルはカスケード接続バスではなくローカル メモリに出力を書き込みます。

図 1. 5G NR ビームフォーミングに必要な 3 個のカーネル

いずれのビームフォーミング カーネルも 1 列分 (8 個) の入力 {x0, x1, x2, …, x7} に対して 8 回の MAC4 演算を実行し、8 つの出力 {y0, y1, y2, …, y7} を計算します。各 MAC4 演算は 8 つの係数と 2 つの入力に対して実行され、この結果が 384 ビットのレジスタに格納されます。{y0, …, y3} と {y4, …, y7} に 2 つの累算レジスタが割り当てられます。計算が終わると、部分和が次の AI エンジンに送られてさらに累算が実行されるか、またはシフト、丸め、飽和の後にローカル メモリに出力されます。次の図に、このプロセスを示します。これは、同じ係数行列を共有するすべてのサブキャリアが処理されるまで L 回繰り返されます。

図 2. 入力データ x0 と x1 に対する 2 回の mul4 演算
図 3. 入力データ x2 と x3 に対する 2 回の mac4 演算
図 4. 入力データ x4 と x5 に対する 2 回の mac4 演算
図 5. 入力データ x6 と x7 に対する 2 回の mac4 演算

次に、bf8x8_fst カーネルの内周ループのタイミング図を示します。ループの前に、レジスタ bufa および bufb は前半部の係数 {h0, h1, …, h31} で初期化されます。1 列分の入力データ {x0, x1, … x7} がレジスタ dat にロードされます。ループの最初の 4 サイクルで、前半部の係数に対する MAC 演算が実行され、それと並行して後半部の係数がレジスタにロードされます。クロック サイクル 7 で {y0, y1, y2, y3} が計算され、カスケード接続バスを介して次の AI エンジンに送られます。同様に、次のサイクルで {y4, y5, y6, y7} が送られます。クロック サイクル 9 ~ 16 では、次の 8 個のデータに対して逆順で計算が実行されます。まず、既にレジスタに格納されている後半部の係数に対して MAC 演算が実行され、サイクル 13 と 14 で前半部の係数がロードされます。内周ループには 16 クロック サイクルがかかり、この期間に 16 回の mul4/mac4 演算、10 回のメモリ ロード、およびカスケード接続バスへの 4 回の転送が並列に実行されます。ベクター プロセッサは、アイドル サイクルなしに常に演算を実行します。L 個のサブキャリアに対して、内周ループは L/2 回の反復を実行します。

図 6. カーネル bf8x8_fst の内周ループのタイミング図

カーネル bf8x8_mid は直前の AI エンジンから部分和を読み出した後、最初の MAC 演算を開始します。次の C コードで、組み込み関数 get_scd() はカスケード接続バスのデータを累算レジスタにロードし、組み込み関数 mac4() はアイドル クロック サイクルなしに累算を再開します。

acca = mac4(getc_scd(), bufa, 0, 0x3210, 8, dat, 0, 0x0000, 1); 
accb = mac4(getc_scd(), bufa, 4, 0x3210, 8, dat, 0, 0x0000, 1);

カーネル bf8x8_lst は、最終的な計算結果をローカル メモリに書き込みます。ベクター {y0, y1, …, y7} は 256 ビットで、768 ビット 8 レーン累算レジスタからデータを取得する場合、1 クロック サイクルでメモリに書き込むことができます。1 回の mac4 演算では 4 レーンしか更新されないため、組み込み関数 ext_loext_hiupd_lo、および upd_hi が必要です。ほかのカーネルとの比較のため、次にループの最初の 4 つの命令を示します。

acc = upd_lo(acc, mac4(getc_scd(),  bufa, 0, 0x3210, 8, dat, 0,0x0000, 1));
acc = upd_hi(acc, mac4(getc_scd(),  bufa, 4, 0x3210, 8, dat, 0,0x0000, 1));
acc = upd_lo(acc, mac4(ext_lo(acc), bufb, 0, 0x3210, 8, dat, 2,0x0000, 1));
acc = upd_hi(acc, mac4(ext_hi(acc), bufb, 4, 0x3210, 8, dat, 2,0x0000, 1));