Chiselを使って、非常にシンプルなCPUを作ってみるプロジェクト。
CPUコアのバスサイズ、Debug情報のON/OFFなどをパラメータにより調整する。
デザインのパラメタライズ
パラメータ化する項目は、以下のようにして1つのクラスにまとめた。
RVConfig
を継承して、RV64IConfig
クラスを作成して、これをシミュレーション時に適用する。
src/main/scala/cpu/config.scala
abstract class RVConfig() { val xlen = 32 val bus_width = 16 val debug = false } case class RV64IConfig() extends RVConfig { override val xlen = 64 override val bus_width = 16 override val debug = true }
src/test/scala/cpu/CpuTests.scala
class CpuTopTests [Conf <: RVConfig](c: CpuTop[Conf], hexname: String, pipename: String) extends PeekPokeTester(c) { val fp = Source.fromFile(hexname) val lines = fp.getLines ... class Tester extends ChiselFlatSpec { "Basic test using Driver.execute" should "be used as an alternative way to run specification" in { iotesters.Driver.execute(Array(), () => new CpuTop(new RV64IConfig)) { c => new CpuTopTests(c, "test.hex", "pipetrace.log") } should be (true) } }
パラメータを各モジュールに適用させるのは、他のクラスと同様にパラメータを追加すればよい。
src/main/scala/cpu/cpu.scala
class Cpu [Conf <: RVConfig](conf: Conf) extends Module { val io = IO (new CpuIo(conf)) ...
ちなみに、Bundle内でFlippedを使っている場合、デフォルトだとパラメータのコピーがうまくいかずにコンパイルに失敗する。
[error] (run-main-0) chisel3.core.AutoClonetypeException: Unable to automatically infer cloneType on class cpu.InstBus: constructor has parameters (conf) that are not both immutable and accessible. Either make all parameters immutable and accessible (vals) so cloneType can be inferred, or define a custom cloneType method. [error] chisel3.core.AutoClonetypeException: Unable to automatically infer cloneType on class cpu.InstBus: constructor has parameters (conf) that are not both immutable and accessible. Either make all parameters immutable and accessible (vals) so cloneType can be inferred, or define a custom cloneType method.
したがって、Bundleに対してcloneTypeのカスタム関数を追加する必要があった。
class InstBus [Conf <: RVConfig](conf: Conf) extends Bundle { override def cloneType: this.type = new InstBus(conf).asInstanceOf[this.type] ...
デバッグ時のポート削除をパラメータで実現する
Verilogを生成時に、余計なデバッグポートを削除する。
これもParameterにより制御する。CPUのVerilog生成時には、RV64IConfig
の代わりにRV64ISynth
パラメータを適用する。
src/main/scala/cpu/cpu.scala
object CpuTop extends App { chisel3.Driver.execute(args, () => new CpuTop(new RV64ISynth)) }
conf.debug = false
に設定されているので、CpuDbgMonitor
の信号が全て0ビットに設定され、削除される。
この方法は、 Chiselを使ってCPUを作ろう(5. トレース記述をどう作る?)
のコメントで教えてもらった。
src/main/scala/cpu/cpu.scala
class CpuDebugMonitor [Conf <: RVConfig](conf: Conf) extends Bundle { val inst_valid = if (conf.debug == true) Output(Bool()) else Output(UInt(0.W)) val inst_addr = if (conf.debug == true) Output(UInt(32.W)) else Output(UInt(0.W)) val inst_hex = if (conf.debug == true) Output(UInt(32.W)) else Output(UInt(0.W)) ...