1、介绍
Latch(锁存器)是一种基本的存储元件,用于在数字电路中保存一个二进制位的信息。锁存器是电平敏感的,意味着它的输出状态会根据输入信号和使能信号的状态来变化。
2、Latch 的危害
1、时序问题
- 竞争和冒险:锁存器是电平敏感的,这可能导致竞争和冒险情况,尤其是在输入信号迅速变化时。这可能导致输出不稳定,增加设计的复杂性。
2、不确定性
- 电平保持:在使能信号低电平时,锁存器保持当前状态。如果此时输入信号发生变化,可能导致不确定的输出,影响后续电路的行为。
3、设计不良引发的错误
- 时序违反:如果锁存器的时序特性没有得到良好的管理,可能导致时序违反,从而引发功能错误。
3、Latch 的产生
1、组合逻辑中 if 语句没有 else
在组合逻辑中使用了 if 语句而没有 else 分支,未满足条件的情况下,输出变量的值将保持不变。这种情况下,输出就会保持之前的状态,从而导致锁存器的行为。
verilog
if (condition) begin
output = value;
end
// 省略 else,output 在 condition 不满足时保持不变
1
2
3
4
2
3
4
2、组合逻辑中 case 的条件未列举完并且不写 default
在 case 语句中,如果没有涵盖所有可能的输入条件且缺少 default 分支,当输入匹配不到任何条件时,输出变量可能会处于未知状态(x)或 高阻态(z),具体取决于编译器和仿真工具。
verilog
case (input)
2'b00: output = value1;
2'b01: output = value2;
// 未列举 2'b10 和 2'b11
endcase
// 没有 default,output 可能会处于未知状态(x)或 高阻态(z)
1
2
3
4
5
6
2
3
4
5
6
3、输出变量赋值时未被更新
在组合逻辑中,如果某些条件下输出变量被赋值,而在其他条件下没有更新,那么输出的值可能会保持上一次的状态。
verilog
assign output = (condition1) ? value1 : (condition2 ? value2 : output);
// output 在不满足任何条件时不更新
1
2
2
4、如何避免
避免 latch 的产生,在组合逻辑中,可以遵循以下具体建议:
1、完整的 if-else 或 case 语句结构
确保所有可能的条件都被考虑到。在 if 语句中,使用 else 处理未满足条件的情况;在 case 语句中,列举所有可能的输入或至少提供一个 default 分支,以避免在不匹配条件处于未知状态(x)或 高阻态(z)
verilog
// 使用 if-else
if (condition1)
output = value1;
else if (condition2)
output = value2;
else
output = default_value; // 避免不确定性
end
// 使用 case
case (input)
2'b00: output = value1;
2'b01: output = value2;
default: output = default_value; // 提供默认处理
endcase
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2、不要将赋值信号放在赋值源头或条件判断中 在条件判断中避免使用自身作为赋值源,这可能导致无法正确更新输出值。
verilog
// 错误示例
assign output = (condition) ? value : output; // 不应引用自身
// 正确示例
assign output = (condition) ? value : other_value; // 使用其他变量
1
2
3
4
5
2
3
4
5
3、使用 always @(*) 语句
建议在组合逻辑中使用 always @(*),这样可以自动包含所有输入信号,确保逻辑在任何输入变化时都会被更新,避免状态保持。
verilog
always @(*) begin
if (condition1)
output = value1;
else if (condition2)
output = value2;
else
output = default_value; // 明确处理
end
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8