目次
- 目次
- 1. はじめに
- 2. 動作原理
- 3. 2つのペイロードが合流するパイプライン
- 4. シーケンス バースト長4、データは連続して来る、d_readyはアサートのままのシーケンス
- 5. コード
- 6. 本質要素抽象化とは
- ライセンス
1. はじめに
このドキュメントはAIに読み込ませてコードを自動生成することを目標としています。
本記事では、パイプライン処理においてペイロードが合流する場合のAXIライトデータチャネルの動作を模擬します。前回までに学んだパイプライン処理の基本概念を応用し、実際のハードウェア設計でよく遭遇する「バーストライト」シナリオを扱います。
バーストライトは、アドレスリクエストとライトデータが合流するシナリオです。パイプラインの途中で1つのPayload(アドレス)がバースト回数分に膨らみます。この膨らんだアドレスは書き込みデータに合流します。Payload-1(アドレス)の個数が増えるパイプラインステージより上流のパイプラインを停止して待機させる必要があります。また、Payload-1(アドレス)はPayload-2(データ)と合流しさらにPayload-3(レスポン)に受け渡されます。Readyの発生源はPayload-1(アドレス)のバースト、Payload-2(データ)の書き込み可能かどうか、Payload-3(レスポン)の下流側から入力されるReadyの3箇所あります。この3つのパイプラインにできるだけ無駄なサイクルが発生しない実装を考えます。
AXIライトチャネルの特徴を整理します:
- アドレスチャネル: 書き込みアドレスとバースト情報を伝達
- データチャネル: 実際のデータとストローブ信号を伝達
- レスポンスチャネル: 書き込み完了の応答を伝達
このようにあらゆる設計を本質要素抽象化により検討内容をシンプルにして進めます。
ライトパイプランの実装は管理するチャネルが3つになり、またReadyの条件が複雑化するため難易度が一気に上がります。しかしながら、ここまで進めてきた単純化・ルール化によって先の見通しはかなりいいはずです。
2. 動作原理
2.1 ペイロード増幅シナリオ
ペイロード増幅は第4回で解説した通り、パイプライン処理において1つの入力データが複数の出力データに変換される現象です。特にバーストアクセスでは、1つのリクエストに対して複数のデータ応答が返されます。これはリードと同様にライトでも発生します。ペイロード増幅の実装方法はすでに学んだ方法を使用します。
3. 2つのペイロードが合流するパイプライン
T0Aはアドレスをカウントする回路。T0Dはデータパイプラインをアドレスパイプラインと同じ位置に合わせる。
T1はT0AとT0Dの制御をすると同時に、アドレス、データ、WEを生成する。
T2はライトの結果としてレスポンスを生成する。AXIではLASTサイクルにレスポンスを返すルールになっているが、この回路では、書き込みが正常である証にアドレスとデータが同じでWEがアサートされているかどうかをチェックする。正常の場合はT1のアドレスを出力、異常の場合はペイロードに不定を出力する。
2.2 複数のReadyを制御するシナリオ
Ready信号は、アドレスチャネルのペイロード増幅によるReady、データチャネルの書き込み待ちによるReady、レスポンスチャネルの最下流からのReadyの3つあります。データチャネルのReadyを除くと第4回の構造がそのまま使えます。
第4回と同様に複数のReadyのマージは非同期の論理ANDです。
Readyの制御について説明します。
このパイプライン全体のイネーブルを制御するd_Readyはレスポンスチャネルから入力されます。このd_ReadyがネゲートされるとT0,T1,T2のパイプラインを停止します。d_Readyは途中のパイプラインで生成されるReadyと非同期ANDされて上流に渡されます。
T1はデータとアドレスを待ち合わせるためのT0A_M_ReadyとT0D_M_Readyを生成します。T0A_M_Readyがアサートされる条件はT0DがValid && T0Aがnot Valid またはT0DとT0Aの両方がnot Valid またはT0DとT0Aの両方がValidです。T0D_M_Readyがアサートされる条件は、T0Dがnot Valid && T0AがValid またはT0DとT0Aの両方がnot Valid またはT0DとT0Aの両方がValidです。T0A_M_ReadyとT0D_M_Readyはd_Readyと非同期ANDされて上流に渡されます。
T0Dはデータパイプラインです。T0D_Ready=Hの場合にペイロードをラッチします。
T0Aはアドレスパイプラインです。第4回の2.3章で説明したアドレスの回路と同じ動作をします。バーストの管理のためにT0A_Readyが生成されます。このT0A_ReadyはT0A_M_Readyと非同期ANDされて上流に渡されます。
u_Payload_D=> [T0D]=======++
^ ||
| ||
u_Ready_D <-[AND]---+ ||
^ | ||
| | ||
[T0D_Ready] | ||
| ||
u_Payload_A=> [T0A] ===> [T1] => [T2] => d_Payload
^ | ^ ^
| | | |
u_Ready_A <-[AND]<--+---+-------+--- <- d_Ready
^ ^
| |
[T0A_Ready] |
[T0A_M_Ready]
4. シーケンス バースト長4、データは連続して来る、d_readyはアサートのままのシーケンス
Clock : 123456789012345678901
Address : xxxxxx044448888xxxxxx
Data : xxxxxx0123456789ABxxx
Length : xxxxxx333333333xxxxxx
Valid : ______HHHHHHHHHHHH___
Ready : HHHHHHH___H___H___HHH
T0A_Count : FFFFFFF321032103210FF
T0A_Valid : _______HHHHHHHHHHHH__
T0A_Last : __________H___H___H__
T0A_Ready : HHHHHHH___H___H___HHH
T0D_Data : xxxxxxx0123456789ABxxx
T0D_Valid : _______HHHHHHHHHHHH__
T0D_Ready : HHHHHHHHHHHHHHHHHHHHH
T1_Address : xxxxxxx0123456789ABxx
T1_Data : xxxxxxx0123456789ABxx
T1_WE : _______HHHHHHHHHHHH__
T1_Valid : _______HHHHHHHHHHHH__
T1_Last : __________H___H___H__
d_Response : xxxxxxxx0123456789ABx
d_Valid : ________HHHHHHHHHHHH_
d_Ready : HHHHHHHHHHHHHHHHHHHHH
シーケンスの説明:
- Clock 1-6: リセット解除後の初期化期間
- Clock 7: バースト開始、アドレス0x04、長さ3(4回のバースト)
- Clock 8-11: アドレスカウンタが3→2→1→0とカウントダウン
- Clock 12: アドレスカウンタが0xFF(アイドル状態)に戻る
- Clock 13: 次のバースト開始、アドレス0x08、長さ3
- Clock 14-17: アドレスカウンタが3→2→1→0とカウントダウン
- Clock 18-19: アドレスカウンタが0xFF(アイドル状態)に戻る
T1 stageの動作:
- T1_Valid: T0A_Valid && T0D_Valid の条件で生成
- T1_Last: T0A_Last を転送
T2 stage(出力)の動作:
- d_Valid: T1_Valid を転送(T1がvalidな間、出力もvalid)
- d_Response: T1_Valid && (T1_addr == T1_data) && T1_we の条件でT1_addrを出力、それ以外は不定値
- この例では、アドレスとデータが一致しているため、アドレス値がそのままレスポンスとして出力される
3. コード
3.1 バーストライトパイプラインモジュール
コードの特徴:
- 3つのパイプライン: T0A(アドレス)、T0D(データ)、T1(合流制御)、T2(レスポンス生成)の4段階構成
-
Ready制御の統合: パイプライン全体が
d_ready
信号で制御されており、各ステージの動作はReadyがHの時のみ実行されます - Merge制御: T0AとT0Dのデータを適切なタイミングで合流させる制御ロジック
- レスポンス生成: アドレスとデータが一致し、書き込みが有効な場合のみアドレス値をレスポンスとして出力
- バースト制御: T0Aステージでバースト長の管理とアドレスのカウントアップを実装
3.2 バーストライトパイプラインテストベンチ
コード: burst_write_pipeline_tb.v
コードの特徴:
- 2つのインターフェース: アドレスインターフェースとデータインターフェースを独立して制御
- キュー配列によるテストデータ管理: アドレス、データ、期待値、ストール制御をキュー配列で管理
- バースト制御のテスト: バースト長のランダム生成とバースト完了の検証
- デバッグ信号監視: T1ステージの内部信号を監視してデバッグ情報を出力
- 包括的なテスト: バブルサイクル、ストールサイクル、データ整合性の検証
テストベンチの構造
テストベンチは以下の主要セクションで構成されています:
- Clock and Reset: クロック生成とリセット制御
- Test pattern generator signals: アドレスとデータのテスト信号生成
- Test pattern arrays: テストデータを格納するキュー配列
- Expected response arrays: 期待されるレスポンスデータ
- Stall control arrays: ストール制御用の配列
- Array control variables: 配列制御用の変数
- DUT interface signals: DUTとのインターフェース信号
- Test control signals: テスト制御用の信号
- Burst tracking for reporting: バースト追跡用の信号
- DUT instance: デバイスアンダーテストのインスタンス
- Clock generation: クロック生成回路
- Reset generation: リセット生成回路
- Test data initialization: テストデータの初期化
- Test pattern generator: アドレスとデータのテストパターン生成
- Downstream Ready control circuit: 下流Ready制御回路
- Test result checker circuit: テスト結果チェック回路
- Debug signal monitoring: デバッグ信号監視
テスト信号の参照方法
T1 stageのデバッグ信号は以下のように階層名で参照します:
// デバッグ信号の監視
always @(posedge clk) begin
if (dut.t1_valid && dut_ready) begin
$display("Time %0t: T1 Debug - addr: %0d, data: %0d, we: %0d, valid: %0d, last: %0d",
$time, dut.t1_addr, dut.t1_data, dut.t1_we, dut.t1_valid, dut.t1_last);
end
end
5. 本質要素抽象化とは
本質要素抽象化とは、複雑な設計課題を基本的な要素に分解し、それぞれの要素を独立して検討することで、全体の設計をシンプルにする手法です。複雑なシステムを設計する際、すべての要素を同時に考慮すると設計が困難になります。本質要素抽象化では、システムを制御要素、データ要素に分解します。
また、名称は具体名ではなく本質的にその機能を指し示す抽象的な名称にして、同じグループであるかそれとも別のグループであるかを明確にします。ここまで使用された抽象的な名称はReady、Valid、Payloadです。パイプラインは本質的にこの3種類の信号で説明が可能です。
抽象化の重要性
抽象化により、具体的な実装詳細に囚われることなく、システムの本質的な動作を理解できます。例えば、AXIプロトコルの詳細な信号名(AWVALID、WREADY、BRESPなど)ではなく、Ready、Valid、Payloadという抽象的な概念で考えることで、パイプラインの基本動作を理解しやすくなります。
3つの基本要素
Ready: データを受け取れる状態を示す制御信号
Valid: データが有効であることを示す制御信号
Payload: 転送されるデータそのもの
ValidとPayloadの関係
重要な洞察として、Validは本質的にはPayloadであるということができます。Valid信号は、その時点で有効なデータ(Payload)が存在するかどうかを示す制御情報ですが、これは実際には「データの有効性」という情報自体がPayloadとして機能していることを意味します。
つまり、Valid信号は:
- データチャネルでは「データが有効である」という情報を伝達
- 制御チャネルでは「制御情報が有効である」という情報を伝達
- アドレスチャネルでは「アドレスが有効である」という情報を伝達
このように、Validは各チャネルにおいて「何が有効であるか」という具体的なPayload情報を伝達する役割を果たしています。したがって、ValidとPayloadは密接に関連しており、ValidはPayloadの有効性を示すメタデータとして機能していると言えます。
Readyによる制御の統一性
さらに重要な点として、ValidとPayloadはいずれもReadyで制御されているという統一性があります。これは、パイプライン設計における制御の本質を表しています:
-
Ready信号の役割: Ready信号は、下流のステージがデータを受け取れる状態であることを示し、上流のステージに対してデータ転送の許可を与えます。
-
ValidとPayloadの制御: Valid信号(データの有効性)とPayload(実際のデータ)の両方が、下流からのReady信号によって制御されます。Readyがアサートされていない場合、ValidとPayloadは下流に伝播されません。
-
制御の階層構造: この制御構造により、パイプライン全体の流れが統一され、データの整合性が保たれます。Ready信号は、パイプラインの各段階における「流れの制御」を司る中心的役割を果たしています。
この統一性により、複雑なパイプラインシステムでも、Ready、Valid、Payloadの3つの基本要素だけで制御構造を理解し、設計することが可能になります。
この3つの要素により、あらゆるパイプラインの動作を統一的に記述できます。具体的なプロトコルや信号名に関係なく、パイプラインの本質的な動作を理解するための強力なツールとなります。
ライセンス
Licensed under the Apache License, Version 2.0 - see LICENSE file for details.