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

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

Chisel-Bootcampの気になってたことを調べてみた

スポンサーリンク

このブログでは自分のChiselの勉強を進めるための題材としてChisel-Bootcampを使わせてもらっている。
今回はChisel-Bootcampをやっていて今まで放置していた部分について、仕組みを調べてたのでそれをまとめてみる。

getVerilogって何よ?

まず最初にChisel-BootcampでVerilog-HDLのRTLを生成して表示する際に使用されているgetVerilogメソッド。
このメソッドに作成したChiselのモジュールのインスタンスを渡すとそのRTLを表示してくれるのだが、今まで中身をちゃんと見てなかったなーと。
実はChiselを勉強し始めた際にはこのメソッドがRTL生成の方法だと思っていて、Chisel-Bootcampを使わないでHWを設計した際にメソッドが無くて慌てた。。
その際に調べてみて意外とRTLを生成する方法について解説したものが見当たらないなーと思って書いたのが以下の記事だった。

www.tech-diningyo.info

既にこのメソッドがやってくれていることは書いてしまったが、一応使うと何が起きるかを見ておこう。

class A extends Module {
  val io = IO(new Bundle {
    val inB = Input(Bool())
    val inI = Input(UInt(32.W))
    val inS = Input(SInt(32.W))
    val outB = Output(Bool())
    val outI = Output(UInt(32.W))
    val outS = Output(SInt(32.W))
  })

  io.outB := io.inB
  io.outI := io.inI
  io.outS := io.inS
}

println(getVerilog(new A))
  • 実行結果
[info] [0.001] Elaborating design... <- エラボレートして
[info] [0.612] Done elaborating.
Total FIRRTL Compile Time: 201.9 ms
module cmd3HelperA( // @[:@3.2]      <- RTLを文字列で返却してくれる
  input         clock, // @[:@4.4]
  input         reset, // @[:@5.4]
  input         io_inB, // @[:@6.4]
  input  [31:0] io_inI, // @[:@6.4]
  input  [31:0] io_inS, // @[:@6.4]
  output        io_outB, // @[:@6.4]
  output [31:0] io_outI, // @[:@6.4]
  output [31:0] io_outS // @[:@6.4]
);
  assign io_outB = io_inB;
  assign io_outI = io_inI;
  assign io_outS = io_inS;
endmodule

ソースコードを追ってみる

getVerilogソースコードはChisel-Bootcampのディレクトリ"source"の下の"load-ivy.sc"に定義されており、以下のようなものになっている。

def getVerilog(dut: => chisel3.core.UserModule): String = {
  import firrtl._
  return chisel3.Driver.execute(Array[String](), {() => dut}) match {
    case s:chisel3.ChiselExecutionSuccess => s.firrtlResultOption match {
      case Some(f:FirrtlExecutionSuccess) => f.emitted
    }
  }
}

基本的に中でやっているのは”ChiselでRTLを生成する際に実施するDriver.executeを呼び出すこと”になる。 executeの第2引数の() => dutfunction0を渡しているのを初めて知った。。

ついでにexecuteの処理も。

  def execute(args: Array[String], dut: () => RawModule): ChiselExecutionResult = {
    val optionsManager = new ExecutionOptionsManager("chisel3") with HasChiselExecutionOptions with HasFirrtlOptions

    optionsManager.parse(args) match {
      case true =>
        execute(optionsManager, dut)
      case _ =>
        ChiselExecutionFailure("could not parse results")
    }
  }

引数として渡されたargsの解析を行い、結果が正しければそのオブションとともにexecuteを呼び出す。 で処理された結果、RTLが生成されその内容がprintlnに引き渡される、、、なのだが、イマイチここの詳細なフローが把握しきれない。。 RTLが返ってくるように見えないのよね。ここについては追ってもう少し詳細な調査を。 Driver.executeを通す関係でエラボレート時にはFIRRTL/RTL/Jsonの3つのファイルが生成されていくので、必要に応じてそちらも見るといいだろう。

dsptoolsが使えるわけ

Module3.6の冒頭でdsptoolsがインポートされている。 これをどこでダウンロードしているのかがについて。

これもgetVerilogと同様にload-ivy.scでChiselと一緒にダウンロードされるようになっていた。

import $ivy.`edu.berkeley.cs::chisel3:3.1.0`
import $ivy.`edu.berkeley.cs::chisel-iotesters:1.2.0`
import $ivy.`edu.berkeley.cs::dsptools:1.1.0`
import $ivy.`org.scalanlp::breeze:0.13.2`

ちなみにdsptoolsもUC Berkeleyが公開しているChisel用のパッケージ

github.com

あんまり詳しくは追ってないけど、いろいろ役に立ちそうなライブラリを公開してくれている。

Dsptools is a library that can be used with any Chisel library. Some of the goals of dsptools are to enable:

  1. Pipeline delay checking (Isn't it annoying when the delays of two signals into an operation don't line up because you forgot to delay a corresponding signal in your haste to close timing?)
  2. Enhanced support for designing and testing DSP with generic types (i.e. switching between DSPReal for verifying functional correctness with double-precision floating point and FixedPoint for evaluating fixed-point design metrics by changing a single parameter).
  3. More useful and universal testing platform for numeric types!

    Numbers are displayed in their correct formats instead of hex for peek, poke, and expect operations. Additionally, if your tester extends DSPTester, you can optionally dump your test sequence to a Verilog testbench that replays the test for functional verification on all simulation platforms (i.e. Xilinx, Altera, etc. instead of only VCS). The tolerance of comparisons with expected values can also be changed via DSPTester.setTol(floTol = decimal_tolerance, fixedTol = number_of_bits).

  4. Miscellaneous additional features
  5. Wide range of LUT modules for ease of generating lookup tables from pre-calculated constants (no intermediate representation)
  6. Memory modules that abstract out confusion associated with Chisel Mem
  7. Generates useful helper files with each Verilog output (constraints, generator parameters used, etc.).
  8. Easier to rename modules & signals and have renaming actually succeed.
  9. Expanding Support for non-base-2 math.
  10. Adds support for numerical processing in the Chisel Environment via Breeze.

これもそのうち調べてみよう。

今日は薄味、、、だけどここまで。