手作りコンピュータのバスアーキテクチャ

「RETROF-16」は16ビット

50個ほどのTTLで構成されるRETROF-16はその名が示す通り16ビットのマシンです。
初代ファミコンは8ビットでスーパーファミコンは16ビット、PS2は32ビットだと言われます。最近のパソコンですと64ビットのCPUを登載した物もあります。
ところで、この8/16/32/64という値はいったい何を表す数字なのでしょうか?

R16A

実はこの「NビットマシンのNとは何か?」という問いに明確な答はなく、様々な人達が様々な視点で、様々な数字を述べているに過ぎないのです。

本ページでは、このNという値がどの様な意味で使われているのかを考えながら、同時にRETROF-16が何故16ビットバスアーキテクチャを採用したのかを解説したく思います。

画像はRETROF-16シリーズの1つRETROF-16改
RETOROFシリーズの一覧はこちら


2つの不可避な回路とそれらを構成するバス

図1はどんなコンピュータにも必ず存在する2つの回路を図式化して並べたものです。左はコンピュータが主メモリから命令やデータを取り出すための回路で、右は実際の計算をする回路です。

図1

様々なビット幅

各回路は共にいくつかの部品から構成されます。それらの部品間でデータを受け渡しするための結線(図では矢印で表記)がバスです。

単に「Nビットマシン」と言う場合、Nはこの図のいずれかのバスの幅(バスを構成する信号線の数)を示すのが一般的です。

但し、Nがどのバスの幅を言うのかは明確な「決まり」はありません。以後、①〜④の全てのバスに対し、そのバス幅の決定に至った経緯を解説します。


各バスの幅の単位はビット(bit)と表記します。バスの実体は複数の信号線なので「本」を単位としても間違いではないのですが、1本1本の信号線がそれぞれ1bitの情報が流れる経路となるので、単位としてはビット(またはbit)を使うのが慣例です。但し文脈によっては、「このバス幅は16とする」の様に単位を省略して記述することもあります。

アドレスバス

プログラムカウンタから主メモリへのバス

図1の①で示すバスがアドレスバスです。主メモリに対してアドレス指定する役割を持ちます。主メモリはこのバスで指定されたアドレスから、命令を読んだり、データを読み書きします。

このアドレスバスの幅は、主メモリの最大容量から機械的に決まります。従ってこのビット数が大きいほど、より多くの命令やデータを扱うことができるCPUだと言えます。

但しアドレスバスの幅がどんなに大きくても、実際にそのバスが示す領域に主メモリが実装されていなければ意味はありません。また、ここでは仮想記憶やバンク切り替えなどのテクニックはないものとして、アドレスバス幅=主メモリ容量として話を進めます。

手作りコンピュータのアドレスバスの最適ビット数

では、TTLでコンピュータを自作する際の最適なアドレスバス幅をは幾つなのでしょうか?

まず最初に前提条件として、アドレスバス幅は4の倍数に限るとします。これは74シリーズに含まれるレジスタやカウンタ用のTTLの多くが、4ビット長のバス幅を扱う様に作られているからです。実際の製作ではこの4ビット用のTTLを複数並べて多ビット長のレジスタやカウンタを構成しますので、4の倍数にすると都合がよいのです。

上記の制約を除けば、「アドレスバス幅は幾つが最適なのか?」は「どの程度複雑なプログラムの実行したいのか?」と同じ問題になります。 

物理的なメモリ量と実行可能なプログラム

表1は物理的な主メモリの量と、そのメモリ量で実行可能なプログラム(及びゲームプログラム)の対応表です。
但し、同じ主メモリ量でも使用するCPU(および外部記憶装置やグラフィック制御装置などの性能)により実行可能なプログラムは大きく変わります。この表は大体の目安です。 

表1

物理メモリ量  作成可能なプログラムの例  適切な表示装置があれば作成可能なゲームの例
16B(バイト) 1から10までの和を求める ゲームを作れるほどの容量ではない
256B 掛算・割算の実験 数あてゲーム
約4KB 簡易なインタプリタ オセロゲーム、簡略化したインベーダーゲームなど
約64KB 簡易なOS、簡単なコンパイラ オリジナルのインベーダーゲームやギャラクシアンなど
約1MB フルスペックのCコンパイラ 初代ファミコン相当のゲーム
約16MB Windows95相当のOS スーパーファミコン相当のゲーム

どのレベルを狙うかは、それを作る者の自由です。ここでは表の黄色で示した性能を作成するCPUの目標性能とします。(この理由は「開発計画時の基本ポリシー」として別途公開予定)

「物理メモリ量」は「アドレスバス幅」と「データバス幅」の積となります。そこでとりあえず物理メモリ量を64KB前後とアバウトに仮定した上で、先にデータバス幅を決定し、その後アドレスバス幅を逆算して決めるという方法をとることにします。

データバス

データバス幅を決定する際の基本的な考え方

図1の②がデータバスです。アドレスバス幅が主メモリ量から機械的に決まるのに対して、データバス幅の決定は少々厄介です。ノイマンアーキテクチャにおけるデータバスは、値としてのデータの受け渡しと、命令としてのデータの受け渡しの両方を担うため、互いに矛盾する2つの理想的なバス幅が現れてしまうからです。 

まず値としてのデータの受け渡しですが、高速数値計算をを目的としない限り、それほど大きくする必要はありません。(注) 極端な話4ビットもあれば、ソフト側の対応でどんなに大きな数でも計算することが可能です。勿論一度に計算できる値が大きいほどプログラミングは楽になりますが、ハードを手作りすることが前提の場合、データバス幅は小さければ小さいほど、部品数も少なくできますし回路設計も楽になります。

一方、命令コードを取り出すためのデータバス幅を考えると、これとは違った理想のバス幅が登場します。この点に関しては次項でその詳細を説明します。

【注】但し1つのデータを1つの画素に対応させる方式の表示回路を実装する場合は、このビット数は表現可能な色の種類を決定しますので、フルカラーグラフィックスの制御をするのであれば、それなりのビット数が必要となります。
 

命令長とデータバス幅の関係

図2の(A)は命令長とオペランド長の関係を表したものです。命令長がデータバス幅に等しく、オペランドがアドレスバス幅に等しいと仮定すると、「データバス幅>アドレスバス幅」でなけらばいけません。仮にアドレスバス幅を16とすると、データバス幅は20〜24程度は必要となり、前項で述べた「データバス幅は4ビットでも十分」という考え方と矛盾してしまうのです(注)

図2

様々なビット幅

この矛盾を解決するには図2(B)の様に、1つの命令を複数のデータで構成するしかありません。これを複数ワード命令方式と呼びます。 

複数ワード命令方式は、少ないでデータバス幅で多彩な命令を表現できるという利点がある反面、複数回主メモリをアクセスしないと命令が決まらないという欠点があり、命令を取り出す回路や、命令を解析(デコード)する回路も複雑になってしまいます。


このため、自作コンピュータとしては敬遠されがちな方式ですが、RETROF-16では十分なメモリ空間を確保するために、あえてこの複数ワード命令方式を採用しました。

但し、複数ワードと言っても最大2までとします。「最大2」に拘る必要は無いのですが、この制約を設けたのは、命令デコード回路を必要以上に複雑にしない事を優先するためです。
ちなみに世界初のマイクロコンピュータである4004は4ビットのバス幅ですが、12ビットのアドレス空間を表現する4ワード命令を有します。また8080は8ビットのバス幅ですが、16ビットのアドレス空間を表現する3ワード命令があります。

【注】黎明期のコンピュータ(EDSAC等のレガシーマシン)はメモリが非常に高価であったため、アドレス空間は最大でも10ビット前後しかありませんでした。また数値演算はできるだけハードで高速処理するためにデータバス幅を30ビット以上にするのが一般的でした。このためアドレスバス幅>データバス幅となるような矛盾は発生しませんでした。


第一感はアドレスバス幅16ビット、データバス幅12ビット

ここまでに登場した数字をまとめると、オペコードを8bit、オペランド(=アドレスバス幅)を16ビットとすると、命令長は合わせて24ビットとなり、それを2語で表現すると、1語あたりの大きさ(=データバス幅)は12ビットとなります。

いずれの数字も4の倍数ですからTTLで構築するのに適切な値ですし、搭載可能な主メモリも16ビット空間×12ビット幅=96KBと十分です。これが自作TTLコンピュータにおけるバスアーキテクチャ設計の第一感です。 しかし最終仕様ではありません。話はまだ続きます。

演算関係のバス

相対ジャンプ命令

下図は本ページ冒頭の図1の再掲です。データバス幅②が12ビットなら、③も12ビットになりますし、演算の種類として乗算がないのであれば④も12ビットとなります。これで全てが丸く収まるのですが、ここで1つ「欲」が出てしまいました。相対ジャンプ命令です。

機械語プログラミングでは分岐命令は非常に多く出現します。そしてその分岐先は、分岐元から大きく離れた位置ではなく数ワード先とか数ワード前であることが殆どです。
この様な「近距離」分岐は、絶対アドレスではなく、基点(その命令)からの距離で指定することにより、オペランドは極端に小さくできます。つまり相対分岐命令があれば、2ワード命令ではなく1ワード命令でも分岐が可能になるのです。

しかし、普通に考えると相対分岐命令は専用の加減算器が必要になり回路規模が大きくなります。従って手作りコンピュータでは実装は割愛されやすい命令です。しかし私は通常の演算用の演算装置を相対分岐命令用の加減算器として使えば、回路規模を大きくせずに相対分岐が可能になるのではないかと考えました。

再掲図1

様々なビット幅

結論から言うと演算用の演算装置を相対分岐命令用の加減算器に使う事は十分可能です。
(理由は詳細設計編で解説予定) 

しかしアドレスバスは16ビットですから、演算器も16ビット対応にする必要があります。言い換えると図1の全てのバスを16ビットにすることにより、相対分岐を含む全ての命令を効率よく実装できるということです。


アドレスバス幅とデータバス幅を同じにすると、もう一つ大きなメリットが生じます。「それはアドレス値をデータ領域に格納するのがとても簡単になる」という点です。これは「戻り番地」をデータ領域に記憶する必要があるサブルーチンコールの実装をも簡単にしてくれます。

バス幅に関する最終仕様

結局全てが16ビット

以上の考察に基づき、結局、最終仕様は「全てのバスが16ビット」となりました。

図3

様々なビット幅

全てのバスが16ビットなので各種のレジスタ群も全て16ビットとなりました。(フラグレジスタだけは例外で4bit)

このため、RETROF-16が「16ビットコンピュータ」であるのは明らかなのですが、どのバス(あるいはどのレジスタ)の大きさを指して16ビットと称するのかは、設計した本人も分からないままとなりました(笑)。

しかしこれで、更に詳細な設計を開始することができます。


次章は、全てのレジスタの種類と配置、並びにそれらを結ぶバスの詳細を紹介します。

(参考資料)EDSAC

EDSACは1949年に稼働した真空管式コンピュータです。水銀遅延管を用いた主メモリが搭載され、計算も2進数で行うなど、現在のコンピュータの原型となったマシンです。
主メモリは1024ワード(実装は512ワード、1ワードは17bit)です。演算は35ビット同士の四則演算ができました。

再掲図1

様々なビット幅

EDSACの命令長は1語でしたが、アドレス空間は10ビットしかなかったため、1語(=17ビット)で任意のアドレスへの分岐命令を表現できました。

EDSACとRETROFはその構成部品が真空管かTTLかという違いはあるものの、コンピュータの設計思想はとてもよく似ています。
しかし、当時と今では主メモリの実装可能量が桁違いに違うため、個々の主要なバス幅は全く異なるものとなっております。


 

(2015年6月13日初出)