跳到主要内容

锁存器与D触发器的Verilog语言描述与电路特点

1 锁存器 Latch

在 Verilog 中,锁存器(Latch) 是一种电平敏感的存储元件,它在使能信号有效时(通常是高电平)将输入数据传递到输出,使能信号无效时保持输出不变。在组合逻辑 always 块中,意外产生锁存器是一个常见的设计问题,因为它可能导致不可预测的硬件行为、功耗增加和时序问题。

1.1 锁存器结构

电路结构如下图所示,原理详见数字电路课程

Latch

1.2 锁存器产生的原因

当一个 always 块描述组合逻辑(通常使用 always @(*))时,如果在某些输入条件下,块内没有为某个输出变量赋值,综合工具就会推断出一个锁存器来保持该变量的旧值。也就是说,变量的值在某些条件下是“不确定”或“保持不变”,这正是锁存器的行为。

  1. if 语句缺少 else 分支
    always @(*) begin
    if (enable) data_out = data_in;
    end
    分析:当 enable 为 0 时,data_out 的值没有被明确指定。为了在 enable 为 0 时保持 data_out 的值不变,综合工具会生成一个锁存器。
  2. case 语句没有覆盖所有可能的值
    always @(*) begin // 组合逻辑
    case (sel)
    2'b00: y = a;
    2'b01: y = b;
    2'b10: y = c; // 没有处理 sel == 2'b11 的情况!
    endcase
    end
    分析:sel 的值可能为 2'b11,但是没有处理这种情况,因此综合工具会生成一个锁存器来保持 y 的值不变。
  3. 原信号赋值或者判断
    always @(*) begin
    if (a & b) a = 1'b1; // a -> Latch
    else a = 1'b0;
    end
    分析:a 的值作为条件判断
  4. 敏感信号列表不完整 如果组合逻辑中 always@() 块内敏感信号列表不完整,该触发的时候没有触发,那么相关寄存器还是会保存之前的输出结果。因而会生成锁存器

1.3 锁存器的避免

  1. 为所有 if 分支提供 else 确保在 if 语句的每个分支(包括 if 和 else)中都为所有相关的输出变量赋值。
    always @(*) begin
    if (enable) data_out = data_in;
    else data_out = 1'b0;
    end
  2. 在 case 语句中使用 default 为 case 语句提供 default 分支,并确保 default 分支中为所有相关的输出变量赋值。
    always @(*) begin
    case (sel)
    2'b00: y = a;
    2'b01: y = b;
    2'b10: y = c;
    default: y = 1'b0; // 添加默认分支
    endcase
    end
  3. 不要将赋值信号放在赋值源头,或条件判断中
    reg a_r;
    always @(posedge clk) a_r <= a;
    always @(*) begin
    if (a_r & b) a = 1'b1;
    else a = 1'b0;
    end
  4. 敏感信号列表建议多用 always@(*)

2 D触发器

2.1 D触发器的结构

D触发器(D Flip-Flop)是一种电平敏感的存储元件,它可以将输入数据传递到输出,并保持输出不变,直到下一次输入数据改变。D触发器的结构如下图所示,原理详见数字电路课程

DFF

2.2 D触发器和锁存器的区别

  • 触发方式:D触发器是边沿触发的,锁存器是电平触发的。
  • 内部结构:D触发器通常由两个锁存器(主从结构)级联而成。第一个锁存器在时钟边沿前一个时刻(例如下降沿)锁存 D 值,第二个锁存器在时钟边沿(例如上升沿)接收第一个锁存器的输出;这种结构确保了只在时钟边沿时刻对 D 采样。锁存器结构相对简单,通常由门电路(如 NAND、NOR 门)构成,直接响应使能信号电平。

2.3 D触发器的Verilog语言描述

module D_FF(D, clk, rst, Q); 
input D, clk, rst;
output reg Q;
always @(posedge clk or posedge rst) begin
if (rst) Q <= 1'b0;
else Q <= D;
end
endmodule