0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[高位合成] IFプロトコルの話

Posted at

IFの説明

高位合成では複数のIFが用意されてあります。
なので今回はIFの説明になります。

概要

一口にIFと言っても複数あります。大きく分けると以下です。

  • ポートレベルのIF
  • バス(AXI)のIF
  • ブロックレベルのIF

そのうちバス以外のIFについて説明します。バスは別途します。

早速説明する前に、そもそもポートレベルとブロックレベルのIFとは何を指しているのかを説明します。

ポートレベルのIFとは

関数の入出力信号のプロトコルになります。
例えば以下のコードがあった場合、

void function(int a, int b, int* c)
{

}

aとbとcに対するプロトコルになります。
このように普通に書くとプロトコルなしの信号になります。言い換えるとデータ線のみになります。

ブロックレベルのIFとは

モジュールに対しての制御プロトコルになります。
先ほどと同じコードを例にすると、こちらはfuctionモジュールに対してのプロトコルになります。

ポートレベルでのプロトコル

ポートレベルのIFですが、大きく3つのカテゴリーがあります。

  • レジスタ
  • ストリーム
  • メモリ

順に説明してきます。

また、プロトコルの指定の仕方ですが、#pragma HLS interfaceで指定します。

レジスタ系

スカラーデータがこれに当てはまります。

プラグマ:#pragma HLS interface ap_none port = xxx
プロトコル:プロトコルなし
説明:単純なデータ線のみの信号(つまりソースコードに書いた信号のみ)
例:

void function(uint16_t a, uint16_t* b)
{
#pragma HLS interface ap_none      port = a
#pragma HLS interface ap_none      port = b
#pragma HLS interface ap_ctrl_none port = return

    *b = a * 10;
}

SCR-20250525-skeg.png


プラグマ:#pragma HLS interface ap_vld port = xxx
プロトコル:valid信号あり
説明:データ線にvalid信号を付与する
例:

void function(uint16_t a, uint16_t *b)
{
#pragma HLS interface ap_vld       port = a
#pragma HLS interface ap_vld       port = b
#pragma HLS interface ap_ctrl_none port = return

    *b = a * 10;
}

SCR-20250525-smqd.png


プラグマ:#pragma HLS interface ap_ovld port = xxx
プロトコル:valid信号あり(入出力信号)
説明:出力のデータ線にvalid信号を付与され、入力のデータ線にはap_noneが適用される。
例:

void function(uint16_t a, uint16_t *b)
{
#pragma HLS interface ap_none      port = a
#pragma HLS interface ap_ovld      port = b
#pragma HLS interface ap_ctrl_none port = return

    *b = a * *b;
}

SCR-20250525-ugiv.png


プラグマ:#pragma HLS interface ap_ack port = xxx
プロトコル:ack信号あり
説明:
入力データに対しては出力のack信号が生成され、入力が読み出されたタイミングでアサートされる。
出力データに対しては入力のack信号が生成され、出力が読み出されたことを確認される。
例:

void function(uint16_t a, uint16_t *b)
{
#pragma HLS interface ap_ack       port = a
#pragma HLS interface ap_ack       port = b
#pragma HLS interface ap_ctrl_none port = return

    *b = a * 10;
}

SCR-20250525-tvvd.png

CoSimでは出力のack信号を使用するデザインは検証できないです


プラグマ:#pragma HLS interface ap_hs port = xxx
プロトコル:今までの全部入りのプロトコル
説明:2方向によるハンドシェイク
例:

void function(uint16_t a, uint16_t *b, uint16_t *c)
{
#pragma HLS interface ap_hs   port = a
#pragma HLS interface ap_hs   port = b
#pragma HLS interface ap_hs   port = c
#pragma HLS interface ap_none port = return

    *b = a * *c;
    *c = a;
}

SCR-20250525-udfx.png

メモリ系

配列データがこれに当てはまります。

プラグマ:#pragma HLS interface bram port = xxx
プロトコル:シングルポートのメモリアクセス
説明:RAMのインターフェースとして合成される
例:

void function(uint16_t a[10], uint16_t *b)
{
#pragma HLS interface bram       port = a
#pragma HLS interface ap_none    port = b
#pragma HLS interface ap_ctrl_hs port = return

    uint16_t sum = 0;
    for (int i = 0; i < 10; i++) {
#pragma HLS pipeline ii = 1
        sum += a[i];
    }

    *b = sum;
}

SCR-20250526-bafu.png


プラグマ:#pragma HLS interface ap_memory port = xxx
プロトコル:インターフェースが分離されたメモリアクセス
説明:RAMのインターフェースとして合成される
例:

void function(uint16_t a[10], uint16_t *b)
{
#pragma HLS interface ap_memory  port = a
#pragma HLS interface ap_none    port = b
#pragma HLS interface ap_ctrl_hs port = return

    uint16_t sum = 0;
    for (int i = 0; i < 10; i++) {
#pragma HLS pipeline ii = 1
        sum += a[i];
    }

    *b = sum;
}

SCR-20250525-uomr.png

以下のように読み取りと書き込みの両方があればデュアルポートとしてIFが生成されます。

void function(uint16_t a[10])
{
#pragma HLS interface ap_memory  port = a
#pragma HLS interface ap_ctrl_hs port = return

    for (int i = 0; i < 10; i++) {
#pragma HLS pipeline ii = 1
        a[i] = a[i] + 10;
    }
}

SCR-20250526-borj.png

bramとap_memoryの違い

SCR-20250526-bdpx.png

ストリーム系

こちらも配列データがこれに当てはまります。

プラグマ:#pragma HLS interface ap_fifo port = xxx
プロトコル:FIFOアクセス
説明:FIFOのインターフェースとして合成される
例:

void IfRegister(uint16_t a[5], uint16_t *b)
#pragma HLS interface ap_fifo    port = a
#pragma HLS interface ap_vld     port = b
#pragma HLS interface ap_ctrl_hs port = return

    uint16_t sum = 0;
    for (uint16_t i = 0; i < FIFO_DEPTH; i++) {
        sum += a[i];
    }

    *b = sum;
}

SCR-20250601-rsjx.png

ブロックレベルの制御プロトコル

プラグマ:#pragma HLS interface ap_ctrl_chain port = retrun
プロトコル:以下図

SCR-20250601-sups.png

説明:チェーン制御
例:

void function(uint16_t a[5], uint16_t b[5], uint16_t* c)
{
#pragma HLS interface ap_memory     port = a
#pragma HLS interface ap_memory     port = b
#pragma HLS interface ap_memory     port = c
#pragma HLS interface ap_ctrl_chain port = return

    static uint16_t sum = 0;
    for (int i = 0; i < 5; ++i) {
        sum = sum + a[i] + b[i];
    }

    *c = sum;
}

SCR-20250601-tfss.png


プラグマ:#pragma HLS interface ap_ctrl_hs port = retrun
プロトコル:先ほどのap_ctrl_chainのap_continue信号が常に1になる。
説明:シーケンシャル制御
例:

void function(uint16_t a[5], uint16_t b[5], uint16_t* c)
{
#pragma HLS interface ap_memory  port = a
#pragma HLS interface ap_memory  port = b
#pragma HLS interface ap_memory  port = c
#pragma HLS interface ap_ctrl_hs port = return

    static uint16_t sum = 0;
    for (int i = 0; i < 5; ++i) {
        sum = sum + a[i] + b[i];
    }

    *c = sum;
}

SCR-20250601-telx.png

ここでap_ctrl_chainとの違いですが、ざっくり以下です。

動作イメージ
・ap_ctrl_chain
① 前段モジュールがap_startを出力
② 本モジュールが処理し、ap_doneを出力
③ 後段モジュールがap_continueを出力することでチェーン継続

・ap_ctrl_hs
① ソフト or 他モジュールがap_startを出力
② 本モジュールが処理し、ap_doneを出力
③ 再度ap_startを受け処理を開始

まとめ:
ap_ctrl_chainは自律的に各モジュール同士が連携し常に動作するイメージ。
ap_ctrl_hsはどこかからトリガーを受けて単発で動くイメージ。


プラグマ:#pragma HLS interface ap_ctrl_none port = retrun
プロトコル:プロトコルなし
説明:プロトコルがないため、常にパイプラインで処理したい場合などで有利
例:

void function(uint16_t a, uint16_t b, uint16_t* c)
{
#pragma HLS interface ap_none      port = a
#pragma HLS interface ap_none      port = b
#pragma HLS interface ap_none      port = c
#pragma HLS interface ap_ctrl_none port = return

    uint16_t sum = 0;

    sum = a + b;

    *c = sum;
}

SCR-20250601-tzcw.png

IF編はこれにて終了。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?