kivantium活動日記

プログラムを使っていろいろやります

ラッチとフリップフロップ

この記事はkivantium Advent Calendarの6日目です。

昨日までは入力だけで出力が確定する組み合わせ回路を扱っていました。
しかし、掛け算のような複雑な演算を効率的に行うには前の計算結果を保存しておいて、何度か繰り返し計算を行うような処理が必要になります。

そこで、今回はデータを保存する方法について取り上げます。

 \overline{SR}ラッチ

 \overline{SR}ラッチは次のような回路です。

見て分かるようにNANDゲートだけで構成されています。
 \overline{SR}ラッチは入力 \overline{S} (setのS),  \overline{R} (ResetのR) に応じて出力 Qが次のようにして決まります。

 \overline{S}  \overline{R} 動作
0 0 禁止
0 1 Q=1
1 0 Q=0
1 1 保持

挙動を一つずつ確認してみます。

 \overline{S}=0,  \overline{R}=0
この状態を入力すると Q=1,  \overline{Q}=1となって関係が崩れるので禁止されています。
 \overline{S}=0,  \overline{R}=1
 \overline{S}=0なので、上のNANDゲートは \overline{Q}に関わらず 1を出力します。すると下のNANDゲートが 0を出力するので表にある動きをします。
 \overline{S}=1,  \overline{R}=0
 \overline{R}=0より下のNANDは常に 1を出力します。すると上のNANDゲートが 0を出力するので表にある動きになります。
 \overline{S}=1,  \overline{R}=1
上のNANDゲートは \overline{Q}を反転した値を出力し、下のNANDゲートは Qを反転した値を出力します。この状態で安定するので値が保存されます。

値として1を保存したければ(0, 1)を入力した後(1, 1)に切り替え、0を保存したければ(1, 0)を入力した後(1, 1)に切り替えることで1bitのメモリとして \overline{SR}ラッチを使うことができます。

D型フリップフロップ (D-FF)

D-FFはクロックが立ち上がった(=0から1に変化した)ときの入力を保持する回路で、次のような記号で表します。

D-FFは以下のように \overline{SR}ラッチを3つ組み合わせたような形をしています。

動作を確認していきます。下から3つ入力があるNANDゲートは入力が全て1のときのみ0を出力し、その他の場合は1を出力します。

Clockが0のとき

上のラッチは \overline{R}=0となるので \overline{Q}にあたる 1が出力ラッチに入ります。
下のラッチは \overline{S}=0となるので Qにあたる1が出力ラッチに入ります。
したがって出力ラッチは値を保持します。

Clockが立ち上がったとき

Dataが0のとき
下のラッチは0を出力し、上のラッチは1を出力するので出力ラッチは0を出力します。
Dataが1のとき
下のラッチは1を出力し、上のラッチは0を出力するので出力ラッチは1になります。

Clockが1のとき

立ち上がり時のDataが0のとき
一番下のNANDゲートは、上側の入力が常に0なのでDataの値によらず常に1を出力するため値は保持されます。
立ち上がり時のDataが1のとき
Dataが1のときは下のラッチが1、上のラッチが1を出力するので出力ラッチは1を出力します。Dataが0のときは上のラッチが保持になり、下が1、上が0という状態が維持され、出力ラッチは1を出力します。

D-FFの使い道にはいろいろありますが、よく使うのはシフトレジスタです。
シフトレジスタはD-FFを何段か並べて、ある段のD-FFの出力を次の段の入力につないで作ります。

こうすることでクロックが入るたびに1段目はDataからの入力を保存し、2段目以降は前の段の値を持つようになります。
このようにクロックが入るたびにデータがシフトするのでシフトレジスタと呼びます。
シフトレジスタは掛け算や割り算の実装にも使われます。

Earleラッチ

EarleラッチはE_Hが0のとき前の値を保持し、E_Hが1のときDataの値をそのまま出力する回路です。(E_LにはE_Hを反転したものを入れる)

これはIBM System/360 Model 91でパイプラインのデータを保持するときに使われました。

ラッチとフリップフロップ

ラッチとフリップフロップにはここで紹介した以外にもたくさんの種類があるので興味がある人は調べてください。Verilogで書く場合にはどのFFを使うかはあまり意識せず、ここにFFが入るなと思う程度になります。

ラッチとフリップフロップの呼び分けには明確な決まりがないようですが、クロックの立ち上がり・立ち下がりをデータ読み込みのタイミングに使うものをフリップフロップと呼び、クロックの状態で保存するかどうかが変わるものをラッチと呼ぶことが多いようです。

同期式回路

シフトレジスタの例のように全てのフリップフロップに入るクロックが同じ回路を同期式回路といいます。クロックが変化している最中にデータが変化するとハザードと呼ばれる状態になり出力が不安定になります。それぞれのフリップフロップが別々のクロックに従って値を変えてしまうとハザードが発生します。
全てのフリップフロップが同一のクロックに従えば、回路の全ての部分で値の変化が同時に起こり、値の変化が落ち着いてから次のクロックが来るようにすればハザードを回避できます。このためFPGAでの開発では同期式回路が好まれます。

一方、クロックも電気の流れなのでCPUを流れるのに時間がかかります。光の速度で動いたとしても10GHzのクロックでは1クロックで3cmしか動くことができずフリップフロップごとにクロックの到達時間が異なってしまいます(スキュー)。これを回避するために非同期式回路の研究をしている人もいるようですがあまり盛んではないように見えます……

参考