ググってもなかなか出てこないのでメモ代わりに書いておく.動作確認はしてますが間違いがあるかもしれません
Chipyardは詳しくないので知ってる人がいたらコメントで教えて下さい
(今後追記・修正するかも)
Chipyardでの簡単なプログラムの実行
事前にChipyard(https://github.com/ucb-bar/chipyard )とriscv-tests(https://github.com/riscv-software-src/riscv-tests )をクローンしておき,Chipyardでhttps://chipyard.readthedocs.io/en/latest/Chipyard-Basics/Initial-Repo-Setup.html を参考にツールチェインとかをビルドしておく.
Chipyardのディレクトリで次を実行
source env.sh
cd sims/verilator
make debug CONFIG=DualSmallBoomConfig VERILATOR_FST_MODE=1
(chipyard/generators/chipyard/src/main/scala/config/BoomConfigs.scalaにある次のコアをビルドするらしい.他のConfigを参考にすれば自分好みのマルチコアを作れると思う)
class DualSmallBoomConfig extends Config(
new boom.common.WithNSmallBooms(2) ++ // 2 boom cores
new chipyard.config.AbstractConfig)
riscv-tests/benchmarks/common/crt.Sの125行目を次のように書き換える(ここのa1レジスタでコアがいくつあるかを示す)
li a1, 2
次のようにhello.c
を作る
#include<stdio.h>
#include<stdlib.h>
volatile int _wait = 0;
void thread_entry(int cid, int nc)
{
if(cid == 0) {
while(_wait == 0);
printf("Core ID; %d\n", cid);
exit(0);
}
else {
printf("Core ID: %d\n", cid);
_wait = 1;
asm volatile("wfi;");
}
}
要するにコア0では_wait
が0以外になるまで無限ループで待って,終了する.コア1では_wait
を1にして,その後wfi
命令で割り込みがあるまで待機する.
hello.c
を次のようにコンパイルする(riscv-testsのMakeの出力を参考にした)
riscv64-unknown-elf-gcc -I/home/hidetaro/github_dir/riscv-tests/benchmarks/../env -I/home/hidetaro/github_dir/riscv-tests/benchmarks/common -DPREALLOCATE=1 -mcmodel=medany -static -std=gnu99 -O2 -ffast-math -fno-common -fno-builtin-printf -fno-tree-loop-distribute-patterns -o hello hello.c /home/hidetaro/github_dir/riscv-tests/benchmarks/common/syscalls.c /home/hidetaro/github_dir/riscv-tests/benchmarks/common/crt.S -static -nostdlib -nostartfiles -lm -lgcc -T /home/hidetaro/github_dir/riscv-tests/benchmarks/common/test.ld
Chipyardのsims/verilator
ディレクトリで次のように実行する(最後のところはプログラムの場所に応じて変更する)
./simulator-chipyard-DualSmallBoomConfig-debug --vcd=dualboomhello.fst --verbose ~/riscv/chipyard_test/hello
実行結果
using random seed 1662501447
This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1.
Listening on port 45895
[UART] UART0 is here (stdin/stdout).
Core ID: 1
Core ID; 0
*** PASSED *** Completed after 34928 cycles
両方のコアがたぶん動作していることが確認できる.ただしコア0の部分でwhileとprintfを入れ替えると何故か動作しなくなったりするのでどっかたぶん間違えてそう