トップデジタル回路[JavaScript版] > Dフリップフロップ

Dフリップフロップ

1.Dフリップフロップとは

D入力の値をクロックに同期して読み込み、 次のクロックが加わるまでの期間中その値を保持、記憶する回路をDフリップフロップという。 また、D入力を読み込むことをラッチ(Latch)するという。

クロックが0のとき、Dの値を変えても直ちに出力に反映されず、 クロックが1になるまで待たされる。つまり、遅れがある。DフリップのDは Delay(遅れ) の頭文字をとったものである。

通常は、クロックの立ち上がりまたは立下りでD入力をラッチするエッジトリガ型が用いられる。 SN7475はクロックがHighレベルでは、Dの値がそのまま出力Qに現れ、クロックの立下りでラッチされ、 クロックがLowレベルの間はこの値が保持される。このようなタイプをバイステーブル・ラッチと呼び、 立ち上がりまたは立下りでしか入力を受け付けないものと区別されることもある。

2.Dフリップフロップ(by R-S-T FlipFlop)

Dフリップの実現方法はいくつか知られている。最初に、R-S-Tフリップフロップを使った実現方法を示す。 次の回路では、入力信号Dの値を変更しても、それが出力に伝わるのは、入力信号Tの値が1のときである。

現時刻の入力信号 D, T および出力信号 Q,Q の値をそれぞれ i0, t0 および o0, o1 で表す。また、入力端子Rの現時刻の信号の値を i1 で表す。

NOTゲートおよびR-S-T内部回路の入力段のANDゲートの遅延時間を無視する(0とみなす)と、 i1 および次の時刻(NORゲート遅延時間後の時刻)における 出力信号 Q,Q の値 n0, n1 は次のように表される。

    i1 = !i0;                   // NOT
    n0 = !((i1 && t0) || o1);   // AND → NOR
    n1 = !((i0 && t0) || o0);   // 同上

下の一つの長方形記号のDフリップフロップは上に述べたように動作している。

一方、上の回路では NOT回路の遅延時間は考慮している。 このため、上の回路と下の回路の動作は完全には一致していない。 しかし、通常の使い方ではこれでよい。

前にも述べたように、遅延時間は素子によりバラツクし、ある一つの素子をとってみても、温度などにより変化する。 遅延時間を精確にシミュレーションすることはもともと無理がある。

しかし、一般に、閉ループを含むときは遅延時間を 0 とみなすことはできない。 一方、信号が、回路図上、左にある素子から右にある素子へと一方向に流れるときは、 遅延時間を無視できる。

ここで、通常の使い方とは一体どんな使い方なのかを明らかにしておかねばならない。 入力信号Dは時間的に変化し、1になったり0になったりするが、 この変化するきわどい時間でクロック信号Tを1から0に変えたりしない。 きわどいタイミングでクロック信号を1から0に変えると、出力が0のこともあれば1のこともある。 回路全体としては入力信号Dが変化するタイミングと クロック信号が1から0に変化するタイミングが一定時間以上ずれるように設計しておくわけである。 このずれの時間がゲートの遅延時間より十分大きければ、ゲートの遅延時間が多少ばらついたり、 時間的に変動しても誤動作しない。 これが、通常の使い方であり、後々のページで詳しく説明する。

3.Dフリップフロップ(by NANDゲート4個)

次の図(静止画)は下に示すシミュレーション回路のスナップショットである。 入力信号D, Tの値はマウスクリックで適当に変動させた。 この回路も初期状態では発振するが、一度Tの値を1にすると、 発振は止まり、その後はどのような入力の組み合わせについても発振することはない。

この回路は、クロックTが 0 の期間中はデータを記憶するが、 Tが1の期間中はDの値がそのまま出力Qに現れ、 Dが変化すると出力もそれに応じてすぐに変化する。

入力Dの値を1に保った状態で、Tの値を0から1に変えたとき、Qの値は1を保っているが、 Qの値は0の値を保つのではなく、Tの値を0から1に変わったとき 一瞬1になっている。すなわち、ヒゲ状のノイズ(ハザード)が生じている。

Dは1に保たれているので、信号Cの値は T となる。 従って下のNANDゲートの入力は TとTである。 ここで、Tの信号は上のNANDゲートを通過するのに時間がかかっているため、 もう一つの入力Tより少し時間遅れがある。このため、この遅延時間の間、 TとTが共に1となることから、信号Dの値がこの間0となる。 このため、後段のNANDの入力が0となり、Qの値が一瞬1となる。

通常、ヒゲ状のノイズでは誤動作しないように回路設計されるが、気持ちのいいものではない。

前のR-S-TによるDフリップを構成するゲートは5個であるのに対して、 こちらの回路はNANDゲート4個で構成されるので、その点は有利である。


論理式や回路の簡単化では、通常、遅延時間は考慮しないが、 実際には、遅延時間があるため、このことまで含めると元の回路や式と 簡単化された回路や式は 完全に等価というわけではない。

4.Dフリップフロップ(by J-K FlipFlop)

次にクロックの立下りでD入力をラッチするようなDフリップフロップを考えよう。 マスタースレーブJ-Kフリップフロップによるシミュレーションのスナップショットを下に示す。


一つの長方形記号で表したDフリップフロップの動作を 先に述べたマスタースレーブJ-Kフリップフロップの構造に従って表現すると次のようになる。 ここでは4つの中間変数を用いている。

i1 = !i0;
scope.setVal(mid[0], delayGate, i0 && o1);	// 前段AND
scope.setVal(mid[1], delayGate, i1 && o0);
scope.setVal(mid[2], delay, !((m0 && t0) || m3));// 前段FF
scope.setVal(mid[3], delay, !((m1 && t0) || m2));
n0 = !((m2 && !t0) || o1);	// 後段FF
n1 = !((m3 && !t0) || o0);

一方、このような内部構造には拘らず、Dフリップの仕様から考えると 次のようなシンプルなプログラムで表現される。 ここでクロック信号Tの現在の値を t0、一つ前の値 tL とする。

if (tL && !t0) {	// クロックの立下り
    n0 = i0;	// D入力をセット
    n1 = !i0;
} else {
    n0 = o0;	// 現在の値を保持
    n1 = o1;
}

今回のシミュレーションはこの簡単なプログラムの結果を示すものである。 初期値はQ、Qとも0としている。発振は起きない。 また、上のスナップショットで、最後(左端)から1周期余り前に、 クロックの立下りが起こる直前に入力Dの値を1から0に変化させている。 マスタースレーブJ-Kフリップフロップでは遅延時間の影響で、 この時の立下りではこの直前の変化がキャッチできず、入力Dは1とみなしている。

一方で、下の回路ではこのような遅延時間はないため、 この入力Dの変化をキャッチし、出力の値は0に変わっている。

前にも述べたが、実際の回路では、 このようなきわどいタイミングで入力の値を変化させたりしないため、 このような微細な差異は無視してよい。

この先、Dフリップフロップは頻繁に登場するが、 原則としてこのシンプルなプログラムを採用する。