Chiselを使ったRISC-Vの勉強(4. プロジェクトへの機械語の読み込みの自動化)
今更ながら環境を整える
VSCodeにChiselプラグインを入れつつ頑張っていたのですが、IDEがオブジェクトやクラスの階層を把握していないため、補完機能が乏しいことなどから限界を感じてました。
いつも参考にさせていただいている、diningyo氏(id:diningyo-kpuku-jougeki)のブログ
Scalaの勉強 - 統合開発環境IntelliJ IDEAのインストール - ハードウェアの気になるあれこれ
というわけでIntelliJ IDEAに乗り換えました。すごく快適。最初っからこうしていればよかった。
機械語の生成
いままでCPUロジックに与えるhexはハンドアセンブルしていましたが、そろそろ限界を感じています。
例えば、JAL命令。
こんなの毎回のように手動アセンブラやってたら脳が停止してしまいます。それに、間違った機械語を記述していたのに気づかずデコーダを作ったら収拾がつかなくなります。
これに関してはみなさん工夫されているようです。
RISC-V(RV32I)のアセンブリから機械語への翻訳(簡易) - Qiita
a163236氏によるscala記述のアセンブラです。機械語がバイナリ文字列で出力されるので、コピペでChiselプロジェクトに貼り付けられるのが魅力。
さて、自分はscalaでアセンブラとか記述できないので、実直にriscv64-unknown-elf-asとodコマンドを用いる方向にしました。
参考1:Chisel-Templateを使ってオリジナルデザインを作ってみるチュートリアル (3. CPUのコアのDebug-Trace作成) - FPGA開発日記
参考2:【 od 】コマンド――ファイルを8進数や16進数でダンプする:Linux基本コマンドTips(93) - @IT
Linuxやwsl環境で32bit(=4byte)長ごとに改行された可読できる機械語を出力するには以下のようにします。(アセンブラファイルはtest.s、欲しいファイルはtest.hexという名前とします。)
riscv64-unknown-elf-as test.s -o test.o riscv64-unknown-elf-objcopy --gap-fill 0 -O binary test.o test.bin od -An -tx4 -w4 test.bin >> test.hex
test.hexはこんな感じになります。
00000013 00100093 00100113 00200193 00300213 00400293 00500313 00600393 00700413 01b00e13 01c00e93 ….
1行あたり32bitで、16進数表記です。
これならコピペしたり、scalaからSource.fromFile
でオープンすることも可能です。
このブログの最後に明記しますが、Makefileを記述したので、make asm
コマンドでワンストップで生成できます。
Scalaからこのファイルをオープンするにはどうしたらいいでしょう。
以下のようにしました。 間違ってたらご指摘ください。
val s = Source.fromFile("test.hex") var bufs :Array[String] = _ try { bufs = s.getLines.toArray } finally { s.close() } // このあと、Arrayから読み出すコードを記述する
ここまでのコード
コードは今後も漸進的に更新されるので、以下のように-bでタグを指定してcloneするのがいいと思います。
macOSな方はGNU odを使う関係上以下のようにしてcoreutilsをインストールしてください。
brew install coreutils
BSD odと区別するためなのはわかってるつもりですけど、GNU odをgodってするのどうかと思いますね………。
どうでもいいですけど。
git clone http://github.com/panda5mt/KyogenRV -b 0.0.10 --depth 1 cd KyogenRV/
アセンブラは(プロジェクトフォルダ)/src/sw/test.sにあります。適宜書き換えてみてください。
nano src/sw/test.s
------- 補足:riscv-gnu-toolchainの導入(まだ導入していない人向け) -------
今回のコードからriscv-gnu-toolchainが必須となります。
こちらからソースからビルドした方がいいかも。
GitHub - riscv/riscv-gnu-toolchain: GNU toolchain for RISC-V, including GCC
パッケージ管理がディストリビューションごとに違うので、依存ファイルの導入はMacの場合を書きます。
brew install python3 gawk gnu-sed gmp mpfr libmpc isl zlib expat coreutils
riscv-gnu-toolchainを導入します。
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain cd riscv-gnu-toolchain git submodule update --init --recursive ./configure --prefix=/opt/riscv --enable-multilib make
PATHを/opt/riscv/binに通します。
nano ~/.bash_profile # または nano ~/.bashrc
.bashrcまたは.bash_profileに以下を追加
export PATH=$PATH:/opt/riscv/bin
source ~/.bash_profile
またはsource ~/.bashrc
でPATHを通します。
------- 補足終わり -------
保存後、プロジェクトのルートフォルダで
make asm
するとアセンブルがはじまります。
また依存関係の解決をMakefileにさせているのでtest.sに変更があった場合は
make test
したときに同時にアセンブルも行います。(riscv-gnu-toolchainが導入されていて、PATHが通っていることが前提です。)
ビルドが完了すると(project_root)/src/sw/test.hex
が生成されます。
話題は変わりますが、上記プロジェクトには分岐命令の一部を実装しています。
この分岐命令の話などは、また次回の記事で。