ChiselでbundleのWire接続に詰まった話

DMAを作成する前に、Busモジュールが複数Master/Slaveに対応できないといけないため、 Parameterでマスタ数、スレーブ数を変更できるようにしようしました。 まずは本当にシンプルに以下の仕様で作成しようとしたんです。

  • Master側のIFモジュールで複数マスタのうち一つのマスタを選択
    • Writeは投げたら選択解除
    • ReadはReadレスポンスが帰ってきたら、選択解除
    • FIFOなしなので、複数マスタアクセスするとトランザクションが消える(笑)
  • 選択されたマスタのアドレスに従って、転送先スレーブ選択

で、↑であればすぐできるかなとざっと記載してみたんですが、 エラーメッセージが出まくりました。 書いている内容見ると、以下のような箇所でエラーが出ているようでした。 ただのwire間の接続なので意味がわかりません。。 エラーメッセージ調べてみてもよくわかりませんでした。。

val w_if_mst_sel = Wire(Vec(N_MST, new Axi4LiteIF))
val arbtrator = for (i <- 0 until N_MST-1) yield {
  w_if_mst_sel(i) <> w_if_mst_sel(i+1)
}

で、いろいろ変えたりして1日くらい苦しみ続けました。 で、段々と怪しいと思えてきたのはBundleのWire化です。 このBundleはInput/Outputが混じっていて、Wire化したときに Input/Output属性がなくなってしまったのではと推測しました。 であれば、Bundleをバラして向きに合わせて接続すればと思って、接続するとうまくいきました。

うまくいってよかったですが、すごいストレスでした。

さらに調べてみると、Bundleで<>拡張子をオーバライドすれば対応可能そうにも見えましたが、 さすがにつらかったので、今回は諦めました。

あとがき

というわけで、どの言語でも何度かぶつかる壁がありますが、chisel/scalaの一つ目の壁にぶち当たりました。 いつかは、この問題をうまく記述できるようにしたいです。

もしくは、デフォルトであるArbterモジュールクラスなどを使えば簡単に実装できるかもしれませんね。