FPGA開発日記

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

Chiselを使ってCPUを作ろう(10. Configurationを1つのcaseにまとめる)

f:id:msyksphinz:20181123005953p:plain

Chiselを使って、非常にシンプルなCPUを作ってみるプロジェクト、テストパタンを動かしながらデバッグしている。 いくつかコンフィグレーションを変えながら動かしたいところがあり、またVerilogのパラメータのように扱いたい部分があるのだが、Chiselにはcaseを用いたコンフィグレーションの設定方法があるらしい。

RISC-V Sodorには以下のような記述がみられた。

  • src/common/configuration.scala
case class SodorConfiguration()
{
   val xprlen = 32
   val nxpr = 32
   val nxprbits = log2Ceil(nxpr)
   val rvc = false
   val vm = false
   val usingUser = false
}
  • src/rv32_1stage/cpath.scala
class CpathIo(implicit val conf: SodorConfiguration) extends Bundle()
{
   val dcpath = Flipped(new DebugCPath())
   val imem = new MemPortIo(conf.xprlen)
   val dmem = new MemPortIo(conf.xprlen)
   val dat  = Flipped(new DatToCtlIo())
   val ctl  = new CtlToDatIo()
   override def cloneType = { new CpathIo().asInstanceOf[this.type] }
}

上記のように、implicit valとしてパラメータの一式をデザインに渡すことができる。これを自作RISC-V CPUにも適用しよう。 以下のようなConfigurationを作成する。

case class RV64IConf()
{
  val xlen = 64
  val bus_width = 16
}

各モジュールを、このConfigurationを使うように書き換えた。

class Cpu (implicit val conf: RV64IConf) extends Module {
  val io = IO (new CpuIo())

  val u_cpath   = Module (new CtlPath)
  val u_regs    = Module (new Regs)
  val u_alu     = Module (new Alu)
  val u_csrfile = Module (new CsrFile)

...

一番上位mainになる部分や、モジュールをインスタンスする部分については、以下のようにして明示的にConfigurationを渡してやることが必要らしい。

object CpuTop extends App {
  implicit val conf = RV64IConf()
  chisel3.Driver.execute(args, () => new CpuTop())
}
  • テスト実行記述
  "Basic test using Driver.execute" should "be used as an alternative way to run specification" in {
    implicit val conf = RV64IConf()
    iotesters.Driver.execute(Array(), () => new CpuTop()) {
      c => new CpuTopTests(c)
    } should be (true)
  }

これで、コンフィグレーションを任意に変更できるようになった。