標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第40回]

●回路図を差し替えました

前回、プログラムカウンタの回路図をお見せしましたが、あとで古い回路図をUPしてしまったことに気がつきました。
当初はプログラムカウンタに74HC191を使うように設計していたのですが、後で74HC191にはCLR端子が無いことに気がついたため、74HC193に変更しました([第12回]参照)。
ところがこのときに、説明のために、ホームページ用のフォルダに移動しておいたプログラムカウンタの旧回路図を、うっかりそのままUPLOADしてしまいました。
回路図が違っていることにさきほど気がつきましたので、急いでホンモノの回路図と差し替えました。
以上、ご報告です。

●本日はいよいよ、MOV命令、MVI命令、HLT命令の回路の説明です(でも本日だけではとても終わりません)

いよいよ命令実行回路の説明です。
回路図をお見せする前に、マシン語命令コードについて、説明をします。

●MOV命令のマシン語コード

MOV命令のマシン語コードは
01dddsss
です。

ddd、sssはレジスタ、メモリを示す3ビットのコードで、それぞれ000〜111の8通りがあります。
3ビットのコードとレジスタ(メモリ)との対応は以下の通りです。

000 Bレジスタ
001 Cレジスタ
010 Dレジスタ
011 Eレジスタ
100 Hレジスタ
101 Lレジスタ
110 M(HLレジスタによって間接的に示されるメモリアドレス)
111 Aレジスタ

sssはデータを読み出す方のレジスタ(またはメモリ)であることを示し、dddはデータを書き込む方のレジスタであることを示しています。
sssはsource(出所、原因)から来ていると思われます。dddはdestination(目的、行き先)から来ていると思われます。

たとえば、
01001000 は
アセンブラニーモニックでは、MOV C,B と表記され、Bレジスタの値をCレジスタに送る命令になります。
このとき、もとになるBレジスタの値は変わりません。
その意味ではMOV(Move)よりもCOPYの方が動作をより正確に表現しているように思えますが、どういうわけか、CPUが異なっていても、アセンブラ命令ではMoveを使うのが一般的のようです。

dddとsssに同じレジスタを指定しても、エラーにはならず、その通りに実行されます。
たとえば、
01000000 は
アセンブラでは MOV B,B と表記され、BレジスタからBレジスタにデータを送る、という命令になります。
実際にそのように動作しますが、結局、何も変わらないので、NOP(No Operation)命令と同じことになります。

ただし、例外があります。

●HLT命令

01110110 は、
MOV M,M ではなくて、HLT命令になります。HLT命令はHalt(停止、ストップ)命令です。

●MVI命令のマシン語コード

MVI命令は、Move Immediateの略語からきたニーモニックで、Immediateは、直接の、すぐ近くの、ただちに、というような意味です。
命令コードに続く8ビットのデータ(命令コードのすぐ次のメモリアドレスにあるデータ)を、指定するレジスタに書き込みます。

MVI命令のマシン語命令コードはMOV命令のマシン語コードとは別のものなのですが、動作そのものは、よく似ていますので、一緒にまとめて回路設計をしました。

MVI命令のマシン語コードは
00ddd110
です。

上位2ビットがMOVでは01だったのが、MVIでは00になります。
dddはMOVと同じ位置にあって、意味も同じです。dddで示されるレジスタ(メモリ)にデータを書き込みます。
そのデータはMVI命令の書かれているメモリアドレスの、すぐ次のメモリアドレスにあるデータです。

メモリアドレスにあるデータには違いありませんから、MOVでsssにしていた位置にメモリアドレスを示すコードの110を置いた、ように思われます。
あるいはCPU回路の設計上、そのようにすることに意味があったのかも知れません。
私の描いた回路では、ここが110になっていても、何の得にもなりませんでした(でもないか。デコードが少し楽でした)。

●MVI命令の動作

MVI命令の動作を、たとえばメモリの0010番地に命令コードがあったとして、

0001 ………
0010 00101110
0011 01010000
0100 ………

のような場合で説明してみます。

0010番地にはddd=101のMVI命令コードがあります。ddd=101はLレジスタです。
次のメモリアドレス、0011番地には、01010000というデータがあります。
このとき、この命令コードは、
命令コードのある0010番地の次のメモリアドレス、0011番地のデータ01010000を読み込んで、Lレジスタに書き込みなさい
という意味になります。
この命令を実行すると、Lレジスタに01010000が書き込まれます。

これをニーモニックで表現すると
MVI L,50
になります。

●さて、MOV、HLT、MVI命令の回路図です



自分で描いておいて、言うのもなになのですけれど、これは、すごい回路です(ほんとに、すごい回路になってしまいました)。
どうしてこんなすごい回路になってしまうか、と言いますと、MOVの対象に、レジスタだけではなくてメモリがあるためです。

レジスタに対するMOV回路とメモリに対するMOV回路は、同じというわけにはいきません。
しかもそのメモリが、dddの側にあるときと、sssの側にあるときとで、また動作が分かれてしまいます。
そこへもってきて、MVIまで一緒にしてしまったので、余計にすごいことになってしまいました。
そこに、さらにHLT命令が加わります。

こんなの、見ても、全くわかんないよー、という声が聞こえてきそうです。
でもね、こんなのを、実際に描いて、そして実際に配線しているのですよ。
まあ、正気の沙汰ではない、かも知れませんね。

そこで、いつものように、わかりやすく、回路を分解してみることにしましょう。

●まずは、MOV r,r’の回路図です

MOV命令の中で一番シンプルな、レジスタとレジスタの組み合わせです。
dddもsssもレジスタだけで、メモリは対象にしません。
つまり、ddd≠110で、かつsss≠110です。



なんだか急にすっきりしてしまいました。
タイミングチャートを見ながら説明をしていきます。

●MOV r,r’のタイミングチャートです



前回説明したOPコードフェッチサイクル(T0〜T3)は、どの命令でも同じなので省いてあります。
ですから命令の実行部分のタイミングチャートは、T4から始まります。

なんだかすごく簡単です。
これで本当にMOV命令が実行されてしまうのか?と疑問に思ってしまうくらいです。
でも、回路に工夫がしてあるので、これでデータのレジスタ間Moveができてしまいます。

d0〜d2、s0〜s2はOPコードレジスタにラッチした命令コードそのままです。
この信号によってデータを送り出す側のレジスタと、そのデータを受ける側のレジスタがともに選択されます。
d0〜d2、s0〜s2はタイミングの制約は受けず、OPコードが有効な限りラインに出力されています。

s0〜s2とregRD信号が組み合わさることで、選択されたレジスタのデータが内部バスに出力されます。
d0〜d2とregWR信号が組み合わさることで、選択されたレジスタに内部バス上のデータが書き込まれます。

すると、やっぱりレジスタ選択回路が必要になってしまいますね。
あっと、レジスタ選択回路は[第27回](●レジスタ選択回路)ですでにご紹介済みでした。動作説明もしておりましたので、そちらももう一度ご参照願います。
あれまあ、MOV命令や、sss、dddについてもしっかり説明しておりましたですねぇ([第27回]●s0〜s3、d0〜d3)。

うーん。レジスタ回路についてもすでにご紹介済みでした([第23回]●レジスタの回路図です。A、B、C、D、Eの各レジスタです)。
こちらについても、もう一度ご参照願います(H、Lレジスタの回路図はこちらです)。
なんだか、計画性ゼロであちこちに思いつきで回路図をUPしてしまったものですから、お手数をおかけして申し訳ありません。あちこち見て回っていただきますよう、お願いいたします。

●MOV r,r’回路の説明です

さて、以上の説明をまとめると、要するに、MOV r,r’は、OPコードレジスタの出力のビット0〜2をs0〜s2に与え、ビット3〜5をd0〜d2に与えた上で、M2の期間regRDをアクティブ(L)にして、そしてT4の期間regWRをアクティブ(L)にすればよいことがわかります。
そこで、もう一度MOV r,r’の回路図を見てみましょう。

MOV命令であることは、OPコードレジスタからの出力の上位2ビットOP7、OP6だけで決定できます。
OP7=0、OP6=1を、74HC04(3)と74HC08(1)で検出しています。
その後ろの74HC08(1)、74HC08(3)の2つのゲートでddd≠110およびsss≠110である場合のみを検出しています。
この条件のときだけ、M2の期間、regRDがLになり、T4の期間、regWRがLになります。

s0〜s2、d0〜d2はいつもOPコードのビット0〜5と連動してもらっては困るので、MOV命令のときだけ、そのようになるように、74HC126でゲートしたのち出力しています。
以上説明した通り、これだけの回路で、ちゃんと、レジスタからレジスタへのデータ転送が行われます。

●どうして、regRDはM2で、regWRはT4なのでしょう?

これは、確実に動作するための工夫なのです。
もう一度よくMOV r,r’のタイミングチャートを見てください。
regRDはM2の期間Lになります。
このregRD信号とs0〜s2によって、レジスタ選択回路の74HC138から、M2の期間Lになるパルスが出力され、そのLパルスは、選択されたレジスタのデータを内部バスに出力するための74HC244のpin1とpin19に入力されます。
74HC244はpin1とpin19にLが入力されている間、データを通します(その間だけレジスタのデータが内部バスに出力される)。
ということは、T4の開始とほぼ同時にデータが内部バスに出てくることを意味します(でもゲートの遅れ時間だけ遅延して出力されます)。

regWRもT4の開始と同時にLになります。
regWR信号は、d0〜d2とともにレジスタ選択回路の74HC238に入力され、その結果、選択されたレジスタへの書き込みパルス(Hパルス)が、74HC238から出力されます。
T4の期間Hになる74HC238からの出力パルスは、選択されたレジスタの74HC373のpin11(G)に入力されます。

74HC373はG入力がHの期間中、データが筒抜けになり、G=Lになった瞬間に、そのときの入力データをラッチします。
ということは、74HC373が内部バスのデータをラッチするのは、T4の終わり(の一瞬)だということになります。

T4の始めに内部バスに出てくるデータをT4の終わりにラッチするのですから、ほぼT4の期間と同じ時間(250ns)の余裕があるということになります。
これで、誤動作などしたら、それこそ「うそでしょう」ということになります。

それならば、regWRをT5に持っていったら、もっとマージンが稼げるではないか、というと、それがそうではないのです。
今度はregRDの終わりが問題になります。

regRDはT5の終わりに非アクティブになります。
ということは、T5の終わりには、内部バスに出力されていたデータが不確定になってくることを意味します。

しかし、T5の期間をregWRに当てると、74HC373のデータをラッチするタイミングもデータが不確定になるのと同じT5の終わりになってしまうため、マージンが0で、場合によってはデータが書き込まれずに終わってしまったり、変なデータが書かれてしまう可能性がでてきます。

もう一度、さきほどのregWRがT4である場合に戻って、regRDの終わりについても見てみましょう。
74HC373がデータをラッチするのはT4の終わり(ということはT5の始めでもある)です。データが不確定になるT5の終わりまでは、やはり250nsの余裕があることになります。

ですから、ちょっと見には、regWRが前の方に寄っているため、おかしな感じがしますが、regWRとしてはこのタイミングが正解なのです(このタイミングこそが、best choiceです)。

●Mclrっていったい何者?

さて、MOV r,r’の回路図タイミングチャートには、T6のタイミングでMclrという信号が出力されています。
これはいったい何者なのでしょうか?
これこそが「つくるCPU」回路のキモ中のキモのそのまたキモというくらい、肝心カナメのものなのです。

Mclrはいったいどこに作用しているか、といいますと、
ここに行くのです。

前回お見せした、T、M、Wクロック発生回路のおおもとの、バイナリカウンタ74HC161のpin1(RES)の入力信号(および74HC74のpin13、CLRへの入力信号)なのです。
ここをLにすると、一瞬にしてQa〜Qeの出力は0クリアされて、T0のタイミングに戻ってしまいます。
タイミングチャートでは幅があるように描いてありますが、ほとんど幅はありません(せいぜい20〜30nsくらいです)。

Mclrは、命令の終わりの印なのです。
Mclrの出力によって、命令のサイクルが完了し、またOPコードフェッチサイクルに戻るので、そのようにして、次々に命令を読み込んで実行していくことが可能になるのです。

逆にいうと、もしMclr信号が無かったならば、次の命令を読み込むOPコードフェッチサイクルは、ずっと先にカウンタの出力が一巡してしまい、また0に戻ってくるまで、待っていなければならないということになります。
Mclr信号こそが、肝心カナメである、という所以(ゆえん)です。
2008.8.18upload

前へ
次へ
ホームページトップへ戻る