明けましておめでとうございます。今年もよろしくお願いします。
今年の目標は
- Chiselでハードウェア設計をもっと楽に出来るようになること
なので、今年も引き続きChiselネタ多めでお送りしていく予定です。興味があればお付き合いください。
昨年末の記事ではWindowsのノートPCしか作業環境がなく、それをいいことにWindows上でのChisel-Bootcampの環境構築の手順を紹介してみた。
新年最初の記事ではついでにWindows上でChiselの開発環境を整えるには何をすればいいのかを調べてみたので紹介してみようと思う。
Chiselの開発環境構築に必要なのは??
ということでChiselの開発環境構築手順を紹介するつもりなのだが、まずここでChiselを動かすには何が必要になるのかを改めて確認してみようと思う。
必要なのは、ざっくり書くと
の3つの環境になる。ここで大切なのが
ということである。
本記事の冒頭にWindows上でChiselの開発環境を整えるには??と書いてはみたのだが、Javaは各種OSごとにRuntimeが提供されており、基本的にはJavaのコードはプラットフォームを選ばないと言われている(まあそううまくは行かないこともあるらしいけど。。)。
そのため、実際には本記事で紹介する方法で構築されるChiselの開発環境はWindowsでもLinuxでも動作するものになる(一応、筆者のWindows10とUbuntu16.04 LTSでは同じ手順で構築した環境が実際に使用可能なことを確認してます)。
先に書いたとおり、WindowsでもLinuxでも同じ手順で構築可能だが、各種ソフトのインストール手順がOSによって異なるため、本記事ではWindowsPC上での構築手順を紹介することにする。
構築手順
改めて本筋のChiselの開発環境の構築手順を。Scalaが実行可能な環境を整えて(=JRE入れてScalaの実行ファイルダウンロード)、Chiselのコード一式を展開すればそれで使えるようにはなるのだが、そんなことをしなくてもいいようにChiselを開発しているfreechipsprojectではChiselの開発用の雛形となるChisel Project Template(chisel-template)を公開してくれている。
本記事ではこのテンプレートとJavaの開発環境であり、Scalaの開発も可能な統合開発環境IntelliJ IDEAを使ってChiselの開発環境を整えてみようと思う。
ということで手順としては
という4つのステップを実行することになる。
まずはJavaのインストールとIDEAのインストールになるわけだが、この2つは本ブログの過去記事で結構詳細に書いたつもりなので、必要な部分のみを紹介して詳しい説明はそちらに譲ることにする。
Javaのインストール
Java(というかJRE)のインストール手順は、昨年末のChisel-bootcampをWindowsPCにインストールするという手順で紹介した通りのものとなる。
手順は以下のサイトから各々のPCにあったインストーラを取得して、それを実行するだけである。
Windows10 - 64bitの場合はインストールするファイルは"jdk-8u192-windows-x64.exe"になる。
Intellij IDEAのインストール
これはScalaの勉強を始めたタイミングで統合開発環境をインストールするために調べた内容を書いた以下の記事で紹介している。
こちらもJavaのインストールと手順は一緒で、各OS毎に適切なインストーラを取得してそれを実行するだけとなる。
プロフェッショナル版は有償版となるためコミュニティ版をダウンロードしよう。
その後、インストーラを実行してインストール先を設定すれば基本的にはOKだ。なおインストール時に追加のプラグインでScalaを追加することが可能になっているのでこのタイミングで追加してインストールしておこう。
あとからでも設定可能だが、プラグインをダウンロードして入れるかどうかが問われる。 ScalaのためIntellij IDEAを入れるのでScalaをインストールする。
chisel-templateのダウンロード
Chisel-templateはgithubに公開されている。
なのでgit clone
で適当なフォルダを指定して、データを取得するかgithubのページからzipファイルとして取得して、適当な作業フォルダに展開しておこう。
展開すると以下のよう構成になっているはずだ。
<chisel-teplateのルート> | +- project/ +- src/ +- .gitignore +- build.sbt +- README.md +- scalastyle-config.xml +- scalastyle-test-config.xml
IDEAのプロジェクト作成とサンプルの実行
さてここからがメインの作業。さきほどchisel-templateのgithubのサイトからダウンロードして展開したフォルダにIDEAのプロジェクトを作成していく。
まずはIDEAを起動して"Create New Project"でプロジェクトを作成する。すると以下の画面が開くので左の選択リストから"Scala"を選択して、表示された右側のリストから"sbt"を選んで"Next"をクリック。
次の画面ではプロジェクトをどこに作成するかを聞かれるので"Location"の右側の"..."からフォルダの選択画面を開き、chisel-templaeteを展開したフォルダを選択する。
なおsbtのバージョンだが、chisel-templateのデフォルトのバージョンは1.1.1になっているのでchisel-template野中の以下のファイルを開いてバージョンを変更しておく。 #別にしなくてもなんとかなるみたいなんだけど、余計な設定が増えるので。。
- project/build.properties
#sbt.version = 1.1.1 sbt.version = 1.2.1
以下がプロジェクト作成時のバージョン等の設定。chisel-templateの展開先フォルダを選択したこと以外はデフォルトの設定のまま
上記の設定でプロジェクトを作成すると、メインの画面に遷移して作業が行えるようになる。sbtを使った開発では画面下部にある"sbt shell"を使った作業が個人的にはやりやすいのでその手順で紹介していく。
プロジェクト作成後にはchisel-templateに含まれている"build.sbt"の解析が行われて必要なライブラリのダウンロードが開始される。その際に"sbt shell"をアクティブな状態にしておくと、その時の処理がわかるので進み具合が心配な場合はそこを開いておくことをおすすめする。
そのまま"sbt shell"の”(initializing) > "という表記がただの"> "になるまでは裏でダウンロード処理等が動いている状態なので、そのまま待機。
ダウンロードが終わると"sbt shell"を使ってchisel-templateに含まれているサンプルのChiselデザインの実行が可能な状態になっているので、"sbt shell"から以下のコマンドを実行する。
2018/01/06追記 上記のプロジェクトの初期化時に一回だけ以下のようなエラーに遭遇した。
[error] java.lang.ClassNotFoundException: $d3754b0b99a4405b2f61$ [error] at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:64) [error] at java.lang.ClassLoader.loadClass(ClassLoader.java:424) [error] at java.lang.ClassLoader.loadClass(ClassLoader.java:357) [error] at java.lang.Class.forName0(Native Method) [error] at java.lang.Class.forName(Class.java:348) [error] at sbt.compiler.Eval$.getModule(Eval.scala:584) [error] at sbt.compiler.EvalDefinitions.values(Eval.scala:58) [error] at sbt.internal.DefinedSbtValues.$anonfun$values$1(LoadedSbtFile.scala:50) [error] at scala.collection.TraversableLike.$anonfun$flatMap$1(TraversableLike.scala:240) [error] at scala.collection.immutable.List.foreach(List.scala:388) [error] at scala.collection.TraversableLike.flatMap(TraversableLike.scala:240) [error] at scala.collection.TraversableLike.flatMap$(TraversableLike.scala:237) [error] at scala.collection.immutable.List.flatMap(List.scala:351) [error] at sbt.internal.DefinedSbtValues.values(LoadedSbtFile.scala:50) [error] at sbt.internal.EvaluateConfigurations$.$anonfun$evaluateSbtFile$4(EvaluateConfigurations.scala:166) [error] at sbt.internal.Load$.loadSettingsFile$1(Load.scala:1137) [error] at sbt.internal.Load$.$anonfun$discoverProjects$2(Load.scala:1144) [error] at scala.collection.MapLike.getOrElse(MapLike.scala:127) [error] at scala.collection.MapLike.getOrElse$(MapLike.scala:125) [error] at scala.collection.AbstractMap.getOrElse(Map.scala:59) [error] at sbt.internal.Load$.memoLoadSettingsFile$1(Load.scala:1143) [error] at sbt.internal.Load$.$anonfun$discoverProjects$4(Load.scala:1151) [error] at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:233) [error] at scala.collection.mutable.ResizableArray.foreach(ResizableArray.scala:58) [error] at scala.collection.mutable.ResizableArray.foreach$(ResizableArray.scala:51) [error] at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47) [error] at scala.collection.TraversableLike.map(TraversableLike.scala:233) [error] at scala.collection.TraversableLike.map$(TraversableLike.scala:226) [error] at scala.collection.AbstractTraversable.map(Traversable.scala:104) [error] at sbt.internal.Load$.loadFiles$1(Load.scala:1151) [error] at sbt.internal.Load$.discoverProjects(Load.scala:1165) [error] at sbt.internal.Load$.discover$1(Load.scala:862) [error] at sbt.internal.Load$.loadTransitive(Load.scala:937) [error] at sbt.internal.Load$.loadProjects$1(Load.scala:726) [error] at sbt.internal.Load$.$anonfun$loadUnit$11(Load.scala:729) [error] at sbt.internal.Load$.timed(Load.scala:1395) [error] at sbt.internal.Load$.$anonfun$loadUnit$1(Load.scala:729) [error] at sbt.internal.Load$.timed(Load.scala:1395) [error] at sbt.internal.Load$.loadUnit(Load.scala:688) [error] at sbt.internal.Load$.$anonfun$builtinLoader$4(Load.scala:484) [error] at sbt.internal.BuildLoader$.$anonfun$componentLoader$5(BuildLoader.scala:176) [error] at sbt.internal.BuildLoader.apply(BuildLoader.scala:241) [error] at sbt.internal.Load$.loadURI$1(Load.scala:546) [error] at sbt.internal.Load$.loadAll(Load.scala:562) [error] at sbt.internal.Load$.loadURI(Load.scala:492) [error] at sbt.internal.Load$.load(Load.scala:471) [error] at sbt.internal.Load$.$anonfun$apply$1(Load.scala:251) [error] at sbt.internal.Load$.timed(Load.scala:1395) [error] at sbt.internal.Load$.apply(Load.scala:251) [error] at sbt.internal.Load$.defaultLoad(Load.scala:69) [error] at sbt.BuiltinCommands$.liftedTree1$1(Main.scala:829) [error] at sbt.BuiltinCommands$.doLoadProject(Main.scala:829) [error] at sbt.BuiltinCommands$.$anonfun$loadProjectImpl$2(Main.scala:800) [error] at sbt.Command$.$anonfun$applyEffect$4(Command.scala:142) [error] at sbt.Command$.$anonfun$applyEffect$2(Command.scala:137) [error] at sbt.Command$.process(Command.scala:181) [error] at sbt.MainLoop$.processCommand(MainLoop.scala:151) [error] at sbt.MainLoop$.$anonfun$next$2(MainLoop.scala:139) [error] at sbt.State$$anon$1.runCmd$1(State.scala:246) [error] at sbt.State$$anon$1.process(State.scala:250) [error] at sbt.MainLoop$.$anonfun$next$1(MainLoop.scala:139) [error] at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:16) [error] at sbt.MainLoop$.next(MainLoop.scala:139) [error] at sbt.MainLoop$.run(MainLoop.scala:132) [error] at sbt.MainLoop$.$anonfun$runWithNewLog$1(MainLoop.scala:110) [error] at sbt.io.Using.apply(Using.scala:22) [error] at sbt.MainLoop$.runWithNewLog(MainLoop.scala:104) [error] at sbt.MainLoop$.runAndClearLast(MainLoop.scala:59) [error] at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:44) [error] at sbt.MainLoop$.runLogged(MainLoop.scala:35) [error] at sbt.StandardMain$.runManaged(Main.scala:138) [error] at sbt.xMain.run(Main.scala:89) [error] at xsbt.boot.Launch$$anonfun$run$1.apply(Launch.scala:109) [error] at xsbt.boot.Launch$.withContextLoader(Launch.scala:128) [error] at xsbt.boot.Launch$.run(Launch.scala:109) [error] at xsbt.boot.Launch$$anonfun$apply$1.apply(Launch.scala:35) [error] at xsbt.boot.Launch$.launch(Launch.scala:117) [error] at xsbt.boot.Launch$.apply(Launch.scala:18) [error] at xsbt.boot.Boot$.runImpl(Boot.scala:41) [error] at xsbt.boot.Boot$.main(Boot.scala:17) [error] at xsbt.boot.Boot.main(Boot.scala) [error] java.lang.ClassNotFoundException: $d3754b0b99a4405b2f61$ [error] Use 'last' for the full log. Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore? r
この際に、上記ログの最後に出ているProject loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?
に従ってr
を選択したところ、特にエラーは発生せずにsbtのコマンド受付までたどり着いた。
testOnly gcd.GCDTester -- -z Basic
すると実行に必要なデータのダウンロードが行われた後に、サンプルデザインのGCDのテストが実行される。
以下がその実行ログ(長いのでダウンロード部分は一部のみ記載)
[IJ]sbt:chisel-module-template> testOnly gcd.GCDTester -- -z Basic [info] Updating ... [info] downloading https://repo1.maven.org/maven2/org/antlr/antlr4-runtime/4.7.1/antlr4-runtime-4.7.1.jar ... - 中略 - [info] downloading https://repo1.maven.org/maven2/org/scala-lang/scala-compiler/2.11.12/scala-compiler-2.11.12.jar ... [info] [SUCCESSFUL ] com.thoughtworks.paranamer#paranamer;2.8!paranamer.jar(bundle) (1121ms) - 中略 - [info] [SUCCESSFUL ] org.scala-lang#scala-compiler;2.11.12!scala-compiler.jar (32049ms) [info] Done updating. [warn] There may be incompatibilities among your library dependencies. [warn] Run 'evicted' to see detailed eviction warnings [info] Compiling 1 Scala source to <プロジェクトのパス>\target\scala-2.11\classes ... [info] Non-compiled module 'compiler-bridge_2.11' for Scala 2.11.12. Compiling... [info] Compilation completed in 9.736s. [warn] there were 5 feature warnings; re-run with -feature for details [warn] one warning found [info] Done compiling. [info] Compiling 2 Scala sources to <プロジェクトのパス>\target\scala-2.11\test-classes ... [warn] there were 6 feature warnings; re-run with -feature for details [warn] one warning found [info] Done compiling. # ここからがChiselの実行ログになる [info] [0.000] Elaborating design... [info] [0.860] Done elaborating. Total FIRRTL Compile Time: 447.9 ms Total FIRRTL Compile Time: 115.3 ms file loaded in 0.199824156 seconds, 20 symbols, 13 statements [info] [0.000] SEED 1546610559865 test GCD Success: 168 tests passed in 1107 cycles in 0.047029 seconds 23538.63 Hz [info] [0.031] RAN 1102 CYCLES PASSED # <-- テストが実行されてPASSした状態 [info] GCDTester: [info] GCD [info] Basic test using Driver.execute [info] - should be used as an alternative way to run specification [info] using --backend-name verilator [info] running with --is-verbose [info] running with --generate-vcd-output on [info] running with --generate-vcd-output off [info] ScalaTest [info] Run completed in 2 seconds, 578 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [info] Passed: Total 1, Failed 0, Errors 0, Passed 1 [success] Total time: 98 s, completed 2019/01/04 23:02:42
ここまでくれば、あとはこのchisel-template環境に自分のデザインとテストを追加してそれぞれを実行して自分のChiselデザインを設計することが可能になる。
因みに上記のテストの実行の結果生成されたデータは以下のパスにあるので興味があったら覗いてみてほしい。
- <プロジェクトのパス>/test_run_dir/gcd.GCDTesterxxxxx
- xxxxは数字。プロセスIDとかなのかしら。。よくわからん
- 今回の場合はChisel3を変換したFIRのデータとかが出来る(拡張子が*.firのファイル)
ということでプロジェクト作成とサンプルの実行ができたので今日はここまで。
次回は今回作成したChisel-template環境に自分のデザインとテストを追加して開発を行うために必要なことを紹介する。一応、chisel-templateのフォルダ構成やVCD形式の波形をダンプしてデバッグをするところまで紹介するつもりでいる。