FPGA開発日記

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

Chisel + Diplomacyでのマルチコア構成デバッグ

自作CPUの構成をマルチコアに変更したので、いくつか問題が表面化してしまっている。例えばメモリは1サイクルでアクセスできる仮定にしていたのを、いくつかValid & Readyの方式に実装し直さなければならない。このためには、とりあえずTileLinkにDelayerを挿入したうえで1コアに絞ってデバッグした方がなにかとやりやすい。という訳でコアの数をConfigurableにする。

まずはコア数はTestHarnessnumCoresとして宣言する。

class TestHarness()(implicit p: Parameters) extends Module {
  val rv_conf = new RV64IConfig
  val numCores = 2

これをcore_complexにパラメータとして伝える。

  val ldut = LazyModule(new core_complex(rv_conf, numCores = numCores, 4, 5000))

core_complexではCPUのインスタンスを以下のように書き換え、numCoresに基づいて複数のCPUをインスタンス化できるようにしている。

class core_complex[Conf <: RVConfig] (conf: Conf, numCores: Int, ramBeatBytes: Int, txns: Int)(implicit p: Parameters) extends LazyModule {
  val loader = LazyModule(new loader("loader"))

  val core   = Seq.fill(numCores) { LazyModule(new CoreTop(conf, 0, "core")) }

バスの接続だが、オブジェクトに対するforeachを用いてバスに対する接続を繰り返し記述するようにする。

  xbar.node := loader.node
  core.foreach { case (core) => {
    xbar.node := TLDelayer(0.1) := core.inst_node
    xbar.node := TLDelayer(0.1) := core.data_node
  }
  }
  memory.node := xbar.node

デバッグポートだが、これもコアの数だけVecの配列として宣言し、それぞれのコアに対して接続するようにした。

  lazy val module = new LazyModuleImp(this) {
    val io = IO(new Bundle {
      val req   = Input(Bool())
      val addr  = Input(UInt(32.W))
      val data  = Input(UInt(32.W))
      val ready = Output(Bool())

      val cpu_dbg = Output(Vec(numCores, new CpuDebugMonitor(conf)))
    })
    // CPU Core Contorl
    val cpu_run = Seq.fill(numCores) { RegInit(false.B) }
    cpu_run.foreach { case(cpu_run) => cpu_run := Mux(io.req && io.req && (io.addr === 0x20000000.U), io.data(0), cpu_run) }

    core.zip(cpu_run).foreach { case (core, cpu_run) => core.module.io.run := cpu_run }

    io.cpu_dbg := core.map { case(core) => core.module.io.dbg_monitor }

これにより、コアの数を自由に変更することができるようになった。例えば、numCores=16としてみる。

f:id:msyksphinz:20201203020015p:plain

くそダサいが、一応こんなことができる。16コアの命令バスとデータバスを直接メモリに繋げるとこんなことができる、ということだ。

とりあえず1コアに戻してデバッグしよう。