今日はあるのは知ってたけど、まだ試せてなかったChiselの機能をやっと試せたのでその機能についてご紹介をば。
Chiselのアノテーション@chiselName
これはchisel3のwikiに説明がある機能。
上記ページの説明文を訳して引用すると:
Chiselに
when
やwithClockAndReset
のようなブロックの中で宣言された信号に名前を降って欲しいのであればchiselName
アノテーションを以下の例のように使ってみよう。
とのこと。
ということでサンプルコードがこちら
使い方
ちょっとだけwikiに載ってるコードからは変更してあります。変更した意図はネストしたブロックでもちゃんと拾って名前を維持してくれるかを見てみたかったから。
import chisel3._ import chisel3.experimental.chiselName // chisel3.1.7ではexperimental扱い @chiselName class TestMod extends Module { val io = IO(new Bundle { val a = Input(Bool()) val b = Input(Bool()) val c = Output(UInt(4.W)) }) when (io.a) { val innerReg = RegInit(5.U(4.W)) innerReg := innerReg + 1.U when (io.b) { val innerRegB = innerReg + 1.U innerReg := innerRegB } io.c := innerReg } .otherwise { io.c := 10.U } } object Elaborate extends App { Driver.execute(Array( "-tn=TestMod", "-td=rtl/chiselName" ), () => new TestMod) }
とりあえずこれだけで動かすと以下のようなエラーが出る
runMain Elaborate [info] Compiling 1 Scala source to /home/diningyo/prj/study/2000_chisel/500_learning-chisel3/subprj/chisel-name/target/scala-2.11/classes ... [error] /home/diningyo/prj/study/2000_chisel/500_learning-chisel3/subprj/chisel-name/src/main/scala/chiselNameTrial.scala:6:7: macro annotation could not be expanded (the most common reason for that is that you need to enable the macro paradise plugin; another possibility is that you try to use macro annotation in the same compilation run that defines it) [error] class TestMod extends Module { [error] ^ [error] one error found [error] (Compile / compileIncremental) Compilation failed
wikiにちゃんと書いてあるのだが、以下のコンパイラ・プラグインの設定が必要とのこと。
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
なので使用する前にこのコンパイラプラグイン設定を"build.sbt"に上記を追加しておこう。
上記の設定を行った後に"build.sbt"をリロードすればその際に"paradise"をダウンロードしてくれるはずだ。
- プロジェクトのリロード
reload [info] downloading https://repo1.maven.org/maven2/org/scalamacros/paradise_2.11.12/2.1.0/paradise_2.11.12-2.1.0-sources.jar ... [info] [SUCCESSFUL ] org.scalamacros#paradise_2.11.12;2.1.0!paradise_2.11.12.jar(src) (871ms)
ダウンロードを確認したら再度エラボレートしてみよう
runMain Elaborate [info] Compiling 1 Scala source to /home/diningyo/prj/study/2000_chisel/500_learning-chisel3/subprj/chisel-name/target/scala-2.11/classes ... [info] Done compiling. [info] Packaging /home/diningyo/prj/study/2000_chisel/500_learning-chisel3/subprj/chisel-name/target/scala-2.11/chiselname_2.11-2.0.jar ... [info] Done packaging. [info] Running Elaborate [info] [0.002] Elaborating design... [info] [1.057] Done elaborating. Total FIRRTL Compile Time: 438.3 ms [success] Total time: 5 s, completed 2019/07/08 23:19:05
今度は成功した!
効果をRTLで確認
で大事なのはRTLがどうなったか、ということなので生成したRTLを見ておこう
@chiselName
を使ったのだけを載せても効果が分からないので、使用していない版から。
なおどちらもバージョンともRANDAMIZEに関する記述は削除してあるのでご了承の程。
@chiselName
不使用- どこにも"innerReg"という文字は見当たらない。
module TestMod( // @[:@3.2] input clock, // @[:@4.4] input reset, // @[:@5.4] input io_a, // @[:@6.4] input io_b, // @[:@6.4] output [3:0] io_c, // @[:@6.4] output [3:0] io_d // @[:@6.4] ); reg [3:0] _T_16; // @[chiselNameTrial.scala 17:27:@10.6] reg [31:0] _RAND_0; wire [4:0] _T_18; // @[chiselNameTrial.scala 18:26:@11.6] wire [3:0] _T_19; // @[chiselNameTrial.scala 18:26:@12.6] reg [3:0] _T_21; // @[chiselNameTrial.scala 20:30:@15.8] reg [31:0] _RAND_1; wire [4:0] _T_23; // @[chiselNameTrial.scala 21:25:@16.8] wire [3:0] _T_24; // @[chiselNameTrial.scala 21:25:@17.8] wire [3:0] _GEN_0; // @[chiselNameTrial.scala 19:17:@14.6] assign _T_18 = _T_16 + 4'h1; // @[chiselNameTrial.scala 18:26:@11.6] assign _T_19 = _T_16 + 4'h1; // @[chiselNameTrial.scala 18:26:@12.6] assign _T_23 = _T_21 + 4'h1; // @[chiselNameTrial.scala 21:25:@16.8] assign _T_24 = _T_21 + 4'h1; // @[chiselNameTrial.scala 21:25:@17.8] assign _GEN_0 = io_b ? _T_24 : 4'h0; // @[chiselNameTrial.scala 19:17:@14.6] assign io_c = io_a ? _T_16 : 4'ha; // @[chiselNameTrial.scala 23:10:@20.6 chiselNameTrial.scala 25:10:@23.6] assign io_d = io_a ? _GEN_0 : 4'h0; // @[chiselNameTrial.scala 14:8:@8.4 chiselNameTrial.scala 21:12:@18.8] always @(posedge clock) begin if (reset) begin _T_16 <= 4'h5; end else begin _T_16 <= _T_19; end if (reset) begin _T_21 <= _T_16; end end endmodule
@chiselName
使用- "innerReg"/"innerRegB"共にきちんと名前が維持された!
module TestMod( // @[:@3.2] input clock, // @[:@4.4] input reset, // @[:@5.4] input io_a, // @[:@6.4] input io_b, // @[:@6.4] output [3:0] io_c, // @[:@6.4] output [3:0] io_d // @[:@6.4] ); reg [3:0] innerReg; // @[chiselNameTrial.scala 17:27:@10.6] reg [31:0] _RAND_0; wire [4:0] _T_17; // @[chiselNameTrial.scala 18:26:@11.6] wire [3:0] _T_18; // @[chiselNameTrial.scala 18:26:@12.6] reg [3:0] innerRegB; // @[chiselNameTrial.scala 20:30:@15.8] reg [31:0] _RAND_1; wire [4:0] _T_21; // @[chiselNameTrial.scala 21:25:@16.8] wire [3:0] _T_22; // @[chiselNameTrial.scala 21:25:@17.8] wire [3:0] _GEN_0; // @[chiselNameTrial.scala 19:17:@14.6] assign _T_17 = innerReg + 4'h1; // @[chiselNameTrial.scala 18:26:@11.6] assign _T_18 = innerReg + 4'h1; // @[chiselNameTrial.scala 18:26:@12.6] assign _T_21 = innerRegB + 4'h1; // @[chiselNameTrial.scala 21:25:@16.8] assign _T_22 = innerRegB + 4'h1; // @[chiselNameTrial.scala 21:25:@17.8] assign _GEN_0 = io_b ? _T_22 : 4'h0; // @[chiselNameTrial.scala 19:17:@14.6] assign io_c = io_a ? innerReg : 4'ha; // @[chiselNameTrial.scala 23:10:@20.6 chiselNameTrial.scala 25:10:@23.6] assign io_d = io_a ? _GEN_0 : 4'h0; // @[chiselNameTrial.scala 14:8:@8.4 chiselNameTrial.scala 21:12:@18.8] always @(posedge clock) begin if (reset) begin innerReg <= 4'h5; end else begin innerReg <= _T_18; end if (reset) begin innerRegB <= innerReg; end end endmodule
ということでChieslでユーザーが使える便利なアノテーション@chiselName
の紹介でした。
でも、これわざわざアノテーションを付与しないでこの挙動をデフォルトでいいんじゃ??という気がする。
少なくとも自分で作るモジュールにはつけておこうかなーという感じ。
今回試したソースコードは以下に置いてありますので興味があればどうぞ。