穴日記

どうだ明るくなったろう

プロセッサ・コンパイラ実験記(あるいはCPU実験記)

id:sukai1989が書いていたので。

彼とは同じ班だったので、彼の記事(http://d.hatena.ne.jp/sukai1989/20110311)を読めば、まあ、全てがわかりますが、色々とだらだら書いておきます。主に僕のやったことを中心に書くので、CPU実験全体についてはsukaiさんのほうが多分詳しいです。

CPU実験とは

CPU実験とは、4,5人で班を作り、FPGA上で実際に動くCPUを開発、さらに与えられたプログラムをコンパイルするコンパイラも開発し、レイトレーシングプログラムを動作させる、というものです。色々な役割があり、班内で分担することになる、僕の通う情報科学科の名物らしい授業です。

シミュレータ係りとは

僕はCPU実験ではシミュレータ係りという重要そうに見えてあんまり忙しくない係りでした。
このシミュレータ係りというのは要するに、班のCPUアーキテクチャのシミュレーションやらエミュレーションやらを行うプログラムを作る、というものです。このシミュレータというやつが無いとコンパイラデバッグできないわ、ハードウェアの正しさを検証できないわ、統計情報は得られないわ、最適化は進まないわ、と、とんでもないことが起きるのですね。
しかし、それにも関わらず、シミュレータというのは実はあんまり作るのが難しくないため、この係りはコア係りとかと比べると仕事が無いんです。

シミュレータ係りとして(最初期)

僕も、単純にシミュレーションするだけのプログラムはあっというまに出来てしまいました。しかし、いくらなんでもこのままだとやることなさすぎだろう、ということでGUI化を行うことに。このGUI化はQtというC++によるライブラリを使わせていただきましたが、これがなかなか使い勝手が良く、結構あっさりGUI化に成功しちゃいました。そこで、さらなる拡張を暇に飽かして施しまくり、最終的に結構リッチなものになったと思います。まあ完全にただの趣味です。来年以降の人達は頑張ってJITを組み込んだり、実行統計をリアルタイムでグラフ描画したりしてほしいですね。

シミュレータ係りを超えて(中期)

で、あまりにもやることが無いので、途中で「目の前のFPGAボードで何ができるか?」を追求することににしました。たしか、最初にやったのはPerlin Noiseを出力するプログラムを自アーキテクチャ向けに書いたところからだったと思います。その後、Mandelbrot setを出力するプログラムとかも書いた記憶があります。
まあそういう感じになったので、せっかくなのでとりあえずゲームでも作るかという自然な流れになったわけです。
そっからは結構やることありました。まず、FPGAからディスプレイ画像を出力しなければならない。
去年まで使ってたFPGA基盤にはDVI出力用のコネクタが接続されていたため、それを使えば普通にディスプレイから画像が出たらしいです。しかし、今年使ってる基盤にはそういう気の利いた端子は全くありませんでした。そこで、「まあ適当につかってよ」みたいな感じでなんとなく生えている拡張コネクタ端子から線を引っ張ってきてVGA端子を自作するところからゲーム製作は始まったわけです。
大体、VGAの仕様を僕が調べ、VHDLでモジュールを書き、半田漬けとかはsukaiさんがやる、という感じでした。しかし、VGAはアナログ。FPGAの出力はデジタル。ということで、いわゆるデジタルアナログコンバートを行わなければなりませんでした。これがかなり大変で、色々な回路で最適なものを模索しました。最終的には抵抗を並べてそれなりにうまく変換されるものができましたが、詳細はsukaiさんの方が詳しいです。
そんなこんなで、頑張ってFPGAからディスプレイに最初に絵がでたときはさすがにちょっと感動しましたね。はっきりいってCPU実験で一番嬉しかったですね。ちなみに次に嬉しかったのは音が出力されたときですね。

同人CPUで同人ゲームを動かそう(後期)

FPGAからディスプレイ出力に成功したので、次に入力機構を作りました。これは、色々案があったのですが、最終的にスーパーファミコンのコントローラーを改造してパラレル通信するのが一番ハードウェア的にもソフトウェア的にも楽だろう、ということでそのようになりました。これはほとんどsukaiさんが改造してるのを眺めてるだけで、僕がやったのはインターフェースを決めるのとテストプログラムを書くくらいでした。
入力については、ちゃんと配線したはずなのになぜかボタンを押すと信号が超不安定になるという謎のバグがハードウェアに発生し、ちょっと困りましたが、単にICのGNDをどこにも接続していなかったという凡ミスだった、というのが印象に残っています。
画像出力、コントローラー入力、とくれば次は音声出力です。実は、過去、CPU実験においてはディスプレイに絵を出し、テトリスをプレイできるようにした人達がいたらしいのですが、その人達も音までは出していなかったらしいのです。ということで音声出力は地味に前人未到な試みでした。
具体的には、YAMAHAの音源ICであるYMZ294というチップをFPGA側から操作し、スピーカーに対して出力する波形を生成させる、という構成になりました。別にYMZ294にした根拠は何もないです。しいていえば秋月電子で簡単に手に入ったから、という程度の理由です。FPGAで直接波形生成する、という案もあったのですが、かなりの手間っぽかったので止めました。
YMZ294はかなりわかりやすいICで、FPGA側からの制御は結構楽でした。多少バグも発生しましたが、結構すぐ直るようなものばかりでした。それでも最初に音が出たときはなかなか感慨深いものがありました。

イカディウスだ!(終盤)

このころから、いよいよ自CPU上で現実的にゲームが動きそうになってきたので、ゲームのプログラム開発を開始。そのために、従来のシミュレータに画像出力機能と入力機能、それにYMZ294チップのシミュレータを付け加え、ゲーム開発用シミュレータとして拡張を加え、さらに、ゲームで使う画像を独自フォーマットに変換するためのいくつかの補助スクリプトなどを書きました。
いきなりゲームを作るのも無謀かと思ったので、まず、基本的な画像出力や入力、ファイルのロードなどをテストするためのプログラムを書くことにして、ブロック崩しや、3D描画(Utah Teapot)、BGM演奏プログラムなどを完成させました。
これら基本的なプログラムの動作を確認した後、いよいよ同人ゲームイカディウスの開発に着手しました。これは侵略!イカ娘を題材にした二次創作同人ゲームになっており、絵は全部sukaiさんが描いてくれました。感謝。
プログラム期間は途中休憩をはさんだりしつつ大体二週間といったところです。min-camlというOCamlのサブセットの関数型言語でゲーム作るのは大変かなあ、と思っていましたが、案外楽でした。
プログラム全体の構成としては、ゲームのロジック部分は全部min-camlで書き、描画ルーチンなどの高度な最適化が必要な部分や、サウンドドライバなどはアセンブリで直接書いた感じです。
そして、発表前日になりようやく一本のゲームとして完成を迎えた、というわけです。

そして発表

発表はsukaiさんも書いてるとおり、微妙にgdgdでしたが、僕はFPGAでゲームが動かせた、という事実だけで半分くらい満足してたのでまああんなもんかなって感じでした。ただ、動画とかに残すのを忘れてたのがちょっと残念です。完成させたのは深夜で、頭も体もつかれきっており、そこまで気がまわらなかったのですねー。まあそのうちFPGA借りればいいかって話ですけど。

それでも、せっかくsukaiさんが描いてくれた絵をそのまま腐らせるのももったいないので、ただいまウィンドウズアプリケーションに絶賛移植中です。min-camlはOCamlのサブセットであり、OCamlはF#のサブセットなので、F#でコアロジックを移植し、描画とかの手続き的な部分はC#で書き、両者を連携させていい感じに移植できてます。完成したらそのうち公開することになるでしょう・・・。

まとめ

そんなこんなで半年にわたるCPU実験も終りを迎えたわけですが、いいかげんあの単一の評価用プログラムでコンテストするって形式は無理があるんじゃないですかね。プログラムの方を変えるか、あるいはもっと多面的な評価(例えばCPUアーキテクチャの独創性とか)を競うとか、あるいはプレゼンの質で評価するとか、そういう方向にシフトしないとあんまり現代的でない気がします。
それに、班員の負担も差がありすぎる気がします。結局一部の人が死ぬほど頑張って、他の人達を引っ張るような構図になっている班がいくつもありました。
まあ、このあたりのことは来年以降どうなっていくかを見ていたいと思います。そして、来年度以降の人達があっと驚くような結果(速度的にも、余興的にも)を出してくることを期待したいです。

とりあえず、半年間の間関係者の皆様はお疲れ様でした。