TECH PLAY

RISC-VとChiselで学ぶ はじめてのCPU自作 --オープンソース命令セットによるカスタムCPU実装への第一歩

3,520円 (税込)

楽天

RISC-VとChiselで学ぶ はじめてのCPU自作 --オープンソース命令セットによるカスタムCPU実装への第一歩

書籍情報

発売日:

著者/編集:西山悠太朗、井田健太

出版社:技術評論社

発行形態:単行本

書籍説明

内容紹介

本書では、UCバークレーで開発されたオープンソースの命令セット(ISA)「RISC-V」を用いて、CPUの作り方を解説します。コンピュータ・アーキテクチャ、ハードウェアに関する知識があまりない方にも理解できるように、基礎からわかりやすく学ぶ構成となっています。CPUとコンピュータ・アーキテクチャのしくみを解説したうえで、基本整数命令の実装から、CPUの高速化で活躍するパイプラインの実装、スーパーコンピュータでも活躍するベクトル拡張命令(SIMD)、さらに汎用CPUでは負荷の高い処理をより高速に実行するためにCPUへ追加可能なカスタム命令の実装までを行います。CPU設計に用いる基本言語としては、Velilogを抽象化したHDL(ハードウェア記述言語)であるChiselを利用しています。CPUの自作範囲に関して、手順が煩雑なFPGAでの動作確認は行わず、ソフトウェア上でのエミュレーションをゴールとしているので、ソフトウェアエンジニアの方にも取っ付きやすいものとなっています。巻末には、昨今RISC-Vが注目されている理由を整理するため、RISC-Vのもたらす価値についてまとめています。

目次

目次 まえがき 第Ⅰ部 CPU自作のための基礎知識 第1章 CPUとは何か 1-1 電子回路が論理を表現できる理由 1-1-1 デジタル信号への変換 1-1-2 論理演算を表現する回路 1-1-3 いかなる真理値表も表現できる基本論理回路 1-2 基本論理回路がCPUを実現できる理由 1-2-1 順序論理回路:ラッチ回路 1-2-2 有限状態機械 1-2-3 クロック信号による同期 1-3 CPUの製造プロセス Column バイポーラトランジスタとCMOS 第2章 コンピュータ・アーキテクチャ 2-1 メモリ 2-1-1 レジスタ 2-1-2 メインメモリ 2-2 コンピュータの基本的な処理の流れ 2-2-1 命令フェッチ(IF:Instruction Fetch) 2-2-2 命令デコード(ID:Instruction Decode) 2-2-3 演算(EX:Execution) 2-2-4 メモリアクセス(MEM:Memory Access) 2-2-5 ライトバック(WB:Write Back) Column デコード処理の簡略化 Column RISCとCISC Column レジスタとメモリの扱い 第3章 ハードウェア記述言語Chiselの基本 3-1 Chiselとは 3-2 オブジェクト指向とは 3-2-1 クラスとインスタンス 3-2-2 継承 3-3 Scalaの基本文法 3-3-1 変数varとval 3-3-2 メソッド:def 3-3-3 コレクション:Seq 3-3-4 for式 3-3-5 オブジェクト 3-3-6 名前空間 3-4 Chiselの基本文法 3-4-1 bit値を表す基本型 3-4-2 演算子 3-4-3 Module 3-4-4 IO 3-4-5 Flippedオブジェクト 3-4-6 配線の接続 3-4-7 組み合わせ論理回路:Wire/WireDefault 3-4-8 順序論理回路:RegInit 3-4-9 Memによるレジスタファイル定義 3-4-10 制御回路 3-4-11 bit操作 3-4-12 printfによるデバッグ Column あらゆるものがオブジェクト 第Ⅱ部「簡単なCPUの実装」 第4章 環境構築 4-1 chisel-templateのダウンロード 4-2 Dockerによる実行環境の構築 4-2-1 Dockerのインストール 4-2-2 Dockerfileの作成 4-2-3 イメージの作成 4-2-4 コンテナの作成 4-3 命令bit列および定数ファイル 4-3-1 Instructions.Scala 4-3-2 Consts.scala 4-4 第Ⅱ部で実装する命令とChiselコード全体 第5章 命令フェッチの実装 5-1 Chiselコードの概要 5-2 Chiselの実装 第6章 ChiselTestによる命令フェッチテスト 6-1 ChiselTestのインストール 6-2 テストの流れ 6-3 Chiselテストコードの作成 6-3-1 trait 6-3-2 peekメソッド 6-3-3 clock.stepメソッド 6-4 メモリ用hexファイルの作成 6-5 printfを活用したデバッグ信号の出力 6-6 テストの実行 6-7 Dockerコンテナのcommit 第7章 命令デコーダの実装 7-1 Chiselの実装 7-1-1 レジスタ番号の解読 7-1-2 レジスタデータの読み出し 7-1-3 デバッグ用信号の出力 7-2 テストの実行 第8章 LW命令の実装 8-1 RISC-VのLW命令定義 8-2 Chiselの実装 8-2-1 ①命令bitパターンの定義 8-2-2 ②CPUとメモリ間のポート定義 8-2-3 ③CPU内の処理実装 8-2-4 ④メモリのデータ読み込み実装 8-3 テストの実行 8-3-1 命令ファイルlw.hexの作成 8-3-2 メモリにロードするファイル名の変更 8-3-3 テスト終了条件の変更 8-3-4 デバッグ信号の追加 8-3-5 テストの実行 第9章 SW命令の実装 9-1 RISC-VのSW命令定義 9-2 Chiselの実装 9-2-1 ①命令bitパターンの定義 9-2-2 ②CPUとメモリ間のポート定義 9-2-3 ③CPU内の処理実装 9-2-4 ④メモリのデータ書き込み実装 9-3 テストの実行 9-3-1 命令ファイルsw.hexの作成 9-3-2 メモリにロードするファイル名の変更 9-3-3 テスト終了条件の変更 9-3-4 デバッグ用信号の追加 9-3-5 テストの実行 第10章 加減算命令の実装 10-1 RISC-Vの加減算命令定義 10-2 Chiselの実装 10-2-1 命令bitパターンの定義 10-2-2 加減算結果の接続@EXステージ 10-2-3 加減算結果のレジスタライトバック@WBステージ 第11章 論理演算の実装 11-1 RISC-Vの論理演算命令定義 11-2 Chiselの実装 11-2-1 命令bitパターンの定義 11-2-2 論理演算結果の接続@EXステージ 11-2-3 論理演算結果のレジスタライトバック@WBステージ 第12章 デコーダの強化 12-1 ALU用デコード 12-1-1 デコーダの強化@IDステージ 12-1-2 デコード信号を活用したALU簡略化@EXステージ 12-2 MEM用デコード 12-2-1 デコーダの強化@IDステージ 12-2-2 命令デコードの不要化@MEMステージ 12-3 WB用デコード 12-3-1 デコーダの強化@IDステージ 12-3-2 命令デコードの不要化@WBステージ 第13章 シフト演算の実装 13-1 RISC-Vのシフト演算命令定義 13-2 Chiselの実装 13-2-1 命令bitパターンの定義 13-2-2 デコード信号の生成@IDステージ 13-2-3 シフト演算結果の接続@EXステージ 第14章 比較演算の実装 14-1 RISC-Vの比較演算命令定義 14-2 Chiselの実装 14-2-1 命令bitパターンの定義 14-2-2 デコード信号の生成@IDステージ 14-2-3 比較演算結果の接続@EXステージ 第15章 分岐命令の実装 15-1 RISC-Vの分岐命令定義 15-2 Chiselの実装 15-2-1 命令bitパターンの定義 15-2-2 PCの制御@IFステージ 15-2-3 即値およびデコード信号の生成@IDステージ 15-2-4 分岐可否、ジャンプ先アドレスの計算@EXステージ 第16章 ジャンプ命令の実装 16-1 RISC-Vのジャンプ命令定義 16-2 Chiselの実装 16-2-1 命令bitパターンの定義 16-2-2 デコードおよびオペランドデータの読み出し@IDステージ 16-2-3 JALR用演算の追加@EXステージ 16-2-4 PCの制御@IFステージ 16-2-5 raのライトバック@WBステージ 第17章 即値ロード命令の実装 17-1 RISC-Vの即値ロード命令定義 17-2 Chiselの実装 17-2-1 命令bitパターンの定義 17-2-2 デコードおよびオペランドデータの読み出し@IDステージ Column LI(Load Immediate)命令 第18章 CSR命令の実装 18-1 RISC-VのCSR命令定義 18-2 Chiselの実装 18-2-1 命令bitパターンの定義 18-2-2 即値およびデコード信号の生成@IDステージ 18-2-3 op1_dataの接続@EXステージ 18-2-4 CSRの読み書き@MEMステージ 18-2-5 CSR読み出しデータのレジスタライトバック@WBステージ 第19章 ECALLの実装 19-1 RISC-VのECALL命令定義 19-2 Chiselの実装 19-2-1 命令bitパターンの定義 19-2-2 PCの制御@IFステージ 19-2-3 デコード信号の生成@IDステージ 19-2-4 CSR書き込み@MEMステージ 第20章 riscv-testsによるテスト 20-1 riscv-testsのビルド 20-2 ELFファイルをBINファイルへ変換 20-3 BINファイルのhex化 20-4 riscv-testsのパス条件 20-5 riscv-testsの実行 20-5-1 Chiselの実装 20-5-2 テストの実行 20-6 一括テストスクリプト 20-6-1 hexファイルの一括生成:tohex.sh 20-6-2 riscv-testsの一括実行:riscv_tests.sh 第21章 Cプログラムを動かしてみよう 21-1 Cプログラム作成 21-2 コンパイル 21-3 リンク 21-4 機械語のhex化とdumpファイルの生成 21-5 テストの実行 Column コンパイルとアセンブル 第Ⅲ部 パイプラインの実装 第22章 パイプラインとは 22-1 パイプライン処理の意義 22-2 CPU処理のパイプライン化 22-3 第Ⅲ部で完成するChiselコード 第23章 パイプラインレジスタの実装 23-1 レジスタ定義 23-2 IFステージ 23-2-1 命令フェッチおよびPC制御 23-2-2 IF/IDレジスタへの書き込み 23-3 IDステージ 23-3-1 ①レジスタ番号のデコードおよびレジスタデータの読み出し 23-3-2 ②即値のデコード 23-3-3 ③csignalsのデコード 23-3-4 ④オペランドデータの選択 23-3-5 ⑤csr_addrの生成 23-3-6 ⑥ID/EXレジスタへの書き込み 23-4 EXステージ 23-4-1 ①alu_outへの信号接続 23-4-2 ②分岐命令の処理 23-4-3 ③EX/MEMレジスタへの書き込み 23-5 MEMステージ 23-5-1 ①メモリアクセス 23-5-2 ②CSR 23-5-3 ③wb_data 23-5-4 ④MEM/WBレジスタへの書き込み 23-6 WBステージ 第24章 分岐ハザード処理 24-1 分岐ハザードとは 24-2 Chiselの実装 24-2-1 IFステージの無効化 24-2-2 IDステージの無効化 24-2-3 デバッグ用信号の追加 24-3 分岐ハザードのテスト 24-3-1 テスト用Cプログラムの作成 24-3-2 hexおよびdumpファイルの生成 24-3-3 分岐ハザード対応前CPUでのテスト 24-3-4 分岐ハザード対応後CPUでのテスト Column 静的分岐予測と動的分岐予測 第25章 データハザード処理 25-1 データハザードとは 25-2 フォワーディングのChisel実装 25-3 ストールのChisel実装 25-3-1 stall_flg信号の追加@IDステージ 25-3-2 ストール処理@IFステージ 25-3-3 BUBBLE化@IDステージ 25-3-4 デバッグ用信号の追加 25-4 データハザードのテスト 25-4-1 ①ID/WB間のデータハザードをフォワーディングするパターン 25-4-2 ②ID/EX間のデータハザードによるストール→ID/MEM間でフォワーディングするパターン 25-4-3 riscv-testsテスト 第Ⅳ部 ベクトル拡張命令の実装 第26章 ベクトル命令とは 26-1 SIMDとは 26-2 既存のベクトルアーキテクチャ 26-3 RISC-Vのベクトル命令とSIMD命令の相違点 26-3-1 SIMD命令のベクトルレジスタ長 26-3-2 RVV命令のベクトルレジスタ長 26-4 第Ⅳ部で完成するChiselコード Column スーパーコンピュータ「富岳」 第27章 VSETVLI命令の実装 27-1 RISC-VのVSETVLI命令定義 27-2 VTYPE 27-2-1 SEWとLMUL 27-2-2 vill、vta、vma 27-3 Chiselの実装 27-3-1 命令bitパターンの定義 27-3-2 デコード信号の生成@IDステージ 27-3-3 ベクトルCSRへの書き込み@MEMステージ 27-3-4 VLのレジスタライトバック@WBステージ 27-4 テストの実行 27-4-1 e32/m1テスト 27-4-2 e64/m1テスト 27-4-3 e32/m2テスト 第28章 ベクトルロード命令の実装 28-1 unit-stride形式のベクトルロード命令定義 28-1-1 SEWとEEW 28-1-2 bit配置 28-2 Chiselの実装 28-2-1 命令bitパターンの定義 28-2-2 DmemPortIoの拡張 28-2-3 ベクトルレジスタの追加 28-2-4 デコード信号の生成@IDステージ 28-2-5 ベクトルロードデータのレジスタライトバック@WBステージ 28-2-6 メモリからベクトルデータの読み出し@Memoryクラス 28-2-7 デバッグ用信号の追加 28-3 テストの実行 28-3-1 e32/m1テスト 28-3-2 e64/m1テスト 28-3-3 e32/m2テスト 第29章 ベクトル加算命令VADD.VVの実装 29-1 RISC-VのVADD.VV命令定義 29-2 Chiselの実装 29-2-1 命令bitパターンの定義 29-2-2 ベクトルレジスタの読み出し@IDステージ 29-2-3 デコード信号の生成@IDステージ 29-2-4 ベクトル加算器の追加@EXステージ 29-2-5 加算結果のレジスタライトバック@WBステージ 29-2-6 デバッグ用信号の追加 29-3 テストの実行 29-3-1 e32/m1テスト 29-3-2 e64/m1のテスト 29-3-3 e32/m2のテスト 第30章 ベクトルストア命令の実装 30-1 unit-stride形式のベクトルストア命令定義 30-2 Chiselの実装 30-2-1 命令bitパターンの定義 30-2-2 DmemPortIoの拡張 30-2-3 デコード信号の生成、ストアデータの読み出し@IDステージ 30-2-4 ストアデータの接続@MEMステージ 30-2-5 ベクトルデータのメモリへの書き込み@Memoryクラス 30-3 テストの実行 30-3-1 e32/m1テスト 30-3-2 e64/m1テスト 30-3-3 e32/m2テスト 第Ⅴ部 カスタム命令の実装 第31章 カスタム命令の意義 31-1 シングルコアの性能向上と限界 31-1-1 ムーアの法則 31-1-2 デナード則 31-1-3 デナード則の崩壊 31-2 マルチコアによる並列処理の効率化と限界 31-2-1 マルチコアへの移行 31-2-2 並列処理の効率化の限界 31-3 DSAの可能性 31-3-1 ASIC 31-3-2 FPGA 31-3-3 DSAのデメリット 31-4 DSAとRISC-V 31-4-1 自由なアーキテクチャ設計 31-4-2 カスタム命令 Column 消費電力対策 Column アクセラレータ 第32章 ポピュレーションカウント命令の実装 32-1 ポピュレーションカウント命令とは 32-2 カスタム命令を実装しない場合のポピュレーションカウントプログラム 32-3 カスタム命令用のコンパイラ(アセンブラ)実装 32-3-1 GNU Assemblerの概要 32-3-2 PCNT命令をGASへ追加 32-3-3 コンパイラの再ビルド 32-3-4 PCNT 命令のコンパイル 32-4 Chiselの実装 32-4-1 命令列の定義 32-4-2 デコード信号の生成@IDステージ 32-4-3 ALUの追加@EXステージ 32-5 テストの実行 付録 RISC-Vの価値 A-1 オープンソースISAの必要性 A-2 RISC-Vが実現するもの A-2-1 ①高性能・低コストを両立するDSA A-2-2 ②安価な汎用CPU A-2-3 ③誰でも気軽に勉強・実装ができる教育環境 A-3 チップ製造コストの壁とその将来性 もっと深く学びたい人へのお勧め書籍

著者情報

井田, 健太, 1986-

西山, 悠太朗, 1991-

西山悠太朗、井田健太

西山 悠太朗 株式会社フィックスターズRISC-V研究所研究員。ウエストバーグ株式会社代表取締役。 メディア事業や教育出版事業など複数の事業売却を経験。ビッグデータ解析、WEBマーケティングを軸に、一部上場企業からスタートアップまで幅広く業務支援を行う 井田 健太 株式会社フィックスターズRISC-V 研究所研究員。大学院修士課程修了後、半導体後工程の装置メーカーに就職し、装置用組み込みソフトウェアの開発を行う。 その後転職を経て、株式会社フィックスターズにて主にFPGA の論理設計とFPGA を制御するためのソフトウェア開発を行う。