こうこく
作 ▸

書いて覚えたいSRフリップフロップ (JavaScript)

試験勉強で覚えたいだけなのですごく浅いです

もくじ

フリップフロップ回路とは

  • 前回の出力値が Q であるときに、いくつかの入力値によって次の Q の値が決定される論理回路。
  • 電流が流れてる限り、最後の出力値 (1bitだから 0 or 1) を覚えていられるのが特徴。
  • Q のためにバランスをとってくれる Q をセットで持ってる。Q の値は、常に Q の逆になる。フリップフロップ=ぎっこんばったん。

フリップフロップ回路でできてるRAMがSRAM。回路が複雑なので高価だけど、フリップフロップ回路でビットの状態を覚えてられるので、DRAMと違ってリフレッシュがいらない。あと、SRAMは速いからキャッシュメモリに使われてるらしい。

SRフリップフロップとは

前回の出力値が Q であるときに、任意の入力値 S と R によって次の Q の値が決定されるタイプのフリップフロップ。

調べてると『SR』だったり『RS』だったりするが同じものっぽい。S は Set、R は Reset。

  • S = 0 かつ R = 0 なら、次の Q は前回と同じ (保持)。
  • S = 0 かつ R = 1 なら、次の Q は必ず 0 (リセット)。
  • S = 1 かつ R = 0 なら、次の Q は必ず 1 (セット)。
  • *S = 1 かつ R = 1 を入力するのは、Q と Q が両方とも 0 になって「Q は常に Q の逆」というルールを崩してしまうので、『禁止』または結果が『不定』とされている。*実際にどうなるかはハードの実装に依存する。

サンプルコード

NORで作るのとNANDで作るのがあるらしいので、両方作った。もちろんどっちでも挙動は同じ。

また、ここでは「Q は常に Q の逆」が崩れた時にエラーとなるようにした。よって S = 1 かつ R = 1 は実質禁止。

SRフリップフロップ (NOR型)
class FlipFlop {
	constructor() {
		this.q  = false;  // ここでは初期値はゼロ (false) とする
		this.q_ = true;
	}
	input(s, r) {
		s = !!s, r = !!r;
		this.q_ = !(s || this.q);
		this.q  = !(r || this.q_);
		if (this.q === this.q_) throw new Error('qとq_が逆になってません!');
		return Number(this.q);
	}
}
SRフリップフロップ (NAND型)
class FlipFlop {
	constructor(q) {
		this.q  = false;  // ここでは初期値はゼロ (false) とする
		this.q_ = true;
	}
	input(s, r) {
		s = !!s, r = !!r;
		this.q_ = !(!r && this.q);
		this.q  = !(!s && this.q_);
		if (this.q === this.q_) throw new Error('qとq_が逆になってません!');
		return Number(this.q);
	}
}

上記2つのコードは、以下のテストに合格する。

テスト
var flipflop = new FlipFlop();               // 初期値 0
console.assert(flipflop.input(0, 0) === 0);  // 保持     (0 -> 0)
console.assert(flipflop.input(1, 0) === 1);  // セット   (0 -> 1)
console.assert(flipflop.input(1, 0) === 1);  // セット   (1 -> 1)
console.assert(flipflop.input(0, 0) === 1);  // 保持     (1 -> 1)
console.assert(flipflop.input(0, 1) === 0);  // リセット (1 -> 0)
console.assert(flipflop.input(0, 1) === 0);  // リセット (0 -> 0)

くわしく

// 初期状態: この時点で内部に保持してる Q は 0
var flipflop = new FlipFlop();

// 1周目: 入力 S = 0, R = 0 (保持)
console.log( flipflop.input(0, 0) ); // Q = 0 (初期値のまま)

// 2周目: 入力 S = 1, R = 0 (セット)
console.log( flipflop.input(1, 0) ); // Q = 1 (1周目の値を無視して 1 で上書き)

// 3周目: 入力 S = 0, R = 0 (保持)
console.log( flipflop.input(0, 0) ); // Q = 1 (2周目の値を保持)

// 4周目: 入力 S = 0, R = 1 (リセット)
console.log( flipflop.input(0, 1) ); // Q = 0 (3周目の値を無視して 0 で上書き)
この記事に何かあればこちらまで (非公開)