> For the complete documentation index, see [llms.txt](https://s2.shizhz.me/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://s2.shizhz.me/s2e4/3.md).

# 4.3. D Flip-Flop：以时钟为脉搏的存储器

前文中提到的 SR Latch 具备了存储 1 Bit 数据的能力，而时钟用来同步电路的运行，那么如何利用时钟信号来控制数据进行写入呢？下图所示的 D Latch 可以实现该效果：

![D Latch](/files/-MdWNdefQPYqRAWYlLXa)

分析该电路可以发现，时钟信号控制着数据的写入情况：

* 当时钟信号 C = 0 时，Q 不改变
* 当时钟信号 C = 1 时，Q 的值被设置成 D

细心的读者会发现：D Latch 还解决了 S 与 R 不能同时为 1 的问题。

D Latch 的特点是，当时钟信号是 1 时， Q 的数据总是会保持与 D 一致。这种机制的电路叫着 Level-trigger, Level 指时钟脉冲信号的上沿（Top level）或下沿（Bottom level）。上图的 D Latch 是上沿触发的，信号 D 和 Q 随着时钟脉冲信号 CK 变化的示意图如下：

![](/files/-MdWNx6dxrZsDZsbQo9q)

注意在最后一个时钟的上沿阶段，Q 随着 D 变化了两次，而这正是 D Latch 的特点：在时钟信号为 1 时，输出信号 Q 总是能够实时**捕捉**到输入数据 D 的变化。

与 Level-trigger 相对应的是在时钟信号变化的瞬间进行触发，而在其它时候保持 Q 的信号不变。这种触发方式叫着 Edge-trigger, 下图展现的是通过两个 D Latch 与一个非门组装的效果图，上面的电路通过上升沿触发，下面的通过下降沿触发：

![D Flip-Flop](/files/-MdWOAbAwjpGh0p70n98)

我们来分析 A, 一个通过上升沿触发的电路组件：当 CLK 为 0 时， CLK0 为 1, 因此 Q0 的值会一直与 D 保持一致，而由于 CLK1 此时为 0, 所以输出端 Q 的值不会改变；但当 CLK 变为 1 时，CLK1 的值变为 1, 此时 Q0 的值会立马写入 Q, 而由于 CLK0 此时为 0, Q0 的值将保持不变，所以 Q 的值将会锁定为 CLK 由 0 变为 1 时的瞬时值，即数据的写入是由时钟信号的上升沿触发的。

这种电子组件叫着 D Flip-Flop, D 可以代表 Data, 也可以是 Delay, 简称为 DFF. 由于 DFF 总是在时钟信号变化时才触发数据的写入操作，因此其输出信号与输入信号满足如下关系：out(t) = in(t - 1), 其中 t 为任意时钟周期。一个 DFF 的信号在时钟周期上的表示如下图所示：

![DFF Behavior](/files/-MdWOUTW1f1DKge4zFgx)

DFF 是构建存储型电子芯片的基础元件，寄存器（Register）、内存（RAM）等都可以基于 DFF 进行构建，所有的 DFF 都连接到系统的时钟信号上，这样可以保证所有对数据的写入操作都会在下个时钟周期生效，而这正是我们期待的效果。
