随分とほったらかしにしていたが、Chiselを使ってオリジナルデザイン開発を再開した。
簡単なRISC-VコアをフルスクラッチでChiselで作ってみて、Chiselの理解を深めようと思う。
まず、テストパタンを用意しなければならない。テストパタンはテキストファイルで作って、Scalaで読み込んでメモリに格納する。
まずはコンパイルしたプログラムを、objcopy → od でテキストファイル形式に変換する。
- tests/simple/simple.s
_start: li x1, 0 li x2, 1 li x3, 2 li x4, 3 li x5, 4 li x6, 5 li x7, 6 li x8, 7 ...
$(TARGET).hex : $(TARGET).bin od -tx4 -v -w4 -Ax $^ | sed 's/^/0x/g' | gawk -F ' ' '{printf "@%08x %s\n", rshift(strtonum($$1), 2), $$2}' > $@ $(TARGET).bin : $(TARGET).elf riscv64-unknown-elf-objcopy --gap-fill 0 -O binary $^ $@ $(TARGET).elf : $(TARGET).s riscv64-unknown-elf-as $^ -o $@
- tests/simple/test.hex
@00000000 00000093 @00000001 00100113 @00000002 00200193 @00000003 00300213 @00000004 00400293 @00000005 00500313 ...
これをScalaで読み込んでメモリに格納する。
val fp = Source.fromFile("test.hex") val lines = fp.getLines val memory = lines.map{ line => val split_line = line.split(" ") if (split_line.length == 2) { Array(Integer.parseInt(line.split(" ")(0).diff("@"), 16), Integer.parseUnsignedInt(line.split(" ")(1), 16)) } else { Array(Integer.parseInt(line.split(" ")(0).diff("@"), 16), 0) } }
ちなみに、Chiselでprintfを使うと、%x
のサイズが指定できなくて苦労する。そこでPrintHex()を自分で作って桁指定のできるprintfを作ってとりあえず難をしのぐ。
object PrintHex { def apply(x: UInt, length: Int): String = { require(length > 0) var result = "" for (i <- length-1 to 0 by -1) { printf("%x", (x >> (4.U * i.asUInt)) & 0xf.U) } result } def apply(x: SInt, length: Int): String = { require(length > 0) var result = "" for (i <- length-1 to 0 by -1) { printf("%x", (x.asUInt >> (4.U * i.asUInt)) & 0xf.U) } result } }
これで何となくログが出てくるようになった。