電卓ができるまで 第7回:同期・非同期

論理回路で電卓を作ろう

本シリーズは、論理回路で電卓を作ろうと思い、そのために勉強した結果を残しているものだ。

前回から、新しい内容である順序回路に入った。

出力を再度入力に使いまわすことにより、情報の保持ができるようになった回路だ。

その具体例として、フリップフロップという1ビットを保持する回路を4つほど紹介した。

が、色々と問題点があったと思う。

以下がその記事だ。

さて、前回どんな問題があったかと、それを解決する方法…の名前だけは簡単に紹介した。

しかし、それだけだと何がなんだかさっぱりだと思う。

そこで、今回はその部分をさらに深掘りして解説していこう

スポンサーリンク

非同期・問題点と同期

まずは軽く復習から。

前回出した4つのフリップフロップは、非同期という形で組まれていたものだ。

非同期とは常に入力や現状態を出力に反映させる方式のことで、例えば前回出した回路のいずれに対しても、入力を変化させると即時で出力も変化する。

しかし、それでは問題が発生していた。

何かというと、例えばJKフリップフロップで両入力とも1を入力した場合や、Tフリップフロップで1を入力した場合

これらは、現在の状態を反転させ、出力するという動作になっていた。

すると、最初の状態が\(Q = 0\)(\(\overline{Q} = 1\))だった場合、以下のような動きをする。

  • 現状態の反転である\(Q = 1\)(\(\overline{Q} = 0\))を出力し、それが新たな現状態となる
  • 現状態の反転である\(Q = 0\)(\(\overline{Q} = 1\))を出力し、それが新たな現状態となる
  • 現状態の反転である\(Q = 1\)(\(\overline{Q} = 0\))を出力し、それが新たな現状態となる
  • 現状態の反転である\(Q = 0\)(\(\overline{Q} = 1\))を出力し、それが新たな現状態となる
  • 以下エンドレス

ようは、1回変化すれば終わりではなく、反転させる操作を延々と繰り返してしまうのだ。

問題はこれだけではない。

JKフリップフロップで現状態を保持しているとき、入力は両方とも0だった。

ここから状態を反転させたいといった場合、両方の入力を同時に1にする必要がある。

これがわずかでもズレると、その瞬間はセットorリセットの動作となり、思った結果にならなくなってしまう

これも、入力を常に即時で反映させる非同期という組み方が問題になっていた。

これを解決するのが、同期という方法。

同期とは、本来の入力とは別にもう一つ入力を用意し、その新たな入力が特定の状態になったタイミングでの入力を出力に反映させる方法だ。

これを使えば、延々と状態を切り替える現象を1回分で抑えたり、JKフリップフロップで両方0から1に変化させた後にそのタイミングを与えてあげることで誤差による想定外な結果を防ぐことができる。

前回は文章であれこれと書いていたが、今回はこの中身を詳しく解説していこう。

クロック

同期を使った回路では、タイミングの決定にこのクロックというものを使う。

クロックとは、一定周期で0と1を繰り返し入力する信号のことだ。

これを使って、クロックが1のタイミングで出力を変化させる、というのがまず一つ思いつくだろう。

入力の記号には\(C\)や\(Clock\)をよく使うので覚えておこう。

ここで、同期のタイミングを見るのに便利なタイムチャートも紹介しておこう。

以下の図がそうだ。

JKフリップフロップのタイムチャート例

見方なのだが、基本的に左から右に向かって時間が進んでいく

各入力、出力について、0と1の変化の様子を表しているのがタイムチャートだ。

例えば、最初の状態としては両入力とも0が入力されており、出力も0となっている。

この状態でクロックが1になっても、現状態を保持だったので、何も変わらない。

次に、クロックが0に戻り、その間に\(J\)だけ1にしてみる。

すると、これはセットの意味だったので、次のクロックが立ち上がったタイミングで出力に反映され、\(Q = 1\)となる。

図には書いていないが、もちろん\(\overline{Q}\)は元々1で、このタイミングで0に変化する。

またクロックが0に戻ったら、今度は\(J\)、\(K\)両方とも0と1を入れ替える。

ここではまだ出力に反映されず、次にクロックが立ち上がったタイミングでリセット、つまり\(Q = 0\)、\(\overline{Q} = 1\)となる、という感じの見方だ。

回路の組み方も提案しておこう。

これも幾つか組み方があるが、ここでは前回出した回路を組み替えて実装してみる。

とはいえ…考え方としては、クロックが1の時のみ出力に反映させるだけ

つまり、SRフリップフロップとJKフリップフロップは入力だった部分を各入力とクロックのANDにし、DフリップフロップとTフリップフロップは前回の内容を使って組み直せばいい。

こうすれば、クロックが0の時は常に現状態を保持となるので、狙った動作になるだろう。

さて、この方法で問題が解決する…とはまだ言えない

この形式では、あくまでクロックが0の時は反映されないだけで、1である間は非同期と同じなのだ。

そのため、JKフリップフロップに両方1を入力していると…

JKフリップフロップのタイミングチャート

こんなことになってしまう。

クロックも短時間で0と1を繰り返しているが、それ以上のスピードで状態の反転が行われているため、クロックだけでは問題を防ぐことはできない。

ではどうれば問題を解決できるか。

その一つが、マスタースレーブ方式というものだ。

マスタースレーブ方式

これは、メインとなるフリップフロップの後ろに、もう一つサブのフリップフロップを用意する

メイン側がマスター、サブ側がスレーブと呼ばれている。

で、メインには通常通りクロックを、スレーブにはクロックの否定を入力することで、変化を1度だけにすることが可能だ。

Dフリップフロップを例に回路図を組んでみると、以下のようになる。

マスタースレーブ方式Dフリップフロップの論理回路図

さあ、だいぶ複雑になってきた。

が、一個一個分解して見ていけばそこまで難しくはない。

まず、入力\(D\)とその否定が入力\(Clock\)とANDで取り込まれ、その次にNORで繋がっている。

この出力が、クロックを用いた一つのDフリップフロップになっている。

で、ここまでがマスター側となり、その出力\(Q\)をスレーブ側の入力\(D\)として扱っている。

そして、スレーブ側のクロックは\(Clock\)の否定を入力、そのスレーブ側の出力を実際の出力とする。

こんな感じで、マスタースレーブ方式のフリップフロップが構成されている。

…さて、この弱点を見ておこう。

何が弱点かというと、これはクロックが1から0に変化したタイミングの値で次の状態が決定する

つまり、0から1になってから、その1である間だけ出力の変化が遅延するのだ。

それと、これは私の勉強不足なのだろうが…やはり、これでも状態の反転で発生していた問題は解決できていないように思えている

結局、マスター側ではこれまでと同じように状態の0と1が行ったり来たりする。

そのため、結局クロックが0に変化したタイミングではどうなっているか分からないのではないだろうか。

色々調べてみたが、この疑問を解消することはできなかった…

まあ、勉強記録なのと、次の方式でこれも解決できるので許してほしい。

エッジトリガ方式

先に言ってしまうと、本シリーズでは今後このエッジトリガ方式を使うので、少し細かめに解説していくことにしよう。

エッジトリガ方式とは、クロックが0から1になった瞬間、あるいは1から0になった瞬間にのみ入力を反映させる方式だ。

特に、0から1のタイミングで反映させる方ポジティブエッジトリガ1から0のタイミングで反映させる方ネガティブエッジトリガと呼ぶ。

マスタースレーブ方式も1から0になった瞬間という意味ではネガティブエッジトリガに見えるが、こちらはそもそも回路の組み方を変えてしまう。

JKフリップフロップのポジティブエッジトリガ方式で組んだ論理回路図を以下に示す。

ポジティブエッジトリガ方式JKフリップフロップの論理回路図

ここで一つ注意。

回路の真ん中くらいに二つほど、3つの入力が入っているNAND素子がある。

これは、その3入力で先にANDを取り、そのNOTを出力することを意味している。

ANDやORは先に二つを取り、もう一つを後で取っても結果が変わらなかった。

しかし、NANDは同じことをすると結果が変わってしまうので注意しよう。

言い換えると、NANDは結合法則が成り立たない

このNANDも2入力にしたい場合は単にNANDを二つ重ねるのではなく、意味通り先にANDを2回取り、結果をNOTにするという形にする必要があるので気を付けて欲しい。

さて、これまでの回路とは全然違うしかなり複雑だが…まあ、ぶっちゃけてしまうとこのあたりの同期フリップフロップはシミュレータ側で用意されていることが多いので、内部はそこまで深く気にする必要もない。

中身がそうなってるんだなぁと思いつつ、それぞれがどういうタイミングで、入力がどうなっている時にどう出力が変化するかを把握するのが一番大事だ。

そのためには、ご自身でタイムチャートを色々と書いてみるのが手っ取り早いだろう。

ただ、用意されていない場合はこのように組む必要があるので、覚えておこう。

で、気になるのは…これで問題だった反転がしっかり動作するか

これは、問題が無くなる

例えば、現状態\(Q\)が0で、クロックが0の間に入力\(J\)、\(K\)を両方1にする。

このタイミングでは出力には反映されないので、差があってもセットやリセットは行われない

次に、クロックが0から1になった瞬間、一度だけ反転され、\(Q = 1\)になる。

これも、次にまたクロックが0になり、再び1になるまではこのままだ。

次のクロックの0→1でも再度反転させたい場合は、入力を変化させずにおけば切り替わってくれる。

ここまでの内容をタイムチャートにして以下に載せておこう。

ポジティブエッジトリガ方式JKフリップフロップのタイムチャート例

問題だったのは出力がどっちになっているか分からないという点だった。

しかし、今はクロックが0から1になるごとに反転するため、しっかり出力を決定することができる

さらに、遅延についても、一応各素子を通って結果に反映されるまでの時間はかかるが…逆に言えばそれだけだ。

マスタースレーブ方式で問題になっていた、クロックが1である間だけズレることもなくなる

ということで、これまでの問題を全て解決できる形になっている。

さっきも少し書いてしまったが、今後本シリーズで同期フリップフロップを使う場合は、このポジティブエッジトリガ方式で組んでいることを仮定して進めよう

あえて非同期や他の同期の手法で使う場合は、その旨を明記するつもりだ。

私と同じくDigitalというシミュレータを使用している場合、通常の入力とクロック入力がある各フリップフロップは全てポジティブエッジトリガ方式で実装されているとドキュメントに書かれていた。

詳細は「Help」→「Components」に書かれているので、それに目を通しておくといいだろう。

他のシミュレータの場合も、あらかじめ動作を確認しておくか、ドキュメントを見て把握しておくようにしよう。

おわりに

今回は、同期式のフリップフロップについて解説した。

非同期・同期の違いや各同期回路において変化するタイミング、それぞれの問題点等は覚えておくといいだろう。

最終的に使うポジティブエッジトリガ方式の具体的な回路はJKフリップフロップしか載せていないが…SRフリップフロップは動作だけ見ればJKフリップフロップの下位互換だし、Dフリップフロップ、TフリップフロップはJKフリップフロップを使えば前回と同じ考え方で作成可能。

そのため、もう作れたとして詳細は割愛させてもらおう。

今後は、シミュレータ側で用意されているもの(ポジティブエッジトリガ方式)を使うことにする。

さて、これで情報の記憶が行えるようになったわけだ。

そこで、次回は四則演算の完成に向けて動き出そう。

具体的には、加減算は以前作成できていたので、残るは乗算除算

これらに必要な、カウンタと呼ばれる回路を次回実装しようと思う。

今回作成したポジティブエッジトリガ方式のフリップフロップも使うと思うので、動作はしっかりと把握しておこう。

2022/6/18追記

次回の内容、カウンタの記事を公開した。

一応乗算・除算回路も作成しているが…それはまた作り直すので、そんな方法もあるんだなぁ程度に見てもらえると幸いだ。

コメント

タイトルとURLをコピーしました