DATE2022に上がっていたChiselの拡張言語Twineというものについて、論文を読んでみることにした。 今回はインタフェースの接続方法と実装まで。うーん、データフローのみのハードウェアならやりようはあるかもしれないが、細かいCPUみたいな実装ではあまり活用できるとは思えない。
前回の記事
B. プロデューサー・コンシューマの関係とデータフローの構築
設計の効率性を高めるために、Twineは低レベルのポート接続ではなく、プロデューサーとコンシューマーの関係を表現するセマンティクスのセットを提供します。プロデューサー/コンシューマーモデルは、タイミング動作や制御信号を抽象化し、ユーザーがデータの依存関係に完全に集中できるようにします。このような設計思想は、設計をより直感的にし、ハイレベルな設計の自動化を可能にする。Twineでは、システム制御ロジックを合成するために、各コンポーネント間のデータ依存性の情報を収集する必要があります。データ依存性を分析するために、各コンポーネントにproducer、consumer、stakeholderの3つのラベルを付けます。消費者は、現在のモジュールから直接値を取り込むコンポーネントである。生産者は、入力データの元となるコンポーネントである。ステークホルダーは、他のモジュールの状態を監視して制御上の決定を行う必要があるコンポーネントである。例えば、1つのプロデューサーに複数の消費者がいる場合、プロデューサーはすべての消費者が消費する準備ができたときにのみ結果をリリースすることができる。このような場合、各コンシューマは他のコンシューマの状態を監視して重複を避け、正しさを確保する必要がある。ステークホルダーには、生産者-ステークホルダー(p-stakeholder)と消費者-ステークホルダー(c-stakeholder)の2種類があります。P-stakeholdersは少なくとも1つの共通の消費者を共有し、c-stakeholdersは少なくとも1つの共通の生産者を共有する。リスト1と図1の設計を例として、構成要素間の関係を表IIに示す。
設計の効率性を高めるために、Twineは低レベルのポート接続だけでなく、プロデューサーとコンシューマの関係を表現する文法を導入する。これにより、設計をより直感的にするという目的がある。Twineでは、各コンポーネントのデータ依存性を分析するために、各コンポーネントに対してproducer/consumer/satkeholderの3つのラベルを付けるようにしている。
- Consumer : モジュールから直接値を取り込むコンポーネント
- Producer : 入力データの元となるコンポーネント
- Stakeholder : ほかのモジュールの状態を監視して制御上の決定を行う必要があるコンポーネント
- 全てのConsumerの準備が整わないとProducerがデータを発出できない場合の制御など
- Producer-Stakeholder : 少なくとも1つのProducerと状態を共有する
- Consumer-Stakeholder : 少なくとも1つの消費者と状態を共有する
コンポーネント | Consumer | Producer | P-Stakeholder | C-Stakeholder |
---|---|---|---|---|
Top | fma, sqrt2 | fma2 | N/A | N/A |
fma1 | sqrt1 | top | N/A | sqrt2 |
fma2 | top | sqrt1, sqrt2 | N/A | N/A |
sqrt1 | fma2 | fma1 | sqrt2 | N/A |
sqrt2 | fma2 | top | sqrt1 | fma1 |
fma2にとって、sqrt1とsqrt2は共通のConsumerであるため、互いにP-Stakeholderであり、fma1とsqrt2は共通のProducerであるtopを共有しているためC-Stakeholderである。
これらの関係性はTwineがエラボレーション時に指定する。プロデューサ・コンシューマ間の関係として>>>
を指定する。
C. コンポーネント間接続の自動化
コンポーネント間の接続について、Twineは各コンポーネントのインタフェースの形式に基づいて制御論理を構築する。型変換も同時にサポートしており、符号なし、符号あり整数の変換、浮動小数点データの基本的な変換を自動的にサポートしている。これらのコンバータは、肩の異なるインタフェースを接続する際に自動的に挿入される。
III. 実装
本節では、Twineの実装について説明する。TwineはChiselと完全に下位互換性があり、Chiselの全機能をサポートしています。開発者は、コンポーネントを宣言する際にTwineModule
を継承することで、自分のデザインにTwineを取り入れることができます。TwineModule
は、通常のChiselモジュールとして使用することもできます。Twineのオペレーションが評価されると、Chiselのオペレーションに変換され、必要な場所にコンバージョンコンポーネントを挿入し、接続情報をTwine profile (後のステージでシステムの合成をガイドする情報の集合)に登録します。コンポーネント間の接続が完了するのは、全てのステートメントが評価され、コンテキスト情報が完全に収集された後です。Chiselのエラボレーションフェーズにフックを追加し、すべてのステートメントが評価された後にTwine合成を開始します。そしてTwineはproducer/consumer関係を解析し、制御連携のための接続を完成させます。
TwinModuleを使用するとChiselモジュールの代わりにTwineを使うことができる。接続情報をTwine profileに登録し、コンポーネント間の接続が完了するのは、すべてのステートメントが評価され、コンテキスト情報が完全に収集された跡となる。Chiselのエラボレーション時に新たな動作がフックされ、Twineの合成が開始される。
TwineからFIRRTLへのワークフローは以下の通りである(Twine特有のステップには"*"を付けている)。
- Chiselを用いて低レベルコンポーネントを生成する。
- Twineのコンポーネントは、標準的なTwineインターフェースで実装されている。*
- Twine仕様から高レベルの情報を収集*
- 必要なバッファやコンバータを生成 高水準の仕様に基づき、適切な位置に挿入する。*
- Twineコンポーネントの役割と関係を再構築する。*
- 制御信号の調整を行う。全コンポーネントを相互接続する。*
- ChiselのプリミティブをFIRRTL表現にコンパイルする。
- コンポーネントが正しいTwineデザインを生成するために必要な基準を満たしているかチェックする(例:
TightlyCoupledIOCtrl
モジュールのレイテンシは一定、DecoupledIOCtrl
のready信号とvalid信号は相互に依存しない)。* - 完成したFIRRTLファイルを出力する。