FPGA開発日記

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

自作RISC-Vアウトオブオーダコアの実装 (FPU演算のFFLAGSアップデートのサポート)

自作RISC-Vアウトオブオーダコアの実装、FPUを実装している。 基本的な演算について、FPNewとの接続作業は完了した。演算自体は上手く回ってFPレジスタに答えを書くことが出来ているようだが、問題はFFLAGSをアップデートするパスを用意していなかった。この実装方法について考える。

FFLAGSはシステムレジスタとして定義されており、以下のビットフィールドを持つ。

FFLAGSレジスタは演算命令によってまい命令アップデートされるため、汎用レジスタと同様に扱う必要がある。つまり、アウトオブオーダ実行を行ったとしても正しくフラグの結果を更新する必要があり、FPレジスタと同様にリネームのような処理が必要となる。

したがって、いくつかの実装方法がありそうだ。

  • ROBの命令エントリ毎にFFLAGSの結果を保持しておき、コミット時にFFLAGSシステムレジスタを更新する。
  • FPR書き込みレジスタと同様にリネームし、FFLAGS専用の物理レジスタファイルを用意しそこに書き込む。コミット時にFFLAGSシステムレジスタを更新する。

1番目の方法はROBのすべてのエントリにFFLAGSの途中格納レジスタを保持するためROBが大きくなってしまうが、簡単なのでまずはこっちで実装してみることにする。 2番目の方法は、リネーム番号をどこから拾ってくるかという問題がある。通常のFPU演算であればFPRのリネームIDと兼用すれば良いが、それ以外の例えばFEQ命令の場合はリネームIDは整数側から取ってくる必要がある。その整合性を取るのがちょっと面倒くさそうだ(前のFADD命令のFPRリネームIDと次のFEQ命令のGPRリネームIDが一緒だったらどうするのか、など)。

スケジューラの部分はALU命令とFPU命令(と、それ以外のLSU以外の命令)はスケジューラの実装を統一しているためFPU以外のスケジューラにもFFLAGSのアップデート信号が入ってしまうが、まあこれはとりあえず無視するということにしている。

これらの実装とFPNewの実装を組み合わせて、とりあえず基本的なFPU命令のテストケースをPassさせることが出来るようになってきた。

2586 : 78 : PC=[00000000800001a0] (U,14,02) 021071d3 fadd.d  ft3, ft0, ft1
2587 : 79 : PC=[00000000800001a4] (U,15,01) e2018553 fmv.x.d a0, ft3
2660 : 91 : PC=[00000000800001d4] (U,03,02) 021071d3 fadd.d  ft3, ft0, ft1
2661 : 92 : PC=[00000000800001d8] (U,04,01) e2018553 fmv.x.d a0, ft3
2732 : 104 : PC=[0000000080000208] (U,08,02) 021071d3 fadd.d  ft3, ft0, ft1
2733 : 105 : PC=[000000008000020c] (U,09,01) e2018553 fmv.x.d a0, ft3
2796 : 117 : PC=[000000008000023c] (U,13,02) 0a1071d3 fsub.d  ft3, ft0, ft1
2797 : 118 : PC=[0000000080000240] (U,14,01) e2018553 fmv.x.d a0, ft3
2860 : 130 : PC=[0000000080000270] (U,02,02) 0a1071d3 fsub.d  ft3, ft0, ft1
2861 : 131 : PC=[0000000080000274] (U,03,01) e2018553 fmv.x.d a0, ft3
2925 : 143 : PC=[00000000800002a4] (U,08,02) 0a1071d3 fsub.d  ft3, ft0, ft1
2926 : 144 : PC=[00000000800002a8] (U,09,01) e2018553 fmv.x.d a0, ft3
2997 : 156 : PC=[00000000800002d8] (U,13,02) 121071d3 fmul.d  ft3, ft0, ft1
2998 : 157 : PC=[00000000800002dc] (U,14,01) e2018553 fmv.x.d a0, ft3
3061 : 169 : PC=[000000008000030c] (U,02,02) 121071d3 fmul.d  ft3, ft0, ft1
3062 : 170 : PC=[0000000080000310] (U,03,01) e2018553 fmv.x.d a0, ft3
3125 : 182 : PC=[0000000080000340] (U,07,02) 121071d3 fmul.d  ft3, ft0, ft1
3126 : 183 : PC=[0000000080000344] (U,08,01) e2018553 fmv.x.d a0, ft3
3190 : 195 : PC=[0000000080000374] (U,13,02) 0a1071d3 fsub.d  ft3, ft0, ft1
3191 : 196 : PC=[0000000080000378] (U,14,01) e2018553 fmv.x.d a0, ft3