目次
1. はじめに
このドキュメントはAIに読み込ませてコードを自動生成することを目標としています。
パイプライン回路の動作原理の説明を説明してコードを提供します。
2. パイプラインの動作原理
パイプラインは複数の処理段階を並列に実行することで、全体の処理能力を向上させる手法です。各段階は独立して動作し、ペイロードを次の段階に順次受け渡します。
2.1 基本的な考え方
パイプラインは制御されるペイロードと制御信号であるReadyとValidで構成されます。Validはペイロードの一部であり、各パイプラインステージに有効なペイロードがあるかどうかを示します。Readyは上流の回路に対してペイロードを受け取れるかどうかを示します。Readyがネゲートされるとパイプラインが停止してペイロードはReadyがHになるまでホールドされます。下流の回路がペイロードを受け取れない状態の時にReadyをネゲートします。パイプラインが停止すると、上流の回路にReadyをネゲートしてペイロードを受け取れないことを知らせます。また、パイプランは段数を自由に増やせます。パイプラインの段数を増やしても送信側と受信側のシーケンスは変わりません。
基本ルール1 : パイプランはREADYでペイロードのイネーブルを制御し、パイプラインの全てのFFのイネーブルに接続
基本ルール2 : VALIDはペイロードの一部である
基本ルール3 : パイプラインの段数を1段増やしてもシーケンスは変わらない
2.2 Ready/Validハンドシェイク
パイプラインの制御にはReady/Validハンドシェイクが使用されます:
- Valid信号: ペイロードが有効であることを示す
- Ready信号: 次の段階がペイロードを受け取れることを示す
- 転送条件: Ready=H の時にペイロードとValidが転送される
2.3 ストール動作
ReadyがLの時、パイプラインは停止(ストール)します:
- ペイロードは現在の段階で保持される
- Valid信号も同様に保持される
- 上流の回路にReady=Lを伝播させる
2.4 バブル動作
ValidがLの時、無効なペイロード(バブル)がパイプラインを流れます:
- ペイロードは転送されるが、Valid=Lにより無効として扱われる
- 下流の回路はValidを確認してペイロードの有効性を判断する
3. パイプライン構造
3.1 基本構造
- シフトレジスタ構造: パイプラインはシンプルにシフトレジスタ構造
- ペイロードの種類: アドレス、データ、IDなどパイプラインで受け取るペイロードすべてが含まれる
- Validパイプライン: ペイロードパイプラインに並行して同じ段数のValidパイプラインが存在
- Valid信号の役割: ペイロードと一緒に入力され、出力までペイロードと一緒に流れ、出力ペイロードが有効かどうかのフラグとして使用
- Ready信号の接続: シンプルにすべてのFFのイネーブルピンに接続
- Ready信号の流れ: 下流側から入ったReadyはそのまま非同期で上流側に出力されます。
この制御方法は非常にシンプルで実装が容易です。ただし、Readyが非同期で下流から上流に突き抜けてしまう点とReadyのファンアウトが大きい点がデメリットです。対策は別途解説します。
Input -> [T0] -> [T1] -> [T2] -> [T3] -> Output
| | | |
Ready Out <-+-------+-------+-------+-<- Ready In
(Common)
3.2 パイプライン構成表
段階 | ペイロードFF | Valid FF | イネーブル信号 | 説明 |
---|---|---|---|---|
T0 | N-bit FF | 1-bit FF | Ready (共通) | 入力段階 |
T1 | N-bit FF | 1-bit FF | Ready (共通) | 第1段階 |
T2 | N-bit FF | 1-bit FF | Ready (共通) | 第2段階 |
T3 | N-bit FF | 1-bit FF | Ready (共通) | 出力段階 |
3.3 FF詳細仕様
項目 | ペイロードFF | Valid FF | Ready信号 |
---|---|---|---|
ビット幅 | N-bit | 1-bit | 1-bit (共通) |
個数 | 4個 | 4個 | 1本 |
イネーブル信号 | Ready (共通) | Ready (共通) | - |
同期方式 | 同期 | 同期 | - |
4. パイプライン動作シーケンス
4.1 Readyがアサート状態のシーケンス
ReadyがHの期間は、Validとペイロードはパイプラインに順番に流れます。
Clock : 12345678901234
Input : xx012345xxxxxx
Valid : __HHHHHH______
T0 : xxx012345xxxxx
T0_Valid : ___HHHHHH_____
T1 : xxxx012345xxxx
T1_Valid : ____HHHHHH____
T2 : xxxxx012345xxx
T2_Valid : _____HHHHHH___
T3 : xxxxxx012345xx
T3_Valid : ______HHHHHH__
Ready : HHHHHHHHHHHHHH
4.2 Validが途中でネゲートされるケース
ValidがLの場合、無効なペイロード(バブル)がパイプラインを流れます。
Clock : 123456789012345
Input : xx012x345xxxxxx
Valid : __HHH_HHH______
T0 : xxx012x345xxxxx
T0_Valid : ___HHH_HHH_____
T1 : xxxx012x345xxxx
T1_Valid : ____HHH_HHH____
T2 : xxxxx012x345xxx
T2_Valid : _____HHH_HHH___
T3 : xxxxxx012x345xx
T3_Valid : ______HHH_HHH__
Ready : HHHHHHHHHHHHHHH
4.3 Readyが途中でネゲートされるケース
ReadyがLの時、パイプラインは停止(ストール)します。ReadyがLになると、その次のサイクルでペイロードが保持され、現在のサイクルと同じ値になります。ReadyがLからHになったサイクルのT0,T1,T2,T3は、ReadyがLのサイクルと同じペイロードになります。
4.3.1 1クロックネゲートのケース
Clock : 123456789012345
Input : xx0123445xxxxxx
Valid : __HHHHHHH______
T0 : xxx0123345xxxxx
T0_Valid : ___HHHHHHH_____
T1 : xxxx0122345xxxx
T1_Valid : ____HHHHHHH____
T2 : xxxxx0112345xxx
T2_Valid : _____HHHHHHH___
T3 : xxxxxx0012345xx
T3_Valid : ______HHHHHHH__
Ready : HHHHHH_HHHHHHHH
-
Ready信号の動作:
- 7クロック目でReadyがL('_')になる
- 8クロック目でReadyがHに戻る
-
パイプラインのストール動作:
- 7クロック目(Ready=L): 6クロック目でReady=Hだったため、7クロック目でペイロードが更新される。FFのイネーブルがネゲートされるため、8クロック目でペイロードが保持される
- 8クロック目(Ready=H): 7クロック目でReady=Lだったため、T0,T1,T2,T3の値が7クロック目と同じ値で保持される
- 9クロック目以降: 正常にペイロードが流れ始める
-
具体的なペイロードの流れ:
- 7クロック目: T0=3, T1=2, T2=1, T3=0
- 8クロック目: T0=3, T1=2, T2=1, T3=0(同じ値)
- 9クロック目: T0=4, T1=3, T2=2, T3=1(正常に流れ始める)
-
Valid信号の動作:
- Valid信号も同様にストールされる
- 8クロック目は7クロック目と同じ値が保持される
4.3.2 2クロックネゲートのケース
Clock : 1234567890123456
Input : xx01234445xxxxxx
Valid : __HHHHHHHH______
T0 : xxx01233345xxxxx
T0_Valid : ___HHHHHHHH_____
T1 : xxxx01222345xxxx
T1_Valid : ____HHHHHHHH____
T2 : xxxxx01112345xxx
T2_Valid : _____HHHHHHHH___
T3 : xxxxxx00012345xx
T3_Valid : ______HHHHHHHH__
Ready : HHHHHH__HHHHHHHH
-
Ready信号の動作:
- 7-8クロック目でReadyがL('_')になる(2クロック間)
- 9クロック目でReadyがHに戻る
-
パイプラインのストール動作:
- 7-8クロック目(Ready=L): 6クロック目でReady=Hだったため、7クロック目でペイロードが更新される。FFのイネーブルがネゲートされるため、8-9クロック目でペイロードが保持される
- 9クロック目(Ready=H): 8クロック目でReady=Lだったため、T0,T1,T2,T3の値が8クロック目と同じ値で保持される
- 10クロック目以降: 正常にペイロードが流れ始める
-
具体的なペイロードの流れ:
- 7クロック目: T0=3, T1=2, T2=1, T3=0(ストール開始)
- 8クロック目: T0=3, T1=2, T2=1, T3=0(ストール継続)
- 9クロック目: T0=3, T1=2, T2=1, T3=0(ストール解除、同じ値)
- 10クロック目: T0=4, T1=3, T2=2, T3=1(正常に流れ始める)
- 11クロック目: T0=4, T1=4, T2=3, T3=2(正常に流れ続ける)
-
Valid信号の動作:
- Valid信号も同様にストールされる
- 7-8クロック目と9クロック目で同じ値が保持される
- ペイロードとValidは2クロック間ホールドされる
5. コード
ここまでの説明を読み込ませてAIに自動生成させたコードです。非常にシンプルで難しいところはありません。AXIバスの基本シーケンスはこのようなReadyを使用したシフトレジスタ構造なのです。
コード: pipeline.v
このファイルには、パイプライン回路の基本的な実装が含まれています。Ready/Validハンドシェイクを使用した4段パイプラインの設計例です。
6. 帰納法的設計
この回路はN段のパイプラインをN+1段に増やしても同じロジックが使えます。このように小さな回路でルールを考えて1つ段増やしても同じルールを使う設計手法を(私は)帰納法的設計と呼んでいます。この設計方法は例えば乗算器を設計する時に8ビットくらいでロジックを考えておいて全ケーステストをした後に16bitに拡張するとか(全ケーステストはとても時間がかかる場合に、縮小した回路のテストで論理の正常性を担保できる)。他の例としては、Readyのネゲートの動作を確認するときは1クロックネゲート、2クロックネゲート、Nクロックネゲートというように解析します。この方法はテストパターンを端折る場合などにも応用できます。
ライセンス
Licensed under the Apache License, Version 2.0 - see LICENSE file for details.