作 ▸
書いて覚えたい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 は実質禁止。
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);
}
}
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 で上書き)