chiselでリファクタリングしてみました

chiselの使い方がわかってきたので、よりまともな記述ができるようにリファクタリングしてみました。 チートシートを参考にしたりしました。

chiselチートシート: GitHub - freechipsproject/chisel-cheatsheet: Chisel Cheatsheet
ChiselSheet · freechipsproject/chisel3 Wiki · GitHub

Interfaceをまとめる(BundleのBundle)

chiselではBundleをさらにBundleでまとめられました!! system verilogで言うならinterface内にinterface入れる感覚です。 すごすぎでした。

class Axi4LiteIF extends Bundle {
  val i_WriteAddressChannel  = new WriteAddressChannel
  val i_WriteDataChannel     = new WriteDataChannel
  val i_WriteResponseChannel = new WriteResponseChannel
  val i_ReadAddressChannel   = new ReadAddressChannel
  val i_ReadDataChannel      = new ReadDataChannel
}

マジックナンバーの消去

ベースアドレスをヘッダに記述するようにしました。 chiselではdefineがないようだったのでオブジェクトとして記載しました。

object OBJ_BASE_ADDR {
  val BASE_ADDR_REGION1 = 0x00000.U
  val BASE_ADDR_REGION2 = 0x04000.U
}

パラメータ化

実はchiselの売りの一つであるパラメータを、今まで一切使ってませんでした笑 なので、アドレスだけでもパラメータ化してみました! 良く考えるとSystem verilogでもありますが便利ですね。

class WriteAddressChannel(ADDR_WIDTH: Int = 20) extends Bundle {
  val AWADDR = Output(UInt(ADDR_WIDTH.W))
  val AWPROT = Output(UInt(1.W))
  val AWVALID = Output(UInt(1.W))
  val AWREADY = Input (UInt(1.W))
}

注意点として、↑でパラメータ化したものをFlipped関数で反転させようとすると、合成時にエラーを出力しました。これは最悪だと思い、回避策を調べたところ以下サイトなどでで回避方法の記載がありました。 試してみると回避できました。 chisel使っているとかなりの確率で引っかかると思われるので、 なぜデフォルトでいれといてくれないのか?と思いました。

参考: Chiselを使ってCPUを作ろう(15. デザインのパラメタライズ) - FPGA開発日記

  override def cloneType: this.type =
    new Axi4LiteIF(ADDR_WIDTH).asInstanceOf[this.type]

あとがき

chiselの優れた手法を使うことで、だいぶ良い風に記載することができました!! やはり最先端言語はびっくりするくらい使い勝手が良いと思われました。

refactoring · moamoai/AXI_interface@3125a22 · GitHub