FPGA開発日記

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

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (7. KunmingHuのビルドと試行)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

実際のGitHubリポジトリをダウンロードして、いろいろ試してみようと思う。

xiangshan-doc.readthedocs.io


  • Gitリポジトリのダウンロード:

以下で、build/XSTop.vにChiselから生成されたVerilogが生成される。

git clone https://github.com/OpenXiangShan/XiangShan.git --recurse-submodules
cd XiangShan
make verilog

ちなみに、ドキュメントに書いてある通りの以下のコマンドだと落ちてしまった。

make emu CONFIG=MinimalConfig MFC=1 -j$(nproc)
[warn]       intrGenRegs(randomPosition(5)) := intrReg(randomPosition(5)) | UIntToOH(randomPosition(4, 0))
[warn]                  ^
[warn] There were 63 warning(s) during hardware elaboration.
Exception in thread "main" java.util.NoSuchElementException: NOOP_HOME
        at ... ()
...
        at logger.Logger$.$anonfun$makeScope$4(Logger.scala:148)
        at scala.util.DynamicVariable.withValue(DynamicVariable.scala:59)
        at logger.Logger$.makeScope(Logger.scala:146)
        at logger.Logger$.makeScope(Logger.scala:133)
        at ... ()
        at ... (Stack trace trimmed to user code only. Rerun with --full-stacktrace to see the full stack trace)
1 targets failed
xiangshan[chisel].test.runMain subprocess failed
make: *** [Makefile:133: build/rtl/SimTop.v] Error 1

ブランチをkunminghuに変更してみたが、それでもだめだった。

git checkout kunminghu
git submodule update --init --recursive
make emu CONFIG=MinimalConfig MFC=1 -j$(nproc)

一応、MFC=1だけ(MLIRを使用する)では、ビルドしてVerilogファイルを生成できるようだ。

make MFC=1 -j$(nproc) 

もうちょっとマニュアルをまじめに見ながらやってみる。

git clone https://github.com/OpenXiangShan/NEMU.git
cd NEMU
export NEMU_HOME=${PWD}
cd ..
git clone https://github.com/OpenXiangShan/nexus-am.git
cd nexus-am
export AM_HOME=${PWD}
cd XiangShan
export NOOP_HOME=${PWD}
make emu CONFIG=MinimalConfig MFC=1 -j$(nproc)

パッケージのインストールが必要だ:

make[3]: Entering directory '/home/msyksphinz/work/riscv/xiangshan/XiangShan/build/emu-compile'   
In file included from /home/msyksphinz/work/riscv/xiangshan/XiangShan/build/chisel_db.cpp:2:                                                                                                     
/home/msyksphinz/work/riscv/xiangshan/XiangShan/build/chisel_db.h:12:10: fatal error: sqlite3.h: No such file or directory
   12 | #include <sqlite3.h>                                                                  
      |          ^~~~~~~~~~~                                                                                                                                                                 
compilation terminated.                                                                                                                                                                      
make[3]: *** [VSimTop.mk:94: chisel_db.o] Error 1                                                                                                                                            
make[3]: *** Waiting for unfinished jobs....                                                                                                                                                 
In file included from /home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest/src/test/csrc/common/compress.cpp:17:                                                                             
/home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest/src/test/csrc/common/compress.h:26:10: fatal error: zstd.h: No such file or directory                                                   
   26 | #include <zstd.h>                                                                                                                                                                    
      |          ^~~~~~~~                                                                                                                                                                    
compilation terminated.                                                                       
make[3]: *** [VSimTop.mk:104: compress.o] Error 1                                                                                                                                            
In file included from /home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest/src/test/csrc/common/ram.cpp:22:
/home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest/src/test/csrc/common/compress.h:26:10: fatal error: zstd.h: No such file or directory                                                   
   26 | #include <zstd.h>                                                                                                                                                                    
      |          ^~~~~~~~                                                                     
compilation terminated.                                                                       
make[3]: *** [VSimTop.mk:124: ram.o] Error 1                                                                                                                                                 
make[3]: Leaving directory '/home/msyksphinz/work/riscv/xiangshan/XiangShan/build/emu-compile'    
make[2]: *** [verilator.mk:140: build_emu_local] Error 2                                      
make[2]: Leaving directory '/home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest'                                                                                                            
make[1]: *** [verilator.mk:144: /home/msyksphinz/work/riscv/xiangshan/XiangShan/build/emu] Error 2                                                                                               
make[1]: Leaving directory '/home/msyksphinz/work/riscv/xiangshan/XiangShan/difftest'             
make: *** [Makefile:179: emu] Error 2                                                                                                                                                        
sudo apt install libsqlite3-dev libzstd-dev

で、やり直し。すると、うまくいったようだ。なにやらVerilatorのビルドが走り始めた。結構時間がかかるようだ。

Coremarkも試してみる。

The image is /home/msyksphinz/work/riscv/xiangshan/nexus-am/apps/coremark/build/coremark-riscv64-xs.bin
Running CoreMark for 10 iterations
2K performance run parameters for coremark.
CoreMark Size    : 666
Total time (ms)  : 21663
Iterations       : 10
Compiler version : GCC13.1.0
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0xfcaf
Finished in 21663 ms.
==================================================
CoreMark Iterations/Sec 461

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (6. Kuminghuのマイクロアーキテクチャ続き)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

次は、マイクロアーキテクチャのトピックについて。続き。

xiangshan-doc.readthedocs.io


  • フロントエンドのアップデート
    • フェッチ・予測の幅を増強
    • ミス率の低減
    • 高周波数化
  • TAGEの予測器の性能向上
    • Branch Historyのハッシュ化
    • テーブルと履歴長の調整
  • L2 Fetch Target Buffer (FTB)のアップデート
    • FTBは要するにBTBのこと。
    • 4KBのL2 FTBを実装。
    • FTBP というのは L1 & L2 の中間バッファのこと。
  • 命令キャッシュのプリフェッチャのアップデート
    • フロントエンドが分離されたので、FDIPのプリフェッチアルゴリズムを実装。
    • PFキューからプリフェッチリクエストを選択
    • プリフェッチバッファにリフィルデータを書き込む。
    • 命令キャッシュとプリフェッチバッファの検索を並列に行う。
  • バックエンドパイプラインの改良
    • 発行後にレジスタを読み込むように変更
      • リザベーションステーションの回路量を削減するという目的がある。
      • レジスタファイルを読み込むための効率的なアービタを実装する。
      • 投機的なウェイクアップとキャンセルを実装する。
    • uopのコミットとリダイレクトを高速化
      • リネームバッファ(RAB)を実装し、レジスタファイルの変更履歴を記録する。
        • リネームバッファにレジスタファイルのマッピング情報を記録する。
        • 命令がコミット・リダイレクトすると、RABをウェイクアップする
        • RABはリネームテーブルをアップデートする責任を持つ
      • 利点
        • ROBのリリースを高速化する
        • タイミングを最適化する
        • Vector命令のuopへの分割をサポートする
        • ROBを圧縮する
    • ベクトルパイプラインを実装
      • VLEN=128のベクトル命令をサポート
      • デコード・ディスパッチ・アウトオブオーダ実行を共有
  • ロードステアユニットのアップデート
    • L1D SRAMの消費電力を削減するため、ウェイ予測を導入する
    • ロードストアのバンド幅を向上させるため、ハイブリッド・ロード・ストアユニットを導入する
    • L1Dプリフェッチを導入する
      • StreamプリフェッチャとStrideプリフェッチャを導入する
    • ロードキューのタイミングを向上させるため、ロードキューを分割する
      • ロードキューを状況に応じて分割して割り当てる
        • ライトバック後に仮想ロードキューから順番にリタイアすることができる
    • TLBのタイミング向上のため、L1/L2 TLBを再デザインする

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (5. Kuminghuのマイクロアーキテクチャ)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

次は、マイクロアーキテクチャのトピックについて。続き。

xiangshan-doc.readthedocs.io


  • 実装はハードウェア記述言語Chiselで行っている。
    • いくつかの高性能ユーティリティを実装した。
  • 性能カウンタを搭載し、性能を簡単に測定できるようにする。
  • KunmingHu : 第3世代のマイクロアーキテクチャ
    • Beijing Institute of Open Source Chip (BOSC) と共同で開発
    • RISC-V Vector Extension 1.0をサポート
    • RISC-V ハイパーバイザをサポート
    • ループ予測器、ループバッファをサポート
    • 命令キュー・実行ユニット・ロードストアユニットをリファクタリング
    • L1Dプリフェッチャを実装
    • AMBA CHI互換
  • KunmingHu の性能見積もり
    • Simpointによりチェックポイントを測定。
    • 3GHzで44.98のスコアを想定。

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (4. Microarchitecture Design and Implementation)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

次は、マイクロアーキテクチャのトピックについて。続き。

xiangshan-doc.readthedocs.io


  • バックエンドの構成
  • 命令フュージョン
    • 隣接しているuOPsを結合する。
    • RV64GCとRV64GC-Fusedで4%の命令削減、RV64GCBからRV64GCB-Fusedで2%の命令削減。
  • Rename & Move Elimination
    • 単純なmove命令は、リネームマップの差し替えにより実現する。
  • Reservation Stationの構成
    • 2-input & 2-output / 1-input & 1-outputの構成
    • Age Matrixベースの命令選択
  • FPUの構成
    • IEEE 754互換の浮動小数点実行ハードウェア
  • FPUはCascade FMAを実装。
    • FADDのDelayは5サイクルから3サイクルに削減。
  • MMUの構成
    • STLB向けにNext Line Prefetcherを実装
    • Page Table Walkを並列実行
    • PMP / PMAをサポート
  • メモリ・アクセスのブロック
    • ロードパイプラインは2本用意
    • LDヒットレイテンシ:4サイクル
    • ストアアドレスパイプライン:2
    • ストアデータパイプライン:2
    • ストアデータのバンド幅 : 2x8B/cycle
    • マージバッファ:16キャッシュライン
  • ロード・パイプライン
    • 4ステージ構成
  • L1 Dキャッシュ
    • ライトバック・キューはどういう仕組みだろう?
  • L1 Dキャッシュ
    • バンクを分割し、複数リードポートを持っている。

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (3. Microarchitecture Design and Implemenation)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

次は、マイクロアーキテクチャのトピックについて。

xiangshan-doc.readthedocs.io


XiangShanには3つの世代がある。

  • YQH : 28nm でテープアウトし1.3GHz。性能的にはSPEC CPU2006 7.01 @1GHz
  • NH : 14nmでテープアウトし2.0GHz。性能的にはSPEC CPU2006 20 @2GHz
  • KMH : Vector拡張とハイパーバイザー拡張を実装。
  • まずは第1世代のYQHについて。
    • 11ステージの6命令デコード・リネーム
    • TAGE-SC-Lの分岐予測器を実装
    • 整数物理レジスタ160エントリ、浮動小数点物理レジスタ160エントリ
    • 192エントリのROB、64エントリのLQ、48エントリのSQ
    • 各機能ユニットには16エントリのRS
    • 16KBのL1命令キャッシュ、128KBのL1plus命令キャッシュ
    • 32KBのL1データキャッシュ
    • 32エントリのITLB / DTLB, 4KエントリのSTLB
    • 1MBのインクルーシブ・L2キャッシュ
  • YQHのマイクロアーキテクチャ(パイプライン)
    • ディスパッチするときにレジスタを読むスタイル。14Read / 8Write
    • 最大コミット数は6命令/1サイクル
  • 第2世代、NHのアーキテクチャ
    • 整数物理レジスタ196エントリ、浮動小数点物理レジスタ192エントリに増強
    • ROBは256エントリに増強、80エントリのLQ、64エントリのSQに増強
    • 算術演算ユニットは各32エントリのRS
    • 64KBのL1命令キャッシュ
    • 64KBのL1データキャッシュ
    • 80エントリのDTLB、32エントリのITLB、2KエントリのSTLB
    • 1MBのノン・インクルーシブL2キャッシュ
    • 6MBのノン・インクルーシブL3キャッシュ
  • NHのフロントエンド
    • フロントエンドをProducerとConsumerに分離。
      • Producer : 分岐予測ユニット
      • Consumer : 命令フェッチユニット
  • 分岐予測について
    • 3ステージの分岐予測
      • ステージ1: uBTB
      • ステージ2: FTB + TAGE (FTB : Fetch Target Bufferのこと)
      • ステージ3: SC + ITAGE + RAS (SCは良く分からないが、Statistical Correctorのこと?)
  • 命令キャッシュ
    • 64KBの4-way VIPTブロッキングキャッシュ
    • TileLinkをサポート
    • PLRUのリプレースメント

Vivado Simulatorを用いてUVMに入門する (3. テストベンチの解析)

UVMに入門したくて、簡単な例を用いて試してみることにした。以下のようなシンプルなデザインをテストしたい。

vlsiverify.com

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com


次にMonitorとScoreboardについてみていこうと思う。

monitorについては、駆動側と同様にseq_item mon_itemを用意し、そこに工藤側から生成された入力値を入れておく。 そしてこのadderは計算結果を出力するのに1サイクル必要なため、@(posedge vif.clk)だけ待ってから、DUTの計算結果を格納する。 そして、その結果をitem_collect_portに格納する。item_collect_portseq_itemを含んだuvm_analysis_portで、これの詳細は正直よくわからない。

  task run_phase (uvm_phase phase);
    forever begin
      wait(!vif.reset);
      @(posedge vif.clk);
      mon_item.ip1 = vif.ip1;
      mon_item.ip2 = vif.ip2;
      `uvm_info(get_type_name, $sformatf("ip1 = %0d, ip2 = %0d", mon_item.ip1, mon_item.ip2), UVM_HIGH);
      @(posedge vif.clk);
      mon_item.out = vif.out;
      item_collect_port.write(mon_item);
    end
  endtask

とにかく、このrun_phaseによって、item_collect_port.write()が実行されすべての情報が格納されるというわけだ。

そして、scoreboardによって検証が行われる。scoreboardrun_phaseはでは、item_qの中から1つの要素が取り出され、計算結果があっているかの検証が行われる。 上記のmonitorが、item_collect_port.write()を呼び出したのは、下記のwrite()と同一なのだろうか?この辺の詳細もよくわからない。

  function void write(seq_item req);
    item_q.push_back(req);
  endfunction

  task run_phase (uvm_phase phase);
    seq_item sb_item;
    forever begin
      wait(item_q.size > 0);

      if(item_q.size > 0) begin
        sb_item = item_q.pop_front();
        $display("----------------------------------------------------------------------------------------------------------");
        if(sb_item.ip1 + sb_item.ip2 == sb_item.out) begin
          `uvm_info(get_type_name, $sformatf("Matched: ip1 = %0d, ip2 = %0d, out = %0d", sb_item.ip1, sb_item.ip2, sb_item.out),UVM_LOW);
        end
        else begin
          `uvm_error(get_name, $sformatf("NOT matched: ip1 = %0d, ip2 = %0d, out = %0d", sb_item.ip1, sb_item.ip2, sb_item.out));
        end
        $display("----------------------------------------------------------------------------------------------------------");
      end
    end
  endtask

つまり、UVMの検証環境は、スコアボードによってうまく一致が検出できるようにテストを構成できるか、というのが肝になるのではなかろうか。 つまり、一致比較が可能なようにテストを構成し、Scoreboardでうまく一致比較することがポイントとなる。

RISC-Vの高性能アウト・オブ・オーダCPU XiangShanについての資料を読む (2. XiangShanのAgile Development)

HPCA2024で開催された、RISC-Vのアウト・オブ・オーダCPU XiangShanについての資料が公開されていたので、読んでみることにした。 じっくり読みたいので、1ページずつ要点を抑えていく。

xiangshan-doc.readthedocs.io


次に、XiangShanを支えるAgile Developmentについて見て行く。

最初のアプローチとしては、Chiselを使って開発するというものである。

新しいハードウェア記述言語を使用することによって、デザインのオブジェクト指向化を行い、よりコンフィギャラブルにすることが目的である。

Agile Developmentにおいて必要な要素は何か?それは検証である。

Agile Developmentを支える検証ツールチェインについて見て行く。

Difftestというテスト環境を用意する。命令がコミットされると、命令セットシミュレータが同じ命令を実行し、結果を比較する。

性能評価のために、RTLシミュレーションとチェックポイントの機能を導入する。 チェックポイントによって、コンパイル20分と、シミュレーションはおよそ5時間で実行することができる。

これには4つのステップが必要である:

  1. 高速なシミュレータを使って、命令群をスライスしながらシミュレーションする
  2. クラスタリングアルゴリズムを用いて、代表的なスライスを選出する
  3. RTLシミュレーションを実行する
  4. 再構築する

この手法によって、17個の新しいツールを作成して、検証を高速化した。この成果はMICRO2022に掲載された。

XiangShanでは、3つのポイントのうち2.5個を達成した。

研究のための理想的なインフラストラクチャについて考える。

  • Imprecise Store Exceptions (ISCA23)で使用された。
  • Fast, Robust and Transferable Prediction for Hardware Logic Synthesis (MICRO23)で使用された。