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