公開日:2026/01/17
37th Season
#37-8 Nihoniumパイプライン実装(Who)
Cmod A7ボード(FPGA)を使って開発しているオリジナル32ビットCPUコアNihoniumの実装方式として、パイプライン方式を採用してみたいと思います。
前回、Nihoniumをパイプライン方式で実装するに当たり、4段パイプラインを適用すると決めましたので、続きの考察を進めます。
4段パイプラインの設計
改めて、4段パイプラインの実行図を描いて見ましょう。

縦方向/横方向とも、時間の経過を示しています。
- 縦方向は命令の実行に掛かる時間経過。
- 横方向は命令内ステージの実行に掛かる時間経過。
併せて、左上方から右下方の斜め方向へ時間が経過します(青色点線矢印)。
縦に見て、赤枠のような瞬間に、IF/ID/EA/WBの4ステージが同時に実行されています。
横に見て、各ステージ枠内の時間は左から右へ向かって進んでいるので、各ステージの開始時は枠の左端、終了時は枠の右端、となります。また、CPUクロックの立ち上がりエッジが、各枠の左右端に位置します。つまり、1枠の横幅が1クロック(1サイクル)に相当します。
続いて、各ステージの動作をブロック図を描きながら解説して行きます。
IFステージ
IFステージのブロック図を以下に示し、解説を続けます。

- IFステージ: Instruction Fetch (fetch bus address and command phase) stage
- レジスタファイルRGFのプログラムカウンタpcを、フェッチアドレスfadrに出力。
- フェッチバスアクセスを発行する。
- フェッチバスプロトコルのアドレス・コマンド相に相当する。
- フェッチバスのプロトコルは、メモリバス仕様と同様。
- ただしフェッチバスコマンドfcmdには、読み出しアクセスしか存在しない事、バイトアクセスが存在しない事、等、メモリバスコマンドbcmdのサブセットである。
- Pc+2して、RGFのPcを更新する。
- そのままIDステージへも送る(ID_Pc)。
- ID_Pcは、この後、パイプラインに乗ってEAステージまで進む。
- Moscoviumシリーズでは、EAステージでPcを参照した場合、このID_Pc(=フェッチしたアドレス+2)が読める仕様だから、必要な処置。
- 何故なら、IFが実行される度にRGF内真のPcが+2で更新され、
- EAに到達する頃には期待しない値に変化してしまっているため。
- フェッチは32ビットデータバスとする。
- 命令コードは16ビット固定長なので、フェッチバスサイクルは2回に1回(32ビット毎)実行すれば良い。
- Pcが奇数ワードアドレスだった場合、フェッチバスコマンドfcmdをNOP出力して、バスサイクルの発行を抑止する。
- 次段のIDがID_busyの間、IFもストールする。
- IF_IrおよびID_Irは、内部命令コード。
IDステージ
IDステージのブロック図を以下に示し、解説を続けます。

- IDステージ: Instruction Decode (fetch bus read data phase) stage
- IFステージが発行したフェッチバスアクセスを受けて、フェッチデータfdatを回収する。
- フェッチバスプロトコルのリードデータ相に相当する。
- フェッチしたデータを命令レジスタir(Instruction Register)へ書き込む。
- フェッチデータバスfdatrは32ビット。
- 命令コードは16ビット固定長なので、フェッチバスサイクルは2回に1回(32ビット毎)実行すれば良い。
- フェッチアドレスが偶数ワードアドレスだった場合:
- fdatrの上位ワード(16ビット)をIrへ書き込む。
- fdatrの下位ワード(16ビット)は次命令レジスタnir(Next Ir)へ取り込む。
- フェッチアドレスが奇数ワードアドレスだった場合:
- 前のバスサイクル(偶数ワードアドレス)でNirにフェッチ済み。
- Ir=Nirを次のEAに投入する。
- ldli命令等の16ビット/32ビット即値は、拡張命令レジスタeir(Extended Ir)へ取り込む。
- ID_Pcを次のEAステージへ投入する(EA_Pc)。
- 次段のEAがEA_busyの間、IDもID_busyをアサートしてストールする。
EX(EA)ステージ
EX(EA)ステージのブロック図を以下に示し、解説を続けます。

- EXステージ: Execution stage
- レジスタファイルRGFから読み出したデータを演算して宛先レジスタrdへ書き込む📥。
- 算術論理演算ユニットALUで演算する場合と、外部コプロセッサ(浮動小数演算ユニットFPU)で演算する場合がある。
- プログラムカウンタpcを参照する場合は、EA_Pcを参照する。
- RGF内のPcは、IFステージ実行毎に+2加算されているので不適切。
- 演算が1サイクルで終了しない(crdy=0の)場合、EA_busyをアサートして、EXの実行サイクルを延長する。
- 先行命令のWB_busyの間、ストールして同期する。
- 更に、先行命令のWBステージが書き込むレジスタをEXが参照する場合、WB終了までストール。
- EXで命令の実行終了なので、次のWBステージを発行しない。
- 命令によってEXまたはMAとなるが、同じパイプラインのステージを共有するので、併せて「EAステージ(EX or MA stage)」と称する。
MA(EA)ステージ
MA(EA)ステージのブロック図を以下に示し、解説を続けます。

- MAステージ: Memory Access (memory bus address and command phase) stage
- レジスタファイルRGFから読み出したデータをbadr/bdatwへ出力。
- メモリバスサイクルを発行する。
- メモリバスプロトコルのアドレス・コマンド相に相当する。
- プログラムカウンタpcを参照する場合は、EA_Pcを参照する。
- RGF内のPcは、IFステージ実行毎に+2加算されているので不適切。
- brdy=0の間、EA_busyをアサートして、MAステージの実行サイクルを延長する。
- 先行命令のWB_busyの間、ストールして同期する。
- 更に、先行命令のWBステージが書き込むレジスタをMAが参照する場合、WB終了までストール。
- 読み出しアクセスの場合、WBを発行する(WB_Ir)。
- 命令によってEXまたはMAとなるが、同じパイプラインのステージを共有するので、併せて「EAステージ(EX or MA stage)」と称する。
WBステージ
WBステージのブロック図を以下に示し、解説を続けます。

- WBステージ: Write Back (memory bus read data phase) stage
- MAステージが発行したメモリバスアクセスを受けて、読み出しデータbdatrを回収する。
- メモリバスプロトコルのリードデータ相に相当する。
- 読み出したデータを宛先レジスタrdへ書き込む。
- brdy=0の間、WB_busyをアサートして、WBステージの実行サイクルを延長する。
- EXステージとの間で、宛先レジスタrdが競合した場合、後続命令であるEXが優先。
4段パイプラインの各ステージでどのような仕事を担当するのか、ブロック図を作成して検討が終了しました。各ステージは同時並列に処理を実行するので、次回以降、共有資源の競合などについて検討を広げます。


