LowerTypeの調査を続けている、前回の記事からずいぶんと時間が経ってしまったが、Bundleを分解する方法について調査している。つまり、FIRRTLで以下のように記述されているコードを、Vectorを分解せずにBundleのみ分解するということである。
circuit VecBundle : module VecBundle : input in: { a : UInt<32>, b : UInt<32> }[4] input sel: UInt<2> output out : { a : UInt<32>, b : UInt<32> } out.a <= in[sel].a out.b <= in[sel].b
上記のFIRのコードを分解する。下記のようになれば良い。
circuit VecBundle : module VecBundle : input in_a : UInt<32>[4] input in_b : UInt<32>[4] input sel : UInt<2> output out_a : UInt<32> output out_b : UInt<32> skip out_a <= in_a[sel] out_b <= in_b[sel]
このためにLowerType
内のメソッドにおいて、loweredName
において、
VectorType
の場合、VectorType
自体は維持したまま内部の型を変換する。BundleType
の場合、Bundleの内部の値を取り出して_
でつなげる。WRef
の場合、値をそのまま連結して返す。
という手順を取ることにする。これを実現するために、以下のloweredTypeName()
を実装した。
val delim = "_" def loweredTypeName(e: Expression): String = loweredTypeName(e, "") def loweredTypeName(e: Expression, substr: String): String = e match { case e: WRef => { if (substr == "") { e.name } else { e.name + "_" + substr } } case e: WSubField => s"${loweredTypeName(e.expr, substr + e.name)}" case e: WSubIndex => s"${loweredTypeName(e.expr, substr)}$delim${e.value}" case e: WSubAccess => s"${loweredTypeName(e.expr)}_${substr}[${loweredTypeName(e.index)}]" }
これにより、上記のサンプルコードを処理してみる。
sbt assembly && ./utils/bin/firrtl -td regress -i ./regress/VecBundle.fir -X sverilog -ll trace 2>&1 | tee VecBundle.log
まだエラーが出るが、LowerType
の段階で以下のようになった。
circuit VecBundle : module VecBundle : input in_a : UInt<32>[4] input in_b : UInt<32>[4] input sel : UInt<2> output out_a : UInt<32> output out_b : UInt<32> skip out_a <= in_a[sel] out_b <= in_b[sel]
とりあえず変換はできるようになった。問題は、in_a[sel]
が正しく変数に分解できていないということだ。これを処理するためにまだResolveKinds
でエラーが発生している。
Exception in thread "main" firrtl.FirrtlInternalException: Internal Error! Please file an issue at https://github.com/ucb-bar/firrtl/issues at firrtl.Utils$.error(Utils.scala:423) at firrtl.Utils$.throwInternalError(Utils.scala:164) at firrtl.stage.FirrtlStage.run(FirrtlStage.scala:35) at firrtl.options.Stage$$anon$1.transform(Stage.scala:43) at firrtl.options.Stage$$anon$1.transform(Stage.scala:43) ... at firrtl.stage.FirrtlMain.main(FirrtlStage.scala) Caused by: java.util.NoSuchElementException: key not found: in_a[sel] at scala.collection.MapLike.default(MapLike.scala:235) ...