Chiselにはバージョンがあり、Chisel2とChisel3が公開されている。 微妙に文法が異なっているので要注意だ。
Chisel2ではVerilogとC++を生成する方法が公開されているが、Chisel3ではどうだろう。
Chisel2でのVerilogとC++の生成方法については、以下のサイトにまとめられている。 と思っていろいろ探したら自分のブログだった。
src/main/scala/hello/Hello.scala
package Hello import Chisel._ class Hello extends Module { val io = new Bundle { val out = UInt(OUTPUT, 8) } io.out := UInt(42) } class HelloTests(c: Hello) extends Tester(c) { step(1) expect(c.io.out, 42) } object Hello { def main(args: Array[String]): Unit = { val tutArgs = args.slice(1, args.length) chiselMainTest(tutArgs, () => Module(new Hello())) { c => new HelloTests(c) } } }
Chisel3を触っているとわかる。微妙に違う。まず、import Chisel._ではなくChisel3だとimport chisel3._になる。次にBundleにカッコが入っていない。
次に、chiselMainTestなどという関数はない。これらを修正していく必要がある。
Chisel2では、chiselMainTestのargsを変更することによりC++を出力することができる。
つまり、--backend cを追加することでC++のコードが生成できる。
しかし、Chisel3ではできない。どのようにすればよいのか。
まず、上記のデザインはChisel3では以下のようになる。
package hello import chisel3._ import chisel3.iotesters.{PeekPokeTester, Driver} class Hello extends Module { val io = IO(new Bundle { val out = Output(UInt(8.W)) }) io.out := 42.U } class HelloTests(c: Hello) extends PeekPokeTester(c) { step(1) expect(c.io.out, 42) } object Hello { def main(args: Array[String]): Unit = { if (!Driver(() => new Hello())(c => new HelloTests(c))) System.exit(1) } }
細かな文法の違いはあるが、大きくはchiselMainTest()が消える。その代わり、iotestersのDriverが直接呼び出される。
このAPIはVerilogを生成するためのAPIである。じゃあC++を生成するためにはどうすればよいのか。
[https://chisel.eecs.berkeley.edu/api/latest/chisel3/Driver$.html#execute(args:Array[String],dut:()=%3Echisel3.experimental.RawModule):chisel3.ChiselExecutionResult:title]
同じiotestersにverilogToCppというメソッドがあるけど、これは何か違う気がする。
[https://chisel.eecs.berkeley.edu/api/latest/chisel3/Driver$.html#verilogToCpp(dutFile:String,dir:java.io.File,vSources:Seq[java.io.File],cppHarness:java.io.File,suppressVcd:Boolean):scala.sys.process.ProcessBuilder:title]
結論から言うと、Chisel3でC++を生成するのは直接的には不可能で、VerilatorでシミュレーションするためにC++を生成するという考え方に近い。
このiotestersのDriverにはどのような機能があるのか。オプションを与えるように変更していろいろと変えてみる。
object Hello { def main(args: Array[String]): Unit = { chisel3.Driver.execute(args, () => new Hello) } }
sbt実行時に`sbt "run Hello.Hello --help"とか入れてみる。
common options
-tn, --top-name <top-level-circuit-name>
This options defines the top level circuit, defaults to dut when possible
-td, --target-dir <target-directory>
This options defines a work directory for intermediate files, default is .
-ll, --log-level <Error|Warn|Info|Debug|Trace>
This options defines a work directory for intermediate files, default is .
-cll, --class-log-level <FullClassName:[Error|Warn|Info|Debug|Trace]>[,...]
This options defines a work directory for intermediate files, default is .
-ltf, --log-to-file default logs to stdout, this flags writes to topName.log or firrtl.log if no topName
-lcn, --log-class-names shows class names and log level in logging output, useful for target --class-log-level
--help prints this usage text
<arg>... optional unbounded args
chisel3 options
-chnrf, --no-run-firrtl Stop after chisel emits chirrtl file
firrtl options
-i, --input-file <firrtl-source>
use this to override the default input file name , default is empty
-o, --output-file <output>
use this to override the default output file name, default is empty
-faf, --annotation-file <input-anno-file>
Used to specify annotation files (can appear multiple times)
-foaf, --output-annotation-file <output-anno-file>
use this to set the annotation output file
-X, --compiler <high|middle|low|verilog|sverilog>
compiler to use, default is verilog
--info-mode <ignore|use|gen|append>
specifies the source info handling, default is append
-fct, --custom-transforms <package>.<class>
runs these custom transforms during compilation.
-fil, --inline <circuit>[.<module>[.<instance>]][,..],
Inline one or more module (comma separated, no spaces) module looks like "MyModule" or "MyModule.myinstance
-firw, --infer-rw <circuit>
Enable readwrite port inference for the target circuit
-frsq, --repl-seq-mem -c:<circuit>:-i:<filename>:-o:<filename>
Replace sequential memories with blackboxes + configuration file
-clks, --list-clocks -c:<circuit>:-m:<module>:-o:<filename>
List which signal drives each clock of every descendent of specified module
-fsm, --split-modules Emit each module to its own file in the target directory.
--no-check-comb-loops Do NOT check for combinational loops (not recommended)
--no-dce Do NOT run dead code elimination
--compilerオプションがあるが、ここにはhigh|middle|low|verilog|sverilogとだけあり、high|middle|lowはFIRのレベル、sverilogに至っては生成されるものはVerilogと同一である。
このあたりのオプションがChisel2とChisel3ではかなり異なっている。注意して扱う必要がありそうだ。