HDLbits Sequential Logic3.2.1——Latches and Filp-Flops

1、AD 触发器是一种在时钟信号的(通常)上升沿存储位并定期更新的电路。当使用时钟控制的always块时,逻辑合成器会创建 D 触发器。AD触发器是“组合逻辑块后接触发器”的最简单形式,其中组合逻辑部分只是一条线。

创建一个 D 触发器。

Dff.png
module top_module (     input clk,    // Clocks are used in sequential circuits     input d,     output reg q );//      // Use a clocked always block     //   copy d to q at every positive edge of clk     //   Clocked always blocks should use non-blocking assignments     always@(posedge clk)         q<=d;  endmodule

2、创建 8 个 D 触发器。所有 DFF 都应由clk的上升沿触发。

module top_module (     input clk,     input [7:0] d,     output [7:0] q );          always@(posedge clk)         q<=d;  endmodule

3、创建 8 个具有高电平有效同步复位的 D 触发器。所有 DFF 都应由clk的上升沿触发。

module top_module (     input clk,     input reset,            // Synchronous reset     input [7:0] d,     output [7:0] q );     always@(posedge clk)         begin             if(reset) q<=0;             else                 q<=d;         end  endmodule

4、创建 8 个具有高电平有效同步复位的 D 触发器。触发器必须重置为 0x34 而不是零。所有 DFF 都应由clk的下降沿触发

module top_module (     input clk,     input reset,     input [7:0] d,     output [7:0] q );     always@(negedge clk)         begin             if(reset)                 q<=8'h0x34;             else                 q<=d;         end  endmodule

5、创建 8 个具有高电平有效异步复位的 D 触发器。所有 DFF 都应由clk的上升沿触发。

module top_module (     input clk,     input areset,   // active high asynchronous reset     input [7:0] d,     output [7:0] q );     always@(posedge clk or posedge areset)         if(areset)             q<=0;         else             q<=d;           endmodule

6、创建 16 个 D 触发器。有时只修改一组触发器的一部分很有用。字节使能输入控制 16 个寄存器中的每个字节是否应在该周期写入。byteena[1]控制高字节d[15:8],而byteena[0]控制低字节d[7:0]

resetn是一个同步的低电平有效复位。

所有 DFF 都应由clk的上升沿触发。

module top_module (     input clk,     input resetn,     input [1:0] byteena,     input [15:0] d,     output [15:0] q );     always@(posedge clk)         begin             if(!resetn)                 q<=0;             else                 begin                     q[15:8]<=byteena[1]?d[15:8]:q[15:8];                     q[7:0]<=byteena[0]?d[7:0]:q[7:0];                 end         end  endmodule

7、实现以下电路:

1)请注意,这是一个锁存器,因此预计会出现关于已推断锁存器的 Quartus 警告。

2)锁存器是电平敏感(非边沿敏感)电路,因此在一个始终块中,它们使用电平敏感灵敏度列表。

3)但是,它们仍然是顺序元素,因此应该使用非阻塞赋值。

4)D 锁存器在启用时就像一条线(或非反相缓冲器),在禁用时保留当前值。

Exams m2014q4a.png

module top_module (     input d,      input ena,     output q);          //always@(ena)     always@(*)         if(ena)             q<=d;  endmodule

8、实现以下电路:

考试 m2014q4b.png

module top_module (     input clk,     input d,      input ar,   // asynchronous reset异步复位     output q);      always@(posedge clk or posedge ar)         if(ar)             q<=0;         else             q<=d; endmodule

9、实现以下电路:

考试 m2014q4c.png

 

module top_module (     input clk,     input d,      input r,   // synchronous reset同步复位     output q);          always@(posedge clk)         if(r)             q<=0;         else             q<=d;  endmodule

10、实现以下电路:

考试 m2014q4d.png

module top_module (     input clk,     input in,      output out);      always@(posedge clk)         begin             out<=in^out;         end endmodule

11、考虑下面的时序电路:

mt2015 muxdff.png

假设您要为此电路实现分层 Verilog 代码,使用其中具有触发器和多路复用器的子模块的三个实例化。为此子模块编写一个名为top_module的 Verilog 模块(包含一个触发器和多路复用器)。

module top_module (     input clk,     input L,     input r_in,     input q_in,     output reg Q);      always@(posedge clk)         Q<=L?r_in:q_in; endmodule

12、考虑如下所示 的n位移位寄存器电路:

考试 2014q4.png

为该电路的一个阶段编写一个名为 top_module 的 Verilog 模块,包括触发器和多路复用器。

 

module top_module (     input clk,     input w, R, E, L,     output Q );          always@(posedge clk)         begin          Q<=L?R:E?w:Q;         end  endmodule

13、给定如图所示的有限状态机电路,假设 D 触发器在机器开始之前初始复位为零。

建立这个电路。

小心复位状态。确保每个 D 触发器的Q输出确实是其 Q 输出的倒数,即使在模拟的第一个时钟沿之前也是如此。

Ece241 2014 q4.png

 

module top_module (     input clk,     input x,     output z );       reg q1,q2,q3;     always@(posedge clk)     begin         q1<=x^q1;         q2<=x&(~q2);         q3<=x|(~q3);     end          assign z=~(q1|q2|q3); endmodule

14、JK 触发器具有以下真值表。实现一个只有 D 型触发器和门的 JK 触发器。注意:Qold 是正时钟沿之前 D 触发器的输出。

J K Q
0 0 Qold
0 1 0
1 0 1
1 1~ Qold
module top_module (     input clk,     input j,     input k,     output Q);       always@(posedge clk)         begin             case({j,k})                 2'b00:Q<=Q;                 2'b01:Q<=0;                 2'b10:Q<=1;                 2'b11:Q<=~Q;             endcase         end endmodule

15、对于 8 位向量中的每一位,检测输入信号何时从一个时钟周期的 0 变为下一个时钟周期的 1(类似于上升沿检测)。输出位应在发生 0 到 1 转换后的周期设置。

这里有些例子。为清楚起见,in[1] 和 pedge[1] 分别显示。

 

 

module top_module (     input clk,     input [7:0] in,     output [7:0] pedge );     reg [7:0] state_in;     always@(posedge clk)         begin             state_in<=in;             pedge<=~state_in&in;             //pedge<=state_in~&in;错误写法             //pedge<=state_in^in;检测输入信号从0跳变到1的位置,用xor门会同时检测到从1变到0的位置         end  endmodule

16、对于 8 位向量中的每一位,检测输入信号何时从一个时钟周期变为下一个时钟周期(检测任何边沿)。输出位应在发生 0 到 1 转换后的周期设置。

这里有些例子。为清楚起见,in[1] 和 anyedge[1] 分别显示

1)上升沿加下降沿检测。上升沿核心检测逻辑: ~in_last & in。下降沿类似上升沿核心逻辑为: in_last & ~in。最后运用或逻辑组合起来即可。核心代码:anyedge = (~in_last & in) | (in_last & ~in)。

2)异或逻辑检测。边沿检测,从整体来看,即信号发生变化就进行检测输出。因此使用异或逻辑 。核心代码:in ^ in_last 。

module top_module (     input clk,     input [7:0] in,     output [7:0] anyedge );     reg [7:0] state_in;     always@(posedge clk)         begin             state_in<=in;             anyedge<=state_in^in;         end  endmodule

17、对于 32 位向量中的每一位,在输入信号从一个时钟周期的 1 变为下一个时钟周期的 0 时进行捕捉。“捕获”表示输出将保持为 1,直到寄存器复位(同步复位)。

每个输出位的行为类似于 SR 触发器:输出位应在 1 到 0 转换发生后的周期设置(为 1)。当复位为高电平时,输出位应在正时钟沿复位(为 0)。如果上述两个事件同时发生,则重置优先。在下面示例波形的最后 4 个周期中,“reset”事件比“set”事件早一个周期发生,因此这里不存在冲突。

在下面的示例波形中,为清楚起见,reset、in[1] 和 out[1] 再次分别显示。

1)题意:检测下降沿,检测到后out一直为高,直到reset == 1时,out才为0。
2)方法:先通过边沿检测,得到一个脉冲信号,然后如果这个脉冲信号为高,将其输出给out,输出为低就不管(保持前面状态)。
但是这样做,边沿检测时会延迟一个clk,在将其输出给out时又会延迟一个clk,这样就与题目中给的时序图不符,

3)改正:直接将边沿检测信号与输出信号本身相或赋值给输出信号,就能在一个clk下完成,得到与题目符合的时序图。

4)设初始  in:0000,out:0000

        然后假设in:0001  -> 0000,这时out:0001

               假设in:0001 -> 0101,这时out:0101

  

module top_module (     input clk,     input reset,     input [31:0] in,     output [31:0] out );     reg [31:0] state_in;     always@(posedge clk)         state_in<=in;     always@(posedge clk)//同步复位         begin             if(reset)                 out<=32'h0000;             else                 out<=(state_in&~in)|out;           end  endmodule

 18、您熟悉在时钟上升沿或时钟下降沿触发的触发器。在时钟的两个边沿触发双边触发触发器。但是,FPGA 没有双边触发触发器,并且始终不接受 @(posedge clk 或 negedge clk)作为合法的敏感度列表。

构建一个功能类似于双边触发触发器的电路:

(注意:它不一定完全等效:触发器的输出没有毛刺,但模拟这种行为的更大组合电路可能会。但我们将在这里忽略这个细节。)

您无法在 FPGA 上创建双边触发触发器。但是您可以同时创建正沿触发负沿触发触发器。

module top_module (     input clk,     input d,     output q );     reg q1,q2;     always@(posedge clk)         begin             q1<=d;         end     always@(negedge clk)         begin             q2<=d;         end     assign q=clk?q1:q2; endmodule