ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

Chiselの便利なアノテーション@chiselNameを試してみた

スポンサーリンク

今日はあるのは知ってたけど、まだ試せてなかったChiselの機能をやっと試せたのでその機能についてご紹介をば。

Chiselのアノテーション@chiselName

これはchisel3のwikiに説明がある機能。

上記ページの説明文を訳して引用すると:

ChiselにwhenwithClockAndResetのようなブロックの中で宣言された信号に名前を降って欲しいのであれば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の紹介でした。
でも、これわざわざアノテーションを付与しないでこの挙動をデフォルトでいいんじゃ??という気がする。
少なくとも自分で作るモジュールにはつけておこうかなーという感じ。
今回試したソースコードは以下に置いてありますので興味があればどうぞ。