FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

BOOM (Berkeley Out-of-Order Machine) のマイクロアーキテクチャドキュメントを読む (2)

RISC-VのアウトオブオーダコアであるBOOM (Berkely Out-of-Order Machine) について勉強を進めている。以下のドキュメントを日本語に訳しながら読んでいくことにした。

docs.boom-core.org


RISC-V命令セットアーキテクチャ

RISC-V ISAは、広く採用されているオープンソースのISAで、 さまざまなアプリケーションに適しています。 BOOM は RISC-V ISA の RV64GCバリエーション (別称 IMAFDC) 1 を実装しています。 これには,MAFDC 拡張と特権的仕様(乗算/除算、AMO、ロード・リザーブ/ストア・コンディショナル、 単精度および倍 精度の IEEE 754-2008 浮動小数点)が含まれています.

RISC-Vには、以下のような特徴があり、高性能な設計に対応しやすくなっています。

  • リラックスメモリモデル

    これにより、ロードが他のロードをスヌープする必要も、コヒーレンストラフィックがLSUをスヌープする必要もなく、 Load/Store Unit (LSU) が大幅に簡素化されます(シーケンシャル・コンシステンシーでは必要)。

  • 正確な浮動小数点(FP) 例外フラグ

    FPステータスレジスタのリネームを行う必要はありませんし、 FP命令自体が例外を発生させることもありません.

  • 整数命令の副作用無し

    すべての整数ALU演算は、書き込みレジスタの書き込み以外には、副作用がありません。 これにより、追加のコンディション・ステートのリネームの必要がなくなります。

  • CMOVとプレディケーション命令の不採用

    プレディケーションは、小規模な設計であれば分岐予測器の複雑さを軽減することができますが、 整数演算用に3つ目の読み出しポートを追加するなど、 アウトオブオーダーパイプラインを大幅に複雑化させます。

  • 暗黙的なレジスタ指定を含まない

    JALでさえ、明示的にレジスタを指定する必要があります。これにより、リネームロジックがシンプルになり、 リネームテーブルにアクセスする前にまず命令を知る必要がなくなったり、 命令デコードをクリティカルパスから外すためにポートを増やすことがなくなります。

  • rs1, rs2, rs3, rdレジスタのフィールド位置は常に同一

    これによりデコードとリネームを同時に実行することができます。

RISC-V ISAに関するより詳細な情報は http://riscv.org より参照できます。

1 現在、BOOMは “V”拡張を実装していません。

命令フェッチ

BOOM :term:`Front-end`

BOOM は、Rocket コアが独自の フロントエンド をインスタンス化するのと同様に、独自の フロントエンド をインスタンス化します。 この フロントエンド は、複数のフェッチサイクル (F0F1…) で命令ストリームをリダイレクトするために、 フェッチステージを通して命令をフェッチし、予測を行います。 BOOMの バックエンド (実行パイプライン)で予測の間違いが検出された場合や、 BOOM自身の予測器の一つがパイプラインを別の方向に向けたいと思った場合、 フロントエンド にリクエストが送られ、新しい命令パスに沿ってフェッチを開始します。 分岐予測がフェッチステージのパイプラインにどのように適合するかについての詳細は、 分岐予測 を参照してください。

スーパースカラフェッチがサポートされているので、 フロントエンド は命令メモリから命令の フェッチパケット を取得し、 フェッチバッファ に入れてパイプラインの残りの部分に渡します。 フェッチパケットには、有効マスク(パケット内のどの命令が有効か)や、パイプラインの後半で使用される分岐予測情報など、 他のメタデータも含まれています。 さらに、PCと分岐予測情報は、パイプラインの残りの部分のためにこれらの情報を保持する フェッチターゲットキュー の中に格納されます。

Rocketコア 命令キャッシュ

BOOM は、Rocket プロセッサのソースコードから取得した命令キャッシュをインスタンス化します。 命令キャッシュは、仮想的にインデックスを付け、 物理アドレスにタグを付けたセットアソシアティブキャッシュです。

電力を節約するために、命令キャッシュは固定数のバイト(アラインド)を読み出し、 命令ビットをレジスタに格納します。 さらなる命令のフェッチは、このレジスタで管理できます。 命令キャッシュは、フェッチレジスタが使い果たされたとき(または、分岐予測によってPCが別の場所に移動したとき)にのみ、再び起動されます。

また、スーパースカラ・フェッチ・アドレスに対して(現在では)アンアラインでのフェッチもサポートしていません。1

命令キャッシュは(現在は)it-under-missをサポートしていません。 命令キャッシュにミスが発生した場合、ミスが処理されるまで命令キャッシュはそれ以上のリクエストを受け付けません。 これは、パイプラインがブランチの分岐予測失敗を検出し、 正しいパスに沿ってフェッチを開始するために命令キャッシュをリダイレクトしたい場合には理想的ではありません。

Compressed命令のフェッチ

このセクションでは、 RISC-V Compressed ISA extension が BOOM にどのように実装されたかを説明します。 Compressed ISA 拡張 (RVC)は、一般的な命令をより小さな16ビットのエンコーディングにすることで、 スタティックおよびダイナミックなコードサイズを小さくすることができます。 “RVC “には、マイクロアーキテクトにとって特に興味深いいくつかの機能が搭載されています。

  • 32ビットの命令はアライメントの制約が無く、16バイトの境界から開始することができる。
  • 全ての16ビット命令はより長い32ビットの命令にマッピングすることができる。

BOOM は フロントエンド ステージにおいて、命令キャッシュから フェッチパケット を取得し、 分岐予測のために命令を素早くデコードして、 フェッチパケット を フェッチバッファ にプッシュします。 しかし、これを行うには、管理すべき特殊な問題が発生します。

  • デコードの複雑さが増す(オペランドが位置が変わるようになったため)。
  • 命令が どこから 始まるかを見つける必要がある。
  • コードベース全体での +4 の仮定の削除(特に分岐処理で)。
  • アンアラインド命令、特にキャッシュラインや仮想ページからの実行。

最後の点については、命令のすべての部分をフェッチするのに複数のサイクルを要することがあるため、 フェッチユニット に追加の “statefulness” が必要になります。

以下では、命令の寿命を記述することで、BOOMにおけるRVCの実装を説明します。

  • フロントエンド は fetchWidth という 16ビット幅の フェッチパケット を返します。 これは、BOOMの フロントエンド で本質的にサポートされていました。
  • F3 では、 フェッチパケット が命令キャッシュのレスポンスキューからデキューされ、 フェッチバッファ にエンキューされるサイクルにおいて、ステートフルネスを維持します。
  • F3 は、最後の フェッチパケット の末尾の16ビット、PC、および命令境界を追跡します。 これらのビットは、現在の フェッチパケット と結合され、 fetchWidth に拡張され、 フェッチバッファ にエンキューされます。 プリデコードは、この フェッチパケット 内のすべての命令の開始アドレスを決定し、 フェッチパケット を フェッチバッファ 用にマスクします。
  • フェッチバッファ は、メモリに格納する際に、無効な命令やミスアラインメントの命令を圧縮します。

次のセクションでは、その他の実装の詳細について説明します。

  • 困難な問題は、 フェッチ境界 を越える命令を扱うことです。 このような命令は、その上位16ビットを含む フェッチパケット に属するものとして追跡します。 これらの命令のPCを決定する際には、最初に フェッチ境界 を越えてミスアラインされたすべての命令を追跡することで、 注意しなければなりません。
  • また、パイプラインは、命令が元々16ビットだったのか32ビットだったのかを追跡し、PC+4PC+2 を計算する必要があります。