FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages

Chisel-Templateを使ってオリジナルデザインを作ってみるチュートリアル (3. CPUのコアのDebug-Trace作成)

随分とほったらかしにしていたが、Chiselを使ってオリジナルデザイン開発を再開した。

簡単なRISC-VコアをフルスクラッチでChiselで作ってみて、Chiselの理解を深めようと思う。

msyksphinz.hatenablog.com

まず、テストパタンを用意しなければならない。テストパタンはテキストファイルで作って、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
  }
}

これで何となくログが出てくるようになった。

f:id:msyksphinz:20181118002157p:plain