Permalink: 2015-01-13 00:02:00+09:00 by tu1978 in tags: HLS

現在Vivado HLSを使用して回路合成の実験をしているが、いろいろと問題に遭遇している。

  • バージョン2014.2で合成するとCo-simulationが終了しない。
  • バージョン2014.4で合成するとCo-simulationは終了するが、C simulationと結果が一致しない。

ひょっとしたら合成側ではなく、シミュレータ側に問題があるかと予想し、 2014.2で合成した結果を2014.4のシミュレータで動かしてみたが、終了しないのは 変わらなかった。

また、2014.2で合成した結果をインプリしてみたが、AXI Stream出力なのに、 TREADYがHighになっていないにも関わらず、TVALIDがHighでTDATAが変化してしまっていたりする 状況が見られた(FIFO fullなのに書き込み側が止まらずに進んでしまっているような状況)。 これは明らかにハンドシェークとしておかしい。

今はC++から合成しているが、自分の意図としては「ここは並列して動いて欲しい」 というところがツールにちゃんと伝わらないことが多いのも不満がある。 RTLでの記述は並列に動作するのが前提だが、Cのような言語は逐次実行が前提なので、 どこまで並列化できるかは、ツールの賢さに完全に依存してしまう。

細かいところでは、配列はBlock RAMとして実装されることがあるが、 その場合自動的に変数は複製してくれないので、Block RAMの2ポート制約の せいで並列性が犠牲になることがある。自動的に同一のBlock RAMを複数 コピーするようにしてくれれば嬉しい(あるいは複製数を指定できるとか)。 仕方ないので、今は手動で同一の配列変数を作成している。

SystemCからの合成もできるようなので、そちらで試してみるかもしれない。 SystemCはRTLのように並列箇所を明示できるので、ツール側としては 並列抽出は(Cからの変換よりは)楽なはず。

印象としては、簡単な回路であれば、ほとんどの場合問題なく合成してくれるが、「高位合成を使いたい」と思うような、 RTL手コーディングが面倒な場面では、夢のようには機能しない。結局のところ、合成結果を (シミュレーション結果の波形を見たりして)眺めて、所望の結果が得られるように Cコードレベルで最適化する作業が必要になる。この作業にはもちろん、RTLを書くときに考える ようなパイプラインのイメージやらBlock RAMのポート数のイメージやらが必要になる。 それならば高位合成なんていらないや、という人もいるかもしれないが、 RTLで書いていてSimまで通したのにインプリしたらタイミングがあと0.02ns間に合わない!といったような 悲しい場面になってしまったときに、自分でレジスタを追加して再度検証するのは結構手間が かかるもの。このような、クロック周波数を考慮した回路の段数も、ある程度適切に 考慮して合成してくれるのはかなり助かる、と思う。もっとも、ツールが想定する周波数は それほど正確ではない、というのもまた事実なのだけれど。また、RTLで記述した 回路のためのテストベンチを書くのも結構手間がかかるものだが、Cベースで検証できるという メリットも相当大きい。

Comments