JKフリップフロップという便利な回路素子があります。 日本語で「JKフリップフロップ」と検索すると、多くの場合、それと異なるJKラッチの説明が出てきて混乱しがちです(JKラッチは便利ではないので使うことはあまりないと思います)。 これを整理するのがこの記事の目的です。
ラッチとフリップフロップ
ラッチやフリップフロップは、1ビットの情報が記憶できる素子で、順序回路を構成するために欠かせない基本素子です。 その名称の使い分けには三種類の流儀があります。 一つの流儀を一貫して使えばよいのですが、複数種類の流儀を混ぜると意味不明になります。 フリップフロップ - Wikipediaやラッチ回路 - Wikipediaはいろいろな流儀のものを寄せ集めて作ったのか、流儀が混在していて、それが原因で混乱が生じています。
| 制御信号のないもの | レベルセンシティブな(=Enable信号が1の時のみ透過になる)もの | エッジトリガな(=Clock信号のエッジでのみ出力が変化する)もの | |
|---|---|---|---|
| 流儀1 | セット・リセットタイプのラッチ | トランスペアレントタイプのラッチ | エッジトリガタイプのラッチ |
| 流儀2 | 非同期式フリップフロップ | 非同期式フリップフロップ | 同期式フリップフロップ |
| 流儀3 | ラッチ | ゲート付きラッチ | フリップフロップ |
| 例 | SRラッチ、S̄R̄ラッチ、JKラッチ | ゲート付きSRラッチ、ゲート付きDラッチ、ゲート付きJKラッチ | Dフリップフロップ、JKフリップフロップ |
本記事では順序回路 - WikipediaやFlip-flop (electronics) - Wikipediaで採用されている流儀3を使用していきます。
(セット・リセットタイプの)ラッチ
SRラッチ
最も基本的なラッチに、NORゲート二つを使ったSRラッチがあります。 SRラッチは、SとRという二つの入力と、QとQ̄という二つの出力を持ちます(Q̄はない場合もあるかもしれません)。 配線は、次の図のようになっています(引用元:File:RS Flip-flop (NOR).svg - Wikimedia Commons)。 上側のNORゲートはRとQ̄を入力としてその出力がQになります。 下側のNORゲートはSとQを入力としてその出力がQ̄になります。 このように、出力が入力に戻されるような、循環的な構造を持つことで情報を記憶します。

SRラッチと呼ばれる理由は、片方の端子がSet(出力Qを1にする)、もう片方の端子がReset(出力Qを0にする)というわかりやすい意味を持つからです。 SとRが共に0の時、QとQ̄の値が現状維持となります。
動作例として、例えばQが1、Rが0で、Sが1である状況を考えます。 この時、下側のNORゲートの出力Q̄は、Qが1かつSが1なので0になります。 そして、上側のNORゲートの出力Qは、Rが0かつQ̄が0なので1になります。 このようにSRラッチ回路には循環がありますが、同じところに戻ってくるまでにNOT的な素子を二回通るようになっていて、循環が整合的に閉じているので発振しません(後述のメタステーブル状態になった場合を除く)。
この状態でSを0に変化させたとします。 この時、下側のNORゲートの出力Q̄は、Sが0であってもQが1なので0になります。 上側のNORゲートは、先ほどと入力が変わっていないので出力も同じで、出力Qは1になります。
下側のNORゲートの出力Q̄が0になる原因をたどってみると、Qが1であることが原因で、そしてそれはQ̄が0であることが原因です。 ここでQ̄が0になった原因を考えてみると、いつかの時点でSが1になったことが原因のはずです。
Sを1にすることはQを1にする効果がありますが、その後にSを0にしてもQは1のままです。 つまり、Qが1であるというのは、「以前にSが1になったことがある」という意味を持つ出力であり、この意味において情報を記憶する能力を持っています。
同様のことはRについても言えます。 RはSと逆に、Qを0にする効果を持ちます。 したがってより正確には、Qが1であるというのは「以前Rが1になった時よりも後に、Sが1になったことがある」を、Qが0であるというのは「以前Sが1になった時よりも後に、Rが1になったことがある」を、それぞれ意味します。
Sを1にすることは電池への充電、Rを1にすることは電池の放電、と考えるとわかりやすいかもしれません。 電池を充電しきった後、充電をやめても電池は充電された状態のままです。 電池を放電しきった後、放電をやめても電池は放電された状態のままです。 そして電池の今の状態は、充電と放電のどちらを最後に行ったかによります。
禁止入力(S,R)=(1,1)について
SRラッチにおいて、SとRをともに1にすることは禁止と言われます。 これは電池のアナロジーからも明らかで、充電しながら放電もするというのはおかしな話です。 NORゲート二つからなるSRラッチの場合には、ハードウェアが壊れるわけではありませんが、QもQ̄も0になってしまい、相補性(QとQ̄が常に異なる性質)が破れます。 この状態を積極的に活用することで回路が小さくなるみたいな曲芸がありますが、あまりやるべきではなさそうです。
他の用途としては早押し検出回路があります。 SとRがともに1の状態からともに0の状態に移行させようとしたとき、ふつうはSとRが変化するタイミングが完全に同一とはいかず、ほんのわずかな時間差があるはずです。 すると、(S,R)=(1,0)である瞬間か(S,R)=(0,1)である瞬間のどちらか一方があるはずです。 SRラッチはそれを見逃さず、前者であれば「以前Rが1になった時よりも後に、Sが1になったことがある」を示すQ=1を、後者であれば「以前Sが1になった時よりも後に、Rが1になったことがある」を示すQ=0を、それぞれ出力するようになります。
ただし、本当にほぼ同一タイミング、あるいはゲート遅延程度の時間差しかないような場合、相当長い時間出力が安定しなくなるメタステーブル状態になることがあります。 (S,R)=(1,1)が禁止入力と言われる背景には、潜在的にこのような問題を抱えることもあります。 なお、論理回路シミュレータだと循環を通して互いを追いかけるように状態が更新され続けるような挙動になったりしますが、実際の信号がそういう感じとは限りません。
S̄R̄ラッチ
NORゲートの代わりにNANDゲートを使って同じようなものを作ると、Qを1にしたいときには入力Aを0にする必要があり、Qを0にしたいときには入力Bを0にする必要があるようなラッチができます。 つまり、入力が負論理(何かをしたいときに信号を1にするのではなく、何かをしたいときに信号を0にする必要がある)になっています。 入力AはQを1にするというSet操作を負論理で行うためS̄と、入力BはQを0にするというReset操作を負論理で行うためR̄と、それぞれ呼ばれます。 この二つをとって、S̄R̄ラッチと呼ばれます。 配線は以下のようになっています(引用元:File:SR Flip-flop Diagram.svg - Wikimedia Commons)。

ちなみに、S̄R̄ラッチの禁止入力は(S̄,R̄)=(0,0)ですが、この時の出力はSRラッチと異なり(Q,Q̄)=(1,1)になります。 (S,R)=(1,1)が禁止入力であると言われる背景には、このように、中身をどう構成したかによって禁止入力に対する出力が変わってしまうことも挙げられます。
JKラッチ
SRラッチで禁止入力であった(S,R)=(1,1)に対して、出力を反転させるといった機能を割り当てたものがJKラッチです。 端子の名前はリセットする方をK、セットする方をJと呼んでいます。 端子の名前は、SRラッチの発展版がJKラッチであることと順番が対応していることから、Set→J、Reset→Kと覚えればよいです。 あるいは、0にする方=killする方がKだと覚えればよいです。
JKラッチは単独では役に立ちません。 出力を反転させるという機能が直感的で回路を組むうえで便利だということ自体は正しい説明です。 しかしながら、JKラッチは(J,K)=(1,1)とした瞬間に出力が反転し続けます(発振します)。 つまり元の状態を「1回だけ」反転させる、という機能は実現できません。

回路図はエレキ素人が何か考える(その9):JKフリップフロップ #電子回路 - Qiitaを参考にして自分で描きました。
ゲート付きラッチ
単なるラッチは、入力信号が変化するとそれがすぐに出力に反映されてしまいます。 組み合わせ論理回路を適当に設計すると変なグリッチが立ったりしてしまうことがありますが、その際に意図せず記憶した情報が失われてしまうことにつながります。
ゲート付きラッチは、「入力の変化を反映させる」意味を持つEnable信号を明示的に持ちます。 この信号が0の時には、SやR(S̄・R̄・J・K)がどのように変わっても出力は変わりません。 この信号が1の時には、従来のラッチと同様に動作します。 このEnable信号をうまく使うと、以下のようにすることができて、意図しない情報消失を防げます。
- 計算期間。Enable信号を0にしておく。S入力やR入力につながる前段の組み合わせ論理回路でグリッチが立っても、Enableが0なので出力は変わらず、データの消失は起こらない。
- 更新期間。Enable信号を1にしておく。計算済みのS入力やR入力が取り込まれ、記憶状態が更新される。計算期間を十分長くとっておけば、更新期間中にグリッチが立つことはないはず。必要であれば(S,R)=(0,0)などとして記憶状態を維持することも可能。
ゲート付きラッチの作り方(ゲート付きSRラッチを例に)
ゲート付きラッチを作るのは簡単です。 S入力やR入力などにEnable信号とのANDゲートを追加するだけです。 例えば、ゲート付きSRラッチの回路図は以下のようになります(引用元:File:SR (Clocked) Flip-flop Diagram.svg - Wikimedia Commons)。

(ゲート付き)Dラッチ
次の回路はゲート付きDラッチです(引用元:File:D-type Transparent Latch (NOR).svg - Wikimedia Commons)。 ゲート付きDラッチは、単にDラッチと呼ばれることが多いです(“ゲートなし”のDラッチはデータの保持ができなくて、記憶素子として役に立たないためです)。 この回路は、Enableが0の時はデータを保持、Enableが1の時は入力をそのまま出力、といった動作をします。 SRラッチが「1に変える」「0に変える」といった入力を持つのに対して、「入力をそのまま記憶する」という直感的な動作をする点がうれしいです。

出力を再利用するみたいな匠の技を使うと、以下のように作れるようです(引用元:File:D-Type Transparent Latch.svg - Wikimedia Commons)。

ゲート付きDラッチの回路シンボルは、Dフリップフロップと似たようなものが使われることもありますが、明示的に区別するために以下のようなものをよく見かけます。

回路図記号は私がhttps://infoscience.epfl.ch/record/178151/files/scm.pdfを参考にして自分で描きました。
この記号の出典はよくわかりませんでした。 standard cell-based memoryの論文でしか見かけないので、その分野に特有の記法なのかもしれません。 とはいえWikimedia commonsを見ると、手書きで「]」記号を使っている図(File:D latch flip-flop functional symbol.png - Wikimedia Commons・File:D master-slave flip-flop circuit.png - Wikimedia Commons)や、「)」記号を使っている図(File:Flip-flop synchronization types schematic.svg - Wikimedia Commons)を見つけることができました。 何かのツールで使われている記法が自然と広まっただけで標準化された記法ではないとかでしょうか。
ゲート付きJKラッチ
次の回路はゲート付きJKラッチです。

ゲート付きJKラッチは次のようにも作れます。 後段のNORをNANDに変えたので、SRラッチからS̄R̄ラッチに変わりました。 それに伴い、上下が反転しました(JとKが入れ替わりました)。 SとRではなくS̄とR̄になったので、前段はANDではなくNANDになりました。

Enable信号はクロックではない
これらの回路のEnable信号(ゲート信号)はフリップフロップのクロック信号とは性質が大きく異なります。 Enable信号はあくまで、入力(S・R・J・K・Dなど)の情報を後ろに通す通さないかを制御する信号です。 ゲート付きJKラッチは、(J,K)=(1,1)の時にEnable信号を1にしている間中ずっと出力が反転し続けるため、役に立つよう設計するためには工夫が必要です。 これに対してクロック信号を持つJKフリップフロップは、(J,K)=(1,1)の時、クロック信号の立ち上がり(または立ち下がり)の瞬間に一度だけ出力が反転するため、直感的に扱いやすいです。
そもそも、Enable信号が1の間は結局のところ、入力が素通しです。 ラッチの記憶状態が更新された時、その出力は先につながる組み合わせ論理回路に入力されますが、その計算結果がラッチの入力に戻ってくることがあります。 クロックに同期した回路のいいところはそういうことが起こらないことです。 そういったことが発生しうるということを明確にするためにも、ラッチ回路におけるゲート信号をクロックと呼ぶのはやめたほうがいいでしょう。
多くの日本語文献で混乱が見られるのは、JKラッチのことを流儀2でJKフリップフロップと呼びつつ、しかもEnable信号のことをクロック信号と呼んでいることに起因します。 これにより見た目上、流儀3の意味でのJKフリップフロップ(クロック信号がある)と区別がつかず、混乱が生じているようです。 流儀を明確にする・回路図を示す・Enableと呼び分ける、などで違いを明確にできるので、この記事ではそのようにしています。
Dラッチがデータを“ラッチする”様子
ゲート付きラッチ、特にDラッチにデータを覚えさせることを、(データを)“ラッチする”と言ったりします。 Enableが1から0になる(=扉が閉まる)瞬間のデータを挟んで落とさないようにするようなイメージです。 次に新たにデータを覚えようとする場合、「Enableが1から0になる瞬間のデータを覚える」わけですから一旦Enableを1に戻す必要があり、この時には挟んでいたデータを落としてしまいます。 このイメージをアニメーションにしてみました。

Enableが1の場合は素通しで、Enableが0の時はDを無視して現状維持、という動作が確認できると思います。
パルスラッチ
ゲート付きラッチのEnable信号に、(0と1が一定周期で交代するようなクロック信号ではなく)一瞬だけ1になり他の時間はずっと0であるような信号を入れることで、上記の問題を解決することができます。 このような構成をパルスラッチと呼ぶことがあります。 ラッチはフリップフロップよりも小さく高速であるなどの利点がありますが、タイミング制約が厳しくなるなどの欠点もあり、素直にフリップフロップを使う設計が人気だそうです(参考:ウェスト&ハリス CMOS VLSI回路設計 応用編 丸善出版 (2014) p.556)。
マスタースレーブ型構成のフリップフロップ
パルスラッチのようなことをしなくても、うまく回路を作ることで、クロック信号の立ち上がり(または立ち下がり)の瞬間のみで記憶状態が変わるようにすることができます。 そのような方法の一つに、マスタースレーブ型構成があります。 マスタースレーブ型構成では、ゲート付きラッチを直列に二つ並べます。 以下、ゲート付きラッチのことを単にラッチと呼びます。 前段(入力側)のラッチをマスターラッチ、後段(出力側)のラッチをスレーブラッチと呼ぶようです。 ここで、二つのラッチは互いに反転した信号をEnable信号として受け取るようにします。
このようにすると、入力が出力に素通しになることがなくなり、前述の問題が解決されます。 動作を順番に見ていきます。 マスターラッチがEnableの時、スレーブラッチはEnableではありません。 したがって、マスターラッチが素通しでも、スレーブラッチは現在の出力をそのまま続けます。 ここでクロックが変化すると、スレーブラッチがEnableで、マスターラッチがEnableでない状態に変わります。 この時スレーブラッチの状態が更新されます。 その後スレーブラッチは素通し状態になりますが、スレーブラッチの入力を作っているマスターラッチの出力は変化しないので、出力は固定されます。 その後クロックが再度変化すると、マスターラッチがEnableでスレーブラッチがEnableでない状態に戻ります。 この時、スレーブラッチの出力が固定されるので、やはり出力はそのままです。 このように二つのゲート付きラッチを、同時に開かない二重扉のごとく使うことで、入力の素通しを防ぎます。 このような構成は、マスターラッチがEnableでなくなった瞬間の入力を切り取って、それを一度だけ状態更新に使うような動作をします。
具体的な回路図をいくつか紹介します。
Dフリップフロップ
次の回路図は、Dラッチを二つ直列並べることで作ったDフリップフロップです(引用元:File:D-Type Flip-flop Diagram.svg - Wikimedia Commons)。 このDフリップフロップは、クロックが立ち上がった瞬間のD入力の値を、次にクロックが立ち上がるまでの間出力し続けます。

以下のアニメーションを見ると、二重扉を使って入力の素通しを防いでいること、マスターラッチの扉が閉まるタイミングのみで出力Qが変わるようになっていることがわかると思います。

Dフリップフロップの回路図記号は、以下のようなものが使われることが多いです。

回路図記号は私がhttps://infoscience.epfl.ch/record/178151/files/scm.pdfを参考にして自分で描きました。
JKフリップフロップ
次の回路図は、役に立つJKフリップフロップの回路図です。 ゲート付きJKラッチを前段に、ゲート付きS̄R̄ラッチを後段に、それぞれ配置して作っています。 ここで、ゲート付きJKラッチは「QやQ̄をフィードバックする」という本質部分を抜き出す形で採用している点に注意してください。 単にゲート付きJKラッチをゲート付きS̄R̄ラッチの前に配置するだけだとJKラッチ部分が発振する問題が解消されないのでダメです。

回路図はJKフリップフロップ - 電気主任技術者のナレッジノートを参考にして自分で描きました。
汎用ロジックICに入っているフリップフロップ
上記のマスタースレーブ構成はたくさんの素子が必要なため(でしょうか?)、汎用ロジックICの中にはより洗練された構成のフリップフロップが実装されています。
次の回路図は、汎用ロジックICに入っているDフリップフロップの回路を簡略化したものです。 S̄R̄ラッチの各入力の前にそれぞれS̄R̄ラッチがついていて、なんだか入力を整える働きをしているようです。 しかしながら回路構成がかなり非対称であり、しかもS̄R̄ラッチの禁止入力である(S̄,R̄)=(0,0)を有効利用することで後段のS̄R̄ラッチの保持入力(S̄,R̄)=(1,1)を作っているなど非常に技巧的な構成で、なぜこれでいいのかを直感的に説明できるような構成にはなっていません。 一体どうやったらこのような回路を思いつけるのでしょうか……。

同様の技巧的な構成はJKフリップフロップにも応用できて、以下のような対称な形の回路になるようです。

回路図はhttps://ocw.u-tokyo.ac.jp/lecture_files/engin_04/7/notes/ja/07.pdfを参考にして自分で描きました。
汎用ロジックICに入っているJKフリップフロップの回路はこれとはちょっと違うようです。 四角で囲った部分はいずれもラッチになっていません。

回路図はTEXAS INSTRUMENTS社のデータシートを参考にして自分で描きました。
動作を確認してみます。
Clockが0の時、NANDゲートが常に1を出力しているため、外側のANDゲート経由で循環ができています(内側のANDゲートは常に0を出力していて循環に影響しません)。 Clockが0から1になる瞬間、外側のANDゲート経由の循環が途切れる前に内側のANDゲート経由の循環が完成します。 外側のAND経由の循環が途切れるまでにはNANDゲート一段分の遅延が存在するため、その短い時間を使ってバトンタッチが行われるのです。 これに加えて、残り2つのANDゲートのうちどちらか一方も循環に貢献します。 Qが0の場合、下のNANDは1を出力するため、下のANDゲート経由の循環が存在します。 Qが1の場合、上のNANDは1を出力するため、上のANDゲート経由の循環が存在します。
Clockが1から0になる瞬間が状態更新のタイミングです。 Clockが1から0になる瞬間は、内側のANDゲート経由の循環がまず先に途切れ、NANDゲート一段分の遅延の後、外側のANDゲート経由の循環が成立します。 この隙間が状態の更新の鍵です。 外側のANDゲート経由の循環が最初から成立している場合はバトンタッチできますが、そうでない場合にはバトンタッチに失敗します。
まず、(J,K)=(0,0)を考えます。 この場合、NANDゲートの出力はClock信号にかかわらず1であり、常に外側のANDゲート経由の循環が成立しています。 よって、Clockが1から0になるときも正しくバトンタッチが行われ、状態が保持されます。
次に、(J,K)=(0,1)を考えます。 まず、上のNANDゲートは1を出力しているため、上のANDゲート経由の循環は成立しています。 また、もともとQ=0であれば、下のANDゲート経由の循環はすでに成立しています。 よって、Q=0の場合は、状態は保持されます。 Q=1の場合、その情報を保持するための循環がNANDゲート一段分の遅延時間の間、完全に途切れます。 K=1により下のANDゲート経由の循環が有効になっていないためです。 これによりQ̄が1となり、上のANDゲート経由の循環を通じてQが0になります。
(J,K)=(1,0)の場合はこれと対称なので省略します。
最後に(J,K)=(1,1)を考えます。 もともとQ=1の時は、各素子の出力は(J,K)=(0,1)の時と同じであり、Q=1を伝える循環が一瞬途切れることにより状態がトグルされます。 もともとQ=0の時は、各素子の出力が(J,K)=(1,0)の時と同じであり、Q̄=1を伝える循環が一瞬途切れることにより状態がトグルされます。
ゲート一段分の遅延を有効利用してバトンタッチしたり、逆にそれにより生じるハザードを利用してバトンを落とさせて状態を更新したりする、賢い構成になっていることがわかりました。
CMOS VLSIで使われているフリップフロップ
LSI(CPUとか)で使われているDフリップフロップは以下のような、トランスミッションゲートを使用した回路になっているらしいです(transmission-gate flip-flop, TGFF)。

回路図はhttps://onlinelibrary.wiley.com/doi/10.1155/2016/8268917を参考にして自分で描きました。 実際には入出力を安定させるために追加のNOTゲートをDの後とQの前に入れるのが一般的なようです。
この図のうち、青い四角でくくった部分はトランスミッションゲート、黄色い四角で囲った部分はNOTゲートです。 緑の四角で囲った部分は見慣れない構成ですが、点線部分があればNOTゲートとトランスミッションゲートの組み合わせになっています。 点線がない場合は、クロックトトライステート/クロックトCMOS/C²MOSなどと呼ばれる素子になります(参考:ウェスト&ハリス CMOS VLSI回路設計 応用編 丸善出版 (2014) p.541)。 この点線部分はあってもなくても論理的な動作には影響がありませんが、タイミング・面積・電力消費等に利点欠点があるため、点線がある構成とない構成の両方を見かけます。 この構成はマスタースレーブ構成ですが、通過可能・通過不能を直接実現するトランスミッションゲートを使うことでトランジスタ数を大幅に減らしています。
この構成は他の構成と大きく異なりますが、非常に直感的な設計になっています。 advanced-computer-organization/aco-shioya-02.pdf at master · shioyadan/advanced-computer-organization · GitHubの52ページに書いてあるような回路をそのままCMOS回路に落とし込んだものです。 ようするに、NOTゲート二つで作ったループ(1ビットの情報を記憶することができる)に値を取り込むかを単純にスイッチのON/OFFで制御しているということです。
まとめ
ラッチとフリップフロップの用語の混乱を整理し、代表的なラッチやフリップフロップの回路図を紹介しました。
回路図の参考文献
回路図を書く時に参考にしたと明示したもの以外で、配線が同じ回路図であることを確認したもの
- File:Edge triggered D flip flop.svg - Wikimedia Commons
- 洗練されたD-FF
- https://www.ti.com/lit/ds/symlink/sn74s74.pdf
- 洗練されたD-FF
- https://ocw.u-tokyo.ac.jp/lecture_files/engin_04/7/notes/ja/07.pdf
- 洗練されたD-FF, マスタースレーブ型JK-FF, 洗練されたJK-FF
- 5. フリップフロップ — Digital Electronic Circuits 1.0 ドキュメント
- マスタースレーブ型JK-FF
- 論理回路 / JKフリップフロップ | meyon's STUDY
- マスタースレーブ型JK-FF
- エッジトリガ型フリップフロップ
- 洗練されたD-FF, 洗練されたJK-FF
本文中で示したゲート付きDラッチの回路図記号が使われている文献