サンプル ベースの C コード
次にサンプル ベースの C コードの例を示します。このコード形式の主な特徴は、トランザクションごとに関数で 1 つのデータ サンプルが処理されることです。
void foo (data_t *in, data_t *out) {
static data_t acc;
Loop1: for (int i=N-1;i>=0;i--) {
acc+= ..some calculation..;
}
*out=acc>>N;
}
サンプル ベースのコード形式では、関数にスタティック変数が含まれることがよくあります。スタティック変数の値は、アキュムレータやサンプル カウンターなど、関数呼び出し間で保持される必要があります。
サンプル ベースのコードを使用すると、PIPELINE 指示子の位置が明確になり、II = 1 を達成して、クロック サイクルごとに 1 つのデータ値が処理されるようにできます。このためには、関数のパイプライン処理が必要です。
パイプライン処理により関数内のループがすべて展開され、追加ロジックが作成されますが、これを回避する方法はありません。Loop1 がパイプライン処理されると、完了するのに最低でも N クロック サイクルかかります。この後にのみ、関数は次の x 入力値を読み込むことができます。
サンプル レベルで動作する C コードを使用する際は、常に関数をパイプライン処理するようにします。
このタイプのコード形式では、ループは通常配列に対して実行され、シフト レジスタまたはライン バッファー関数が実行されます。パフォーマンスのための構造最適化に示すように、これらの配列を個別のエレメントに分割し、すべてのサンプルが 1 クロック サイクルでシフトされるようにするのが一般的な方法です。配列がブロック RAM にインプリメントされる場合、各クロック サイクルで読み込みまたは書き出しできるのは最大 2 サンプルだけなので、これがデータ処理のボトルネックとなります。
この例でのソリューションは、関数 foo をパイプライン処理することです。これにより、クロックごとに 1 サンプル処理するデザインが得られます。