FPGA開発日記

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

Chipyardで独自コアシミュレーション環境構築方法の調査

Chipyardの環境ではScalaで実装しているRocket-ChipやBOOMコアもインスタンス化することができるが、それ以外にSystemVerilogで実装されているArianeもシミュレーションを実行することができる。

つまり、SystemVerilogで実装した独自CPUコアに対してもChipyardの環境を構築することができるということだ。この方法について調査しようと思う。

ArianeのChipyard用Wrapper

ArianeはSystemVerilogで記述されているため、これをそのままChiselベースのChipyardに載せることは出来ない。このため、Chiselで書いたSystemVerilog用のWrapperを用いることになる。

f:id:msyksphinz:20210119010740p:plain:w300

ここで大事なのはArinaneCoreBlackBoxで、ここにはSystemVerilogのデザインをラップするための機能が入っている。

  • src/main/scala/ArianeCoreBlackbox.scala
class ArianeCoreBlackbox(
  traceportEnabled: Boolean,
  traceportSz: Int,
  xLen: Int,
  rasEntries: Int,
  btbEntries: Int,
  bhtEntries: Int,
  execRegAvail: Int = 5,
...
      extends BlackBox(
    Map(
      "TRACEPORT_SZ" -> IntParam(traceportSz),
      "XLEN" -> IntParam(xLen),
      "RAS_ENTRIES" -> IntParam(rasEntries),
      "BTB_ENTRIES" -> IntParam(btbEntries),
      "BHT_ENTRIES" -> IntParam(bhtEntries),
      "EXEC_REG_CNT" -> IntParam(exeRegCnt),
      "CACHE_REG_CNT" -> IntParam(cacheRegCnt),

このデザインを見て初めて知ったのだが、Chiselの変数をパラメータとして伝搬させることもできるのか。知らなかった。

I/Oの接続は、I/Oポートを宣言してこれをTileで接続するようになっていた。

  • src/main/scala/ArianeCoreBlackbox.scala
  with HasBlackBoxResource
{
  val io = IO(new Bundle {
    val clk_i = Input(Clock())
    val rst_ni = Input(Bool())
    val boot_addr_i = Input(UInt(64.W))
    val hart_id_i = Input(UInt(64.W))
    val irq_i = Input(UInt(2.W))
    val ipi_i = Input(Bool())
    val time_irq_i = Input(Bool())
    val debug_req_i = Input(Bool())
    val trace_o = Output(UInt(traceportSz.W))

    val axi_resp_i_aw_ready      = Input(Bool())
    val axi_req_o_aw_valid       = Output(Bool())
    val axi_req_o_aw_bits_id     = Output(UInt(axiIdWidth.W))
...

最終的なI/Oの接続はTile上で行われている。これはArianeのI/OがAXIのようなのでこれをそのままつなげたようだ。

  • src/main/scala/ArianeTile.scala
  // connect the axi interface
  outer.memAXI4Node.out foreach { case (out, edgeOut) =>
    core.io.axi_resp_i_aw_ready    := out.aw.ready
    out.aw.valid                   := core.io.axi_req_o_aw_valid
    out.aw.bits.id                 := core.io.axi_req_o_aw_bits_id
    out.aw.bits.addr               := core.io.axi_req_o_aw_bits_addr
    out.aw.bits.len                := core.io.axi_req_o_aw_bits_len
    out.aw.bits.size               := core.io.axi_req_o_aw_bits_size

このように、ポートの規格を統一すれば独自コアでもChipyardの環境を構築することができる。今度はこれに挑戦してみよう。