読者です 読者をやめる 読者になる 読者になる

幼女でもできる自作CPUチップ (4) 命令デコーダ設計

電子工作 自作LSI

 前回の記事

ourfool.hatenablog.com

では、CPUの具体的な構成や命令セット、つまりアーキテクチャを策定した。

 そして今回は、第1回のフローに示したRTL設計をおこなっていく–––––つもりだったのだが、方針を変えて回路シミュレータを使い各回路ブロックの検証をおこなうことに決めた。

 というのも、RTL設計にはそもそもHDL (Hardware description language) に関する知識が必要であり、その上、シミュレーション用のソフトウェアも利用方法が難解である。これらの理由から「幼女でもできる」という趣旨には反しているように思えてきた*1

 加えて、RTL設計をソフトウェアでおこなえば、そこから自動で論理ゲートレベルの設計をおこなうことが出来てしまう。これによって、自ら論理設計をおこなう、というクッソ面倒な作業へのモチベーションが潰える危険性は極めて高い。それゆえ、全体のRTL検証は後回しとして、まずはフリーの回路シミュレータで各ブロックごとの地道な検証をおこなっていく。

 まず、前回記事内容の修正について書いていく。

f:id:ourfool:20160529183155p:plain

前回は上図のImDataやAddressを5bitとしていたが、これを10bitへと変更する。これは、流石に5bit(命令が最大32ステップ)じゃなんもできないのでは、、といった考えから来たやむを得ずの変更である。前回このCPUを「LO5」と命名したが、この変更に伴って「LO10」へと改名する。オペコードは5bitのままであるから、命令セットに変更はない。一方、レジスタやALU間のデータはすべて10bitでやり取りされる。
 また、命令デコーダの真理値表に一部誤りがあったので、修正したものを再掲する。

f:id:ourfool:20160529183743j:plain

だいぶ威圧感を感じるが、今回はこれを人力で論理ゲートレベルに直し、回路シミュレータで検証する。

 ここでデコーダ入力のCはキャリー信号を表す。ALUが加算命令をおこなう際、桁上げがおこった場合にはキャリー信号を出力する。この信号の有無で、CPUの挙動を変えることにより、条件分岐ジャンプ命令(JNC)を可能にする。

 論理ゲートレベルへの変換に先立って、まずは論理の簡単化をおこなう。大学の授業等ではカルノー図で頑張るところだが、流石に5(or 6)変数にカルノー図を使うのはつらいので、Web上のアプリを使わせていただくことにする(オンライン 論理圧縮・論理式簡単化システム 論理あっしゅ君)。これによって、真理値表の5入力(O4、O3、O2、O1、O0)と、SBやSAといった出力の関係を論理式として把握できる。
 それぞれについて地道に値を打ち込み、調べていくことになるのだが、このままの真理値表を使うのではあまりに面倒なので、以下のような表を作成し直す。

f:id:ourfool:20160529184925j:plain

5bitの入力が(0, 0, 0, 0, 0)~(1, 1, 1, 1, 1)と順に変化していくよう、命令を並び替えている。これで入力が一気に楽になった。

 5bitの入力で表せる状態が2^5=32種類なのに対して、命令は21種類しかない。よって、その他の11状態はそもそも入力として現れる可能性がないので、出力は何であっても構わないとして、x(Don't care)としている。これにより、論理の簡単化が図れる。

 それぞれの結果は以下に示すようになった。

f:id:ourfool:20160529190104j:plain

SB、SAあたりは何も考えていないだけに酷いことになったが、その他はほどほどに簡単化されたので、まあ良しとする。

 さて、これらの論理式をインバータやNANDゲート、NORゲートといった論理回路図で表現し、それを検証することが、今回の目標である。

 検証には、フリーの回路シミュレータとして有名なLTspiceを用いることにした。

電子回路シミュレータLTspice入門編―素子数無制限!動作を忠実に再現! (ツール活用シリーズ)

電子回路シミュレータLTspice入門編―素子数無制限!動作を忠実に再現! (ツール活用シリーズ)

 

フリーのSpiceシミュレータにも関わらず素子数無制限で収束性もよく、幼女でも気軽に扱えるUIが魅力である。書籍など情報源も豊富。

 LTspiceにはデフォルトでディジタル論理ゲートのデータが含まれているので、それを用いてシミュレーションをおこなう。Edit→Componentから[Digital]→and、or、invなどを選択し配置する。入力波形は、voltage素子を用いて生成する。

 雑でアレなのだが、シミュレーション用の回路図は以下のようになった。上部で入力波形を生成しており、下にそれぞれの論理式を満たすよう、NANDやNORゲートを配置している。

f:id:ourfool:20160529191746j:plain

 上部の拡大図は以下、voltage素子を複数配置してそれぞれの周期を調整すれば、5bit入力を順次変化させていくことができる。

f:id:ourfool:20160529192058j:plain

 SBは以下のような接続、ゲートはデフォルトで5入力なので、使わない端子はまとめてGNDへ接続する。

f:id:ourfool:20160529192149p:plain

 SA、S2、S1は以下のような接続。

f:id:ourfool:20160529192441p:plain

 S0、LA、LBは以下。

f:id:ourfool:20160529192939p:plain

 LP、LOは以下。

f:id:ourfool:20160529192910p:plain

 接続を終えたのち、シミュレーションをおこなった。Simulate→Runののち、各ノードをクリックすれば電圧が確認できる。解析時間さえ設定すればよく非常に簡単。

f:id:ourfool:20160529193415j:plain

波形は上からO4、O3、O2、O1、O0、LBを表している。入力のO4-O0が変化するにしたがって、LBも真理値表どおりの値をとっていることが確認できる。この作業を各出力についておこない検証した。意外と合っているもの(勝利)。

 今回は命令デコーダの設計をおこなった。この調子で、次回はALUの設計をおこなう。続いて、これら2つの回路をウェハ上のレイアウト図にする。たぶんこれが一番難しい。

*1:一般的なCPUの設計論にはHDLが必須だが、論理合成のプロセスはブラックボックスになってしまう。CPUを0から作る、というコンセプトには人力論理合成の方が合っているように思える。