Slide 1

Slide 1 text

TS-3 ますます注目される オープンCPUアーキテクチャ RISC-Vの最新動向 The latest trend of RISC-V, attracted open CPU architecture FPGA開発日記 著者 @msyksphinz_dev http://msyksphinz.hatenablog.com 1

Slide 2

Slide 2 text

本日のセッションについて • RISC-Vについて知ってはいるけどあまり詳しくない方のために 2 RISC-Vの概要 RISC-Vの命令セット仕様 RISC-Vを動かしてみよう HiFive1ボードを動かしてみよう RISC-VのRTL実装Rocket-Chipを動かしてみ よう RISC-Vの命令セットシミュレータを作って Linuxを立ち上げよう

Slide 3

Slide 3 text

RISC-Vの概要と歴史 3

Slide 4

Slide 4 text

RISC-Vとは • カリフォルニア大学バークレイ校(UCB)が2011年から公開している新しい 命令セットアーキテクチャ • シンプルかつオープン、しかしLinuxが動くまでにはしっかりしている • かつ、自由にカスタマイズ可能 • RISC-Vの仕様を決定する非営利団体”RISC-V Foundation” • GoogleやNVIDIAなどがメンバーに加入し注目を浴びる • 2018年9月現在で加盟団体・企業は150に迫る

Slide 5

Slide 5 text

RISC-V発展の歴史 2011 2012 2013 2014 2015 2016 2017 RISC-V Processor Raven-1 7th RISC-V Workshop 6th RISC-V Workshop RISC-V Processor Raven-2 RISC-V Processor Raven-3 5th RISC-V Workshop 4th RISC-V Workshop 3th RISC-V Workshop 1th RISC-V Workshop 2th RISC-V Workshop User-Level ISA Ver. 1.0 User-Level ISA Ver. 2.0 User-Level ISA Ver. 2.1 User-Level ISA Ver. 2.2 Privileged ISA Ver. 1.7 Privileged ISA Ver. 1.9 Privileged ISA Ver. 1.10 世界発の商用 RISC-Vボード 研究チップの制御 プロセッサとして利用 ヘネパタ第6版は RISC-Vで刷新 パタヘネのRISC-V 版が登場 約半年に1回の頻度で Workshop開催 8th RISC-V Workshop in Barcelona RISC-V Day in Shanghai 9th RISC-V Workshop in Chennai RISC-V Day in Tokyo RISC-V Day in MICRO51 RISC-V Summit in Santa Clara Linuxが動作す るRISC-Vボード 2018 ◼ 2015年から定期的にWorkshopを開催 ◼ トップカンファレンスにRISC-Vネタで 通している。 ◼ パタヘネ・ヘネパタはRISC-Vに移行 ◼ 2017年/2018年に日本でイベント開催

Slide 6

Slide 6 text

Turing Award 2017 を受賞した David A. PattersonがRISC-Vを推す 6 https://sdtimes.com/devexec/john-l-hennessy-david-patterson-awarded-2017-acm-m-turing-award-risc-approach/ David Patterson & Andrew Waterman “RISC-V Reader : An Open Architecture Atlas”

Slide 7

Slide 7 text

気づかぬ間に浸透しています “RISC-V” According to the LinkedIn profile, work on the Exynos 9820 began in January this year, and the Samsung engineer appears to have been working on a 5G RF chip based on the RISC-V architecture ever since May 2017, which could reinforce a 2019 release for the 5G smartphones. (https://www.notebookcheck.net/Samsung-Exynos-9820-SoC-and-5G-RF-chips-already-in-the- works.295886.0.html) WD、同社製品搭載のプロセッサ/コントローラなどをRISC-Vへ移行 (https://pc.watch.impress.co.jp/docs/news/1094891.html) NVIDIA gave a presentation about how its proprietary Falcon (Fast Logic CONtroller) core will be replaced by RISC-V cores. (https://www.electronicdesign.com/industrial-automation/rise-risc-v-display-workshop) Internal Project to demonstrate ability to easily develop custom RISC-V implementation by leveraging Rocket Chip. (https://content.riscv.org/wp-content/uploads/2018/05/13.15-13.30-matt-Cockrell.pdf) BSC is promoting the adoption of RISC-V as a key partner of the European Processor Initiative, the consortium to design and develop Europe’s low-power processors and related technologies for extreme- scale, high-performance computing, which will be funded by the European Commission under the Horizon 2020 program. (https://insidehpc.com/2018/05/bsc-host-risc-v-workshop-road- european-processor-initiative/)

Slide 8

Slide 8 text

“RISC-V 命令セットアーキテクチャ” を支えるエコシステム RISC-V Foundation Working Group GCC Binutils LLVM Linux QEMU ISS BOOM Rocket- Chip Freedom SoC HiFive1 HiFive Unleashed ボード・ プラットフォーム SIMD拡張 Privileged Spec セキュリティ メモリモデル ソフトウェア ツールチェイン Board of Directorsを中心に、ISAの各分野でWorking Groupが存在している。 … Linux パッケージメンテナ 有志によるOS 移植 Foundation 加入 メンバによるメンテ Foundation 加入 メンバによる開発 Board of Directors RISC-V ISA Manual

Slide 9

Slide 9 text

手っ取り早くRISC-Vを試すために (情報収集方法) RISC-V メーリングリスト, github Wikiなど sifive.com メーリングリスト 書籍、雑誌など ブログなど

Slide 10

Slide 10 text

コンピュータアーキテクチャの教科書が 次々とRISC-Vに移行 10 コンピュータの構成と設計 通称パタヘネ Computer Architecture: A Quantitative 通称ヘネパタ RISC-V原典 オープンアーキテクチャのススメ 原本: RISC-V Reader Patterson先生が書いた。10/22新発売

Slide 11

Slide 11 text

RISC-V命令セット仕様 11

Slide 12

Slide 12 text

RISC-Vアーキテクチャ 命令セット外観 12 ARM Manual 6000ページくらい RISC-V Manual 200ページくらい どっちが良いかは別にして… 細かいことをいろいろ喋っても仕方がないので外観だけ。 ざっくりと必要なところだけ説明します。 もはや凶器

Slide 13

Slide 13 text

RISC-Vの特権モードと動作モード • 3種類の動作モードが定義されている • 最初の版では4種類だったが削減されて3種類 • ユーザモード • 最も権限の少ないモード。アプリケーション を動かすためのモード • スーパバイザモード • OSが例外処理などを行うための権限の高い モード。 • マシンモード • 最も権限が高い。マシンモード。何でもでき る • モード間の遷移について • 外部から割り込み挿入 or 命令実行中に例外発 生 • ECALL命令によるSupervisor Call • 例外処理後に実行するMRET / SRET / URET 13 マシンモード スーパバイザモード ユーザモード

Slide 14

Slide 14 text

RISC-V命令セットアーキテクチャ形態について • RISC-Vは大きく「基本命令セット」と 「拡張命令セット」に分かれる。 • 基本命令セット : RV32I / RV32E / RV64I / RV128I • 拡張命令セット : 基本命令セット+特定向け命令 • 浮動小数点とか、ベクトル命令とか 14 “A” atomic拡張 “C” 16bit短縮命令 “F” 単精度浮動小数点 “D” 倍精度浮動小数点 “L” 10進数浮動小数点 “Q” 4倍精度浮動小数点 “M” 乗除算命令 “S” スーパバイザモード “P” Packed SIMD “V” Vector拡張 “N” ユーザレベル割り込み RV32I RV32E RV64I RV128I 拡張命令 基本命令 RV32I RV32E RV64I RV128I + M A F D + + + M A F D C = RV32G = RV64GC ■ RISC-V アーキテクチャの呼び方 アーキテクチャ識別子を付加して呼ぶ

Slide 15

Slide 15 text

RISC-Vのレジスタ 15 x0 x1 x2 x3 x4 x5 x31 … XLEN=128 x0 x1 x2 x3 x4 x5 x31 … XLEN=64 x0 x1 x2 x3 x4 x5 x31 … XLEN=32 f0 f1 f2 f3 f4 f5 f31 … FLEN=128, Q Extension f0 f1 f2 f3 f4 f5 f31 … FLEN=64, D Extension f0 f1 f2 f3 f4 f5 f31 … FLEN=32, F Extension 整数レジスタの表記は全てxN x0 – x31まで定義 整数レジスタ長はXLENで表記される RV32 : XLEN=32 RV64 : XLEN=64 RV128 : XLEN=128 浮動小数点レジスタの表記は全てfN f0 – f31まで定義 浮動小数点レジスタ長はFLENで表記される F拡張 : FLEN=32 D拡張 : FLEN=64 Q拡張 : FLEN=128

Slide 16

Slide 16 text

Floatレジスタは Single/Double/Quadで共有 • 例えば、Float⇔DoubleのConvert命令の場合 • FCVT.D.S fd, fs • FCVT.S.D fd, fs • DoubleとFloatがレジスタを 共有しているので • NaN Boxingをサポートする必要がある • FLEN>32で、Single Floating Pointの命令を実行するときは、 32bit以上の値は全て1が設定されている必要がある 16 fd fs Convert 1111…1111 Single-Float Value FLEN=64 Single値として見た場合 : 普通の値 Double値としてみた場合 : 上位がすべて1 なので NaN → 型を明確に識別するための手法

Slide 17

Slide 17 text

割り込み・例外 • RISC-Vの割り込み・例外要因は多くない • 割り込み • ソフトウェア割り込み • タイマ―割り込み • 外部割込み • ユーザ・スーパバイザ・ マシンモード毎に定義 • 外部割込みが少ないので PLICを外部に定義 17

Slide 18

Slide 18 text

C命令系列 (Compressed命令) • RISC-Vの通常命令は32-bit • C命令系列は16ビット長 • RISC-Vの命令種はシンプルな分、命令密度が低い • 16-bit長命令を使ってマイクロアーキテクチャの面で 効率を上げる 18 RD  RD + RS1 RD  RD + IMM Stack-relative Store Compact Load Compact Store Compact Jump

Slide 19

Slide 19 text

RISC-Vの拡張命令 • RISC-Vの命令系列にはカスタム領域が存在する • 将来のための予約領域 (現時点では好き勝手に使うことも?) • 実はRISC-Vの命令セットは64-bit長の領域が定義されている 19

Slide 20

Slide 20 text

RISC-Vのシステムレジスタ • システムレジスタは専用命令でアクセスする。 • csrrw (CSR Register Read/Write) • csrrs (CSR Register Set) • csrrc (CSR Register Clear) • csrrwi (CSR Register Read/Write Immediate) • csrrsi (CSR Register Set Immediate) • csrrci (CSR Register Clear Immediate) • 汎用レジスタとCSRレジスタの交換 (csrrw / csrrwi) • 即値を指定してCSRの特定のビットを1に設定する (csrrs/csrrsi) • 即値を指定してCSRの特定のビットを0に設定する(csrrc/csrrci) 20 x0 x1 x2 x31 CSR 基本は1命令で データを交換

Slide 21

Slide 21 text

CSRレジスタの系統 • Machine-Mode, Supervisor-Mode, User-Mode用の CSRレジスタでアドレス空間が分けられている 21 User-Mode Supervisor-Mode Machine-Mode

Slide 22

Slide 22 text

仮想メモリ • RISC-Vの仮想メモリは(比較的)複雑 • Sv32 : VA 32bit → PA : 34bit • Sv39 : VA 39bit → PA : 56bit • Sv48 : VA 48bit → PA : 56bit 22 Bare Sv32 Bare Sv39 Sv48 RV32 RV64 SATP vpn[2] vpn[1] vpn[0] offset ppn[1] ppn[0] + + ppn[1]ppn[0] + ppn[1]ppn[0] + Supervisor Address Translation and Protection Register 物理メモリ アドレス 仮想メモリ アドレス

Slide 23

Slide 23 text

RISC-V命令セットの実際性能 23 ・RV32 / RV64は他のISAに比べて コードサイズが大きい → フェッチサイズが大きい。 ・そこで、RV32C / RV64Cという 圧縮命令を活用する。 → フェッチサイズを圧縮できる。 Computer Architecture Research with RISC-V Krste Asanovic より抜粋 ISA Shootout: Comparing RISC-V, ARM, and x86 on SPECInt 2006 より抜粋 RV32GC / RV64GCでは、多くの ベンチマークプログラムで他の 命令セットよりも優れる。

Slide 24

Slide 24 text

Micro-Op Fusionによる性能向上 24 そもそも命令密度において優位性が無いので、マイクロアーキテクチャにより 実行性能を上げるしかない。 実行時に複数命令をFusionさせて発行することで、性能を向上させる → Micro-Op Fusion Computer Architecture Research with RISC-V より抜粋

Slide 25

Slide 25 text

現在Discussionが行われているISA仕様 25 ■ Vector Extension (SIMD) https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc 大枠が固まりつつあるが、最終決定には至っていない。 ■ Hypervisor Extension 現在Discussionが行われている。Ver 0.2 がRISC-V Tokyo 2018で紹介された。

Slide 26

Slide 26 text

RISC-Vの導入のしどころ RISC-V導入のメリット・デメリット 26

Slide 27

Slide 27 text

メリット RISC-Vを導入することによる メリット・デメリット RISC-Vを導入すれば、すべてが解決するなどと言うつもりはありません。 企業が作ったアーキテクチャ ではないので、企業の 経営状態に左右されない ◼ 注目されている分、メリット・デメリットがある。 ◼ 冷静に分析し、「自社にとってどのようなメリットがあるのか?」を解析する必要がある。 デメリット RISC-Vはカスタマイズが可能 RISC-Vは商用プロセッサほど 実装技術が最適化されていない ソフトウェアエコシステムが ある程度用意されている RISC-Vは ISAの断片化の恐れがある 一社で開発される実装は仕様が 統一されている RISC-Vはライセンス料の 問題を削減できる 歴史あるアーキテクチャは プラットフォームも豊富

Slide 28

Slide 28 text

RISC-Vが解決すること、しないこと ライセンス料・特許の問題 例: IBM産業スパイ事件 Intelはx86命令に対して膨大な特許を持っている 自社でCPUを独自開発して、その特許を掻い潜れるか? → オープンソースISAに乗った方が特許の問題を解決できる ライセンス料・特許の問題 をすべて解決できるか?→ No マイクロアーキテクチャ(実装)の特許は解決できない。

Slide 29

Slide 29 text

RISC-Vを導入することによるメリットを しっかり考えること • 自社独自コアを持っているが、メンテナンスに手が回らない場合 • ソフトウェアエコシステムを含めてRISC-Vを導入することによりコストを削減する • 独自開発したことによる特許の問題が心配な場合 • 本当に力を入れたいのは、CPUコアではなく別のところにある場合 • 補助プロセッサとしてRISC-Vを使用するという選択肢 • 制御プロセッサの設計とメンテナンスに必要なコストを最小化する。 • 開発しているチップがプロセッサメインで性能が要求される場合 • 余力あればRISC-Vプロセッサを独自に開発するという選択肢がある • 特許に関する問題を解決することができれば。 いろんな手段はありますが 用量・用法を守ることが肝要です

Slide 30

Slide 30 text

RISC-Vを触ってみましょう 30

Slide 31

Slide 31 text

31 まず何をしたい? とりあえず手持ちのプログラムを RISC-V向けにコンパイルして 実行してみたい。 riscv-toolsによる 開発環境の整備 riscv-isa-simによる シミュレーション QEMUによるLinux のブート RISC-VプロセッサのRTL シミュレーションをしてみたい Rocket-Chipの RTL立ち上げ BOOMの RTL立ち上げ RISC-Vチップを使ってプログラム をガリガリ書いてみたい。 RISC-Vについてもっと 詳しく理解したい。 RISC-Vシミュレータ を作ろう RISC-VチップHiFive1 を使ってみよう。

Slide 32

Slide 32 text

riscv-toolsリポジトリの中身 32 riscv-tools riscv-openocd riscv-fesvr riscv-gnu-toolchain riscv-isa-sim riscv-opcodes riscv-tests riscv-pk RISC-Vデバッグ用のOpenOCD実装 シミュレーション用のフロントエンドサーバ コンパイラやライブラリなど 命令セットシミュレータ RISC-Vテストパタン RISC-Vのプロキシカーネル RISC-Vのソフトウェア開発を行う際の最もBaseとなるツール群が 入っている。 全部ダウンロードするとかなりディスクを消費します(2GBくらい)。

Slide 33

Slide 33 text

RISC-Vのソフトウェア環境を用意する 33 $ git clone https://github.com/riscv/riscv-tools.git $ cd riscv-tools $ export RISCV=/home/msyksphinz/riscv64 $ MAKEFLAGS=“-j8” ./build.sh ... $ cd ${RISCV}/ $ export PATH=${RISCV}/bin:${PATH} $ export LD_LIBRARY_PATH=${RISCV}/lib:${LD_LIBRARY_PATH} $ git clone https://github.com/riscv/riscv-tools.git $ cd riscv-tools $ export RISCV=/home/msyksphinz/riscv32 $ MAKEFLAGS=“-j8” ./build.sh ... $ cd ${RISCV}/ $ export PATH=${RISCV}/bin:${PATH} $ export LD_LIBRARY_PATH=${RISCV}/lib:${LD_LIBRARY_PATH} 64-bit版 RISC-Vツールチェイン 32-bit版 RISC-Vツールチェイン

Slide 34

Slide 34 text

GCCを使ってプログラムをコンパイル & シミュレーション 34 #include int gcd (int a, int b) { int c; if (a < b) { int tmp; tmp = b; b = a; a = tmp; } while (b != 0) { c = a % b; a = b; b = c; } return a; } int main () { printf ("hello world¥nCalling GCD ...¥n"); printf ("GCD(273, 21) = %d¥n", gcd(273, 21)); printf ("GCD(411, 27117) = %d¥n", gcd(411, 27117)); return 0; } $ riscv64-unknown-elf-gcc gcd.c –o gcd $ riscv64-unknown-elf-objdump -D gcd > gcd.dmp $ spike pk gcd <> <> hello world Calling GCD ... GCD(273, 21) = 21 GCD(411, 27117) = 3 <> 命令セットシミュレータを実行

Slide 35

Slide 35 text

“spike gcd”って何をしているの? • SpikeはUCBが開発しているRISC-V命令セットシミュレータ • Linuxも起動することができる • 各種外部デバイスもサポートしている • タイマ • 割り込みなど • システムコールが呼び出されると pk(Proxy Kernel)を通じてホ ストのLinuxマシンに処理を依頼する • printf()や、ファイルシステムのアクセスも実現可能 35 x86 Host Linux pk (proxy kernel) Spike RISC-V Simulator dtb Device Tree Blob Target Program Elf Log Files

Slide 36

Slide 36 text

ベンチマークプログラムのコンパイル・ シミュレーション実行 • riscv-testsディレクトリ • 命令セットのテストパタンや、ベンチマークプログラムが格納されて いる。 • riscv-tools/riscv-tests/benchmarks 36 $ spike ${RISCV}/riscv64-unknown-elf/share/riscv-tests/ ¥ benchmarks/dhrystone.riscv Microseconds for one run through Dhrystone: 396 Dhrystones per Second: 2525 mcycle = 198024 minstret = 198030 Dhrystoneの実行 $ cd freedom-u-sdk $ spike work/riscv-pk/bbl ... Welcome to Buildroot buildroot login: root root Password: sifive # echo hello echo hello hello # Linuxもブートできます

Slide 37

Slide 37 text

QEMUでLinuxを立ち上げる(1) 37 $ wget https://download.qemu.org/qemu-2.12.0.tar.xz $ tar Jxf qemu-2.12.0.tar.xz $ cd qemu-2.12.0/ $ mkdir build $ cd build $ ../configure --target-list=riscv64-softmmu --prefix=${RISCV} TargetをRISC-Vに設定して QEMUをビルド $ wget https://fedorapeople.org/groups/risc-v/disk-images/vmlinux $ wget https://fedorapeople.org/groups/risc-v/disk-images/bbl $ wget https://fedorapeople.org/groups/risc-v/disk-images/stage4- disk.img.xz $ xzdec -d stage4-disk.img.xz > stage4-disk.img Linuxのイメージをダウンロード

Slide 38

Slide 38 text

QEMUでLinuxを立ち上げる(2) 38 qemu-system-riscv64 ¥ -nographic -machine virt -kernel bbl ¥ -object rng-random,filename=/dev/urandom,id=rng0 ¥ -device virtio-rng-device,rng=rng0 -append "console=ttyS0 ro root=/dev/vda" ¥ -device virtio-blk-device,drive=hd0 -drive file=stage4-disk.img,format=raw,id=hd0 ¥ -device virtio-net-device,netdev=usernet -netdev user,id=usernet,hostfwd=tcp::10000-:22 QEMUの起動 Fedoraの起動

Slide 39

Slide 39 text

世界初のRISC-V 商用チップ HiFive1

Slide 40

Slide 40 text

初の商用RISC-V評価ボード “HiFive1” • SiFive社から発売 • 日本だとボード1枚につき10,000円で入手可 • Raspberry-Pi3よりも高い… • 主な仕様 • RV32IMAC • 32-bitモード • ハードウェア乗算器・除算器搭載 • Atomic命令搭載 • Compact命令(16-bit長命令)搭載 • 最大動作周波数: 320MHz • キャッシュ • L1IC : 16kB / L1DC : 16kB • SPIフラッシュ : 128Mbit

Slide 41

Slide 41 text

様々な開発環境を用意している • RISC-Vのアピールチップだと思えば 何ということはない • HiFive1を制御するアプローチはさまざま • Windows, Linux, MacOSどれでも可 • GUI, CUIなど様々な環境が用意されている • Lチカ、ベンチマークプログラム動作 くらいなら一瞬で出来る • 立ち上げは超お手軽 • GUIでも開発できる • Freedom Studio • Windows • Linux • MacOS

Slide 42

Slide 42 text

HiFive1/Freedom SoCのための FreedomStudio • SiFiveが提供されるEclipseベースの開発環境 • Windows / Linux / MacOS に対応している • SiFiveの提供している各種プラットフォームに対応 • HiFive1 • Freedom E300 • Freedom U500 42

Slide 43

Slide 43 text

GUIが嫌いな人のための、”Freedom-SDK”開発環境 • https://github.com/sifive/freedom-e-sdk • HiFive1構成用riscv-tools、ベンチマークプログラム、サンプルプログラムなど 一通り揃う • printf、getc的な物も使える freedom-e-sdk bsp openocd riscv-gnu-toolchain software demo_gpio dhrystone welcome local_interrupt led_fade # software/demo_gpioをコンパイル $ make software PROGRAM=demo_gpio # software/demo_gpio を Hifive1にupload $ make upload PROGRAM=demo_gpio # HiFive1のコンソールを出力を取得 $ screen /dev/ttyUSB1 115200

Slide 44

Slide 44 text

HiFive1を使ってちょっと複雑なプログラムを実行してみた い • 最近流行りのニューラルネットワークをHiFive1に移植して動作させる • ターゲットアプリケーション: MNIST (数字文字認識) • 今回は推論の部分のみ • 学習フェーズはx86で実施 → パラメータを抽出 参考にした本: ゼロから学ぶDeep Learning 全部Pythonで書いてあるのでC言語に移植 ※ 発表者はディープラーニング初心者なので、あまり詳細な ことは知りません。 性能評価などもあまり突っ込んだことはしていません… 入力値 Batch_Size 28x28 重み W0 28x28 Hidden_size × Affine1 出力 Batch_Size Hidden_Size → 1. Affine1 Affine1 出力 Batch_Size Hidden_Size ReLU 出力 Batch_Size Hidden_Size → 2. ReLU Batch_Size 重み W1 Hidden_Size 10 × ReLU 出力 Batch_Size Hidden_Size → 3. Affine2 Batch_Size 10 Batch_Size → 4. Softmax Affine2 出力 10 Affine2 出力 10 Softmax 出力 重み b0 + 重み b1 + 図. 実装した主な演算

Slide 45

Slide 45 text

Freedom-E-SDK環境で MNISTを動かす • printf(), getc()なども使えるので デバッグもかなり楽 • freedom-e-sdk環境でコンパイルして HiFive1にアップロードで動かすことが できる。 • HiFive1を使ってみてわかったこと • L1Dキャッシュが小さい & SPIフラッシュメモリへのアクセスが遅い • 学習済みパラメータの アクセスが異常に 遅くなってしまう。 • お金に余裕があるならば、 マルチコアが搭載されたRISC-V ボードはいかが freedom-e-sdk bsp openocd riscv-gnu-toolchain software demo_gpio dhrystone welcome local_interrupt led_fade mnist HiFive Unleashed

Slide 46

Slide 46 text

カスタム可能なRISC-V実装 Rocket Chip

Slide 47

Slide 47 text

RISC-V Implementationの代表格「Rocket-Chip」 • UCBの開発したRISC-V Implementation • XilinxのFPGAボードならばサポート ZedBoard Zybo ZC706 HiFive1の中身も実際は Rocket Chip(32-bit) Rocket-ChipのRTLシミュレーションと ソフトウェアデバッグの様子 無料 ソースコード公開 最新仕様に(かなり)追従 開発が活発 Chiselって何? どうやって動かすの? カスタマイズの方法が分からん

Slide 48

Slide 48 text

Rocket-Chipの実装言語 “Chisel” • Scalaをベースとしたハードウェア記述言語 • Rocket Chipはすべて”Chisel”で実装してある • 最終的にはVerilogに変換される • Chiselを使うことにより、合成用言語Verilogと分離する • Chisel→FIRRTL(中間言語)と変換することで、 VHDLなども出せる(一応) • 検証で有利 • Verilogシミュレータを走らせなくても Chisel(≒Scala)で検証パタンを書ける→高速 FIRRTL Verilog

Slide 49

Slide 49 text

Chiselによる実装は、 部品を取り付けたり外したりするイメージ class WithNBigCores(n: Int) extends Config((site, here, up) => { case RocketTilesKey => { val big = RocketTileParams( core = RocketCoreParams(mulDiv = Some(MulDivParams( mulUnroll = 8, mulEarlyOut = true, divEarlyOut = true))), dcache = Some(DCacheParams( rowBits = site(SystemBusKey).beatBits, nMSHRs = 0, blockBytes = site(CacheBlockBytes))), icache = Some(ICacheParams( ... } }) class With1TinyCore extends Config((site, here, up) => { case XLen => 32 case RocketTilesKey => List(RocketTileParams( core = RocketCoreParams( useVM = false, fpu = None, mulDiv = Some(MulDivParams(mulUnroll = 8))), btb = None, dcache = Some(DCacheParams( rowBits = site(SystemBusKey).beatBits, nSets = 256, // 16Kb scratchpad nWays = 1, nTLBEntries = 4, nMSHRs = 0, blockBytes = site(CacheBlockBytes), scratch = Some(0x80000000L))), … blockBytes = site(CacheBlockBytes))))) }) class TinyConfig extends Config( new WithNMemoryChannels(0) ++ new WithIncoherentTiles ++ new With1TinyCore ++ new BaseConfig) Chiselを使って、コアの部品を簡単に着脱・ カスタマイズできる。 ベースのコンフィグレーションに対して、 カスタマイズを行っていく。 VM Support メインパイプライン FPU DIV I-cache 構成 D-cache 構成 I/F

Slide 50

Slide 50 text

Rocket-Chip Generator, Freedom SoCの構成方法 • 高いポータビリティ • Chisel(Scala拡張)によるモジュールの切り離し、コンフィグレーションの 構成変更が容易 • Xilinx ZYNQ FPGA, Arty, Virtex Ultrascaleなどに対応した構成を作成可能 Xilinx ARTY FPGA E300 Freedom SoC E3 Coreplex RV32E/IMACN ROM Debug AON UART SPIFlash SPI GPIO PWM I2C I-Cache 4kB D-Cache 16kB Custom Coprocessor Xilinx ZYNQ FPGA Rocket-Chip Generator RV64GC ROM Debug I-Cache 4kB D-Cache 16kB Custom Coprocessor AXI2TileLink ARM DRAM I/O class DefaultConfig extends Config( new WithNBigCores(1) ++ new BaseConfig) class TinyConfig extends Config( new WithNMemoryChannels(0) ++ new WithIncoherentTiles ++ new With1TinyCore ++ new BaseConfig) Chiselを使って、Rocketの 構成を簡単に変更できる

Slide 51

Slide 51 text

Rocket-Chipを使ってみよう • University of California Berkeleyの開発しているRISC-V実装 • 5-stageパイプライン • RISC-V Foundationに最も近い人たちが実装しているので信頼できる • Rocket-Chip + 周辺バスを含めてFPGAに実装できる • リポジトリ : https://github.com/freechipsproject/rocket-chip • https://github.com/freechipsproject/rocket-chip.gitで 丸ごとダウンロードできる 51

Slide 52

Slide 52 text

Rocket-Chipのダウンロードとビルド • ↑を実行するとツールチェインまで全部ダウンロードして時間 がかかるので 52 $ git clone https://github.com/freechipsproject/rocket-chip.git¥ --recurse-submodules $ git clone https://github.com/freechipsproject/rocket-chip.git $ cd rocket-chip $ git submodule init $ subpackages=`git submodule status | cut -d' ‘ –f3 | grep -v riscv-tools` $ git submodule update --init --recursive $subpackages riscv-toolsを既にインストールしている場合、 全てダウンロードする必要はない $ cd rocket-chip $ cd emulator # Verilatorを使う場合 $ cd vsim # Synopsys VCSを使う場合 $ make CONFIG=DefaultConfig # DefaultConfig構成でビルド(RTL作成)

Slide 53

Slide 53 text

Rocket-Chipでテストパタンを動かしてみる 53 $ make output/rv64ui-p-add.out ln -fs /home/msyksphinz/riscv64//riscv64-unknown-elf/share/riscv- tests/isa/rv64ui-p-add output/rv64ui-p-add ./emulator-freechips.rocketchip.system-DefaultConfig +max- cycles=100000000 +verbose output/rv64ui-p-add 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/rv64ui-p- add.out && [ $PIPESTATUS -eq 0 ] <> <> $ $ less output/rv64ui-p-add.out using random seed 1537717042 This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. Listening on port 36423 C0: 0 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 1 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 2 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 3 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 4 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 5 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 6 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 7 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 8 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 9 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 10 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 11 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 12 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 13 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 14 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 15 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) C0: 16 [0] pc=[f629403494] W[r 0=0000000000000000][0] R[r15=e50f7b8dc1ff78b6] R[r31=7cf3faa98e59e7f7] inst=[0000ed10] sd a2, 24(a0) ...

Slide 54

Slide 54 text

[1]と出ているのが有効な命令 54 $ grep "¥[1¥] pc=" output/rv64ui-p-add.out C0: 53763 [1] pc=[0000000824] W[r 0=0000000000000000][0] R[r 8=0000000000000000] R[r 0=0000000000000000] inst=[fe0408e3] beqz s0, pc - 16 C0: 53764 [1] pc=[0000000814] W[r 8=0000000000000000][1] R[r 0=0000000000000000] R[r20=0000000000000003] inst=[f1402473] csrr s0, mhartid C0: 53767 [1] pc=[0000000818] W[r 0=0000000000000100][0] R[r 0=0000000000000000] R[r 8=0000000000000000] inst=[10802023] sw s0, 256(zero) C0: 53773 [1] pc=[000000081c] W[r 0=0000000000000400][1] R[r 8=0000000000000000] R[r 0=0000000000000000] inst=[40044403] lbu s0, 1024(s0) C0: 53781 [1] pc=[0000000820] W[r 8=0000000000000000][1] R[r 8=0000000000000000] R[r 3=0000000000000003] inst=[00347413] andi s0, s0, 3 C0: 53782 [1] pc=[0000000824] W[r 0=0000000000000000][0] R[r 8=0000000000000000] R[r 0=0000000000000000] inst=[fe0408e3] beqz s0, pc - 16 C0: 53783 [1] pc=[0000000814] W[r 8=0000000000000000][1] R[r 0=0000000000000000] R[r20=0000000000000003] inst=[f1402473] csrr s0, mhartid C0: 53786 [1] pc=[0000000818] W[r 0=0000000000000100][0] R[r 0=0000000000000000] R[r 8=0000000000000000] inst=[10802023] sw s0, 256(zero) C0: 53792 [1] pc=[000000081c] W[r 0=0000000000000400][1] R[r 8=0000000000000000] R[r 0=0000000000000000] inst=[40044403] lbu s0, 1024(s0) C0: 53800 [1] pc=[0000000820] W[r 8=0000000000000001][1] R[r 8=0000000000000001] R[r 3=0000000000000003] inst=[00347413] andi s0, s0, 3 C0: 53801 [1] pc=[0000000824] W[r 0=0000000000000000][0] R[r 8=0000000000000001] R[r 0=0000000000000000] inst=[fe0408e3] beqz s0, pc - 16 C0: 53805 [1] pc=[0000000828] W[r 8=0000000000000001][1] R[r 8=0000000000000001] R[r 1=0000000000000003] inst=[00147413] andi s0, s0, 1 C0: 53806 [1] pc=[000000082c] W[r 0=0000000000000000][0] R[r 8=0000000000000001] R[r 0=0000000000000000] inst=[00040863] beqz s0, pc + 16 C0: 53807 [1] pc=[0000000830] W[r 8=0000000080001008][1] R[r 0=0000000000000000] R[r18=0000000000000003] inst=[7b202473] csrr s0, dscratch C0: 53808 [1] pc=[0000000834] W[r 0=0000000000000104][0] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[10002223] sw zero, 260(zero) C0: 53809 [1] pc=[0000000838] W[r 0=000000000000083c][1] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[30000067] jalr zero, zero, 768 C0: 53828 [1] pc=[0000000300] W[r 0=0000000000000304][1] R[r 0=0000000000000000] R[r24=0000000000000003] inst=[0380006f] j pc + 0x38 命令hex RS2 RS1 Exec Cycle 命令ニーモニック Program Counter 書き込みレジスタ $ make output/dhrystone.riscv.out mkdir -p ./output ... <> Microseconds for one run through Dhrystone: 494 Dhrystones per Second: 2021 mcycle = 247478 minstret = 198773 <> 次にDhrystoneを流してみましょう

Slide 55

Slide 55 text

具体的には何をやってんのさ? 55 $ make output/dhrystone.riscv.out mkdir -p ./output ln –fs ${RISCV}/riscv64-unknown-elf/share/riscv- tests/benchmarks/dhrystone.riscv output/dhrystone.riscv ./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/dhrystone.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/dhrystone.riscv.out && [ $PIPESTATUS -eq 0 ] outputディレクトリを作成 ${RISCV}ディレクトリに存在する テストベンチをoutputディレクトリにリンク Verilatorでシミュレーションを実行 spike-dasmはRTLシミュレーションの生 成するログを読んで 逆アセンブルしたログを生成する

Slide 56

Slide 56 text

最初に出てきたDefaultConfigって何? 56 class DefaultConfig extends Config(new WithNBigCores(1) ++ new BaseConfig) ■ main/scala/system/Configs.scala class WithNBigCores(n: Int) extends Config((site, here, up) => { case RocketTilesKey => { val big = RocketTileParams( core = RocketCoreParams(mulDiv = Some(MulDivParams( mulUnroll = 8, mulEarlyOut = true, divEarlyOut = true))), dcache = Some(DCacheParams( rowBits = site(SystemBusKey).beatBits, nMSHRs = 0, blockBytes = site(CacheBlockBytes))), icache = Some(ICacheParams( rowBits = site(SystemBusKey).beatBits, blockBytes = site(CacheBlockBytes)))) List.tabulate(n)(i => big.copy(hartId = i)) } }) class BaseConfig extends Config( new WithDefaultMemPort() ++ new WithDefaultMMIOPort() ++ new WithDefaultSlavePort() ++ new WithTimebase(BigInt(1000000)) ++ // 1 MHz new WithDTS("freechips,rocketchip-unknown", Nil) ++ new WithNExtTopInterrupts(2) ++ new BaseSubsystemConfig() )

Slide 57

Slide 57 text

ちょっと待って、Rocketは RTLでシミュレーションしてるの? • Rocket-ChipのシミュレーションはRTLが前提 • Chiselでシミュレーションできれば良いのだが、やり方が書いていな い。 • そのためRTLの生成に時間がかかる (Chisel→FIR→Verilog) • ちなみに、Chisel→VerilogのRTLは死ぬほど読みにくい。 57 wire _GEN_53; // @[Monitor.scala 64:14:[email protected]] wire _GEN_65; // @[Monitor.scala 73:14:[email protected]] wire _GEN_75; // @[Monitor.scala 81:14:[email protected]] wire _GEN_85; // @[Monitor.scala 89:14:[email protected]] wire _GEN_95; // @[Monitor.scala 97:14:[email protected]] wire _GEN_105; // @[Monitor.scala 105:14:[email protected]] plusarg_reader #(.FORMAT("tilelink_timeout=%d"), .DEFAULT(0)) plusarg_reader ( // @[PlusArg.scala 42:11:[email protected]] .out(plusarg_reader_out) ); assign _T_26 = io_in_a_bits_source <= 9'h12f; // @[Parameters.scala 55:20:[email protected]] assign _T_36 = 6'h7 << io_in_a_bits_size; // @[package.scala 185:77:[email protected]] assign _T_37 = _T_36[2:0]; // @[package.scala 185:82:[email protected]] assign _T_38 = ~ _T_37; // @[package.scala 185:46:[email protected]] assign _GEN_18 = {{14'd0}, _T_38}; // @[Edges.scala 21:16:[email protected]] assign _T_39 = io_in_a_bits_address & _GEN_18; // @[Edges.scala 21:16:[email protected]] assign _T_40 = _T_39 == 17'h0; // @[Edges.scala 21:24:[email protected]] assign _T_41 = {{1'd0}, io_in_a_bits_size}; // @[Misc.scala 203:34:[email protected]] assign _T_42 = _T_41[1:0]; // @[OneHot.scala 51:49:[email protected]] assign _T_43 = 4'h1 << _T_42; // @[OneHot.scala 52:12:[email protected]] assign _T_44 = _T_43[2:0]; // @[OneHot.scala 52:27:[email protected]] assign _T_45 = _T_44 | 3'h1; // @[Misc.scala 203:81:[email protected]] assign _T_46 = io_in_a_bits_size >= 2'h3; // @[Misc.scala 207:21:[email protected]] assign _T_47 = _T_45[2]; // @[Misc.scala 210:26:[email protected]] assign _T_48 = io_in_a_bits_address[2]; // @[Misc.scala 211:26:[email protected]] assign _T_49 = _T_48 == 1'h0; // @[Misc.scala 212:20:[email protected]] assign _T_51 = _T_47 & _T_49; // @[Misc.scala 216:38:[email protected]] assign _T_52 = _T_46 | _T_51; // @[Misc.scala 216:29:[email protected]] assign _T_54 = _T_47 & _T_48; // @[Misc.scala 216:38:[email protected]] assign _T_55 = _T_46 | _T_54; // @[Misc.scala 216:29:[email protected]] assign _T_56 = _T_45[1]; // @[Misc.scala 210:26:[email protected]] assign _T_57 = io_in_a_bits_address[1]; // @[Misc.scala 211:26:[email protected]] assign _T_58 = _T_57 == 1'h0; // @[Misc.scala 212:20:[email protected]] こんなの読めますか...? ってかECOとか どうするんだ...

Slide 58

Slide 58 text

BOOM (Berkeley Out-of-Order Machine) • アウトオブオーダのRISC-V実装 • UCBの学生が開発 • 2-way版と4-way版が存在する(ハズ) • BOOMv1 : サイクル性能重視 (v2に比べて) • BOOMv2 : 動作周波数重視(サイクル性能はv1に劣る?) 58 UCBの大学生が(1~2人で)書いた ちなみにかBOOMを設計した本人は RISC-Vベンチャーの Esperanto Technologiesに就職しました。 David Ditzel氏

Slide 59

Slide 59 text

BOOMのダウンロードとビルド • ↑を実行するとツールチェインまで全部ダウンロードして時間 がかかるので 59 $ git clone https://github.com/esperantotech/boom-template.git --recurse-submodules $ git clone https://github.com/ccelio/boom-template.git $ cd boom-template $ git submodule update --init --recursive boom torture $ git submodule update rocket-chip $ cd rocket-chip $ git submodule update --init --recursive chisel3 firrtl hardfloat torture $ cd boom-template $ cd verisim # Verilatorを使う場合 $ cd vsim # Synopsys VCSを使う場合 $ make riscv-toolsを既にインストールしている場合、 全てダウンロードする必要はない

Slide 60

Slide 60 text

BOOMでベンチマークプログラムを実行 60 $ make run-bmark-tests ... ./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/towers.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/towers.riscv.out && [ $PIPESTATUS -eq 0 ] <> mcycle = 6334 minstret = 6170 <> ./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/vvadd.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/vvadd.riscv.out && [ $PIPESTATUS -eq 0 ] <> mcycle = 2512 minstret = 2420 <> ./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose output/mt-matmul.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/mt-matmul.riscv.out && [ $PIPESTATUS -eq 0 ] <> matmul(cid, nc, 16, input1_data, input2_data, results_data); barrier(nc): 41033 cycles, 10.0 cycles/iter, 1.5 CPI <>

Slide 61

Slide 61 text

FPGA への実装 • ZedBoard向けに論理合成→インプリメント • UCBのfpga-zynqリポジトリが便利 • (https://github.com/ucb-bar/fpga-zynq) • インプリメントの手順は非常に単純 • cd zedboard; make • 合成後binファイル (.bin) • FSBL, U-Boot, BOOT.binなどZynqの起動に必要なもの • PS部(ARM)で動作させるPeta-Linuxのビルド • RISC-Vで動作させるLinuxのビルド • 全部自動でやってくれる! • このフレームワークはRISC-Vだけで使うのは もったいない • SDカードに書き込むファイル群が ディレクトリにまとめて生成させるので、 SDカードにコピーするだけ fpga-zynq rocket-chip zedboard zynq zc706 sub-repo 合成ディレクトリ 合成ディレクトリ 合成ディレクトリ

Slide 62

Slide 62 text

Rocket-Chipの拡張機能 RoCC • RoCC (Rocket Custom Coprocessor) • Rocket Coreとダイレクトに接続 (L1DC, External MemoryIFに接 続) • RISC-Vのカスタム命令の仕様と直結 CMD RESP RESP CMD Rocket Core L1 D- cache Accelerato r CMD RESP External ここを自作するこ とで、オリジナル 命令を作成できる custom0 rd, rs1, rs2 ・rd, rs1, rs2のレジスタアドレス情報 ・rs1, rs2 のレジスタデータ ・デコード情報など

Slide 63

Slide 63 text

Dot Product Acceleratorを作って Rocket Coreに接続した × 2つの行列のアドレスと長さを指定して、 自動的にデータをフェッチ+MAD処理をするアクセラレータ = 要素1つ 分計算 ハードウェアを使って、メモリ のフェッチ処理とデータの演算 処理をオーバラップさせること で高速化を狙う CMD RESP RESP CMD Rocket Core L1 D-cache Accelerator CMD RESP External H_addr MAD V_addr

Slide 64

Slide 64 text

性能評価 ◼ZedBoardで動作させた ◼ SW: ソフトウェアで実行 ◼ HW1: ハードウェアで実行 ◼ 行列積を「行」→「列」の順番で実行 ◼ HW2: ハードウェアで実行 ◼ 行列積を「列」→「行」の順番で実行 ◼ 行列のサイズが大きくなると、約4倍の性能向上 ◼ 行列積の計算の順番で、キャッシュのヒット率が変わる? 0 20000 40000 60000 80000 100000 120000 140000 160000 180000 2 x 2 x 2 4 x 4 x 4 8 x 8 x 8 16 x16 x16 17 x23 x27 サイクル数 行列サイズ Dot Product Acceleratorを使った行列積 サイクル数 SW HW1 HW2 0.0 1.0 2.0 3.0 4.0 5.0 2 x 2 x 2 4 x 4 x 4 8 x 8 x 8 16 x16 x16 17 x23 x27 性能比率 行列サイズ ソフトウェア実行を1とした場合の、 ハードウェア実行の性能向上率 SW/SW SW HW1 HW2 2 x 2 x 2 221 145 178 4 x 4 x 4 1284 512 539 8 x 8 x 8 8336 2510 2590 16 x16 x16 66735 16099 16161 17 x23 x27 164199 39571 39877 表1. サイクル数 SW/SW HW1/SW HW2/SW 2 x 2 x 2 1.000 1.524 1.242 4 x 4 x 4 1.000 2.508 2.382 8 x 8 x 8 1.000 3.321 3.219 16 x16 x16 1.000 4.145 4.129 17 x23 x27 1.000 4.149 4.118 表2. 性能向上比率

Slide 65

Slide 65 text

オリジナルカスタマイズの例: RISC-V+ディープラーニング ◼ カスタム命令を追加する ◼ 不要な機能を削除してダイエット ◼ 自社のIPをアクセラレータとして接続する (RoCC : Rocket Custom Coprocessor) CMD RESP RESP CMD Rocket Core L1 D-cache Accelerator CMD RESP External H_addr MAD V_addr Chiselで記述 図. Rocket-Chip on RISC-V上でMNISTを実行 Acceleration無し Acceleration IP接続

Slide 66

Slide 66 text

Dot Product Accelerator Block Diagram 66 DotProductF16 Fix16Mul a_data_queue b_data_queue ResultRAM InputRAM WeightRAM io.cmd a_address b_address io.mem.req io.mem.resp 実機Debug用 Data Logger データがOoOで返ってくる ためシリアライズが必須

Slide 67

Slide 67 text

ChiselでDot Product Acceleratorを作ろう 67 // MEMORY REQUEST INTERFACE io.mem.req.valid := (r_cmd_state === s_mem_fetch) io.mem.req.bits.addr := w_addr io.mem.req.bits.tag := r_tag io.mem.req.bits.cmd := M_XRD // perform a load (M_XWR for stores) io.mem.req.bits.typ := MT_W // D = 8 bytes, W = 4, H = 2, B = 1 io.mem.req.bits.data := Bits(0) // we're not performing any stores... io.mem.req.bits.phys := Bool(false) io.mem.invalidate_lr := Bool(false) val a_data_queue = Module (new ReorderQueue(UInt(width=32), n-1)) a_data_queue.io.enq.valid := io.mem.resp.fire() && !io.mem.resp.bits.tag(h_v_bit) a_data_queue.io.enq.bits.data := io.mem.resp.bits.data a_data_queue.io.enq.bits.tag := io.mem.resp.bits.tag a_data_queue.io.deq.tag := Cat(data_tag_counter(n-2, h_v_bit), UInt(0, width=1), data_tag_counter(h_v_bit-1, 0)) when (a_data_queue.io.deq.matches && b_data_queue.io.deq.matches) { a_data_queue.io.deq.valid := Bool(true) data_tag_counter := data_tag_counter + UInt(1) } .otherwise { a_data_queue.io.deq.valid := Bool(false) } data_queue controller io.mem requester

Slide 68

Slide 68 text

ChiselでDot Product Acceleratorを作ろう 68 // int32_t AC = A*C; // int32_t AD_CB = A*D + C*B; // uint32_t BD = B*D; val w_ah_bh = Reg(SInt(width=32)) val w_ah_bl_al_bh = Reg(SInt(width=32)) val w_al_bl = Reg(UInt(width=32)) w_ah_bh := w_a_hi * w_b_hi w_ah_bl_al_bh := w_a_hi * w_b_lo + w_a_lo * w_b_hi w_al_bl := w_a_lo * w_b_lo val product_hi = Wire(SInt(width=32)) product_hi := w_ah_bh + w_ah_bl_al_bh(31,16).asSInt() val product_lo = Wire(UInt(width=32)) product_lo := w_al_bl + Cat(w_ah_bl_al_bh, UInt(0,width=16)) val product_hi2 = Wire(SInt(width=32)) when (product_lo < w_al_bl) { product_hi2 := product_hi + SInt(1) } .otherwise { product_hi2 := product_hi } f16 multiplier

Slide 69

Slide 69 text

C言語側から Dot Product Acceleratorを制御する 69 #define N (18) #define M (24) #define K (28) int main() { uint64_t cycle; int32_t output_data[N*K]; // Allocate Largest Size printf (" HW2, HW1, SW¥n"); for (int size = 2; size <=16; size *= 2) { printf ("%2d x%2d x%2d : ", size, size, size); cycle = matrixmul_hw1 (output_data, input1_data, input2_data, size, size, size, 0); printf ("%ld, ", cycle); printf ("¥n"); } return 0; }

Slide 70

Slide 70 text

C言語側から Dot Product Acceleratorを制御する 70 #define XCUSTOM_MATRIXMUL32 0 #define k_MTRXMUL_SETM (0) #define k_MTRXMUL_SETK (1) #define k_MTRXMUL_DOCALC (2) #define matrixmul32_setM(y, len) ¥ ROCC_INSTRUCTION(XCUSTOM_MATRIXMUL32, y, len, 0, k_MTRXMUL_SETM); #define matrixmul32_setK(y, len) ¥ ROCC_INSTRUCTION(XCUSTOM_MATRIXMUL32, y, len, 0, k_MTRXMUL_SETK); #define matrixmul32(y, mem_addr0, mem_addr1) ¥ ROCC_INSTRUCTION(XCUSTOM_MATRIXMUL32, y, mem_addr0, mem_addr1, k_MTRXMUL_DOCALC);

Slide 71

Slide 71 text

C言語側から Dot Product Acceleratorを制御する 71 #define CUSTOMX(X, rd, rs1, rs2, funct) ¥ CUSTOMX_OPCODE(X) | ¥ (rd << (7)) | ¥ (0x7 << (7+5)) | ¥ (rs1 << (7+5+3)) | ¥ (rs2 << (7+5+3+5)) | ¥ (EXTRACT(funct, 7, 0) << (7+5+3+5+5)) // Standard macro that passes rd, rs1, and rs2 via registers #define ROCC_INSTRUCTION(X, rd, rs1, rs2, funct) ¥ ROCC_INSTRUCTION_R_R_R(X, rd, rs1, rs2, funct, 10, 11, 12) // rd, rs1, and rs2 are data // rd_n, rs_1, and rs2_n are the register numbers to use #define ROCC_INSTRUCTION_R_R_R(X, rd, rs1, rs2, funct, rd_n, rs1_n, rs2_n) { ¥ register uint64_t rd_ asm ("x" # rd_n); ¥ register uint64_t rs1_ asm ("x" # rs1_n) = (uint64_t) rs1; ¥ register uint64_t rs2_ asm ("x" # rs2_n) = (uint64_t) rs2; ¥ asm volatile ( ¥ ".word " STR(CUSTOMX(X, rd_n, rs1_n, rs2_n, funct)) "¥n¥t" ¥ : "=r" (rd_) ¥ : [_rs1] "r" (rs1_), [_rs2] "r" (rs2_)); ¥ rd = rd_; ¥ }

Slide 72

Slide 72 text

RTLでDot Product Acceleratorの 動作を確認 72 $ make CONFIG=DefaultConfig output/train_twolayernet.riscv.out ./emulator-freechips.rocketchip.system-DefaultConfig +max- cycles=100000000 +verbose output/train_twolayernet.riscv 3>&1 1>&2 2>&3 | /home/msyksphinz/riscv64/bin/spike-dasm > output/train_twolayernet.riscv.out && [ $PIPESTATUS -eq 0 ] === TestNetwork === === TestNetwork === === start === Correct = 0 Correct = 1 Correct = 2 Correct = 3 Correct = 4 Fail = 5 Correct = 5 Time = 0114d6ae - 003e0a7d = 00d6cc31

Slide 73

Slide 73 text

RISC-Vシミュレータを作ろう 73

Slide 74

Slide 74 text

Linuxがブートする RISC-Vシミュレータを作る • RISC-VのISAをしっかり理解したい • マニュアルを読むだけでは何が何だか分からないことが多い。 RISC-Vシミュレータを 自作する 目標1. コンプライアンステストをPassさせる 目標2. Linuxをブートさせる 使用したRISC-V Linux : Freedom-U-SDKで公開されているLinuxバイナリ buildrootで1つのバイナリにまとめられている。Kernel v4.15 https://github.com/sifive/freedom-u-sdk で公開されており、ビルドできます。 ※ 上記に限らず、RISC-V向けにビルドしたLinuxディストリビューションは各種公開されている。 RedHat, Debian, … 今回はディスクイメージが1つにまとめられているので上記を使用。 あるものを理解したいとき、フルスクラッチで自分で 作ってみるの、おすすめです。

Slide 75

Slide 75 text

RISC-Vの命令セットシミュレータを作った pk (proxy kernel) RISC-V Instruction Set Simulator dtb Device Tree Blob Target Program Elf Log Files x86 Host Linux ※ pk(proxy kernel) RISC-Vのプログラムを動かすにあたり、システムコールを代わりに処理してくれる仕組み。 printf()やら、ファイルアクセスなどを代行できる (Linuxの起動には使用しません)。 参考にしたもの RISC-V ISA Spec Manual RISC-V Privileged Manual riscv-isa-sim 実装!! マニュアル見て意味が分からなかっ たら実装を見るのがおすすめ RISC-Vの仕様を、C++の実装 でほぼ忠実に再現してある。 GitHub公開中 : http://github.com/msyksphinz/swimmer_riscv Rocket-Chipを含め、多くの RISC-V実装は最初に Device Tree を読み込む

Slide 76

Slide 76 text

RISC-Vシミュレータの命令定義 76 命令フェッチ 命令デコード ADD命令実行 SUB命令実行 LD命令実行 SW命令実行 レジスタ デコード レジスタ デコード レジスタ デコード レジスタ デコード レジスタ リード 演算実行 レジスタ ライト レジスタ リード 演算実行 レジスタ ライト レジスタ リード レジスタ リード メモリ アクセス 例外判定 レジスタ ライト メモリ アクセス 例外判定

Slide 77

Slide 77 text

例: 命令の実装 77 命令テーブルから自動的 に実装を生成する (Lambdaを使用)

Slide 78

Slide 78 text

Linuxをブートしながら学んだ RISC-Vのすごいところ(仕様編) • 命令デコードがシンプルだが、C命令(Compressed命令)の理解は必須 • デコーダの設計はかなりシンプルで自動化できる • RISC-Vの真の性能を発揮したいなら、C命令はサポートすべき • スーパバイザに権限を移譲する”Delegation(移譲)” • Machine Modeで処理するのが面倒な例外はSupervisor Modeに移譲して動かす • コンテキストスイッチ時にレジスタ退避を簡略化するための仕組み • XS / FSビットフィールドにより、レジスタの書き換え発生を記憶している • mstatusシステムレジスタは過去の実行モードを記憶することが可能 • 例外処理に入る→復帰の処理が割と容易 スーパバイザモード マシンモード 例外発生 移譲 例外処理 例外から戻る ユーザモード スーパバイザモード マシンモード 例外発生 例外受付 動作モード変更 例外処理 例外から戻る ユーザモード 割り込み・例外の移譲を使う場合 割り込み・例外の移譲を使わない場合 こちらも参考になります : https://www.sifive.com/blog/2017/10/23/all-aboard-part-7-entering-and-exiting-the-linux- kernel-on-risc-v/

Slide 79

Slide 79 text

Linuxをブートしながら学んだ RISC-Vのすごいところ(環境編) • ツールがすべて公開されているので、デバッグが容易 • https://github.com/riscv/riscv-tools を参照のこと • テストセットもすべて公開されている • ISAのテストパタン riscv-tests / riscv-torture • ~な高速化技法試してみようかな→ 一旦テストセットで全部リグレッションを動かして確認

Slide 80

Slide 80 text

RISC-Vを通じて変わる 「ハードウェア設計の常識」

Slide 81

Slide 81 text

Open-Hardwareの目指すところ • ハードウェア設計・CPUアーキテクチャをオープンに 議論できる環境を構築する • 例: Meltdown / Spectre • 例: Memory Consistency Model of RISC-V • RISC-Vのメモリコンシステンシモデルのバグを大学が発見 • 2018年はハードウェアを含め、セキュリティ界隈の話が多い • RISC-Vをベースにオープンなセキュリティプラットフォームの 構築を目指すKeystone

Slide 82

Slide 82 text

実チップ?FPGA?いえいえ、AWS FireSim : RISC-V Implementation on AWS F1 instance 複数FPGAを使って最大1024コアまで動作。 GitHubで公開されている (https://github.com/firesim) 大規模FPGAの購入にはかなりのコスト高。200~300万円 FPGAを常に手元に置いておく必要がない。 必要な時に必要な分だけコストがかかる。 → コストダウン・参入障壁を下げる一要因になることを期待 FPGA-Accelerated Cycle-Exact Scale-Out System Simulation in the Public Cloud http://iscaconf.org/isca2018/slides/1A3.pdf

Slide 83

Slide 83 text

AWSを使ってRISC-Vを動かし Linuxをブートする お値段 : f1.2xlarge (Rocket-ChipならばSingle-Core) : 1.65USD/h f1.16xlarge (Rocket-Chipならば8-Core) : 13.20USD/h Single使用なら 個人でも何とか… (ちょっと見えにくいけど) AWS F1上でRISC-V Linuxがブート RISC-Vと関係なく、とりあえずAWSインスタンスを 試したいということも可能: AWS FPGAリポジトリ : https://github.com/aws/aws-fpga

Slide 84

Slide 84 text

まとめ 84

Slide 85

Slide 85 text

• RISC-Vを取り巻く最新動向についてご紹介しました。 • RISC-Vの開発環境の構築方法について簡単にご説明し ました。 • シミュレータを使ったアプリケーションの実行 • RTLシミュレータを使ったRISC-Vコアの動作 • FPGAを使ったRISC-V + アクセラレータの実現 • 自作命令セットシミュレータを使ったLinuxのブート • RISC-Vと、オープンハードウェアが向かう未来につい て、その一端をご紹介しました。 85