FPGA開発日記

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

RocketChipの足回りを理解する(1. RocketChipのVerilogを読み解く)

RISC-VのUCB実装であるRocketChipはRISC-Vのプロセッサ実装の中で最も参考になるもので、例えばSoCに組み込むとなると真っ先に導入を考えるRISC-V IPの一つだ。

RocketChipはデフォルトで64ビット命令をサポートしており、シンプルなパイプラインながら性能もソコソコ出る、と言うことを謳っている(まあそれが真実かは分からないけれども)。

RocketChipのコアだけを取り出して他のSoCに組み込みたいとき、または自分のバスにRocketChipを接続したいときに、どのようにすればよいのだろう? 適当にgithubから取得してきた環境でMakeして、とりあえずVerilatorでシミュレーションして終わるのならば可能だが、実際のインプリメンテーションとなるとRocketChipは分からないことが多い。 特に足回りの部分だ。

今回は、RocketChipの足回りの構成について、Scalaの実装部分と、出力されたVerilogの部分を見ながら比較、調査してみる。

RockeChipのサンプルデザインで構築される環境

今回は、VerilatorのVCDも分かりにくい、家にVCSなんてライセンスの必要なシミュレータなんて持っているはずもない、という環境のため、QuestaSim Starter Editionを使ってシミュレーションをする環境を構築した。

RocketChipのリポジトリをcloneしてくると、シミュレーション用のディレクトリとして、

  • emulator : Verilatorを使ったシミュレーション
  • vsim : VCSを使ったシミュレーション

ディレクトリが作成されるらしい。何故Questaが無いのだ!という話はあるかもしれないが、これはDPIの仕様などが微妙に異なるためと予想する。

ただし今回はDPIなんて使わずに基本的にリセット解除して、フェッチして、デコードして実行ができればよいので、無駄なものはいろいろ切り取ってシンプルな構成に変更していく。

この結果、RocketChipのデザインで生成されるRTLシミュレーション環境は、大まかに言って以下のような関係になっている。

  • TestDriver
  • TestHarness
  • ExampleRocketTop
  • 足回りの部品など
  • SRAMなど
  • coreplex

このCoreplexというものが実際のRocketCoreだと予想するが、確証はない。そこから先も大量のモジュールがインスタンスされているので、正直どこがコア部分なのか良く分からないのだ。

このcoreplexというモジュールは、RocketPlex_coreplexというモジュールになっている。Verilogファイルを参照してみる。Verilogファイルはrocket-chip/emulator/generated-src/freechips.rocketchip.chipDefaultcConfig.vに格納されている。

module RocketPlex_coreplex(
  input         clock,
  input         reset,
  input         io_interrupts_0_0,
  input         io_interrupts_0_1,
  output        io_l2in_0_a_ready,
  input         io_l2in_0_a_valid,
  input  [2:0]  io_l2in_0_a_bits_opcode,
  input  [2:0]  io_l2in_0_a_bits_param,
  input  [3:0]  io_l2in_0_a_bits_size,
  input  [3:0]  io_l2in_0_a_bits_source,
  input  [31:0] io_l2in_0_a_bits_address,
  input  [7:0]  io_l2in_0_a_bits_mask,
...

大きく分けて以下のバスが搭載されている。

  • io_l2in : External –> coreplex (L2関係?)
  • io_mmio : coreplex –> External (IOMMU関係?)
  • io_mem : coreplex –> External (命令、データフェッチ関係?)
  • io_debug : External –> coreplex (デバッグ関係?)

f:id:msyksphinz:20170712013910p:plain

良く分からないのだけれど、これらのバスはTileLinkと呼ばれるものだろうか?生成されたVerilogの中にも、TLBufferなどというモジュールでは、

module TLBuffer_fsb(
  output        io_in_0_a_ready,
  input         io_in_0_a_valid,
  input  [2:0]  io_in_0_a_bits_opcode,
  input  [2:0]  io_in_0_a_bits_param,
  input  [3:0]  io_in_0_a_bits_size,
  input  [3:0]  io_in_0_a_bits_source,
  input  [31:0] io_in_0_a_bits_address,
  input  [7:0]  io_in_0_a_bits_mask,
  input  [63:0] io_in_0_a_bits_data,
...

という感じでこのバスプロトコルが使われている。これも含め要調査だな。