2015年4月5日日曜日

[コンピュータ開発][コンピュータシステムの理論と実践] ALUの作成

先日、O'Reillyから「コンピュータシステムの理論と実装」が発売された。
NANDという電子素子からスタートし、論理ゲート、加算器、CPUを設計します。そして、オペレーティングシステム、コンパイラ、バーチャルマシンなどを実装しコンピュータを完成させて、最後にその上でアプリケーション(テトリスなど)を動作させます。 
という内容で、まえがきには「腕まくりをし、コンピュータをゼロから作り上げたいと願う読者のための本」と書かれている。
実際にはハードウェアは作成せず、Javaで書かれたエミューレータ上で、コンピュータを作っていく。

自分でデザインしたCPUを動かしたいと思い、DE0を購入し、入門書を参考に、簡単な回路を作ったりしていたのだけど、この本を一通りこなしてから、DE0でのCPU作成にとりかかろうと思う。

各章毎にテーマがあり、動作するものを作成していく構成になっている。
第1章 NANDを使って基本的な論理回路の作成
第2章 ALUの作成 まで完了した。
HDL(Hardware Description Language)で回路か記述し、ハードウェアエミュレータで動作確認をしていく。
エミューレータによるテスト中は、入力データ、出力データ、回路内部のデータがピコピコ表示されて面白い。

はまった点

いくつか、はまった点があったので書いておく。

Hardware Emulator

Windows8.1 + Java8の環境

画面右上にあるViewでOuputとCompareを選択しても、表示されない。
この挙動を見て、Linuxで作業することにしたので、解決方法は不明。
Javaのバージョンを下げると動くのかもしれない。

Debian Wheezy + Awesome Windowの環境

Manager Awesomeが便利なので、常用しているが、HardwareEmulatro.shを実行すると、一面グレーのウィンドウが表示されるだけ。
Java6,7,8、いずれも同じ現象。
Window ManagerをXfce4に変更したら正しく表示された。

HDLの書き方

ALUで、出力が0の場合に nz=1 となるように、以下の定義を書いたが、hdlの読み込みでエラーとなった。
Mux16(a = out0, b = nout0, sel = no, out = out, out[15] = ng);

Or8Way(in[0..7] = out[0..7], out = or0);
Or8Way(in[0..7] = out[8..15], out = or1);
Or(a = or0, b = or1, out = nonzero);
Not(in = nonzero, out = zr);
エミュレータの下部にエラーメッセージが表示されるが、一行しか表示されず、エラーの行番号は分かるが、肝心なエラー原因は途中で切れて分からない。エミュレータのウィンドウを広げても、表示幅は固定のため、内容を確認できない。
検索したり、試行錯誤したりして、以下のように記述したら、正しく解釈できた。
Mux16(a = out0, b = nout0, sel = no, out = out, out[15] = ng, out[0..7] = out1l, out[8..15] = out1h);

Or8Way(in = out1l, out = or0);
Or8Way(in = out1h, out = or1);
Or(a = or0, b = or1, out = nonzero);
Not(in = nonzero, out = zr);

エミューレータのソースは公開されているので、手っ取り早く対応するには、エラーメッセージを標準出力に出力するようにすれば、便利かも。

 その他

ハードウェアエミュレータは素子の遅延時間は見ない 遅延時間は見ないので、非効率な回路を定義しても、論理的に合っていればテストOKとなる。 実際に回路を組むときは、この遅延時間を考慮することは非常に重要なのだけど、ここまで、記述はないようだ。