制御ロジックの抽出と I/O ポートのインプリメント例 - 2023.2 日本語

Vitis 高位合成ユーザー ガイド (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 日本語

次の図に、ここに示すコード例の制御ロジックの抽出と I/O ポートのインプリメンテーションを示します。


void foo(int in[3], char a, char b, char c, int out[3]) {
  int x,y;
  for(int i = 0; i < 3; i++) {
    x = in[i]; 
    y = a*x + b + c; 
    out[i] = y;
  }
}
図 1. 制御ロジックの抽出と I/O ポートのインプリメンテーションの例

このコード例では前の例と同じ演算が実行されますが、演算が for ループ内で実行され、関数引数のうちの 2 つが配列である点が異なります。結果のデザインでは、コードがスケジューリングされたときに for ループ内のロジックが 3 回実行されます。高位合成では C コードから制御ロジックが自動的に抽出され、RTL デザインでこれらの演算を順序付ける有限ステート マシン (FSM) が作成されます。最終的な RTL デザインでは、最上位関数の引数がポートになります。char 型のスカラー変数は標準の 8 ビット データ バス ポートにマップされます。in および out などの配列引数には、データ コレクション全体が含まれます。

高位合成では、配列はデフォルトでブロック RAM に合成されますが、FIFO、分散 RAM、個別のレジスタなどに合成することも可能です。最上位関数で配列を引数として使用すると、ブロック RAM が最上位関数外にあると想定され、データ ポート、アドレス ポート、必要なチップ イネーブルまたはライト イネーブル信号など、デザイン外のブロック RAM にアクセスするためのポートが自動的に作成されます。

FSM では、データをいつレジスタに格納するかと、I/O 制御信号のステートが制御されます。FSM は C0 ステートで開始し、次のクロックで C1 ステートに遷移し、その後 C2 ステート、C3 ステートに遷移します。そして C1 (および C2C3) を 3 回反復してから、C0 ステートに戻ります。

注記: これは、C コードの for ループの制御構造と類似しています。ステートの完全なシーケンスでは、C0{C1, C2, C3}{C1, C2, C3}{C1, C2, C3} の後、C0 に戻ります。

bc の加算が必要なのは 1 回だけなので、この演算は for ループ外に出され、C0 ステートに挿入されます。この加算結果は、C3 ステートに遷移するたびに再利用されます。

デザインでは in のデータが読み出され、x に格納されます。FSM の C1 で最初の要素のアドレスが生成されます。また、C1 ステートでは、C1C2C3 ステートを何回反復する必要があるのかを知るために、加算器がインクリメントされます。C2 ステートでは、ブロック RAM から in のデータが返され、変数 x として格納されます。

計算に必要なその他の値が a ポートから読み出され、最初の y 出力が生成されます。FSM で正しいアドレスと制御信号が生成され、この値がブロック外に格納されます。この後デザインは C1 ステートに戻り、配列/ブロック RAM の in から次の値が読み出されます。このプロセスは、すべての出力が書き込まれるまで継続されます。そして C0 ステートに戻り、bc の次の値が読み出されて、プロセスが再度実行されます。