FPGA開発日記

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

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

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

docs.boom-core.org


分岐ユニット & 分岐命令の投機実行

分岐ユニット は、すべての分岐命令とジャンプ命令の解決を行います。

パイプラインの中で “インフライト “である(割り当てられたROBエントリを持つ)すべての UOPs<Micro-Op (UOP) には分岐マスクが与えられます。 分岐マスクの各ビットは、 UOPs<Micro-Op (UOP) が予測されるされる未実行のインフライト分岐に対応しています。 デコード の各分岐命令には分岐タグが割り当てられ、それに続くすべての UOPs<Micro-Op (UOP) には分岐マスクの対応するビットが設定されます ( Branch Unit でブランチが解決されるまで)。

分岐(またはジャンプ)が フロントエンド によって正しく推測された場合、 分岐ユニット の唯一のアクションは、 ブランチが正しく解決されたことを 全ての インフライトの UOPs<Micro-Op (UOP) に対応する分岐タグをブロードキャストすることです。 各 UOP<Micro-Op (UOP) は、その分岐マスクの対応するビットをクリアすることができ、 その分岐タグは、その後、Decode ステージで新しいブランチに割り当てることができます。

もし分岐(またはジャンプ)の予測が間違っていた場合、 分岐ユニット は PC を正しいターゲットにリダイレクトし、 フロントエンド と フェッチバッファ を殺し、 依存しているすべての機内の UOPs<Micro-Op (UOP) を殺すことができるように、予測が間違っている分岐タグをブロードキャストしなければなりません。 PCリダイレクト信号は、分岐予測ミスのペナルティを減らすために、すぐに出力されます。 しかし、kill 信号はクリティカルパス上の理由から1サイクル遅れます。

フロントエンド は、正しい方向を予測と一致させるために、 適切な分岐推測のメタデータをパイプラインに渡さなければなりません。 ジャンプレジスタ命令は、正しいターゲットとROB内の次の命令のPCを比較して評価されます(利用できない場合は、分岐予測ミスが想定されます)。 ジャンプは フロントエンド で評価され、処理されます(命令がデコードできるようになると、その方向とターゲットの両方が判明するため)。

BOOMは(現在のところ)1つの 分岐ユニット を持つことのみをサポートしています。

ロードストアユニット

ロード/ストアユニット(LSU) は、ロード、ストア、アトミック、フェンスの各オペレーションの実行を担当します。

BOOMは(現在)、1つのLSUを持つことしかサポートしていません(したがって、1サイクルあたり1つのロードまたはストアをメモリに送ることしかできません)。2

LSUの詳細については 「ロードストアユニット」 を参照してください。

浮動小数点ユニット

Functional Unit for FPU

Fig. 23 FPUのクラス階層を示します。専門家によって書かれたコードは、hardfloatとrocketのリポジトリに含まれています。 “FPU”クラスはRocketコンポーネントインスタンス化し、 それ自体はさらに抽象的な 機能ユニット クラスによってラップされています(これはアウトオブオーダーの投機サポートを提供します)。

BOOM で使用される低レベルの浮動小数点ユニットは、Rocket プロセッサ (https://github.com/chipsalliance/rocket-chip) と hardfloat (https://github.com/ucb-bar/berkeley-hardfloat) のリポジトリから取得しています。 図 Fig. 23 は、FPU のクラス階層を示しています。

書き込みポートのスケジューリングが容易になるように、パイプライン化されたFPユニットはすべて同じレイテンシになるようにパディングされています。3

浮動小数点除算と平方根ユニット

BOOM は、単一の FDiv/Sqrt (略して fdiv) を用いた浮動小数点の除算と平方根演算を完全にサポートしています。 BOOM は hardfloat リポジトリから倍精度ユニットをインスタンス化することでこれを実現しています。 このユニットには以下のような機能・制約があります。

  • 65ビットの再コード化された倍精度入力を期待する
  • 65ビットに再コード化された倍精度の出力を提供する
  • 除算と平方根の演算を同時に実行可能
  • 演算はパイプライン化されておらず、未知の可変レイテンシーを要する
  • 不安定FIFOインターフェース

単精度演算は、オペランドが倍精度にアップスケールされ、出力はダウンスケールされます。4

このユニットは非パイプラインですが、他の 機能ユニット で使用されている Pipelined/Unpipelined の抽象化にはきれいに収まりません ( Fig. 22 参照)。 これは、このユニットが不安定なFIFOインターフェースを提供しているからです。 ユニットはサイクルiready 信号を提供しているかもしれませんが、たとえ操作がキューに入っていなくても、 サイクル i+1ready であり続けるという保証はありません。 これは、命令発行キューが命令を発行しようとしても、 後のサイクルでユニットに届いたときにユニットがそれを受け入れるかどうか確信が持てないため、難しい問題となります。

解決策としては、ユニット内に追加のバッファリングを追加して、命令がユニットに直接リリースされるまでの間、 命令を保持することです。ユニットのバッファリングが一杯になったら、 バックプレッシャーをかけて 命令発行キュー に安全にアクセスできます。5

パラメータ化

BOOMは命令発行の幅や実行パイプラインの中の 機能ユニット の組み合わせを柔軟に指定することができます。 BOOMの実行パイプラインをどのようにインスタンス化するかについての詳細な見解は、 src/main/scala/exu/execution-units.scala を参照してください。

FPユニットのレイテンシーなどに関する追加のパラメータ設定は、コンフィギュレーション設定(src/main/common/config-mixins.scala)の中にあります。

Control/Statusレジスタ操作命令

CSR(Control/Status Register) 命令群により、コントロール/ステータス・レジスタのアトミックな読み出し/書き込みが可能になりました。 これらのアーキテクチャレジスタは、整数レジスタやフローティング・レジスタとは別に、サイクル・カウント、リタイア命令カウント、ステータス、例外PC、例外ベクタ・レジスタ(その他多数)を含んでいます。 各CSRには、読み書きに必要な特権レベルがあり、読み書き時に独自の副作用が発生するものもあります。

BOOMは(現在)CSRの名前を変更しません。 また、CSRの読み書きによって生じる潜在的な副作用に加えて、BOOMはCSR命令を非特定的にしか実行しません 6 これは、CSR命令を「ユニーク」(または「シリアライズ」)な命令としてマークすることで実現します。 その後、命令発行キューで発行され、物理レジスタ・ファイルから適切なオペランドを読み込み、CSRファイルに送られます。7 CSR命令はCSRFileで実行され、必要に応じて物理レジスタファイルにデータを書き戻します。 CSRFileは、CSR命令(例:syscall)の実行の一部として、PCリダイレクトや例外を発することもあります。

RoCCインタフェース は,コントロール・プロセッサのスカラ・レジスタ・ファイルから、RoCCコマンドと最大2つのレジスタ入力を受け付ける。 RoCCコマンドは、コントロール・プロセッサによってフェッチされたRISC-V命令全体(“RoCC命令”)となります。 したがって,各RoCCキューのエントリは,最低でも 2\*XPRLEN + 32 ビットのサイズになります (追加のRoCC命令は,より長い命令フォーマットを使用して追加の動作をエンコードすることができます)。

BOOMはROBに命令ビットを格納しないので、別のデータ構造(A “RoCC Shim”)は、 RoCC命令がコミットされ、RoCCコマンドがコプロセッサに送信されるまで、命令を保持します。

また、ソース・オペランドは、BOOMのレジスタ・ファイルにアクセスする必要がある。 RoCC命令はイシューウィンドウにディスパッチされ、オペランドが利用可能になった時点でレジスタファイルのリードポートにアクセスできるようにスケジューリングされます。 その後、オペランドはRoCC Shimに書き込まれ、コプロセッサに送信されるまでオペランドと命令ビットが保存されます。 これには重要な状態が必要です。

RoCCへの発行後、飛行中のRoCC命令のキューを追跡します。 これは、RoCCレスポンスからの論理的なデスティネーション・レジスタ識別子を、 以前に名前を変更した物理的なデスティネーション・レジスタ識別子に変換する必要があるためです。

現在、RoCCインターフェイスは、割り込み、例外処理、BOOM FPUの再利用、L1データキャッシュへの直接アクセスなどをサポートしていません。 これらはすべて簡単に追加できるはずで、需要があれば完成させる予定です。