Slide 1

Slide 1 text

Chisel + RISC-V 2015/02/01 #fpgax No6 LT iwag (@iwag_org) https://flic.kr/p/4m7eim

Slide 2

Slide 2 text

自己紹介 ● iwag ( https://github.com/iwag ) ● 現職:WEBエンジニア ○ C++とかScalaとか ● 前職:組み込みエンジニア ○ CUDA、JavaとかSoCとか ● さらに前はアクセラレータの研究してた ○ 演算方法とかVerilog 書いてました

Slide 3

Slide 3 text

なぜChisel ● MSのアレ ○ 実現可能な範囲をハード化できないか考えてた ● (昔)Verilog + (今)Scala → Chisel !!! ● Chiselとその背景となったRISC-V を触ってみて かなりクールだと思ったので紹介

Slide 4

Slide 4 text

Chisel

Slide 5

Slide 5 text

Chisel ● Scala DSLのハードウェア記述言語 ○ https://github.com/ucb-bar/chisel ○ 高位合成じゃないよ ■ eruby + verilog に近い ○ Scala なので関数型っぽく書ける ○ Verilogと CシミュレータとVCDを生成 ● RISC-Vアーキテクチャの開発のため作られた ○ 副産物として産まれたのがChisel ○

Slide 6

Slide 6 text

雰囲気 Chisel class Mux2 extends Module { val io = new Bundle { val sel = Bits(INPUT, 1) val in0 = Bits(INPUT, 1) val in1 = Bits(INPUT, 1) val out = Bits(OUTPUT, 1) } io.out := (io.sel & io.in1) | (~io.sel & io.in0) } Verilog module mux_using_assign( in0, in1, sel, out ); input in0, in1, sel ; output out; wire out; assign out = (sel) ? in1 : in0; endmodule

Slide 7

Slide 7 text

もっと知りたい方へ ● いおりんさんのスライド ● 公式のチュートリアルもわかりやすい ● 動画もあります

Slide 8

Slide 8 text

RISC-V

Slide 9

Slide 9 text

RISC-V(リスクファイブ) ● V、UCBで作られた5番目のRISC ISA ○ MIPS をさらにシンプルにした感じ http://riscv.org/riscv- spec-v2.0.pdf ○ パタヘネのパターソン先生とかいる ● BSD ライセンスでOSS, Freeなのが売り ○ “INSTRUCTION SETS SHOULD BE FREE” とのこと ○ ISAだけでなくて関連ソフトウェアも ● ライバルはARM? ○ 似たプロジェクト:OpenRISC, LatticeMico32 ● 日本語で扱ってる唯一のブログhttp://msyksphinz.hatenablog.com

Slide 10

Slide 10 text

何に使えるのか? ● VerilogでCPUを作るのは簡単 ● ちゃんと動くの作るのは大変… ○ 必要なものがやまほどあって萎える

Slide 11

Slide 11 text

何に使えるのか? ● VerilogでCPUを作るのは簡単 ● ちゃんと動くの作るのは大変… ○ 必要なものがやまほどあって萎える → 既存の動いてるCPUを改造してオレオレ命令を 実装するとすごく楽ができる →その環境に最適なのがRISC-Vアーキテクチャ

Slide 12

Slide 12 text

必要そうなもの ● アセンブラ・コンパイラ ● テスト ● ISAシミュレータ ● CPU の実装 →RISC-Vなら全部揃ってます

Slide 13

Slide 13 text

やってみた

Slide 14

Slide 14 text

まじめな手順 ● テスト作成 ● アセンブラ改造・コンパイル ● ISAシミュレータを改造 ● ISAシミュレータでテスト ● CPU のコード(Chisel )を改造 ● 生成されたCシミュレータでテスト ● 生成されたRTLシミュレータでテスト ○ RTLシミュレータがなかったので試してません

Slide 15

Slide 15 text

仕様 ● ビット逆順にする reverse Rd, Rs 0xf0f0 → 0x0f0f0000 ● opcodeにこのへん↓が開いてるので突っ込む

Slide 16

Slide 16 text

テストファースト # revserse_asm.S .text .align 2 .globl reverse_asm .type reverse_asm,@function reverse_asm: reverse a0, a0 ret # reverse_main.c extern int reverse_asm(int a); unsigned int reverse(unsigned int x) { x = (x & 0x55555555) << 1 | (x & 0xAAAAAAAA) >> 1; x = (x & 0x33333333) << 2 | (x & 0xCCCCCCCC) >> 2; x = (x & 0x0F0F0F0F) << 4 | (x & 0xF0F0F0F0) >> 4; x = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8; x = (x & 0x0000FFFF) << 16 | (x & 0xFFFF0000) >> 16; return x; } int main() { int a = 0xf0f0; int b,c; setStats(1); c = reverse_asm(a); setStats(0); d = reverse(a); return c-d; // チェック }

Slide 17

Slide 17 text

Rocket CPU ● 5 stage pipeline ● decode と execute(ALU) だけ変更

Slide 18

Slide 18 text

ALU (Chisel) class ALU extends Module { val io = new ALUIO … def reverseBit(v: Bits): UInt = Cat( v(0), v(1), v(2), v(3), v(4), v(5), v(6), v(7), v(8), v(9), v(10), v(11), v(12), v(13), v(14), v(15), v(16), v(17), v(18), v(19), v(20), v(21), v(22), v(23), v(24), v(25), v(26), v (27), v(28), v(29), v(30), v(31)) val out = Mux(io.fn === FN_ADD || io.fn === FN_SUB, sum, Mux(io.fn === FN_SR || io.fn === FN_SRA, shout_r, Mux(io.fn === FN_SL, shout_l, Mux(io.fn === FN_AND, io.in1 & io.in2, Mux(io.fn === FN_OR, io.in1 | io.in2, Mux(io.fn === FN_XOR, io.in1 ^ io.in2, Mux(io.fn === FN_REVERSE, reverseBit(io.in1), cmp))))))) } object XDecode extends DecodeConstants { val table = Array( … ADDI-> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_ADD, N,M_X, MT_X, N,N,Y,CSR.N, N,N,N,N,N,N), REVERSE -> List(Y, N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,FN_REVERSE,N,M_X, MT_X, N,N,Y, CSR.N,N,N,N,N,N,N), … )

Slide 19

Slide 19 text

できた ● 実行 $ RISCV=$HOME/Devel/riscv make run-bmarks-test ./emulator-DefaultCPPConfig +dramsim +max-cycles=100000000 +verbose +loadmem=output/custom0.riscv.hex none 3>&1 1>&2 2>&3 | /usr/local/bin/riscv-dis > output/custom0.riscv.out && [ $PIPESTATUS -eq 0 ] cycle = 1041 instret = 181 ● Cシミュレータのダンプ C0: 1585 [0] pc=[0002cfc] W[r 0=00000f13][0] R[r10=00000f0f] R[r12=00000004] inst=[00c508b3] add v1, s8, s10 C0: 1586 [1] pc=[0002cfc] W[r10=f0f00000][1] R[r10=00000f0f] R[r 0=00000000] inst=[0005050b] unknown これ C0: 1587 [1] pc=[0002d00] W[r 0=00002d04][1] R[r 1=0000303c] R[r 0=00000000] inst=[00008067] jr ra C0: 1591 [1] pc=[00303c] W[r15=00000000][1] R[r 0=00000000] R[r 0=00000000] inst=[00000793] li tp, 0 C0: 1592 [1] pc=[003040] W[r14=00000000][1] R[r15=00000000] R[r 1=00000000] inst=[0017d71b] srliw sp, tp, 1 C0: 1593 [1] pc=[003044] W[r13=0000001f][1] R[r 0=00000000] R[r31=00000000] inst=[01f00693] li s11, 31 C0: 1594 [1] pc=[003048] W[r 0=00000001][0] R[r14=00000000] R[r 0=00000000] inst=[00070e63] beqz sp, pc + 28

Slide 20

Slide 20 text

C0: 2941 [0] pc=[000022a4] W[r 0=aaaab000][0] R[r21=000230d0] R[r10=] inst=[aaaab7b7] lui tp, 0xaaaab C0: 2942 [0] pc=[000022a8] W[r 0=55555000][0] R[r10=000230d0] R[r21=] inst=[555556b7] lui s11, 0x55555 C0: 2943 [0] pc=[000022a8] W[r 0=55555000][0] R[r10=000230d0] R[r21=] inst=[555556b7] lui s11, 0x55555 C0: 2944 [0] pc=[000022b0] W[r 0=fffffaaa][0] R[r15=] R[r10=] inst=[aaa7879b] addiw tp, tp, -1366 C0: 2945 [1] pc=[00002b08] W[r 0=00002b0c][1] R[r 1=000030a8] R[r 0=] inst=[00008067] jr ra C0: 2946 [0] pc=[00002b0c] W[r 0=000231d0][0] R[r 2=000231e0] R[r16=] inst=[ff010113] addi s0, s0, -16 C0: 2947 [0] pc=[00002b0c] W[r 0=000231d0][0] R[r 2=000231e0] R[r16=] inst=[ff010113] addi s0, s0, -16 C0: 2948 [0] pc=[00002b14] W[r 0=000231e8][0] R[r 2=000231e0] R[r 1=000030a8] inst=[00113423] sd ra, 8(s0) C0: 2949 [1] pc=[000030a8] W[r11=00000003][1] R[r 0=] R[r 3=000030a8] inst=[00300593] li s9, 3 C0: 2950 [1] pc=[000030ac] W[r10=00000002][1] R[r 0=] R[r 2=000030a8] inst=[00200513] li s8, 2 C0: 2951 [1] pc=[000030b0] W[r 1=000030b4][1] R[r31=000231e0] R[r20=000030a8] inst=[9f4ff0ef] jal pc - 0xe0c C0: 2952 [0] pc=[000030b4] W[r 0=][0] R[r 0=] R[r 0=] inst=[00000513] li s8, 0 C0: 2953 [0] pc=[000030b4] W[r 0=][0] R[r 0=] R[r 0=] inst=[00000513] li s8, 0 C0: 2954 [0] pc=[000030bc] W[r 0=000231e8][0] R[r 2=000231e0] R[r 8=000030a8] inst=[00813083] ld ra, 8(s0) C0: 2955 [1] pc=[000022a4] W[r15=aaaab000][1] R[r21=000231e0] R[r10=000030a8] inst=[aaaab7b7] lui tp, 0xaaaab C0: 2956 [1] pc=[000022a8] W[r13=55555000][1] R[r10=000231e0] R[r21=000030a8] inst=[555556b7] lui s11, 0x55555 C0: 2957 [1] pc=[000022ac] W[r13=55555555][1] R[r13=55555000] R[r21=000030a8] inst=[5556869b] addiw s11, s11, 1365 C0: 2958 [1] pc=[000022b0] W[r15=aaaaaaaa][1] R[r15=aaaab000] R[r10=000030a8] inst=[aaa7879b] addiw tp, tp, -1366 C0: 2959 [1] pc=[000022b4] W[r15=00000002][1] R[r10=00000002] R[r15=aaaaaaaa] inst=[00f577b3] and tp, s8, tp C0: 2960 [1] pc=[000022b8] W[r10=][1] R[r10=00000002] R[r13=55555555] inst=[00d57533] and s8, s8, s11 C0: 2961 [1] pc=[000022bc] W[r10=][1] R[r10=] R[r 1=55555555] inst=[0015151b] slliw s8, s8, 1 Cのreverse実装(22clk)

Slide 21

Slide 21 text

つまり 22clk => 1clk 22倍高速!!!!!

Slide 22

Slide 22 text

感想 https://flic.kr/p/eqySu3

Slide 23

Slide 23 text

よい点:OSS ● フルアクセスできる… ○ エミュレーター ○ コンパイラ等 ○ ハード ●

Slide 24

Slide 24 text

エミュレーター ● ISA シミュレータ ucb-bar/riscv-isa-simulator ● qemu ucb-bar/riscv-qemu ●

Slide 25

Slide 25 text

● binutils, gcc, newlib ucb-bar/riscv-gnu-tools ● llvm ucb-bar/riscv-llvm ● clang ucb-bar/riscv-clang ● テスト ucb-bar/riscv-tests ○ 命令レベルの単体テスト、ベンチマーク ● Linux ucb-bar/riscv-linux コンパイラ、OS等

Slide 26

Slide 26 text

ハード ● rocket (CPU code) ucb-bar/rocket ● uncore (cache, float) ucb-bar/uncore ● riscv-fpga (zynq support) ucb-bar/fpga-zynq ○ サポートしてるのはZedBoard, Zybo, ZC706

Slide 27

Slide 27 text

● githubで今風の開発をしている! ○ アクティビティ ○ プルリクエスト よい点:github

Slide 28

Slide 28 text

今っぽい開発 https://github.com/ucb-bar

Slide 29

Slide 29 text

プルリクエストベースの開発

Slide 30

Slide 30 text

よい点:モダンなインストーラ ● homebrewでインストール(OSXなら) $ brew tap ucb-bar/riscv $ brew install riscv-tools …. $ riscv-gcc -v Using built-in specs.COLLECT_GCC=riscv-gccCOLLECT_LTO_WRAPPER=/usr/local/Cellar/riscv- gcc/gnu/libexec/gcc/riscv-elf/4.9.1/lto-wrapperTarget: riscv-elfConfigured with: /private/tmp/riscv-gcc- 7Mq0WF/build/src/newlib-gcc/configure --target=riscv-elf --prefix=/usr/local/Cellar/riscv-gcc/gnu --disable- shared --disable-threads --enable-tls --enable-languages=c,c++ --with-newlib --disable-libmudflap -- disable-libssp --disable-libquadmath --disable-libgomp --disable-nlsThread model: singlegcc version 4.9.1 (GCC)

Slide 31

Slide 31 text

よい点:Chisel いい ● 普段使いしてるInteliJ使うと ほぼソフトウェア開発… ○ 補完も効く ○ 難解なScalaのライブラ リっぽい感覚 ● IntelliJ IDEA Community Edition(無料)でいけます

Slide 32

Slide 32 text

つらい点:Chisel つらい ● Scala なのにコンパイル時にチェックしてくれない ● wireやレジスタが64bit or 32bit 決め打ち ● 想像より生成されるVerilogが読めない

Slide 33

Slide 33 text

つらい点:コンパイラのバグ ● 同じファイル内の関数は呼び出してくれない(?) ○ 別ファイルの関数なら呼べる ● わからん

Slide 34

Slide 34 text

つらい点:RISC-V RISC-Vの将来性(◞‸◟)

Slide 35

Slide 35 text

今後 ● Zynqボード買ってちゃんと動かしたい ● プルリク送りたい ● ゆくゆくはbingのアレのミニみたいなのをやりたい ○ 全文検索特化の拡張命令ってなんだろう