サンプル ベースの 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 サンプル処理するデザインが得られます。