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

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

紙版発売
電子版発売

B5変形判/336ページ

定価3,520円(本体3,200円+税10%)

ISBN 978-4-297-12305-5

電子版

→学校・法人一括購入ご検討の皆様へ

書籍の概要

この本の概要

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

こんな方におすすめ

  • ソフトウェアエンジニアで,CPUや命令セットなどのローレイヤーを学びたい人
  • 情報,コンピュータ関連学部へ通う学生
  • RISC-Vに興味がある人
  • カスタムCPU,DSA(Domain Specific Architecture)に興味がある人

この書籍に関連する記事があります!

CPUは何をしているのか?
コンピュータの頭脳と例えられるCPU。CPUを動かすためには,CPUが解釈して実行できる機械語の仕様を定めた,命令セットアーキテクチャと呼ばれるものが必要となります。

目次

  • まえがき

第Ⅰ部 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 チップ製造コストの壁とその将来性
  • もっと深く学びたい人へのお勧め書籍

著者プロフィール

⻄⼭悠太朗(にしやまゆうたろう)

株式会社フィックスターズRISC-V研究所研究員。ウエストバーグ株式会社代表取締役。メディア事業や教育出版事業など複数の事業売却を経験。ビッグデータ解析,WEBマーケティングを軸に,⼀部上場企業からスタートアップまで幅広く業務⽀援を⾏う。また,⽴ち上げたD2C事業を1 年で年商5億円規模まで急成⻑させる等,toB/toC,有形/無形商材と幅広いビジネス経験を積む。PCメーカー経営をきっかけにコンピュータへの興味が膨らみ,現在はRISC-V 研究に携わる。著書に『現場のプロから学ぶSEO 技術バイブル』(マイナビ),『仕事の説明書〜あなたは今どんなゲームをしているのか〜』(土日出版)。


井⽥健太(いだけんた)

株式会社フィックスターズRISC-V 研究所研究員。⼤学院修⼠課程修了後,半導体後⼯程の装置メーカーに就職し,装置⽤組み込みソフトウェアの開発を⾏う。その後転職を経て,株式会社フィックスターズにて主にFPGA の論理設計とFPGA を制御するためのソフトウェア開発を⾏う。趣味は電⼦⼯作とマイコンプログラミングで,それに関連して雑誌記事の執筆や同⼈誌の発⾏などを⾏っている。著書に『基礎から学ぶ 組込みRust』(C&R研究所)。