fjt7tdmi のノート

メモ帳みたいなもの

低レイヤの規格書・仕様書についてのメモ

今までに(一部でもいいから)読んだ規格書・仕様書や、読んでみたい規格書・仕様書、あるいはそれらに関係が深そうなものについて記載する。 「アレの規格書・仕様書ってどこにあるんだっけ…?」となった時の備忘録のつもり。 入手方法などについてもコメントしているが、もしかしたら不正確な情報もあるかもしれない。やる気があれば、適宜アップデートする。

CPU の規格書・仕様書

ARM

昔は ARM Info Center という名前だった気がするが、ここ 1,2 年でサイトがリニューアルされた。 ARM の ISA の規格書だけでなく、AXI バスや Cortex シリーズのデートシートもダウンロードできる。 ユーザー登録しないと読めないドキュメントも多いが、低レイヤ・組込み開発者ならユーザー登録しておいて損はないだろう。 個人的に、学生時代から非常にお世話になっている。

Intel x86

言わずと知れた Intel の SDM. 実は、私はほとんど読んだことが無い。 正直なところ、このまま読まずに人生を過ごせた方が幸せかなー、などとも思っている。 現在良く使われる CPU アーキテクチャの中で Intel x86 は最も歴史が古く、過去の名残みたいなものが多いのだが、それを把握していくことにあまり喜びを感じられない。

RISCV

RISCV は、オープンな規格を標榜しているだけあって、ユーザー登録しなくても仕様書が読めるようになっている。 新進の ISA なので、分量も ARM/x86 に比べて少ない。CPU 仕様書の初心者にもお勧めできる。

GPU の規格書・仕様書

AMD

こちらも数多くのドキュメントがある。私が一番気にあるアーキテクチャ関連について、NVIDIA よりはドキュメントが多そう、という気がする。 RDNA の ISA のマニュアルなどがある。個人的に興味があるので読んでみたいが、最近時間が…

NVIDIA

ドキュメントは数多くあるが、私が一番気になるアーキテクチャ関連については、それほどドキュメントが無い気がする。NVIDIA が ARM を買収するということだし、ARM のドキュメント並みに詳しいドキュメントで溢れていくことを期待したい。

インターコネクトの規格書・仕様書

インターコネクトは、実用的に使われているものだけでも本当に多くの種類がある。 とりあえず、自分が知っているやつだけまとめる。分類方法も迷ったので、とりあえずアルファベット順に並べた。

AXI

ARM のチップ内インターコネクトだが、ARM 製品に限らず至るところで使われている。ARM のサイトからダウンロードして読むことができる。

Display Port

基本的に VESA という業界団体に加入しないと、規格書は読めない。

ただし、Display Port 1.2a など一部の規格書は、フリーでダウンロードできる。

Ethernet

Ethernet の規格は事実上 IEEE 802.3 である。 試していないが、ユーザー登録すれば以下のページからフリーでダウンロードできるようだ。

また、以下のページに過去の規格書のアーカイブがあったりする。

HDMI

基本的には HDMI アダプタという業界団体に加入しないと、規格書は読めない。 ただし、一部の規格書は Web サイトに登録すると無料で読めるらしい。

また HDMI の元となった DVI の規格書は無料で読めた…らしいのだが、今はドメインが失効している。

I2C

 I2C はフィリップスが策定した規格で、現在は NXP セミコンダクターズの Web サイトで規格書が配布されている。なんと日本語の規格書もある。内容も難しくないので、規格書初心者にオススメ。

PCIe

PCIe の規格書は、PCI-SIG という業界団体のメンバになったりお金を払ったりしないと読むことができない。

SATA

SATA の規格書は、SATA-IO という業界団体にお金を払わないと読むことができない。

規格書・仕様書があるかはよく知らないが、SPI 自体そんなに難しくないので、Wikipedia 読んどけばいい気がする。

UART

UART は規格書・仕様書ってあるんだっけ…これも難しくないので、Wikipedia でも読めば十分だと思う。

https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter

USB

USB はオープンな規格なので、誰でも仕様書をダウンロードして読むことができる。

ホストコントローラの IF である EHCI, xHCI については Intel のサイトから仕様書をダウンロードする。

プログラミング言語の規格書・仕様書

プログラミング言語は星の数ほどあるが、私が触ったものの中で低レイヤのものについてだけ記載。Rust は詳しくないので、含まれていない。

C

cpprefence に、C 言語や ABI の規格のリンク集がある。

C++

cpprefjp に、標準規格へのリンクがある。

SystemVerilog

これかなー。

CeVIO や棒読みちゃんで喋るアラームを公開

「VOICEROID や CeVIO が喋ってくれるアラームがほしい!」と思ったので、自分で使うためにちょっとした Windows アプリケーションを作成しました。 今回、それを GitHub で公開してみることにしてみました。皆様も、リモートワークのお供にいかがでしょうか?

詳しい使い方は README.md に書いてありますので、そちらをご覧ください。 こっちのブログには、もっとくだけた話を書きます。

音声合成アプリの購入が必要

今回作成した VoiAlarm (ボイアラームと読む) は、CeVIO や VOICEROID を外部から操作するアラームアプリです。これらの多くの音声合成アプリは有料で、当然 VoiAlarm には付属していません。ご自身でお買い上げになる必要があります。

音声合成アプリを持っていない方は、CeVIO が 30 日間の無料体験版を配布してますので、それで試してみるのが良いと思います。後述のように、CeVIO なら VoiAlarm との連携も簡単です。私も、開発中は無料体験版を使っていました。(最近、30日を過ぎてしまったので製品版を購入しましたが。)

VOICEROID を使うには棒読みちゃんが必要

最初のターゲットは VOICEROID シリーズだったのですが、VOICEROID シリーズは外部アプリケーションから簡単に操作できる機能が用意されていません。そのため、VOICEROID シリーズを操作するには棒読みちゃんと、Voiceroid Talk Plus というプラグインが必要です。

これらの素晴らしいプログラムを開発してくださった方々に、この場を借りて感謝を申し上げます。

VoiAlarm から VOICEROID に発話してもらうには、これらのプログラムがすべて正しくセットアップされている必要があります。そのため、VoiAlarm を公開はしてみたものの、VOICEROID を利用するのはハードルが高いかも…と思っております。

しかし、おかげで棒読みちゃんが対応している音声合成アプリが VoiAlarm 関係なく利用できるようになりました。棒読みちゃんを使いこなせる方には、便利かもしれません。

CeVIO なら簡単

CeVIO CS7 は外部連携インターフェースを公式で提供しています。VoiAlarm でもこれを使わせていただきました。よって、CeVIO を使う場合は棒読みちゃんなど他のプログラムを介在させる必要がありませんでした。

今回 VoiAlarm は C# / WPF で開発しましたが、その大きな理由が「CeVIO が外部連携インターフェースとして .NET アセンブリを提供している」ことにあります。

VoiAlarm を使っていて起きる問題

自分で作っといて情けないですが、VoiAlarm には色々ハマりどころがあります。 一番よく起きるのは「外部ツール (VOICEROID など) が起動していないため、アラーム時刻になっても音声が再生されない」というものです。

しかし、どうしても VoiAlarm 自身で改善できることが限られます。いっそ公式がアラーム作ってくれないかな…

今後やりたいこと

  • 発話の設定を、もっと細かくできるようにする
  • 棒読みちゃんを経由せずに VOICEROID を叩けるようにする
  • Google カレンダー連携

こんな感じの実装をしたら便利かな、と思っています。(実装するとは言ってない)

2010 年代のスマホの CPU の進化 (Apple と Samsung)

身内向けの勉強会*1で 2010年代の ARM 系 CPU の進化の話をしたのですが、その時に作った表が我ながら面白かったので、ブログに載せます。

AppleSamsung のフラッグシップスマートフォンの CPU の一覧表を作ってみました。なお、情報ソースは主に Wikipedia / Wikichips / PC Watch ですので、そのレベルの資料とお考え下さい。

追記

コンピュータ・アーキテクチャに詳しくないプログラマ向けに、CPU のスペックの見方をざっくり説明する補足資料をアップしました。よければ、こちらもどうぞ。 www.slideshare.net

Apple iPhone の CPU

IPC に関する情報(デコード幅、発行幅など)については、集まった情報だけを載せています。

発表 搭載製品 SoC CPU
2010 iPhone 4 A4 Cortex-A8 x1 core (1.0 GHz) (In-Order / 2-decode / 2-issue)
2011 iPhone 4s A5 Cortex-A9 x1 core (1.0 GHz) (Out-of-Order / 2-decode / 2-issue)
2012 iPhone 5 A6 Swift x2 core (1.3 GHz) (Out-of-Order / 3-decode / 3-issue)
2013 iPhone 5s A7 Cyclone x2 core (1.4 GHz) (Out-of-Order / 6-issue)
2014 iPhone 6 A8 Typhoon x2 core (1.5 GHz) (Out-of-Order / 6-decode / 6-issue)
2015 iPhone 6s A9 Cyclone 2ndx2 core (1.85 GHz) (Out-of-Order / 6-issue)
2016 iPhone 7 A10 Hurricane x2 core (2.34 GHz) + Zephyr x2 core (1.05 GHz)
2017 iPhone 8,X A11 Monsoon x2 core (2.39 GHz / Out-of-Order/ 7-decode) + Mistral x4 core (Swift-based)
2018 iPhone XS,XR A12 Vortex x2 core (2.49 GHz / Out-of-Order / 7-decode) + Tempest x4 core (Swift-based)
2019 iPhone 11 A13 Lightning x2 core (2.66GHz) + Thunder x4 core

Apple は 2012 年に発表した iPhone 5 から独自 CPU を使っています。2013 年には CPU が 64 bit 化したわけですが、この時点で 6-issue とそこそこ「大きい」CPU コアです。

Apple の場合、2010 年代前半に IPC はかなり上昇したと思われますが、一方でクロック周波数・コア数の伸びは Galaxy に比べ緩やかでした。

Samsung Galaxy の CPU

一部の Galaxy には Exynos 搭載モデルと Snapdragon 搭載がありますが、この表では Exynos 搭載モデルの方が載っています。

発表 搭載製品 SoC CPU
2010 Galaxy S Exynos 3 Single Cortex-A8 (1.0-1.2GHz) x1 core (In-Order /2-issue)
2011 Galaxy S II Exynos 4 Dual Cortex-A9 (1.2-1.4 GHz) x2 core (Out-of-Order / 2-issue)
2012 Galaxy S III Exynos 4 Quad Cortex-A9 (1.4-1.6 GHz) x4 core (Out-of-Order / 2-issue)
2013 Galaxy S4 Exynos 5 Octa Cortex-A15 (1.6 GHz) x4 core (Out-of-Order / 3-issue) + Cortex-A7 (1.2 GHz) x4 core (In-Order / 2-issue)
2014 Galaxy S5 Exynos 5 Octa Cortex-A15 (1.9–2.1 GHz) x4 core (Out-of-Order / 3-issue) + Cortex-A7 (1.3–1.5 GHz) x4 core (In-Order / 2-issue)
2015 Galaxy S6 Exynos 7 Octa Cortex-A57 (2.1 GHz) x4 core (3-decode / 3-issue) + Cortex-A53 (1.5 GHz) x4 core
2016 Galaxy S7 Exynos 8 Octa Mongoose 1 (2.3-2.6 GHz) x4 core (4-decode) + Cortex-A53 (1.586 GHz) x4 core
2017 Galaxy S8 Exynos 9 Series(Exynox 8895) Mongoose 2 (2.5 GHz) x4 core (4-decode) + Cortex-A53 (1.586 GHz) x4 core
2018 Galaxy S9 Exynos 9 Series(Exynox 9810) Mongoose 3 (2.9 GHz) x4 core (6-decode) + Cortex-A55 (1.9 GHz) x4 core
2019 Galaxy S10 Exynos 9 Series(Exynox 9820) Mongoose 4 (2.7 GHz) x2 core (6-decode) + Cortex-A75 (2.3 GHz) x2 core (3-decode / 7-issue) + Cortex-A55 (1.9 GHz) x4 core

Galaxy に搭載される CPU は、2010 年代前半に周波数およびコア数が一気に増えました。big.LITTLE の導入も Apple より3年ほど早いです。2010 年代後半には、高性能コアのデコード幅・発行幅が増えて「大きく」なりました。

2010年代中ごろは、Apple / Samsung で CPU の構成が大きく違っていましたが、最近は両者が同じような構成に合流していて、面白いですね。

Intel CPU との比較

これまで mac には Intel 系 CPU が使われていたわけですが、2019 年発売の Ice Lake は 6 micro-ops decode / 10 issue です。

デコード幅・発行幅は IPC の上限を決める重要なパラメータですが、これについてはスマホも PC も既に同レベルと言えますね。個人的な感想ですが、Apple の技術者は独自 CPU 開発を始めた当初から mac にも搭載することを狙っていたのではないでしょうか。

流石にクロック周波数をもっと上げないと、既存の Intel mac に性能が追い付かないような気もしますが…2021 年発売予定の ARM 搭載モデルがどんなふうになるのか、今から楽しみです。

*1:Apple Silicon と富岳のおかげで ARM に注目が集まったので、コンピュータ・アーキテクチャに詳しくない友人向けに最近の ARM 系 CPU の進化を説明しました

RISCV の個人プロジェクトの CI の話

前回のブログに書いた通り、最近は Chisel で RISCV の CPU を書いています。Chisel 以外にも SystemVerilog で RISCV の CPU を実装していますし、RISCV の CPU エミュレータもいくつかのプログラミング言語で作っています。

今回は、それらで共通して使っている CI の話です。

概要

私が趣味で開発して GitHub にアップロードしている RISCV 関連プロダクトでは、GitHub 製の CI フレームワークである GitHub Actions を使っています。

また、CI の実行時間を短縮するために verilator や riscv-tests などをプレビルドバイナリとして用意しています。

これらのプレビルドバイナリは docker を使って作成しており、プレビルドバイナリの作成手順を容易に保存・編集・バージョン管理できるようになっています。

GitHub Actions

help.github.com

GitHub Actions は最近開発が活発な CI サービスです。Travis-CI や Circle CI など、他の CI サービスの使用も検討した(というか一時期は使っていた)のですが、本格的に CI を整備するタイミングでちょうど GitHub Actions が話題になっていたので、これを使いました。

f:id:fjt7:20200618235624p:plain

GitHub との親和性が高くて使いやすく、マシンスペックも申し分ないので、オススメです。

プレビルドバイナリ

RISCV の CPU エミュレータや HDL 実装をテストする際は、riscv-tests という OSS のテストプログラムを使うのがお手軽です。

また SystemVerilog や Chisel のシミュレーションを実行するために、フリーの Verilog エミュレータである Verilator を使います。

www.veripool.org

よって CI の実行時には riscv-tests や Verilator のバイナリが必要です。Verilator のバイナリは、GitHub Actions の Ubuntu において apt で取得することもできるのですが、開発スピードが速いので最新版を自分でビルドする方がオススメです。

しかし riscv-tests や Verilator のビルドには数分以上はかかるので、CI を実行するたびにビルドしていると開発効率が下がってしまいます。そこで riscv-tests や Verilator のビルド済バイナリを別リポジトリにコミットしておき、これをチェックアウトして使うことで CI の実行時間を短縮させています。

プレビルドバイナリを作成する docker イメージ

前節で述べたプレビルドバイナリを作成するには、実はそこそこ手間がかかります。RISCV 用のコンパイラツールチェインなどを用意する必要があるのですが、その辺の環境整備にはわりと手間と時間がかかります。そして、一度プレビルドバイナリを用意すると滅多にその環境を使わないので、後で作業が必要になったときに環境をロスト・使い方を忘却して、結局同じプレビルドバイナリを作れなくなる、なんてことになりがちです。

そこで、プレビルドバイナリの作成は docker を使って行うことにしました。最初の環境構築の際に Dockerfile をちゃんと書いておけば、後で環境をロストする事故を防ぐことができます。(それでも使い方を忘れることはよくありますが)

私は、ネットの情報を色々参考にしたうえでオリジナルの docker イメージを作っていますが、RISCV の CPU を作っている人は世の中にたくさんいるはずなので、探せばもっと良い docker イメージも見つかるのではないかと思います。

github.com

Chisel HDL で超簡単な CPU を書いた

筆不精でずっとブログを書いていませんでしたが、最近いろいろ生活が変わってきているので、これを機会にブログ執筆にリトライします。 というわけで、今回は Chisel で超簡単な CPU を書いてみた話。

知っている方も多いでしょうが、chisel は近年注目を集めているハードウェア記述言語です。 私は学生時代に SystemVerilog で CPU を書いていて、その後流行り始めた chisel をいじってみたいとずっと思っていたのですが、最近ようやく chisel を書き始めました。

Chisel に入門するときにやったこと

技書博で、だいにんぎょーさんの「Chisel を始めたい人に読んでほしい本」を買っていたので、とりあえずそれを読みました。今は booth で買えます。

これ一冊読めば chisel で簡単な CPU を書くくらいはできますが、公式にも目を通しておきたかったので、以下のページを読みました。

Chisel の資料と言えば、バークレーの方が書いた原著論文が引き合いに出されることが多かったですが、もうかなり古くなってしまったので chisel3 wiki とかを読んだ方が良いです。

作ったプロセッサの構成

ごく単純な In-Order スカラ・プロセッサを作りました。いわゆる MIPS 5段パイプラインみたいなやつです。(私が作った他の CPU に合わせたため、パイプラインは5段ではありませんが) 命令セットは RV64I のみを実装しており、riscv-tests の fence 以外のテストが通ることを確認しています。 一応ソースコードは public にしていますが、正直他の人に参考にしてもらうレベルではないかな…まあ、これからがんばります。

他人のコードを読む方法

最近、他人が書いたコードを読む機会が増えてきました。
何万行もある未知のコードをどう読み解いて行くのか、自分の中で方法論が出来てきたように思うので、メモっておきます。

コードを読む目的を明確にする

一番大事なのは、「何を知りたいのか」ということを明確にした上でコードを読むことです。適切な目的を持たずにコードを読んでいると、途中で興味を持つポイントがどんどん変わって行って、何を調べていたんだかわからなくなるということが起こります。そんなことをしていてはいつまでもコードを読む作業が終わりません。短時間でコードを読み終えるためには、コードを読む目的を明確にしたうえで、その目的を達成することに集中する必要があります。

 

私がよく設定する目的は、

  • 自分は○○という機能を実装したいので、それに必要な API について調べる
  • とにかくコードの全体像を知りたいので、モジュールの機能を全てリストアップする

などです。

 

メモをする

コードを読んで行く際は、必ずメモをとるようにしましょう。コードを読むときにやりがちなのが、IDE やエディタで適当に関数の定義を追っていくという、ネットサーフィン的なやり方です。しかし、これでは何のためにコードを調べていたのか/何がわかったのかが、すぐに頭から抜けてしまいます。

 

前節で「コードを読む目的を明確化しろ」と書きましたが、「目的」は必ず目立つ場所に書いておきましょう。そして、コードを読む際は定期的にそれを見るようにしましょう。これにより、本来の目的を忘れて単にコードを眺めている状態に陥るのを防ぐことができます。

 

また、コードを読んでわかったことも、必ずメモを取るようにしましょう。どんなに綺麗に書かれているコードでも、「(コードを読んでいる)今の自分の目的に合わせて整理されている」ということはあり得ません。自分にとって大事なことがわかったら、忘れないうちにメモをとるようにしましょう。

 

メモを取る道具は何でもいいです。私はプログラマの癖にアナログな人間なのでペンとノートを使いますが、エディタでもブログでも良いので、自分の使いやすいものを選びましょう。

 

つまり、頭を使って手を動かせということ

コードを読むのは、コードを書くよりはるかに頭を使う作業です。コードを書いている時は、プログラムを実行すればフィードバックを得られるので、「作業の進捗度」や「現状の問題点」を比較的容易に知ることができます。しかし、コードを読むときはそうはいきません。コードを理解できたか判断できるのは自分しかおらず、「作業の進捗度(どこまでわかったか)」や「現状の問題点(何が分かってないのか)」を知ることは簡単ではありません。

 

難しいことをするときは、それなりの作戦を立てなければなりません。「コードを読む目的を明確化する」のは、その作戦の最初にして最も重要なステップです。

 

頭を使う作業を行うときは、手も一緒に動かした方が効率が上がります。私がコードを読む際に「メモを取る」のは、あまりに難しくてメモを取らんとやってられんからです。