推荐答案
测试一下
题目
5.2 产生锁存器latch的代码
参考答案与知识点
参考答案
锁存器(latch)是电平敏感的存储单元,在数字设计中应尽量避免,因为它会导致时序分析困难、毛刺敏感以及静态功耗增加。常见的产生锁存器的代码模式包括:
1. **if 语句缺少 else 分支**:在组合逻辑(如 always@(*))中使用 if 时,若条件不满足时没有 else 赋值,综合工具会推断出锁存器以保持原值。例如:
```verilog
reg out;
always @(*) begin
if (en) out = in;
end
```
当 en=0 时,out 保持原值,形成锁存器。
2. **case 语句缺少 default**:在组合逻辑的 case 中,若未覆盖所有可能取值且无 default,则未出现的 case 项会保持前一状态,产生锁存器。例如:
```verilog
reg sel;
always @(*) begin
case (sel)
2'b00: out = a;
2'b01: out = b;
endcase
end
```
当 sel=2'b10/11 时,out 保持原值,综合出锁存器。
3. **always 块敏感列表不完整**:虽然现在综合工具通常提示“incomplete sensitivity list”,但若故意遗漏敏感信号,仍可能产生意想不到的锁存器。例如:
```verilog
always @(a or b) begin
if (sel) out = a; else out = b; // sel未在敏感列表中,但sel变化也会触发?实际综合会忽略?
end
```
更常见的是:在 always@(*) 中忽略某些输入也可能导致锁存器。
4. **组合逻辑中给变量多次赋值**:如果在一个 always 块中对同一个变量在多个分支赋值,但某些条件下未赋值,综合会推断锁存器。
**避免方法**:
- 在组合逻辑的 always@(*) 块中,对所有输入信号都给出完整的分支(if 必须配 else,case 必须配 default)。
- 若确实需要保持状态,应使用时序逻辑(always@(posedge clk))显式地使用寄存器。
- 推荐采用“一次性赋值”风格:在组合逻辑开始处给所有输出赋初值(如 default 值),再写条件分支。
**易错点**:
- 认为“综合时出现 latch 警告也没关系”,实际上 latch 会引入竞争冒险和时序不确定。
- 混淆锁存器与寄存器:寄存器同步于时钟沿,锁存器同步于电平。
- 在 case 语句中,如果用了 unique 或 priority 修饰,仍需保证完整性。题库中常见此类陷阱。
涉及知识点
- 时序
- 功耗
- 组合逻辑
- 综合
- verilog