標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第59回]
●フラグレジスタの回路図です
8080のフラグは、S(サイン)フラグ、Z(ゼロ)フラグ、H(ハーフキャリー)フラグ、P(パリティ)フラグ、C(キャリー)フラグの5つです。
数としては5つしかありませんが、8ビットのフラグレジスタを構成します。
各フラグと、フラグレジスタのビット位置の関係は次の通りです。
bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
S | Z | - | H | - | P | - | C |
レジスタA〜Lは8ビットレジスタ74HC373を使っていますが、フラグレジスタは命令によって特定のフラグのみが変化するものがあるため、8ビット全部を一度に書き換えてしまう、8ビットレジスタは使うことができません。
そこで、フラグレジスタには、それぞれ独立して書き換えができるように、Dフリップフロップ74HC74を使いました。
74HC74のPR(プリセット)端子をアクティブ(L)にすることでフラグをセットし、CLR(クリア)端子をアクティブ(L)にすることでフラグをリセットします。
しかしPUSH命令、POP命令ではフラグをまとめてフラグレジスタとして全部同時にread/writeします。
そこでA〜Lレジスタと同じように、全部のフラグを1つのレジスタとして、同時に書き込みができるようにするために、フラグレジスタのビット位置に相当する内部データバスのビットをDフリップフロップのD入力端子にそれぞれ接続し、CK入力端子にフラグレジスタ書き込みパルス(FregWR)を入力するようにしました。
またフラグレジスタとして全部のフラグを同時に読み出すことができるように、74HC244を介して内部データバスに出力するようにしました。
74HC244のG入力端子にフラグレジスタ読み出しパルス(FregRD)を接続してあります。
FregWRは1枚目の基板のレジスタ選択回路の74HC238からの出力信号ですから、正論理(アクティブH)パルスです。
74HC74はCK入力がL→HのタイミングでD入力をラッチしますから、74HC238からの出力パルスをそのまま74HC74のCK入力にすると、パルスの立ち上がりでデータをラッチしてしまいます。
これではまずいので、書き込みパルスの終わりのタイミングでデータをラッチするようにするために、74HC04で反転させてから、CK端子に接続するようにしました。
なお、Hフラグ以外のS、Z、P、Cフラグは、条件JP命令、条件CALL命令、条件RET命令で参照されます。
そのために、Hフラグ以外のフラグ出力は、フラグがセットされていることを示す、SF、ZF、PF、CFと、フラグがリセットされていることを示す、SF_(SFの負論理出力)、ZF_、PF_、CF_も出力するようにしてあります。
●74HC74は74LS74ではなかった!
なにをいまさら…。
HC(ハイスピードCMOS)がLS(ローパワーショットキー)と違うことなど、いまさらあらためて言わなくても、このシリーズのはじめのところでちゃんとことわったはず、でした。
いや、それはそうなのですけれど、じつは74HC74は、そういう74HCと74LSの全部に共通する相違点のほかに、なんと、内部のロジック自体が違っていることに気がついたのです。
どういうことかを説明するために、それぞれの内部ロジックを比較してみます。
●74LS74の内部論理図です
(出典:モトローラ社74LS74データシート)
●74HC74の内部論理図です
(出典:フィリップス・セミコンダクター社74HC74データシート)
●74HC74の出力にはバッファがついている!
74LS74は2段のRSフリップフロップで構成されていることがわかります。
74HC74の方は、なんじゃこれは?というような、わかりにくいロジック図です。
ただなんとなく、74LS74と同じような回路かなぁ、と思えます。
しかし、大きく違っているところがありました。
74LS74はRSフリップフロップの出力がそのままQ出力端子およびQ_出力端子につながっていますが、74HC74はフリップフロップの出力と、Q出力端子およびQ_出力端子との間にインバータ(バッファ)が入っているのがわかります。
たった1個のインバータですが、このインバータが有るのと無いのとでは、Dフリップフロップの扱いが全く変わってきてしまいます。
74LS74のQおよびQ_出力端子は、内部論理図をよーく見てみると、なんと入力端子でもあるのです!
Dフリップフロップはクロックに同期してデータをラッチします。
クロック信号さえしっかりガードしておけば、ラッチしているデータがノイズなどで書き換わってしまう心配は少なくなります。
しかし、このQ、Q_出力回路は、全く無防備なRSフリップフロップの入力端子なのです。
このような出力(じつは「隠れ入力」)ラインがずっと長くのびて、はてには基板の外までそのまま出て行くとなると…!
その結果は、おおよそ見当がついてきます。
オシロで見てみると、D入力にもCK入力にもノイズは乗っていないのに、なぜかときどきDフリップフロップが反転してしまう…。
そのようなことがないように、Dフリップフロップの出力ラインが長くなるような回路では、QまたはQ_出力にバッファを入れるのが、「常識」だったのです。
もちろん私も常識にしたがって、このようにしていました。
ところが、フラグレジスタ回路の、出力に追加されたインバータの、そのわけを説明しようとして、74HC74のデータシートをダウンロードしてみたところ!
あれまぁ、もう「とおの昔に」、インバータが74HC74の中に、はいってしまっているじゃぁありませんか!
…いやぁ、こういうことになっていたとは、ほんと、全く、気がつきませんでした。
新たに74HC74を作るに際して、それまで蓄積された74LSの技術資産を受け継ぐと同時に、おそらく当時の回路技術者たちによって指摘されていたであろう、74LS74の弱点が、IC内部で出力にバッファをつける、という形で改良されたのではないか、と想像されます。
普段私たちが気がつかないでいる、このような目立たないところにも、先輩技術者たちの創意と工夫が生かされているのだ、とあらためて実感いたしました。
[第59回]のはじめの部分からここまで、9月7日に大幅に加筆するとともに、回路図を訂正いたしました。
●INR、DCR命令の回路図です
INRとDCRはup/downカウンタにupカウントさせるかdownカウントさせるかの違いがあるだけで、回路は全く同じです。
INRは74HC191をupカウントさせ、DCRはdownカウントさせます。
74HC191はpin5入力がLのときにupカウントし、Hのときにdownカウントします。
INRの命令コードは、00ddd100 で、DCRは、00ddd101 です。
ちょうど都合良く、74HC191のbit5に与えるH、L(1、0と同じ)と、OPコードのbit0の1、0がup(INR)、down(DCR)に一致します。
そこで、OP0をそのままINRレジスタのpin5(d/u端子)に与えることにして、そのほかの回路はINRとDCRで共通にしました。
回路図だけではわかりにくいと思います。
いつものようにタイミングチャートを見ながら説明をします。
●INR/DCR命令のタイミングチャートです
INR、DCRはA、B、C、D、H、Lの値を+1、−1しますが、ddd=110のときは、HLレジスタで示すメモリアドレスの値を+1、−1します。
対象がレジスタであるときと、メモリであるときとで、出力する信号は異なりますから、タイミングチャートはそれぞれの場合に分けて表示しました。
しかし、以前にMOV命令の回路で説明した、MEMRD、MEMWRの回路の工夫([第45回])によって、INR、DCR命令の回路としては、対象がレジスタであっても、メモリであっても、同じ回路で済みます。
INR、DCR命令のタイミングチャートを見ていきましょう。
T4サイクルで、レジスタまたはメモリから、up/downカウンタ(74HC191、INRreg)に値をロードします。
up/downカウンタを+1または−1するために、次のT5サイクルにINRregCLKを出力します。このパルスは74HC191のpin14(CLK入力)に入れられます。
次のT6、T7サイクルで、+1または−1された値をもとのレジスタ、カウンタに戻します。
タイミングチャートにはありませんが、最後のT6サイクルのときに、SフラグとZフラグおよびHフラグをセット、リセットするために、SFenblとZFenbl、INRHFenblを出力します(回路図で見ると下の方に、そのための信号出力回路があります)。
タイミングチャートを見ながら、あらためて回路図を見てみると、そのままの当たり前の回路であることがわかると思います。
CPU回路などというと、なんだかすごい回路のように思えますが、こうして整理してみると、実に簡単な回路なのです。
2008.9.6upload
2008.9.7加筆、修正
前へ
次へ
ホームページトップへ戻る