【Vivado HLS】平均計算を高位合成する(ap_fifo/PIPELINE/rewind)

前回までは2値の平均値を高位合成してきました。

【Vivado HLS】平均計算を高位合成する(インタフェース合成 ap_ctrl_hs/ap_vld/ap_ovld)

今回は入力としてストリームデータを想定した構成にしてみます。イメージは次のタイミングチャートです。

Vivado HLS 高位合成 ap_fifo

ストリームデータを想定する場合にはHLSストリームライブラリを使用するのが良いみたいなのですが、まだ使い方がよく分かっていません。そのため今回は配列を使用して実装してみました。次が今回のソースコードになります。CファイルからC++ファイルに変更しています。

#include "average.h"

void average(int data[N], int* ave)
{
	int temp = 0;

	for (int i = 0; i < N; i++) {
		temp += data[i];
	}

	*ave = temp / N;
}
#define N 4

void average(int data[N], int* ave);
#include <stdio.h>
#include <stdlib.h>
#include "average.h"

int main()
{
	int testData[N];
	int testAve = 0;
	int cmpAve = 0;

	srand(10);

	for (int j = 0; j < 4; j++) {
		testAve = 0;
		cmpAve = 0;

		for (int i = 0; i < N; i++) {
			testData[i] = rand() % 256;
			cmpAve += testData[i];
		}

		cmpAve /= N;

		average(testData, &testAve);

		if (testAve != cmpAve) {
			printf("Test Error!\n");
			printf("cmpAve=%d testAve=%d\n", cmpAve, testAve);
		}
		else {
			printf("Test OK!\n");
		}
	}

	return 0;
}

入力データを配列引数としました。この引数のインターフェイスにap_fifoを指定します。出力はポインタのままでもいいような気もしますが、折角なのでこちらもap_fifoを指定します。

  • ap_fifo
    ブロック外部にFIFOが接続されると想定したI/Fです。ブロックに対する入力の場合、FIFOからデータをリードすると想定してread_enable,emptyがI/Fに追加されます。ブロックからの出力の場合、FIFOへデータを格納すると想定し、write_enable,fullがI/Fに追加されます。
  • ディレクティブ指定した様子が下画像です。
    Vivado HLS 高位合成 ap_fifo

    Cシミュレーションした結果も問題なかったため、そのままC合成、C/RTL協調シミュレーションを実施して波形を表示しました。

    Vivado HLS 高位合成 ap_fifo

    計算は出来ていますが、各計算結果を得るまでに想定よりも時間がかかっています。想定では4クロック毎に結果が出力されてほしい。これはforループが終了するタイミングで新しい入力が読み込まれないために発生するそうです。

    これを解決するにはPIPELINEディレクティブのrewindオプションを使用すると良さそうです。本来PIPELINEディレクティブは複数の処理がある場合に、それらの処理をパイプライン処理して処理効率を上げるためのディレクティブです。(まだ試したことがないので調べた限りの話ですが…。そのうち試してみたい。)今回は処理が一つしかないのでPIPELINEの効果がないのですが、PIPELINEのオプションであるrewindを使用すると、forループ終了後に連続して処理を継続できるとのこと。

    forループに対してPIPELINEを適用します。ディレクティブタブに"for Statement"の文字があるので、これを右クリックしてディレクティブエディタを開きます。

    Vivado HLS 高位合成 PIPELINE rewind

    ディレクティブエディタでは"Directive"で"PIPELINE"を、また"Options"で"enable loop rewinding"にチェックをつけてOKを押します。

    Vivado HLS 高位合成 PIPELINE rewind

    forループに対してつけるラベル名を指定します。ここで指定したラベルがソースコードに挿入されるので、ソースを保存しておきましょう。

    Vivado HLS 高位合成 PIPELINE rewind

    下画像がrewindオプション付きでPIPELINEディレクティブをforループへ適用した状態です。

    Vivado HLS 高位合成 PIPELINE rewind

    この状態でC/RTL協調シミュレーションを実施すると、次のような波形になります。出力を4クロック毎に得ることが出来ています。

    Vivado HLS 高位合成 ap_fifo PIPELINE rewind

    細かいところを言うと、初回入力読み込んでいるために発生するレイテンシは初めの想定とは違うのですが、連続入力時は問題なく動作しているので良しとします。

    シェアする

    • このエントリーをはてなブックマークに追加

    フォローする