Latches and Flipflops¶
D-flipflop¶
A D flip-flop is a circuit that stores a bit and is updated periodically, at the (usually) positive edge of a clock signal.
D flip-flops are created by the logic synthesizer when a clocked always block is used (See alwaysblock2). A D flip-flop is the simplest form of "blob of combinational logic followed by a flip-flop" where the combinational logic portion is just a wire.
Create a single D flip-flop.
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
synchronous and asynchronous reset flip-flops¶
在数字电路设计中,同步复位
(Synchronous Reset)和异步复位
(Asynchronous Reset)是两种用于控制触发器(flip-flop)复位的方式。这两者的区别主要在于复位信号如何影响触发器的输出。以下是对这两者的详细解释:
同步复位 (Synchronous Reset)¶
定义:同步复位是指复位信号与时钟信号同步,即复位信号的作用只会在时钟边沿(通常是上升沿或下降沿)到来时才会被检测和执行。
工作原理: - 当复位信号被置为有效(通常是低电平或高电平,取决于设计),在下一个时钟边沿到来时,触发器的输出会被复位到一个预定的状态(通常是0)。 - 如果复位信号在非时钟边沿期间变化,触发器的输出不会立即响应,而是要等到下一个时钟边沿来临时才会执行复位操作。
优点: - 易于综合(synthesis),因为复位信号与时钟同步,可以确保所有的触发器在同一时刻复位,减少了竞争冒险(race conditions)的可能性。 - 复位时不会产生毛刺(glitch),因为复位信号在时钟边沿才会被采样。
缺点: - 在需要快速复位的情况下,响应速度较慢,因为必须等待下一个时钟边沿。 - 需要额外的逻辑来实现同步复位,这可能会增加电路的复杂性。
异步复位 (Asynchronous Reset)¶
定义:异步复位是指复位信号与时钟信号异步,即复位信号不依赖于时钟信号,可以在任何时候立即触发复位动作。
工作原理: - 当复位信号被置为有效时,无论时钟信号处于什么状态,触发器的输出都会立即被复位到一个预定的状态。 - 当复位信号无效时,触发器重新回到正常工作状态,继续响应时钟信号的输入。
优点: - 响应速度快,能够立即复位,不需要等待时钟边沿。 - 电路实现相对简单,不需要额外的逻辑来同步复位信号。
缺点: - 容易产生毛刺,尤其是在复位信号解除时,因为复位信号的边沿可能会引发触发器的误动作。 - 可能引入竞争冒险问题,尤其是在不同复位路径上存在时延差异时,导致复位不一致。
应用场景¶
- 同步复位常用于对时序要求严格的系统中,如同步数字电路和状态机设计中,因为它能确保所有触发器的复位发生在同一个时钟周期内。
- 异步复位常用于对复位响应速度要求高的场合,如需要在电源上电或系统故障时立即复位的系统。
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
DFF + gate¶
Verilog | |
---|---|
1 2 3 4 5 6 7 8 |
|
JK flip-flop¶
A JK flip-flop has the below truth table. Implement a JK flip-flop with only a D-type flip-flop and gates. Note: Qold is the output of the D flip-flop before the positive clock edge.
J | K | Q |
---|---|---|
0 | 0 | Qold |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | ~Qold |
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Edgedetect¶
For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.
Here are some examples. For clarity, in[1] and pedge[1] are shown separately.
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Edgedetect2¶
For each bit in an 8-bit vector, detect when the input signal changes from one clock cycle to the next (detect any edge). The output bit should be set the cycle after a 0 to 1 transition occurs.
Here are some examples. For clarity, in[1] and anyedge[1] are shown separately.
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Edgecapture¶
For each bit in a 32-bit vector, capture when the input signal changes from 1 in one clock cycle to 0 the next. "Capture" means that the output will remain 1 until the register is reset (synchronous reset).
Each output bit behaves like a SR flip-flop: The output bit should be set (to 1) the cycle after a 1 to 0 transition occurs. The output bit should be reset (to 0) at the positive clock edge when reset is high. If both of the above events occur at the same time, reset has precedence. In the last 4 cycles of the example waveform below, the 'reset' event occurs one cycle earlier than the 'set' event, so there is no conflict here.
In the example waveform below, reset, in[1] and out[1] are shown again separately for clarity.
Verilog | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Dualedge¶
You're familiar with flip-flops that are triggered on the positive edge of the clock, or negative edge of the clock. A dual-edge triggered flip-flop is triggered on both edges of the clock. However, FPGAs don't have dual-edge triggered flip-flops, and always @(posedge clk or negedge clk) is not accepted as a legal sensitivity list.
Hint: - You can't create a dual-edge triggered flip-flop on an FPGA. But you can create both positive-edge triggered and negative-edge triggered flip-flops. - This problem is a moderately difficult circuit design problem, but requires only basic Verilog language features. (This is a circuit design problem, not a coding problem.) It may help to first sketch a circuit by hand before attempting to code it.
```verilog module top_module( input clk, input d, output q);
Text Only | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
endmodule Verilog模块尝试实现一个双沿触发的触发器,也就是在时钟信号的正沿(posedge clk)和负沿(negedge clk)都可以捕捉数据。
设计原理:¶
这使用了两个寄存器 p
和 n
,分别在正沿和负沿时更新它们的值。通过 p
和 n
的交替更新和异或运算(p ^ n
),实现了每个时钟沿更新输出 q
的效果。
具体的实现步骤如下:
-
正沿触发:
verilog always @(posedge clk) p <= d ^ n;
这里,p
在时钟正沿时被赋值为d ^ n
,即d
和n
的异或值。 -
负沿触发:
verilog always @(negedge clk) n <= d ^ p;
在时钟的负沿,n
被赋值为d ^ p
,即d
和p
的异或值。 -
输出逻辑:
verilog assign q = p ^ n;
q
是p
和n
的异或结果。根据设计,每个时钟沿都会使p
和n
交替加载一个与当前输入d
相关的值,而最终q
总是会稳定在当前d
的值。
为什么这个方法有效?¶
- 当时钟处于正沿时,
p
被赋值为d ^ n
,此时输出q = p ^ n = (d ^ n) ^ n = d
,因为n ^ n = 0
。 - 当时钟处于负沿时,
n
被赋值为d ^ p
,此时输出q = p ^ n = p ^ (d ^ p) = d
,因为p ^ p = 0
。 - 通过这种交替的更新机制,保证了每次时钟的正沿和负沿都能够正确地更新输出
q
,使得q
在每个时钟沿都跟踪输入d
。