Rocket Chip環境の仕組み解析メモの垂れ流し記事。前回見ていったGeneratorの中のgenerateFirrtl
を見ていくのが良さそうだったので、今回からはそれを少しずつ見ていく。
generateFirrtl
このメソッドはGenerator
オブジェクトが継承するGeneratorApp
トレイト内に定義されている。
GeneratorApp
が定義されているファイルは"util/GeneratorUtils.scala"
処理は以下。
/** Output FIRRTL, which an external compiler can turn into Verilog. */ def generateFirrtl { Driver.dumpFirrtl(circuit, Some(new File(td, s"$longName.fir"))) // FIRRTL }
Driver.dumpFirrtl
の第一引数circuit
はGeneratorApp
トレイト内にlazy val
として宣言されている。
lazy val names: ParsedInputNames = { require(args.size == 5, "Usage: sbt> " + "run TargetDir TopModuleProjectName TopModuleName " + "ConfigProjectName ConfigNameString") ParsedInputNames( targetDir = args(0), topModuleProject = args(1), topModuleClass = args(2), configProject = args(3), configs = args(4)) } lazy val td: String = names.targetDir lazy val config: Config = getConfig(names.fullConfigClasses) lazy val params: Parameters = config.toInstance lazy val circuit: Circuit = elaborate(names.fullTopModuleClass, params)
トレイト内部でプログラム引数args
から値を生成するためlazy val
にして遅延評価している。
トレイト"GeneratorApp
"の挙動
順番的には
generateFirrtl
内でcircuit
が参照されるGeneratorApp
トレイト内のlazy val circuit
が評価されるcircuit
の右辺のelaborate
の引数でnames
/params
が参照されるparams
の評価が始まる
という感じ。
なお、namesはGenerator
オブジェクト内部でlongName
の構築時に既に参照されているのでそのタイミングで値が評価される。
elaborateの処理
上述の様にcircuit
という変数にelaborate
された結果のFIRRTLが格納されている。
下記のelaborate
メソッドの第1引数は既出のParsedInputNames
にて引数より構築された文字列になっており、それがelaborate
で生成されるFIRRTLのトップ階層のクラス名になっている。
def elaborate(fullTopModuleClassName: String, params: Parameters): Circuit = { val top = () => Class.forName(fullTopModuleClassName) .getConstructor(classOf[Parameters]) .newInstance(params) match { case m: RawModule => m case l: LazyModule => LazyModule(l).module } Driver.elaborate(top) }
上記のコードでは第一引数のfullTopModuleClassName
をJAVAのClass.forNameに入れることで、所望のトップ階層のモジュールを文字列から生成してそれをChiselのDriver
に渡すことでFIRRTLを生成している。
なのでコードとしては以下のコードのMyModule
部分をプログラム引数から生成できるようにしたイメージ。
object Elaborate extends App { Driver.elaborate(() => new MyModule()) }
上記elaborate
メソッドの第1引数はrunMain
実行時にGenerator
オブジェクトに渡すプログラム引数の2番目/3番めの要素を結合したものになっており、READMEの手順に従ってmake
した時は以下のような文字列になっている。
- "freechips.rocketchip.system.TestHarness"
ということでemulatorディレクトリの下でmake
を実行して生成可能なRokcet Chipのトップ階層のモジュールは
ということになる。
このクラスはただのChiselのModule
になっているためval top
のmatch
式に於いてはcase m
にマッチし、それがそのままtop
に格納されている。
とりあえず今日はここまで。次回はTestHarness
の中身を少し追ってみようと思う。