配列引数を使用した FFT 関数は、HLS 名前空間で定義され、次のように呼び出すことができます。
hls::fft<STATIC_PARAM> (
INPUT_DATA_ARRAY,
OUTPUT_DATA_ARRAY,
OUTPUT_STATUS,
INPUT_RUN_TIME_CONFIGURATION);
STATIC_PARAM
は、FFT のスタティック パラメーターを定義するスタティック パラメーター指定構造体です。
入力データおよび出力データは、配列 (INPUT_DATA_ARRAY
および OUTPUT_DATA_ARRAY
) として関数に供給されます。最終的なインプリメンテーションでは、FFT RTL ブロックのポートは AXI4-Stream ポートとしてインプリメントされます。AMD では、次を推奨しています。
set_directive_dataflow
) を使用したデータフロー領域では常に FFT 関数を使用し、set_directive_stream
コマンドを使用して両方の配列をストリーミングとして指定することを勧めします。FFT は、パイプラインされた領域では使用できません。特に、データを処理せずに FFT が停止するクロック サイクルを回避することで、パフォーマンスの優れた演算が必要な場合は、次のようにする必要があります。 - FFT を含むデザイン階層全体、および FFT より上位の階層は、データフロー領域か、dataflow-in-loop のみを含む関数のいずれかである必要があります。
- 協調シミュレーションのデッドロック検出 で説明するように、すべての FIFO には、協調シミュレーションでブロッキングを避けるのに十分な深さが必要です。
- 階層構造のすべてのデータフロー プロセスに含めるのは、次のものだけです。
- rewind オプションを使用したパイプライン
- または、rewind オプションを使用したパイプライン処理済みループ
配列のデータ型は、float
または ap_fixed
のいずれかにできます。
typedef float data_t;
complex<data_t> in_fft[FFT_LENGTH];
complex<data_t> out_fft[FFT_LENGTH];
固定小数点型を使用する場合は、Vitis HLS 任意精度型 ap_fixed
を使用する必要があります。
#include "ap_fixed.h"
typedef ap_fixed<FFT_INPUT_WIDTH,1> data_in_t;
typedef ap_fixed<FFT_OUTPUT_WIDTH,FFT_OUTPUT_WIDTH-FFT_INPUT_WIDTH+1> data_out_t;
#include <complex>
typedef hls::x_complex<data_in_t> cmpxData;
typedef hls::x_complex<data_out_t> cmpxDataOut;
どちらの場合でも、FFT のパラメーターを同じ正しいデータ サイズに指定する必要があります。浮動小数点型の場合、データ幅は常に 32 ビットで、その他のサイズを指定しても無効と判断されます。
マルチチャネル FFT
FFT のマルチチャネル機能は、入力データと出力データの 2 次元配列を使用すると使用できます。この場合、最初の次元が各チャネル、2 つ目の次元が FFT データを表すように配列データを設定する必要があります。
typedef float data_t;
static complex<data_t> in_fft[FFT_CHANNELS][FFT_LENGTH];
static complex<data_t> out_fft[FFT_CHANNELS][FFT_LENGTH];
FFT コアは、データをインターリーブされたチャネル (たとえば、ch0-data0、ch1-data0、ch2-data0 など、ch0-data1、ch1-data1、ch2-data1、など) として生成および消費します。このため、FFT の入力配列または出力配列をデータを読み出しおよび書き込みするのと同じ順序でストリーミングするには、次の例に示すように、まずチャネル インデックスを順に処理することにより、複数のチャネルの 2 次元配列を充填または空にする必要があります。
cmpxData in_fft[FFT_CHANNELS][FFT_LENGTH];
cmpxData out_fft[FFT_CHANNELS][FFT_LENGTH];
// Read data into FFT Input Array
for (unsigned i = 0; i < FFT_LENGTH; i++) {
for (unsigned j = 0; j < FFT_CHANNELS; ++j) {
in_fft[j][i] = in.read();
}
}
// Write data out from FFT Output Array
for (unsigned i = 0; i < FFT_LENGTH; i++) {
for (unsigned j = 0; j < FFT_CHANNELS; ++j) {
out.write(out_fft[j][i]);
}
}