今日は前回の続きでChisel3.3.0で変更/追加になった機能について確認していく。 今回は一番気になったRTLの生成処理の変更について。
#1213 Driverのいくつかのメソッドが非推奨になった
Chisel3.2.xまでのバージョンではRTLの生成時に次のようにDriver.execute
メソッドを実行すればよかった。
object OldElaborate extends App { val name = "SampleModule" Driver.execute(Array( "-td=rtl", s"-tn=$name" ), () => new SampleModule ) }
上記のコードをChisel3.3.0以降のコードで実行してみると次のように警告が表示されるようになっている。
[warn] chisel-3.3.x/src/main/scala/Elaborate.scala:23:10: method execute in object Driver is deprecated: Use chisel3.stage.ChiselStage.execute. This will be removed in 3.4. [warn] chisel-3.3.x/src/main/scala/Elaborate.scala:23:3: object Driver in package chisel3 is deprecated: Please switch to chisel3.stage.ChiselStage. Driver will be removed in 3.4.
警告の中身は
chisel3.Driver.execute
が非推奨になりChisel3.4で削除予定なのでchisel3.stage.ChiselStage.execute
を使うようにchisel3.Driver
が非推奨になりChisel3.4で削除予定なのでchisel3.stage.ChiselStage
を使うように
というものだ。
ソースコードの方をみるとDriver
オブジェクトの全メソッドに@deprecated
が付与されているので、本当にまるごと削除されるみたい。
Chisel3.stage.ChiselStage
ということでChisel3.3.0以降の水晶となったChiselStage
を使ったRTLの生成について確認しておく。
代わりに、、と書いてあったのでDriver.execute
をそのままstage.ChiselStage.execute
に置き換えてみた所エラーが発生した。。。
// このコードはエラーが発生する object NewElaborate extends App { val name = "SampleModule" stage.ChiselStage.execute(Array( "-td=rtl", s"-tn=$name" ), () => new SampleModule ) }
出てくるエラーはこんなメソッドは存在しない、、というもの。 仕方ないので、ソースコードを確認する。
class ChiselStage extends Stage with PreservesAll[Phase] { val shell: Shell = new Shell("chisel") with ChiselCli with FirrtlCli ~~~ 中略 ~~~ object ChiselStage { /** Return a Chisel circuit for a Chisel module * @param gen a call-by-name Chisel module */ def elaborate(gen: => RawModule): cir.Circuit = {
上記の様にChiselStage
というクラスとそのコンパニオン・オブジェクトが定義されているのだが、どちらのChiselStage
にもexecute
という
メソッドは存在していなかった。
エラボレートを行うだけなら、オブジェクトの方のChiselStage
にモジュールを渡せば良さそう。
ちゃんとモジュール内にエラーが存在する場合は次のように、例外が発生する。
[error] chisel3.internal.ChiselException: Connection between sink (Bool(IO in unelaborated SampleModule)) and source (Bool(IO in unelaborated SampleModule)) failed @: Sink is unwriteable by current module. [error] ... [error] at SampleModule.<init>(Elaborate.scala:14) [error] at NewElaborate$$anonfun$2.apply(Elaborate.scala:33) [error] at NewElaborate$$anonfun$2.apply(Elaborate.scala:33)
とはいえ、上記のelaborate
メソッドはCircuit
になっていて、このメソッドの中ではRTLへの変換やRTLファイルの生成は行われない。
もう少し探してみた所execute
メソッドはChiselStage
のスーパークラスであるStage
に定義されていた。
abstract class Stage extends Phase { ~~~ 中略 ~~~ final def execute(args: Array[String], annotations: AnnotationSeq): AnnotationSeq = transform(shell.parse(args, annotations))
ということで、クラスの方のChiselStage
を使って再度エラボレート処理を実行してみる。
ここで気をつけないと行けないのは、上記execute
メソッドの第2引数がAnnotationSeq
を要求していること。
なので生成したいモジュールを次のようにして渡してやる。
object NewElaborate extends App { val name = "SampleModule" (new stage.ChiselStage).execute(Array( "-td=rtl", s"-tn=$name" ), Seq(chisel3.stage.ChiselGeneratorAnnotation( () => new SampleModule)) ) }
これでもまだ次のようなエラーが出た。。。。オプションも変わっているのか??
[error] (run-main-4) firrtl.options.OptionsException: Option --top-name failed when given ''. Option '--top-name/-tn' was removed as part of the FIRRTL Stage refactor. Use an explicit input/output options instead. [error] This error will be removed in 1.3.
ChiselStage.executeを使ったRTLの生成
最終的にChisel3.2.xまでのDriver.execute
と同様にRTLを生成できたコードは次のようになった。
object NewElaborate extends App { val name = "SampleModule" (new stage.ChiselStage).execute( Array("-td=rtl", s"-o=$name"), Seq(chisel3.stage.ChiselGeneratorAnnotation( () => new SampleModule))) }
-tn
に関するエラーメッセージで指定されていたinput/output
オプションは実際にはそれぞれ次のオプション名が正しい物になる。
- input ->
-i
/--input-file
- output ->
-o
/--output-file
長い方のオプションだと-file
が必要な点に注意が必要。
ChiselStage.emitVerilogを使ったRTLの生成
ChiselStage
にはemitVerilog
というメソッドが追加されているので、こちらを使ってもOK。というかexecute
使うよりも
こっちのほうが使いやすい。戻り値はString
となっていて、生成されたRTLがそのまま入っている。
object NewElaborate extends App { val rtl = (new stage.ChiselStage).emitVerilog( new SampleModule, Array("-td=rtl", s"-o=$name")) print(rtl) }
上記のコードを実行するとエラボレートのprintln
が実行されて、生成されたRTLが表示される。
[IJ]sbt:chisel33x> runMain NewElaborate [warn] Multiple main classes detected. Run 'show discoveredMainClasses' to see the list [info] running NewElaborate [info] [0.002] Elaborating design... [info] [0.065] Done elaborating. Computed transform order in: 171.3 ms Total FIRRTL Compile Time: 528.6 ms module SampleModule( input clock, input reset, input io_in, output io_out ); assign io_out = io_in; // @[Elaborate.scala 15:10] endmodule [success] Total time: 2 s, completed 2020/05/17 16:29:30 [IJ]sbt:chisel33x>
単純にRTLの生成の面からすると、少し面倒になったなぁという印象ではある。
ただなんとなくコードを見ているとChiselStage
を使うことで、生成の過程をカスタマイズできそうな気配もあるので
この辺はもう少し掘り下げてみたい所。
ということでChisel3.3.0からの推奨となった新しいRTLの生成フローについての紹介でした。