FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

教育用RISC-V実装Clarviの調査

Twitterでvengineerさんに教えてもらった教育用RISC-V実装、Clarviについて簡単に調査してみた。

Clarviは大学が教育用に作成したRISC-Vプロセッサで、もちろんRISC-Vの仕様に完全に準拠しているわけではないが、非常にコンパクトな実装と、教育用に簡単な拡張が行えるような工夫がなされているプロセッサだ。

  • ECAD and Architecture Practical Classes

Computer Laboratory – Course pages 2016–17: ECAD and Architecture Practical Classes - Lab 1- Clarvi

実装を試行するためには、上記のホームページからclarvi.zipsoftware.zipをダウンロードする必要がある。

clarvi.zipはハードウェア実装になっており、メインのファイルはclarvi.svだけで非常に簡潔に記述してある。一部だがシステムレジスタもサポートしてある。

足回りについては、

  • ハーバードアーキテクチャ(命令系とデータ系が分離された足回り)
  • 6ステージパイプライン
    • 命令フェッチ → デコード → 実行 → メモリアライン → ライトバック
  • バスインタフェースはAvalon-Bus
  • 外部割込みを1本サポート
  • サポート命令
    • LUI
    • AUIPC
    • JAL, JALR
    • BEQ, BNE, BLT, BLTU, BGE, BGEU
    • Load系命令、Store系命令
    • ADD, SUB, SLT, SLTU, XOR, OR, AND, SLL, SR
    • FENCE
    • CSRRW, CSRRS, CSRRC
    • その他若干の特権操作命令

ソフトウェアのビルド

software.zipを使おう。ソフトウェアはMakefileをたたくだけで簡単にビルド可能だ。

$ cd software/example-asm
$ make
mkdir -p build
riscv32-unknown-elf-gcc -c -o build/init.o src/init.s -O0 -m32 -march=RV32I
riscv32-unknown-elf-gcc -c -o build/main.o src/main.s -O0 -m32 -march=RV32I
riscv32-unknown-elf-gcc -o build/program.elf build/init.o build/main.o -T link.ld -nostdlib
riscv32-unknown-elf-objcopy -O binary --only-section=.data* --only-section=.text* build/program.elf build/mem.bin
hexdump -v -e '"%08x\n"' build/mem.bin > build/mem.txt
python txt2hex.py build/mem.txt build/mem.hex 4
riscv32-unknown-elf-objdump -S -s build/program.elf > build/program.dump
$ less build/program.dump
Disassembly of section .text.init:

00000000 <entry>:
   0:   00010117                auipc   sp,0x10
   4:   fe010113                addi    sp,sp,-32 # ffe0 <main+0xffac>
   8:   00000297                auipc   t0,0x0
   c:   01428293                addi    t0,t0,20 # 1c <end>
  10:   30529073                csrw    mtvec,t0
  14:   020000ef                jal     34 <main>
  18:   00000073                ecall

0000001c <end>:
  1c:   0000006f                j       1c <end>

Disassembly of section .text:

00000020 <myfunction>:
  20:   fe010113                addi    sp,sp,-32
  24:   00112023                sw      ra,0(sp)
  28:   00012083                lw      ra,0(sp)
  2c:   02010113                addi    sp,sp,32
  30:   00008067                ret

00000034 <main>:
  34:   fe010113                addi    sp,sp,-32
  38:   00112023                sw      ra,0(sp)
  3c:   fe5ff0ef                jal     20 <myfunction>
  40:   00012083                lw      ra,0(sp)
  44:   00008067                ret

リンカスクリプトはアドレス0からプログラムとデータを配置させる仕様になっている。 非常に簡単なプログラムだが動作させることが出来る。

ただし、シミュレーションを実行するためにはSystemVerilogに対応したシミュレータが必要だ。デフォルトではModelSimで動作するようにパッケージが記述されている。 バリバリにSystemVerilogの記述が使われているので、だましてVerilogシミュレータで動作させるのはちょっと無理っぽい。そんな高価なシミュレータは持っていないのでシミュレーションするのは諦めよう。。。