Chisel3.4.0の変更点確認の5回目&最後(のはず)の記事。今回は#1073で追加されたgroup
オブジェクトについて。
(#1073) Grouping Chisel API, added a chisel annotation API for triggering the firrtl.transforms.GroupComponents transformation.
前回のverification
オブジェクトと同じくexperimental
扱いではあるが、PR #1073でgroup
というオブジェクトが追加されている。
group
オブジェクトの説明には、次の様な記載がある。
scala /** Marks a set of components (and their interconnected components) to be included in a new * instance hierarchy.
この内容からするに、group
に指定したChiselのハードウェアをモジュールとしてまとめてくれるような機能っぽい。
group
オブジェクト
追加されたオブジェクトに準備されているapply
メソッドは次のようなもの。
/* * @param components components in this group * @param newModule suggested name of the new module * @param newInstance suggested name of the instance of the new module * @param outputSuffix suggested suffix of any output ports of the new module * @param inputSuffix suggested suffix of any input ports of the new module * @param compileOptions necessary for backwards compatibility * @tparam T Parent type of input components */ def apply[T <: Data]( components: Seq[T], newModule: String, newInstance: String, outputSuffix: Option[String] = None, inputSuffix: Option[String] = None )(implicit compileOptions: CompileOptions): Unit = {
とりあえず、第一引数のcomponents
にまとめたい信号をSeq
で渡せば良さそうな雰囲気で、後の引数はインスタンスされるモジュールの命名に影響するものの様子。
ということで、サンプルコードを、と思ったのだが@example
としてコードが準備されていたので、まずはそれをそのまま使用して確認してみよう。
import chisel3._ import chisel3.util._ import chisel3.util.experimental.group // モジュール名は変えたけど、次のコードを拝借したもの // src/main/scala/chisel3/util/experimental/group.scala:L.13 // https://github.com/chipsalliance/chisel3/blob/23f9f71e51c8187d732fbce6a53ef2cbfc60d4f6/src/main/scala/chisel3/util/experimental/group.scala#L13 class TryGroup extends Module { val io = IO(new Bundle { val a = Input(Bool()) val b = Output(Bool()) }) val reg1 = RegInit(0.U) reg1 := io.a val reg2 = RegNext(reg1) io.b := reg2 group(Seq(reg1, reg2), "DosRegisters", "doubleReg") } object ElaborateTryGroup extends App { println((new stage.ChiselStage).emitVerilog(new TryGroup)) }
これをエラボレートして生成したRTLは次のようになった。
確かにgroup
で指定したレジスタが別のモジュールとして、切り出され、そのモジュールがインスタンスされている。
Chiselのモジュールにするほどではないけど、モジュール内の論理を構造化したいときとかに使えそうかな?という感じ。
inputSuffix
/outputSuffix
も指定できるので、グループ化の際に指定しておくと生成後のRTLの可読性を上げられそう。
module TryGroup( input clock, input reset, input io_a, output io_b ); wire doubleReg_clock; wire doubleReg_reset; wire doubleReg_reg2_0; wire doubleReg_io_a; DosRegisters doubleReg ( .clock(doubleReg_clock), .reset(doubleReg_reset), .reg2_0(doubleReg_reg2_0), .io_a(doubleReg_io_a) ); assign doubleReg_clock = clock; assign doubleReg_reset = reset; assign io_b = doubleReg_reg2_0; // @[TryGroup.scala 14:8] assign doubleReg_io_a = io_a; endmodule module DosRegisters( input clock, input reset, output reg2_0, input io_a ); reg reg1; // @[TryGroup.scala 11:21] reg reg2; // @[TryGroup.scala 13:21] assign reg2_0 = reg2; always @(posedge clock) begin if (reset) begin // @[TryGroup.scala 11:21] reg1 <= 1'h0; // @[TryGroup.scala 11:21] end else begin reg1 <= io_a; // @[TryGroup.scala 12:8] end reg2 <= reg1; // @[TryGroup.scala 13:21] end endmodule
ということで短いけどgroup
の紹介でした。